-
Notifications
You must be signed in to change notification settings - Fork 0
/
timelock.sol
102 lines (84 loc) · 3 KB
/
timelock.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import "hardhat/console.sol";
//cast sig "changeValue(uint256)"
//0xf965e32e
//cast abi-encode "changeValue(uint256)" 5
//0x0000000000000000000000000000000000000000000000000000000000000005
//QueueProposal() params
//0xf8e81D47203A594245E36C48e151709F0C19fBe8, "0xf965e32e", "0x0000000000000000000000000000000000000000000000000000000000000005", 1664440900
contract Timelock {
error ProposalListed();
error ProposalTSError();
error ProposalExecuted();
error OnlyOwner();
error ProposalNotListed();
error ProposalTimeExpired();
error ExecutionFailed();
address public owner;
uint256 public constant MIN_DELAY = 10 seconds;
uint256 public constant MAX_DELAY = 1000 seconds;
uint256 public constant GRACE_PERIOD = 1000 seconds;
struct Proposal {
bool listed;
bool executed;
}
mapping(bytes32 => Proposal) public Proposals;
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
if(msg.sender != owner) revert OnlyOwner();
_;
}
function getBlockTimeStamp() external view returns(uint256) {
return block.timestamp;
}
function QueueProposal(address _addr, bytes4 _func, bytes memory _param, uint256 _ts)
external onlyOwner returns(bytes32 _hash) {
_hash = getHash(_addr, _func, _param, _ts);
if(Proposals[_hash].listed == true)
revert ProposalListed();
if(Proposals[_hash].executed == true)
revert ProposalExecuted();
if(_ts < (block.timestamp+MIN_DELAY) || _ts > (block.timestamp+MAX_DELAY))
revert ProposalTSError();
Proposals[_hash].listed = true;
}
function ExecuteProposal(address _addr, bytes4 _func, bytes memory _param, uint256 _ts)
external {
bytes32 _hash = getHash(_addr, _func, _param, _ts);
if(Proposals[_hash].listed == false)
revert ProposalNotListed();
if(Proposals[_hash].executed == true)
revert ProposalExecuted();
if(block.timestamp > (_ts+GRACE_PERIOD))
revert ProposalTimeExpired();
(bool success, bytes memory log) = _addr.call(abi.encodePacked(_func, _param));
if(success) {
Proposals[_hash].executed = true;
}
else {
revert ExecutionFailed();
}
}
function getHash(address _addr, bytes4 _func, bytes memory _param, uint256 _ts) internal pure
returns(bytes32) {
return keccak256(abi.encodePacked(_addr, _func, _param, _ts));
}
}
contract Test {
error NotAuth();
uint256 public value;
address public timeLock;
constructor(address _timeLock) {
timeLock = _timeLock;
value = 1;
console.log("constructor");
}
function changeValue(uint256 _value) external {
if(msg.sender != timeLock) revert NotAuth();
console.log("The value is ", _value);
value = _value;
}
}