@lazy-sol/access-control 1.0.6 → 1.1.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/CHANGELOG.md +43 -0
- package/README.md +69 -48
- package/artifacts/contracts/OwnableToAccessControlAdapter.sol/OwnableToAccessControlAdapter.json +7 -64
- package/contracts/AccessControl.sol +15 -219
- package/contracts/AccessControlCore.sol +353 -0
- package/contracts/AdapterFactory.sol +1 -1
- package/contracts/OwnableToAccessControlAdapter.sol +7 -5
- package/contracts/mocks/AccessControlMock.sol +7 -1
- package/hardhat.config.js +6 -6
- package/index.js +4 -0
- package/package.json +12 -10
- package/test/include/deployment_routines.js +3 -12
- package/test/include/rbac.behaviour.js +22 -7
- package/test/ownable_to_rbac_adapter.js +1 -1
- package/test/ownable_to_rbac_adapter_rbac.js +3 -3
- package/test/rbac_modifier.js +1 -1
- package/ui.html +506 -0
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.
|
112
|
-
|
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/
|
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,
|
109
|
+
contract MyERC20Token is ERC20, AccessControlCore {
|
125
110
|
|
126
111
|
...
|
127
112
|
|
128
113
|
}
|
129
114
|
```
|
130
115
|
|
131
|
-
2.
|
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.
|
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
|
-
|
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
|
-
|
165
|
-
|
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.
|
196
|
-
|
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.
|
202
|
-
|
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.
|
205
|
-
|
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.
|
212
|
-
|
213
|
-
|
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.
|
220
|
-
|
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.
|
229
|
-
|
230
|
-
|
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.
|
237
|
-
|
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.
|
247
|
-
|
248
|
-
|
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,
|
package/artifacts/contracts/OwnableToAccessControlAdapter.sol/OwnableToAccessControlAdapter.json
CHANGED
@@ -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": "
|
339
|
-
"deployedBytecode": "
|
281
|
+
"bytecode": "0x608060405234801561001057600080fd5b50604051610a23380380610a2383398101604081905261002f9161012f565b80600061003f82600019806100bb565b61004a3082806100bb565b50506001600160a01b0382166100955760405162461bcd60e51b815260206004820152600c60248201526b7a65726f206164647265737360a01b604482015260640160405180910390fd5b50600180546001600160a01b0319166001600160a01b0392909216919091179055610162565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b80516001600160a01b038116811461012a57600080fd5b919050565b6000806040838503121561014257600080fd5b61014b83610113565b915061015960208401610113565b90509250929050565b6108b2806101716000396000f3fe6080604052600436106100a05760003560e01c8063491d261111610064578063491d2611146101d35780635defb40d146101f3578063ae5b102e14610213578063ae682e2e14610233578063d4b839921461024b578063d5bb7f6714610283576100bf565b806309c5eabe146100ff5780630e82fe25146101285780632b5214161461016357806334e48c9e14610185578063442767331461019d576100bf565b366100bf576100bd604051806020016040528060008152506102a3565b005b6100bd6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102a392505050565b61011261010d36600461064c565b6102a3565b60405161011f91906106ed565b60405180910390f35b34801561013457600080fd5b5061015561014336600461071d565b60026020526000908152604090205481565b60405190815260200161011f565b34801561016f57600080fd5b5030600090815260208190526040902054610155565b34801561019157600080fd5b50610155600160fd1b81565b3480156101a957600080fd5b506101556101b836600461074f565b6001600160a01b031660009081526020819052604090205490565b3480156101df57600080fd5b506100bd6101ee36600461076a565b610411565b3480156101ff57600080fd5b506100bd61020e366004610794565b610477565b34801561021f57600080fd5b506100bd61022e3660046107ed565b61048c565b34801561023f57600080fd5b50610155600160ff1b81565b34801561025757600080fd5b5060015461026b906001600160a01b031681565b6040516001600160a01b03909116815260200161011f565b34801561028f57600080fd5b506100bd61029e366004610809565b6104f5565b602081015181516060919015610323576001600160e01b03198116600090815260026020526040812054908190036103185760405162461bcd60e51b81526020600482015260136024820152721858d8d95cdcc81c9bdb19481b9bdd081cd95d606a1b60448201526064015b60405180910390fd5b61032181610502565b505b60015460405160009182916001600160a01b03909116903490610347908890610822565b60006040518083038185875af1925050503d8060008114610384576040519150601f19603f3d011682016040523d82523d6000602084013e610389565b606091505b5091509150816103ce5760405162461bcd60e51b815260206004820152601060248201526f195e1958dd5d1a5bdb8819985a5b195960821b604482015260640161030f565b7f57a62eca76fc623c92f161d2a4b851851ece707135ce2af1eec256d660571b6d8386836040516104019392919061083e565b60405180910390a1949350505050565b61041e600160fd1b610502565b6001600160e01b03198216600081815260026020908152604091829020849055815192835282018390527fdb8ed917742b49e83acd1322bcaa8f18b1e5f78a70784c43ea14db7ab50e628d910160405180910390a15050565b610488828051906020012082610411565b5050565b610499600160ff1b610502565b61048882826104f0336104c1876001600160a01b031660009081526020819052604090205490565b6001600160a01b0391909116600090815260208190526040902054600019808818821618908716919091171690565b610513565b6104ff308261048c565b50565b6104ff61050e8261056b565b61057d565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b6000610577338361059b565b92915050565b806104ff57604051634ca8886760e01b815260040160405180910390fd5b6001600160a01b038216600090815260208190526040812054821682145b9392505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156105f1576105f16105c0565b604051601f8501601f19908116603f01168101908282118183101715610619576106196105c0565b8160405280935085815286868601111561063257600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561065e57600080fd5b813567ffffffffffffffff81111561067557600080fd5b8201601f8101841361068657600080fd5b610695848235602084016105d6565b949350505050565b60005b838110156106b85781810151838201526020016106a0565b50506000910152565b600081518084526106d981602086016020860161069d565b601f01601f19169290920160200192915050565b6020815260006105b960208301846106c1565b80356001600160e01b03198116811461071857600080fd5b919050565b60006020828403121561072f57600080fd5b6105b982610700565b80356001600160a01b038116811461071857600080fd5b60006020828403121561076157600080fd5b6105b982610738565b6000806040838503121561077d57600080fd5b61078683610700565b946020939093013593505050565b600080604083850312156107a757600080fd5b823567ffffffffffffffff8111156107be57600080fd5b8301601f810185136107cf57600080fd5b6107de858235602084016105d6565b95602094909401359450505050565b6000806040838503121561080057600080fd5b61078683610738565b60006020828403121561081b57600080fd5b5035919050565b6000825161083481846020870161069d565b9190910192915050565b63ffffffff60e01b8416815260606020820152600061086060608301856106c1565b828103604084015261087281856106c1565b969550505050505056fea26469706673582212201ba377eb6a91d1e61a05796e2c3f7b98c258168e3db52e709dd2c3a003d3eb7864736f6c63430008150033",
|
282
|
+
"deployedBytecode": "0x6080604052600436106100a05760003560e01c8063491d261111610064578063491d2611146101d35780635defb40d146101f3578063ae5b102e14610213578063ae682e2e14610233578063d4b839921461024b578063d5bb7f6714610283576100bf565b806309c5eabe146100ff5780630e82fe25146101285780632b5214161461016357806334e48c9e14610185578063442767331461019d576100bf565b366100bf576100bd604051806020016040528060008152506102a3565b005b6100bd6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102a392505050565b61011261010d36600461064c565b6102a3565b60405161011f91906106ed565b60405180910390f35b34801561013457600080fd5b5061015561014336600461071d565b60026020526000908152604090205481565b60405190815260200161011f565b34801561016f57600080fd5b5030600090815260208190526040902054610155565b34801561019157600080fd5b50610155600160fd1b81565b3480156101a957600080fd5b506101556101b836600461074f565b6001600160a01b031660009081526020819052604090205490565b3480156101df57600080fd5b506100bd6101ee36600461076a565b610411565b3480156101ff57600080fd5b506100bd61020e366004610794565b610477565b34801561021f57600080fd5b506100bd61022e3660046107ed565b61048c565b34801561023f57600080fd5b50610155600160ff1b81565b34801561025757600080fd5b5060015461026b906001600160a01b031681565b6040516001600160a01b03909116815260200161011f565b34801561028f57600080fd5b506100bd61029e366004610809565b6104f5565b602081015181516060919015610323576001600160e01b03198116600090815260026020526040812054908190036103185760405162461bcd60e51b81526020600482015260136024820152721858d8d95cdcc81c9bdb19481b9bdd081cd95d606a1b60448201526064015b60405180910390fd5b61032181610502565b505b60015460405160009182916001600160a01b03909116903490610347908890610822565b60006040518083038185875af1925050503d8060008114610384576040519150601f19603f3d011682016040523d82523d6000602084013e610389565b606091505b5091509150816103ce5760405162461bcd60e51b815260206004820152601060248201526f195e1958dd5d1a5bdb8819985a5b195960821b604482015260640161030f565b7f57a62eca76fc623c92f161d2a4b851851ece707135ce2af1eec256d660571b6d8386836040516104019392919061083e565b60405180910390a1949350505050565b61041e600160fd1b610502565b6001600160e01b03198216600081815260026020908152604091829020849055815192835282018390527fdb8ed917742b49e83acd1322bcaa8f18b1e5f78a70784c43ea14db7ab50e628d910160405180910390a15050565b610488828051906020012082610411565b5050565b610499600160ff1b610502565b61048882826104f0336104c1876001600160a01b031660009081526020819052604090205490565b6001600160a01b0391909116600090815260208190526040902054600019808818821618908716919091171690565b610513565b6104ff308261048c565b50565b6104ff61050e8261056b565b61057d565b6001600160a01b0383166000818152602081815260409182902084905581518581529081018490527fe9be537308880e0f56b7d7cfd7abf85f14c4934486d138f848b92a0cbaf659b4910160405180910390a2505050565b6000610577338361059b565b92915050565b806104ff57604051634ca8886760e01b815260040160405180910390fd5b6001600160a01b038216600090815260208190526040812054821682145b9392505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156105f1576105f16105c0565b604051601f8501601f19908116603f01168101908282118183101715610619576106196105c0565b8160405280935085815286868601111561063257600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561065e57600080fd5b813567ffffffffffffffff81111561067557600080fd5b8201601f8101841361068657600080fd5b610695848235602084016105d6565b949350505050565b60005b838110156106b85781810151838201526020016106a0565b50506000910152565b600081518084526106d981602086016020860161069d565b601f01601f19169290920160200192915050565b6020815260006105b960208301846106c1565b80356001600160e01b03198116811461071857600080fd5b919050565b60006020828403121561072f57600080fd5b6105b982610700565b80356001600160a01b038116811461071857600080fd5b60006020828403121561076157600080fd5b6105b982610738565b6000806040838503121561077d57600080fd5b61078683610700565b946020939093013593505050565b600080604083850312156107a757600080fd5b823567ffffffffffffffff8111156107be57600080fd5b8301601f810185136107cf57600080fd5b6107de858235602084016105d6565b95602094909401359450505050565b6000806040838503121561080057600080fd5b61078683610738565b60006020828403121561081b57600080fd5b5035919050565b6000825161083481846020870161069d565b9190910192915050565b63ffffffff60e01b8416815260606020820152600061086060608301856106c1565b828103604084015261087281856106c1565b969550505050505056fea26469706673582212201ba377eb6a91d1e61a05796e2c3f7b98c258168e3db52e709dd2c3a003d3eb7864736f6c63430008150033",
|
340
283
|
"linkReferences": {},
|
341
284
|
"deployedLinkReferences": {}
|
342
285
|
}
|