@venusprotocol/governance-contracts 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contracts/Governance/AccessControlManager.sol +97 -0
- package/contracts/Governance/AccessControlledV5.sol +56 -0
- package/contracts/Governance/AccessControlledV8.sol +83 -0
- package/contracts/Governance/GovernorBravoDelegate.sol +516 -0
- package/contracts/Governance/GovernorBravoDelegator.sol +92 -0
- package/contracts/Governance/GovernorBravoInterfaces.sol +234 -0
- package/contracts/Governance/IAccessControlManagerV5.sol +120 -0
- package/contracts/Governance/IAccessControlManagerV8.sol +22 -0
- package/contracts/Governance/Timelock.sol +152 -0
- package/contracts/Utils/SafeMath.sol +163 -0
- package/contracts/test/MockAccessTest.sol +13 -0
- package/contracts/test/MockImports.sol +8 -0
- package/package.json +100 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
pragma solidity ^0.5.16;
|
|
2
|
+
pragma experimental ABIEncoderV2;
|
|
3
|
+
|
|
4
|
+
contract GovernorBravoEvents {
|
|
5
|
+
/// @notice An event emitted when a new proposal is created
|
|
6
|
+
event ProposalCreated(
|
|
7
|
+
uint id,
|
|
8
|
+
address proposer,
|
|
9
|
+
address[] targets,
|
|
10
|
+
uint[] values,
|
|
11
|
+
string[] signatures,
|
|
12
|
+
bytes[] calldatas,
|
|
13
|
+
uint startBlock,
|
|
14
|
+
uint endBlock,
|
|
15
|
+
string description,
|
|
16
|
+
uint8 proposalType
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
/// @notice An event emitted when a vote has been cast on a proposal
|
|
20
|
+
/// @param voter The address which casted a vote
|
|
21
|
+
/// @param proposalId The proposal id which was voted on
|
|
22
|
+
/// @param support Support value for the vote. 0=against, 1=for, 2=abstain
|
|
23
|
+
/// @param votes Number of votes which were cast by the voter
|
|
24
|
+
/// @param reason The reason given for the vote by the voter
|
|
25
|
+
event VoteCast(address indexed voter, uint proposalId, uint8 support, uint votes, string reason);
|
|
26
|
+
|
|
27
|
+
/// @notice An event emitted when a proposal has been canceled
|
|
28
|
+
event ProposalCanceled(uint id);
|
|
29
|
+
|
|
30
|
+
/// @notice An event emitted when a proposal has been queued in the Timelock
|
|
31
|
+
event ProposalQueued(uint id, uint eta);
|
|
32
|
+
|
|
33
|
+
/// @notice An event emitted when a proposal has been executed in the Timelock
|
|
34
|
+
event ProposalExecuted(uint id);
|
|
35
|
+
|
|
36
|
+
/// @notice An event emitted when the voting delay is set
|
|
37
|
+
event VotingDelaySet(uint oldVotingDelay, uint newVotingDelay);
|
|
38
|
+
|
|
39
|
+
/// @notice An event emitted when the voting period is set
|
|
40
|
+
event VotingPeriodSet(uint oldVotingPeriod, uint newVotingPeriod);
|
|
41
|
+
|
|
42
|
+
/// @notice Emitted when implementation is changed
|
|
43
|
+
event NewImplementation(address oldImplementation, address newImplementation);
|
|
44
|
+
|
|
45
|
+
/// @notice Emitted when proposal threshold is set
|
|
46
|
+
event ProposalThresholdSet(uint oldProposalThreshold, uint newProposalThreshold);
|
|
47
|
+
|
|
48
|
+
/// @notice Emitted when pendingAdmin is changed
|
|
49
|
+
event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin);
|
|
50
|
+
|
|
51
|
+
/// @notice Emitted when pendingAdmin is accepted, which means admin is updated
|
|
52
|
+
event NewAdmin(address oldAdmin, address newAdmin);
|
|
53
|
+
|
|
54
|
+
/// @notice Emitted when the new guardian address is set
|
|
55
|
+
event NewGuardian(address oldGuardian, address newGuardian);
|
|
56
|
+
|
|
57
|
+
/// @notice Emitted when the maximum number of operations in one proposal is updated
|
|
58
|
+
event ProposalMaxOperationsUpdated(uint oldMaxOperations, uint newMaxOperations);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
contract GovernorBravoDelegatorStorage {
|
|
62
|
+
/// @notice Administrator for this contract
|
|
63
|
+
address public admin;
|
|
64
|
+
|
|
65
|
+
/// @notice Pending administrator for this contract
|
|
66
|
+
address public pendingAdmin;
|
|
67
|
+
|
|
68
|
+
/// @notice Active brains of Governor
|
|
69
|
+
address public implementation;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @title Storage for Governor Bravo Delegate
|
|
74
|
+
* @notice For future upgrades, do not change GovernorBravoDelegateStorageV1. Create a new
|
|
75
|
+
* contract which implements GovernorBravoDelegateStorageV1 and following the naming convention
|
|
76
|
+
* GovernorBravoDelegateStorageVX.
|
|
77
|
+
*/
|
|
78
|
+
contract GovernorBravoDelegateStorageV1 is GovernorBravoDelegatorStorage {
|
|
79
|
+
/// @notice DEPRECATED The delay before voting on a proposal may take place, once proposed, in blocks
|
|
80
|
+
uint public votingDelay;
|
|
81
|
+
|
|
82
|
+
/// @notice DEPRECATED The duration of voting on a proposal, in blocks
|
|
83
|
+
uint public votingPeriod;
|
|
84
|
+
|
|
85
|
+
/// @notice DEPRECATED The number of votes required in order for a voter to become a proposer
|
|
86
|
+
uint public proposalThreshold;
|
|
87
|
+
|
|
88
|
+
/// @notice Initial proposal id set at become
|
|
89
|
+
uint public initialProposalId;
|
|
90
|
+
|
|
91
|
+
/// @notice The total number of proposals
|
|
92
|
+
uint public proposalCount;
|
|
93
|
+
|
|
94
|
+
/// @notice The address of the Venus Protocol Timelock
|
|
95
|
+
TimelockInterface public timelock;
|
|
96
|
+
|
|
97
|
+
/// @notice The address of the Venus governance token
|
|
98
|
+
XvsVaultInterface public xvsVault;
|
|
99
|
+
|
|
100
|
+
/// @notice The official record of all proposals ever proposed
|
|
101
|
+
mapping(uint => Proposal) public proposals;
|
|
102
|
+
|
|
103
|
+
/// @notice The latest proposal for each proposer
|
|
104
|
+
mapping(address => uint) public latestProposalIds;
|
|
105
|
+
|
|
106
|
+
struct Proposal {
|
|
107
|
+
/// @notice Unique id for looking up a proposal
|
|
108
|
+
uint id;
|
|
109
|
+
/// @notice Creator of the proposal
|
|
110
|
+
address proposer;
|
|
111
|
+
/// @notice The timestamp that the proposal will be available for execution, set once the vote succeeds
|
|
112
|
+
uint eta;
|
|
113
|
+
/// @notice the ordered list of target addresses for calls to be made
|
|
114
|
+
address[] targets;
|
|
115
|
+
/// @notice The ordered list of values (i.e. msg.value) to be passed to the calls to be made
|
|
116
|
+
uint[] values;
|
|
117
|
+
/// @notice The ordered list of function signatures to be called
|
|
118
|
+
string[] signatures;
|
|
119
|
+
/// @notice The ordered list of calldata to be passed to each call
|
|
120
|
+
bytes[] calldatas;
|
|
121
|
+
/// @notice The block at which voting begins: holders must delegate their votes prior to this block
|
|
122
|
+
uint startBlock;
|
|
123
|
+
/// @notice The block at which voting ends: votes must be cast prior to this block
|
|
124
|
+
uint endBlock;
|
|
125
|
+
/// @notice Current number of votes in favor of this proposal
|
|
126
|
+
uint forVotes;
|
|
127
|
+
/// @notice Current number of votes in opposition to this proposal
|
|
128
|
+
uint againstVotes;
|
|
129
|
+
/// @notice Current number of votes for abstaining for this proposal
|
|
130
|
+
uint abstainVotes;
|
|
131
|
+
/// @notice Flag marking whether the proposal has been canceled
|
|
132
|
+
bool canceled;
|
|
133
|
+
/// @notice Flag marking whether the proposal has been executed
|
|
134
|
+
bool executed;
|
|
135
|
+
/// @notice Receipts of ballots for the entire set of voters
|
|
136
|
+
mapping(address => Receipt) receipts;
|
|
137
|
+
/// @notice The type of the proposal
|
|
138
|
+
uint8 proposalType;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/// @notice Ballot receipt record for a voter
|
|
142
|
+
struct Receipt {
|
|
143
|
+
/// @notice Whether or not a vote has been cast
|
|
144
|
+
bool hasVoted;
|
|
145
|
+
/// @notice Whether or not the voter supports the proposal or abstains
|
|
146
|
+
uint8 support;
|
|
147
|
+
/// @notice The number of votes the voter had, which were cast
|
|
148
|
+
uint96 votes;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/// @notice Possible states that a proposal may be in
|
|
152
|
+
enum ProposalState {
|
|
153
|
+
Pending,
|
|
154
|
+
Active,
|
|
155
|
+
Canceled,
|
|
156
|
+
Defeated,
|
|
157
|
+
Succeeded,
|
|
158
|
+
Queued,
|
|
159
|
+
Expired,
|
|
160
|
+
Executed
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/// @notice The maximum number of actions that can be included in a proposal
|
|
164
|
+
uint public proposalMaxOperations;
|
|
165
|
+
|
|
166
|
+
/// @notice A privileged role that can cancel any proposal
|
|
167
|
+
address public guardian;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
contract GovernorBravoDelegateStorageV2 is GovernorBravoDelegateStorageV1 {
|
|
171
|
+
enum ProposalType {
|
|
172
|
+
NORMAL,
|
|
173
|
+
FASTTRACK,
|
|
174
|
+
CRITICAL
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
struct ProposalConfig {
|
|
178
|
+
/// @notice The delay before voting on a proposal may take place, once proposed, in blocks
|
|
179
|
+
uint256 votingDelay;
|
|
180
|
+
/// @notice The duration of voting on a proposal, in blocks
|
|
181
|
+
uint256 votingPeriod;
|
|
182
|
+
/// @notice The number of votes required in order for a voter to become a proposer
|
|
183
|
+
uint256 proposalThreshold;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/// @notice mapping containing configuration for each proposal type
|
|
187
|
+
mapping(uint => ProposalConfig) public proposalConfigs;
|
|
188
|
+
|
|
189
|
+
/// @notice mapping containing Timelock addresses for each proposal type
|
|
190
|
+
mapping(uint => TimelockInterface) public proposalTimelocks;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
interface TimelockInterface {
|
|
194
|
+
function delay() external view returns (uint);
|
|
195
|
+
|
|
196
|
+
function GRACE_PERIOD() external view returns (uint);
|
|
197
|
+
|
|
198
|
+
function acceptAdmin() external;
|
|
199
|
+
|
|
200
|
+
function queuedTransactions(bytes32 hash) external view returns (bool);
|
|
201
|
+
|
|
202
|
+
function queueTransaction(
|
|
203
|
+
address target,
|
|
204
|
+
uint value,
|
|
205
|
+
string calldata signature,
|
|
206
|
+
bytes calldata data,
|
|
207
|
+
uint eta
|
|
208
|
+
) external returns (bytes32);
|
|
209
|
+
|
|
210
|
+
function cancelTransaction(
|
|
211
|
+
address target,
|
|
212
|
+
uint value,
|
|
213
|
+
string calldata signature,
|
|
214
|
+
bytes calldata data,
|
|
215
|
+
uint eta
|
|
216
|
+
) external;
|
|
217
|
+
|
|
218
|
+
function executeTransaction(
|
|
219
|
+
address target,
|
|
220
|
+
uint value,
|
|
221
|
+
string calldata signature,
|
|
222
|
+
bytes calldata data,
|
|
223
|
+
uint eta
|
|
224
|
+
) external payable returns (bytes memory);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
interface XvsVaultInterface {
|
|
228
|
+
function getPriorVotes(address account, uint blockNumber) external view returns (uint96);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
interface GovernorAlphaInterface {
|
|
232
|
+
/// @notice The total number of proposals
|
|
233
|
+
function proposalCount() external returns (uint);
|
|
234
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
pragma solidity 0.5.16;
|
|
3
|
+
|
|
4
|
+
interface IAccessControlManagerV5 {
|
|
5
|
+
/**
|
|
6
|
+
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
|
|
7
|
+
*
|
|
8
|
+
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
|
|
9
|
+
* {RoleAdminChanged} not being emitted signaling this.
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @dev Emitted when `account` is granted `role`.
|
|
16
|
+
*
|
|
17
|
+
* `sender` is the account that originated the contract call, an admin role
|
|
18
|
+
* bearer except when using {AccessControl-_setupRole}.
|
|
19
|
+
*/
|
|
20
|
+
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @dev Emitted when `account` is revoked `role`.
|
|
24
|
+
*
|
|
25
|
+
* `sender` is the account that originated the contract call:
|
|
26
|
+
* - if using `revokeRole`, it is the admin role bearer
|
|
27
|
+
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
|
|
28
|
+
*/
|
|
29
|
+
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @dev Returns `true` if `account` has been granted `role`.
|
|
33
|
+
*/
|
|
34
|
+
function hasRole(bytes32 role, address account) external view returns (bool);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @dev Returns the admin role that controls `role`. See {grantRole} and
|
|
38
|
+
* {revokeRole}.
|
|
39
|
+
*
|
|
40
|
+
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
|
|
41
|
+
*/
|
|
42
|
+
function getRoleAdmin(bytes32 role) external view returns (bytes32);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @dev Grants `role` to `account`.
|
|
46
|
+
*
|
|
47
|
+
* If `account` had not been already granted `role`, emits a {RoleGranted}
|
|
48
|
+
* event.
|
|
49
|
+
*
|
|
50
|
+
* Requirements:
|
|
51
|
+
*
|
|
52
|
+
* - the caller must have ``role``'s admin role.
|
|
53
|
+
*/
|
|
54
|
+
function grantRole(bytes32 role, address account) external;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @dev Revokes `role` from `account`.
|
|
58
|
+
*
|
|
59
|
+
* If `account` had been granted `role`, emits a {RoleRevoked} event.
|
|
60
|
+
*
|
|
61
|
+
* Requirements:
|
|
62
|
+
*
|
|
63
|
+
* - the caller must have ``role``'s admin role.
|
|
64
|
+
*/
|
|
65
|
+
function revokeRole(bytes32 role, address account) external;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @dev Revokes `role` from the calling account.
|
|
69
|
+
*
|
|
70
|
+
* Roles are often managed via {grantRole} and {revokeRole}: this function's
|
|
71
|
+
* purpose is to provide a mechanism for accounts to lose their privileges
|
|
72
|
+
* if they are compromised (such as when a trusted device is misplaced).
|
|
73
|
+
*
|
|
74
|
+
* If the calling account had been granted `role`, emits a {RoleRevoked}
|
|
75
|
+
* event.
|
|
76
|
+
*
|
|
77
|
+
* Requirements:
|
|
78
|
+
*
|
|
79
|
+
* - the caller must be `account`.
|
|
80
|
+
*/
|
|
81
|
+
function renounceRole(bytes32 role, address account) external;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @notice Gives a function call permission to one single account
|
|
85
|
+
* @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE
|
|
86
|
+
* May emit a {RoleGranted} event.
|
|
87
|
+
* @param contractAddress address of contract for which call permissions will be granted
|
|
88
|
+
* @param functionSig signature e.g. "functionName(uint,bool)"
|
|
89
|
+
*/
|
|
90
|
+
function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @notice Revokes an account's permission to a particular function call
|
|
94
|
+
* @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE
|
|
95
|
+
* May emit a {RoleRevoked} event.
|
|
96
|
+
* @param contractAddress address of contract for which call permissions will be revoked
|
|
97
|
+
* @param functionSig signature e.g. "functionName(uint,bool)"
|
|
98
|
+
*/
|
|
99
|
+
function revokeCallPermission(
|
|
100
|
+
address contractAddress,
|
|
101
|
+
string calldata functionSig,
|
|
102
|
+
address accountToRevoke
|
|
103
|
+
) external;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @notice Verifies if the given account can call a praticular contract's function
|
|
107
|
+
* @dev Since the contract is calling itself this function, we can get contracts address with msg.sender
|
|
108
|
+
* @param account address (eoa or contract) for which call permissions will be checked
|
|
109
|
+
* @param functionSig signature e.g. "functionName(uint,bool)"
|
|
110
|
+
* @return false if the user account cannot call the particular contract function
|
|
111
|
+
*
|
|
112
|
+
*/
|
|
113
|
+
function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);
|
|
114
|
+
|
|
115
|
+
function hasPermission(
|
|
116
|
+
address account,
|
|
117
|
+
address contractAddress,
|
|
118
|
+
string calldata functionSig
|
|
119
|
+
) external view returns (bool);
|
|
120
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BSD-3-Clause
|
|
2
|
+
pragma solidity 0.8.13;
|
|
3
|
+
|
|
4
|
+
import "@openzeppelin/contracts/access/IAccessControl.sol";
|
|
5
|
+
|
|
6
|
+
interface IAccessControlManagerV8 is IAccessControl {
|
|
7
|
+
function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;
|
|
8
|
+
|
|
9
|
+
function revokeCallPermission(
|
|
10
|
+
address contractAddress,
|
|
11
|
+
string calldata functionSig,
|
|
12
|
+
address accountToRevoke
|
|
13
|
+
) external;
|
|
14
|
+
|
|
15
|
+
function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);
|
|
16
|
+
|
|
17
|
+
function hasPermission(
|
|
18
|
+
address account,
|
|
19
|
+
address contractAddress,
|
|
20
|
+
string calldata functionSig
|
|
21
|
+
) external view returns (bool);
|
|
22
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
pragma solidity ^0.5.16;
|
|
2
|
+
|
|
3
|
+
import "../Utils/SafeMath.sol";
|
|
4
|
+
|
|
5
|
+
contract Timelock {
|
|
6
|
+
using SafeMath for uint;
|
|
7
|
+
|
|
8
|
+
event NewAdmin(address indexed newAdmin);
|
|
9
|
+
event NewPendingAdmin(address indexed newPendingAdmin);
|
|
10
|
+
event NewDelay(uint indexed newDelay);
|
|
11
|
+
event CancelTransaction(
|
|
12
|
+
bytes32 indexed txHash,
|
|
13
|
+
address indexed target,
|
|
14
|
+
uint value,
|
|
15
|
+
string signature,
|
|
16
|
+
bytes data,
|
|
17
|
+
uint eta
|
|
18
|
+
);
|
|
19
|
+
event ExecuteTransaction(
|
|
20
|
+
bytes32 indexed txHash,
|
|
21
|
+
address indexed target,
|
|
22
|
+
uint value,
|
|
23
|
+
string signature,
|
|
24
|
+
bytes data,
|
|
25
|
+
uint eta
|
|
26
|
+
);
|
|
27
|
+
event QueueTransaction(
|
|
28
|
+
bytes32 indexed txHash,
|
|
29
|
+
address indexed target,
|
|
30
|
+
uint value,
|
|
31
|
+
string signature,
|
|
32
|
+
bytes data,
|
|
33
|
+
uint eta
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
uint public constant GRACE_PERIOD = 14 days;
|
|
37
|
+
uint public constant MINIMUM_DELAY = 1 hours;
|
|
38
|
+
uint public constant MAXIMUM_DELAY = 30 days;
|
|
39
|
+
|
|
40
|
+
address public admin;
|
|
41
|
+
address public pendingAdmin;
|
|
42
|
+
uint public delay;
|
|
43
|
+
|
|
44
|
+
mapping(bytes32 => bool) public queuedTransactions;
|
|
45
|
+
|
|
46
|
+
constructor(address admin_, uint delay_) public {
|
|
47
|
+
require(delay_ >= MINIMUM_DELAY, "Timelock::constructor: Delay must exceed minimum delay.");
|
|
48
|
+
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
|
|
49
|
+
|
|
50
|
+
admin = admin_;
|
|
51
|
+
delay = delay_;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function() external payable {}
|
|
55
|
+
|
|
56
|
+
function setDelay(uint delay_) public {
|
|
57
|
+
require(msg.sender == address(this), "Timelock::setDelay: Call must come from Timelock.");
|
|
58
|
+
require(delay_ >= MINIMUM_DELAY, "Timelock::setDelay: Delay must exceed minimum delay.");
|
|
59
|
+
require(delay_ <= MAXIMUM_DELAY, "Timelock::setDelay: Delay must not exceed maximum delay.");
|
|
60
|
+
delay = delay_;
|
|
61
|
+
|
|
62
|
+
emit NewDelay(delay);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function acceptAdmin() public {
|
|
66
|
+
require(msg.sender == pendingAdmin, "Timelock::acceptAdmin: Call must come from pendingAdmin.");
|
|
67
|
+
admin = msg.sender;
|
|
68
|
+
pendingAdmin = address(0);
|
|
69
|
+
|
|
70
|
+
emit NewAdmin(admin);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function setPendingAdmin(address pendingAdmin_) public {
|
|
74
|
+
require(msg.sender == address(this), "Timelock::setPendingAdmin: Call must come from Timelock.");
|
|
75
|
+
pendingAdmin = pendingAdmin_;
|
|
76
|
+
|
|
77
|
+
emit NewPendingAdmin(pendingAdmin);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function queueTransaction(
|
|
81
|
+
address target,
|
|
82
|
+
uint value,
|
|
83
|
+
string memory signature,
|
|
84
|
+
bytes memory data,
|
|
85
|
+
uint eta
|
|
86
|
+
) public returns (bytes32) {
|
|
87
|
+
require(msg.sender == admin, "Timelock::queueTransaction: Call must come from admin.");
|
|
88
|
+
require(
|
|
89
|
+
eta >= getBlockTimestamp().add(delay),
|
|
90
|
+
"Timelock::queueTransaction: Estimated execution block must satisfy delay."
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
|
|
94
|
+
queuedTransactions[txHash] = true;
|
|
95
|
+
|
|
96
|
+
emit QueueTransaction(txHash, target, value, signature, data, eta);
|
|
97
|
+
return txHash;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function cancelTransaction(
|
|
101
|
+
address target,
|
|
102
|
+
uint value,
|
|
103
|
+
string memory signature,
|
|
104
|
+
bytes memory data,
|
|
105
|
+
uint eta
|
|
106
|
+
) public {
|
|
107
|
+
require(msg.sender == admin, "Timelock::cancelTransaction: Call must come from admin.");
|
|
108
|
+
|
|
109
|
+
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
|
|
110
|
+
queuedTransactions[txHash] = false;
|
|
111
|
+
|
|
112
|
+
emit CancelTransaction(txHash, target, value, signature, data, eta);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function executeTransaction(
|
|
116
|
+
address target,
|
|
117
|
+
uint value,
|
|
118
|
+
string memory signature,
|
|
119
|
+
bytes memory data,
|
|
120
|
+
uint eta
|
|
121
|
+
) public payable returns (bytes memory) {
|
|
122
|
+
require(msg.sender == admin, "Timelock::executeTransaction: Call must come from admin.");
|
|
123
|
+
|
|
124
|
+
bytes32 txHash = keccak256(abi.encode(target, value, signature, data, eta));
|
|
125
|
+
require(queuedTransactions[txHash], "Timelock::executeTransaction: Transaction hasn't been queued.");
|
|
126
|
+
require(getBlockTimestamp() >= eta, "Timelock::executeTransaction: Transaction hasn't surpassed time lock.");
|
|
127
|
+
require(getBlockTimestamp() <= eta.add(GRACE_PERIOD), "Timelock::executeTransaction: Transaction is stale.");
|
|
128
|
+
|
|
129
|
+
queuedTransactions[txHash] = false;
|
|
130
|
+
|
|
131
|
+
bytes memory callData;
|
|
132
|
+
|
|
133
|
+
if (bytes(signature).length == 0) {
|
|
134
|
+
callData = data;
|
|
135
|
+
} else {
|
|
136
|
+
callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// solium-disable-next-line security/no-call-value
|
|
140
|
+
(bool success, bytes memory returnData) = target.call.value(value)(callData);
|
|
141
|
+
require(success, "Timelock::executeTransaction: Transaction execution reverted.");
|
|
142
|
+
|
|
143
|
+
emit ExecuteTransaction(txHash, target, value, signature, data, eta);
|
|
144
|
+
|
|
145
|
+
return returnData;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function getBlockTimestamp() internal view returns (uint) {
|
|
149
|
+
// solium-disable-next-line security/no-block-members
|
|
150
|
+
return block.timestamp;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
pragma solidity ^0.5.16;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @dev Wrappers over Solidity's arithmetic operations with added overflow
|
|
5
|
+
* checks.
|
|
6
|
+
*
|
|
7
|
+
* Arithmetic operations in Solidity wrap on overflow. This can easily result
|
|
8
|
+
* in bugs, because programmers usually assume that an overflow raises an
|
|
9
|
+
* error, which is the standard behavior in high level programming languages.
|
|
10
|
+
* `SafeMath` restores this intuition by reverting the transaction when an
|
|
11
|
+
* operation overflows.
|
|
12
|
+
*
|
|
13
|
+
* Using this library instead of the unchecked operations eliminates an entire
|
|
14
|
+
* class of bugs, so it's recommended to use it always.
|
|
15
|
+
*/
|
|
16
|
+
library SafeMath {
|
|
17
|
+
/**
|
|
18
|
+
* @dev Returns the addition of two unsigned integers, reverting on
|
|
19
|
+
* overflow.
|
|
20
|
+
*
|
|
21
|
+
* Counterpart to Solidity's `+` operator.
|
|
22
|
+
*
|
|
23
|
+
* Requirements:
|
|
24
|
+
* - Addition cannot overflow.
|
|
25
|
+
*/
|
|
26
|
+
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
27
|
+
return add(a, b, "SafeMath: addition overflow");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
|
|
32
|
+
* overflow (when the result is negative).
|
|
33
|
+
*
|
|
34
|
+
* Counterpart to Solidity's `-` operator.
|
|
35
|
+
*
|
|
36
|
+
* Requirements:
|
|
37
|
+
* - Subtraction cannot overflow.
|
|
38
|
+
*/
|
|
39
|
+
function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
|
40
|
+
uint256 c = a + b;
|
|
41
|
+
require(c >= a, errorMessage);
|
|
42
|
+
|
|
43
|
+
return c;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @dev Returns the subtraction of two unsigned integers, reverting on
|
|
48
|
+
* overflow (when the result is negative).
|
|
49
|
+
*
|
|
50
|
+
* Counterpart to Solidity's `-` operator.
|
|
51
|
+
*
|
|
52
|
+
* Requirements:
|
|
53
|
+
* - Subtraction cannot overflow.
|
|
54
|
+
*/
|
|
55
|
+
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
56
|
+
return sub(a, b, "SafeMath: subtraction overflow");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
|
|
61
|
+
* overflow (when the result is negative).
|
|
62
|
+
*
|
|
63
|
+
* Counterpart to Solidity's `-` operator.
|
|
64
|
+
*
|
|
65
|
+
* Requirements:
|
|
66
|
+
* - Subtraction cannot overflow.
|
|
67
|
+
*/
|
|
68
|
+
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
|
69
|
+
require(b <= a, errorMessage);
|
|
70
|
+
uint256 c = a - b;
|
|
71
|
+
|
|
72
|
+
return c;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @dev Returns the multiplication of two unsigned integers, reverting on
|
|
77
|
+
* overflow.
|
|
78
|
+
*
|
|
79
|
+
* Counterpart to Solidity's `*` operator.
|
|
80
|
+
*
|
|
81
|
+
* Requirements:
|
|
82
|
+
* - Multiplication cannot overflow.
|
|
83
|
+
*/
|
|
84
|
+
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
85
|
+
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
|
86
|
+
// benefit is lost if 'b' is also tested.
|
|
87
|
+
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
|
|
88
|
+
if (a == 0) {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
uint256 c = a * b;
|
|
93
|
+
require(c / a == b, "SafeMath: multiplication overflow");
|
|
94
|
+
|
|
95
|
+
return c;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @dev Returns the integer division of two unsigned integers. Reverts on
|
|
100
|
+
* division by zero. The result is rounded towards zero.
|
|
101
|
+
*
|
|
102
|
+
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
|
103
|
+
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
|
104
|
+
* uses an invalid opcode to revert (consuming all remaining gas).
|
|
105
|
+
*
|
|
106
|
+
* Requirements:
|
|
107
|
+
* - The divisor cannot be zero.
|
|
108
|
+
*/
|
|
109
|
+
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
110
|
+
return div(a, b, "SafeMath: division by zero");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
|
|
115
|
+
* division by zero. The result is rounded towards zero.
|
|
116
|
+
*
|
|
117
|
+
* Counterpart to Solidity's `/` operator. Note: this function uses a
|
|
118
|
+
* `revert` opcode (which leaves remaining gas untouched) while Solidity
|
|
119
|
+
* uses an invalid opcode to revert (consuming all remaining gas).
|
|
120
|
+
*
|
|
121
|
+
* Requirements:
|
|
122
|
+
* - The divisor cannot be zero.
|
|
123
|
+
*/
|
|
124
|
+
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
|
125
|
+
// Solidity only automatically asserts when dividing by 0
|
|
126
|
+
require(b > 0, errorMessage);
|
|
127
|
+
uint256 c = a / b;
|
|
128
|
+
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
|
129
|
+
|
|
130
|
+
return c;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
|
135
|
+
* Reverts when dividing by zero.
|
|
136
|
+
*
|
|
137
|
+
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
|
138
|
+
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
|
139
|
+
* invalid opcode to revert (consuming all remaining gas).
|
|
140
|
+
*
|
|
141
|
+
* Requirements:
|
|
142
|
+
* - The divisor cannot be zero.
|
|
143
|
+
*/
|
|
144
|
+
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
145
|
+
return mod(a, b, "SafeMath: modulo by zero");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
|
|
150
|
+
* Reverts with custom message when dividing by zero.
|
|
151
|
+
*
|
|
152
|
+
* Counterpart to Solidity's `%` operator. This function uses a `revert`
|
|
153
|
+
* opcode (which leaves remaining gas untouched) while Solidity uses an
|
|
154
|
+
* invalid opcode to revert (consuming all remaining gas).
|
|
155
|
+
*
|
|
156
|
+
* Requirements:
|
|
157
|
+
* - The divisor cannot be zero.
|
|
158
|
+
*/
|
|
159
|
+
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
|
|
160
|
+
require(b != 0, errorMessage);
|
|
161
|
+
return a % b;
|
|
162
|
+
}
|
|
163
|
+
}
|