Dynamic Timelocks
Relevant source files
The following files were used as context for generating this wiki page:
Dynamic Timelocks are a core security feature of the Canon Guard (formerly Safer Safe) multisig solution. They provide a flexible mechanism for queuing and executing transactions with on-chain enforcement of time delays, ensuring that multisig operations are transparent, predictable, and resilient against immediate unauthorized changes.
This system is built on top of Safe smart contracts and utilizes specialized "Actions" contracts to define transaction patterns. By incorporating dynamic delays, the system allows for different security tiers depending on the approval status and the nature of the action being performed.
Sources: README.md:1-5, CLAUDE.md:7-12
Architecture and Components
The Dynamic Timelock mechanism is integrated into the SafeEntrypoint, which serves as the primary gateway for executing transactions. The system manages transaction lifecycles through three distinct timestamps: queuedAt, executableAt, and expiresAt.
Lifecycle States
Transactions move through a state machine enforced by the timelock logic:
- Queued: The transaction is registered in the system.
- Executable: The transaction has passed its required delay.
- Expired: The transaction is no longer valid for execution.
Sources: CLAUDE.md:15-16, test/invariants/PROPERTIES.md:28-30
Key Technical Parameters
The system utilizes specific delay constants to manage the "dynamic" nature of the timelocks:
| Parameter | Description |
|---|---|
SHORT_TX_EXECUTION_DELAY | Reduced delay used for pre-approved transactions or specific action builders. |
LONG_TX_EXECUTION_DELAY | Standard delay used for non-pre-approved or high-risk transactions. |
TX_EXPIRY_DELAY | The window of time after executableAt during which the transaction remains valid. |
Sources: test/invariants/PROPERTIES.md:31-32, test/invariants/PROPERTIES.md:46-52
Transaction Flow
The following diagram illustrates the lifecycle of a transaction within the Dynamic Timelock system, from initial queueing to final execution or expiration.
The diagram shows the time-gated progression of a transaction through the SafeEntrypoint.
Sources: test/invariants/PROPERTIES.md:28-30, CLAUDE.md:15-16
Approval-Based Delay Logic
The "Dynamic" aspect of the timelock refers to the system's ability to adjust the required delay based on the transaction's context and approval status. Transactions involving approved "Action Builders" or "Action Hubs" may benefit from shorter execution windows.
Delay Selection Logic
- Pre-Approved Transactions: Use the
SHORT_TX_EXECUTION_DELAYat the time of queueing. - Standard Transactions: Default to the
LONG_TX_EXECUTION_DELAYto provide a longer window for community or admin intervention.
Sources: test/invariants/PROPERTIES.md:23-26, test/invariants/PROPERTIES.md:31-32
Sequence of determining the applicable timelock delay during the queueing process.
Sources: CLAUDE.md:15-20, test/invariants/PROPERTIES.md:23-26
Security Invariants
To ensure the integrity of the timelock mechanism, the system enforces several core invariants through continuous testing (e.g., Medusa fuzzing):
- Timing Consistency: The system always ensures that
expiresAt > executableAtandexecutableAt >= queuedAt. - Approval Validity: Queued transactions must only exist for action builders or hubs with valid, non-expired approvals.
- Delay Enforcement: Pre-approved transactions are strictly limited to using the short delay, preventing them from bypassing the standard queuing process without proper credentials.
- Expiry Constraints: Approval expiries are capped at a maximum duration (
MAX_APPROVAL_DURATION) to prevent indefinite authorizations.
Sources: test/invariants/PROPERTIES.md:23-32, package.json:28
Implementation Configuration
The project utilizes Solidity 0.8.30 and is optimized for the Prague EVM version. High optimizer runs (10,000) are used to ensure efficient on-chain execution of the timelock logic.
| Component | Setting |
|---|---|
| Solidity Version | 0.8.30 |
| EVM Version | Prague |
| Optimizer Runs | 10,000 |
| Via IR | Enabled for optimized/test profiles |
Sources: foundry.toml:13-22, package.json:41-44
Summary
Dynamic Timelocks in Canon Guard provide a programmable security layer for multisig wallets. By differentiating between standard and pre-approved actions, the system balances operational efficiency with rigorous security. The on-chain enforcement of executableAt and expiresAt ensures that no transaction can be executed prematurely or remain pending indefinitely, while the integration with ActionHub allows for granular control over which entities can trigger shorter delays.