@lazy-sol/access-control 1.0.6 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md ADDED
@@ -0,0 +1,43 @@
1
+ v1.1.1: Role-based Access Control (RBAC) Inspector
2
+ - Introduced the Role-based Access Control (RBAC) Inspector UI capable of evaluating features and roles
3
+ for already deployed contracts; supports all EVM-based networks (mainnet, sepolia, etc.)
4
+ - Optimized npm imports moving all prod dependencies into dev dependencies
5
+
6
+ v1.1.0: Contact Size Optimizations
7
+
8
+ - __Breaking Change:__ Solidity 0.8.4 is now required to compile the contracts
9
+ (previously was 0.4.22 for the core contract and 0.6.2 for periphery contracts).
10
+ - Replaced "access denied" error with string literal (0.4.22) with the custom error AccessDenied() (0.8.4)
11
+ - Introduced lighter modification of the "AccessControl" RBAC contract – "AccessControlCore" (RBAC-C).
12
+ The 'core' version of the RBAC contract hides three rarely used external functions from the public ABI,
13
+ making them internal and thus reducing the overall compiled implementation size.
14
+
15
+ | old name | old modifier | new name | new modifier |
16
+ |----------------------|--------------|-----------------------|--------------|
17
+ | `isFeatureEnabled()` | `public` | `isFeatureEnabled()` | `internal` |
18
+ | `isSenderInRole()` | `public` | `_isSenderInRole()` | `internal` |
19
+ | `isOperatorInRole()` | `public` | `_isOperatorInRole()` | `internal` |
20
+
21
+ - Added `_requireSenderInRole()` and `_requireAccessCondition()` internal functions for a convenient and gas-efficient
22
+ way of checking the access permissions and throwing the AccessDenied() error.
23
+ - Added the CHANGELOG (this file)
24
+
25
+ v1.0.7:
26
+ - Exported the RBAC behavior
27
+
28
+ v1.0.6:
29
+ - Updated the documentation
30
+
31
+ v1.0.5:
32
+ - Exported RBAC JavaScript constants and functions
33
+
34
+ v1.0.4:
35
+ - Fixed broken dependencies
36
+ - Upgraded npm libraries
37
+ - Added Sepolia network support
38
+
39
+ v1.0.3:
40
+ - Allowed lower versions of Hardhat to be used
41
+
42
+ v1.0.2:
43
+ - Optimized npm dependencies
package/README.md CHANGED
@@ -65,7 +65,7 @@ features and roles. Usually, smart contracts use different values for all the fe
65
65
  next section).
66
66
 
67
67
  Access manager may revoke its own permissions, including the bit 255. Eventually that allows an access manager to let
68
- the smart contract “float freely” and be controlled only by the community (via DAO) or by no one at all.
68
+ the smart contract “float freely” and be controlled only by the community (via the DAO) or by no one at all.
69
69
 
70
70
  ## Comparing with OpenZeppelin
71
71
 
@@ -73,7 +73,7 @@ Both our and OpenZeppelin Access Control implementations feature a similar API t
73
73
  thing".
74
74
 
75
75
  Zeppelin implementation is more flexible:
76
- * it allows setting unlimited number of roles, while current is limited to 256 different roles
76
+ * it allows setting an unlimited number of roles, while current is limited to 256 different roles
77
77
  * it allows setting an admin for each role, while current allows having only one global admin
78
78
 
79
79
  Our implementation is more lightweight:
@@ -81,21 +81,6 @@ Our implementation is more lightweight:
81
81
  * it allows setting up to 256 roles at once, in a single transaction, while Zeppelin allows setting only one role in a
82
82
  single transaction
83
83
 
