false
false
0

Contract Address Details

0x9485ACB40C5c3229a48558BC79c005e78f2817fE

Contract Name
SalaryVesting
Creator
0xc7d98c–7f3521 at 0xb306ab–b50140
Balance
0 CLO
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
18610864
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
SalaryVesting




Optimization enabled
true
Compiler version
v0.8.18+commit.87f61d96




Optimization runs
200
EVM Version
default




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

Constructor Arguments

0x000000000000000000000000b7971f9b973b3a630ef13d3f65d3f88ae8a51f91000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000065324c1c000000000000000000000000c7d98c4c919e93ed44755718e27b53791e7f3521

Arg [0] (address) : 0xb7971f9b973b3a630ef13d3f65d3f88ae8a51f91
Arg [1] (uint256) : 2
Arg [2] (uint256) : 1
Arg [3] (uint256) : 1697795100
Arg [4] (address) : 0xc7d98c4c919e93ed44755718e27b53791e7f3521

              

Contract source code

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

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable {
    address internal _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     *//*
    constructor () {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);
    }
    */

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev 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.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

interface ISoyPair {
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 
}

interface IERC20 {
    function balanceOf(address owner) external view returns (uint);
    function transfer(address to, uint value) external;
}

contract SalaryVesting is Ownable {

    ISoyPair constant public CLO_BUSDT = ISoyPair(0xB852AD87329986EaC6e991954fe329231D1E4De1);    // reserve0 - BUSDT, reserve1 - WCLO


    address public employee;    // address of employee who can claim CLO
    uint256 public startTimestamp;  // timestamp from which start periods
    uint256 public salary; // salary in BUSDT
    uint256 public salaryPeriod = 30;   // salary period in days
    uint256 public lastSalaryClaim; // timestamp when salary was claimed last time
    uint256 public bonus; // bonus in BUSDT
    uint256 public bonusPeriod = 91;    // period in days for bonus
    uint256 public lastBonusClaim; // timestamp when bonus was claimed last time
    bool public isPaused;

    event SetSalary(address _employee, uint256 _salary, uint256 _bonus);
    event SetPeriods(uint256 _salaryPeriod, uint256 _bonusPeriod);
    event Claim(uint256 amount);

    event Rescue(address _token, uint256 _amount);

    constructor (address _employee, uint256 _salary, uint256 _bonus, uint256 _startTimestamp, address _newOwner) {
        require(_startTimestamp != 0);
        startTimestamp = _startTimestamp;
        lastSalaryClaim = _startTimestamp;
        lastBonusClaim = _startTimestamp;
        employee = _employee;
        salary = _salary;
        bonus = _bonus;
        emit SetSalary(_employee, _salary, _bonus);
        _owner = _newOwner;
        emit OwnershipTransferred(address(0), _newOwner);
    }

    receive() external payable {}

    // Set salary in BUSDT without decimals
    function setSalary(address _employee, uint256 _salary, uint256 _bonus) external onlyOwner {
        employee = _employee;
        salary = _salary;
        bonus = _bonus;
        emit SetSalary(_employee, _salary, _bonus);
    }

    // Set periods in days
    function setPeriods(uint256 _salaryPeriod, uint256 _bonusPeriod) external onlyOwner {
        bonusPeriod = _bonusPeriod;
        salaryPeriod = _salaryPeriod;
        emit SetPeriods(_salaryPeriod, _bonusPeriod);
    }

    function setPause(bool pause) external onlyOwner {
       isPaused = pause;
    }

    function claim() external {
        require(!isPaused, "Payout paused");
        require(msg.sender == employee, "Only employee");
        uint256 unlockedAmount = getUnlockedAmount();
        if (unlockedAmount != 0) {
            uint256 balance = address(this).balance;
            if (unlockedAmount > balance) unlockedAmount = balance;
            lastSalaryClaim = block.timestamp;
            lastBonusClaim = block.timestamp;
            safeTransferCLO(employee, unlockedAmount);
            emit Claim(unlockedAmount);
        }
    }


    // return unlocked amount of CLO
    function getUnlockedAmount() public view returns(uint256 unlockedAmount) {
        // calculate BUSDT amount for salary 
        uint256 paidPeriods = (lastSalaryClaim - startTimestamp) / (salaryPeriod * 1 minutes);
        uint256 passedPeriods = (block.timestamp - startTimestamp) / (salaryPeriod * 1 minutes);
        uint256 unpaidPeriods = passedPeriods - paidPeriods;
        uint256 pendingBUSDT = unpaidPeriods * salary;   // pending amount in BUSDT

        // calculate BUSDT amount for bonus 
        paidPeriods = (lastBonusClaim - startTimestamp) / (bonusPeriod * 1 minutes);
        passedPeriods = (block.timestamp - startTimestamp) / (bonusPeriod * 1 minutes);
        unpaidPeriods = passedPeriods - paidPeriods;
        pendingBUSDT += (unpaidPeriods * bonus);     // pending amount in BUSDT

        // calculate CLO amount based on CLO_BUSDT pool
        (uint112 reserveBUSDT, uint112 reserveCLO,) = CLO_BUSDT.getReserves();
        unlockedAmount = pendingBUSDT * reserveCLO / reserveBUSDT;
    }

    function getUnallocatedAmount() public view returns(uint256 amount) {
        amount = address(this).balance;
        uint256 unclaimed = getUnlockedAmount();
        if (amount > unclaimed) amount = amount - unclaimed;
        else amount = 0;
    }

    function rescueTokens(address _token) onlyOwner external {
        uint256 amount;
        if (_token == address(0)) {
            amount = address(this).balance;
            safeTransferCLO(msg.sender, amount);
        } else {
            amount = IERC20(_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 safeTransferCLO(address to, uint value) internal {
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: CLO_TRANSFER_FAILED');
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_employee","internalType":"address"},{"type":"uint256","name":"_salary","internalType":"uint256"},{"type":"uint256","name":"_bonus","internalType":"uint256"},{"type":"uint256","name":"_startTimestamp","internalType":"uint256"},{"type":"address","name":"_newOwner","internalType":"address"}]},{"type":"event","name":"Claim","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","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":"event","name":"SetPeriods","inputs":[{"type":"uint256","name":"_salaryPeriod","internalType":"uint256","indexed":false},{"type":"uint256","name":"_bonusPeriod","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetSalary","inputs":[{"type":"address","name":"_employee","internalType":"address","indexed":false},{"type":"uint256","name":"_salary","internalType":"uint256","indexed":false},{"type":"uint256","name":"_bonus","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ISoyPair"}],"name":"CLO_BUSDT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"bonus","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"bonusPeriod","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claim","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"employee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"}],"name":"getUnallocatedAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"unlockedAmount","internalType":"uint256"}],"name":"getUnlockedAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPaused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastBonusClaim","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastSalaryClaim","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"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":"","internalType":"uint256"}],"name":"salary","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"salaryPeriod","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPause","inputs":[{"type":"bool","name":"pause","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPeriods","inputs":[{"type":"uint256","name":"_salaryPeriod","internalType":"uint256"},{"type":"uint256","name":"_bonusPeriod","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSalary","inputs":[{"type":"address","name":"_employee","internalType":"address"},{"type":"uint256","name":"_salary","internalType":"uint256"},{"type":"uint256","name":"_bonus","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"startTimestamp","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

Verify & Publish
0x6080604052601e600455605b60075534801561001a57600080fd5b506040516110303803806110308339810160408190526100399161012b565b8160000361004657600080fd5b600282905560058290556008829055600180546001600160a01b0319166001600160a01b03871690811790915560038590556006849055604080519182526020820186905281018490527f70c22001aa542796dc91ca19cb337e7ea7d4fcf47d2b7ddcbc0ee3fd856c74799060600160405180910390a1600080546001600160a01b0319166001600160a01b03831690811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505050505061017b565b80516001600160a01b038116811461012657600080fd5b919050565b600080600080600060a0868803121561014357600080fd5b61014c8661010f565b945060208601519350604086015192506060860151915061016f6080870161010f565b90509295509295909350565b610ea68061018a6000396000f3fe6080604052600436106101225760003560e01c8063767ac369116100a0578063bedb86fb11610064578063bedb86fb146102f7578063dc16edf314610317578063e6fd48bc1461032d578063f2fde38b14610343578063f79bc6351461036357600080fd5b8063767ac3691461024f5780637ebe37971461026f5780638da5cb5b1461028f578063a0a1a7d7146102ad578063b187bd26146102cd57600080fd5b80634af4a127116100e75780634af4a127146101e35780634e71d92d146101f957806363ec240a1461020e578063715018a61461022457806375b4d78c1461023957600080fd5b8062ae3bf81461012e5780630397b6521461015057806324ea36261461017957806328733bb71461018e578063427de6c1146101a357600080fd5b3661012957005b600080fd5b34801561013a57600080fd5b5061014e610149366004610c52565b610379565b005b34801561015c57600080fd5b5061016660035481565b6040519081526020015b60405180910390f35b34801561018557600080fd5b50610166610498565b34801561019a57600080fd5b5061016661063b565b3480156101af57600080fd5b506101cb73b852ad87329986eac6e991954fe329231d1e4de181565b6040516001600160a01b039091168152602001610170565b3480156101ef57600080fd5b5061016660075481565b34801561020557600080fd5b5061014e610668565b34801561021a57600080fd5b5061016660055481565b34801561023057600080fd5b5061014e610766565b34801561024557600080fd5b5061016660065481565b34801561025b57600080fd5b5061014e61026a366004610c74565b6107e9565b34801561027b57600080fd5b5061014e61028a366004610c96565b610862565b34801561029b57600080fd5b506000546001600160a01b03166101cb565b3480156102b957600080fd5b506001546101cb906001600160a01b031681565b3480156102d957600080fd5b506009546102e79060ff1681565b6040519015158152602001610170565b34801561030357600080fd5b5061014e610312366004610cd7565b610908565b34801561032357600080fd5b5061016660085481565b34801561033957600080fd5b5061016660025481565b34801561034f57600080fd5b5061014e61035e366004610c52565b610954565b34801561036f57600080fd5b5061016660045481565b3361038c6000546001600160a01b031690565b6001600160a01b0316146103bb5760405162461bcd60e51b81526004016103b290610cf4565b60405180910390fd5b60006001600160a01b0382166103dc5750476103d73382610a4d565b610451565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610420573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104449190610d29565b9050610451823383610b1b565b604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af291015b60405180910390a15050565b600080600454603c6104aa9190610d58565b6002546005546104ba9190610d75565b6104c49190610d88565b90506000600454603c6104d79190610d58565b6002546104e49042610d75565b6104ee9190610d88565b905060006104fc8383610d75565b905060006003548261050e9190610d58565b9050600754603c61051f9190610d58565b60025460085461052f9190610d75565b6105399190610d88565b9350600754603c61054a9190610d58565b6002546105579042610d75565b6105619190610d88565b925061056d8484610d75565b91506006548261057d9190610d58565b6105879082610daa565b905060008073b852ad87329986eac6e991954fe329231d1e4de16001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156105de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106029190610dd4565b5091509150816001600160701b0316816001600160701b0316846106269190610d58565b6106309190610d88565b965050505050505090565b476000610646610498565b9050808211156106605761065a8183610d75565b91505090565b600091505090565b60095460ff16156106ab5760405162461bcd60e51b815260206004820152600d60248201526c14185e5bdd5d081c185d5cd959609a1b60448201526064016103b2565b6001546001600160a01b031633146106f55760405162461bcd60e51b815260206004820152600d60248201526c4f6e6c7920656d706c6f79656560981b60448201526064016103b2565b60006106ff610498565b90508015610763574780821115610714578091505b426005819055600855600154610733906001600160a01b031683610a4d565b6040518281527f7bb2b3c10797baccb6f8c4791f1edd6ca2f0d028ee0eda64b01a9a57e3a653f79060200161048c565b50565b336107796000546001600160a01b031690565b6001600160a01b03161461079f5760405162461bcd60e51b81526004016103b290610cf4565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b336107fc6000546001600160a01b031690565b6001600160a01b0316146108225760405162461bcd60e51b81526004016103b290610cf4565b6007819055600482905560408051838152602081018390527ff355485fd39648c96140f89a21fb926a63ae03457c42858e830db3b48afba0f2910161048c565b336108756000546001600160a01b031690565b6001600160a01b03161461089b5760405162461bcd60e51b81526004016103b290610cf4565b600180546001600160a01b0319166001600160a01b03851690811790915560038390556006829055604080519182526020820184905281018290527f70c22001aa542796dc91ca19cb337e7ea7d4fcf47d2b7ddcbc0ee3fd856c74799060600160405180910390a1505050565b3361091b6000546001600160a01b031690565b6001600160a01b0316146109415760405162461bcd60e51b81526004016103b290610cf4565b6009805460ff1916911515919091179055565b336109676000546001600160a01b031690565b6001600160a01b03161461098d5760405162461bcd60e51b81526004016103b290610cf4565b6001600160a01b0381166109f25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103b2565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b604080516000808252602082019092526001600160a01b038416908390604051610a779190610e24565b60006040518083038185875af1925050503d8060008114610ab4576040519150601f19603f3d011682016040523d82523d6000602084013e610ab9565b606091505b5050905080610b165760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a20434c4f5f5452414e534645525f46414960448201526213115160ea1b60648201526084016103b2565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691610b779190610e24565b6000604051808303816000865af19150503d8060008114610bb4576040519150601f19603f3d011682016040523d82523d6000602084013e610bb9565b606091505b5091509150818015610be3575080511580610be3575080806020019051810190610be39190610e53565b610c2f5760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016103b2565b5050505050565b80356001600160a01b0381168114610c4d57600080fd5b919050565b600060208284031215610c6457600080fd5b610c6d82610c36565b9392505050565b60008060408385031215610c8757600080fd5b50508035926020909101359150565b600080600060608486031215610cab57600080fd5b610cb484610c36565b95602085013595506040909401359392505050565b801515811461076357600080fd5b600060208284031215610ce957600080fd5b8135610c6d81610cc9565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600060208284031215610d3b57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610d6f57610d6f610d42565b92915050565b81810381811115610d6f57610d6f610d42565b600082610da557634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610d6f57610d6f610d42565b80516001600160701b0381168114610c4d57600080fd5b600080600060608486031215610de957600080fd5b610df284610dbd565b9250610e0060208501610dbd565b9150604084015163ffffffff81168114610e1957600080fd5b809150509250925092565b6000825160005b81811015610e455760208186018101518583015201610e2b565b506000920191825250919050565b600060208284031215610e6557600080fd5b8151610c6d81610cc956fea264697066735822122083d19da62668c75e04f95aaf5143d53c7e129ce110cc0b6b191c3c1ac701c87264736f6c63430008120033000000000000000000000000b7971f9b973b3a630ef13d3f65d3f88ae8a51f91000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000065324c1c000000000000000000000000c7d98c4c919e93ed44755718e27b53791e7f3521

Deployed ByteCode

0x6080604052600436106101225760003560e01c8063767ac369116100a0578063bedb86fb11610064578063bedb86fb146102f7578063dc16edf314610317578063e6fd48bc1461032d578063f2fde38b14610343578063f79bc6351461036357600080fd5b8063767ac3691461024f5780637ebe37971461026f5780638da5cb5b1461028f578063a0a1a7d7146102ad578063b187bd26146102cd57600080fd5b80634af4a127116100e75780634af4a127146101e35780634e71d92d146101f957806363ec240a1461020e578063715018a61461022457806375b4d78c1461023957600080fd5b8062ae3bf81461012e5780630397b6521461015057806324ea36261461017957806328733bb71461018e578063427de6c1146101a357600080fd5b3661012957005b600080fd5b34801561013a57600080fd5b5061014e610149366004610c52565b610379565b005b34801561015c57600080fd5b5061016660035481565b6040519081526020015b60405180910390f35b34801561018557600080fd5b50610166610498565b34801561019a57600080fd5b5061016661063b565b3480156101af57600080fd5b506101cb73b852ad87329986eac6e991954fe329231d1e4de181565b6040516001600160a01b039091168152602001610170565b3480156101ef57600080fd5b5061016660075481565b34801561020557600080fd5b5061014e610668565b34801561021a57600080fd5b5061016660055481565b34801561023057600080fd5b5061014e610766565b34801561024557600080fd5b5061016660065481565b34801561025b57600080fd5b5061014e61026a366004610c74565b6107e9565b34801561027b57600080fd5b5061014e61028a366004610c96565b610862565b34801561029b57600080fd5b506000546001600160a01b03166101cb565b3480156102b957600080fd5b506001546101cb906001600160a01b031681565b3480156102d957600080fd5b506009546102e79060ff1681565b6040519015158152602001610170565b34801561030357600080fd5b5061014e610312366004610cd7565b610908565b34801561032357600080fd5b5061016660085481565b34801561033957600080fd5b5061016660025481565b34801561034f57600080fd5b5061014e61035e366004610c52565b610954565b34801561036f57600080fd5b5061016660045481565b3361038c6000546001600160a01b031690565b6001600160a01b0316146103bb5760405162461bcd60e51b81526004016103b290610cf4565b60405180910390fd5b60006001600160a01b0382166103dc5750476103d73382610a4d565b610451565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa158015610420573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104449190610d29565b9050610451823383610b1b565b604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af291015b60405180910390a15050565b600080600454603c6104aa9190610d58565b6002546005546104ba9190610d75565b6104c49190610d88565b90506000600454603c6104d79190610d58565b6002546104e49042610d75565b6104ee9190610d88565b905060006104fc8383610d75565b905060006003548261050e9190610d58565b9050600754603c61051f9190610d58565b60025460085461052f9190610d75565b6105399190610d88565b9350600754603c61054a9190610d58565b6002546105579042610d75565b6105619190610d88565b925061056d8484610d75565b91506006548261057d9190610d58565b6105879082610daa565b905060008073b852ad87329986eac6e991954fe329231d1e4de16001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156105de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106029190610dd4565b5091509150816001600160701b0316816001600160701b0316846106269190610d58565b6106309190610d88565b965050505050505090565b476000610646610498565b9050808211156106605761065a8183610d75565b91505090565b600091505090565b60095460ff16156106ab5760405162461bcd60e51b815260206004820152600d60248201526c14185e5bdd5d081c185d5cd959609a1b60448201526064016103b2565b6001546001600160a01b031633146106f55760405162461bcd60e51b815260206004820152600d60248201526c4f6e6c7920656d706c6f79656560981b60448201526064016103b2565b60006106ff610498565b90508015610763574780821115610714578091505b426005819055600855600154610733906001600160a01b031683610a4d565b6040518281527f7bb2b3c10797baccb6f8c4791f1edd6ca2f0d028ee0eda64b01a9a57e3a653f79060200161048c565b50565b336107796000546001600160a01b031690565b6001600160a01b03161461079f5760405162461bcd60e51b81526004016103b290610cf4565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b336107fc6000546001600160a01b031690565b6001600160a01b0316146108225760405162461bcd60e51b81526004016103b290610cf4565b6007819055600482905560408051838152602081018390527ff355485fd39648c96140f89a21fb926a63ae03457c42858e830db3b48afba0f2910161048c565b336108756000546001600160a01b031690565b6001600160a01b03161461089b5760405162461bcd60e51b81526004016103b290610cf4565b600180546001600160a01b0319166001600160a01b03851690811790915560038390556006829055604080519182526020820184905281018290527f70c22001aa542796dc91ca19cb337e7ea7d4fcf47d2b7ddcbc0ee3fd856c74799060600160405180910390a1505050565b3361091b6000546001600160a01b031690565b6001600160a01b0316146109415760405162461bcd60e51b81526004016103b290610cf4565b6009805460ff1916911515919091179055565b336109676000546001600160a01b031690565b6001600160a01b03161461098d5760405162461bcd60e51b81526004016103b290610cf4565b6001600160a01b0381166109f25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103b2565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b604080516000808252602082019092526001600160a01b038416908390604051610a779190610e24565b60006040518083038185875af1925050503d8060008114610ab4576040519150601f19603f3d011682016040523d82523d6000602084013e610ab9565b606091505b5050905080610b165760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a20434c4f5f5452414e534645525f46414960448201526213115160ea1b60648201526084016103b2565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691610b779190610e24565b6000604051808303816000865af19150503d8060008114610bb4576040519150601f19603f3d011682016040523d82523d6000602084013e610bb9565b606091505b5091509150818015610be3575080511580610be3575080806020019051810190610be39190610e53565b610c2f5760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016103b2565b5050505050565b80356001600160a01b0381168114610c4d57600080fd5b919050565b600060208284031215610c6457600080fd5b610c6d82610c36565b9392505050565b60008060408385031215610c8757600080fd5b50508035926020909101359150565b600080600060608486031215610cab57600080fd5b610cb484610c36565b95602085013595506040909401359392505050565b801515811461076357600080fd5b600060208284031215610ce957600080fd5b8135610c6d81610cc9565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600060208284031215610d3b57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610d6f57610d6f610d42565b92915050565b81810381811115610d6f57610d6f610d42565b600082610da557634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610d6f57610d6f610d42565b80516001600160701b0381168114610c4d57600080fd5b600080600060608486031215610de957600080fd5b610df284610dbd565b9250610e0060208501610dbd565b9150604084015163ffffffff81168114610e1957600080fd5b809150509250925092565b6000825160005b81811015610e455760208186018101518583015201610e2b565b506000920191825250919050565b600060208284031215610e6557600080fd5b8151610c6d81610cc956fea264697066735822122083d19da62668c75e04f95aaf5143d53c7e129ce110cc0b6b191c3c1ac701c87264736f6c63430008120033