DevStation / Marketplace / TimelockController

TimelockController

Enforces a mandatory delay between proposing and executing on-chain actions.

Contract template Official

Proposers schedule operations that can only be executed after the minimum delay elapses. Used by DAOs to give token holders time to react before significant changes take effect.

solidity
1// SPDX-License-Identifier: MIT
2pragma solidity ^0.8.20;
3 
4contract TimelockController {
5 uint256 public immutable minDelay;
6 mapping(address => bool) public isProposer;
7 mapping(address => bool) public isExecutor;
8 mapping(bytes32 => uint256) public timestamps;
9 
10 event Scheduled(bytes32 indexed id, address target, uint256 value, uint256 readyAt);
11 event Executed(bytes32 indexed id);
12 
13 constructor(uint256 minDelaySeconds, address[] memory proposers, address[] memory executors) {
14 minDelay = minDelaySeconds;
15 for (uint256 i = 0; i < proposers.length; i++) isProposer[proposers[i]] = true;
16 for (uint256 i = 0; i < executors.length; i++) isExecutor[executors[i]] = true;
17 }
18 
19 function hashOperation(address target, uint256 value, bytes calldata data, bytes32 salt)
20 public pure returns (bytes32)
21 {
22 return keccak256(abi.encode(target, value, data, salt));
23 }
24 
25 function schedule(address target, uint256 value, bytes calldata data, bytes32 salt, uint256 delay) external {
26 require(isProposer[msg.sender], "NOT_PROPOSER");
27 require(delay >= minDelay, "DELAY_TOO_SHORT");
28 bytes32 id = hashOperation(target, value, data, salt);
29 require(timestamps[id] == 0, "ALREADY_SCHEDULED");
30 timestamps[id] = block.timestamp + delay;
31 emit Scheduled(id, target, value, block.timestamp + delay);
32 }
33 
34 function execute(address target, uint256 value, bytes calldata data, bytes32 salt) external payable {
35 require(isExecutor[msg.sender], "NOT_EXECUTOR");
36 bytes32 id = hashOperation(target, value, data, salt);
37 uint256 ready = timestamps[id];
38 require(ready != 0 && block.timestamp >= ready, "NOT_READY");
39 timestamps[id] = 0;
40 (bool ok, ) = target.call{value: value}(data);
41 require(ok, "CALL_FAILED");
42 emit Executed(id);
43 }
44 
45 receive() external payable {}
46}
DevStation
Loading console…