Address Details
contract
0x03ACD8bb7293858B5885E515C5a64a0Df63CE14f
- Contract Name
- DCA
- Creator
- 0xe59f13–f1e2b8 at 0x2e7aef–8d080c
- Balance
- 0.2 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- Fetching transactions...
- Transfers
- Fetching transfers...
- Gas Used
- Fetching gas used...
- Last Balance Update
- 24841997
Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- DCA
- Optimization enabled
- true
- Compiler version
- v0.8.13+commit.abaa5c0e
- Optimization runs
- 999999
- EVM Version
- london
- Verified at
- 2022-06-01T20:41:11.926871Z
contracts/DCA.sol
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IExchange.sol"; contract DCA { address cUSDAddress; IExchange cUSDExchange; struct Order { IERC20 sellToken; IERC20 buyToken; uint256 total; uint256 spent; uint256 amountPerPurchase; uint256 blocksBetweenPurchases; uint256 lastBlock; } mapping(address => Order[]) public orders; event OrderCreated( address indexed userAddress, uint256 index, uint256 total, IERC20 sellToken, IERC20 buyToken, uint256 amountPerPurchase, uint256 blocksBetweenPurchases ); constructor(address _cUSDAddress, IExchange _cUSDExchange) { cUSDAddress = _cUSDAddress; cUSDExchange = _cUSDExchange; } function getUserOrders(address userAddress) external view returns (Order[] memory) { return orders[userAddress]; } function getOrder(address userAddress, uint256 index) external view returns (Order memory) { return orders[userAddress][index]; } function createOrder( IERC20 _sellToken, IERC20 _buyToken, uint256 _total, uint256 _amountPerPurchase, uint256 _blocksBetweenPurchases ) external returns (uint256 index) { require( _sellToken.transferFrom(msg.sender, address(this), _total), "DCA: Not enough funds" ); Order memory newOrder = Order( _sellToken, _buyToken, _total, 0, _amountPerPurchase, _blocksBetweenPurchases, 0 ); index = orders[msg.sender].length; orders[msg.sender].push(newOrder); emit OrderCreated( msg.sender, index, _total, _sellToken, _buyToken, _amountPerPurchase, _blocksBetweenPurchases ); } function executeOrder(address userAddress, uint256 index) external { Order storage order = orders[userAddress][index]; require( order.lastBlock + order.blocksBetweenPurchases <= block.number, "DCA: Not enough time passed yet." ); require( order.spent + order.amountPerPurchase <= order.total, "DCA: Order fully executed" ); order.spent += order.amountPerPurchase; order.lastBlock = block.number; IExchange exchange = getMentoExchange(order.sellToken); order.sellToken.approve(address(exchange), order.amountPerPurchase); // TODO: Arreglar el 0, esto no puede subirse a ningún lado así. uint256 boughtAmount = exchange.sell(order.amountPerPurchase, 0, false); require( order.buyToken.transfer(userAddress, boughtAmount), "DCA: buyToken transfer failed" ); } function withdraw(uint256 index) external { Order storage order = orders[msg.sender][index]; uint256 amountToWithdraw = order.total - order.spent; order.spent = order.total; require( order.sellToken.transfer(msg.sender, amountToWithdraw), "DCA: Not enough funds to withdraw" ); } function getMentoExchange(IERC20 token) internal view returns (IExchange) { if (address(token) == cUSDAddress) { return cUSDExchange; } revert("DCA: Exchange not found"); } }
/_openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
/contracts/IExchange.sol
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; interface IExchange { // function buy(uint256, uint256, bool) external returns (uint256); function sell(uint256, uint256, bool) external returns (uint256); // function exchange(uint256, uint256, bool) external returns (uint256); // function setUpdateFrequency(uint256) external; // function getBuyTokenAmount(uint256, bool) external view returns (uint256); // function getSellTokenAmount(uint256, bool) external view returns (uint256); // function getBuyAndSellBuckets(bool) external view returns (uint256, uint256); }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_cUSDAddress","internalType":"address"},{"type":"address","name":"_cUSDExchange","internalType":"contract IExchange"}]},{"type":"event","name":"OrderCreated","inputs":[{"type":"address","name":"userAddress","internalType":"address","indexed":true},{"type":"uint256","name":"index","internalType":"uint256","indexed":false},{"type":"uint256","name":"total","internalType":"uint256","indexed":false},{"type":"address","name":"sellToken","internalType":"contract IERC20","indexed":false},{"type":"address","name":"buyToken","internalType":"contract IERC20","indexed":false},{"type":"uint256","name":"amountPerPurchase","internalType":"uint256","indexed":false},{"type":"uint256","name":"blocksBetweenPurchases","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"index","internalType":"uint256"}],"name":"createOrder","inputs":[{"type":"address","name":"_sellToken","internalType":"contract IERC20"},{"type":"address","name":"_buyToken","internalType":"contract IERC20"},{"type":"uint256","name":"_total","internalType":"uint256"},{"type":"uint256","name":"_amountPerPurchase","internalType":"uint256"},{"type":"uint256","name":"_blocksBetweenPurchases","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeOrder","inputs":[{"type":"address","name":"userAddress","internalType":"address"},{"type":"uint256","name":"index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct DCA.Order","components":[{"type":"address","name":"sellToken","internalType":"contract IERC20"},{"type":"address","name":"buyToken","internalType":"contract IERC20"},{"type":"uint256","name":"total","internalType":"uint256"},{"type":"uint256","name":"spent","internalType":"uint256"},{"type":"uint256","name":"amountPerPurchase","internalType":"uint256"},{"type":"uint256","name":"blocksBetweenPurchases","internalType":"uint256"},{"type":"uint256","name":"lastBlock","internalType":"uint256"}]}],"name":"getOrder","inputs":[{"type":"address","name":"userAddress","internalType":"address"},{"type":"uint256","name":"index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct DCA.Order[]","components":[{"type":"address","name":"sellToken","internalType":"contract IERC20"},{"type":"address","name":"buyToken","internalType":"contract IERC20"},{"type":"uint256","name":"total","internalType":"uint256"},{"type":"uint256","name":"spent","internalType":"uint256"},{"type":"uint256","name":"amountPerPurchase","internalType":"uint256"},{"type":"uint256","name":"blocksBetweenPurchases","internalType":"uint256"},{"type":"uint256","name":"lastBlock","internalType":"uint256"}]}],"name":"getUserOrders","inputs":[{"type":"address","name":"userAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"sellToken","internalType":"contract IERC20"},{"type":"address","name":"buyToken","internalType":"contract IERC20"},{"type":"uint256","name":"total","internalType":"uint256"},{"type":"uint256","name":"spent","internalType":"uint256"},{"type":"uint256","name":"amountPerPurchase","internalType":"uint256"},{"type":"uint256","name":"blocksBetweenPurchases","internalType":"uint256"},{"type":"uint256","name":"lastBlock","internalType":"uint256"}],"name":"orders","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"index","internalType":"uint256"}]}]
Contract Creation Code
0x60803461009957601f61119438819003918201601f19168301916001600160401b0383118484101761009e5780849260409485528339810103126100995780602061008a92519161004f836100b4565b01519061005b826100b4565b600080546001600160a01b03199081166001600160a01b03938416179091556001805490911691909216179055565b6040516110ce90816100c68239f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116036100995756fe60806040526004361015610013575b600080fd5b6000803560e01c9081632e1a7d4d1461008e57508063518e62db1461008557806363c69f081461007c578063793b8c6d14610073578063dc3528d61461006a5763edb258411461006257600080fd5b61000e610a6f565b5061000e6106f0565b5061000e610608565b5061000e6104e7565b5061000e6101ed565b346101cc5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cc57338152600260205261018c8160206101736100dd600435604085206105bd565b5061012f61011660028301549260038101936100fa855482610f6e565b94555473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1690565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015260248101929092529093849283919082906044820190565b03925af19081156101bf575b8391610191575b50610f85565b604051f35b6101b2915060203d81116101b8575b6101aa8183610b7e565b810190610c34565b83610186565b503d6101a0565b6101c7610c4c565b61017f565b80fd5b73ffffffffffffffffffffffffffffffffffffffff81160361000e57565b503461000e5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5761041c60043561022c816101cf565b602435610238816101cf565b7f1ca7e15bb55042f2fce0be38a0ff228a9d717fcbac85d171c7b3903a9625394b60443591606435936104096084356103016040517f23b872dd000000000000000000000000000000000000000000000000000000008152602081806102ce8b30336004850160409194939294606082019573ffffffffffffffffffffffffffffffffffffffff80921683521660208201520152565b0381600073ffffffffffffffffffffffffffffffffffffffff8a165af190811561043e575b600091610420575b50610c59565b610309610bbf565b73ffffffffffffffffffffffffffffffffffffffff841681529673ffffffffffffffffffffffffffffffffffffffff85166020890152866040890152600060608901528060808901528160a0890152600060c08901526103bd61038c3373ffffffffffffffffffffffffffffffffffffffff166000526002602052604060002090565b54986103b83373ffffffffffffffffffffffffffffffffffffffff166000526002602052604060002090565b610cbe565b60405194859433988a879290969594919360a09460c08501988552602085015273ffffffffffffffffffffffffffffffffffffffff809216604085015216606083015260808201520152565b0390a26040519081529081906020820190565b0390f35b610438915060203d81116101b8576101aa8183610b7e565b386102fb565b610446610c4c565b6102f3565b6020908160408183019282815285518094520193019160005b828110610472575050505090565b909192938260e0826104db600194895160c0809173ffffffffffffffffffffffffffffffffffffffff808251168552602082015116602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b01950193929101610464565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff600435610539816101cf565b1660005260028152604060002090815467ffffffffffffffff81116105b0575b604051919261056e600583901b850184610b7e565b8183526000908152838120938084015b838310610593576040518061041c878261044b565b6007826001926105a289610bcc565b81520196019201919461057e565b6105b8610b25565b610559565b80548210156105d9576000526007602060002091020190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435610644816101cf565b60243573ffffffffffffffffffffffffffffffffffffffff8092166000526002602052604060002090815481101561000e5761067f916105bd565b508054600182015460028301546003840154600485015460058601546006909601546040805173ffffffffffffffffffffffffffffffffffffffff978a1688168152989095169095166020880152928601919091526060850152608084015260a083019190915260c082015260e090f35b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043561072c816101cf565b6024356107598273ffffffffffffffffffffffffffffffffffffffff166000526002602052604060002090565b90610763916105bd565b5060068101918254600583015461077991610e18565b43101561078590610e30565b60038201918254936004820193845495866107a08183610e18565b600286015410156107b090610e95565b6107b991610e18565b9055439055805473ffffffffffffffffffffffffffffffffffffffff169373ffffffffffffffffffffffffffffffffffffffff94856107f782611010565b6040517f095ea7b3000000000000000000000000000000000000000000000000000000008152911673ffffffffffffffffffffffffffffffffffffffff8116600483015260248201939093526020949093859384908187806044810103816000809e819a165af161018c99610953986108c2939280156109fb575b6109de575b50546040519687809481937f8ab1a5d4000000000000000000000000000000000000000000000000000000008352600483016040600091939293606081019481528260208201520152565b03925af19283156109d1575b8893610997575b50600101546108f99073ffffffffffffffffffffffffffffffffffffffff16610116565b90876040518096819582947fa9059cbb000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af191821561098a575b849261096d575b5050610f09565b6109839250803d106101b8576101aa8183610b7e565b3880610966565b610992610c4c565b61095f565b6108f991935060016109c161011692873d89116109ca575b6109b98183610b7e565b810190610efa565b949250506108d5565b503d6109af565b6109d9610c4c565b6108ce565b6109f490853d87116101b8576101aa8183610b7e565b5038610877565b610a03610c4c565b610872565b610a6d9092919260e081019360c0809173ffffffffffffffffffffffffffffffffffffffff808251168552602082015116602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b565b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5761041c610b19610b1360c073ffffffffffffffffffffffffffffffffffffffff600435610acb816101cf565b604051610ad781610b55565b60009381858093528260208201528260408201528260608201528260808201528260a082015201521681526002602052604060243591206105bd565b50610bcc565b60405191829182610a08565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60e0810190811067ffffffffffffffff821117610b7157604052565b610b79610b25565b604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610b7157604052565b60405190610a6d82610b55565b90604051610bd981610b55565b60c06006829473ffffffffffffffffffffffffffffffffffffffff8082541685526001820154166020850152600281015460408501526003810154606085015260048101546080850152600581015460a08501520154910152565b9081602091031261000e5751801515810361000e5790565b506040513d6000823e3d90fd5b15610c6057565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4443413a204e6f7420656e6f7567682066756e647300000000000000000000006044820152fd5b8054610ce19168010000000000000000821015610ddb575b6001820181556105bd565b919091610dac57805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff91821617835560069160c091610d7d90602083015116600186019073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055565b60408101516002850155606081015160038501556080810151600485015560a081015160058501550151910155565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b610de3610b25565b610cd6565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81198111610e24570190565b610e2c610de8565b0190565b15610e3757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f4443413a204e6f7420656e6f7567682074696d6520706173736564207965742e6044820152fd5b15610e9c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4443413a204f726465722066756c6c79206578656375746564000000000000006044820152fd5b9081602091031261000e575190565b15610f1057565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4443413a20627579546f6b656e207472616e73666572206661696c65640000006044820152fd5b818110610f79570390565b610f81610de8565b0390565b15610f8c57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4443413a204e6f7420656e6f7567682066756e647320746f207769746864726160448201527f77000000000000000000000000000000000000000000000000000000000000006064820152fd5b73ffffffffffffffffffffffffffffffffffffffff908180600054169116146110915760646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4443413a2045786368616e6765206e6f7420666f756e640000000000000000006044820152fd5b600154169056fea2646970667358221220567720a4df00dc0d717674306486a6ce5d593dc9d6f74a20cf5641bb2310acdd64736f6c634300080d0033000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a00000000000000000000000067316300f17f063085ca8bca4bd3f7a5a3c66275
Deployed ByteCode
0x60806040526004361015610013575b600080fd5b6000803560e01c9081632e1a7d4d1461008e57508063518e62db1461008557806363c69f081461007c578063793b8c6d14610073578063dc3528d61461006a5763edb258411461006257600080fd5b61000e610a6f565b5061000e6106f0565b5061000e610608565b5061000e6104e7565b5061000e6101ed565b346101cc5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101cc57338152600260205261018c8160206101736100dd600435604085206105bd565b5061012f61011660028301549260038101936100fa855482610f6e565b94555473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1690565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015260248101929092529093849283919082906044820190565b03925af19081156101bf575b8391610191575b50610f85565b604051f35b6101b2915060203d81116101b8575b6101aa8183610b7e565b810190610c34565b83610186565b503d6101a0565b6101c7610c4c565b61017f565b80fd5b73ffffffffffffffffffffffffffffffffffffffff81160361000e57565b503461000e5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5761041c60043561022c816101cf565b602435610238816101cf565b7f1ca7e15bb55042f2fce0be38a0ff228a9d717fcbac85d171c7b3903a9625394b60443591606435936104096084356103016040517f23b872dd000000000000000000000000000000000000000000000000000000008152602081806102ce8b30336004850160409194939294606082019573ffffffffffffffffffffffffffffffffffffffff80921683521660208201520152565b0381600073ffffffffffffffffffffffffffffffffffffffff8a165af190811561043e575b600091610420575b50610c59565b610309610bbf565b73ffffffffffffffffffffffffffffffffffffffff841681529673ffffffffffffffffffffffffffffffffffffffff85166020890152866040890152600060608901528060808901528160a0890152600060c08901526103bd61038c3373ffffffffffffffffffffffffffffffffffffffff166000526002602052604060002090565b54986103b83373ffffffffffffffffffffffffffffffffffffffff166000526002602052604060002090565b610cbe565b60405194859433988a879290969594919360a09460c08501988552602085015273ffffffffffffffffffffffffffffffffffffffff809216604085015216606083015260808201520152565b0390a26040519081529081906020820190565b0390f35b610438915060203d81116101b8576101aa8183610b7e565b386102fb565b610446610c4c565b6102f3565b6020908160408183019282815285518094520193019160005b828110610472575050505090565b909192938260e0826104db600194895160c0809173ffffffffffffffffffffffffffffffffffffffff808251168552602082015116602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b01950193929101610464565b503461000e576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5773ffffffffffffffffffffffffffffffffffffffff600435610539816101cf565b1660005260028152604060002090815467ffffffffffffffff81116105b0575b604051919261056e600583901b850184610b7e565b8183526000908152838120938084015b838310610593576040518061041c878261044b565b6007826001926105a289610bcc565b81520196019201919461057e565b6105b8610b25565b610559565b80548210156105d9576000526007602060002091020190600090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e57600435610644816101cf565b60243573ffffffffffffffffffffffffffffffffffffffff8092166000526002602052604060002090815481101561000e5761067f916105bd565b508054600182015460028301546003840154600485015460058601546006909601546040805173ffffffffffffffffffffffffffffffffffffffff978a1688168152989095169095166020880152928601919091526060850152608084015260a083019190915260c082015260e090f35b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5760043561072c816101cf565b6024356107598273ffffffffffffffffffffffffffffffffffffffff166000526002602052604060002090565b90610763916105bd565b5060068101918254600583015461077991610e18565b43101561078590610e30565b60038201918254936004820193845495866107a08183610e18565b600286015410156107b090610e95565b6107b991610e18565b9055439055805473ffffffffffffffffffffffffffffffffffffffff169373ffffffffffffffffffffffffffffffffffffffff94856107f782611010565b6040517f095ea7b3000000000000000000000000000000000000000000000000000000008152911673ffffffffffffffffffffffffffffffffffffffff8116600483015260248201939093526020949093859384908187806044810103816000809e819a165af161018c99610953986108c2939280156109fb575b6109de575b50546040519687809481937f8ab1a5d4000000000000000000000000000000000000000000000000000000008352600483016040600091939293606081019481528260208201520152565b03925af19283156109d1575b8893610997575b50600101546108f99073ffffffffffffffffffffffffffffffffffffffff16610116565b90876040518096819582947fa9059cbb000000000000000000000000000000000000000000000000000000008452600484016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af191821561098a575b849261096d575b5050610f09565b6109839250803d106101b8576101aa8183610b7e565b3880610966565b610992610c4c565b61095f565b6108f991935060016109c161011692873d89116109ca575b6109b98183610b7e565b810190610efa565b949250506108d5565b503d6109af565b6109d9610c4c565b6108ce565b6109f490853d87116101b8576101aa8183610b7e565b5038610877565b610a03610c4c565b610872565b610a6d9092919260e081019360c0809173ffffffffffffffffffffffffffffffffffffffff808251168552602082015116602085015260408101516040850152606081015160608501526080810151608085015260a081015160a08501520151910152565b565b503461000e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261000e5761041c610b19610b1360c073ffffffffffffffffffffffffffffffffffffffff600435610acb816101cf565b604051610ad781610b55565b60009381858093528260208201528260408201528260608201528260808201528260a082015201521681526002602052604060243591206105bd565b50610bcc565b60405191829182610a08565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60e0810190811067ffffffffffffffff821117610b7157604052565b610b79610b25565b604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610b7157604052565b60405190610a6d82610b55565b90604051610bd981610b55565b60c06006829473ffffffffffffffffffffffffffffffffffffffff8082541685526001820154166020850152600281015460408501526003810154606085015260048101546080850152600581015460a08501520154910152565b9081602091031261000e5751801515810361000e5790565b506040513d6000823e3d90fd5b15610c6057565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4443413a204e6f7420656e6f7567682066756e647300000000000000000000006044820152fd5b8054610ce19168010000000000000000821015610ddb575b6001820181556105bd565b919091610dac57805182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff91821617835560069160c091610d7d90602083015116600186019073ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055565b60408101516002850155606081015160038501556080810151600485015560a081015160058501550151910155565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b610de3610b25565b610cd6565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81198111610e24570190565b610e2c610de8565b0190565b15610e3757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f4443413a204e6f7420656e6f7567682074696d6520706173736564207965742e6044820152fd5b15610e9c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4443413a204f726465722066756c6c79206578656375746564000000000000006044820152fd5b9081602091031261000e575190565b15610f1057565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4443413a20627579546f6b656e207472616e73666572206661696c65640000006044820152fd5b818110610f79570390565b610f81610de8565b0390565b15610f8c57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4443413a204e6f7420656e6f7567682066756e647320746f207769746864726160448201527f77000000000000000000000000000000000000000000000000000000000000006064820152fd5b73ffffffffffffffffffffffffffffffffffffffff908180600054169116146110915760646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4443413a2045786368616e6765206e6f7420666f756e640000000000000000006044820152fd5b600154169056fea2646970667358221220567720a4df00dc0d717674306486a6ce5d593dc9d6f74a20cf5641bb2310acdd64736f6c634300080d0033