false
false
0

Contract Address Details

0x385C32d00cD8FF896eCd7Ca3335bb30f391a3057

Contract Name
DepositContract
Creator
0x1f2aaf–d2497e at 0x1a511b–1c81b2
Balance
55,066,624 FTN ( )
Tokens
Fetching tokens...
Transactions
4,103 Transactions
Transfers
0 Transfers
Gas Used
246,903,195
Last Balance Update
3587073
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
DepositContract




Optimization enabled
true
Compiler version
v0.8.16+commit.07a7930e




Optimization runs
200
EVM Version
london




Verified at
2024-05-20T14:15:49.150158Z

Contract source code

// ┏━━━┓━┏┓━━━━━━━━━┏━━━┓━━━━━━━━━━━━━━━━━━━┏┓━━━━━┏━━━┓━━━━━━━━━┏┓━━━━━━━━━━━━━━┏┓━
// ┃┏━━┛┏┛┗┓━━━━━━━━┗┓┏┓┃━━━━━━━━━━━━━━━━━━┏┛┗┓━━━━┃┏━┓┃━━━━━━━━┏┛┗┓━━━━━━━━━━━━┏┛┗┓
// ┃┗━━┓┗┓┏┛┏━┓━━━━━━┃┃┃┃┏━━┓┏━━┓┏━━┓┏━━┓┏┓┗┓┏┛━━━━┃┃━┗┛┏━━┓┏━┓━┗┓┏┛┏━┓┏━━┓━┏━━┓┗┓┏┛
// ┃┏━━┛━┃┃━┃┏┓┓━━━━━┃┃┃┃┃┏┓┃┃┏┓┃┃┏┓┃┃━━┫┣┫━┃┃━━━━━┃┃━┏┓┃┏┓┃┃┏┓┓━┃┃━┃┏┛┗━┓┃━┃┏━┛━┃┃━
// ┃┃━━━━┃┗┓┃┃┃┃━━━━┏┛┗┛┃┃┃━┫┃┗┛┃┃┗┛┃┣━━┃┃┃━┃┗┓━━━━┃┗━┛┃┃┗┛┃┃┃┃┃━┃┗┓┃┃━┃┗┛┗┓┃┗━┓━┃┗┓
// ┗┛━━━━┗━┛┗┛┗┛━━━━┗━━━┛┗━━┛┃┏━┛┗━━┛┗━━┛┗┛━┗━┛━━━━┗━━━┛┗━━┛┗┛┗┛━┗━┛┗┛━┗━━━┛┗━━┛━┗━┛
// ━━━━━━━━━━━━━━━━━━━━━━━━━━┃┃━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// ━━━━━━━━━━━━━━━━━━━━━━━━━━┗┛━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

// SPDX-License-Identifier: CC0-1.0

pragma solidity ^0.8.16;


// Based on official specification in https://eips.ethereum.org/EIPS/eip-165
interface ERC165 {
    /// @notice Query if a contract implements an interface
    /// @param interfaceId The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceId` and `interfaceId` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceId) external pure returns (bool);
}

/// @notice This is the FastexChain(Bahamut) deposit contract interface.
interface IDepositContract {

    /// @notice A processed deposit event.
    event DepositEvent(
        bytes pubkey,
        bytes withdrawal_credentials,
        bytes contract_address,
        bytes amount,
        bytes signature,
        bytes index
    );

    /** 
     *  @notice Submit a DepositData object.
     *  @param pubkey A BLS12-381 public key.
     *  @param withdrawal_credentials Commitment to a public key for withdrawals.
     *  @param contract_address Address of the smart contract that a associated with this deposit.
     *  @param signature A BLS12-381 signature.
     *  @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.
     */
    function deposit(
        bytes calldata pubkey,
        bytes calldata withdrawal_credentials,
        bytes calldata contract_address,
        bytes calldata signature,
        bytes32 deposit_data_root
    ) external payable;

    /** 
     *  @notice Changes contract ownership
     *  @param contract_address Address of the smart contract which ownership need to transfer
     *  @param new_owner_address New owner address
     */
    function transfer_contract_ownership(address contract_address, address new_owner_address) external;

    /**
     * @notice Query the owner of the given contract
     * @return The owner of the contract
     */
    function get_contract_owner(address contract_address) external view returns (address);

