false
false
0
Contract Address Details
contract

0xc2780EBF3e5B877192031a665EA95a35BB4fFACb

Sponsored: ERAM, a pioneering Central Bank Blockchain. The First Banking Regulatory Blockchain, Licensed by the Central Bank.

ERAM, Central Bank Digital Currency (CBDC) (STABLE COIN)

Overview

ERAM Balance

0 ERAM

ERAM Value

$0.00

Token Holdings

Fetching tokens...

More Info

Private Name Tags

Last Balance Update

Blocks Validated

Sponsored

Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
TokenLocker




Optimization enabled
true
Compiler version
v0.8.13+commit.abaa5c0e




Optimization runs
5000
EVM Version
default




Verified at
2024-07-20T06:18:53.595951Z

Constructor Arguments

0x0000000000000000000000008df97eab2651e87a8a4080008ddabf6824c9f672000000000000000000000000000000000000000000000000002386f26fc10000

Arg [0] (address) : 0x8df97eab2651e87a8a4080008ddabf6824c9f672
Arg [1] (uint256) : 10000000000000000

              

contracts/TokenLock/TokenLock.sol

Sol2uml
new
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract TokenLocker {
    address public owner;
    uint256 public price;
    uint256 public penaltyfee;

    struct holder {
        address holderAddress;
        mapping(address => Token) tokens;
    }

    struct Token {
        uint256 balance;
        address tokenAddress;
        uint256 unlockTime;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only available to the contract owner.");
        _;
    }

    mapping(address => holder) public holders;

    constructor(address _owner, uint256 _price) {
        owner = _owner;
        price = _price;
        penaltyfee = 10; // default value
    }

    event Hold(
        address indexed holder,
        address token,
        uint256 amount,
        uint256 unlockTime
    );

    event PanicWithdraw(
        address indexed holder,
        address token,
        uint256 amount,
        uint256 unlockTime
    );

    event Withdrawal(address indexed holder, address token, uint256 amount);

    event FeesClaimed();

    event SetOwnerSuccess(address owner);

    event SetPriceSuccess(uint256 _price);

    event SetPenaltyFeeSuccess(uint256 _fee);

    event OwnerWithdrawSuccess(uint256 amount);

    function tokenLock(
        address token,
        uint256 amount,
        uint256 unlockTime,
        address withdrawer
    ) public payable {
        require(msg.value >= price, "Required price is low");

        holder storage holder0 = holders[withdrawer];
        holder0.holderAddress = withdrawer;

        Token storage lockedToken = holders[withdrawer].tokens[token];

        if (lockedToken.balance > 0) {
            lockedToken.balance += amount;

            if (lockedToken.unlockTime < unlockTime) {
                lockedToken.unlockTime = unlockTime;
            }
        } else {
            holders[withdrawer].tokens[token] = Token(
                amount,
                token,
                unlockTime
            );
        }

        IERC20(token).transferFrom(withdrawer, address(this), amount);

        emit Hold(withdrawer, token, amount, unlockTime);
    }

    function withdraw(address token) public {
        holder storage holder0 = holders[msg.sender];

        require(
            msg.sender == holder0.holderAddress,
            "Only available to the token owner."
        );

        require(
            block.timestamp > holder0.tokens[token].unlockTime,
            "Unlock time not reached yet."
        );

        uint256 amount = holder0.tokens[token].balance;

        holder0.tokens[token].balance = 0;

        IERC20(token).transfer(msg.sender, amount);

        emit Withdrawal(msg.sender, token, amount);
    }

    function panicWithdraw(address token) public {
        holder storage holder0 = holders[msg.sender];

        require(
            msg.sender == holder0.holderAddress,
            "Only available to the token owner."
        );

        uint256 feeAmount = (holder0.tokens[token].balance / 100) * penaltyfee;
        uint256 withdrawalAmount = holder0.tokens[token].balance - feeAmount;

        holder0.tokens[token].balance = 0;

        //Transfers fees to the contract administrator/owner
        // holders[address(owner)].tokens[token].balance = feeAmount;

        // Transfers fees to the token owner
        IERC20(token).transfer(msg.sender, withdrawalAmount);

        // Transfers fees to the contract administrator/owner
        IERC20(token).transfer(owner, feeAmount);

        emit PanicWithdraw(
            msg.sender,
            token,
            withdrawalAmount,
            holder0.tokens[token].unlockTime
        );
    }

    // function claimTokenListFees(address[] memory tokenList) public onlyOwner {

    //     for (uint256 i = 0; i < tokenList.length; i++) {

    //         uint256 amount = holders[owner].tokens[tokenList[i]].balance;

    //         if (amount > 0) {

    //             holders[owner].tokens[tokenList[i]].balance = 0;

    //             IERC20(tokenList[i]).transfer(owner, amount);
    //         }
    //     }
    //     emit FeesClaimed();
    // }

    // function claimTokenFees(address token) public onlyOwner {

    //     uint256 amount = holders[owner].tokens[token].balance;

    //     require(amount > 0, "No fees available for claiming.");

    //     holders[owner].tokens[token].balance = 0;

    //     IERC20(token).transfer(owner, amount);

    //     emit FeesClaimed();
    // }

    function OwnerWithdraw() public onlyOwner {
        uint256 amount = address(this).balance;
        address payable ownerAddress = payable(owner);

        ownerAddress.transfer(amount);

        emit OwnerWithdrawSuccess(amount);
    }

    function getcurtime() public view returns (uint256) {
        return block.timestamp;
    }

    function GetBalance(address token) public view returns (uint256) {
        Token storage lockedToken = holders[msg.sender].tokens[token];
        return lockedToken.balance;
    }

    function SetOwner(address contractowner) public onlyOwner {
        owner = contractowner;
        emit SetOwnerSuccess(owner);
    }

    function SetPrice(uint256 _price) public onlyOwner {
        price = _price;
        emit SetPriceSuccess(price);
    }

    // function GetPrice() public view returns (uint256) {
    //     return price;
    // }

    function SetPenaltyFee(uint256 _penaltyfee) public onlyOwner {
        penaltyfee = _penaltyfee;
        emit SetPenaltyFeeSuccess(penaltyfee);
    }

    // function GetPenaltyFee() public view returns (uint256) {
    //     return penaltyfee;
    // }

    function GetUnlockTime(address token) public view returns (uint256) {
        Token storage lockedToken = holders[msg.sender].tokens[token];
        return lockedToken.unlockTime;
    }
}
        

@openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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);
}
          

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","devdoc","userdoc","storageLayout","evm.gasEstimates"],"":["ast"]}},"optimizer":{"runs":5000,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_price","internalType":"uint256"}]},{"type":"event","name":"FeesClaimed","inputs":[],"anonymous":false},{"type":"event","name":"Hold","inputs":[{"type":"address","name":"holder","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"unlockTime","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnerWithdrawSuccess","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"PanicWithdraw","inputs":[{"type":"address","name":"holder","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"unlockTime","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetOwnerSuccess","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetPenaltyFeeSuccess","inputs":[{"type":"uint256","name":"_fee","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetPriceSuccess","inputs":[{"type":"uint256","name":"_price","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrawal","inputs":[{"type":"address","name":"holder","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"GetBalance","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"GetUnlockTime","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"OwnerWithdraw","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"SetOwner","inputs":[{"type":"address","name":"contractowner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"SetPenaltyFee","inputs":[{"type":"uint256","name":"_penaltyfee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"SetPrice","inputs":[{"type":"uint256","name":"_price","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getcurtime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"holderAddress","internalType":"address"}],"name":"holders","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"panicWithdraw","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"penaltyfee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"price","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"tokenLock","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"unlockTime","internalType":"uint256"},{"type":"address","name":"withdrawer","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"token","internalType":"address"}]}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b50604051610f7a380380610f7a83398101604081905261002f9161005d565b600080546001600160a01b0319166001600160a01b039390931692909217909155600155600a600255610097565b6000806040838503121561007057600080fd5b82516001600160a01b038116811461008757600080fd5b6020939093015192949293505050565b610ed4806100a66000396000f3fe6080604052600436106100dd5760003560e01c80634e92afc81161007f5780636ad8809b116100595780636ad8809b146102a15780638da5cb5b146102b4578063a035b1fe146102d4578063fcea7d37146102ea57600080fd5b80634e92afc8146102175780634f5539c01461026157806351cff8d91461028157600080fd5b806318a5bbdc116100bb57806318a5bbdc14610144578063272a5c47146101975780632c84d560146101bb57806343e2e504146101d057600080fd5b80630949083b146100e25780631444cf3914610104578063167d3e9c14610124575b600080fd5b3480156100ee57600080fd5b506101026100fd366004610d25565b6102fd565b005b34801561011057600080fd5b5061010261011f366004610d47565b61058c565b34801561013057600080fd5b5061010261013f366004610d25565b610648565b34801561015057600080fd5b5061017a61015f366004610d25565b6003602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a357600080fd5b506101ad60025481565b60405190815260200161018e565b3480156101c757600080fd5b5061010261072e565b3480156101dc57600080fd5b506101ad6101eb366004610d25565b3360009081526003602090815260408083206001600160a01b0394909416835260019093019052205490565b34801561022357600080fd5b506101ad610232366004610d25565b3360009081526003602090815260408083206001600160a01b0394909416835260019093019052206002015490565b34801561026d57600080fd5b5061010261027c366004610d47565b610824565b34801561028d57600080fd5b5061010261029c366004610d25565b6108d9565b3480156102ad57600080fd5b50426101ad565b3480156102c057600080fd5b5060005461017a906001600160a01b031681565b3480156102e057600080fd5b506101ad60015481565b6101026102f8366004610d60565b610ac0565b336000818152600360205260409020805490916001600160a01b03909116146103935760405162461bcd60e51b815260206004820152602260248201527f4f6e6c7920617661696c61626c6520746f2074686520746f6b656e206f776e6560448201527f722e00000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6002546001600160a01b03831660009081526001830160205260408120549091906103c090606490610dd5565b6103ca9190610e10565b6001600160a01b0384166000908152600184016020526040812054919250906103f4908390610e4d565b6001600160a01b038516600081815260018601602052604080822091909155517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018390529192509063a9059cbb906044016020604051808303816000875af1158015610470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104949190610e64565b506000546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152602481018490529085169063a9059cbb906044016020604051808303816000875af1158015610501573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105259190610e64565b506001600160a01b03841660008181526001850160209081526040918290206002015482519384529083018490529082015233907f4ac88631be4f499653ed7b66b6f8e58dfc443de552029ad793891daf8ffc5ae79060600160405180910390a250505050565b6000546001600160a01b0316331461060c5760405162461bcd60e51b815260206004820152602560248201527f4f6e6c7920617661696c61626c6520746f2074686520636f6e7472616374206f60448201527f776e65722e000000000000000000000000000000000000000000000000000000606482015260840161038a565b60028190556040518181527fedcd245976eea9fd65115c661166bb4c47dee4016fecd9c8793899e6f27492cd906020015b60405180910390a150565b6000546001600160a01b031633146106c85760405162461bcd60e51b815260206004820152602560248201527f4f6e6c7920617661696c61626c6520746f2074686520636f6e7472616374206f60448201527f776e65722e000000000000000000000000000000000000000000000000000000606482015260840161038a565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f38c6b687fdabf6d647e4a6206aeb599852214abb9a8ef2468862b6dea3fd50949060200161063d565b6000546001600160a01b031633146107ae5760405162461bcd60e51b815260206004820152602560248201527f4f6e6c7920617661696c61626c6520746f2074686520636f6e7472616374206f60448201527f776e65722e000000000000000000000000000000000000000000000000000000606482015260840161038a565b6000805460405147926001600160a01b0390921691829184156108fc0291859190818181858888f193505050501580156107ec573d6000803e3d6000fd5b506040518281527fc67a6e2c9e13b320d5ce7e24743ea93ba9261320310966dd6240569493690eff9060200160405180910390a15050565b6000546001600160a01b031633146108a45760405162461bcd60e51b815260206004820152602560248201527f4f6e6c7920617661696c61626c6520746f2074686520636f6e7472616374206f60448201527f776e65722e000000000000000000000000000000000000000000000000000000606482015260840161038a565b60018190556040518181527f464ca40143674f1d1aba4360a8ed0760e2b1dbfc9f5dca703b77c01268509cf69060200161063d565b336000818152600360205260409020805490916001600160a01b039091161461096a5760405162461bcd60e51b815260206004820152602260248201527f4f6e6c7920617661696c61626c6520746f2074686520746f6b656e206f776e6560448201527f722e000000000000000000000000000000000000000000000000000000000000606482015260840161038a565b6001600160a01b038216600090815260018201602052604090206002015442116109d65760405162461bcd60e51b815260206004820152601c60248201527f556e6c6f636b2074696d65206e6f742072656163686564207965742e00000000604482015260640161038a565b6001600160a01b03821660008181526001830160205260408082208054929055517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810182905290919063a9059cbb906044016020604051808303816000875af1158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190610e64565b50604080516001600160a01b03851681526020810183905233917f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398910160405180910390a2505050565b600154341015610b125760405162461bcd60e51b815260206004820152601560248201527f5265717569726564207072696365206973206c6f770000000000000000000000604482015260640161038a565b6001600160a01b03808216600081815260036020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169094178455938816825260018301905291909120805415610b9f5784816000016000828254610b819190610e86565b90915550506002810154841115610b9a57600281018490555b610c1f565b604080516060810182528681526001600160a01b0388811660208084018281528486018a8152898516600090815260038452878120948152600194850190935295909120935184555190830180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169190921617905590516002909101555b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152306024830152604482018790528716906323b872dd906064016020604051808303816000875af1158015610c8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb19190610e64565b50604080516001600160a01b03888116825260208201889052918101869052908416907f798405fcfe35651392d912beb1dfab78676446555cb469e46bc055948a9793c49060600160405180910390a2505050505050565b80356001600160a01b0381168114610d2057600080fd5b919050565b600060208284031215610d3757600080fd5b610d4082610d09565b9392505050565b600060208284031215610d5957600080fd5b5035919050565b60008060008060808587031215610d7657600080fd5b610d7f85610d09565b93506020850135925060408501359150610d9b60608601610d09565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082610e0b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610e4857610e48610da6565b500290565b600082821015610e5f57610e5f610da6565b500390565b600060208284031215610e7657600080fd5b81518015158114610d4057600080fd5b60008219821115610e9957610e99610da6565b50019056fea264697066735822122067052df623c5feed30fcc79084bd6a77493c95afa43b7ad81a969fe9b922572a64736f6c634300080d00330000000000000000000000008df97eab2651e87a8a4080008ddabf6824c9f672000000000000000000000000000000000000000000000000002386f26fc10000

Deployed ByteCode

0x6080604052600436106100dd5760003560e01c80634e92afc81161007f5780636ad8809b116100595780636ad8809b146102a15780638da5cb5b146102b4578063a035b1fe146102d4578063fcea7d37146102ea57600080fd5b80634e92afc8146102175780634f5539c01461026157806351cff8d91461028157600080fd5b806318a5bbdc116100bb57806318a5bbdc14610144578063272a5c47146101975780632c84d560146101bb57806343e2e504146101d057600080fd5b80630949083b146100e25780631444cf3914610104578063167d3e9c14610124575b600080fd5b3480156100ee57600080fd5b506101026100fd366004610d25565b6102fd565b005b34801561011057600080fd5b5061010261011f366004610d47565b61058c565b34801561013057600080fd5b5061010261013f366004610d25565b610648565b34801561015057600080fd5b5061017a61015f366004610d25565b6003602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a357600080fd5b506101ad60025481565b60405190815260200161018e565b3480156101c757600080fd5b5061010261072e565b3480156101dc57600080fd5b506101ad6101eb366004610d25565b3360009081526003602090815260408083206001600160a01b0394909416835260019093019052205490565b34801561022357600080fd5b506101ad610232366004610d25565b3360009081526003602090815260408083206001600160a01b0394909416835260019093019052206002015490565b34801561026d57600080fd5b5061010261027c366004610d47565b610824565b34801561028d57600080fd5b5061010261029c366004610d25565b6108d9565b3480156102ad57600080fd5b50426101ad565b3480156102c057600080fd5b5060005461017a906001600160a01b031681565b3480156102e057600080fd5b506101ad60015481565b6101026102f8366004610d60565b610ac0565b336000818152600360205260409020805490916001600160a01b03909116146103935760405162461bcd60e51b815260206004820152602260248201527f4f6e6c7920617661696c61626c6520746f2074686520746f6b656e206f776e6560448201527f722e00000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6002546001600160a01b03831660009081526001830160205260408120549091906103c090606490610dd5565b6103ca9190610e10565b6001600160a01b0384166000908152600184016020526040812054919250906103f4908390610e4d565b6001600160a01b038516600081815260018601602052604080822091909155517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018390529192509063a9059cbb906044016020604051808303816000875af1158015610470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104949190610e64565b506000546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b039182166004820152602481018490529085169063a9059cbb906044016020604051808303816000875af1158015610501573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105259190610e64565b506001600160a01b03841660008181526001850160209081526040918290206002015482519384529083018490529082015233907f4ac88631be4f499653ed7b66b6f8e58dfc443de552029ad793891daf8ffc5ae79060600160405180910390a250505050565b6000546001600160a01b0316331461060c5760405162461bcd60e51b815260206004820152602560248201527f4f6e6c7920617661696c61626c6520746f2074686520636f6e7472616374206f60448201527f776e65722e000000000000000000000000000000000000000000000000000000606482015260840161038a565b60028190556040518181527fedcd245976eea9fd65115c661166bb4c47dee4016fecd9c8793899e6f27492cd906020015b60405180910390a150565b6000546001600160a01b031633146106c85760405162461bcd60e51b815260206004820152602560248201527f4f6e6c7920617661696c61626c6520746f2074686520636f6e7472616374206f60448201527f776e65722e000000000000000000000000000000000000000000000000000000606482015260840161038a565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f38c6b687fdabf6d647e4a6206aeb599852214abb9a8ef2468862b6dea3fd50949060200161063d565b6000546001600160a01b031633146107ae5760405162461bcd60e51b815260206004820152602560248201527f4f6e6c7920617661696c61626c6520746f2074686520636f6e7472616374206f60448201527f776e65722e000000000000000000000000000000000000000000000000000000606482015260840161038a565b6000805460405147926001600160a01b0390921691829184156108fc0291859190818181858888f193505050501580156107ec573d6000803e3d6000fd5b506040518281527fc67a6e2c9e13b320d5ce7e24743ea93ba9261320310966dd6240569493690eff9060200160405180910390a15050565b6000546001600160a01b031633146108a45760405162461bcd60e51b815260206004820152602560248201527f4f6e6c7920617661696c61626c6520746f2074686520636f6e7472616374206f60448201527f776e65722e000000000000000000000000000000000000000000000000000000606482015260840161038a565b60018190556040518181527f464ca40143674f1d1aba4360a8ed0760e2b1dbfc9f5dca703b77c01268509cf69060200161063d565b336000818152600360205260409020805490916001600160a01b039091161461096a5760405162461bcd60e51b815260206004820152602260248201527f4f6e6c7920617661696c61626c6520746f2074686520746f6b656e206f776e6560448201527f722e000000000000000000000000000000000000000000000000000000000000606482015260840161038a565b6001600160a01b038216600090815260018201602052604090206002015442116109d65760405162461bcd60e51b815260206004820152601c60248201527f556e6c6f636b2074696d65206e6f742072656163686564207965742e00000000604482015260640161038a565b6001600160a01b03821660008181526001830160205260408082208054929055517fa9059cbb0000000000000000000000000000000000000000000000000000000081523360048201526024810182905290919063a9059cbb906044016020604051808303816000875af1158015610a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a769190610e64565b50604080516001600160a01b03851681526020810183905233917f2717ead6b9200dd235aad468c9809ea400fe33ac69b5bfaa6d3e90fc922b6398910160405180910390a2505050565b600154341015610b125760405162461bcd60e51b815260206004820152601560248201527f5265717569726564207072696365206973206c6f770000000000000000000000604482015260640161038a565b6001600160a01b03808216600081815260036020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169094178455938816825260018301905291909120805415610b9f5784816000016000828254610b819190610e86565b90915550506002810154841115610b9a57600281018490555b610c1f565b604080516060810182528681526001600160a01b0388811660208084018281528486018a8152898516600090815260038452878120948152600194850190935295909120935184555190830180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169190921617905590516002909101555b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152306024830152604482018790528716906323b872dd906064016020604051808303816000875af1158015610c8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb19190610e64565b50604080516001600160a01b03888116825260208201889052918101869052908416907f798405fcfe35651392d912beb1dfab78676446555cb469e46bc055948a9793c49060600160405180910390a2505050505050565b80356001600160a01b0381168114610d2057600080fd5b919050565b600060208284031215610d3757600080fd5b610d4082610d09565b9392505050565b600060208284031215610d5957600080fd5b5035919050565b60008060008060808587031215610d7657600080fd5b610d7f85610d09565b93506020850135925060408501359150610d9b60608601610d09565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082610e0b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610e4857610e48610da6565b500290565b600082821015610e5f57610e5f610da6565b500390565b600060208284031215610e7657600080fd5b81518015158114610d4057600080fd5b60008219821115610e9957610e99610da6565b50019056fea264697066735822122067052df623c5feed30fcc79084bd6a77493c95afa43b7ad81a969fe9b922572a64736f6c634300080d0033