├── .gitignore ├── .gitmodules ├── README.md ├── foundry.toml └── src ├── HarveyBaz.sol ├── HarveyFoo.sol ├── ILFCrowdsale.sol └── test └── Benchmarks.t.sol /.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/ds-test"] 2 | path = lib/ds-test 3 | url = https://github.com/dapphub/ds-test 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solidity Fuzzing Benchmarks 2 | 3 | This repository contains Solidity contracts and tests used to benchmark performance of fuzzers. 4 | It's structured to primarily benchmark performance of the [Foundry](https://github.com/gakonst/foundry/) and [Dapptools](https://github.com/dapphub/dapptools) fuzzers. 5 | 6 | Benchmarks in this repo have been pulled from: 7 | - The [Echidna](https://github.com/crytic/echidna) README 8 | - [Targeted Greybox Fuzzing with Static Lookahead Analysis](https://arxiv.org/pdf/1905.07147.pdf), by Valentin Wüstholz and Maria Christakis (these are the benchmarks used by [Harvey](https://mariachris.github.io/Pubs/FSE-2020-Harvey.pdf)) 9 | 10 | **TODO add benchmarks** 11 | -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | remappings = ['ds-test/=lib/ds-test/src/'] 6 | 7 | # See more config options https://github.com/gakonst/foundry/tree/master/config -------------------------------------------------------------------------------- /src/HarveyBaz.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | /** 4 | * @notice Fuzzer should cover all five execution paths of `baz` 5 | * @dev See the below reference for more information on the `minimize` comments 6 | * @custom:ref "Harvey: A Greybox Fuzzer for Smart Contracts", by Valentin 7 | * Wüstholz and Maria Christakis, Figure 1, https://arxiv.org/pdf/1905.06944.pdf 8 | */ 9 | contract HarveyBaz { 10 | function baz(int256 a, int256 b, int256 c) public returns (int256) { 11 | int256 d = b + c; 12 | 13 | // minimize(d < 1 ? 1 - d : 0); 14 | // minimize(d < 1 ? 0 : d); 15 | if (d < 1) { 16 | // minimize(b < 3 ? 3 - b : 0); 17 | // minimize(b < 3 ? 0 : b - 2); 18 | if (b < 3) { 19 | return 1; 20 | } 21 | // minimize(a == 42 ? 1 : 0); 22 | // minimize(a == 42 ? 0 : |a - 42|); 23 | if (a == 42) { 24 | return 2; 25 | } 26 | return 3; 27 | } else { 28 | // minimize(c < 42 ? 42 - c : 0); 29 | // minimize(c < 42 ? 0 : c - 41); 30 | if (c < 42) { 31 | return 4; 32 | } 33 | return 5; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/HarveyFoo.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | /** 4 | * @notice The `revert()` denotes a bug that should be caught 5 | * @custom:ref "Harvey: A Greybox Fuzzer for Smart Contracts", by Valentin 6 | * Wüstholz and Maria Christakis, Figure 2, https://arxiv.org/pdf/1905.06944.pdf 7 | */ 8 | contract HarveyFoo { 9 | int256 private x; 10 | int256 private y; 11 | 12 | constructor() { 13 | x = 0; 14 | y = 0; 15 | } 16 | 17 | function Bar() public returns (int256) { 18 | if (x == 42) { 19 | revert(); 20 | return 1; 21 | } 22 | return 0; 23 | } 24 | 25 | function SetY(int256 ny) public { 26 | y = ny; 27 | } 28 | 29 | function IncX() public { 30 | x++; 31 | } 32 | 33 | function CopyY() public { 34 | x = y; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/ILFCrowdsale.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | /** 4 | * @notice `setOwner` is missing a require check, so fuzzer should detect that 5 | * untrusted address can steal funds via a seqence of calls 6 | * @custom:ref "Learning to Fuzz from Symbolic Execution with Application to 7 | * Smart Contracts", by Jingxuan He, Mislav Balunović, Nodar Ambroladze, Petar 8 | * Tsankov, and Martin Vechev, Figure 2, https://files.sri.inf.ethz.ch/website/papers/ccs19-ilf.pdf 9 | */ 10 | contract ILFCrowdsale { 11 | uint256 goal = 100000 * (10**18); // 100,000 ETH 12 | uint256 phase = 0; // 0: Active , 1: Success , 2: Refund 13 | uint256 raised; 14 | uint256 end; // crowdsale deadline 15 | address owner; 16 | mapping(address => uint256) investments; 17 | 18 | constructor() { 19 | end = block.timestamp + 60 days; 20 | owner = msg.sender; 21 | } 22 | 23 | function invest() public payable { 24 | require(phase == 0 && raised < goal); 25 | investments[msg.sender] += msg.value; 26 | raised += msg.value; 27 | } 28 | 29 | function setPhase(uint256 newPhase) public { 30 | require ( 31 | (newPhase == 1 && raised >= goal) || 32 | (newPhase == 2 && raised < goal && block.timestamp > end) 33 | ); 34 | phase = newPhase; 35 | } 36 | 37 | function setOwner(address newOwner) public { 38 | // require (msg.sender == owner); 39 | owner = newOwner; 40 | } 41 | 42 | function withdraw() public { 43 | require(phase == 1); 44 | payable(owner).transfer(raised); 45 | } 46 | 47 | function refund() public { 48 | require(phase == 2); 49 | payable(msg.sender).transfer(investments[msg.sender]); 50 | investments[msg.sender] = 0; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/Benchmarks.t.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "ds-test/test.sol"; 4 | 5 | contract BenchmarksTest is DSTest { 6 | function setUp() public {} 7 | 8 | function testExample() public { 9 | assertTrue(true); 10 | } 11 | } 12 | --------------------------------------------------------------------------------