Echidna Explained in Detail
Echidna is a smart contract fuzzer for property-based testing. You write properties that should always hold, and Echidna generates inputs or call sequences that try to break them.
It is especially useful when the bug depends on state built up across several calls rather than one isolated function input.
Smart contract example
In a harness where only alice, bob, and the test contract can hold tokens, an Echidna property might look like this:
function echidna_total_supply_matches_balances() public view returns (bool) {
return totalSupply == balanceOf(alice) + balanceOf(bob) + balanceOf(address(this));
}
If Echidna finds a call sequence that makes the property false, it reports the sequence so the issue can be reproduced.
Echidna in Auditing
Echidna helps auditors express protocol invariants as executable properties and then search for call sequences that violate them.
The quality of the result depends on the property and harness. A weak property can pass while the contract is still broken.
Red flags in code
-
Properties only check trivial facts that cannot fail.
-
Handler contracts allow only one actor or one narrow happy path.
-
Fuzzer inputs are filtered so heavily that coverage stays low.
-
Invariants ignore fees, rounding, liquidations, or paused states that exist in production.
-
Passing Echidna results are treated as a replacement for manual review.
How to test or review it
-
Start with facts like total assets covering total shares, debt staying within collateral limits, only authorized actors changing roles, and paused flows not moving funds.
-
Model multiple actors, repeated calls, and invalid-but-possible user behavior.
-
Review coverage to find functions or branches the fuzzer never reaches.
-
Minimize and replay failing sequences before deciding impact.
-
Pair Echidna with Slither and targeted unit tests for a stronger audit workflow.