84
- ## Upgradeability
85
-
86
- [Upgradeable Access Control](https://github.com/lazy-sol/access-control-upgradeable) is a Role-based Access Control
87
- extension supporting the OpenZeppelin UUPS Proxy upgrades. Smart contracts inheriting from the
88
- `UpgradeableAccessControl` can be deployed behind the ERC1967 proxy and will get the upgradeability mechanism setup.
89
-
90
- Upgradeable Access Control introduces another “special” permission bit 254 which is reserved for an upgrade manager role
91
- `ROLE_UPGRADE_MANAGER` which is allowed to and is responsible for implementation upgrades of the ERC1967 Proxy.
92
-
93
- Being controlled by the upgrade manager, the upgradeability is also a revocable feature of the smart contract: the
94
- `upgradeTo` restricted function access can be revoked from all the admin accounts.
95
-
96
- The best practice is to disable contract upgradeability when the protocol is mature enough and has already proven its
97
- security and stability.
98
-
99
84
  ## Installation
100
85
  ```
101
86
  npm i -D @lazy-sol/access-control
@@ -108,11 +93,11 @@ npm i -D @lazy-sol/access-control
108
93
  Restricted function is a function with a `public` Solidity modifier access to which is restricted
109
94
  so that only a pre-configured set of accounts can execute it.
110
95
 
111
- 1. Enable role-based access control (RBAC) in a new smart contract
112
- by inheriting the RBAC contract from the [AccessControl](./contracts/AccessControl.sol) contract:
96
+ 1. Enable role-based access control (RBAC) in a new smart contract
97
+ by inheriting the RBAC contract from the [AccessControlCore](./contracts/AccessControlCore.sol) contract:
113
98
  ```solidity
114
99
  import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
115
- import "@lazy-sol/access-control/contracts/AccessControl.sol";
100
+ import "@lazy-sol/access-control/contracts/AccessControlCore.sol";
116
101
 
117
102
  /**
118
103
  * @title Simple ERC20 Implementation
@@ -121,29 +106,29 @@ so that only a pre-configured set of accounts can execute it.
121
106
  *
122
107
  * @author Lazy So[u]l
123
108
  */
124
- contract MyERC20Token is ERC20, AccessControl {
109
+ contract MyERC20Token is ERC20, AccessControlCore {
125
110
 
126
111
  ...
127
112
 
128
113
  }
129
114
  ```
130
115
 
131
- 2. Define an access control role with the unique integer value:
116
+ 2. Define an access control role with the unique integer value:
132
117
  ```solidity
133
118
  ...
134
119
 
135
120
  /**
136
121
  * @notice Token creator is responsible for creating (minting)
137
- tokens to an arbitrary address
122
+ * tokens to an arbitrary address
138
123
  * @dev Role ROLE_TOKEN_CREATOR allows minting tokens
139
- (calling `mint` function)
124
+ * (calling `mint` function)
140
125
  */
141
126
  uint32 public constant ROLE_TOKEN_CREATOR = 0x0001_0000;
142
127
 
143
128
  ...
144
129
  ```
145
130
 
146
- 3. Add the `require(isSenderInRole(ROLE_TOKEN_CREATOR), "access denied")"` check into the function body:
131
+ 3. Add the `_requireSenderInRole(ROLE_TOKEN_CREATOR)` check into the function body:
147
132
  ```solidity
148
133
  ...
149
134
 
@@ -152,7 +137,7 @@ so that only a pre-configured set of accounts can execute it.
152
137
  */
153
138
  function _mint(address _to, uint256 _value) internal virtual override {
154
139
  // check if caller has sufficient permissions to mint tokens
155
- require(isSenderInRole(ROLE_TOKEN_CREATOR), "access denied");
140
+ _requireSenderInRole(ROLE_TOKEN_CREATOR);
156
141
 
157
142
  // delegate to super implementation
158
143
  super._mint(_to, _value);
@@ -161,8 +146,8 @@ so that only a pre-configured set of accounts can execute it.
161
146
  ...
162
147
  ```
163
148
 
164
- Note: you could also use the `restrictedTo` modifier in the function declaration instead of the `require`
165
- in the function body if you don't need a custom error message:
149
+ Note: it is also possible to use the `restrictedTo` modifier in the function declaration instead of the `require`
150
+ in the function body if this better suits the coding style:
166
151
  ```solidity
167
152
  ...
168
153
 
@@ -177,6 +162,31 @@ so that only a pre-configured set of accounts can execute it.
177
162
  ...
178
163
  ```
179
164
 
165
+ ### Customizing the Error Message
166
+
167
+ Modifier `restrictedTo()`, internal functions `_requireSenderInRole()` and `_requireAccessCondition()` throw the
168
+ `AccessDenied` denied error when access check fails.
169
+
170
+ It is also possible to use your own custom errors or string messages if needed by leveraging a lower level boolean
171
+ functions `_isSenderInRole()` and `_isOperatorInRole()`:
172
+
173
+ ```solidity
174
+ ...
175
+
176
+ /**
177
+ * @inheritdoc ERC20
178
+ */
179
+ function _mint(address _to, uint256 _value) internal virtual override {
180
+ // check if caller has sufficient permissions to mint tokens
181
+ require(_isSenderInRole(ROLE_TOKEN_CREATOR), "access denied");
182
+
183
+ // delegate to super implementation
184
+ super._mint(_to, _value);
185
+ }
186
+
187
+ ...
188
+ ```
189
+
180
190
  Examples:
181
191
  [ERC20Impl](https://raw.githubusercontent.com/vgorin/solidity-template/master/contracts/token/ERC20Impl.sol),
182
192
  [ERC721Impl](https://raw.githubusercontent.com/vgorin/solidity-template/master/contracts/token/ERC721Impl.sol).
@@ -192,32 +202,32 @@ Many deployed contracts are using this model, and when the time comes to switch
192
202
 
193
203
  Prerequisite: deployed OZ Ownable contract (target contract) address (target_address)
194
204
 
195
- 1. Deploy the AccessControl Adapter bound to the already deployed OZ Ownable contract
196
- (specify the target OZ Ownable contract address in the constructor upon the deployment)
205
+ 1. Deploy the AccessControl Adapter bound to the already deployed OZ Ownable contract
206
+ (specify the target OZ Ownable contract address in the constructor upon the deployment)
197
207
  ```javascript
198
208
  const adapter = await (artifacts.require("OwnableToAccessControlAdapter")).new(target_address);
199
209
  ```
200
210
 
201
- 2. Define what Ownable-restricted public functions on the target contract you'd like to be able
202
- to provide access to through the adapter contract
211
+ 2. Define what Ownable-restricted public functions on the target contract you'd like to be able
212
+ to provide access to through the adapter contract
203
213
 
204
- 3. Map every such function with the role required to execute it using `updateAccessRole()` function
205
- For example, to be able to provide an access to the transferOwnership(address) function, you could do
214
+ 3. Map every such function with the role required to execute it using `updateAccessRole()` function
215
+ For example, to be able to provide an access to the transferOwnership(address) function, you could do
206
216
  ```javascript
207
217
  const ROLE_TRANSFER_OWNERSHIP_MANAGER = 0x00010000;
208
218
  await adapter.updateAccessRole("transferOwnership(address)", ROLE_TRANSFER_OWNERSHIP_MANAGER);
209
- ```
219
+ ```
210
220
 
211
- 4. Provide the roles to the corresponding operators as you would usually do with AccessControl
212
- For example, if you wish an address 0x00000000000000000000000000000000000Ff1CE to grant an access to the
213
- transferOwnership(address) function on the target, you could do
221
+ 4. Provide the roles to the corresponding operators as you would usually do with AccessControl
222
+ For example, if you wish an address 0x00000000000000000000000000000000000Ff1CE to grant an access to the
223
+ transferOwnership(address) function on the target, you could do
214
224
  ```javascript
215
225
  const operator = "0x00000000000000000000000000000000000Ff1CE";
216
226
  await adapter.updateRole(operator, ROLE_TRANSFER_OWNERSHIP_MANAGER);
217
227
  ```
218
228
 
219
- 5. Transfer the ownership of the target contract to the deployed AccessControl Adapter contract
220
- Note that you can also do steps 2-4 after the step 5
229
+ 5. Transfer the ownership of the target contract to the deployed AccessControl Adapter contract
230
+ Note that you can also do steps 2-4 after the step 5
221
231
 
222
232
  #### Usage Flow
223
233
 
@@ -225,16 +235,16 @@ Prerequisite: installed AccessControl Adapter with the access to at least one re
225
235
  function configured
226
236
 
227
237
  To execute the restricted access function on the target contract via the AccessControl Adapter
228
- 1. Use target contract ABI to construct a low-level function call calldata
229
- For example, to construct the transferOwnership() function calldata to transfer the ownership to the
230
- 0x00000000000000000000000000000000DEAdc0De address, you could do
238
+ 1. Use target contract ABI to construct a low-level function call calldata
239
+ For example, to construct the transferOwnership() function calldata to transfer the ownership to the
240
+ 0x00000000000000000000000000000000DEAdc0De address, you could do
231
241
  ```javascript
232
242
  const to = "0x00000000000000000000000000000000DEAdc0De";
233
243
  const calldata = target.contract.methods.transferOwnership(to).encodeABI();
234
244
  ```
235
245
 
236
- 2. Execute a low-level function call on the AccessControl Adapter contract using the constructed calldata
237
- For example, to execute the transferOwnership() function (prepared in step 1), you could do
246
+ 2. Execute a low-level function call on the AccessControl Adapter contract using the constructed calldata
247
+ For example, to execute the transferOwnership() function (prepared in step 1), you could do
238
248
  ```javascript
239
249
  await web3.eth.sendTransaction({
240
250
  from: operator,
@@ -243,9 +253,20 @@ To execute the restricted access function on the target contract via the AccessC
243
253
  }
244
254
  ```
245
255
 
246
- 3. It is also ok to add an ether to the transaction by adding a value field to the `sendTransaction` call,
247
- as well as sending plain ether transfer transaction, as long as target contract has payable functions,
248
- and/or has a default payable receiver
256
+ 3. It is also ok to add an ether to the transaction by adding a value field to the `sendTransaction` call,
257
+ as well as sending plain ether transfer transaction, as long as target contract has payable functions,
258
+ and/or has a default payable receiver
259
+
260
+ ## Evaluating Currently Enabled Features and Roles on the Deployed Contract
261
+
262
+ 1. To evaluate currently enabled features use
263
+ * `features()` function, or
264
+ * `getRole(this)` function, replacing `this` with the deployed contract address
265
+ 2. To evaluate currently enabled permissions for a **particular** address use
266
+ * `getRole(address)` function
267
+ 3. To find **all** the addresses having any permissions, track the `RoleUpdated()` event and evaluate the history
268
+ of `assiged` roles for every `operator` address
269
+ * Alternatively, use the [tool](ui.html) which automates the process
249
270
 
250
271
  ## Contributing
251
272
  Please see the [Contribution Guide](./CONTRIBUTING.md) document to get understanding on how to report issues,
@@ -19,6 +19,11 @@
19
19
  "stateMutability": "nonpayable",
20
20
  "type": "constructor"
21
21
  },
22
+ {
23
+ "inputs": [],
24
+ "name": "AccessDenied",
25
+ "type": "error"
26
+ },
22
27
  {
23
28
  "anonymous": false,
24
29
  "inputs": [
@@ -188,68 +193,6 @@
188
193
  "stateMutability": "view",
189
194
  "type": "function"
190
195
  },
191
- {
192
- "inputs": [
193
- {
194
- "internalType": "uint256",
195
- "name": "required",
196
- "type": "uint256"
197
- }
198
- ],
199
- "name": "isFeatureEnabled",
200
- "outputs": [
201
- {
202
- "internalType": "bool",
203
- "name": "",
204
- "type": "bool"
205
- }
206
- ],
207
- "stateMutability": "view",
208
- "type": "function"
209
- },
210
- {
211
- "inputs": [
212
- {
213
- "internalType": "address",
214
- "name": "operator",
215
- "type": "address"
216
- },
217
- {
218
- "internalType": "uint256",
219
- "name": "required",
220
- "type": "uint256"
221
- }
222
- ],
223
- "name": "isOperatorInRole",
224
- "outputs": [
225
- {
226
- "internalType": "bool",
227
- "name": "",
228
- "type": "bool"
229
- }
230
- ],
231
- "stateMutability": "view",
232
- "type": "function"
233
- },
234
- {
235
- "inputs": [
236
- {
237
- "internalType": "uint256",
238
- "name": "required",
239
- "type": "uint256"
240
- }
241
- ],
242
- "name": "isSenderInRole",
243
- "outputs": [
244
- {
245
- "internalType": "bool",
246
- "name": "",
247
- "type": "bool"
248
- }
249
- ],
250
- "stateMutability": "view",
251
- "type": "function"
252
- },
253
196
  {
254
197
  "inputs": [],
255
198
  "name": "target",
@@ -335,8 +278,8 @@
335
278
  "type": "receive"
336
279
  }
337
280
  ],
338
- "bytecode": "0x608060405234801561001057600080fd5b50604051610b40380380610b4083398101604081905261002f9161012f565b80600061003f82600019806100bb565b61004a3082806100bb565b50506001600160a01b0382166100955760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b604482015260640160405180910390fd5b50600180546001600160a01b0319166001600160a01b0392909216919091179055610162565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b80516001600160a01b038116811461012a57600080fd5b919050565b6000806040838503121561014257600080fd5b61014b83610113565b915061015960208401610113565b90509250929050565b6109cf806101716000396000f3fe6080604052600436106100e15760003560e01c8063725f36261161007f578063c688d69311610059578063c688d693146102bc578063d4b83992146102dc578063d5bb7f6714610314578063fcc2c0781461033457610100565b8063725f362614610254578063ae5b102e14610284578063ae682e2e146102a457610100565b806334e48c9e116100bb57806334e48c9e146101c657806344276733146101de578063491d2611146102145780635defb40d1461023457610100565b806309c5eabe146101405780630e82fe25146101695780632b521416146101a457610100565b36610100576100fe60405180602001604052806000815250610354565b005b6100fe6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061035492505050565b61015361014e366004610742565b610354565b60405161016091906107e3565b60405180910390f35b34801561017557600080fd5b50610196610184366004610813565b60026020526000908152604090205481565b604051908152602001610160565b3480156101b057600080fd5b5030600090815260208190526040902054610196565b3480156101d257600080fd5b50610196600160fd1b81565b3480156101ea57600080fd5b506101966101f9366004610845565b6001600160a01b031660009081526020819052604090205490565b34801561022057600080fd5b506100fe61022f366004610860565b6104de565b34801561024057600080fd5b506100fe61024f36600461088a565b610560565b34801561026057600080fd5b5061027461026f3660046108e3565b610575565b6040519015158152602001610160565b34801561029057600080fd5b506100fe61029f3660046108fc565b610597565b3480156102b057600080fd5b50610196600160ff1b81565b3480156102c857600080fd5b506102746102d73660046108fc565b61061c565b3480156102e857600080fd5b506001546102fc906001600160a01b031681565b6040516001600160a01b039091168152602001610160565b34801561032057600080fd5b506100fe61032f3660046108e3565b610645565b34801561034057600080fd5b5061027461034f3660046108e3565b610652565b6020810151815160609190156103f0576001600160e01b03198116600090815260026020526040812054908190036103c95760405162461bcd60e51b81526020600482015260136024820152721858d8d95cdcc81c9bdb19481b9bdd081cd95d606a1b60448201526064015b60405180910390fd5b6103d281610652565b6103ee5760405162461bcd60e51b81526004016103c090610918565b505b60015460405160009182916001600160a01b0390911690349061041490889061093f565b60006040518083038185875af1925050503d8060008114610451576040519150601f19603f3d011682016040523d82523d6000602084013e610456565b606091505b50915091508161049b5760405162461bcd60e51b815260206004820152601060248201526f195e1958dd5d1a5bdb8819985a5b195960821b60448201526064016103c0565b7f57a62eca76fc623c92f161d2a4b851851ece707135ce2af1eec256d660571b6d8386836040516104ce9392919061095b565b60405180910390a1949350505050565b6104eb600160fd1b610652565b6105075760405162461bcd60e51b81526004016103c090610918565b6001600160e01b03198216600081815260026020908152604091829020849055815192835282018390527fdb8ed917742b49e83acd1322bcaa8f18b1e5f78a70784c43ea14db7ab50e628d910160405180910390a15050565b6105718280519060200120826104de565b5050565b30600090815260208190526040812054610591905b8316831490565b92915050565b6105a4600160ff1b610652565b6105c05760405162461bcd60e51b81526004016103c090610918565b6105718282610617336105e8876001600160a01b031660009081526020819052604090205490565b6001600160a01b0391909116600090815260208190526040902054600019808818821618908716919091171690565b61065e565b6001600160a01b03821660009081526020819052604081205461063e9061058a565b9392505050565b61064f3082610597565b50565b6000610591338361061c565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156106e7576106e76106b6565b604051601f8501601f19908116603f0116810190828211818310171561070f5761070f6106b6565b8160405280935085815286868601111561072857600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561075457600080fd5b813567ffffffffffffffff81111561076b57600080fd5b8201601f8101841361077c57600080fd5b61078b848235602084016106cc565b949350505050565b60005b838110156107ae578181015183820152602001610796565b50506000910152565b600081518084526107cf816020860160208601610793565b601f01601f19169290920160200192915050565b60208152600061063e60208301846107b7565b80356001600160e01b03198116811461080e57600080fd5b919050565b60006020828403121561082557600080fd5b61063e826107f6565b80356001600160a01b038116811461080e57600080fd5b60006020828403121561085757600080fd5b61063e8261082e565b6000806040838503121561087357600080fd5b61087c836107f6565b946020939093013593505050565b6000806040838503121561089d57600080fd5b823567ffffffffffffffff8111156108b457600080fd5b8301601f810185136108c557600080fd5b6108d4858235602084016106cc565b95602094909401359450505050565b6000602082840312156108f557600080fd5b5035919050565b6000806040838503121561090f57600080fd5b61087c8361082e565b6020808252600d908201526c1858d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251610951818460208701610793565b9190910192915050565b63ffffffff60e01b8416815260606020820152600061097d60608301856107b7565b828103604084015261098f81856107b7565b969550505050505056fea26469706673582212206993ad950cca82a01e8e72c0503e3a006930148e125b67ad2894063853f6078264736f6c63430008150033",
339
- "deployedBytecode": "0x6080604052600436106100e15760003560e01c8063725f36261161007f578063c688d69311610059578063c688d693146102bc578063d4b83992146102dc578063d5bb7f6714610314578063fcc2c0781461033457610100565b8063725f362614610254578063ae5b102e14610284578063ae682e2e146102a457610100565b806334e48c9e116100bb57806334e48c9e146101c657806344276733146101de578063491d2611146102145780635defb40d1461023457610100565b806309c5eabe146101405780630e82fe25146101695780632b521416146101a457610100565b36610100576100fe60405180602001604052806000815250610354565b005b6100fe6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061035492505050565b61015361014e366004610742565b610354565b60405161016091906107e3565b60405180910390f35b34801561017557600080fd5b50610196610184366004610813565b60026020526000908152604090205481565b604051908152602001610160565b3480156101b057600080fd5b5030600090815260208190526040902054610196565b3480156101d257600080fd5b50610196600160fd1b81565b3480156101ea57600080fd5b506101966101f9366004610845565b6001600160a01b031660009081526020819052604090205490565b34801561022057600080fd5b506100fe61022f366004610860565b6104de565b34801561024057600080fd5b506100fe61024f36600461088a565b610560565b34801561026057600080fd5b5061027461026f3660046108e3565b610575565b6040519015158152602001610160565b34801561029057600080fd5b506100fe61029f3660046108fc565b610597565b3480156102b057600080fd5b50610196600160ff1b81565b3480156102c857600080fd5b506102746102d73660046108fc565b61061c565b3480156102e857600080fd5b506001546102fc906001600160a01b031681565b6040516001600160a01b039091168152602001610160565b34801561032057600080fd5b506100fe61032f3660046108e3565b610645565b34801561034057600080fd5b5061027461034f3660046108e3565b610652565b6020810151815160609190156103f0576001600160e01b03198116600090815260026020526040812054908190036103c95760405162461bcd60e51b81526020600482015260136024820152721858d8d95cdcc81c9bdb19481b9bdd081cd95d606a1b60448201526064015b60405180910390fd5b6103d281610652565b6103ee5760405162461bcd60e51b81526004016103c090610918565b505b60015460405160009182916001600160a01b0390911690349061041490889061093f565b60006040518083038185875af1925050503d8060008114610451576040519150601f19603f3d011682016040523d82523d6000602084013e610456565b606091505b50915091508161049b5760405162461bcd60e51b815260206004820152601060248201526f195e1958dd5d1a5bdb8819985a5b195960821b60448201526064016103c0565b7f57a62eca76fc623c92f161d2a4b851851ece707135ce2af1eec256d660571b6d8386836040516104ce9392919061095b565b60405180910390a1949350505050565b6104eb600160fd1b610652565b6105075760405162461bcd60e51b81526004016103c090610918565b6001600160e01b03198216600081815260026020908152604091829020849055815192835282018390527fdb8ed917742b49e83acd1322bcaa8f18b1e5f78a70784c43ea14db7ab50e628d910160405180910390a15050565b6105718280519060200120826104de565b5050565b30600090815260208190526040812054610591905b8316831490565b92915050565b6105a4600160ff1b610652565b6105c05760405162461bcd60e51b81526004016103c090610918565b6105718282610617336105e8876001600160a01b031660009081526020819052604090205490565b6001600160a01b0391909116600090815260208190526040902054600019808818821618908716919091171690565b61065e565b6001600160a01b03821660009081526020819052604081205461063e9061058a565b9392505050565b61064f3082610597565b50565b6000610591338361061c565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156106e7576106e76106b6565b604051601f8501601f19908116603f0116810190828211818310171561070f5761070f6106b6565b8160405280935085815286868601111561072857600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561075457600080fd5b813567ffffffffffffffff81111561076b57600080fd5b8201601f8101841361077c57600080fd5b61078b848235602084016106cc565b949350505050565b60005b838110156107ae578181015183820152602001610796565b50506000910152565b600081518084526107cf816020860160208601610793565b601f01601f19169290920160200192915050565b60208152600061063e60208301846107b7565b80356001600160e01b03198116811461080e57600080fd5b919050565b60006020828403121561082557600080fd5b61063e826107f6565b80356001600160a01b038116811461080e57600080fd5b60006020828403121561085757600080fd5b61063e8261082e565b6000806040838503121561087357600080fd5b61087c836107f6565b946020939093013593505050565b6000806040838503121561089d57600080fd5b823567ffffffffffffffff8111156108b457600080fd5b8301601f810185136108c557600080fd5b6108d4858235602084016106cc565b95602094909401359450505050565b6000602082840312156108f557600080fd5b5035919050565b6000806040838503121561090f57600080fd5b61087c8361082e565b6020808252600d908201526c1858d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251610951818460208701610793565b9190910192915050565b63ffffffff60e01b8416815260606020820152600061097d60608301856107b7565b828103604084015261098f81856107b7565b969550505050505056fea26469706673582212206993ad950cca82a01e8e72c0503e3a006930148e125b67ad2894063853f6078264736f6c63430008150033",
281
+ "bytecode": "0x608060405234801561001057600080fd5b50604051610a23380380610a2383398101604081905261002f9161012f565b80600061003f82600019806100bb565b61004a3082806100bb565b50506001600160a01b0382166100955760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b604482015260640160405180910390fd5b50600180546001600160a01b0319166001600160a01b0392909216919091179055610162565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b80516001600160a01b038116811461012a57600080fd5b919050565b6000806040838503121561014257600080fd5b61014b83610113565b915061015960208401610113565b90509250929050565b6108b2806101716000396000f3fe6080604052600436106100a05760003560e01c8063491d261111610064578063491d2611146101d35780635defb40d146101f3578063ae5b102e14610213578063ae682e2e14610233578063d4b839921461024b578063d5bb7f6714610283576100bf565b806309c5eabe146100ff5780630e82fe25146101285780632b5214161461016357806334e48c9e14610185578063442767331461019d576100bf565b366100bf576100bd604051806020016040528060008152506102a3565b005b6100bd6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102a392505050565b61011261010d36600461064c565b6102a3565b60405161011f91906106ed565b60405180910390f35b34801561013457600080fd5b5061015561014336600461071d565b60026020526000908152604090205481565b60405190815260200161011f565b34801561016f57600080fd5b5030600090815260208190526040902054610155565b34801561019157600080fd5b50610155600160fd1b81565b3480156101a957600080fd5b506101556101b836600461074f565b6001600160a01b031660009081526020819052604090205490565b3480156101df57600080fd5b506100bd6101ee36600461076a565b610411565b3480156101ff57600080fd5b506100bd61020e366004610794565b610477565b34801561021f57600080fd5b506100bd61022e3660046107ed565b61048c565b34801561023f57600080fd5b50610155600160ff1b81565b34801561025757600080fd5b5060015461026b906001600160a01b031681565b6040516001600160a01b03909116815260200161011f565b34801561028f57600080fd5b506100bd61029e366004610809565b6104f5565b602081015181516060919015610323576001600160e01b03198116600090815260026020526040812054908190036103185760405162461bcd60e51b81526020600482015260136024820152721858d8d95cdcc81c9bdb19481b9bdd081cd95d606a1b60448201526064015b60405180910390fd5b61032181610502565b505b60015460405160009182916001600160a01b03909116903490610347908890610822565b60006040518083038185875af1925050503d8060008114610384576040519150601f19603f3d011682016040523d82523d6000602084013e610389565b606091505b5091509150816103ce5760405162461bcd60e51b815260206004820152601060248201526f195e1958dd5d1a5bdb8819985a5b195960821b604482015260640161030f565b7f57a62eca76fc623c92f161d2a4b851851ece707135ce2af1eec256d660571b6d8386836040516104019392919061083e565b60405180910390a1949350505050565b61041e600160fd1b610502565b6001600160e01b03198216600081815260026020908152604091829020849055815192835282018390527fdb8ed917742b49e83acd1322bcaa8f18b1e5f78a70784c43ea14db7ab50e628d910160405180910390a15050565b610488828051906020012082610411565b5050565b610499600160ff1b610502565b61048882826104f0336104c1876001600160a01b031660009081526020819052604090205490565b6001600160a01b0391909116600090815260208190526040902054600019808818821618908716919091171690565b610513565b6104ff308261048c565b50565b6104ff61050e8261056b565b61057d565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b6000610577338361059b565b92915050565b806104ff57604051634ca8886760e01b815260040160405180910390fd5b6001600160a01b038216600090815260208190526040812054821682145b9392505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156105f1576105f16105c0565b604051601f8501601f19908116603f01168101908282118183101715610619576106196105c0565b8160405280935085815286868601111561063257600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561065e57600080fd5b813567ffffffffffffffff81111561067557600080fd5b8201601f8101841361068657600080fd5b610695848235602084016105d6565b949350505050565b60005b838110156106b85781810151838201526020016106a0565b50506000910152565b600081518084526106d981602086016020860161069d565b601f01601f19169290920160200192915050565b6020815260006105b960208301846106c1565b80356001600160e01b03198116811461071857600080fd5b919050565b60006020828403121561072f57600080fd5b6105b982610700565b80356001600160a01b038116811461071857600080fd5b60006020828403121561076157600080fd5b6105b982610738565b6000806040838503121561077d57600080fd5b61078683610700565b946020939093013593505050565b600080604083850312156107a757600080fd5b823567ffffffffffffffff8111156107be57600080fd5b8301601f810185136107cf57600080fd5b6107de858235602084016105d6565b95602094909401359450505050565b6000806040838503121561080057600080fd5b61078683610738565b60006020828403121561081b57600080fd5b5035919050565b6000825161083481846020870161069d565b9190910192915050565b63ffffffff60e01b8416815260606020820152600061086060608301856106c1565b828103604084015261087281856106c1565b969550505050505056fea26469706673582212201ba377eb6a91d1e61a05796e2c3f7b98c258168e3db52e709dd2c3a003d3eb7864736f6c63430008150033",
282
+ "deployedBytecode": "0x6080604052600436106100a05760003560e01c8063491d261111610064578063491d2611146101d35780635defb40d146101f3578063ae5b102e14610213578063ae682e2e14610233578063d4b839921461024b578063d5bb7f6714610283576100bf565b806309c5eabe146100ff5780630e82fe25146101285780632b5214161461016357806334e48c9e14610185578063442767331461019d576100bf565b366100bf576100bd604051806020016040528060008152506102a3565b005b6100bd6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102a392505050565b61011261010d36600461064c565b6102a3565b60405161011f91906106ed565b60405180910390f35b34801561013457600080fd5b5061015561014336600461071d565b60026020526000908152604090205481565b60405190815260200161011f565b34801561016f57600080fd5b5030600090815260208190526040902054610155565b34801561019157600080fd5b50610155600160fd1b81565b3480156101a957600080fd5b506101556101b836600461074f565b6001600160a01b031660009081526020819052604090205490565b3480156101df57600080fd5b506100bd6101ee36600461076a565b610411565b3480156101ff57600080fd5b506100bd61020e366004610794565b610477565b34801561021f57600080fd5b506100bd61022e3660046107ed565b61048c565b34801561023f57600080fd5b50610155600160ff1b81565b34801561025757600080fd5b5060015461026b906001600160a01b031681565b6040516001600160a01b03909116815260200161011f565b34801561028f57600080fd5b506100bd61029e366004610809565b6104f5565b602081015181516060919015610323576001600160e01b03198116600090815260026020526040812054908190036103185760405162461bcd60e51b81526020600482015260136024820152721858d8d95cdcc81c9bdb19481b9bdd081cd95d606a1b60448201526064015b60405180910390fd5b61032181610502565b505b60015460405160009182916001600160a01b03909116903490610347908890610822565b60006040518083038185875af1925050503d8060008114610384576040519150601f19603f3d011682016040523d82523d6000602084013e610389565b606091505b5091509150816103ce5760405162461bcd60e51b815260206004820152601060248201526f195e1958dd5d1a5bdb8819985a5b195960821b604482015260640161030f565b7f57a62eca76fc623c92f161d2a4b851851ece707135ce2af1eec256d660571b6d8386836040516104019392919061083e565b60405180910390a1949350505050565b61041e600160fd1b610502565b6001600160e01b03198216600081815260026020908152604091829020849055815192835282018390527fdb8ed917742b49e83acd1322bcaa8f18b1e5f78a70784c43ea14db7ab50e628d910160405180910390a15050565b610488828051906020012082610411565b5050565b610499600160ff1b610502565b61048882826104f0336104c1876001600160a01b031660009081526020819052604090205490565b6001600160a01b0391909116600090815260208190526040902054600019808818821618908716919091171690565b610513565b6104ff308261048c565b50565b6104ff61050e8261056b565b61057d565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b6000610577338361059b565b92915050565b806104ff57604051634ca8886760e01b815260040160405180910390fd5b6001600160a01b038216600090815260208190526040812054821682145b9392505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156105f1576105f16105c0565b604051601f8501601f19908116603f01168101908282118183101715610619576106196105c0565b8160405280935085815286868601111561063257600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561065e57600080fd5b813567ffffffffffffffff81111561067557600080fd5b8201601f8101841361068657600080fd5b610695848235602084016105d6565b949350505050565b60005b838110156106b85781810151838201526020016106a0565b50506000910152565b600081518084526106d981602086016020860161069d565b601f01601f19169290920160200192915050565b6020815260006105b960208301846106c1565b80356001600160e01b03198116811461071857600080fd5b919050565b60006020828403121561072f57600080fd5b6105b982610700565b80356001600160a01b038116811461071857600080fd5b60006020828403121561076157600080fd5b6105b982610738565b6000806040838503121561077d57600080fd5b61078683610700565b946020939093013593505050565b600080604083850312156107a757600080fd5b823567ffffffffffffffff8111156107be57600080fd5b8301601f810185136107cf57600080fd5b6107de858235602084016105d6565b95602094909401359450505050565b6000806040838503121561080057600080fd5b61078683610738565b60006020828403121561081b57600080fd5b5035919050565b6000825161083481846020870161069d565b9190910192915050565b63ffffffff60e01b8416815260606020820152600061086060608301856106c1565b828103604084015261087281856106c1565b969550505050505056fea26469706673582212201ba377eb6a91d1e61a05796e2c3f7b98c258168e3db52e709dd2c3a003d3eb7864736f6c63430008150033",
340
283
  "linkReferences": {},
341
284
  "deployedLinkReferences": {}
342
285
  }