Integration Testing
Relevant source files
The following files were used as context for generating this wiki page:
Integration testing within the Canon Guard project is designed to validate the interaction between core system components and external protocols under realistic conditions. These tests are executed within blockchain forks (such as Ethereum Mainnet or Optimism) to ensure that the system's multisig enhancements—including dynamic timelocks and on-chain action contracts—behave correctly when integrated with the Safe ecosystem and third-party DeFi protocols.
The testing suite complements unit tests by focusing on the end-to-end lifecycle of a transaction, from queueing an action via a builder to its final execution after the required delay. This ensures that the SafeEntrypoint, ActionHub, and various Action Builders function as a cohesive unit while respecting the security constraints imposed by the OnlyEntrypointGuard and EmergencyModeHook.
Sources: CLAUDE.md:14-25, README.md:43-45
Test Architecture and Environment
Integration tests are primarily located in the test/integration/ directory and are managed using the Foundry development framework. Unlike unit tests, which are isolated from externalities, integration tests utilize network forking to simulate production environments.
Testing Frameworks and Profiles
The project utilizes several tools for different levels of integration and validation:
- Forge (Foundry): Used for running the standard integration test suite against blockchain forks.
- Medusa: Employed for fuzzing campaigns to test system invariants and state transitions.
- Halmos: Used for formal verification and symbolic execution of contract logic.
Sources: CLAUDE.md:27-46, foundry.toml:15-26, package.json:20-27
Execution Workflow
The following diagram illustrates the workflow for executing integration tests within the development environment:
The testing environment is configured via foundry.toml, which specifies the EVM version (Prague) and optimizer settings to ensure test execution matches expected deployment conditions.
Sources: CLAUDE.md:48-52, README.md:43-65, foundry.toml:15-19
Core Integration Components
Integration tests focus on the interaction between the following primary components of the Canon Guard system:
| Component | Role in Integration Testing |
|---|---|
| SafeEntrypoint | Validates time-delayed execution, approval logic, and transaction queueing. |
| ActionHub | Ensures builders are correctly managed and transaction patterns are recognized. |
| Action Builders | Tests specific transaction logic for SimpleActions, SimpleTransfers, and CappedTokenTransfers. |
| OnlyEntrypointGuard | Verifies that transactions cannot bypass the entrypoint's security checks. |
| Safe Integration | Confirms compatibility with @safe-global/safe-contracts. |
Sources: CLAUDE.md:14-25, test/invariants/PROPERTIES.md:5-12, package.json:44-45
Transaction Lifecycle Flow
Integration tests verify the following sequence of events for a standard Canon Guard transaction:
Testing Configuration and Commands
RPC Endpoints
Integration tests require access to blockchain data, which is provided through RPC endpoints defined in the .env file and referenced in foundry.toml.
[rpc_endpoints]
ethereum = "${ETHEREUM_RPC}"
optimism = "${OPTIMISM_RPC}"
Sources: foundry.toml:34-36
Execution Commands
Integration-specific commands are provided via package.json to simplify the testing process:
- Run Integration Tests:
yarn test:integration(Executesforge test --match-contract Integration -vvv) - Run Fuzzing:
yarn test:fuzz(Executesmedusa fuzz) - Run Symbolic Execution:
yarn test:symbolic(Executeshalmos)
Sources: package.json:20-27, README.md:58-65
Invariant and Property Testing
A significant portion of integration validation is handled through invariant testing. These tests ensure that certain global properties remain true regardless of the sequence of actions performed.
Key System Invariants
| Invariant Category | Description |
|---|---|
| Cap & Accounting | invariant_capNeverExceeded: Ensures epoch-based limits for transfers are never bypassed. |
| Timing Logic | invariant_transactionTimingIsCorrect: Validates that expiresAt > executableAt and executableAt >= queuedAt. |
| Approvals | invariant_queuedTransactionsHaveValidApprovals: Transactions must have valid builder/hub approvals. |
| Ghost State | invariant_sanity_ghostStateConsistency: Ensures internal mapping consistency between action hashes and builders. |
Sources: test/invariants/PROPERTIES.md:17-43
Fuzzer Configuration
The Medusa fuzzer is configured in medusa.json to target the FuzzTest contract. It is set with specific parameters to maximize coverage during integration runs:
- Workers: 10
- Call Sequence Length: 100
- Block Delay Max: 60,480 blocks (simulating time passage)
- Timestamp Delay Max: 604,800 seconds
Sources: medusa.json:3-13
Summary of Integration Scope
Integration testing for Canon Guard ensures that the multisig solution is resilient against timing attacks and authorization bypasses. By combining blockchain forking with fuzzing and formal verification, the project validates the complex interactions between the SafeEntrypoint, the Safe smart account, and various Action Builders. The primary objective is to guarantee that timelocks are strictly enforced and that all transactions executed through the guard adhere to the on-chain rules defined by the builders.
Sources: README.md:1-5, CLAUDE.md:7-12, test/invariants/PROPERTIES.md:14-15