false
false
0

Contract Address Details

0xAe50177B650e18fdEA7A871A8205Acb7e629fD04

Contract Name
MigrationCE
Creator
0xc7d98c–7f3521 at 0x50d312–ab06f8
Balance
126,491,250.971756001389968204 CLO
Tokens
Fetching tokens...
Transactions
417 Transactions
Transfers
0 Transfers
Gas Used
33,659,232
Last Balance Update
16291545
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
MigrationCE




Optimization enabled
true
Compiler version
v0.8.19+commit.7dd6d404




Optimization runs
200
EVM Version
default




Verified at
2024-09-26T15:33:02.893910Z

Contract source code

// SPDX-License-Identifier: No License (None)
pragma solidity 0.8.19;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 *
 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/contracts/ownership/Ownable.sol
 * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts
 * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the
 * build/artifacts folder) as well as the vanilla Ownable implementation from an openzeppelin version.
 */
contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor () {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(),"Not Owner");
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     * @notice Renouncing to ownership will leave the contract without an owner.
     * It will not be possible to call the functions with the `onlyOwner`
     * modifier anymore.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0),"Zero address not allowed");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

interface IERC223 {
    function mint(address _to, uint256 _amount) external;
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function burnFrom(address sender, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external;
    function balanceOf(address account) external view returns (uint256);
}

interface ICS2 {
    struct Staker
    {
        uint amount;
        uint time;              // Staking start time or last claim rewards
        uint multiplier;        // Rewards multiplier = 0.40 + (0.05 * rounds). [0.45..1] (max rounds 12)
        uint end_time;          // Time when staking ends and user may withdraw. After this time user will not receive rewards.
    }
    function staker(address user) external view returns(Staker memory);
}


contract MigrationCE is Ownable {
    ICS2 constant public CS2 = ICS2(0x08A7c8be47773546DC5E173d67B0c38AfFfa4b84);
    address constant public CLOE = address(0x1eAa43544dAa399b87EEcFcC6Fa579D5ea4A6187);
    uint256[] public periodEnd = [1712016000,1714521600,1719792000,1725235200]; // last period will ends on 1 September 2024 23:59:59 UTC
    address[] public tokenCE = [0x3986E815F87feA74910F7aDeAcD1cE7f172E1df0,0xB376e0eE3f4430ddE2cd6705eeCB48b2d5eb5C3C,0x54BdF1fB03f1ff159FE175EAe6cDCE25a2192F2E,0x4928688C4c83bC9a0D3c4a20A4BC13c54Af55C94]; // different tokens for each phase 
    uint256 public currentPeriod;

    uint256 public cloeRate = 20;     // CE amount = CLOE amount * cloeRate
    uint256 public cloRate = 1;     // CE amount = CLO amount * cloRate

    bool public isPause;
    uint256 public totalCEMinted;
    uint256 public totalCLOEMigrated;
    uint256 public totalCLOMigrated;

    struct ReserveCS {
        uint256 amount;
        uint256 time;
        address tokenCE;
    }

    mapping(address => ReserveCS) public reserves;

    event MigrateCLO(address user, uint256 CLOAmount, uint256 CEAmount, address ceAddress);
    event Migrate(address user, uint256 CLOEAmount, uint256 CEAmount, address ceAddress);

    modifier migrationAllowed() {
        require(!isPause, "Migration is paused");
        uint256 lastPeriod = periodEnd.length-1;
        while(periodEnd[currentPeriod] < block.timestamp) {
            require(currentPeriod < lastPeriod, "Migration finished");   // not a last period
            currentPeriod++;
        }
        _;
    }

    // migrate CLO to CE
    receive() external payable {
        require(cloRate != 0, "migration stopped");
        require(msg.value != 0, "0 value");
        address user = msg.sender;
        uint256 amount = msg.value;
        migrate(user, amount, false);
    }

    function migrateCLOE(address user, uint256 amount) external {
        require(amount != 0, "0 value");
        IERC223(CLOE).burnFrom(msg.sender, amount);
        migrate(user, amount, true);
    }

    function migrate(address user, uint256 amount, bool isCLOE) internal migrationAllowed {
        uint256 ceAmount;
        address ceAddress = tokenCE[currentPeriod];
        if (isCLOE) {
            ceAmount = amount * cloeRate;
            totalCLOEMigrated += amount;
            emit Migrate(user, amount, ceAmount, ceAddress); 
        } else {
            ceAmount = amount * cloRate;
            totalCLOMigrated += amount;
            emit MigrateCLO(user, amount, ceAmount, ceAddress); 
        }
        totalCEMinted += ceAmount;
        IERC223(ceAddress).mint(user, ceAmount); 
    }


    function setPause(bool pause) external onlyOwner {
        isPause = pause;
    }
    
    function setCloeCE(uint256 _cloeMigrated, uint256 _cloMigrated, uint256 _ceMinted) external onlyOwner {
        totalCLOEMigrated += _cloeMigrated;
        totalCLOMigrated += _cloMigrated;
        totalCEMinted += _ceMinted;
    }

    function setRates(uint256 _cloeRate, uint256 _cloRate) external onlyOwner {
        cloeRate = _cloeRate;
        cloRate = _cloRate;
    }

    // Rescue tokens
    event Rescue(address _token, uint256 _amount);

    function rescueTokens(address _token) external onlyOwner {
        uint256 _amount;
        if (_token == address(0)) {
            _amount = address(this).balance;
            safeTransferETH(msg.sender, _amount);
        } else {
            _amount = IERC223(_token).balanceOf(address(this));
            safeTransfer(_token, msg.sender, _amount);
        }
        emit Rescue(_token, _amount);
    }

    function safeTransfer(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0xa9059cbb, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper: TRANSFER_FAILED"
        );
    }
    
