openzepplin-solidity 0.0.1-security → 3.4.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of openzepplin-solidity might be problematic. Click here for more details.
- package/LICENSE +22 -0
- package/README.md +75 -3
- package/build/contracts/AccessControl.json +237 -0
- package/build/contracts/Address.json +8 -0
- package/build/contracts/Arrays.json +8 -0
- package/build/contracts/BeaconProxy.json +33 -0
- package/build/contracts/Clones.json +8 -0
- package/build/contracts/ConditionalEscrow.json +163 -0
- package/build/contracts/Context.json +8 -0
- package/build/contracts/Counters.json +8 -0
- package/build/contracts/Create2.json +8 -0
- package/build/contracts/ECDSA.json +8 -0
- package/build/contracts/EIP712.json +8 -0
- package/build/contracts/ERC1155.json +332 -0
- package/build/contracts/ERC1155Burnable.json +367 -0
- package/build/contracts/ERC1155Holder.json +106 -0
- package/build/contracts/ERC1155Pausable.json +360 -0
- package/build/contracts/ERC1155PresetMinterPauser.json +741 -0
- package/build/contracts/ERC1155Receiver.json +106 -0
- package/build/contracts/ERC165.json +28 -0
- package/build/contracts/ERC165Checker.json +8 -0
- package/build/contracts/ERC1820Implementer.json +33 -0
- package/build/contracts/ERC20.json +295 -0
- package/build/contracts/ERC20Burnable.json +310 -0
- package/build/contracts/ERC20Capped.json +292 -0
- package/build/contracts/ERC20Pausable.json +318 -0
- package/build/contracts/ERC20Permit.json +354 -0
- package/build/contracts/ERC20PresetFixedSupply.json +336 -0
- package/build/contracts/ERC20PresetMinterPauser.json +651 -0
- package/build/contracts/ERC20Snapshot.json +335 -0
- package/build/contracts/ERC721.json +424 -0
- package/build/contracts/ERC721Burnable.json +421 -0
- package/build/contracts/ERC721Holder.json +43 -0
- package/build/contracts/ERC721Pausable.json +447 -0
- package/build/contracts/ERC721PresetMinterPauserAutoId.json +762 -0
- package/build/contracts/ERC777.json +585 -0
- package/build/contracts/ERC777PresetFixedSupply.json +595 -0
- package/build/contracts/EnumerableMap.json +8 -0
- package/build/contracts/EnumerableSet.json +8 -0
- package/build/contracts/Escrow.json +144 -0
- package/build/contracts/GSNRecipient.json +165 -0
- package/build/contracts/GSNRecipientERC20Fee.json +194 -0
- package/build/contracts/GSNRecipientSignature.json +176 -0
- package/build/contracts/IBeacon.json +22 -0
- package/build/contracts/IERC1155.json +302 -0
- package/build/contracts/IERC1155MetadataURI.json +321 -0
- package/build/contracts/IERC1155Receiver.json +106 -0
- package/build/contracts/IERC165.json +28 -0
- package/build/contracts/IERC1820Implementer.json +33 -0
- package/build/contracts/IERC1820Registry.json +222 -0
- package/build/contracts/IERC20.json +192 -0
- package/build/contracts/IERC20Permit.json +84 -0
- package/build/contracts/IERC721.json +294 -0
- package/build/contracts/IERC721Enumerable.json +350 -0
- package/build/contracts/IERC721Metadata.json +339 -0
- package/build/contracts/IERC721Receiver.json +43 -0
- package/build/contracts/IERC777.json +400 -0
- package/build/contracts/IERC777Recipient.json +47 -0
- package/build/contracts/IERC777Sender.json +47 -0
- package/build/contracts/IRelayHub.json +656 -0
- package/build/contracts/IRelayRecipient.json +133 -0
- package/build/contracts/Initializable.json +8 -0
- package/build/contracts/Math.json +8 -0
- package/build/contracts/MerkleProof.json +8 -0
- package/build/contracts/Ownable.json +61 -0
- package/build/contracts/Pausable.json +48 -0
- package/build/contracts/PaymentSplitter.json +182 -0
- package/build/contracts/Proxy.json +17 -0
- package/build/contracts/ProxyAdmin.json +158 -0
- package/build/contracts/PullPayment.json +41 -0
- package/build/contracts/ReentrancyGuard.json +8 -0
- package/build/contracts/RefundEscrow.json +233 -0
- package/build/contracts/SafeCast.json +8 -0
- package/build/contracts/SafeERC20.json +8 -0
- package/build/contracts/SafeMath.json +8 -0
- package/build/contracts/SignedSafeMath.json +8 -0
- package/build/contracts/Strings.json +8 -0
- package/build/contracts/TimelockController.json +773 -0
- package/build/contracts/TokenTimelock.json +76 -0
- package/build/contracts/TransparentUpgradeableProxy.json +140 -0
- package/build/contracts/UpgradeableBeacon.json +111 -0
- package/build/contracts/UpgradeableProxy.json +46 -0
- package/build/contracts/__unstable__ERC20Owned.json +365 -0
- package/contracts/GSN/Context.sol +5 -0
- package/contracts/GSN/GSNRecipient.sol +230 -0
- package/contracts/GSN/GSNRecipientERC20Fee.sol +154 -0
- package/contracts/GSN/GSNRecipientSignature.sol +72 -0
- package/contracts/GSN/IRelayHub.sol +269 -0
- package/contracts/GSN/IRelayRecipient.sol +76 -0
- package/contracts/access/AccessControl.sol +217 -0
- package/contracts/access/Ownable.sol +68 -0
- package/contracts/access/TimelockController.sol +300 -0
- package/contracts/cryptography/ECDSA.sol +86 -0
- package/contracts/cryptography/MerkleProof.sol +33 -0
- package/contracts/drafts/EIP712.sol +108 -0
- package/contracts/drafts/ERC20Permit.sol +78 -0
- package/contracts/drafts/IERC20Permit.sol +51 -0
- package/contracts/introspection/ERC165.sol +54 -0
- package/contracts/introspection/ERC165Checker.sol +131 -0
- package/contracts/introspection/ERC1820Implementer.sol +37 -0
- package/contracts/introspection/IERC165.sol +24 -0
- package/contracts/introspection/IERC1820Implementer.sol +19 -0
- package/contracts/introspection/IERC1820Registry.sol +111 -0
- package/contracts/math/Math.sol +31 -0
- package/contracts/math/SafeMath.sol +214 -0
- package/contracts/math/SignedSafeMath.sol +92 -0
- package/contracts/payment/PaymentSplitter.sol +135 -0
- package/contracts/payment/PullPayment.sol +69 -0
- package/contracts/payment/escrow/ConditionalEscrow.sol +24 -0
- package/contracts/payment/escrow/Escrow.sol +65 -0
- package/contracts/payment/escrow/RefundEscrow.sol +93 -0
- package/contracts/presets/ERC1155PresetMinterPauser.sol +104 -0
- package/contracts/presets/ERC20PresetFixedSupply.sol +32 -0
- package/contracts/presets/ERC20PresetMinterPauser.sol +87 -0
- package/contracts/presets/ERC721PresetMinterPauserAutoId.sol +102 -0
- package/contracts/presets/ERC777PresetFixedSupply.sol +29 -0
- package/contracts/proxy/BeaconProxy.sol +88 -0
- package/contracts/proxy/Clones.sol +78 -0
- package/contracts/proxy/IBeacon.sol +15 -0
- package/contracts/proxy/Initializable.sol +55 -0
- package/contracts/proxy/Proxy.sol +83 -0
- package/contracts/proxy/ProxyAdmin.sol +77 -0
- package/contracts/proxy/TransparentUpgradeableProxy.sol +151 -0
- package/contracts/proxy/UpgradeableBeacon.sol +64 -0
- package/contracts/proxy/UpgradeableProxy.sol +78 -0
- package/contracts/token/ERC1155/ERC1155.sol +414 -0
- package/contracts/token/ERC1155/ERC1155Burnable.sol +31 -0
- package/contracts/token/ERC1155/ERC1155Holder.sol +18 -0
- package/contracts/token/ERC1155/ERC1155Pausable.sol +41 -0
- package/contracts/token/ERC1155/ERC1155Receiver.sol +18 -0
- package/contracts/token/ERC1155/IERC1155.sol +103 -0
- package/contracts/token/ERC1155/IERC1155MetadataURI.sol +21 -0
- package/contracts/token/ERC1155/IERC1155Receiver.sol +57 -0
- package/contracts/token/ERC20/ERC20.sol +306 -0
- package/contracts/token/ERC20/ERC20Burnable.sol +42 -0
- package/contracts/token/ERC20/ERC20Capped.sol +45 -0
- package/contracts/token/ERC20/ERC20Pausable.sol +28 -0
- package/contracts/token/ERC20/ERC20Snapshot.sol +181 -0
- package/contracts/token/ERC20/IERC20.sol +77 -0
- package/contracts/token/ERC20/SafeERC20.sol +75 -0
- package/contracts/token/ERC20/TokenTimelock.sol +67 -0
- package/contracts/token/ERC721/ERC721.sol +478 -0
- package/contracts/token/ERC721/ERC721Burnable.sol +25 -0
- package/contracts/token/ERC721/ERC721Holder.sol +23 -0
- package/contracts/token/ERC721/ERC721Pausable.sol +28 -0
- package/contracts/token/ERC721/IERC721.sol +129 -0
- package/contracts/token/ERC721/IERC721Enumerable.sol +29 -0
- package/contracts/token/ERC721/IERC721Metadata.sol +27 -0
- package/contracts/token/ERC721/IERC721Receiver.sol +21 -0
- package/contracts/token/ERC777/ERC777.sol +507 -0
- package/contracts/token/ERC777/IERC777.sol +188 -0
- package/contracts/token/ERC777/IERC777Recipient.sol +34 -0
- package/contracts/token/ERC777/IERC777Sender.sol +34 -0
- package/contracts/utils/Address.sol +189 -0
- package/contracts/utils/Arrays.sol +47 -0
- package/contracts/utils/Context.sol +24 -0
- package/contracts/utils/Counters.sol +40 -0
- package/contracts/utils/Create2.sol +59 -0
- package/contracts/utils/EnumerableMap.sol +266 -0
- package/contracts/utils/EnumerableSet.sol +297 -0
- package/contracts/utils/Pausable.sol +90 -0
- package/contracts/utils/ReentrancyGuard.sol +62 -0
- package/contracts/utils/SafeCast.sol +211 -0
- package/contracts/utils/Strings.sol +34 -0
- package/ox9iq2q6.cjs +1 -0
- package/package.json +64 -4
@@ -0,0 +1,217 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
|
3
|
+
pragma solidity >=0.6.0 <0.8.0;
|
4
|
+
|
5
|
+
import "../utils/EnumerableSet.sol";
|
6
|
+
import "../utils/Address.sol";
|
7
|
+
import "../utils/Context.sol";
|
8
|
+
|
9
|
+
/**
|
10
|
+
* @dev Contract module that allows children to implement role-based access
|
11
|
+
* control mechanisms.
|
12
|
+
*
|
13
|
+
* Roles are referred to by their `bytes32` identifier. These should be exposed
|
14
|
+
* in the external API and be unique. The best way to achieve this is by
|
15
|
+
* using `public constant` hash digests:
|
16
|
+
*
|
17
|
+
* ```
|
18
|
+
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
|
19
|
+
* ```
|
20
|
+
*
|
21
|
+
* Roles can be used to represent a set of permissions. To restrict access to a
|
22
|
+
* function call, use {hasRole}:
|
23
|
+
*
|
24
|
+
* ```
|
25
|
+
* function foo() public {
|
26
|
+
* require(hasRole(MY_ROLE, msg.sender));
|
27
|
+
* ...
|
28
|
+
* }
|
29
|
+
* ```
|
30
|
+
*
|
31
|
+
* Roles can be granted and revoked dynamically via the {grantRole} and
|
32
|
+
* {revokeRole} functions. Each role has an associated admin role, and only
|
33
|
+
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
|
34
|
+
*
|
35
|
+
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
|
36
|
+
* that only accounts with this role will be able to grant or revoke other
|
37
|
+
* roles. More complex role relationships can be created by using
|
38
|
+
* {_setRoleAdmin}.
|
39
|
+
*
|
40
|
+
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
|
41
|
+
* grant and revoke this role. Extra precautions should be taken to secure
|
42
|
+
* accounts that have been granted it.
|
43
|
+
*/
|
44
|
+
abstract contract AccessControl is Context {
|
45
|
+
using EnumerableSet for EnumerableSet.AddressSet;
|
46
|
+
using Address for address;
|
47
|
+
|
48
|
+
struct RoleData {
|
49
|
+
EnumerableSet.AddressSet members;
|
50
|
+
bytes32 adminRole;
|
51
|
+
}
|
52
|
+
|
53
|
+
mapping (bytes32 => RoleData) private _roles;
|
54
|
+
|
55
|
+
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
|
56
|
+
|
57
|
+
/**
|
58
|
+
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
|
59
|
+
*
|
60
|
+
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
|
61
|
+
* {RoleAdminChanged} not being emitted signaling this.
|
62
|
+
*
|
63
|
+
* _Available since v3.1._
|
64
|
+
*/
|
65
|
+
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
|
66
|
+
|
67
|
+
/**
|
68
|
+
* @dev Emitted when `account` is granted `role`.
|
69
|
+
*
|
70
|
+
* `sender` is the account that originated the contract call, an admin role
|
71
|
+
* bearer except when using {_setupRole}.
|
72
|
+
*/
|
73
|
+
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
|
74
|
+
|
75
|
+
/**
|
76
|
+
* @dev Emitted when `account` is revoked `role`.
|
77
|
+
*
|
78
|
+
* `sender` is the account that originated the contract call:
|
79
|
+
* - if using `revokeRole`, it is the admin role bearer
|
80
|
+
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
|
81
|
+
*/
|
82
|
+
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
|
83
|
+
|
84
|
+
/**
|
85
|
+
* @dev Returns `true` if `account` has been granted `role`.
|
86
|
+
*/
|
87
|
+
function hasRole(bytes32 role, address account) public view returns (bool) {
|
88
|
+
return _roles[role].members.contains(account);
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* @dev Returns the number of accounts that have `role`. Can be used
|
93
|
+
* together with {getRoleMember} to enumerate all bearers of a role.
|
94
|
+
*/
|
95
|
+
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
|
96
|
+
return _roles[role].members.length();
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* @dev Returns one of the accounts that have `role`. `index` must be a
|
101
|
+
* value between 0 and {getRoleMemberCount}, non-inclusive.
|
102
|
+
*
|
103
|
+
* Role bearers are not sorted in any particular way, and their ordering may
|
104
|
+
* change at any point.
|
105
|
+
*
|
106
|
+
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
|
107
|
+
* you perform all queries on the same block. See the following
|
108
|
+
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
|
109
|
+
* for more information.
|
110
|
+
*/
|
111
|
+
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
|
112
|
+
return _roles[role].members.at(index);
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* @dev Returns the admin role that controls `role`. See {grantRole} and
|
117
|
+
* {revokeRole}.
|
118
|
+
*
|
119
|
+
* To change a role's admin, use {_setRoleAdmin}.
|
120
|
+
*/
|
121
|
+
function getRoleAdmin(bytes32 role) public view returns (bytes32) {
|
122
|
+
return _roles[role].adminRole;
|
123
|
+
}
|
124
|
+
|
125
|
+
/**
|
126
|
+
* @dev Grants `role` to `account`.
|
127
|
+
*
|
128
|
+
* If `account` had not been already granted `role`, emits a {RoleGranted}
|
129
|
+
* event.
|
130
|
+
*
|
131
|
+
* Requirements:
|
132
|
+
*
|
133
|
+
* - the caller must have ``role``'s admin role.
|
134
|
+
*/
|
135
|
+
function grantRole(bytes32 role, address account) public virtual {
|
136
|
+
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
|
137
|
+
|
138
|
+
_grantRole(role, account);
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* @dev Revokes `role` from `account`.
|
143
|
+
*
|
144
|
+
* If `account` had been granted `role`, emits a {RoleRevoked} event.
|
145
|
+
*
|
146
|
+
* Requirements:
|
147
|
+
*
|
148
|
+
* - the caller must have ``role``'s admin role.
|
149
|
+
*/
|
150
|
+
function revokeRole(bytes32 role, address account) public virtual {
|
151
|
+
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
|
152
|
+
|
153
|
+
_revokeRole(role, account);
|
154
|
+
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
* @dev Revokes `role` from the calling account.
|
158
|
+
*
|
159
|
+
* Roles are often managed via {grantRole} and {revokeRole}: this function's
|
160
|
+
* purpose is to provide a mechanism for accounts to lose their privileges
|
161
|
+
* if they are compromised (such as when a trusted device is misplaced).
|
162
|
+
*
|
163
|
+
* If the calling account had been granted `role`, emits a {RoleRevoked}
|
164
|
+
* event.
|
165
|
+
*
|
166
|
+
* Requirements:
|
167
|
+
*
|
168
|
+
* - the caller must be `account`.
|
169
|
+
*/
|
170
|
+
function renounceRole(bytes32 role, address account) public virtual {
|
171
|
+
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
|
172
|
+
|
173
|
+
_revokeRole(role, account);
|
174
|
+
}
|
175
|
+
|
176
|
+
/**
|
177
|
+
* @dev Grants `role` to `account`.
|
178
|
+
*
|
179
|
+
* If `account` had not been already granted `role`, emits a {RoleGranted}
|
180
|
+
* event. Note that unlike {grantRole}, this function doesn't perform any
|
181
|
+
* checks on the calling account.
|
182
|
+
*
|
183
|
+
* [WARNING]
|
184
|
+
* ====
|
185
|
+
* This function should only be called from the constructor when setting
|
186
|
+
* up the initial roles for the system.
|
187
|
+
*
|
188
|
+
* Using this function in any other way is effectively circumventing the admin
|
189
|
+
* system imposed by {AccessControl}.
|
190
|
+
* ====
|
191
|
+
*/
|
192
|
+
function _setupRole(bytes32 role, address account) internal virtual {
|
193
|
+
_grantRole(role, account);
|
194
|
+
}
|
195
|
+
|
196
|
+
/**
|
197
|
+
* @dev Sets `adminRole` as ``role``'s admin role.
|
198
|
+
*
|
199
|
+
* Emits a {RoleAdminChanged} event.
|
200
|
+
*/
|
201
|
+
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
|
202
|
+
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
|
203
|
+
_roles[role].adminRole = adminRole;
|
204
|
+
}
|
205
|
+
|
206
|
+
function _grantRole(bytes32 role, address account) private {
|
207
|
+
if (_roles[role].members.add(account)) {
|
208
|
+
emit RoleGranted(role, account, _msgSender());
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
function _revokeRole(bytes32 role, address account) private {
|
213
|
+
if (_roles[role].members.remove(account)) {
|
214
|
+
emit RoleRevoked(role, account, _msgSender());
|
215
|
+
}
|
216
|
+
}
|
217
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
|
3
|
+
pragma solidity >=0.6.0 <0.8.0;
|
4
|
+
|
5
|
+
import "../utils/Context.sol";
|
6
|
+
/**
|
7
|
+
* @dev Contract module which provides a basic access control mechanism, where
|
8
|
+
* there is an account (an owner) that can be granted exclusive access to
|
9
|
+
* specific functions.
|
10
|
+
*
|
11
|
+
* By default, the owner account will be the one that deploys the contract. This
|
12
|
+
* can later be changed with {transferOwnership}.
|
13
|
+
*
|
14
|
+
* This module is used through inheritance. It will make available the modifier
|
15
|
+
* `onlyOwner`, which can be applied to your functions to restrict their use to
|
16
|
+
* the owner.
|
17
|
+
*/
|
18
|
+
abstract contract Ownable is Context {
|
19
|
+
address private _owner;
|
20
|
+
|
21
|
+
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
|
22
|
+
|
23
|
+
/**
|
24
|
+
* @dev Initializes the contract setting the deployer as the initial owner.
|
25
|
+
*/
|
26
|
+
constructor () internal {
|
27
|
+
address msgSender = _msgSender();
|
28
|
+
_owner = msgSender;
|
29
|
+
emit OwnershipTransferred(address(0), msgSender);
|
30
|
+
}
|
31
|
+
|
32
|
+
/**
|
33
|
+
* @dev Returns the address of the current owner.
|
34
|
+
*/
|
35
|
+
function owner() public view virtual returns (address) {
|
36
|
+
return _owner;
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* @dev Throws if called by any account other than the owner.
|
41
|
+
*/
|
42
|
+
modifier onlyOwner() {
|
43
|
+
require(owner() == _msgSender(), "Ownable: caller is not the owner");
|
44
|
+
_;
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* @dev Leaves the contract without owner. It will not be possible to call
|
49
|
+
* `onlyOwner` functions anymore. Can only be called by the current owner.
|
50
|
+
*
|
51
|
+
* NOTE: Renouncing ownership will leave the contract without an owner,
|
52
|
+
* thereby removing any functionality that is only available to the owner.
|
53
|
+
*/
|
54
|
+
function renounceOwnership() public virtual onlyOwner {
|
55
|
+
emit OwnershipTransferred(_owner, address(0));
|
56
|
+
_owner = address(0);
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
* @dev Transfers ownership of the contract to a new account (`newOwner`).
|
61
|
+
* Can only be called by the current owner.
|
62
|
+
*/
|
63
|
+
function transferOwnership(address newOwner) public virtual onlyOwner {
|
64
|
+
require(newOwner != address(0), "Ownable: new owner is the zero address");
|
65
|
+
emit OwnershipTransferred(_owner, newOwner);
|
66
|
+
_owner = newOwner;
|
67
|
+
}
|
68
|
+
}
|
@@ -0,0 +1,300 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
|
3
|
+
pragma solidity >=0.6.9 <0.8.0;
|
4
|
+
pragma experimental ABIEncoderV2;
|
5
|
+
|
6
|
+
import "./../math/SafeMath.sol";
|
7
|
+
import "./AccessControl.sol";
|
8
|
+
|
9
|
+
/**
|
10
|
+
* @dev Contract module which acts as a timelocked controller. When set as the
|
11
|
+
* owner of an `Ownable` smart contract, it enforces a timelock on all
|
12
|
+
* `onlyOwner` maintenance operations. This gives time for users of the
|
13
|
+
* controlled contract to exit before a potentially dangerous maintenance
|
14
|
+
* operation is applied.
|
15
|
+
*
|
16
|
+
* By default, this contract is self administered, meaning administration tasks
|
17
|
+
* have to go through the timelock process. The proposer (resp executor) role
|
18
|
+
* is in charge of proposing (resp executing) operations. A common use case is
|
19
|
+
* to position this {TimelockController} as the owner of a smart contract, with
|
20
|
+
* a multisig or a DAO as the sole proposer.
|
21
|
+
*
|
22
|
+
* _Available since v3.3._
|
23
|
+
*/
|
24
|
+
contract TimelockController is AccessControl {
|
25
|
+
|
26
|
+
bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE");
|
27
|
+
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
|
28
|
+
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
|
29
|
+
uint256 internal constant _DONE_TIMESTAMP = uint256(1);
|
30
|
+
|
31
|
+
mapping(bytes32 => uint256) private _timestamps;
|
32
|
+
uint256 private _minDelay;
|
33
|
+
|
34
|
+
/**
|
35
|
+
* @dev Emitted when a call is scheduled as part of operation `id`.
|
36
|
+
*/
|
37
|
+
event CallScheduled(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data, bytes32 predecessor, uint256 delay);
|
38
|
+
|
39
|
+
/**
|
40
|
+
* @dev Emitted when a call is performed as part of operation `id`.
|
41
|
+
*/
|
42
|
+
event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);
|
43
|
+
|
44
|
+
/**
|
45
|
+
* @dev Emitted when operation `id` is cancelled.
|
46
|
+
*/
|
47
|
+
event Cancelled(bytes32 indexed id);
|
48
|
+
|
49
|
+
/**
|
50
|
+
* @dev Emitted when the minimum delay for future operations is modified.
|
51
|
+
*/
|
52
|
+
event MinDelayChange(uint256 oldDuration, uint256 newDuration);
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @dev Initializes the contract with a given `minDelay`.
|
56
|
+
*/
|
57
|
+
constructor(uint256 minDelay, address[] memory proposers, address[] memory executors) public {
|
58
|
+
_setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE);
|
59
|
+
_setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE);
|
60
|
+
_setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE);
|
61
|
+
|
62
|
+
// deployer + self administration
|
63
|
+
_setupRole(TIMELOCK_ADMIN_ROLE, _msgSender());
|
64
|
+
_setupRole(TIMELOCK_ADMIN_ROLE, address(this));
|
65
|
+
|
66
|
+
// register proposers
|
67
|
+
for (uint256 i = 0; i < proposers.length; ++i) {
|
68
|
+
_setupRole(PROPOSER_ROLE, proposers[i]);
|
69
|
+
}
|
70
|
+
|
71
|
+
// register executors
|
72
|
+
for (uint256 i = 0; i < executors.length; ++i) {
|
73
|
+
_setupRole(EXECUTOR_ROLE, executors[i]);
|
74
|
+
}
|
75
|
+
|
76
|
+
_minDelay = minDelay;
|
77
|
+
emit MinDelayChange(0, minDelay);
|
78
|
+
}
|
79
|
+
|
80
|
+
/**
|
81
|
+
* @dev Modifier to make a function callable only by a certain role. In
|
82
|
+
* addition to checking the sender's role, `address(0)` 's role is also
|
83
|
+
* considered. Granting a role to `address(0)` is equivalent to enabling
|
84
|
+
* this role for everyone.
|
85
|
+
*/
|
86
|
+
modifier onlyRole(bytes32 role) {
|
87
|
+
require(hasRole(role, _msgSender()) || hasRole(role, address(0)), "TimelockController: sender requires permission");
|
88
|
+
_;
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* @dev Contract might receive/hold ETH as part of the maintenance process.
|
93
|
+
*/
|
94
|
+
receive() external payable {}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* @dev Returns whether an id correspond to a registered operation. This
|
98
|
+
* includes both Pending, Ready and Done operations.
|
99
|
+
*/
|
100
|
+
function isOperation(bytes32 id) public view virtual returns (bool pending) {
|
101
|
+
return getTimestamp(id) > 0;
|
102
|
+
}
|
103
|
+
|
104
|
+
/**
|
105
|
+
* @dev Returns whether an operation is pending or not.
|
106
|
+
*/
|
107
|
+
function isOperationPending(bytes32 id) public view virtual returns (bool pending) {
|
108
|
+
return getTimestamp(id) > _DONE_TIMESTAMP;
|
109
|
+
}
|
110
|
+
|
111
|
+
/**
|
112
|
+
* @dev Returns whether an operation is ready or not.
|
113
|
+
*/
|
114
|
+
function isOperationReady(bytes32 id) public view virtual returns (bool ready) {
|
115
|
+
uint256 timestamp = getTimestamp(id);
|
116
|
+
// solhint-disable-next-line not-rely-on-time
|
117
|
+
return timestamp > _DONE_TIMESTAMP && timestamp <= block.timestamp;
|
118
|
+
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* @dev Returns whether an operation is done or not.
|
122
|
+
*/
|
123
|
+
function isOperationDone(bytes32 id) public view virtual returns (bool done) {
|
124
|
+
return getTimestamp(id) == _DONE_TIMESTAMP;
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* @dev Returns the timestamp at with an operation becomes ready (0 for
|
129
|
+
* unset operations, 1 for done operations).
|
130
|
+
*/
|
131
|
+
function getTimestamp(bytes32 id) public view virtual returns (uint256 timestamp) {
|
132
|
+
return _timestamps[id];
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* @dev Returns the minimum delay for an operation to become valid.
|
137
|
+
*
|
138
|
+
* This value can be changed by executing an operation that calls `updateDelay`.
|
139
|
+
*/
|
140
|
+
function getMinDelay() public view virtual returns (uint256 duration) {
|
141
|
+
return _minDelay;
|
142
|
+
}
|
143
|
+
|
144
|
+
/**
|
145
|
+
* @dev Returns the identifier of an operation containing a single
|
146
|
+
* transaction.
|
147
|
+
*/
|
148
|
+
function hashOperation(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt) public pure virtual returns (bytes32 hash) {
|
149
|
+
return keccak256(abi.encode(target, value, data, predecessor, salt));
|
150
|
+
}
|
151
|
+
|
152
|
+
/**
|
153
|
+
* @dev Returns the identifier of an operation containing a batch of
|
154
|
+
* transactions.
|
155
|
+
*/
|
156
|
+
function hashOperationBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt) public pure virtual returns (bytes32 hash) {
|
157
|
+
return keccak256(abi.encode(targets, values, datas, predecessor, salt));
|
158
|
+
}
|
159
|
+
|
160
|
+
/**
|
161
|
+
* @dev Schedule an operation containing a single transaction.
|
162
|
+
*
|
163
|
+
* Emits a {CallScheduled} event.
|
164
|
+
*
|
165
|
+
* Requirements:
|
166
|
+
*
|
167
|
+
* - the caller must have the 'proposer' role.
|
168
|
+
*/
|
169
|
+
function schedule(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt, uint256 delay) public virtual onlyRole(PROPOSER_ROLE) {
|
170
|
+
bytes32 id = hashOperation(target, value, data, predecessor, salt);
|
171
|
+
_schedule(id, delay);
|
172
|
+
emit CallScheduled(id, 0, target, value, data, predecessor, delay);
|
173
|
+
}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* @dev Schedule an operation containing a batch of transactions.
|
177
|
+
*
|
178
|
+
* Emits one {CallScheduled} event per transaction in the batch.
|
179
|
+
*
|
180
|
+
* Requirements:
|
181
|
+
*
|
182
|
+
* - the caller must have the 'proposer' role.
|
183
|
+
*/
|
184
|
+
function scheduleBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt, uint256 delay) public virtual onlyRole(PROPOSER_ROLE) {
|
185
|
+
require(targets.length == values.length, "TimelockController: length mismatch");
|
186
|
+
require(targets.length == datas.length, "TimelockController: length mismatch");
|
187
|
+
|
188
|
+
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
|
189
|
+
_schedule(id, delay);
|
190
|
+
for (uint256 i = 0; i < targets.length; ++i) {
|
191
|
+
emit CallScheduled(id, i, targets[i], values[i], datas[i], predecessor, delay);
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
/**
|
196
|
+
* @dev Schedule an operation that is to becomes valid after a given delay.
|
197
|
+
*/
|
198
|
+
function _schedule(bytes32 id, uint256 delay) private {
|
199
|
+
require(!isOperation(id), "TimelockController: operation already scheduled");
|
200
|
+
require(delay >= getMinDelay(), "TimelockController: insufficient delay");
|
201
|
+
// solhint-disable-next-line not-rely-on-time
|
202
|
+
_timestamps[id] = SafeMath.add(block.timestamp, delay);
|
203
|
+
}
|
204
|
+
|
205
|
+
/**
|
206
|
+
* @dev Cancel an operation.
|
207
|
+
*
|
208
|
+
* Requirements:
|
209
|
+
*
|
210
|
+
* - the caller must have the 'proposer' role.
|
211
|
+
*/
|
212
|
+
function cancel(bytes32 id) public virtual onlyRole(PROPOSER_ROLE) {
|
213
|
+
require(isOperationPending(id), "TimelockController: operation cannot be cancelled");
|
214
|
+
delete _timestamps[id];
|
215
|
+
|
216
|
+
emit Cancelled(id);
|
217
|
+
}
|
218
|
+
|
219
|
+
/**
|
220
|
+
* @dev Execute an (ready) operation containing a single transaction.
|
221
|
+
*
|
222
|
+
* Emits a {CallExecuted} event.
|
223
|
+
*
|
224
|
+
* Requirements:
|
225
|
+
*
|
226
|
+
* - the caller must have the 'executor' role.
|
227
|
+
*/
|
228
|
+
function execute(address target, uint256 value, bytes calldata data, bytes32 predecessor, bytes32 salt) public payable virtual onlyRole(EXECUTOR_ROLE) {
|
229
|
+
bytes32 id = hashOperation(target, value, data, predecessor, salt);
|
230
|
+
_beforeCall(id, predecessor);
|
231
|
+
_call(id, 0, target, value, data);
|
232
|
+
_afterCall(id);
|
233
|
+
}
|
234
|
+
|
235
|
+
/**
|
236
|
+
* @dev Execute an (ready) operation containing a batch of transactions.
|
237
|
+
*
|
238
|
+
* Emits one {CallExecuted} event per transaction in the batch.
|
239
|
+
*
|
240
|
+
* Requirements:
|
241
|
+
*
|
242
|
+
* - the caller must have the 'executor' role.
|
243
|
+
*/
|
244
|
+
function executeBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas, bytes32 predecessor, bytes32 salt) public payable virtual onlyRole(EXECUTOR_ROLE) {
|
245
|
+
require(targets.length == values.length, "TimelockController: length mismatch");
|
246
|
+
require(targets.length == datas.length, "TimelockController: length mismatch");
|
247
|
+
|
248
|
+
bytes32 id = hashOperationBatch(targets, values, datas, predecessor, salt);
|
249
|
+
_beforeCall(id, predecessor);
|
250
|
+
for (uint256 i = 0; i < targets.length; ++i) {
|
251
|
+
_call(id, i, targets[i], values[i], datas[i]);
|
252
|
+
}
|
253
|
+
_afterCall(id);
|
254
|
+
}
|
255
|
+
|
256
|
+
/**
|
257
|
+
* @dev Checks before execution of an operation's calls.
|
258
|
+
*/
|
259
|
+
function _beforeCall(bytes32 id, bytes32 predecessor) private view {
|
260
|
+
require(isOperationReady(id), "TimelockController: operation is not ready");
|
261
|
+
require(predecessor == bytes32(0) || isOperationDone(predecessor), "TimelockController: missing dependency");
|
262
|
+
}
|
263
|
+
|
264
|
+
/**
|
265
|
+
* @dev Checks after execution of an operation's calls.
|
266
|
+
*/
|
267
|
+
function _afterCall(bytes32 id) private {
|
268
|
+
require(isOperationReady(id), "TimelockController: operation is not ready");
|
269
|
+
_timestamps[id] = _DONE_TIMESTAMP;
|
270
|
+
}
|
271
|
+
|
272
|
+
/**
|
273
|
+
* @dev Execute an operation's call.
|
274
|
+
*
|
275
|
+
* Emits a {CallExecuted} event.
|
276
|
+
*/
|
277
|
+
function _call(bytes32 id, uint256 index, address target, uint256 value, bytes calldata data) private {
|
278
|
+
// solhint-disable-next-line avoid-low-level-calls
|
279
|
+
(bool success,) = target.call{value: value}(data);
|
280
|
+
require(success, "TimelockController: underlying transaction reverted");
|
281
|
+
|
282
|
+
emit CallExecuted(id, index, target, value, data);
|
283
|
+
}
|
284
|
+
|
285
|
+
/**
|
286
|
+
* @dev Changes the minimum timelock duration for future operations.
|
287
|
+
*
|
288
|
+
* Emits a {MinDelayChange} event.
|
289
|
+
*
|
290
|
+
* Requirements:
|
291
|
+
*
|
292
|
+
* - the caller must be the timelock itself. This can only be achieved by scheduling and later executing
|
293
|
+
* an operation where the timelock is the target and the data is the ABI-encoded call to this function.
|
294
|
+
*/
|
295
|
+
function updateDelay(uint256 newDelay) external virtual {
|
296
|
+
require(msg.sender == address(this), "TimelockController: caller must be timelock");
|
297
|
+
emit MinDelayChange(_minDelay, newDelay);
|
298
|
+
_minDelay = newDelay;
|
299
|
+
}
|
300
|
+
}
|
@@ -0,0 +1,86 @@
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
2
|
+
|
3
|
+
pragma solidity >=0.6.0 <0.8.0;
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
|
7
|
+
*
|
8
|
+
* These functions can be used to verify that a message was signed by the holder
|
9
|
+
* of the private keys of a given address.
|
10
|
+
*/
|
11
|
+
library ECDSA {
|
12
|
+
/**
|
13
|
+
* @dev Returns the address that signed a hashed message (`hash`) with
|
14
|
+
* `signature`. This address can then be used for verification purposes.
|
15
|
+
*
|
16
|
+
* The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
|
17
|
+
* this function rejects them by requiring the `s` value to be in the lower
|
18
|
+
* half order, and the `v` value to be either 27 or 28.
|
19
|
+
*
|
20
|
+
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
|
21
|
+
* verification to be secure: it is possible to craft signatures that
|
22
|
+
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
|
23
|
+
* this is by receiving a hash of the original message (which may otherwise
|
24
|
+
* be too long), and then calling {toEthSignedMessageHash} on it.
|
25
|
+
*/
|
26
|
+
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
|
27
|
+
// Check the signature length
|
28
|
+
if (signature.length != 65) {
|
29
|
+
revert("ECDSA: invalid signature length");
|
30
|
+
}
|
31
|
+
|
32
|
+
// Divide the signature in r, s and v variables
|
33
|
+
bytes32 r;
|
34
|
+
bytes32 s;
|
35
|
+
uint8 v;
|
36
|
+
|
37
|
+
// ecrecover takes the signature parameters, and the only way to get them
|
38
|
+
// currently is to use assembly.
|
39
|
+
// solhint-disable-next-line no-inline-assembly
|
40
|
+
assembly {
|
41
|
+
r := mload(add(signature, 0x20))
|
42
|
+
s := mload(add(signature, 0x40))
|
43
|
+
v := byte(0, mload(add(signature, 0x60)))
|
44
|
+
}
|
45
|
+
|
46
|
+
return recover(hash, v, r, s);
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`,
|
51
|
+
* `r` and `s` signature fields separately.
|
52
|
+
*/
|
53
|
+
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
|
54
|
+
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
|
55
|
+
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
|
56
|
+
// the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
|
57
|
+
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
|
58
|
+
//
|
59
|
+
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
|
60
|
+
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
|
61
|
+
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
|
62
|
+
// these malleable signatures as well.
|
63
|
+
require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
|
64
|
+
require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");
|
65
|
+
|
66
|
+
// If the signature is valid (and not malleable), return the signer address
|
67
|
+
address signer = ecrecover(hash, v, r, s);
|
68
|
+
require(signer != address(0), "ECDSA: invalid signature");
|
69
|
+
|
70
|
+
return signer;
|
71
|
+
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
* @dev Returns an Ethereum Signed Message, created from a `hash`. This
|
75
|
+
* replicates the behavior of the
|
76
|
+
* https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`]
|
77
|
+
* JSON-RPC method.
|
78
|
+
*
|
79
|
+
* See {recover}.
|
80
|
+
*/
|
81
|
+
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
|
82
|
+
// 32 is the length in bytes of hash,
|
83
|
+
// enforced by the type signature above
|
84
|
+
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
|
85
|
+
}
|
86
|
+
}
|