├── .gitignore ├── .gitmodules ├── README.md ├── foundry.toml ├── script └── Counter.s.sol ├── src └── MyContract.sol └── test └── MyContractTest.t.sol /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | !/broadcast 7 | /broadcast/*/31337/ 8 | /broadcast/**/dry-run/ 9 | 10 | # Docs 11 | docs/ 12 | 13 | # Dotenv file 14 | .env 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/forge-std"] 2 | path = lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | branch = v1.5.2 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Fuzzing Example 3 | 4 | # Getting Started 5 | 6 | ## Requirements 7 | 8 | Please install the following: 9 | 10 | - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) 11 | - You'll know you've done it right if you can run `git --version` 12 | - [Foundry / Foundryup](https://github.com/gakonst/foundry) 13 | - This will install `forge`, `cast`, and `anvil` 14 | - You can test you've installed them right by running `forge --version` and get an output like: `forge 0.2.0 (f016135 2022-07-04T00:15:02.930499Z)` 15 | - To get the latest of each, just run `foundryup` 16 | 17 | And you probably already have `make` installed... but if not [try looking here.](https://askubuntu.com/questions/161104/how-do-i-install-make) 18 | 19 | ## Quickstart 20 | 21 | ```sh 22 | git clone https://github.com/patrickalphac/fuzzing-example 23 | cd fuzzing-example 24 | forge install 25 | ``` 26 | 27 | ## Testing 28 | 29 | ``` 30 | forge test 31 | ``` 32 | 33 | You'll see it currently fails! 34 | 35 | 36 | # Contributing 37 | 38 | Contributions are always welcome! Open a PR or an issue! 39 | 40 | 41 | ## Resources 42 | 43 | - [Foundry Documentation](https://book.getfoundry.sh/) 44 | 45 | -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | [fuzz] 7 | runs = 1000 8 | 9 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config -------------------------------------------------------------------------------- /script/Counter.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "forge-std/Script.sol"; 5 | 6 | contract CounterScript is Script { 7 | function setUp() public {} 8 | 9 | function run() public { 10 | vm.broadcast(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/MyContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract MyContract { 5 | uint256 public shouldAlwaysBeZero = 0; 6 | 7 | uint256 private hiddenValue = 0; 8 | 9 | function doStuff(uint256 data) public { 10 | if (data == 2) { 11 | shouldAlwaysBeZero = 1; 12 | } 13 | if (hiddenValue == 7) { 14 | shouldAlwaysBeZero = 1; 15 | } 16 | hiddenValue = data; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/MyContractTest.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import {MyContract} from "../src/MyContract.sol"; 5 | import {Test} from "forge-std/Test.sol"; 6 | import {StdInvariant} from "forge-std/StdInvariant.sol"; 7 | 8 | contract MyContractTest is StdInvariant, Test { 9 | MyContract exampleContract; 10 | 11 | function setUp() public { 12 | exampleContract = new MyContract(); 13 | targetContract(address(exampleContract)); 14 | } 15 | 16 | function testIsAlwaysZeroUnit() public { 17 | uint256 data = 0; 18 | exampleContract.doStuff(data); 19 | assert(exampleContract.shouldAlwaysBeZero() == 0); 20 | } 21 | 22 | function testIsAlwaysZeroFuzz(uint256 randomData) public { 23 | // uint256 data = 0; // commented out line 24 | exampleContract.doStuff(randomData); 25 | assert(exampleContract.shouldAlwaysBeZero() == 0); 26 | } 27 | 28 | function testIsAlwaysZeroUnitManyCalls() public { 29 | uint256 data = 7; 30 | exampleContract.doStuff(data); 31 | assert(exampleContract.shouldAlwaysBeZero() == 0); 32 | 33 | data = 0; 34 | exampleContract.doStuff(data); 35 | assert(exampleContract.shouldAlwaysBeZero() == 0); // this would fail 36 | } 37 | 38 | function invariant_testAlwaysReturnsZero() public { 39 | assert(exampleContract.shouldAlwaysBeZero() == 0); 40 | } 41 | } 42 | --------------------------------------------------------------------------------