Testing Strategy Overview
Relevant source files
The following files were used as context for generating this wiki page:
The testing strategy for Canon Guard is a multi-layered approach designed to ensure the security and reliability of its on-chain multisig enhancement features. It combines standard unit and integration testing with advanced verification methods, including invariant fuzzing using Medusa and symbolic execution using Halmos.
Sources: README.md:16-18, CLAUDE.md:68-73
Testing Tiers and Tools
The project categorizes testing into four distinct levels of verification, each targeting different aspects of the smart contract system.
1. Unit Testing
Unit tests are isolated from externalities and focus on individual contract logic. They utilize the Foundry framework and include bulloak for checking .tree test specification files.
Sources: README.md:16, CLAUDE.md:32, package.json:16
2. Integration Testing
Integration tests run in a blockchain fork environment (specifically Ethereum and Optimism) to validate interactions between Canon Guard components and the underlying Safe multisig infrastructure.
Sources: README.md:16, CLAUDE.md:33, foundry.toml:34-35
3. Invariant Fuzzing (Medusa)
The system uses Medusa for property-based testing. This involves executing long sequences of random transactions to ensure specific security invariants remain true across all possible states. Invariant testing is configured with a 1000-second timeout and persists its findings in a corpus directory.
Sources: test/invariants/PROPERTIES.md:3-5, foundry.toml:23-28, medusa.json:3-10
4. Symbolic Execution (Halmos)
Symbolic execution via Halmos is used to mathematically prove properties about the contracts by exploring all possible execution paths simultaneously.
Sources: README.md:35, CLAUDE.md:73, package.json:23
Test Execution Workflow
The following diagram illustrates the flow of the testing pipeline from source code to various verification engines.
Sources: CLAUDE.md:32-35, package.json:14-25
Invariant Testing Scope
The invariant suite focuses on protecting the core system state, prioritizing "frozen" state prevention and non-reversion over basic functionality.
Core Security Invariants
| Category | Invariant Name | Description |
|---|---|---|
| Caps | invariant_capNeverExceeded | Ensures cap limits are never exceeded in any hub, accounting for epoch boundaries. |
| State | invariant_sanity_ghostStateConsistency | Validates that every hash in ghost state maps to a non-zero action builder address. |
| Approvals | invariant_queuedTransactionsHaveValidApprovals | Confirms queued transactions only exist for approved builders/hubs. |
| Timing | invariant_transactionTimingIsCorrect | Enforces logic: expiresAt > executableAt and executableAt >= queuedAt. |
| Delays | invariant_preApprovedTransactionsUsedShortDelay | Ensures pre-approved transactions utilize the SHORT_TX_EXECUTION_DELAY. |
Sources: test/invariants/PROPERTIES.md:9-25
Fuzzing Configuration
The Medusa configuration defines the parameters for the fuzzing campaign to ensure deep state exploration.
{
"workers": 10,
"callSequenceLength": 100,
"blockTimestampDelayMax": 604800,
"stopOnFailedTest": true
}
Sources: medusa.json:4-44
Development and CI Commands
Developers use specific scripts to trigger different parts of the testing strategy.
| Command | Purpose |
|---|---|
yarn test | Runs the full suite of unit and integration tests. |
yarn test:unit:deep | Runs unit tests with 5,000 fuzz runs (5x the default). |
yarn test:fuzz | Initiates the Medusa invariant fuzzing campaign. |
yarn test:symbolic | Executes Halmos symbolic proofs. |
yarn coverage | Generates a coverage report using Forge. |
Sources: package.json:14-25, CLAUDE.md:44-51
Conclusion
Canon Guard's testing strategy is built for high-assurance DeFi applications. By combining isolated unit tests, forked integration tests, stateful invariant fuzzing, and formal symbolic execution, the project ensures that the dynamic timelocks and on-chain action builders operate within strict security boundaries.
Sources: CLAUDE.md:1-20, README.md:1-5