Common Fuzzing vs Invariant Testing
An objective comparison to help you make the right choice for your security needs.
Common Fuzzing (Stateless)
Traditional fuzz testing that generates random inputs for individual function calls. Each test starts from a clean state — no sequence of transactions, no accumulated state changes.
Strengths
- +
Simple to set up — just add fuzz parameters to test functions
- +
Built into Foundry out of the box (forge test with fuzzed inputs)
- +
Fast execution — each call is independent
- +
Good at finding input validation bugs and boundary conditions
- +
No need to define properties or invariants upfront
Considerations
- -
Each call starts from a clean state — can't find multi-step bugs
- -
Doesn't test interactions between different functions
- -
Misses state-dependent vulnerabilities (reentrancy, accounting drift)
- -
No coverage of realistic user behavior (sequences of deposits, borrows, liquidations)
- -
Limited to single-function correctness
Invariant Testing (Stateful)
Invariant testing generates random sequences of function calls that build on each other. After each sequence, it checks that protocol properties (invariants) still hold — like 'the vault is always solvent' or 'total shares equal total deposits'.
Strengths
- +
Tests sequences of transactions that accumulate state changes
- +
Catches multi-step exploits: reentrancy, flash loan attacks, accounting drift
- +
Properties serve as living documentation of what the protocol guarantees
- +
Finds bugs that only appear after specific sequences of operations
- +
Scales: longer runs explore deeper state space
Considerations
- -
Requires upfront work to define meaningful properties
- -
Steeper learning curve — need to understand protocol invariants
- -
Slower per-iteration (maintaining state between calls)
- -
Property quality determines bug-finding effectiveness
Our Conclusion
Common fuzzing and invariant testing are different levels of the same discipline. Common fuzzing checks 'does this function handle weird inputs?' Invariant testing checks 'does the whole system stay consistent across realistic usage?' For DeFi protocols where bugs emerge from sequences of operations (not single calls), invariant testing is essential. Start with common fuzzing for basic input validation, then graduate to invariant testing for protocol-level guarantees. See our beginner's guide to the Chimera framework.
FAQ
Is common fuzzing enough for my smart contract?
For simple contracts with independent functions, common fuzzing catches a lot. But most DeFi vulnerabilities involve sequences of operations — a deposit followed by a borrow followed by a price change followed by a liquidation. Common fuzzing can't test these sequences. If your contract holds user funds or has multi-step workflows, you need invariant testing.
Can I use both common fuzzing and invariant testing?
Yes, and you should. Common fuzzing is fast feedback on individual functions. Invariant testing covers the interactions between them. Foundry supports both natively, and Recon's Chimera framework makes it straightforward to set up stateful invariant campaigns alongside your existing fuzz tests.
See How We Did This
Liquity
Liquity v2 (BOLD) is a decentralized borrowing protocol and one of the most anticipated DeFi launche...
Centrifuge
Centrifuge is a real-world asset (RWA) protocol that was implementing ERC-7540, the standard for asy...
Corn
Corn is a DeFi protocol built around a vault system for depositing, staking, and distributing reward...