    /**
     * @notice Query the current deposit root hash.
     * @return The deposit root hash.
     */
    function get_deposit_root() external view returns (bytes32);

    /**
     * @notice Query the current deposit count.
     * @return The deposit count encoded as a little endian 64-bit number.
     */
    function get_deposit_count() external view returns (bytes memory);
}

/// @notice This is the FastexChain(Bahamut) deposit contract interface.
contract DepositContract is IDepositContract, ERC165 {

    uint256 private constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;
    // NOTE: this also ensures `deposit_count` will fit into 64-bits
    uint256 private constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;

    bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] private branch;
    uint256 private deposit_count;

    bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] private zero_hashes;

    address private deployer_getter = 0x1000000000000000000000000000000000000002;
    mapping (address => address) private contract_owners;

    constructor() {
        // Compute hashes in empty sparse Merkle tree
        for (uint256 height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++) {
            zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));
        }
    }

    function get_deposit_root() override external view returns (bytes32) {
        bytes32 node;
        uint256 size = deposit_count;
        for (uint256 height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {
            if ((size & 1) == 1)
                node = sha256(abi.encodePacked(branch[height], node));
            else
                node = sha256(abi.encodePacked(node, zero_hashes[height]));
            size /= 2;
        }
        return sha256(abi.encodePacked(
            node,
            _to_little_endian_64(uint64(deposit_count)),
            bytes24(0)
        ));
    }

    function get_deposit_count() override external view returns (bytes memory) {
        return _to_little_endian_64(uint64(deposit_count));
    }

    function transfer_contract_ownership(address contract_address, address new_owner_address) override external {

        require(address(0x0) != contract_address, 'DepositContract: Contract address cannot be null');
        require(address(0x0) != new_owner_address, 'DepositContract: Owner address cannot be null');
        require(msg.sender == get_contract_owner(contract_address), 'DepositContract: Only owner can transfer ownership');
        contract_owners[contract_address] = new_owner_address;
    }

    function deposit(
        bytes calldata pubkey,
        bytes calldata withdrawal_credentials,
        bytes calldata contract_address,
        bytes calldata signature,
        bytes32 deposit_data_root
    ) override external payable {

        // Extended ABI length checks since dynamic types are used.
        require(pubkey.length == 48, "DepositContract: invalid pubkey length");
        require(withdrawal_credentials.length == 32, "DepositContract: invalid withdrawal_credentials length");
        require(contract_address.length == 20, "DepositContract: invalid withdrawal_credentials length");
        require(signature.length == 96, "DepositContract: invalid signature length");

        // Check deposit amount
        address c_address = _to_address(contract_address);
        if (address(0x0) != c_address) {
            require(get_contract_owner(c_address) == msg.sender, "DepositContract: sender should be owner of contract");
        }
        require(msg.value >= 256 ether, "DepositContract: deposit value too low");
        require(msg.value % 1 gwei == 0, "DepositContract: deposit value not multiple of gwei");
        uint256 deposit_amount = msg.value / 1 gwei;
        require(deposit_amount <= type(uint64).max, "DepositContract: deposit value too high");

        // Emit `DepositEvent` log
        bytes memory amount = _to_little_endian_64(uint64(deposit_amount));
        emit DepositEvent(
            pubkey,
            withdrawal_credentials,
            contract_address,
            amount,
            signature,
            _to_little_endian_64(uint64(deposit_count))
        );

        // Compute deposit data root (`DepositData` hash tree root)
        bytes32 root = _calculate_root(
            pubkey,
            withdrawal_credentials,
            contract_address,
            amount,
            signature);

        // Verify computed and expected deposit data roots match
        require(root == deposit_data_root, "DepositContract: reconstructed DepositData does not match supplied deposit_data_root");

        // Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)
        require(deposit_count < MAX_DEPOSIT_COUNT, "DepositContract: merkle tree full");

        // Add deposit data root to Merkle tree (update a single `branch` node)
        deposit_count += 1;

        _update_branch(root);
    }

    function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {
        return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;
    }

    function get_contract_owner(address contract_address) override public view returns (address) {

        if (address(0x0) != contract_owners[contract_address]) {
            return contract_owners[contract_address];
        }

        (bool success, bytes memory deployer) = deployer_getter.staticcall(abi.encodePacked(contract_address));
        require(success, 'DepositContract: Cannot get deployer');
        return _to_address(deployer);
    }

    /// Helper member functions

    function _to_address(bytes memory addr) private pure returns (address ret_address) {

        assembly {
            ret_address := mload(add(addr, 20))
        }
    }

    function _to_little_endian_64(uint64 value) private pure returns (bytes memory ret) {
        ret = new bytes(8);
        bytes8 bytesValue = bytes8(value);
        // Byteswapping during copying to bytes.
        ret[0] = bytesValue[7];
        ret[1] = bytesValue[6];
        ret[2] = bytesValue[5];
        ret[3] = bytesValue[4];
        ret[4] = bytesValue[3];
        ret[5] = bytesValue[2];
        ret[6] = bytesValue[1];
        ret[7] = bytesValue[0];
    }

    function _calculate_root(
        bytes calldata pubkey,
        bytes calldata withdrawal_credentials,
        bytes calldata contract_address,
        bytes memory amount,
        bytes calldata signature)
            pure
            private
            returns(bytes32) {

        bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));
        bytes32 signature_root = sha256(abi.encodePacked(
            sha256(abi.encodePacked(signature[:64])),
            sha256(abi.encodePacked(signature[64:], bytes32(0)))
        ));

        bytes32 node1 = sha256(abi.encodePacked(pubkey_root, withdrawal_credentials));
        bytes32 node2 = sha256(abi.encodePacked(contract_address, bytes12(0), amount, bytes24(0)));
        bytes32 node3 = sha256(abi.encodePacked(signature_root, bytes32(0)));
        bytes32 node4 = sha256(abi.encodePacked(bytes32(0), bytes32(0)));

        bytes32 node12 = sha256(abi.encodePacked(node1, node2));
        bytes32 node34 = sha256(abi.encodePacked(node3, node4));

        return sha256(abi.encodePacked(node12, node34));
    }

    function _update_branch(bytes32 root) private {

        uint256 size = deposit_count;
        for (uint256 height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {
            if ((size & 1) == 1) {
                branch[height] = root;
                return;
            }
            root = sha256(abi.encodePacked(branch[height], root));
            size /= 2;
        }
        // As the loop should always end prematurely with the `return` statement,
        // this code should be unreachable. We assert `false` just to be safe.
        assert(false);
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"DepositEvent","inputs":[{"type":"bytes","name":"pubkey","internalType":"bytes","indexed":false},{"type":"bytes","name":"withdrawal_credentials","internalType":"bytes","indexed":false},{"type":"bytes","name":"contract_address","internalType":"bytes","indexed":false},{"type":"bytes","name":"amount","internalType":"bytes","indexed":false},{"type":"bytes","name":"signature","internalType":"bytes","indexed":false},{"type":"bytes","name":"index","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"payable","outputs":[],"name":"deposit","inputs":[{"type":"bytes","name":"pubkey","internalType":"bytes"},{"type":"bytes","name":"withdrawal_credentials","internalType":"bytes"},{"type":"bytes","name":"contract_address","internalType":"bytes"},{"type":"bytes","name":"signature","internalType":"bytes"},{"type":"bytes32","name":"deposit_data_root","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"get_contract_owner","inputs":[{"type":"address","name":"contract_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"get_deposit_count","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"get_deposit_root","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transfer_contract_ownership","inputs":[{"type":"address","name":"contract_address","internalType":"address"},{"type":"address","name":"new_owner_address","internalType":"address"}]}]
              

Contract Creation Code

Verify & Publish
0x6080604052604180546001600160a01b0319167310000000000000000000000000000000000000021790553480156200003757600080fd5b5060005b62000049600160206200014a565b8110156200012d5760026021826020811062000069576200006962000166565b01546021836020811062000081576200008162000166565b015460408051602081019390935282015260600160408051601f1981840301815290829052620000b1916200017c565b602060405180830381855afa158015620000cf573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190620000f49190620001ad565b602162000103836001620001c7565b6020811062000116576200011662000166565b0155806200012481620001dd565b9150506200003b565b50620001f9565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000160576200016062000134565b92915050565b634e487b7160e01b600052603260045260246000fd5b6000825160005b818110156200019f576020818601810151858301520162000183565b506000920191825250919050565b600060208284031215620001c057600080fd5b5051919050565b8082018082111562000160576200016062000134565b600060018201620001f257620001f262000134565b5060010190565b61193e80620002096000396000f3fe6080604052600436106100555760003560e01c806301ffc9a71461005a57806336a8d2301461008f578063621fd130146100b1578063847dbe4d146100d3578063c1da06e21461010b578063c5f2892f1461011e575b600080fd5b34801561006657600080fd5b5061007a6100753660046112ea565b610141565b60405190151581526020015b60405180910390f35b34801561009b57600080fd5b506100af6100aa366004611337565b610178565b005b3480156100bd57600080fd5b506100c6610310565b60405161008691906113ba565b3480156100df57600080fd5b506100f36100ee3660046113cd565b610322565b6040516001600160a01b039091168152602001610086565b6100af610119366004611431565b610459565b34801561012a57600080fd5b5061013361092b565b604051908152602001610086565b60006001600160e01b031982166301ffc9a760e01b148061017257506001600160e01b031982166301a9c46560e71b145b92915050565b6001600160a01b0382166000036101ef5760405162461bcd60e51b815260206004820152603060248201527f4465706f736974436f6e74726163743a20436f6e74726163742061646472657360448201526f1cc818d85b9b9bdd081899481b9d5b1b60821b60648201526084015b60405180910390fd5b6001600160a01b03811660000361025e5760405162461bcd60e51b815260206004820152602d60248201527f4465706f736974436f6e74726163743a204f776e65722061646472657373206360448201526c185b9b9bdd081899481b9d5b1b609a1b60648201526084016101e6565b61026782610322565b6001600160a01b0316336001600160a01b0316146102e25760405162461bcd60e51b815260206004820152603260248201527f4465706f736974436f6e74726163743a204f6e6c79206f776e65722063616e2060448201527107472616e73666572206f776e6572736869760741b60648201526084016101e6565b6001600160a01b03918216600090815260426020526040902080546001600160a01b03191691909216179055565b606061031d602054610aff565b905090565b6001600160a01b038082166000908152604260205260408120549091161561036357506001600160a01b039081166000908152604260205260409020541690565b6041546040516bffffffffffffffffffffffff19606085901b16602082015260009182916001600160a01b039091169060340160408051601f19818403018152908290526103b0916114fd565b600060405180830381855afa9150503d80600081146103eb576040519150601f19603f3d011682016040523d82523d6000602084013e6103f0565b606091505b50915091508161044e5760405162461bcd60e51b8152602060048201526024808201527f4465706f736974436f6e74726163743a2043616e6e6f7420676574206465706c60448201526337bcb2b960e11b60648201526084016101e6565b601401519392505050565b603088146104b85760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084016101e6565b602086146104d85760405162461bcd60e51b81526004016101e690611519565b601484146104f85760405162461bcd60e51b81526004016101e690611519565b6060821461055a5760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b60648201526084016101e6565b600061059b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cb392505050565b90506001600160a01b0381161561062857336105b682610322565b6001600160a01b0316146106285760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a2073656e6465722073686f756c64206260448201527219481bdddb995c881bd98818dbdb9d1c9858dd606a1b60648201526084016101e6565b680de0b6b3a7640000003410156106905760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b60648201526084016101e6565b61069e633b9aca0034611585565b156107075760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b60648201526084016101e6565b6000610717633b9aca00346115af565b905067ffffffffffffffff8111156107815760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b60648201526084016101e6565b600061078c82610aff565b90507f9690c6325860650852f0f0bd0e7d47145a3d0c2c5c92cba852bad61c02928b098c8c8c8c8c8c878d8d6107c3602054610aff565b6040516107d99a999897969594939291906115ec565b60405180910390a160006107f48d8d8d8d8d8d888e8e610cba565b90508481146108885760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a4016101e6565b60016108966020600261175a565b6108a09190611766565b602054106108fa5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b60648201526084016101e6565b60016020600082825461090d9190611779565b9091555061091c905081611202565b50505050505050505050505050565b6020546000908190815b6020811015610a7b57816001166001036109d55760026000826020811061095e5761095e61178c565b0154604080516020810192909252810185905260600160408051601f198184030181529082905261098e916114fd565b602060405180830381855afa1580156109ab573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109ce91906117a2565b9250610a5c565b600283602183602081106109eb576109eb61178c565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a19916114fd565b602060405180830381855afa158015610a36573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610a5991906117a2565b92505b610a676002836115af565b915080610a73816117bb565b915050610935565b50600282610a8a602054610aff565b604051610a9e9291906000906020016117d4565b60408051601f1981840301815290829052610ab8916114fd565b602060405180830381855afa158015610ad5573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610af891906117a2565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b82600081518110610b3f57610b3f61178c565b60200101906001600160f81b031916908160001a9053508060061a60f81b82600181518110610b7057610b7061178c565b60200101906001600160f81b031916908160001a9053508060051a60f81b82600281518110610ba157610ba161178c565b60200101906001600160f81b031916908160001a9053508060041a60f81b82600381518110610bd257610bd261178c565b60200101906001600160f81b031916908160001a9053508060031a60f81b82600481518110610c0357610c0361178c565b60200101906001600160f81b031916908160001a9053508060021a60f81b82600581518110610c3457610c3461178c565b60200101906001600160f81b031916908160001a9053508060011a60f81b82600681518110610c6557610c6561178c565b60200101906001600160f81b031916908160001a9053508060001a60f81b82600781518110610c9657610c9661178c565b60200101906001600160f81b031916908160001a90535050919050565b6014015190565b60008060028b8b600060801b604051602001610cd893929190611810565b60408051601f1981840301815290829052610cf2916114fd565b602060405180830381855afa158015610d0f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d3291906117a2565b90506000600280610d46604084888a611837565b604051602001610d57929190611861565b60408051601f1981840301815290829052610d71916114fd565b602060405180830381855afa158015610d8e573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610db191906117a2565b6002610dc0876040818b611837565b604051610dd4929190600090602001611871565b60408051601f1981840301815290829052610dee916114fd565b602060405180830381855afa158015610e0b573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e2e91906117a2565b60408051602081019390935282015260600160408051601f1981840301815290829052610e5a916114fd565b602060405180830381855afa158015610e77573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e9a91906117a2565b905060006002838c8c604051602001610eb593929190611883565b60408051601f1981840301815290829052610ecf916114fd565b602060405180830381855afa158015610eec573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610f0f91906117a2565b604051909150600090600290610f31908c908c9085908d90829060200161189d565b60408051601f1981840301815290829052610f4b916114fd565b602060405180830381855afa158015610f68573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610f8b91906117a2565b604080516020810186905260009181018290529192509060029060600160408051601f1981840301815290829052610fc2916114fd565b602060405180830381855afa158015610fdf573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061100291906117a2565b604080516000602082018190529181018290529192509060029060600160408051601f1981840301815290829052611039916114fd565b602060405180830381855afa158015611056573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061107991906117a2565b905060006002858560405160200161109b929190918252602082015260400190565b60408051601f19818403018152908290526110b5916114fd565b602060405180830381855afa1580156110d2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906110f591906117a2565b9050600060028484604051602001611117929190918252602082015260400190565b60408051601f1981840301815290829052611131916114fd565b602060405180830381855afa15801561114e573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061117191906117a2565b905060028282604051602001611191929190918252602082015260400190565b60408051601f19818403018152908290526111ab916114fd565b602060405180830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906111eb91906117a2565b985050505050505050509998505050505050505050565b60205460005b60208110156112dd57816001166001036112375782600082602081106112305761123061178c565b0155505050565b60026000826020811061124c5761124c61178c565b0154604080516020810192909252810185905260600160408051601f198184030181529082905261127c916114fd565b602060405180830381855afa158015611299573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906112bc91906117a2565b92506112c96002836115af565b9150806112d5816117bb565b915050611208565b506112e66118f2565b5050565b6000602082840312156112fc57600080fd5b81356001600160e01b03198116811461131457600080fd5b9392505050565b80356001600160a01b038116811461133257600080fd5b919050565b6000806040838503121561134a57600080fd5b6113538361131b565b91506113616020840161131b565b90509250929050565b60005b8381101561138557818101518382015260200161136d565b50506000910152565b600081518084526113a681602086016020860161136a565b601f01601f19169290920160200192915050565b602081526000611314602083018461138e565b6000602082840312156113df57600080fd5b6113148261131b565b60008083601f8401126113fa57600080fd5b50813567ffffffffffffffff81111561141257600080fd5b60208301915083602082850101111561142a57600080fd5b9250929050565b600080600080600080600080600060a08a8c03121561144f57600080fd5b893567ffffffffffffffff8082111561146757600080fd5b6114738d838e016113e8565b909b50995060208c013591508082111561148c57600080fd5b6114988d838e016113e8565b909950975060408c01359150808211156114b157600080fd5b6114bd8d838e016113e8565b909750955060608c01359150808211156114d657600080fd5b506114e38c828d016113e8565b9a9d999c50979a9699959894979660800135949350505050565b6000825161150f81846020870161136a565b9190910192915050565b60208082526036908201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616040820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826115945761159461156f565b500690565b634e487b7160e01b600052601160045260246000fd5b6000826115be576115be61156f565b500490565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60c08152600061160060c083018c8e6115c3565b8281036020840152611613818b8d6115c3565b9050828103604084015261162881898b6115c3565b9050828103606084015261163c818861138e565b905082810360808401526116518186886115c3565b905082810360a0840152611665818561138e565b9d9c50505050505050505050505050565b600181815b808511156116b157816000190482111561169757611697611599565b808516156116a457918102915b93841c939080029061167b565b509250929050565b6000826116c857506001610172565b816116d557506000610172565b81600181146116eb57600281146116f557611711565b6001915050610172565b60ff84111561170657611706611599565b50506001821b610172565b5060208310610133831016604e8410600b8410161715611734575081810a610172565b61173e8383611676565b806000190482111561175257611752611599565b029392505050565b600061131483836116b9565b8181038181111561017257610172611599565b8082018082111561017257610172611599565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156117b457600080fd5b5051919050565b6000600182016117cd576117cd611599565b5060010190565b838152600083516117ec81602085016020880161136a565b67ffffffffffffffff19939093169190920160208101919091526038019392505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b6000808585111561184757600080fd5b8386111561185457600080fd5b5050820193919092039150565b8183823760009101908152919050565b82848237909101908152602001919050565b838152818360208301376000910160200190815292915050565b8486823760008582016bffffffffffffffffffffffff60a01b8616815284516118cd81600c84016020890161136a565b67ffffffffffffffff19949094169301600c8101939093525050602401949350505050565b634e487b7160e01b600052600160045260246000fdfea264697066735822122052366f8a8c8d63af60f71e74b52b95a317eaf794d2f525ea4aa959fca93ccc0a64736f6c63430008100033

Deployed ByteCode

0x6080604052600436106100555760003560e01c806301ffc9a71461005a57806336a8d2301461008f578063621fd130146100b1578063847dbe4d146100d3578063c1da06e21461010b578063c5f2892f1461011e575b600080fd5b34801561006657600080fd5b5061007a6100753660046112ea565b610141565b60405190151581526020015b60405180910390f35b34801561009b57600080fd5b506100af6100aa366004611337565b610178565b005b3480156100bd57600080fd5b506100c6610310565b60405161008691906113ba565b3480156100df57600080fd5b506100f36100ee3660046113cd565b610322565b6040516001600160a01b039091168152602001610086565b6100af610119366004611431565b610459565b34801561012a57600080fd5b5061013361092b565b604051908152602001610086565b60006001600160e01b031982166301ffc9a760e01b148061017257506001600160e01b031982166301a9c46560e71b145b92915050565b6001600160a01b0382166000036101ef5760405162461bcd60e51b815260206004820152603060248201527f4465706f736974436f6e74726163743a20436f6e74726163742061646472657360448201526f1cc818d85b9b9bdd081899481b9d5b1b60821b60648201526084015b60405180910390fd5b6001600160a01b03811660000361025e5760405162461bcd60e51b815260206004820152602d60248201527f4465706f736974436f6e74726163743a204f776e65722061646472657373206360448201526c185b9b9bdd081899481b9d5b1b609a1b60648201526084016101e6565b61026782610322565b6001600160a01b0316336001600160a01b0316146102e25760405162461bcd60e51b815260206004820152603260248201527f4465706f736974436f6e74726163743a204f6e6c79206f776e65722063616e2060448201527107472616e73666572206f776e6572736869760741b60648201526084016101e6565b6001600160a01b03918216600090815260426020526040902080546001600160a01b03191691909216179055565b606061031d602054610aff565b905090565b6001600160a01b038082166000908152604260205260408120549091161561036357506001600160a01b039081166000908152604260205260409020541690565b6041546040516bffffffffffffffffffffffff19606085901b16602082015260009182916001600160a01b039091169060340160408051601f19818403018152908290526103b0916114fd565b600060405180830381855afa9150503d80600081146103eb576040519150601f19603f3d011682016040523d82523d6000602084013e6103f0565b606091505b50915091508161044e5760405162461bcd60e51b8152602060048201526024808201527f4465706f736974436f6e74726163743a2043616e6e6f7420676574206465706c60448201526337bcb2b960e11b60648201526084016101e6565b601401519392505050565b603088146104b85760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084016101e6565b602086146104d85760405162461bcd60e51b81526004016101e690611519565b601484146104f85760405162461bcd60e51b81526004016101e690611519565b6060821461055a5760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b60648201526084016101e6565b600061059b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cb392505050565b90506001600160a01b0381161561062857336105b682610322565b6001600160a01b0316146106285760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a2073656e6465722073686f756c64206260448201527219481bdddb995c881bd98818dbdb9d1c9858dd606a1b60648201526084016101e6565b680de0b6b3a7640000003410156106905760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b60648201526084016101e6565b61069e633b9aca0034611585565b156107075760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b60648201526084016101e6565b6000610717633b9aca00346115af565b905067ffffffffffffffff8111156107815760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b60648201526084016101e6565b600061078c82610aff565b90507f9690c6325860650852f0f0bd0e7d47145a3d0c2c5c92cba852bad61c02928b098c8c8c8c8c8c878d8d6107c3602054610aff565b6040516107d99a999897969594939291906115ec565b60405180910390a160006107f48d8d8d8d8d8d888e8e610cba565b90508481146108885760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a4016101e6565b60016108966020600261175a565b6108a09190611766565b602054106108fa5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b60648201526084016101e6565b60016020600082825461090d9190611779565b9091555061091c905081611202565b50505050505050505050505050565b6020546000908190815b6020811015610a7b57816001166001036109d55760026000826020811061095e5761095e61178c565b0154604080516020810192909252810185905260600160408051601f198184030181529082905261098e916114fd565b602060405180830381855afa1580156109ab573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109ce91906117a2565b9250610a5c565b600283602183602081106109eb576109eb61178c565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a19916114fd565b602060405180830381855afa158015610a36573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610a5991906117a2565b92505b610a676002836115af565b915080610a73816117bb565b915050610935565b50600282610a8a602054610aff565b604051610a9e9291906000906020016117d4565b60408051601f1981840301815290829052610ab8916114fd565b602060405180830381855afa158015610ad5573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610af891906117a2565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b82600081518110610b3f57610b3f61178c565b60200101906001600160f81b031916908160001a9053508060061a60f81b82600181518110610b7057610b7061178c565b60200101906001600160f81b031916908160001a9053508060051a60f81b82600281518110610ba157610ba161178c565b60200101906001600160f81b031916908160001a9053508060041a60f81b82600381518110610bd257610bd261178c565b60200101906001600160f81b031916908160001a9053508060031a60f81b82600481518110610c0357610c0361178c565b60200101906001600160f81b031916908160001a9053508060021a60f81b82600581518110610c3457610c3461178c565b60200101906001600160f81b031916908160001a9053508060011a60f81b82600681518110610c6557610c6561178c565b60200101906001600160f81b031916908160001a9053508060001a60f81b82600781518110610c9657610c9661178c565b60200101906001600160f81b031916908160001a90535050919050565b6014015190565b60008060028b8b600060801b604051602001610cd893929190611810565b60408051601f1981840301815290829052610cf2916114fd565b602060405180830381855afa158015610d0f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d3291906117a2565b90506000600280610d46604084888a611837565b604051602001610d57929190611861565b60408051601f1981840301815290829052610d71916114fd565b602060405180830381855afa158015610d8e573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610db191906117a2565b6002610dc0876040818b611837565b604051610dd4929190600090602001611871565b60408051601f1981840301815290829052610dee916114fd565b602060405180830381855afa158015610e0b573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e2e91906117a2565b60408051602081019390935282015260600160408051601f1981840301815290829052610e5a916114fd565b602060405180830381855afa158015610e77573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e9a91906117a2565b905060006002838c8c604051602001610eb593929190611883565b60408051601f1981840301815290829052610ecf916114fd565b602060405180830381855afa158015610eec573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610f0f91906117a2565b604051909150600090600290610f31908c908c9085908d90829060200161189d565b60408051601f1981840301815290829052610f4b916114fd565b602060405180830381855afa158015610f68573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610f8b91906117a2565b604080516020810186905260009181018290529192509060029060600160408051601f1981840301815290829052610fc2916114fd565b602060405180830381855afa158015610fdf573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061100291906117a2565b604080516000602082018190529181018290529192509060029060600160408051601f1981840301815290829052611039916114fd565b602060405180830381855afa158015611056573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061107991906117a2565b905060006002858560405160200161109b929190918252602082015260400190565b60408051601f19818403018152908290526110b5916114fd565b602060405180830381855afa1580156110d2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906110f591906117a2565b9050600060028484604051602001611117929190918252602082015260400190565b60408051601f1981840301815290829052611131916114fd565b602060405180830381855afa15801561114e573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061117191906117a2565b905060028282604051602001611191929190918252602082015260400190565b60408051601f19818403018152908290526111ab916114fd565b602060405180830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906111eb91906117a2565b985050505050505050509998505050505050505050565b60205460005b60208110156112dd57816001166001036112375782600082602081106112305761123061178c565b0155505050565b60026000826020811061124c5761124c61178c565b0154604080516020810192909252810185905260600160408051601f198184030181529082905261127c916114fd565b602060405180830381855afa158015611299573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906112bc91906117a2565b92506112c96002836115af565b9150806112d5816117bb565b915050611208565b506112e66118f2565b5050565b6000602082840312156112fc57600080fd5b81356001600160e01b03198116811461131457600080fd5b9392505050565b80356001600160a01b038116811461133257600080fd5b919050565b6000806040838503121561134a57600080fd5b6113538361131b565b91506113616020840161131b565b90509250929050565b60005b8381101561138557818101518382015260200161136d565b50506000910152565b600081518084526113a681602086016020860161136a565b601f01601f19169290920160200192915050565b602081526000611314602083018461138e565b6000602082840312156113df57600080fd5b6113148261131b565b60008083601f8401126113fa57600080fd5b50813567ffffffffffffffff81111561141257600080fd5b60208301915083602082850101111561142a57600080fd5b9250929050565b600080600080600080600080600060a08a8c03121561144f57600080fd5b893567ffffffffffffffff8082111561146757600080fd5b6114738d838e016113e8565b909b50995060208c013591508082111561148c57600080fd5b6114988d838e016113e8565b909950975060408c01359150808211156114b157600080fd5b6114bd8d838e016113e8565b909750955060608c01359150808211156114d657600080fd5b506114e38c828d016113e8565b9a9d999c50979a9699959894979660800135949350505050565b6000825161150f81846020870161136a565b9190910192915050565b60208082526036908201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616040820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826115945761159461156f565b500690565b634e487b7160e01b600052601160045260246000fd5b6000826115be576115be61156f565b500490565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60c08152600061160060c083018c8e6115c3565b8281036020840152611613818b8d6115c3565b9050828103604084015261162881898b6115c3565b9050828103606084015261163c818861138e565b905082810360808401526116518186886115c3565b905082810360a0840152611665818561138e565b9d9c50505050505050505050505050565b600181815b808511156116b157816000190482111561169757611697611599565b808516156116a457918102915b93841c939080029061167b565b509250929050565b6000826116c857506001610172565b816116d557506000610172565b81600181146116eb57600281146116f557611711565b6001915050610172565b60ff84111561170657611706611599565b50506001821b610172565b5060208310610133831016604e8410600b8410161715611734575081810a610172565b61173e8383611676565b806000190482111561175257611752611599565b029392505050565b600061131483836116b9565b8181038181111561017257610172611599565b8082018082111561017257610172611599565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156117b457600080fd5b5051919050565b6000600182016117cd576117cd611599565b5060010190565b838152600083516117ec81602085016020880161136a565b67ffffffffffffffff19939093169190920160208101919091526038019392505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b6000808585111561184757600080fd5b8386111561185457600080fd5b5050820193919092039150565b8183823760009101908152919050565b82848237909101908152602001919050565b838152818360208301376000910160200190815292915050565b8486823760008582016bffffffffffffffffffffffff60a01b8616815284516118cd81600c84016020890161136a565b67ffffffffffffffff19949094169301600c8101939093525050602401949350505050565b634e487b7160e01b600052600160045260246000fdfea264697066735822122052366f8a8c8d63af60f71e74b52b95a317eaf794d2f525ea4aa959fca93ccc0a64736f6c63430008100033