Contract 0xa588fa62c9722ea6824851641f3a51545d083e68 1

Txn Hash Method
Block
From
To
Value [Txn Fee]
0xdd20788edd93c4a13777e610f09a2f47189c4cad99841a28573ec01fdd2059c0Withdraw Rewards58535582022-12-04 0:43:391 hr 36 mins ago0x8ec0b455036b366ea380fa4b6fee1d8de9da6646 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.263308017753 4,864.274034354
0xd0d5ba5866e38c66e6bcca8b172d6004ee7cf4b56deaa098aa08775df9fe64bcUpdate Rewards58535532022-12-04 0:43:111 hr 36 mins ago0x8ec0b455036b366ea380fa4b6fee1d8de9da6646 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO1.654164563074 4,864.2742633
0xd0c815df605606820080b2e6ff998666d5efa96a3e8e15ec4d8bf615d9d29f8eWithdraw Rewards58517432022-12-03 21:52:314 hrs 27 mins ago0x78c6abc1d61a30e6b9a14c99886e9bb51483afcc IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.263312519218 4,864.357193084
0xaa9360ce3b8f72c82e36a7fdea418389343cc9fe649ffedaa631e2aaa70564c1Update Rewards58517392022-12-03 21:52:094 hrs 27 mins ago0x78c6abc1d61a30e6b9a14c99886e9bb51483afcc IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO3.878619673559 4,864.357373515
0xc5c4ad4a621012d3b82b907390a699e3359918e7ed4c5f89fa0831a33480409aWithdraw Rewards58507452022-12-03 20:18:296 hrs 1 min ago0x01218162519c09c60b3baff7b02f789e3bd79cee IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.2632338016890
0xcb3bcda61bd4bddc764c6121b49a8cba03ed279b4d24ec8ffdf36b22274d3124Update Rewards58507432022-12-03 20:18:176 hrs 1 min ago0x01218162519c09c60b3baff7b02f789e3bd79cee IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO2.6851929591220
0x275e7689653fc33765658d0375f4a66d03096c3787dc11f65d9e809134aecac0Withdraw Rewards58502142022-12-03 19:28:266 hrs 51 mins ago0x93384b8b4c03f827f18b5e31510401bb31dd1efa IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.2632351065190
0xdd14e1e76ba35852e3b770cef1e950dd946f3611d30f458f15b5d6adcceca4a3Update Rewards58502102022-12-03 19:28:036 hrs 51 mins ago0x93384b8b4c03f827f18b5e31510401bb31dd1efa IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO2.0282880442650
0xe040296aed8398d532d1bb445b80d699d3396b3d1ba58750871307848ec31f01Withdraw Rewards58493002022-12-03 18:02:008 hrs 17 mins ago0x2ec9dea31ca7db06fd0cf6e03c4dcfaf65f9b4a1 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.2632373715450
0xe2481b9f9742f3d7494b42b2d1b7440788950284a6b7012f699d4cfef07035b8Update Rewards58492972022-12-03 18:01:448 hrs 18 mins ago0x2ec9dea31ca7db06fd0cf6e03c4dcfaf65f9b4a1 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO3.5783136614870
0xd73070b6b0ff0024cb821f124c6997f4bec15224167e5caae1823709f4520c46Withdraw Rewards58473872022-12-03 15:00:3611 hrs 19 mins ago0xfdb48b06757e3fbd6eef27b7675c9d5eab62a9ae IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.2632420307460
0xa15aae2bf01fed33588749fe79c4bb8810af934f7d0de2cb0558b259765f39cbUpdate Rewards58473832022-12-03 15:00:1311 hrs 19 mins ago0xfdb48b06757e3fbd6eef27b7675c9d5eab62a9ae IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO2.9383357577020
0xc6378f15d6ba74cbb9050ce1a424a7ee0beeccd8c585e6236e0b40843379e27cWithdraw Rewards58470892022-12-03 14:32:1811 hrs 47 mins ago0x255bd8a226c9d5fffc99e8f82f900f982ec5bd7e IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.26332396013 4,864.568549088
0xd020266c664cfe04a796a9c1b5fc32775a84205e247d4701c859e400b5c99e3bUpdate Rewards58470862022-12-03 14:32:0111 hrs 47 mins ago0x255bd8a226c9d5fffc99e8f82f900f982ec5bd7e IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO8.56683623892 4,864.568681573
0x261ed60bcab0dc65ab167c04a806404fca60687d367b881df06fe30ac4162b5fWithdraw Rewards58457342022-12-03 12:23:3913 hrs 56 mins ago0x93dc39518c84c8c8bc17f8ae61193a0cb9e9139e IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.263327331886 4,864.630837897
0xda648c9eb2081d6cd3e477e5fc80c1a7256bea81f967afc39d4ee7ad29511178Update Rewards58457302022-12-03 12:23:1613 hrs 56 mins ago0x93dc39518c84c8c8bc17f8ae61193a0cb9e9139e IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO1.955970837949 4,864.631013602
0xeb6f68831beb2ca9c921647908a91e4e4b28e1f738ed9da058df3722925d5ee7Update Rewards58454832022-12-03 11:59:5014 hrs 20 mins ago0xc778e065350217565c047035329701fa552fc74d IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO1.4200959986580
0x3c225c6b182907df1fe31c73c68bbde8d4514bb896e94513c71bf821334fc9dbWithdraw Rewards58416582022-12-03 5:57:1920 hrs 22 mins ago0x209a5f4fdb86026afff3a4761a57a8fb14bdf700 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.2632564388560
0x58f128fa6ddb29df59bc2ad728da3cac264abdd596f9b275e94d1cd91899f437Update Rewards58416552022-12-03 5:57:0220 hrs 22 mins ago0x209a5f4fdb86026afff3a4761a57a8fb14bdf700 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO3.5496798734210
0x3924a52b6554ab13fdd0396ec54c625ec60f62d2d23ab1e516c45e4c254a1eb9Withdraw Rewards58388982022-12-03 1:35:441 day 44 mins ago0x838cf822d8af9b6dc6f4aa9e3136b2390800e240 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.2632633607280
0x1f52d81ad0134dc46daf6cc1ab25f776fda5fe02129b787c9eec9dae2060b0ebUpdate Rewards58388952022-12-03 1:35:271 day 44 mins ago0x838cf822d8af9b6dc6f4aa9e3136b2390800e240 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO9.95670617290
0x3e4ce6f2bdd29e9e1b1328e87c50372a7d5062bb13db2456c5e755c6f8f362dcWithdraw Rewards58366832022-12-02 22:05:461 day 4 hrs ago0x7e11a1860503328ee7c8332d6d08d61104ab7b12 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.263350048001 4,865.050488659
0x97293374ce10db67b7b78664ecc6326c936760fb9667e9a193b171fa62eaaf7bUpdate Rewards58366802022-12-02 22:05:291 day 4 hrs ago0x7e11a1860503328ee7c8332d6d08d61104ab7b12 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.795878495965 4,865.050619931
0x8786de2473b3e270d755e0e85556039a41f606530c7d2d6f1ae5108e48addad7Withdraw Rewards58360932022-12-02 21:09:471 day 5 hrs ago0x79d3752ce78e7224cbad0128bd1c3c5853876494 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO0.2632703182660
0x7de54ebdeea394f468cbb1ac41875aaca907a5ebffcc6c264f8f864f2b99e339Update Rewards58360902022-12-02 21:09:311 day 5 hrs ago0x79d3752ce78e7224cbad0128bd1c3c5853876494 IN  0xa588fa62c9722ea6824851641f3a51545d083e680 CRO6.3844914270850
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TrpzStake

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 12 : TrpzStake.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract TrpzStake is IERC721Receiver, AccessControl, ReentrancyGuard {
    using Counters for Counters.Counter;
    Counters.Counter public stakingId;
    bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
    uint256 lastYieldUpdate;
    uint64 public historicId;
    address public trpzToken;
    address public immutable OGAddress =
        0x51112Bf32B9a1C64716DF2e6b82e63a04Bd384Fd;

    struct stakedNFT {
        uint256 tokenId;
        address nftContract;
        address owner;
    }

    struct historicReward {
        uint256 timestamp;
        uint64 rewardId;
        uint64 reward;
        uint64 next;
    }

    mapping(uint256 => stakedNFT) public stakedNFTIds;
    mapping(address => historicReward) public historicRewardHead;
    mapping(uint64 => historicReward) public historicRewardToId;
    mapping(address => uint256[]) public ownerToIds;
    mapping(address => uint256) public ownerToRewards;
    mapping(address => uint256) public ownerToLastUpdate;
    mapping(address => bool) public whitelistedContracts;
    mapping(address => uint64) public dailyContractRewards;
    mapping(address => uint64) public OGBalance;

    constructor(address _trpzToken) {
        _setupRole(ADMIN_ROLE, msg.sender);
        trpzToken = _trpzToken;
    }

    //=========================== EXTERNAL FUNCTIONS =============== //
    /// @dev Approval for all need to be called followed by a zero address or false call
    /// Will need to provide address - tokenId for each array item
    /// Correct amount of each will be required to correctly match
    function batchDeposit(
        address[] calldata _contractAddress,
        uint256[] calldata _tokenId
    ) external {
        for (uint256 i; i < _contractAddress.length; i++) {
            IERC721(_contractAddress[i]).safeTransferFrom(
                msg.sender,
                address(this),
                _tokenId[i]
            );
        }
    }

    /// @dev Function update rewards for a user making them eligible every 24 hours
    function updateRewards() external nonReentrant {
        require(ownerToIds[msg.sender].length != 0, "No staked NFTs");
        require(
            block.timestamp - ownerToLastUpdate[msg.sender] > 1 days,
            "No rewards to claim"
        );
        uint256 rewards;
        if (ownerToLastUpdate[msg.sender] < lastYieldUpdate) {
            rewards = _updateHistoricRewards(msg.sender);
        } else {
            rewards = _updateRewards(msg.sender);
        }
        ownerToRewards[msg.sender] += rewards;
        ownerToLastUpdate[msg.sender] =
            block.timestamp -
            (ownerToLastUpdate[msg.sender] % 1 days);
    }

    /// @dev Function to let owner withdraw their rewards
    /// If we are minting then may want to remove balance check
    function withdrawRewards() external nonReentrant {
        uint256 rewards = ownerToRewards[msg.sender];
        require(rewards != 0, "No rewards to claim");
        require(
            IERC20(trpzToken).balanceOf(address(this)) >= rewards,
            "No reward funds"
        );
        ownerToRewards[msg.sender] = 0;
        bool success = IERC20(trpzToken).transfer(msg.sender, rewards);
        require(success, "Transfer did not work");
    }

    /// @dev Receiving an NFT - call approve then transfer on front-end for NFT
    function onERC721Received(
        address _operator,
        address _from,
        uint256 _tokenId,
        bytes memory
    ) public virtual override nonReentrant returns (bytes4) {
        require(whitelistedContracts[msg.sender], "Contract not whitelisted");
        if (msg.sender != OGAddress) {
            require(OGBalance[_from] >= 1, "STAKE_OG_TO_UNLOCK");
        }
        uint256 rewards;
        if (ownerToIds[_from].length >= 1) {
            if (ownerToLastUpdate[_from] < lastYieldUpdate) {
                rewards = _updateHistoricRewards(_from);
            } else {
                rewards = _updateRewards(_from);
            }
            if (rewards == 0) {
                ownerToLastUpdate[_from] =
                    block.timestamp -
                    (block.timestamp - ownerToLastUpdate[_from]);
            } else {
                ownerToRewards[_from] += rewards;
                ownerToLastUpdate[_from] =
                    block.timestamp -
                    (ownerToLastUpdate[_from] % 1 days);
            }
        } else {
            ownerToLastUpdate[_from] = block.timestamp;
        }

        stakingId.increment();
        uint256 nftstakingId = stakingId.current();
        stakedNFTIds[nftstakingId] = stakedNFT(_tokenId, msg.sender, _from);
        ownerToIds[_from].push(nftstakingId);
        if (msg.sender == OGAddress) {
            OGBalance[_from] += 1;
        }
        return this.onERC721Received.selector;
    }

    /// @dev Withdraw an NFT
    function withdrawToken(uint256 _stakingId) external nonReentrant {
        require(stakedNFTIds[_stakingId].owner == msg.sender, "Not owner");
        require(ownerToIds[msg.sender].length >= 1, "Nothing staked");

        /// Claim rewards before withdrawal
        uint256 rewards;
        if (ownerToLastUpdate[msg.sender] < lastYieldUpdate) {
            rewards = _updateHistoricRewards(msg.sender);
        } else {
            rewards = _updateRewards(msg.sender);
        }
        if (rewards != 0) {
            ownerToRewards[msg.sender] += rewards;
            ownerToLastUpdate[msg.sender] =
                block.timestamp -
                (ownerToLastUpdate[msg.sender] % 1 days);
        }

        address nftContract;
        uint256 tokenId;
        if (ownerToIds[msg.sender].length == 1) {
            nftContract = stakedNFTIds[ownerToIds[msg.sender][0]].nftContract;
            tokenId = stakedNFTIds[ownerToIds[msg.sender][0]].tokenId;
            if (nftContract == OGAddress) {
                OGBalance[msg.sender] -= 1;
            }
            delete stakedNFTIds[ownerToIds[msg.sender][0]];
            ownerToIds[msg.sender].pop();
        } else {
            for (uint256 i; i < ownerToIds[msg.sender].length; i++) {
                if (
                    ownerToIds[msg.sender][i] == _stakingId &&
                    i != ownerToIds[msg.sender].length - 1
                ) {
                    nftContract = stakedNFTIds[ownerToIds[msg.sender][i]]
                        .nftContract;
                    tokenId = stakedNFTIds[ownerToIds[msg.sender][i]].tokenId;

                    uint256 deletingId = ownerToIds[msg.sender][i];
                    ownerToIds[msg.sender][i] = ownerToIds[msg.sender][
                        ownerToIds[msg.sender].length - 1
                    ];

                    if (nftContract == OGAddress) {
                        OGBalance[msg.sender] -= 1;
                    }

                    delete stakedNFTIds[deletingId];
                    ownerToIds[msg.sender].pop();
                    break;
                }
                if (ownerToIds[msg.sender][i] == _stakingId) {
                    nftContract = stakedNFTIds[ownerToIds[msg.sender][i]]
                        .nftContract;
                    tokenId = stakedNFTIds[ownerToIds[msg.sender][i]].tokenId;

                    if (nftContract == OGAddress) {
                        OGBalance[msg.sender] -= 1;
                    }

                    delete stakedNFTIds[ownerToIds[msg.sender][i]];
                    ownerToIds[msg.sender].pop();
                    break;
                }
            }
        }
        IERC721(nftContract).safeTransferFrom(
            address(this),
            msg.sender,
            tokenId
        );
    }

    function batchWithdrawTokens() external nonReentrant {
        require(ownerToIds[msg.sender].length >= 2, "NOT_ENOUGH");
        uint256 rewards;
        if (ownerToLastUpdate[msg.sender] < lastYieldUpdate) {
            rewards = _updateHistoricRewards(msg.sender);
        } else {
            rewards = _updateRewards(msg.sender);
        }
        if (rewards != 0) {
            ownerToRewards[msg.sender] += rewards;
            ownerToLastUpdate[msg.sender] =
                block.timestamp -
                (ownerToLastUpdate[msg.sender] % 1 days);
        }

        for (uint256 i; i < ownerToIds[msg.sender].length; i++) {
            IERC721(stakedNFTIds[ownerToIds[msg.sender][i]].nftContract)
                .safeTransferFrom(
                    address(this),
                    msg.sender,
                    stakedNFTIds[ownerToIds[msg.sender][i]].tokenId
                );
            delete stakedNFTIds[ownerToIds[msg.sender][i]];
        }
        delete ownerToIds[msg.sender];
        OGBalance[msg.sender] = 0;
    }

    function emergencyWithdrawal(uint256 _stakingId) external {
        require(stakedNFTIds[_stakingId].owner == msg.sender, "Not owner");
        address nftContract = stakedNFTIds[_stakingId].nftContract;
        uint256 tokenId = stakedNFTIds[_stakingId].tokenId;
        IERC721(nftContract).safeTransferFrom(
            address(this),
            msg.sender,
            tokenId
        );
    }

    // ==================== INTERNAL FUNCTIONS ==================== //
    /// @dev Internal function used to calculate rewards for NFTs held
    // Modulo used to carry up to get reward up to previous day passed
    function _updateRewards(address _addr) internal view returns (uint256) {
        uint256[] memory ownerStakingIds = ownerToIds[_addr];
        uint256 rewards;
        for (uint256 i; i < ownerStakingIds.length; i++) {
            rewards += (dailyContractRewards[
                stakedNFTIds[ownerStakingIds[i]].nftContract
            ] * ((block.timestamp - ownerToLastUpdate[_addr]) / 86400));
        }
        return rewards;
    }

    function _updateHistoricRewards(address _addr)
        internal
        view
        returns (uint256)
    {
        uint256[] memory ownerStakingIds = ownerToIds[_addr];
        uint256 rewards;
        uint256 rewardTime;
        for (uint256 i; i < ownerStakingIds.length; i++) {
            /// Named previous here for traversal but this is the headId
            uint64 previous = historicRewardHead[
                stakedNFTIds[ownerStakingIds[i]].nftContract
            ].rewardId;

            /// If the historic stamp is less than last update then the yield hasn't changed
            /// Claim and move on.
            if (
                historicRewardToId[previous].timestamp <
                ownerToLastUpdate[_addr]
            ) {
                rewards += (dailyContractRewards[
                    stakedNFTIds[ownerStakingIds[i]].nftContract
                ] * ((block.timestamp - ownerToLastUpdate[_addr]) / 86400));
                continue;

                /// If the historic stamp is more than that last update then the yield has changed
                /// Find the difference between the time it was updated and now --> claim and move on
            } else {
                uint256 rewardTimeClaim = (
                    (block.timestamp - historicRewardToId[previous].timestamp)
                ) / 86400;
                rewards += (dailyContractRewards[
                    stakedNFTIds[ownerStakingIds[i]].nftContract
                ] * rewardTimeClaim);
            }

            /// Get the next Id
            uint64 current = historicRewardToId[previous].next;
            /// While the timestamp for the next reward has been more recently updated than last update
            /// calculate reward between this next block and the block ahead of it
            while (
                ownerToLastUpdate[_addr] < historicRewardToId[current].timestamp
            ) {
                /// We get the time lapse between updates
                rewardTime =
                    historicRewardToId[previous].timestamp -
                    historicRewardToId[current].timestamp;

                /// Divide reward time into days and multiply by next rewards
                rewards +=
                    historicRewardToId[current].reward *
                    (rewardTime / 86400);
                /// Set current to previous
                previous = current;
                current = historicRewardToId[current].next;
            }

            /// When the last update is sooner than the next rewards timestamp
            /// get the difference between the update and timestamp
            rewardTime =
                historicRewardToId[previous].timestamp -
                ownerToLastUpdate[_addr];
            rewards +=
                historicRewardToId[current].reward *
                (rewardTime / 86400);
        }
        return rewards;
    }

    // ===================== ADMIN FUNCTIONS ====================== //
    /// @dev Whitelist function to add new NFT addresses
    function whitelistContract(address _addr) external {
        require(hasRole(ADMIN_ROLE, msg.sender), "You are not an admin");
        whitelistedContracts[_addr] = !whitelistedContracts[_addr];
    }

    /// @dev Setter function for daily rewards of each NFT contract
    /// Setting new reward to the head + adding to historicIds + pointing the linked list down the chain
    function yieldSetter(address _addr, uint64 _dailyReward) external {
        require(hasRole(ADMIN_ROLE, msg.sender), "You are not an admin");
        require(whitelistedContracts[_addr], "Address not whitelisted");
        lastYieldUpdate = block.timestamp;
        uint64 previousHeadId = historicRewardHead[_addr].rewardId;
        historicId++;
        historicRewardHead[_addr] = historicReward(
            block.timestamp,
            historicId,
            _dailyReward,
            previousHeadId
        );
        historicRewardToId[historicId] = historicRewardHead[_addr];
        dailyContractRewards[_addr] = _dailyReward;
    }

    // ====================== GETTER FUNCTIONS =================== //
    function getStakedNFT(uint256 _stakingId)
        external
        view
        returns (
            uint256 tokenId,
            address contractAddr,
            address owner
        )
    {
        stakedNFT memory nft = stakedNFTIds[_stakingId];
        require(nft.nftContract != address(0), "Doesn't exist");
        uint256 nftId = nft.tokenId;
        address nftContract = nft.nftContract;
        address nftOwner = nft.owner;
        return (nftId, nftContract, nftOwner);
    }

    function getStakedList(address _address)
        external
        view
        returns (uint256[] memory)
    {
        return ownerToIds[_address];
    }

    function getRewards(address _address) external view returns (uint256) {
        uint256 rewards;
        if (ownerToLastUpdate[_address] < lastYieldUpdate) {
            rewards = _updateHistoricRewards(_address);
        } else {
            rewards = _updateRewards(_address);
        }
        return rewards;
    }
}

