Timelock Contract Development
Compound Finance introduced the timelock contract into the mainstream. Their Timelock.sol — a two-day delay before executing any protocol changes — became the standard after several DeFi protocols lost funds due to instant admin operations. Now timelock is a basic requirement from any auditor and the first question at listing.
The idea is simple: an administrative action isn't executed immediately but is queued with a minimum delay. Users see the upcoming change and can exit the protocol if it doesn't suit them. It's not a panacea, but it's an honest contract with users.
Two Implementations: OpenZeppelin TimelockController vs Custom Contract
OpenZeppelin TimelockController — the first choice for most cases. Supports roles (proposer, executor, canceller), batch operation execution, minimum delay verification. Integrates with Governor for on-chain voting. Well-tested, used by Compound, Uniswap, Aave.
Custom timelock is needed when:
- Different delays are required for different operation types (e.g., 48 hours for fee change, 7 days for admin change)
- Integration with multisig without Governor is needed
- Specific cancellation or emergency operation logic
We work with both variants. For a new protocol, we usually start with TimelockController — it covers 80% of cases.
Critical Implementation Details
Minimum Delay
48 hours — minimum for a production protocol. Less — users don't have time to react. DeFi protocol standard: 24-72 hours for parameters, 7 days for owner/admin change.
uint256 public constant MIN_DELAY = 2 days;
uint256 public constant MAX_DELAY = 30 days;
Replay Attack Prevention
Each operation is identified by a hash of parameters plus salt. Without salt, the same operation (e.g., setFee(100)) can only be queued once. With salt — any number of times. Ensure the client understands this behavior.
Emergency Functions
Almost always you need a bypass for critical situations — if a vulnerability is found, you can't wait 48 hours. A Pausable with separate role — standard solution. But the pauser itself should be limited: it only stops, doesn't change logic.
Integration with Governor
For full on-chain governance the chain looks like this: Governor → TimelockController → Protocol. Voting happens in Governor, the winning proposal is queued in TimelockController, executed after delay.
OpenZeppelin provides GovernorTimelockControl — an adapter linking these two contracts. The main mistake is giving TimelockController direct admin access to the protocol, bypassing Governor. This makes voting decorative.
Timeline
Deploying TimelockController with role configuration — 1 day. Custom timelock with multiple delay levels — 2-3 days. Integration with existing Governor — 1-2 days depending on protocol architecture. Tests are included in the estimate.