    function safeTransferETH(address to, uint value) internal {
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
    }
}
        

Contract ABI

[{"type":"event","name":"Migrate","inputs":[{"type":"address","name":"user","internalType":"address","indexed":false},{"type":"uint256","name":"CLOEAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"CEAmount","internalType":"uint256","indexed":false},{"type":"address","name":"ceAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"MigrateCLO","inputs":[{"type":"address","name":"user","internalType":"address","indexed":false},{"type":"uint256","name":"CLOAmount","internalType":"uint256","indexed":false},{"type":"uint256","name":"CEAmount","internalType":"uint256","indexed":false},{"type":"address","name":"ceAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Rescue","inputs":[{"type":"address","name":"_token","internalType":"address","indexed":false},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"CLOE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ICS2"}],"name":"CS2","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"cloRate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"cloeRate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentPeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPause","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"migrateCLOE","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"periodEnd","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueTokens","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"time","internalType":"uint256"},{"type":"address","name":"tokenCE","internalType":"address"}],"name":"reserves","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCloeCE","inputs":[{"type":"uint256","name":"_cloeMigrated","internalType":"uint256"},{"type":"uint256","name":"_cloMigrated","internalType":"uint256"},{"type":"uint256","name":"_ceMinted","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPause","inputs":[{"type":"bool","name":"pause","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRates","inputs":[{"type":"uint256","name":"_cloeRate","internalType":"uint256"},{"type":"uint256","name":"_cloRate","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"tokenCE","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalCEMinted","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalCLOEMigrated","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalCLOMigrated","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

Verify & Publish
0x61010060405263660b4a806080908152636631860060a052636681f18060c0526366d5000060e0526200003790600190600462000117565b5060408051608081018252733986e815f87fea74910f7adeacd1ce7f172e1df0815273b376e0ee3f4430dde2cd6705eecb48b2d5eb5c3c60208201527354bdf1fb03f1ff159fe175eae6cdce25a2192f2e91810191909152734928688c4c83bc9a0d3c4a20a4bc13c54af55c946060820152620000b99060029060046200016f565b5060146004556001600555348015620000d157600080fd5b50600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3620001de565b8280548282559060005260206000209081019282156200015d579160200282015b828111156200015d578251829063ffffffff1690559160200191906001019062000138565b506200016b929150620001c7565b5090565b8280548282559060005260206000209081019282156200015d579160200282015b828111156200015d57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000190565b5b808211156200016b5760008155600101620001c8565b610fc080620001ee6000396000f3fe60806040526004361061012d5760003560e01c80638b50e446116100ab578063cc44fe391161006f578063cc44fe39146103a2578063ce067c86146103c2578063d66bd524146103e2578063dcf79c5a1461044b578063f2fde38b14610473578063ff0938a71461049357600080fd5b80638b50e446146103025780638da5cb5b146103185780638f32d59b14610336578063ac6af28014610362578063bedb86fb1461038257600080fd5b8063464982f9116100f2578063464982f9146102615780635eb325eb1461027757806367457720146102b7578063715018a6146102cd5780637a2786f6146102e257600080fd5b8062ae3bf8146101cc57806306040618146101ec57806327614ec4146102155780632da49d1614610235578063314de7c31461024b57600080fd5b366101c75760055460000361017d5760405162461bcd60e51b81526020600482015260116024820152701b5a59dc985d1a5bdb881cdd1bdc1c1959607a1b60448201526064015b60405180910390fd5b346000036101b75760405162461bcd60e51b8152602060048201526007602482015266302076616c756560c81b6044820152606401610174565b33346101c5828260006104ad565b005b600080fd5b3480156101d857600080fd5b506101c56101e7366004610d9c565b61073a565b3480156101f857600080fd5b5061020260035481565b6040519081526020015b60405180910390f35b34801561022157600080fd5b50610202610230366004610dbe565b610840565b34801561024157600080fd5b5061020260085481565b34801561025757600080fd5b5061020260045481565b34801561026d57600080fd5b5061020260095481565b34801561028357600080fd5b5061029f731eaa43544daa399b87eecfcc6fa579d5ea4a618781565b6040516001600160a01b03909116815260200161020c565b3480156102c357600080fd5b5061020260055481565b3480156102d957600080fd5b506101c5610861565b3480156102ee57600080fd5b5061029f6102fd366004610dbe565b6108d5565b34801561030e57600080fd5b5061020260075481565b34801561032457600080fd5b506000546001600160a01b031661029f565b34801561034257600080fd5b506000546001600160a01b031633145b604051901515815260200161020c565b34801561036e57600080fd5b506101c561037d366004610dd7565b6108ff565b34801561038e57600080fd5b506101c561039d366004610e07565b610934565b3480156103ae57600080fd5b506101c56103bd366004610e24565b610971565b3480156103ce57600080fd5b506101c56103dd366004610e50565b6109e9565b3480156103ee57600080fd5b506104276103fd366004610d9c565b600a602052600090815260409020805460018201546002909201549091906001600160a01b031683565b6040805193845260208401929092526001600160a01b03169082015260600161020c565b34801561045757600080fd5b5061029f7308a7c8be47773546dc5e173d67b0c38afffa4b8481565b34801561047f57600080fd5b506101c561048e366004610d9c565b610ab0565b34801561049f57600080fd5b506006546103529060ff1681565b60065460ff16156104f65760405162461bcd60e51b8152602060048201526013602482015272135a59dc985d1a5bdb881a5cc81c185d5cd959606a1b6044820152606401610174565b6001805460009161050691610e90565b90505b4260016003548154811061051f5761051f610ea9565b906000526020600020015410156105905780600354106105765760405162461bcd60e51b8152602060048201526012602482015271135a59dc985d1a5bdb88199a5b9a5cda195960721b6044820152606401610174565b6003805490600061058683610ebf565b9190505550610509565b6000806002600354815481106105a8576105a8610ea9565b6000918252602090912001546001600160a01b031690508315610641576004546105d29086610ed8565b915084600860008282546105e69190610eef565b9091555050604080516001600160a01b038881168252602082018890528183018590528316606082015290517f426fdf2aca195443a56fd97ff4322fb73871d6267d946e27f5c5e9a23ee6668c9181900360800190a16106b9565b60055461064e9086610ed8565b915084600960008282546106629190610eef565b9091555050604080516001600160a01b038881168252602082018890528183018590528316606082015290517fab32f60d9601df5569fc8710263a70e63893cc3490f8af8f15168d4a3485e4779181900360800190a15b81600760008282546106cb9190610eef565b90915550506040516340c10f1960e01b81526001600160a01b038781166004830152602482018490528216906340c10f1990604401600060405180830381600087803b15801561071a57600080fd5b505af115801561072e573d6000803e3d6000fd5b50505050505050505050565b6000546001600160a01b031633146107645760405162461bcd60e51b815260040161017490610f02565b60006001600160a01b0382166107855750476107803382610ae6565b6107fa565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa1580156107c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ed9190610f25565b90506107fa823383610bb4565b604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af2910160405180910390a15050565b6001818154811061085057600080fd5b600091825260209091200154905081565b6000546001600160a01b0316331461088b5760405162461bcd60e51b815260040161017490610f02565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600281815481106108e557600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b031633146109295760405162461bcd60e51b815260040161017490610f02565b600491909155600555565b6000546001600160a01b0316331461095e5760405162461bcd60e51b815260040161017490610f02565b6006805460ff1916911515919091179055565b6000546001600160a01b0316331461099b5760405162461bcd60e51b815260040161017490610f02565b82600860008282546109ad9190610eef565b9250508190555081600960008282546109c69190610eef565b9250508190555080600760008282546109df9190610eef565b9091555050505050565b80600003610a235760405162461bcd60e51b8152602060048201526007602482015266302076616c756560c81b6044820152606401610174565b60405163079cc67960e41b815233600482015260248101829052731eaa43544daa399b87eecfcc6fa579d5ea4a6187906379cc6790906044016020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610f3e565b50610aac828260016104ad565b5050565b6000546001600160a01b03163314610ada5760405162461bcd60e51b815260040161017490610f02565b610ae381610ccf565b50565b604080516000808252602082019092526001600160a01b038416908390604051610b109190610f5b565b60006040518083038185875af1925050503d8060008114610b4d576040519150601f19603f3d011682016040523d82523d6000602084013e610b52565b606091505b5050905080610baf5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b6064820152608401610174565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691610c109190610f5b565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190610f3e565b610cc85760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610174565b5050505050565b6001600160a01b038116610d255760405162461bcd60e51b815260206004820152601860248201527f5a65726f2061646472657373206e6f7420616c6c6f77656400000000000000006044820152606401610174565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b0381168114610d9757600080fd5b919050565b600060208284031215610dae57600080fd5b610db782610d80565b9392505050565b600060208284031215610dd057600080fd5b5035919050565b60008060408385031215610dea57600080fd5b50508035926020909101359150565b8015158114610ae357600080fd5b600060208284031215610e1957600080fd5b8135610db781610df9565b600080600060608486031215610e3957600080fd5b505081359360208301359350604090920135919050565b60008060408385031215610e6357600080fd5b610e6c83610d80565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610ea357610ea3610e7a565b92915050565b634e487b7160e01b600052603260045260246000fd5b600060018201610ed157610ed1610e7a565b5060010190565b8082028115828204841417610ea357610ea3610e7a565b80820180821115610ea357610ea3610e7a565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b600060208284031215610f3757600080fd5b5051919050565b600060208284031215610f5057600080fd5b8151610db781610df9565b6000825160005b81811015610f7c5760208186018101518583015201610f62565b50600092019182525091905056fea264697066735822122020f3d312248687b2d3f243aeae761aac9ca67966a85636cd473d2358a8bd67ac64736f6c63430008130033

Deployed ByteCode

0x60806040526004361061012d5760003560e01c80638b50e446116100ab578063cc44fe391161006f578063cc44fe39146103a2578063ce067c86146103c2578063d66bd524146103e2578063dcf79c5a1461044b578063f2fde38b14610473578063ff0938a71461049357600080fd5b80638b50e446146103025780638da5cb5b146103185780638f32d59b14610336578063ac6af28014610362578063bedb86fb1461038257600080fd5b8063464982f9116100f2578063464982f9146102615780635eb325eb1461027757806367457720146102b7578063715018a6146102cd5780637a2786f6146102e257600080fd5b8062ae3bf8146101cc57806306040618146101ec57806327614ec4146102155780632da49d1614610235578063314de7c31461024b57600080fd5b366101c75760055460000361017d5760405162461bcd60e51b81526020600482015260116024820152701b5a59dc985d1a5bdb881cdd1bdc1c1959607a1b60448201526064015b60405180910390fd5b346000036101b75760405162461bcd60e51b8152602060048201526007602482015266302076616c756560c81b6044820152606401610174565b33346101c5828260006104ad565b005b600080fd5b3480156101d857600080fd5b506101c56101e7366004610d9c565b61073a565b3480156101f857600080fd5b5061020260035481565b6040519081526020015b60405180910390f35b34801561022157600080fd5b50610202610230366004610dbe565b610840565b34801561024157600080fd5b5061020260085481565b34801561025757600080fd5b5061020260045481565b34801561026d57600080fd5b5061020260095481565b34801561028357600080fd5b5061029f731eaa43544daa399b87eecfcc6fa579d5ea4a618781565b6040516001600160a01b03909116815260200161020c565b3480156102c357600080fd5b5061020260055481565b3480156102d957600080fd5b506101c5610861565b3480156102ee57600080fd5b5061029f6102fd366004610dbe565b6108d5565b34801561030e57600080fd5b5061020260075481565b34801561032457600080fd5b506000546001600160a01b031661029f565b34801561034257600080fd5b506000546001600160a01b031633145b604051901515815260200161020c565b34801561036e57600080fd5b506101c561037d366004610dd7565b6108ff565b34801561038e57600080fd5b506101c561039d366004610e07565b610934565b3480156103ae57600080fd5b506101c56103bd366004610e24565b610971565b3480156103ce57600080fd5b506101c56103dd366004610e50565b6109e9565b3480156103ee57600080fd5b506104276103fd366004610d9c565b600a602052600090815260409020805460018201546002909201549091906001600160a01b031683565b6040805193845260208401929092526001600160a01b03169082015260600161020c565b34801561045757600080fd5b5061029f7308a7c8be47773546dc5e173d67b0c38afffa4b8481565b34801561047f57600080fd5b506101c561048e366004610d9c565b610ab0565b34801561049f57600080fd5b506006546103529060ff1681565b60065460ff16156104f65760405162461bcd60e51b8152602060048201526013602482015272135a59dc985d1a5bdb881a5cc81c185d5cd959606a1b6044820152606401610174565b6001805460009161050691610e90565b90505b4260016003548154811061051f5761051f610ea9565b906000526020600020015410156105905780600354106105765760405162461bcd60e51b8152602060048201526012602482015271135a59dc985d1a5bdb88199a5b9a5cda195960721b6044820152606401610174565b6003805490600061058683610ebf565b9190505550610509565b6000806002600354815481106105a8576105a8610ea9565b6000918252602090912001546001600160a01b031690508315610641576004546105d29086610ed8565b915084600860008282546105e69190610eef565b9091555050604080516001600160a01b038881168252602082018890528183018590528316606082015290517f426fdf2aca195443a56fd97ff4322fb73871d6267d946e27f5c5e9a23ee6668c9181900360800190a16106b9565b60055461064e9086610ed8565b915084600960008282546106629190610eef565b9091555050604080516001600160a01b038881168252602082018890528183018590528316606082015290517fab32f60d9601df5569fc8710263a70e63893cc3490f8af8f15168d4a3485e4779181900360800190a15b81600760008282546106cb9190610eef565b90915550506040516340c10f1960e01b81526001600160a01b038781166004830152602482018490528216906340c10f1990604401600060405180830381600087803b15801561071a57600080fd5b505af115801561072e573d6000803e3d6000fd5b50505050505050505050565b6000546001600160a01b031633146107645760405162461bcd60e51b815260040161017490610f02565b60006001600160a01b0382166107855750476107803382610ae6565b6107fa565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa1580156107c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ed9190610f25565b90506107fa823383610bb4565b604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af2910160405180910390a15050565b6001818154811061085057600080fd5b600091825260209091200154905081565b6000546001600160a01b0316331461088b5760405162461bcd60e51b815260040161017490610f02565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600281815481106108e557600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b031633146109295760405162461bcd60e51b815260040161017490610f02565b600491909155600555565b6000546001600160a01b0316331461095e5760405162461bcd60e51b815260040161017490610f02565b6006805460ff1916911515919091179055565b6000546001600160a01b0316331461099b5760405162461bcd60e51b815260040161017490610f02565b82600860008282546109ad9190610eef565b9250508190555081600960008282546109c69190610eef565b9250508190555080600760008282546109df9190610eef565b9091555050505050565b80600003610a235760405162461bcd60e51b8152602060048201526007602482015266302076616c756560c81b6044820152606401610174565b60405163079cc67960e41b815233600482015260248101829052731eaa43544daa399b87eecfcc6fa579d5ea4a6187906379cc6790906044016020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610f3e565b50610aac828260016104ad565b5050565b6000546001600160a01b03163314610ada5760405162461bcd60e51b815260040161017490610f02565b610ae381610ccf565b50565b604080516000808252602082019092526001600160a01b038416908390604051610b109190610f5b565b60006040518083038185875af1925050503d8060008114610b4d576040519150601f19603f3d011682016040523d82523d6000602084013e610b52565b606091505b5050905080610baf5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b6064820152608401610174565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691610c109190610f5b565b6000604051808303816000865af19150503d8060008114610c4d576040519150601f19603f3d011682016040523d82523d6000602084013e610c52565b606091505b5091509150818015610c7c575080511580610c7c575080806020019051810190610c7c9190610f3e565b610cc85760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152606401610174565b5050505050565b6001600160a01b038116610d255760405162461bcd60e51b815260206004820152601860248201527f5a65726f2061646472657373206e6f7420616c6c6f77656400000000000000006044820152606401610174565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b0381168114610d9757600080fd5b919050565b600060208284031215610dae57600080fd5b610db782610d80565b9392505050565b600060208284031215610dd057600080fd5b5035919050565b60008060408385031215610dea57600080fd5b50508035926020909101359150565b8015158114610ae357600080fd5b600060208284031215610e1957600080fd5b8135610db781610df9565b600080600060608486031215610e3957600080fd5b505081359360208301359350604090920135919050565b60008060408385031215610e6357600080fd5b610e6c83610d80565b946020939093013593505050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610ea357610ea3610e7a565b92915050565b634e487b7160e01b600052603260045260246000fd5b600060018201610ed157610ed1610e7a565b5060010190565b8082028115828204841417610ea357610ea3610e7a565b80820180821115610ea357610ea3610e7a565b6020808252600990820152682737ba1027bbb732b960b91b604082015260600190565b600060208284031215610f3757600080fd5b5051919050565b600060208284031215610f5057600080fd5b8151610db781610df9565b6000825160005b81811015610f7c5760208186018101518583015201610f62565b50600092019182525091905056fea264697066735822122020f3d312248687b2d3f243aeae761aac9ca67966a85636cd473d2358a8bd67ac64736f6c63430008130033