File 2 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 3 of 12 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

File 4 of 12 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 5 of 12 : Counters.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

File 6 of 12 : AccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;

import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

File 7 of 12 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 8 of 12 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 9 of 12 : IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 10 of 12 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 11 of 12 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

File 12 of 12 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_trpzToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OGAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"OGBalance","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_contractAddress","type":"address[]"},{"internalType":"uint256[]","name":"_tokenId","type":"uint256[]"}],"name":"batchDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"batchWithdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"dailyContractRewards","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingId","type":"uint256"}],"name":"emergencyWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getStakedList","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingId","type":"uint256"}],"name":"getStakedNFT","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"contractAddr","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"historicId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"historicRewardHead","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint64","name":"rewardId","type":"uint64"},{"internalType":"uint64","name":"reward","type":"uint64"},{"internalType":"uint64","name":"next","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"historicRewardToId","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint64","name":"rewardId","type":"uint64"},{"internalType":"uint64","name":"reward","type":"uint64"},{"internalType":"uint64","name":"next","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownerToIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ownerToLastUpdate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ownerToRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakedNFTIds","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingId","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"trpzToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updateRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"whitelistContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingId","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint64","name":"_dailyReward","type":"uint64"}],"name":"yieldSetter","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040527351112bf32b9a1c64716df2e6b82e63a04bd384fd73ffffffffffffffffffffffffffffffffffffffff1660809073ffffffffffffffffffffffffffffffffffffffff1660601b8152503480156200005b57600080fd5b506040516200614638038062006146833981810160405281019062000081919062000292565b60018081905550620000ba7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775336200010260201b60201c565b80600460086101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200030c565b6200011482826200011860201b60201c565b5050565b6200012a82826200020960201b60201c565b6200020557600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620001aa6200027360201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b6000815190506200028c81620002f2565b92915050565b600060208284031215620002a557600080fd5b6000620002b5848285016200027b565b91505092915050565b6000620002cb82620002d2565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b620002fd81620002be565b81146200030957600080fd5b50565b60805160601c615df86200034e6000396000818161099901528181610e9601528181611b6801528181612223015281816125db0152612dd70152615df86000f3fe608060405234801561001057600080fd5b50600436106101fa5760003560e01c806379ee54f71161011a578063c8d8b43d116100ad578063ee104cf21161007c578063ee104cf2146105ec578063f462740f1461060a578063fa713b6914610626578063fc9b91df14610659578063feb3d3d61461068b576101fa565b8063c8d8b43d14610578578063d547741f14610596578063dc73f0a0146105b2578063e3c0ff12146105bc576101fa565b8063a217fddf116100e9578063a217fddf14610502578063a560842c14610520578063aee6cd2814610550578063c7b8981c1461056e576101fa565b806379ee54f71461045457806391d1485414610484578063940aa5d8146104b45780639d49be33146104e4576101fa565b806336568abe1161019257806350baa6221161016157806350baa622146103b75780635f10ad3e146103d3578063674b3f901461040357806375b238fc14610436576101fa565b806336568abe14610345578063391feebb146103615780633a0e6d43146103915780633e158b0c146103ad576101fa565b80631a108d0e116101ce5780631a108d0e146102ab578063248a9ca3146102dd5780632f2ff15d1461030d57806330a9073614610329576101fa565b806239522c146101ff57806301ffc9a71461021b5780630b86f6e61461024b578063150b7a021461027b575b600080fd5b61021960048036038101906102149190614db1565b6106bb565b005b61023560048036038101906102309190614d88565b610829565b604051610242919061529f565b60405180910390f35b61026560048036038101906102609190614b69565b6108a3565b60405161027291906154f2565b60405180910390f35b61029560048036038101906102909190614b92565b6108bb565b6040516102a291906152d5565b60405180910390f35b6102c560048036038101906102c09190614db1565b610f8d565b6040516102d49392919061550d565b60405180910390f35b6102f760048036038101906102f29190614d23565b61110c565b60405161030491906152ba565b60405180910390f35b61032760048036038101906103229190614d4c565b61112b565b005b610343600480360381019061033e9190614c85565b61114c565b005b61035f600480360381019061035a9190614d4c565b61126f565b005b61037b60048036038101906103769190614b69565b6112f2565b604051610388919061529f565b60405180910390f35b6103ab60048036038101906103a69190614b69565b611312565b005b6103b5611422565b005b6103d160048036038101906103cc9190614db1565b6116e8565b005b6103ed60048036038101906103e89190614b69565b6128c5565b6040516103fa9190615589565b60405180910390f35b61041d60048036038101906104189190614b69565b6128ec565b60405161042d9493929190615544565b60405180910390f35b61043e612958565b60405161044b91906152ba565b60405180910390f35b61046e60048036038101906104699190614b69565b61297c565b60405161047b91906154f2565b60405180910390f35b61049e60048036038101906104999190614d4c565b6129ed565b6040516104ab919061529f565b60405180910390f35b6104ce60048036038101906104c99190614b69565b612a57565b6040516104db9190615589565b60405180910390f35b6104ec612a7e565b6040516104f991906154f2565b60405180910390f35b61050a612a8a565b60405161051791906152ba565b60405180910390f35b61053a60048036038101906105359190614b69565b612a91565b60405161054791906154f2565b60405180910390f35b610558612aa9565b6040516105659190615202565b60405180910390f35b610576612acf565b005b610580612dd5565b60405161058d9190615202565b60405180910390f35b6105b060048036038101906105ab9190614d4c565b612df9565b005b6105ba612e1a565b005b6105d660048036038101906105d19190614b69565b613417565b6040516105e3919061527d565b60405180910390f35b6105f46134ae565b6040516106019190615589565b60405180910390f35b610624600480360381019061061f9190614c49565b6134c8565b005b610640600480360381019061063b9190614e03565b613957565b6040516106509493929190615544565b60405180910390f35b610673600480360381019061066e9190614db1565b6139c3565b6040516106829392919061550d565b60405180910390f35b6106a560048036038101906106a09190614c0d565b613a2d565b6040516106b291906154f2565b60405180910390f35b3373ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461075f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075690615452565b60405180910390fd5b60006005600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600560008481526020019081526020016000206000015490508173ffffffffffffffffffffffffffffffffffffffff166342842e0e3033846040518463ffffffff1660e01b81526004016107f29392919061521d565b600060405180830381600087803b15801561080c57600080fd5b505af1158015610820573d6000803e3d6000fd5b50505050505050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061089c575061089b82613a5e565b5b9050919050565b60096020528060005260406000206000915090505481565b600060026001541415610903576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fa90615492565b60405180910390fd5b6002600181905550600b60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610997576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098e90615372565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a8c576001600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1667ffffffffffffffff161015610a8b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a8290615352565b60405180910390fd5b5b60006001600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905010610cdc57600354600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610b3157610b2a85613ac8565b9050610b3d565b610b3a85614202565b90505b6000811415610be457600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205442610b919190615779565b42610b9c9190615779565b600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610cd7565b80600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610c33919061565a565b9250508190555062015180600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610c88919061598a565b42610c939190615779565b600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b610d21565b42600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b610d2b6002614404565b6000610d37600261441a565b905060405180606001604052808681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff16815250600560008381526020019081526020016000206000820151816000015560208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002001600090919091909150557f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610f72576001600d60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900467ffffffffffffffff16610f4b91906156b0565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b63150b7a0260e01b9250505060018081905550949350505050565b60008060008060056000868152602001908152602001600020604051806060016040529081600082015481526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816020015173ffffffffffffffffffffffffffffffffffffffff1614156110dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d4906153b2565b60405180910390fd5b600081600001519050600082602001519050600083604001519050828282965096509650505050509193909250565b6000806000838152602001908152602001600020600101549050919050565b6111348261110c565b61113d81614428565b611147838361443c565b505050565b60005b8484905081101561126857848482818110611193577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906111a89190614b69565b73ffffffffffffffffffffffffffffffffffffffff166342842e0e33308686868181106111fe577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b905060200201356040518463ffffffff1660e01b81526004016112239392919061521d565b600060405180830381600087803b15801561123d57600080fd5b505af1158015611251573d6000803e3d6000fd5b50505050808061126090615910565b91505061114f565b5050505050565b61127761451c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146112e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112db906154b2565b60405180910390fd5b6112ee8282614524565b5050565b600b6020528060005260406000206000915054906101000a900460ff1681565b61133c7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775336129ed565b61137b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611372906153f2565b60405180910390fd5b600b60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60026001541415611468576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145f90615492565b60405180910390fd5b60026001819055506000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905014156114f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ed906154d2565b60405180910390fd5b62015180600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054426115459190615779565b11611585576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157c906153d2565b60405180910390fd5b6000600354600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156115e0576115d933613ac8565b90506115ec565b6115e933614202565b90505b80600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461163b919061565a565b9250508190555062015180600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611690919061598a565b4261169b9190615779565b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505060018081905550565b6002600154141561172e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172590615492565b60405180910390fd5b60026001819055503373ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146117da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117d190615452565b60405180910390fd5b6001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490501015611860576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185790615412565b60405180910390fd5b6000600354600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156118bb576118b433613ac8565b90506118c7565b6118c433614202565b90505b600081146119c25780600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461191e919061565a565b9250508190555062015180600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611973919061598a565b4261197e9190615779565b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6000806001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490501415611dc25760056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548110611a8c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915060056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548110611b47577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015481526020019081526020016000206000015490507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611c44576001600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900467ffffffffffffffff16611c1d91906157ad565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b60056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548110611cc0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015481526020019081526020016000206000808201600090556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480611da7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055612849565b60005b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490508110156128475784600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110611e87577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154148015611eed57506001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611ee99190615779565b8114155b156123fc5760056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110611f6d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16925060056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110612027577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015481526020019081526020016000206000015491506000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106120bf577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001549050600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905061215a9190615779565b81548110612191577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110612213577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156122ff576001600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900467ffffffffffffffff166122d891906157ad565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b600560008281526020019081526020016000206000808201600090556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806123e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6001900381819060005260206000200160009055905550612847565b84600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110612474577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015414156128345760056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110612500577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16925060056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083815481106125ba577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015481526020019081526020016000206000015491507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156126b7576001600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a900467ffffffffffffffff1661269091906157ad565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b60056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110612732577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015481526020019081526020016000206000808201600090556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480612819577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055612847565b808061283f90615910565b915050611dc5565b505b8173ffffffffffffffffffffffffffffffffffffffff166342842e0e3033846040518463ffffffff1660e01b81526004016128869392919061521d565b600060405180830381600087803b1580156128a057600080fd5b505af11580156128b4573d6000803e3d6000fd5b505050505050506001808190555050565b600c6020528060005260406000206000915054906101000a900467ffffffffffffffff1681565b60066020528060005260406000206000915090508060000154908060010160009054906101000a900467ffffffffffffffff16908060010160089054906101000a900467ffffffffffffffff16908060010160109054906101000a900467ffffffffffffffff16905084565b7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177581565b600080600354600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156129d8576129d183613ac8565b90506129e4565b6129e183614202565b90505b80915050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600d6020528060005260406000206000915054906101000a900467ffffffffffffffff1681565b60028060000154905081565b6000801b81565b600a6020528060005260406000206000915090505481565b600460089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60026001541415612b15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0c90615492565b60405180910390fd5b60026001819055506000600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000811415612ba5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b9c906153d2565b60405180910390fd5b80600460089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401612c019190615202565b60206040518083038186803b158015612c1957600080fd5b505afa158015612c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c519190614dda565b1015612c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c8990615392565b60405180910390fd5b6000600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600460089054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401612d36929190615254565b602060405180830381600087803b158015612d5057600080fd5b505af1158015612d64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d889190614cfa565b905080612dca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dc190615332565b60405180910390fd5b505060018081905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b612e028261110c565b612e0b81614428565b612e158383614524565b505050565b60026001541415612e60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e5790615492565b60405180910390fd5b60026001819055506002600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490501015612eee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ee590615472565b60405180910390fd5b6000600354600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015612f4957612f4233613ac8565b9050612f55565b612f5233614202565b90505b600081146130505780600960003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612fac919061565a565b9250508190555062015180600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613001919061598a565b4261300c9190615779565b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b60005b600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905081101561335a5760056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208381548110613118577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342842e0e303360056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002087815481106131ed577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001548152602001908152602001600020600001546040518463ffffffff1660e01b81526004016132289392919061521d565b600060405180830381600087803b15801561324257600080fd5b505af1158015613256573d6000803e3d6000fd5b5050505060056000600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083815481106132d5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015481526020019081526020016000206000808201600090556001820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555050808061335290615910565b915050613053565b50600860003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006133a6919061499c565b6000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505060018081905550565b6060600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156134a257602002820191906000526020600020905b81548152602001906001019080831161348e575b50505050509050919050565b600460009054906101000a900467ffffffffffffffff1681565b6134f27fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775336129ed565b613531576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613528906153f2565b60405180910390fd5b600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166135bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016135b490615432565b60405180910390fd5b426003819055506000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900467ffffffffffffffff1690506004600081819054906101000a900467ffffffffffffffff168092919061364590615959565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550506040518060800160405280428152602001600460009054906101000a900467ffffffffffffffff1667ffffffffffffffff1681526020018367ffffffffffffffff1681526020018267ffffffffffffffff16815250600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060408201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160010160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905050600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060076000600460009054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600082015481600001556001820160009054906101000a900467ffffffffffffffff168160010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001820160089054906101000a900467ffffffffffffffff168160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506001820160109054906101000a900467ffffffffffffffff168160010160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555090505081600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b60076020528060005260406000206000915090508060000154908060010160009054906101000a900467ffffffffffffffff16908060010160089054906101000a900467ffffffffffffffff16908060010160109054906101000a900467ffffffffffffffff16905084565b60056020528060005260406000206000915090508060000154908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60086020528160005260406000208181548110613a4957600080fd5b90600052602060002001600091509150505481565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015613b5457602002820191906000526020600020905b815481526020019060010190808311613b40575b5050505050905060008060005b83518110156141f65760006006600060056000888681518110613bad577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900467ffffffffffffffff169050600a60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600760008367ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600001541015613df65762015180600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205442613cfb9190615779565b613d0591906156ee565b600c600060056000898781518110613d46577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1667ffffffffffffffff16613de3919061571f565b84613dee919061565a565b9350506141e3565b600062015180600760008467ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206000015442613e329190615779565b613e3c91906156ee565b905080600c6000600560008a8881518110613e80577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1667ffffffffffffffff16613f1d919061571f565b85613f28919061565a565b9450506000600760008367ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060010160109054906101000a900467ffffffffffffffff1690505b600760008267ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060000154600a60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156140fa57600760008267ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060000154600760008467ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600001546140409190615779565b9350620151808461405191906156ee565b600760008367ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff166140a4919061571f565b856140af919061565a565b9450809150600760008267ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060010160109054906101000a900467ffffffffffffffff169050613f6f565b600a60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600760008467ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206000015461416f9190615779565b9350620151808461418091906156ee565b600760008367ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff166141d3919061571f565b856141de919061565a565b945050505b80806141ee90615910565b915050613b61565b50819350505050919050565b600080600860008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561428e57602002820191906000526020600020905b81548152602001906001019080831161427a575b505050505090506000805b82518110156143f95762015180600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054426142f19190615779565b6142fb91906156ee565b600c60006005600087868151811061433c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1667ffffffffffffffff166143d9919061571f565b826143e4919061565a565b915080806143f190615910565b915050614299565b508092505050919050565b6001816000016000828254019250508190555050565b600081600001549050919050565b6144398161443461451c565b614605565b50565b61444682826129ed565b61451857600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506144bd61451c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b61452e82826129ed565b1561460157600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506145a661451c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b61460f82826129ed565b61469e576146348173ffffffffffffffffffffffffffffffffffffffff1660146146a2565b6146428360001c60206146a2565b6040516020016146539291906151c8565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161469591906152f0565b60405180910390fd5b5050565b6060600060028360026146b5919061571f565b6146bf919061565a565b67ffffffffffffffff8111156146fe577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156147305781602001600182028036833780820191505090505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061478e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110614818577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002614858919061571f565b614862919061565a565b90505b600181111561494e577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106148ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b828281518110614907577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080614947906158b5565b9050614865565b5060008414614992576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161498990615312565b60405180910390fd5b8091505092915050565b50805460008255906000526020600020908101906149ba91906149bd565b50565b5b808211156149d65760008160009055506001016149be565b5090565b60006149ed6149e8846155c9565b6155a4565b905082815260208101848484011115614a0557600080fd5b614a10848285615873565b509392505050565b600081359050614a2781615d38565b92915050565b60008083601f840112614a3f57600080fd5b8235905067ffffffffffffffff811115614a5857600080fd5b602083019150836020820283011115614a7057600080fd5b9250929050565b60008083601f840112614a8957600080fd5b8235905067ffffffffffffffff811115614aa257600080fd5b602083019150836020820283011115614aba57600080fd5b9250929050565b600081519050614ad081615d4f565b92915050565b600081359050614ae581615d66565b92915050565b600081359050614afa81615d7d565b92915050565b600082601f830112614b1157600080fd5b8135614b218482602086016149da565b91505092915050565b600081359050614b3981615d94565b92915050565b600081519050614b4e81615d94565b92915050565b600081359050614b6381615dab565b92915050565b600060208284031215614b7b57600080fd5b6000614b8984828501614a18565b91505092915050565b60008060008060808587031215614ba857600080fd5b6000614bb687828801614a18565b9450506020614bc787828801614a18565b9350506040614bd887828801614b2a565b925050606085013567ffffffffffffffff811115614bf557600080fd5b614c0187828801614b00565b91505092959194509250565b60008060408385031215614c2057600080fd5b6000614c2e85828601614a18565b9250506020614c3f85828601614b2a565b9150509250929050565b60008060408385031215614c5c57600080fd5b6000614c6a85828601614a18565b9250506020614c7b85828601614b54565b9150509250929050565b60008060008060408587031215614c9b57600080fd5b600085013567ffffffffffffffff811115614cb557600080fd5b614cc187828801614a2d565b9450945050602085013567ffffffffffffffff811115614ce057600080fd5b614cec87828801614a77565b925092505092959194509250565b600060208284031215614d0c57600080fd5b6000614d1a84828501614ac1565b91505092915050565b600060208284031215614d3557600080fd5b6000614d4384828501614ad6565b91505092915050565b60008060408385031215614d5f57600080fd5b6000614d6d85828601614ad6565b9250506020614d7e85828601614a18565b9150509250929050565b600060208284031215614d9a57600080fd5b6000614da884828501614aeb565b91505092915050565b600060208284031215614dc357600080fd5b6000614dd184828501614b2a565b91505092915050565b600060208284031215614dec57600080fd5b6000614dfa84828501614b3f565b91505092915050565b600060208284031215614e1557600080fd5b6000614e2384828501614b54565b91505092915050565b6000614e38838361519b565b60208301905092915050565b614e4d816157e1565b82525050565b6000614e5e8261560a565b614e68818561562d565b9350614e73836155fa565b8060005b83811015614ea4578151614e8b8882614e2c565b9750614e9683615620565b925050600181019050614e77565b5085935050505092915050565b614eba816157f3565b82525050565b614ec9816157ff565b82525050565b614ed881615809565b82525050565b6000614ee982615615565b614ef3818561563e565b9350614f03818560208601615882565b614f0c81615a48565b840191505092915050565b6000614f2282615615565b614f2c818561564f565b9350614f3c818560208601615882565b80840191505092915050565b6000614f5560208361563e565b9150614f6082615a59565b602082019050919050565b6000614f7860158361563e565b9150614f8382615a82565b602082019050919050565b6000614f9b60128361563e565b9150614fa682615aab565b602082019050919050565b6000614fbe60188361563e565b9150614fc982615ad4565b602082019050919050565b6000614fe1600f8361563e565b9150614fec82615afd565b602082019050919050565b6000615004600d8361563e565b915061500f82615b26565b602082019050919050565b600061502760138361563e565b915061503282615b4f565b602082019050919050565b600061504a60148361563e565b915061505582615b78565b602082019050919050565b600061506d600e8361563e565b915061507882615ba1565b602082019050919050565b600061509060178361563e565b915061509b82615bca565b602082019050919050565b60006150b360098361563e565b91506150be82615bf3565b602082019050919050565b60006150d6600a8361563e565b91506150e182615c1c565b602082019050919050565b60006150f960178361564f565b915061510482615c45565b601782019050919050565b600061511c601f8361563e565b915061512782615c6e565b602082019050919050565b600061513f60118361564f565b915061514a82615c97565b601182019050919050565b6000615162602f8361563e565b915061516d82615cc0565b604082019050919050565b6000615185600e8361563e565b915061519082615d0f565b602082019050919050565b6151a481615855565b82525050565b6151b381615855565b82525050565b6151c28161585f565b82525050565b60006151d3826150ec565b91506151df8285614f17565b91506151ea82615132565b91506151f68284614f17565b91508190509392505050565b60006020820190506152176000830184614e44565b92915050565b60006060820190506152326000830186614e44565b61523f6020830185614e44565b61524c60408301846151aa565b949350505050565b60006040820190506152696000830185614e44565b61527660208301846151aa565b9392505050565b600060208201905081810360008301526152978184614e53565b905092915050565b60006020820190506152b46000830184614eb1565b92915050565b60006020820190506152cf6000830184614ec0565b92915050565b60006020820190506152ea6000830184614ecf565b92915050565b6000602082019050818103600083015261530a8184614ede565b905092915050565b6000602082019050818103600083015261532b81614f48565b9050919050565b6000602082019050818103600083015261534b81614f6b565b9050919050565b6000602082019050818103600083015261536b81614f8e565b9050919050565b6000602082019050818103600083015261538b81614fb1565b9050919050565b600060208201905081810360008301526153ab81614fd4565b9050919050565b600060208201905081810360008301526153cb81614ff7565b9050919050565b600060208201905081810360008301526153eb8161501a565b9050919050565b6000602082019050818103600083015261540b8161503d565b9050919050565b6000602082019050818103600083015261542b81615060565b9050919050565b6000602082019050818103600083015261544b81615083565b9050919050565b6000602082019050818103600083015261546b816150a6565b9050919050565b6000602082019050818103600083015261548b816150c9565b9050919050565b600060208201905081810360008301526154ab8161510f565b9050919050565b600060208201905081810360008301526154cb81615155565b9050919050565b600060208201905081810360008301526154eb81615178565b9050919050565b600060208201905061550760008301846151aa565b92915050565b600060608201905061552260008301866151aa565b61552f6020830185614e44565b61553c6040830184614e44565b949350505050565b600060808201905061555960008301876151aa565b61556660208301866151b9565b61557360408301856151b9565b61558060608301846151b9565b95945050505050565b600060208201905061559e60008301846151b9565b92915050565b60006155ae6155bf565b90506155ba82826158df565b919050565b6000604051905090565b600067ffffffffffffffff8211156155e4576155e3615a19565b5b6155ed82615a48565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600061566582615855565b915061567083615855565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156156a5576156a46159bb565b5b828201905092915050565b60006156bb8261585f565b91506156c68361585f565b92508267ffffffffffffffff038211156156e3576156e26159bb565b5b828201905092915050565b60006156f982615855565b915061570483615855565b925082615714576157136159ea565b5b828204905092915050565b600061572a82615855565b915061573583615855565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561576e5761576d6159bb565b5b828202905092915050565b600061578482615855565b915061578f83615855565b9250828210156157a2576157a16159bb565b5b828203905092915050565b60006157b88261585f565b91506157c38361585f565b9250828210156157d6576157d56159bb565b5b828203905092915050565b60006157ec82615835565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b82818337600083830152505050565b60005b838110156158a0578082015181840152602081019050615885565b838111156158af576000848401525b50505050565b60006158c082615855565b915060008214156158d4576158d36159bb565b5b600182039050919050565b6158e882615a48565b810181811067ffffffffffffffff8211171561590757615906615a19565b5b80604052505050565b600061591b82615855565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561594e5761594d6159bb565b5b600182019050919050565b60006159648261585f565b915067ffffffffffffffff82141561597f5761597e6159bb565b5b600182019050919050565b600061599582615855565b91506159a083615855565b9250826159b0576159af6159ea565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f5472616e7366657220646964206e6f7420776f726b0000000000000000000000600082015250565b7f5354414b455f4f475f544f5f554e4c4f434b0000000000000000000000000000600082015250565b7f436f6e7472616374206e6f742077686974656c69737465640000000000000000600082015250565b7f4e6f207265776172642066756e64730000000000000000000000000000000000600082015250565b7f446f65736e277420657869737400000000000000000000000000000000000000600082015250565b7f4e6f207265776172647320746f20636c61696d00000000000000000000000000600082015250565b7f596f7520617265206e6f7420616e2061646d696e000000000000000000000000600082015250565b7f4e6f7468696e67207374616b6564000000000000000000000000000000000000600082015250565b7f41646472657373206e6f742077686974656c6973746564000000000000000000600082015250565b7f4e6f74206f776e65720000000000000000000000000000000000000000000000600082015250565b7f4e4f545f454e4f55474800000000000000000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f4e6f207374616b6564204e465473000000000000000000000000000000000000600082015250565b615d41816157e1565b8114615d4c57600080fd5b50565b615d58816157f3565b8114615d6357600080fd5b50565b615d6f816157ff565b8114615d7a57600080fd5b50565b615d8681615809565b8114615d9157600080fd5b50565b615d9d81615855565b8114615da857600080fd5b50565b615db48161585f565b8114615dbf57600080fd5b5056fea264697066735822122059e139858b220cc2a9cf0b59c2890527d86225d9accd6222323abbfeb547c69f64736f6c634300080400330000000000000000000000001cc0b25bd5105cd8905f7e9cd174435d4c890e02

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000001cc0b25bd5105cd8905f7e9cd174435d4c890e02

-----Decoded View---------------
Arg [0] : _trpzToken (address): 0x1cc0b25bd5105cd8905f7e9cd174435d4c890e02

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001cc0b25bd5105cd8905f7e9cd174435d4c890e02


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.