-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathBatchedPhasedEscrow.json
373 lines (373 loc) · 77.2 KB
/
BatchedPhasedEscrow.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
{
"address": "0xa96AD7889ef29D4978e00B0cB31cD41F77bFD8A6",
"abi": [
{
"inputs": [
{
"internalType": "contract IERC20",
"name": "_token",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "beneficiary",
"type": "address"
}
],
"name": "BeneficiaryApproved",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "oldDrawee",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "newDrawee",
"type": "address"
}
],
"name": "DraweeRoleTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "beneficiary",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "TokensWithdrawn",
"type": "event"
},
{
"inputs": [
{
"internalType": "contract IBeneficiaryContract",
"name": "_beneficiary",
"type": "address"
}
],
"name": "approveBeneficiary",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IBeneficiaryContract[]",
"name": "beneficiaries",
"type": "address[]"
},
{
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
}
],
"name": "batchedWithdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "drawee",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract IBeneficiaryContract",
"name": "_beneficiary",
"type": "address"
}
],
"name": "isBeneficiaryApproved",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"internalType": "uint256",
"name": "_value",
"type": "uint256"
},
{
"internalType": "address",
"name": "_token",
"type": "address"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "receiveApproval",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newDrawee",
"type": "address"
}
],
"name": "setDrawee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "token",
"outputs": [
{
"internalType": "contract IERC20",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x0d0e587cc0652ec111ae9d92db0ff1f92d2952cd0a6362263e37dd9ff55721b9",
"receipt": {
"to": null,
"from": "0x123694886DBf5Ac94DDA07135349534536D14cAf",
"contractAddress": "0xa96AD7889ef29D4978e00B0cB31cD41F77bFD8A6",
"transactionIndex": 90,
"gasUsed": "1661630",
"logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000800000000000000000000000000000000000402000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x5271f05403ff0f6054c6896a5344ff57cebaf1a1a50c19d82fc5f8983a2256a7",
"transactionHash": "0x0d0e587cc0652ec111ae9d92db0ff1f92d2952cd0a6362263e37dd9ff55721b9",
"logs": [
{
"transactionIndex": 90,
"blockNumber": 16327124,
"transactionHash": "0x0d0e587cc0652ec111ae9d92db0ff1f92d2952cd0a6362263e37dd9ff55721b9",
"address": "0xa96AD7889ef29D4978e00B0cB31cD41F77bFD8A6",
"topics": [
"0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x000000000000000000000000123694886dbf5ac94dda07135349534536d14caf"
],
"data": "0x",
"logIndex": 177,
"blockHash": "0x5271f05403ff0f6054c6896a5344ff57cebaf1a1a50c19d82fc5f8983a2256a7"
}
],
"blockNumber": 16327124,
"cumulativeGasUsed": "10257008",
"status": 1,
"byzantium": true
},
"args": [
"0xCdF7028ceAB81fA0C6971208e83fa7872994beE5"
],
"numDeployments": 1,
"solcInputHash": "1f648bbc62fc09e530210f2d58cb219e",
"metadata": "{\"compiler\":{\"version\":\"0.8.9+commit.e5eed63a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_token\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"BeneficiaryApproved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldDrawee\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newDrawee\",\"type\":\"address\"}],\"name\":\"DraweeRoleTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokensWithdrawn\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"contract IBeneficiaryContract\",\"name\":\"_beneficiary\",\"type\":\"address\"}],\"name\":\"approveBeneficiary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBeneficiaryContract[]\",\"name\":\"beneficiaries\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"}],\"name\":\"batchedWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"drawee\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IBeneficiaryContract\",\"name\":\"_beneficiary\",\"type\":\"address\"}],\"name\":\"isBeneficiaryApproved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"receiveApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newDrawee\",\"type\":\"address\"}],\"name\":\"setDrawee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"BatchedPhasedEscrow\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"approveBeneficiary(address)\":{\"notice\":\"Approves the provided address as a beneficiary of tokens held by the escrow. Can be called only by escrow owner.\"},\"batchedWithdraw(address[],uint256[])\":{\"notice\":\"Withdraws tokens from escrow to selected beneficiaries, transferring to each beneficiary the amount of tokens specified as a parameter. Only beneficiaries previously approved by escrow owner can receive funds.\"},\"isBeneficiaryApproved(address)\":{\"notice\":\"Returns `true` if the given address has been approved as a beneficiary of the escrow, `false` otherwise.\"},\"receiveApproval(address,uint256,address,bytes)\":{\"notice\":\"Funds the escrow by transferring all of the approved tokens to the escrow.\"},\"setDrawee(address)\":{\"notice\":\"Transfers the role of drawee to another address. Can be called only by the contract owner.\"}},\"notice\":\"A token holder contract allowing contract owner to approve a set of beneficiaries of tokens held by the contract, to appoint a separate drawee role, and allowing that drawee to withdraw tokens to approved beneficiaries in phases.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/BatchedPhasedEscrow.sol\":\"BatchedPhasedEscrow\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9b72f93be69ca894d8492c244259615c4a742afc8d63720dbc8bb81087d9b238\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/BatchedPhasedEscrow.sol\":{\"content\":\"// \\u2593\\u2593\\u258c \\u2593\\u2593 \\u2590\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2584\\u2584 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584\\u2584\\u2584\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2580\\u2580 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\u2580\\u2580\\u2580 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2580\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2580\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2584 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u258c\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2588\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2590\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\n//\\n// Trust math, not hardware.\\n\\n// SPDX-License-Identifier: MIT\\n\\npragma solidity 0.8.9;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\n/// @title Batched Phased Escrow Beneficiary\\n/// @notice Interface expected from contracts receiving tokens from the\\n/// BatchedPhasedEscrow.\\ninterface IBeneficiaryContract {\\n function __escrowSentTokens(uint256 amount) external;\\n}\\n\\n/// @title BatchedPhasedEscrow\\n/// @notice A token holder contract allowing contract owner to approve a set of\\n/// beneficiaries of tokens held by the contract, to appoint a separate\\n/// drawee role, and allowing that drawee to withdraw tokens to approved\\n/// beneficiaries in phases.\\ncontract BatchedPhasedEscrow is Ownable {\\n using SafeERC20 for IERC20;\\n\\n event BeneficiaryApproved(address beneficiary);\\n event TokensWithdrawn(address beneficiary, uint256 amount);\\n event DraweeRoleTransferred(address oldDrawee, address newDrawee);\\n\\n IERC20 public token;\\n address public drawee;\\n mapping(address => bool) private approvedBeneficiaries;\\n\\n modifier onlyDrawee() {\\n require(drawee == msg.sender, \\\"Caller is not the drawee\\\");\\n _;\\n }\\n\\n constructor(IERC20 _token) {\\n token = _token;\\n drawee = msg.sender;\\n }\\n\\n /// @notice Approves the provided address as a beneficiary of tokens held by\\n /// the escrow. Can be called only by escrow owner.\\n function approveBeneficiary(IBeneficiaryContract _beneficiary)\\n external\\n onlyOwner\\n {\\n address beneficiaryAddress = address(_beneficiary);\\n require(\\n beneficiaryAddress != address(0),\\n \\\"Beneficiary can not be zero address\\\"\\n );\\n approvedBeneficiaries[beneficiaryAddress] = true;\\n emit BeneficiaryApproved(beneficiaryAddress);\\n }\\n\\n /// @notice Returns `true` if the given address has been approved as a\\n /// beneficiary of the escrow, `false` otherwise.\\n function isBeneficiaryApproved(IBeneficiaryContract _beneficiary)\\n public\\n view\\n returns (bool)\\n {\\n return approvedBeneficiaries[address(_beneficiary)];\\n }\\n\\n /// @notice Transfers the role of drawee to another address. Can be called\\n /// only by the contract owner.\\n function setDrawee(address newDrawee) external onlyOwner {\\n require(newDrawee != address(0), \\\"New drawee can not be zero address\\\");\\n emit DraweeRoleTransferred(drawee, newDrawee);\\n drawee = newDrawee;\\n }\\n\\n /// @notice Funds the escrow by transferring all of the approved tokens\\n /// to the escrow.\\n function receiveApproval(\\n address _from,\\n uint256 _value,\\n address _token,\\n bytes memory\\n ) external {\\n require(IERC20(_token) == token, \\\"Unsupported token\\\");\\n token.safeTransferFrom(_from, address(this), _value);\\n }\\n\\n /// @notice Withdraws tokens from escrow to selected beneficiaries,\\n /// transferring to each beneficiary the amount of tokens specified\\n /// as a parameter. Only beneficiaries previously approved by escrow\\n /// owner can receive funds.\\n function batchedWithdraw(\\n IBeneficiaryContract[] memory beneficiaries,\\n uint256[] memory amounts\\n ) external onlyDrawee {\\n require(\\n beneficiaries.length == amounts.length,\\n \\\"Mismatched arrays length\\\"\\n );\\n\\n for (uint256 i = 0; i < beneficiaries.length; i++) {\\n IBeneficiaryContract beneficiary = beneficiaries[i];\\n require(\\n isBeneficiaryApproved(beneficiary),\\n \\\"Beneficiary was not approved\\\"\\n );\\n withdraw(beneficiary, amounts[i]);\\n }\\n }\\n\\n function withdraw(IBeneficiaryContract beneficiary, uint256 amount)\\n private\\n {\\n emit TokensWithdrawn(address(beneficiary), amount);\\n token.safeTransfer(address(beneficiary), amount);\\n // slither-disable-next-line calls-loop\\n beneficiary.__escrowSentTokens(amount);\\n }\\n}\\n\",\"keccak256\":\"0xd1ed7b9149ea0672c94e22812ca723751c2be7546b1d23ffb12d9595a14a8f50\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x60806040523480156200001157600080fd5b5060405162001e3e38038062001e3e83398181016040528101906200003791906200022a565b620000576200004b620000e060201b60201c565b620000e860201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555033600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200025c565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001de82620001b1565b9050919050565b6000620001f282620001d1565b9050919050565b6200020481620001e5565b81146200021057600080fd5b50565b6000815190506200022481620001f9565b92915050565b600060208284031215620002435762000242620001ac565b5b6000620002538482850162000213565b91505092915050565b611bd2806200026c6000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063ba07075011610066578063ba0707501461011f578063d6d0aa411461013b578063f2fde38b14610159578063f70cb38e14610175578063fc0c546a146101a55761009e565b8063431714c3146100a3578063715018a6146100bf5780638da5cb5b146100c95780638f4ffcb1146100e7578063a1c9b08014610103575b600080fd5b6100bd60048036038101906100b89190610e1d565b6101c3565b005b6100c76102d3565b005b6100d16102e7565b6040516100de9190610e59565b60405180910390f35b61010160048036038101906100fc919061101c565b610310565b005b61011d6004803603810190610118919061122a565b6103f5565b005b610139600480360381019061013491906112a2565b610579565b005b610143610690565b6040516101509190610e59565b60405180910390f35b610173600480360381019061016e91906112a2565b6106b6565b005b61018f600480360381019061018a9190610e1d565b61073a565b60405161019c91906112ea565b60405180910390f35b6101ad610790565b6040516101ba9190611364565b60405180910390f35b6101cb6107b6565b6000819050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161023790611402565b60405180910390fd5b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fae756b0a5bd1fbe0871906ac484a39752d357561ca291b46f52c068408c39a96816040516102c79190610e59565b60405180910390a15050565b6102db6107b6565b6102e56000610834565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146103a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103979061146e565b60405180910390fd5b6103ef843085600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108f8909392919063ffffffff16565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161047c906114da565b60405180910390fd5b80518251146104c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c090611546565b60405180910390fd5b60005b82518110156105745760008382815181106104ea576104e9611566565b5b602002602001015190506104fd8161073a565b61053c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610533906115e1565b60405180910390fd5b6105608184848151811061055357610552611566565b5b6020026020010151610981565b50808061056c90611630565b9150506104cc565b505050565b6105816107b6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156105f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e8906116eb565b60405180910390fd5b7f2cd645351aa758b6871e153e13b27063dc3eefbf1a8acc38b31486f099cb7510600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168260405161064492919061170b565b60405180910390a180600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6106be6107b6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610725906117a6565b60405180910390fd5b61073781610834565b50565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6107be610a76565b73ffffffffffffffffffffffffffffffffffffffff166107dc6102e7565b73ffffffffffffffffffffffffffffffffffffffff1614610832576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082990611812565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61097b846323b872dd60e01b85858560405160240161091993929190611841565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610a7e565b50505050565b7f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b82826040516109b2929190611878565b60405180910390a1610a078282600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16610b459092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff16634a5f5456826040518263ffffffff1660e01b8152600401610a4091906118a1565b600060405180830381600087803b158015610a5a57600080fd5b505af1158015610a6e573d6000803e3d6000fd5b505050505050565b600033905090565b6000610ae0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610bcb9092919063ffffffff16565b9050600081511115610b405780806020019051810190610b0091906118e8565b610b3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3690611987565b60405180910390fd5b5b505050565b610bc68363a9059cbb60e01b8484604051602401610b64929190611878565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610a7e565b505050565b6060610bda8484600085610be3565b90509392505050565b606082471015610c28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1f90611a19565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610c519190611ab3565b60006040518083038185875af1925050503d8060008114610c8e576040519150601f19603f3d011682016040523d82523d6000602084013e610c93565b606091505b5091509150610ca487838387610cb0565b92505050949350505050565b60608315610d1357600083511415610d0b57610ccb85610d26565b610d0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0190611b16565b60405180910390fd5b5b829050610d1e565b610d1d8383610d49565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115610d5c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d909190611b7a565b60405180910390fd5b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610dd882610dad565b9050919050565b6000610dea82610dcd565b9050919050565b610dfa81610ddf565b8114610e0557600080fd5b50565b600081359050610e1781610df1565b92915050565b600060208284031215610e3357610e32610da3565b5b6000610e4184828501610e08565b91505092915050565b610e5381610dcd565b82525050565b6000602082019050610e6e6000830184610e4a565b92915050565b610e7d81610dcd565b8114610e8857600080fd5b50565b600081359050610e9a81610e74565b92915050565b6000819050919050565b610eb381610ea0565b8114610ebe57600080fd5b50565b600081359050610ed081610eaa565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610f2982610ee0565b810181811067ffffffffffffffff82111715610f4857610f47610ef1565b5b80604052505050565b6000610f5b610d99565b9050610f678282610f20565b919050565b600067ffffffffffffffff821115610f8757610f86610ef1565b5b610f9082610ee0565b9050602081019050919050565b82818337600083830152505050565b6000610fbf610fba84610f6c565b610f51565b905082815260208101848484011115610fdb57610fda610edb565b5b610fe6848285610f9d565b509392505050565b600082601f83011261100357611002610ed6565b5b8135611013848260208601610fac565b91505092915050565b6000806000806080858703121561103657611035610da3565b5b600061104487828801610e8b565b945050602061105587828801610ec1565b935050604061106687828801610e8b565b925050606085013567ffffffffffffffff81111561108757611086610da8565b5b61109387828801610fee565b91505092959194509250565b600067ffffffffffffffff8211156110ba576110b9610ef1565b5b602082029050602081019050919050565b600080fd5b60006110e36110de8461109f565b610f51565b90508083825260208201905060208402830185811115611106576111056110cb565b5b835b8181101561112f578061111b8882610e08565b845260208401935050602081019050611108565b5050509392505050565b600082601f83011261114e5761114d610ed6565b5b813561115e8482602086016110d0565b91505092915050565b600067ffffffffffffffff82111561118257611181610ef1565b5b602082029050602081019050919050565b60006111a66111a184611167565b610f51565b905080838252602082019050602084028301858111156111c9576111c86110cb565b5b835b818110156111f257806111de8882610ec1565b8452602084019350506020810190506111cb565b5050509392505050565b600082601f83011261121157611210610ed6565b5b8135611221848260208601611193565b91505092915050565b6000806040838503121561124157611240610da3565b5b600083013567ffffffffffffffff81111561125f5761125e610da8565b5b61126b85828601611139565b925050602083013567ffffffffffffffff81111561128c5761128b610da8565b5b611298858286016111fc565b9150509250929050565b6000602082840312156112b8576112b7610da3565b5b60006112c684828501610e8b565b91505092915050565b60008115159050919050565b6112e4816112cf565b82525050565b60006020820190506112ff60008301846112db565b92915050565b6000819050919050565b600061132a61132561132084610dad565b611305565b610dad565b9050919050565b600061133c8261130f565b9050919050565b600061134e82611331565b9050919050565b61135e81611343565b82525050565b60006020820190506113796000830184611355565b92915050565b600082825260208201905092915050565b7f42656e65666963696172792063616e206e6f74206265207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006113ec60238361137f565b91506113f782611390565b604082019050919050565b6000602082019050818103600083015261141b816113df565b9050919050565b7f556e737570706f7274656420746f6b656e000000000000000000000000000000600082015250565b600061145860118361137f565b915061146382611422565b602082019050919050565b600060208201905081810360008301526114878161144b565b9050919050565b7f43616c6c6572206973206e6f7420746865206472617765650000000000000000600082015250565b60006114c460188361137f565b91506114cf8261148e565b602082019050919050565b600060208201905081810360008301526114f3816114b7565b9050919050565b7f4d69736d61746368656420617272617973206c656e6774680000000000000000600082015250565b600061153060188361137f565b915061153b826114fa565b602082019050919050565b6000602082019050818103600083015261155f81611523565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f42656e656669636961727920776173206e6f7420617070726f76656400000000600082015250565b60006115cb601c8361137f565b91506115d682611595565b602082019050919050565b600060208201905081810360008301526115fa816115be565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061163b82610ea0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561166e5761166d611601565b5b600182019050919050565b7f4e6577206472617765652063616e206e6f74206265207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b60006116d560228361137f565b91506116e082611679565b604082019050919050565b60006020820190508181036000830152611704816116c8565b9050919050565b60006040820190506117206000830185610e4a565b61172d6020830184610e4a565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061179060268361137f565b915061179b82611734565b604082019050919050565b600060208201905081810360008301526117bf81611783565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006117fc60208361137f565b9150611807826117c6565b602082019050919050565b6000602082019050818103600083015261182b816117ef565b9050919050565b61183b81610ea0565b82525050565b60006060820190506118566000830186610e4a565b6118636020830185610e4a565b6118706040830184611832565b949350505050565b600060408201905061188d6000830185610e4a565b61189a6020830184611832565b9392505050565b60006020820190506118b66000830184611832565b92915050565b6118c5816112cf565b81146118d057600080fd5b50565b6000815190506118e2816118bc565b92915050565b6000602082840312156118fe576118fd610da3565b5b600061190c848285016118d3565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000611971602a8361137f565b915061197c82611915565b604082019050919050565b600060208201905081810360008301526119a081611964565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000611a0360268361137f565b9150611a0e826119a7565b604082019050919050565b60006020820190508181036000830152611a32816119f6565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015611a6d578082015181840152602081019050611a52565b83811115611a7c576000848401525b50505050565b6000611a8d82611a39565b611a978185611a44565b9350611aa7818560208601611a4f565b80840191505092915050565b6000611abf8284611a82565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000611b00601d8361137f565b9150611b0b82611aca565b602082019050919050565b60006020820190508181036000830152611b2f81611af3565b9050919050565b600081519050919050565b6000611b4c82611b36565b611b56818561137f565b9350611b66818560208601611a4f565b611b6f81610ee0565b840191505092915050565b60006020820190508181036000830152611b948184611b41565b90509291505056fea2646970667358221220e866eaf732d163a6a7078656998c3165d0dec06cf5a3aff327d7470ab2fc616f64736f6c63430008090033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063ba07075011610066578063ba0707501461011f578063d6d0aa411461013b578063f2fde38b14610159578063f70cb38e14610175578063fc0c546a146101a55761009e565b8063431714c3146100a3578063715018a6146100bf5780638da5cb5b146100c95780638f4ffcb1146100e7578063a1c9b08014610103575b600080fd5b6100bd60048036038101906100b89190610e1d565b6101c3565b005b6100c76102d3565b005b6100d16102e7565b6040516100de9190610e59565b60405180910390f35b61010160048036038101906100fc919061101c565b610310565b005b61011d6004803603810190610118919061122a565b6103f5565b005b610139600480360381019061013491906112a2565b610579565b005b610143610690565b6040516101509190610e59565b60405180910390f35b610173600480360381019061016e91906112a2565b6106b6565b005b61018f600480360381019061018a9190610e1d565b61073a565b60405161019c91906112ea565b60405180910390f35b6101ad610790565b6040516101ba9190611364565b60405180910390f35b6101cb6107b6565b6000819050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610240576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161023790611402565b60405180910390fd5b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055507fae756b0a5bd1fbe0871906ac484a39752d357561ca291b46f52c068408c39a96816040516102c79190610e59565b60405180910390a15050565b6102db6107b6565b6102e56000610834565b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146103a0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103979061146e565b60405180910390fd5b6103ef843085600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108f8909392919063ffffffff16565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161047c906114da565b60405180910390fd5b80518251146104c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104c090611546565b60405180910390fd5b60005b82518110156105745760008382815181106104ea576104e9611566565b5b602002602001015190506104fd8161073a565b61053c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610533906115e1565b60405180910390fd5b6105608184848151811061055357610552611566565b5b6020026020010151610981565b50808061056c90611630565b9150506104cc565b505050565b6105816107b6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156105f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e8906116eb565b60405180910390fd5b7f2cd645351aa758b6871e153e13b27063dc3eefbf1a8acc38b31486f099cb7510600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168260405161064492919061170b565b60405180910390a180600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6106be6107b6565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561072e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610725906117a6565b60405180910390fd5b61073781610834565b50565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6107be610a76565b73ffffffffffffffffffffffffffffffffffffffff166107dc6102e7565b73ffffffffffffffffffffffffffffffffffffffff1614610832576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082990611812565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61097b846323b872dd60e01b85858560405160240161091993929190611841565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610a7e565b50505050565b7f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b82826040516109b2929190611878565b60405180910390a1610a078282600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16610b459092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff16634a5f5456826040518263ffffffff1660e01b8152600401610a4091906118a1565b600060405180830381600087803b158015610a5a57600080fd5b505af1158015610a6e573d6000803e3d6000fd5b505050505050565b600033905090565b6000610ae0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16610bcb9092919063ffffffff16565b9050600081511115610b405780806020019051810190610b0091906118e8565b610b3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3690611987565b60405180910390fd5b5b505050565b610bc68363a9059cbb60e01b8484604051602401610b64929190611878565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050610a7e565b505050565b6060610bda8484600085610be3565b90509392505050565b606082471015610c28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1f90611a19565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610c519190611ab3565b60006040518083038185875af1925050503d8060008114610c8e576040519150601f19603f3d011682016040523d82523d6000602084013e610c93565b606091505b5091509150610ca487838387610cb0565b92505050949350505050565b60608315610d1357600083511415610d0b57610ccb85610d26565b610d0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0190611b16565b60405180910390fd5b5b829050610d1e565b610d1d8383610d49565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115610d5c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d909190611b7a565b60405180910390fd5b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610dd882610dad565b9050919050565b6000610dea82610dcd565b9050919050565b610dfa81610ddf565b8114610e0557600080fd5b50565b600081359050610e1781610df1565b92915050565b600060208284031215610e3357610e32610da3565b5b6000610e4184828501610e08565b91505092915050565b610e5381610dcd565b82525050565b6000602082019050610e6e6000830184610e4a565b92915050565b610e7d81610dcd565b8114610e8857600080fd5b50565b600081359050610e9a81610e74565b92915050565b6000819050919050565b610eb381610ea0565b8114610ebe57600080fd5b50565b600081359050610ed081610eaa565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610f2982610ee0565b810181811067ffffffffffffffff82111715610f4857610f47610ef1565b5b80604052505050565b6000610f5b610d99565b9050610f678282610f20565b919050565b600067ffffffffffffffff821115610f8757610f86610ef1565b5b610f9082610ee0565b9050602081019050919050565b82818337600083830152505050565b6000610fbf610fba84610f6c565b610f51565b905082815260208101848484011115610fdb57610fda610edb565b5b610fe6848285610f9d565b509392505050565b600082601f83011261100357611002610ed6565b5b8135611013848260208601610fac565b91505092915050565b6000806000806080858703121561103657611035610da3565b5b600061104487828801610e8b565b945050602061105587828801610ec1565b935050604061106687828801610e8b565b925050606085013567ffffffffffffffff81111561108757611086610da8565b5b61109387828801610fee565b91505092959194509250565b600067ffffffffffffffff8211156110ba576110b9610ef1565b5b602082029050602081019050919050565b600080fd5b60006110e36110de8461109f565b610f51565b90508083825260208201905060208402830185811115611106576111056110cb565b5b835b8181101561112f578061111b8882610e08565b845260208401935050602081019050611108565b5050509392505050565b600082601f83011261114e5761114d610ed6565b5b813561115e8482602086016110d0565b91505092915050565b600067ffffffffffffffff82111561118257611181610ef1565b5b602082029050602081019050919050565b60006111a66111a184611167565b610f51565b905080838252602082019050602084028301858111156111c9576111c86110cb565b5b835b818110156111f257806111de8882610ec1565b8452602084019350506020810190506111cb565b5050509392505050565b600082601f83011261121157611210610ed6565b5b8135611221848260208601611193565b91505092915050565b6000806040838503121561124157611240610da3565b5b600083013567ffffffffffffffff81111561125f5761125e610da8565b5b61126b85828601611139565b925050602083013567ffffffffffffffff81111561128c5761128b610da8565b5b611298858286016111fc565b9150509250929050565b6000602082840312156112b8576112b7610da3565b5b60006112c684828501610e8b565b91505092915050565b60008115159050919050565b6112e4816112cf565b82525050565b60006020820190506112ff60008301846112db565b92915050565b6000819050919050565b600061132a61132561132084610dad565b611305565b610dad565b9050919050565b600061133c8261130f565b9050919050565b600061134e82611331565b9050919050565b61135e81611343565b82525050565b60006020820190506113796000830184611355565b92915050565b600082825260208201905092915050565b7f42656e65666963696172792063616e206e6f74206265207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006113ec60238361137f565b91506113f782611390565b604082019050919050565b6000602082019050818103600083015261141b816113df565b9050919050565b7f556e737570706f7274656420746f6b656e000000000000000000000000000000600082015250565b600061145860118361137f565b915061146382611422565b602082019050919050565b600060208201905081810360008301526114878161144b565b9050919050565b7f43616c6c6572206973206e6f7420746865206472617765650000000000000000600082015250565b60006114c460188361137f565b91506114cf8261148e565b602082019050919050565b600060208201905081810360008301526114f3816114b7565b9050919050565b7f4d69736d61746368656420617272617973206c656e6774680000000000000000600082015250565b600061153060188361137f565b915061153b826114fa565b602082019050919050565b6000602082019050818103600083015261155f81611523565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f42656e656669636961727920776173206e6f7420617070726f76656400000000600082015250565b60006115cb601c8361137f565b91506115d682611595565b602082019050919050565b600060208201905081810360008301526115fa816115be565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061163b82610ea0565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561166e5761166d611601565b5b600182019050919050565b7f4e6577206472617765652063616e206e6f74206265207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b60006116d560228361137f565b91506116e082611679565b604082019050919050565b60006020820190508181036000830152611704816116c8565b9050919050565b60006040820190506117206000830185610e4a565b61172d6020830184610e4a565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061179060268361137f565b915061179b82611734565b604082019050919050565b600060208201905081810360008301526117bf81611783565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006117fc60208361137f565b9150611807826117c6565b602082019050919050565b6000602082019050818103600083015261182b816117ef565b9050919050565b61183b81610ea0565b82525050565b60006060820190506118566000830186610e4a565b6118636020830185610e4a565b6118706040830184611832565b949350505050565b600060408201905061188d6000830185610e4a565b61189a6020830184611832565b9392505050565b60006020820190506118b66000830184611832565b92915050565b6118c5816112cf565b81146118d057600080fd5b50565b6000815190506118e2816118bc565b92915050565b6000602082840312156118fe576118fd610da3565b5b600061190c848285016118d3565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000611971602a8361137f565b915061197c82611915565b604082019050919050565b600060208201905081810360008301526119a081611964565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000611a0360268361137f565b9150611a0e826119a7565b604082019050919050565b60006020820190508181036000830152611a32816119f6565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015611a6d578082015181840152602081019050611a52565b83811115611a7c576000848401525b50505050565b6000611a8d82611a39565b611a978185611a44565b9350611aa7818560208601611a4f565b80840191505092915050565b6000611abf8284611a82565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000611b00601d8361137f565b9150611b0b82611aca565b602082019050919050565b60006020820190508181036000830152611b2f81611af3565b9050919050565b600081519050919050565b6000611b4c82611b36565b611b56818561137f565b9350611b66818560208601611a4f565b611b6f81610ee0565b840191505092915050565b60006020820190508181036000830152611b948184611b41565b90509291505056fea2646970667358221220e866eaf732d163a6a7078656998c3165d0dec06cf5a3aff327d7470ab2fc616f64736f6c63430008090033",
"devdoc": {
"kind": "dev",
"methods": {
"owner()": {
"details": "Returns the address of the current owner."
},
"renounceOwnership()": {
"details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."
},
"transferOwnership(address)": {
"details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
}
},
"title": "BatchedPhasedEscrow",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"approveBeneficiary(address)": {
"notice": "Approves the provided address as a beneficiary of tokens held by the escrow. Can be called only by escrow owner."
},
"batchedWithdraw(address[],uint256[])": {
"notice": "Withdraws tokens from escrow to selected beneficiaries, transferring to each beneficiary the amount of tokens specified as a parameter. Only beneficiaries previously approved by escrow owner can receive funds."
},
"isBeneficiaryApproved(address)": {
"notice": "Returns `true` if the given address has been approved as a beneficiary of the escrow, `false` otherwise."
},
"receiveApproval(address,uint256,address,bytes)": {
"notice": "Funds the escrow by transferring all of the approved tokens to the escrow."
},
"setDrawee(address)": {
"notice": "Transfers the role of drawee to another address. Can be called only by the contract owner."
}
},
"notice": "A token holder contract allowing contract owner to approve a set of beneficiaries of tokens held by the contract, to appoint a separate drawee role, and allowing that drawee to withdraw tokens to approved beneficiaries in phases.",
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 488,
"contract": "contracts/BatchedPhasedEscrow.sol:BatchedPhasedEscrow",
"label": "_owner",
"offset": 0,
"slot": "0",
"type": "t_address"
},
{
"astId": 7479,
"contract": "contracts/BatchedPhasedEscrow.sol:BatchedPhasedEscrow",
"label": "token",
"offset": 0,
"slot": "1",
"type": "t_contract(IERC20)671"
},
{
"astId": 7481,
"contract": "contracts/BatchedPhasedEscrow.sol:BatchedPhasedEscrow",
"label": "drawee",
"offset": 0,
"slot": "2",
"type": "t_address"
},
{
"astId": 7485,
"contract": "contracts/BatchedPhasedEscrow.sol:BatchedPhasedEscrow",
"label": "approvedBeneficiaries",
"offset": 0,
"slot": "3",
"type": "t_mapping(t_address,t_bool)"
}
],
"types": {
"t_address": {
"encoding": "inplace",
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"encoding": "inplace",
"label": "bool",
"numberOfBytes": "1"
},
"t_contract(IERC20)671": {
"encoding": "inplace",
"label": "contract IERC20",
"numberOfBytes": "20"
},
"t_mapping(t_address,t_bool)": {
"encoding": "mapping",
"key": "t_address",
"label": "mapping(address => bool)",
"numberOfBytes": "32",
"value": "t_bool"
}
}
}
}