Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Stateful fuzzing of Gearbox is not an easy endeavour. Some actions in staking, gauge or pool contracts are fairly predictable. Most useful actions that can potentially lead to breaking important invariants are on the credit side though, and boi is it hard to fuzz those! Even verifying that a given multicall works is complicated, generating a random one that is guaranteed not to revert is nearly impossible because of all liquidity, solvency and economic security limits present in the system.
Without much hope to make fuzzer explore all the state space, this test suite's main goal's become to make us think deeply about the invariants: what are they? which ones are important? which actions can, in principle, be used to break a given invariant? After answering those questions, fuzzing in the head doesn't differ much from automated fuzzing (especially since there are no intractable math-heavy invariants).
In terms of organization, the suite consists of multiple test contracts (
invariant/tests/
), each implementing a different scenario of interest. Such contracts first deploy needed parts of the system (invariant/Deployer.sol
) and prepare fuzz handlers (invariant/handlers/
) in thesetUp()
function, and then pick which of existing invariants (invariant/Invariants.sol
) should be asserted.