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
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