Smart-contract security & auditing

fuzzing

Fuzzing tests a contract by throwing large numbers of random or semi-random inputs at it and watching for a property that breaks, instead of relying on a few hand-written example cases. A human writes a handful of tests covering the situations they thought of; a fuzzer explores the vast space of inputs they did not, surfacing the edge cases, boundary values, and strange combinations where assumptions quietly fail. It is one of the highest-yield automated techniques for finding real smart-contract bugs.

In practice, smart-contract fuzzing is property-based: rather than asserting a fixed expected output, you assert a property that should hold for all inputs, and the fuzzer searches for any input that falsifies it. Coverage-guided fuzzers steer their randomness toward unexplored code paths, and on finding a failure they shrink the counterexample to the smallest input that still triggers it. The dominant tools are Echidna, Foundry's built-in fuzzer (parameter fuzzing on test arguments and stateful invariant fuzzing), and Medusa.

Fuzzing is only as good as the properties you assert. A fuzz test with no meaningful check merely confirms the code runs without crashing; the skill is encoding what must never happen, no value created from nothing, no user able to withdraw more than they deposited, as a precise assertion the fuzzer can try to violate. Random exploration can also miss states buried behind long, specific call sequences, which is why stateful invariant fuzzing and well-designed handlers matter, and why fuzzing complements rather than replaces formal verification.

// Foundry parameter fuzzing
function testFuzz_NoFreeMoney(uint96 amount) public {
    vm.assume(amount > 0);
    vault.deposit{value: amount}();
    uint256 before = address(this).balance;
    vault.withdraw(amount);
    assertLe(address(this).balance, before + amount);
}

Assert a property; let the fuzzer search for a counterexample.

Fuzzing is only as good as the properties you assert. A fuzzer with no meaningful invariant just confirms the code runs; the skill is encoding what must never happen as a checkable assertion the tool can attack.

Also called
property-based testing屬性測試