pip3 install -U eth-wakeVerify installation by running wake - it should display Wake usage information.
Install Foundry for the Anvil testing environment:
curl -L https://foundry.paradigm.xyz | bash
source ~/.bashrc && foundryupWindows Users: See Windows Installation Guide
Install the Solidity Python Extension Pack, which includes:
- Solidity (Wake) - Remix-like UI, static analysis, Solidity support
- Python - Python language support
wake upInitializes your Wake environment with default configuration.
wake test tests/test_vault_unit.pyThis displays a detailed call trace and test results.
The wake.toml file controls your testing environment.
Testing Environment:
[testing]
cmd = "anvil" # Options: anvil, revm, or othersCompiler Settings:
[compiler.solc]
exclude_paths = ["script", ".venv", "venv", "node_modules", "lib", "test"]
include_paths = ["node_modules"]
remappings = []wake up automatically configures remappings. See compiler documentation for details.
Detectors: wake detect - Lists available security detectors
Printers: wake print - Lists available code analysis printers
Results will be printerd into the console and stored in .wake/. The VSCode extension displays detector results inline.
- SingleTokenVault - Contract under test
- Vault Unit Test - Example
depositfunction test
wake test tests/test_vault_unit.pyRun specific test function:
wake test tests/test_wake_usage.py::test_accountCall Traces:
print(tx.call_trace)Events:
print(tx.events)Debug Mode: Interactive debugging on exceptions
wake test tests/test_vault_unit.py -dConsole Logging:
import "wake/console.sol"; // add this to the top of your file
console.log(variableName);
console.logBytes32(bytes32(0));Generate Python types for better IDE support:
wake init pytypes- Wake Usage Tests - Core testing features
- Wake Signing Tests - Signing and EIP-712 examples
Using Token Unit Test as reference, extend test_vault_unit.py:
- Look at the Vault Unit Test for examples.
- Examine the Vault Contract to understand the contract's functionality.
- Implement your own test cases in test_vault_unit.py:
- Test event emission in deposit
- Test ERC20 balance changes using
token.balanceOf() - Test withdrawal functionality
- Test deposit limits
- Add additional custom test scenarios
Manually guided fuzzing combines random inputs with structured test scenarios. See this blog post for a more detailed overview.
Create a class inheriting from FuzzTest:
class VaultFuzz(FuzzTest):
# Implementation here
VaultFuzz.run(sequences_count=1, flows_count=100)The base FuzzTest class has a run method that will run the test, where you can specify the number of sequences and flows.
graph TD
A["Start"] --> B["Run pre_sequence function"]
B --> C["Execute random @flow function"]
C --> D["Run all @invariant functions"]
D --> E{"flows_count<br/>reached?"}
E -->|No| C
E -->|Yes| F{"sequences_count<br/>reached?"}
F -->|No<br/>(Reset the chain state)| B
F -->|Yes| G["End"]
Flows are:
- Sequence of actions or transactions
- Defined by the tester
- Tester writes code to generate random arguments for the transaction call
Good practices:
- One transaction call per flow function
- Assert all expected events and behaviors
- Generate random arguments for transaction calls
Purpose: Verify contract state consistency after each flow.
Function: Compare contract variables with expected values tracked in Python's mirrored test state.
Use specific seed to reproduce the issue:
wake test tests/test_fuzz.py -S 0abcdefg...(The seed is also printed in the console at the beginning of the test.)
Multi-process testing:
wake test tests/test_fuzz.py -P 4Use breakpoint to stop execution and inspect the state:
breakpoint()Crash logs: Located in .wake/logs/crashes - contains random state for reproduction.
After encountering an error in fuzzing, it might be hard to find what caused this error. Shrinking automatically removes redundant flow executions to find the minimal test case that reproduces the error.
Run shrinking:
wake test tests/test_fuzz.py -SHExecute shrunken test:
wake test tests/test_fuzz.py -SRUsing Fuzz Template as reference, implement Vault Fuzz:
- Get ideas from the fuzz test template Fuzz Template
- Examine the SingleTokenVault contract
- Implement fuzz test in Vault Fuzz:
- Create
pre_sequencefunction and define contracts. - Create
@flowfunction forSingleTokenVault.depositfunction. - Add limit data in the Python test that stores limit values.
- Add balance data in the Python test that stores deposited values.
- Create
@invariantfunction for checking the above balance. - Create
@flowfunction forSingleTokenVault.withdrawfunction. - Add ERC20 token balance data in Python test.
- Create
@invariantfunction for checking the above balance. - Create
@flowfor all state-changing functions. - Add your own custom flow or invariant with your imagination!
- Create
Solution: Vault Fuzz Solution
