Closed ElliotFriedman closed 1 year ago
In our experience echidna tends to be a much stronger fuzzer compared to the build-in fuzzer that is used by Forge/dapptools.
Echidna uses slither to symbolically find all potential inputs
contract HelloWorld {
function hello(string memory who) public pure returns (string memory) {
if (compare(who, "Marco") == 0) { // compare code left out, it's a string comparison method that can be solved by a symbolic solver
return "Meh";
}
return string(abi.encodePacked("Hello, ", who, "."));
}
function testStringMatch(string calldata str) external view returns (bool) {
assert (keccak256(abi.encodePacked(hello(str))) == keccak256(abi.encodePacked(string.concat("Hello, ", string(abi.encodePacked(str)), "."))));
}
}
Echidna almost instantly proposes Marco as an input here while Forge is absolutely blind to it (even if you move the input of hello to an int, Forge will only find obvious matches like "1" due to it not using symbolic analysis.
We recommend to use echidna in assertion breaking mode most usually. The detection rate is much higher than Forge and when using the assertion mode the developer UX is not too much worse than Forge.
Examples of fuzz tests I've found helpful: https://github.com/fei-protocol/flywheel-v2/blob/main/src/test/FlywheelTest.sol https://github.com/fei-protocol/flywheel-v2/blob/main/src/test/token/ERC20GaugesTest.t.sol