What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Use a Foundry fuzz test when you want to find an edge case in one operation; use an invariant campaign when a failure may depend on call order, interactions, or accumulated contract state. Both randomize testing, but they explore different things: fuzz tests vary a test function’s inputs, while invariant campaigns generate sequences of calls and check properties as state changes.
That distinction is about test shape, not a guarantee that one approach finds more bugs. The right choice depends on how you think the failure is triggered—and whether your test harness lets the fuzzer reach that behavior.
What is the difference between Foundry fuzz testing and invariant testing?
A Foundry fuzz test supplies randomized values to a test function. It is useful when the behavior under test can be set up and checked within one controlled scenario—for example, whether a function returns the expected result across unusual inputs.
Free tools Windows power users keep installed
One-click scans. No signup required.
A Forge invariant campaign instead makes randomized calls to selected contracts over a sequence of transactions. It checks declared properties during the campaign, as calls mutate state. Foundry describes this as testing invariant expressions against randomized sequences of calls to predefined contracts. Foundry’s invariant-testing documentation explains the runner and its configuration.
In short: fuzz testing mainly varies what values a test tries; invariant testing varies which calls happen, in what sequence, and with what values.
When should you start with a fuzz test?
Start with a fuzz test when you suspect a bug is tied to an argument, boundary, or result of a single operation under a controlled setup. Random inputs can expose cases that a handful of manually chosen examples miss, while the test’s assertion checks the operation against expected behavior.
- Boundary or unusual input: Try fuzzing values around limits, such as zero, maximum values, or values that change a branch.
- Incorrect result from one call: Compare the function’s result with an expected value or a reference calculation across many inputs.
- Focused regression: Once a failure is found, preserve a clear test for the specific case so the defect remains easy to understand and catch.
When is an invariant campaign a better fit?
Use an invariant campaign when the property should remain true across many state-changing operations, or when the bug may require a particular order of calls or interactions between contracts.
Recommended Free Tools
- Accounting after multiple actions: Check that token supply reconciles with summed account balances after transfers, deposits, withdrawals, or other sequences.
- Protocol relationships: Check a relationship expected to hold as state changes, such as an automated market maker relation like
x*y=k. - Order-dependent behavior: Let the campaign explore different combinations and orderings of operations that may produce a state a single-call test cannot reach.
These examples describe suitable test shapes, not proven vulnerability categories where one method always wins. No controlled head-to-head evidence establishes that Foundry fuzz tests or invariants consistently find more bugs or find them faster.
How do runs, depth, targets, and handlers affect coverage?
An invariant campaign explores only what its harness makes reachable. Foundry’s two main campaign dimensions are runs, the number of generated sequences, and depth, the number of calls in each sequence. A reverting call still uses up a call in the sequence.
- Targets determine which contracts can receive generated calls.
- Senders can vary the caller to simulate multiple actors.
- Selectors and handlers shape which actions are available and how they are issued.
For a complex protocol, a handler can route generated actions through meaningful flows, manage actors, constrain inputs, and track ghost variables for cross-call accounting checks. This can reduce time spent on calls that immediately revert, but the handler itself is part of the test harness and needs scrutiny: incorrect assumptions or incomplete action paths can limit what the campaign explores.
Rank #4
How should you interpret a passing invariant run?
A passing run means the campaign did not falsify its assertions within the configured targets, senders, actions, parameters, and sequence length. It does not prove the property for every possible transaction sequence.
Foundry’s default fail_on_revert setting is false, so a reverted call by itself does not fail the campaign. Review call metrics, reverts, target configuration, and handler behavior to judge whether the intended actions were actually exercised. A green result is less informative if most generated calls revert or important operations are unreachable.
Best Value
There is also a state-isolation detail: each invariant_* function gets a separate EVM executor. Separate invariant functions therefore are not necessarily evaluated against the same evolving state. If several properties must hold together at the same point in a campaign, put their assertions in one invariant function.
How do you choose and keep failures reproducible?
| Suspected trigger or need | Start with | Reason |
|---|---|---|
| Boundary or unusual argument to one function | Fuzz test | Varied inputs can reveal an edge case in a controlled operation. |
| Wrong result for one operation | Fuzz test | The test can compare the result to expected behavior across inputs. |
| Accounting drift after a sequence of actions | Invariant campaign | The property can be checked repeatedly while state changes. |
| Failure depends on call order or contract interaction | Invariant campaign, often with targets and handlers | Generated sequences can vary ordering; handlers can make actions follow meaningful flows. |
| A discovered case needs a clear regression | Either approach, with a focused regression test | Keep the minimized failure in a form that clearly documents the defect. |
Foundry documentation says invariant and fuzz failures are replayed before new campaigns. Even so, a focused regression test is valuable: it records the failure in a concise, reviewable form rather than relying only on future random exploration.
Does “invariant testing” mean the same thing in every tool?
No. “Invariant testing” can refer broadly to property-based testing, not only Forge’s invariant runner. Echidna is a separate property-based fuzzer with multiple modes, including Foundry-style testing; its official project repository documents those modes. Be precise about the tool and mode when describing a test or comparing results. Ethereum.org’s smart-contract testing resources also list tools in the ecosystem.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsQuick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

