MATIC Price: $0.534477 (-0.41%)
Gas: 30.9 GWei
 

Overview

TokenID

399

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
AuctionableERC1155

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 15 : AuctionableERC1155.sol
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;
import "./CreatorsHub/Base.sol";
import "./CreatorsHub/Auctionable.sol";

contract AuctionableERC1155 is
    CreatorsHubBase("https://creatorshub.license.rocks/api/public/metaFile/"),
    Auctionable
{
    constructor() {}
}

File 2 of 15 : Base.sol
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "../EIP712MetaTransaction.sol";
import "./Ownable.sol";
import "../Strings.sol";

/**
 *
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract CreatorsHubBase is
    ERC165Storage,
    IERC1155,
    IERC1155MetadataURI,
    EIP712MetaTransaction("ERC1155", "1"),
    Ownable
{
    using SafeMath for uint256;
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

    // Mapping from account to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    // Mapping from account to true / false mint approvals
    mapping(address => bool) private _mintApprovals;

    // Mapping from account to root operators approvals
    mapping(address => bool) internal _rootOperators;

    mapping(uint256 => string) private _metaFileUrl;

    // Mapping from token ID to proof checksums
    mapping(uint256 => string[]) private _proofChecksums;

    // Mapping from token ID to secret field
    mapping(uint256 => string) private _secretFields;

    // Mapping from token ID to fees lock (true/false)
    mapping(uint256 => bool) private _feesLock;

    // Mapping from token ID to flag (paused = true, active = false)
    mapping(uint256 => bool) internal _isPaused;

    // Mapping from token ID to amount (reedmable if > 0)
    mapping(uint256 => uint256) internal _redeemable;

    // Mapping from token ID to array of addresses
    mapping(uint256 => address[]) internal _redeemed_by;

    struct Listing {
        uint256 initialPrice;
        uint256 price;
        bool biddingEnabled;
        uint256 activeTill;
        address payable currentBidder;
        bool operatorBid;
    }

    struct Fee {
        string name;
        address payable recipient;
        uint256 value; // 185 basis points = 1.85%
        bool percentage;
    }
    // Mapping from token ID to array of fees (initial sale)
    mapping(uint256 => Fee[]) internal _creatorFees;

    // Mapping from token ID to array of fees (reselling)
    mapping(uint256 => Fee[]) internal _resellerFees;

    // Mapping from token ID to account price
    mapping(uint256 => mapping(address => Listing)) internal _tokenListings;

    function addCreatorFees(uint256 tokenId, Fee[] memory fees) public {
        require(_feesLock[tokenId] == false, "Fees locked");
        require(
            _owners[tokenId] == _msgSender() ||
                _rootOperators[_msgSender()] == true,
            "Must be owner or operator"
        );
        for (uint256 i = 0; i < fees.length; i++) {
            if (fees[i].percentage == true) {
                require(
                    fees[i].value < 10000,
                    "Fee must be between 1-10000 basis points"
                );
                require(
                    fees[i].value > 0,
                    "Fee must be between 1-10000 basis points"
                );
            }
            _creatorFees[tokenId].push(fees[i]);
        }
    }

    function addResellerFees(uint256 tokenId, Fee[] memory fees) public {
        require(_feesLock[tokenId] == false, "Fees locked");
        require(
            _owners[tokenId] == _msgSender() ||
                _rootOperators[_msgSender()] == true,
            "Must be owner or operator"
        );
        for (uint256 i = 0; i < fees.length; i++) {
            _resellerFees[tokenId].push(fees[i]);
        }
    }

    modifier notPaused(uint256 _tokenId) {
        require(_isPaused[_tokenId] != true, "Cannot trade paused token");
        _;
    }

    function pauseToken(uint256 tokenId, bool isPausedFlag) public {
        require(_rootOperators[_msgSender()] == true, "Must be operator");
        _isPaused[tokenId] = isPausedFlag;
    }

    function lockFees(uint256 tokenId) public {
        require(
            _owners[tokenId] == _msgSender() ||
                _rootOperators[_msgSender()] == true,
            "Must be owner or operator"
        );
        _feesLock[tokenId] = true;
    }

    function getListing(uint256 tokenId, address seller)
        public
        view
        returns (Listing memory)
    {
        return _tokenListings[tokenId][seller];
    }

    function getCreatorFees(uint256 tokenId)
        public
        view
        returns (Fee[] memory)
    {
        return _creatorFees[tokenId];
    }

    function getResellerFees(uint256 tokenId)
        public
        view
        returns (Fee[] memory)
    {
        return _resellerFees[tokenId];
    }

    function setTokenPrice(
        uint256 _tokenId,
        uint256 price,
        bool biddingEnabled,
        uint256 numberOfDays
    ) public {
        require(
            _balances[_tokenId][_msgSender()] > 0,
            "Caller must own given token"
        );
        if (_tokenListings[_tokenId][_msgSender()].biddingEnabled) {
            require(
                _tokenListings[_tokenId][_msgSender()].currentBidder ==
                    payable(0),
                "Auction in progress"
            );
        }

        if (numberOfDays > 0) {
            _tokenListings[_tokenId][_msgSender()] = Listing(
                price,
                price,
                biddingEnabled,
                block.timestamp + (numberOfDays * 1 days), // active for x days from now
                payable(0),
                false
            );
        } else {
            _tokenListings[_tokenId][_msgSender()] = Listing(
                price,
                price,
                biddingEnabled,
                0, // active for unlimited time
                payable(0),
                false
            );
        }
    }

    function setTokenPriceOperator(
        address ownerAddr,
        uint256 _tokenId,
        uint256 price,
        bool biddingEnabled,
        uint256 numberOfDays
    ) public {
        require(_rootOperators[_msgSender()] == true, "Must be operator");
        require(
            _balances[_tokenId][ownerAddr] > 0,
            "Owner must own given token"
        );
        if (_tokenListings[_tokenId][ownerAddr].biddingEnabled) {
            require(
                _tokenListings[_tokenId][ownerAddr].currentBidder ==
                    payable(0),
                "Auction in progress"
            );
        }

        if (numberOfDays > 0) {
            _tokenListings[_tokenId][ownerAddr] = Listing(
                price,
                price,
                biddingEnabled,
                block.timestamp + (numberOfDays * 1 days), // active for x days from now
                payable(0),
                false
            );
        } else {
            _tokenListings[_tokenId][ownerAddr] = Listing(
                price,
                price,
                biddingEnabled,
                0, // active for unlimited time
                payable(0),
                false
            );
        }
    }

    function addMetaFileUrl(uint256 id, string memory url) public {
        require(
            _owners[id] == _msgSender() || _rootOperators[_msgSender()] == true,
            "Must be owner or operator"
        );
        require(bytes(_metaFileUrl[id]).length == 0, "File url already set");

        _metaFileUrl[id] = url;
    }

    function setSecretField(uint256 id, string memory secret) public {
        require(
            _owners[id] == _msgSender() || _rootOperators[_msgSender()] == true,
            "Must be owner or operator"
        );
        require(bytes(_secretFields[id]).length == 0, "Secret already set");

        _secretFields[id] = secret;
    }

    function getSecretField(uint256 id) public view returns (string memory) {
        require(_balances[id][_msgSender()] > 0, "Caller must own given token");

        return _secretFields[id];
    }

    function getMetaFileUrl(uint256 id) public view returns (string memory) {
        return _metaFileUrl[id];
    }

    function addProofChecksums(uint256 id, string[] memory checksums) public {
        require(
            _owners[id] == _msgSender() || _rootOperators[_msgSender()] == true,
            "Must be owner or operator"
        );

        for (uint256 i = 0; i < checksums.length; i++) {
            _proofChecksums[id].push(checksums[i]);
        }
    }

    function getChecksums(uint256 id) public view returns (string[] memory) {
        return _proofChecksums[id];
    }

    function allowRedeem(uint256 tokenId) public {
        require(
            _owners[tokenId] == _msgSender() || _rootOperators[_msgSender()] == true,
            "Must be owner or operator"
        );
        require(
            _redeemable[tokenId] == 0,
            "Redeem already allowed"
        );
        _redeemable[tokenId] = _balances[tokenId][_msgSender()];
    }

    function redeem(uint256 tokenId, address customerAddr) public {
        require(
            _owners[tokenId] == _msgSender() || _rootOperators[_msgSender()] == true,
            "Must be owner or operator"
        );
        require(
            _redeemed_by[tokenId].length < _redeemable[tokenId],
            "Token cannot be redeemed"
        );
        _redeemed_by[tokenId].push(customerAddr);
    }

     function redeemedBy(uint256 tokenId) public view returns (address[] memory) {
        require(
            _redeemable[tokenId] > 0,
            "Token cannot be redeemed"
        );

        return _redeemed_by[tokenId];
    }

    // Used as the URI for all token types by relying on ID substition, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /*
     *     bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
     *     bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
     *     bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
     *
     *     => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
     *        0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
     */
    bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;

    /*
     *     bytes4(keccak256('uri(uint256)')) == 0x0e89341c
     */
    bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;

    /**
     * @dev See {_setURI}.
     */
    event TokenUpgrade(uint256 oldId, uint256 newId);

    constructor(string memory tokenUri) {
        _setURI(tokenUri);

        // register the supported interfaces to conform to ERC1155 via ERC165
        _registerInterface(_INTERFACE_ID_ERC1155);

        // register the supported interfaces to conform to ERC1155MetadataURI via ERC165
        _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);

        _rootOperators[_msgSender()] = true;
    }

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substituion mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256 tokenId)
        external
        view
        override
        returns (string memory)
    {
        if(bytes(_metaFileUrl[tokenId]).length == 0) {
            return string(abi.encodePacked(_uri, Strings.uint2str(tokenId)));
        } else {
            return _metaFileUrl[tokenId];
        }
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id)
        public
        view
        override
        returns (uint256)
    {
        require(
            account != address(0),
            "ERC1155: balance query for the zero address"
        );
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        override
        returns (uint256[] memory)
    {
        require(
            accounts.length == ids.length,
            "ERC1155: accounts and ids length mismatch"
        );

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            require(
                accounts[i] != address(0),
                "ERC1155: batch balance query for the zero address"
            );
            batchBalances[i] = _balances[ids[i]][accounts[i]];
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        require(
            _msgSender() != operator,
            "ERC1155: setting approval status for self"
        );

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC1155-isApprovedForAll}.
     */
    function isApprovedForAll(address account, address operator)
        public
        view
        override
        returns (bool)
    {
        return _operatorApprovals[account][operator];
    }

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(to != address(0), "ERC1155: transfer to the zero address");
        require(
            _rootOperators[_msgSender()] == true,
            "Caller is not root operator"
        );

        address operator = _msgSender();

        _beforeTokenTransfer(
            operator,
            from,
            to,
            _asSingletonArray(id),
            _asSingletonArray(amount),
            data
        );

        _balances[id][from] = _balances[id][from].sub(
            amount,
            "ERC1155: insufficient balance for transfer"
        );
        _balances[id][to] = _balances[id][to].add(amount);

        emit TransferSingle(operator, from, to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount
    ) internal {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(
            operator,
            from,
            to,
            _asSingletonArray(id),
            _asSingletonArray(amount),
            "0x0"
        );

        _balances[id][from] = _balances[id][from].sub(
            amount,
            "ERC1155: insufficient balance for transfer"
        );
        _balances[id][to] = _balances[id][to].add(amount);

        emit TransferSingle(operator, from, to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, "0x0");
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            ids.length == amounts.length,
            "ERC1155: ids and amounts length mismatch"
        );
        require(to != address(0), "ERC1155: transfer to the zero address");
        require(
            _rootOperators[_msgSender()] == true,
            "Caller is not root operator"
        );

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];
            _balances[id][from] = _balances[id][from].sub(
                amount,
                "ERC1155: insufficient balance for transfer"
            );
            _balances[id][to] = _balances[id][to].add(amount);
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(
            operator,
            from,
            to,
            ids,
            amounts,
            data
        );
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substituion mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    function setURI(string memory newuri) internal virtual {
        require(_rootOperators[_msgSender()] == true, "Must be operator");
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function mint(
        address account,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public {
        require(account != address(0), "ERC1155: mint to the zero address");
        require(
            _owners[id] == address(0),
            "You are not allowed to mint given id"
        );

        address caller = _msgSender();

        _beforeTokenTransfer(
            caller,
            address(0),
            account,
            _asSingletonArray(id),
            _asSingletonArray(amount),
            data
        );

        _balances[id][account] = _balances[id][account].add(amount);
        _owners[id] = payable(caller);

        emit TransferSingle(caller, address(0), account, id, amount);

        _doSafeTransferAcceptanceCheck(
            caller,
            address(0),
            account,
            id,
            amount,
            data
        );
    }

    function mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public {
        require(
            _rootOperators[_msgSender()] == true,
            "Caller is not root operator"
        );
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
            _owners[ids[i]] = payable(to);
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `account`
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens of token type `id`.
     */
    function _burn(
        address account,
        uint256 id,
        uint256 amount
    ) internal virtual {
        require(account != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(
            operator,
            account,
            address(0),
            _asSingletonArray(id),
            _asSingletonArray(amount),
            ""
        );

        _balances[id][account] = _balances[id][account].sub(
            amount,
            "ERC1155: burn amount exceeds balance"
        );

        emit TransferSingle(operator, account, address(0), id, amount);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address account,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(account != address(0), "ERC1155: burn from the zero address");
        require(
            ids.length == amounts.length,
            "ERC1155: ids and amounts length mismatch"
        );

        address operator = _msgSender();

        _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][account] = _balances[ids[i]][account].sub(
                amounts[i],
                "ERC1155: burn amount exceeds balance"
            );
        }

        emit TransferBatch(operator, account, address(0), ids, amounts);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try
                IERC1155Receiver(to).onERC1155Received(
                    operator,
                    from,
                    id,
                    amount,
                    data
                )
            returns (bytes4 response) {
                if (
                    response != IERC1155Receiver(to).onERC1155Received.selector
                ) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try
                IERC1155Receiver(to).onERC1155BatchReceived(
                    operator,
                    from,
                    ids,
                    amounts,
                    data
                )
            returns (bytes4 response) {
                if (
                    response !=
                    IERC1155Receiver(to).onERC1155BatchReceived.selector
                ) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element)
        private
        pure
        returns (uint256[] memory)
    {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

File 3 of 15 : Auctionable.sol
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;
import "./Ownable.sol";
import "./Base.sol";

abstract contract Auctionable is Ownable, CreatorsHubBase {
    event Bid(
        address indexed _bidder,
        uint256 indexed _amount,
        uint256 indexed _tokenId
    );
    event AcceptBid(
        address indexed _bidder,
        address indexed _seller,
        uint256 _amount,
        uint256 indexed _tokenId
    );
    event CancelBid(
        address indexed _bidder,
        uint256 indexed _amount,
        uint256 indexed _tokenId
    );
    event Sold(
        address indexed _buyer,
        address indexed _seller,
        uint256 _amount,
        uint256 indexed _tokenId
    );

    function clearBid(uint256 _tokenId, address seller) private {
        _tokenListings[_tokenId][seller].currentBidder = payable(0);
        _tokenListings[_tokenId][seller].price = _tokenListings[_tokenId][
            seller
        ]
            .initialPrice;
        _tokenListings[_tokenId][seller].operatorBid = false;
    }

    function returnCurrentBid(uint256 _tokenId, address seller) private {
        uint256 currentBid = _tokenListings[_tokenId][seller].price;
        address payable currentBidder =
            _tokenListings[_tokenId][seller].currentBidder;
        if (
            currentBidder != address(0) &&
            !_tokenListings[_tokenId][seller].operatorBid
        ) {
            currentBidder.transfer(currentBid);
        }
    }

    function isGreaterBid(uint256 _tokenId, address seller)
        private
        view
        returns (bool)
    {
        return msg.value > _tokenListings[_tokenId][seller].price;
    }

    function bid(uint256 _tokenId, address seller)
        public
        payable
        notPaused(_tokenId)
    {
        require(
            _tokenListings[_tokenId][seller].biddingEnabled,
            "Must be auction"
        );
        require(seller != _msgSender(), "Seller cannot bid");
        require(isGreaterBid(_tokenId, seller), "Current bid is higher");
        if (_tokenListings[_tokenId][seller].activeTill != 0) {
            require(
                _tokenListings[_tokenId][seller].activeTill > block.timestamp,
                "Listing expired"
            );
        }
        returnCurrentBid(_tokenId, seller);
        _tokenListings[_tokenId][seller].currentBidder = payable(_msgSender());
        _tokenListings[_tokenId][seller].price = msg.value;
        _tokenListings[_tokenId][seller].operatorBid = false;
        emit Bid(_msgSender(), msg.value, _tokenId);
    }

    function operatorBid(
        uint256 _tokenId,
        address seller,
        uint256 price,
        address bidder
    ) public payable notPaused(_tokenId) {
        require(_rootOperators[_msgSender()] == true, "Must be operator");
        require(
            _tokenListings[_tokenId][seller].biddingEnabled,
            "Must be auction"
        );
        require(
            price > _tokenListings[_tokenId][seller].price,
            "Current bid is higher"
        );
        if (_tokenListings[_tokenId][seller].activeTill != 0) {
            require(
                _tokenListings[_tokenId][seller].activeTill > block.timestamp,
                "Listing expired"
            );
        }
        returnCurrentBid(_tokenId, seller);
        _tokenListings[_tokenId][seller].currentBidder = payable(bidder);
        _tokenListings[_tokenId][seller].price = price;
        _tokenListings[_tokenId][seller].operatorBid = true;
        emit Bid(bidder, price, _tokenId);
    }

    function operatorCancelBid(uint256 _tokenId, address seller)
        public
        payable
    {
        require(_rootOperators[_msgSender()] == true, "Must be operator");
        require(
            _tokenListings[_tokenId][seller].biddingEnabled,
            "Must be auction"
        );
        require(
            _tokenListings[_tokenId][seller].currentBidder != address(0),
            "No bid to cancel"
        );
        address payable bidder = _tokenListings[_tokenId][seller].currentBidder;
        uint256 bidAmount = _tokenListings[_tokenId][seller].price;
        returnCurrentBid(_tokenId, seller);
        clearBid(_tokenId, seller);
        emit CancelBid(bidder, bidAmount, _tokenId);
    }

    function acceptBid(uint256 _tokenId) public notPaused(_tokenId) {
        require(
            _tokenListings[_tokenId][_msgSender()].biddingEnabled,
            "Must be auction"
        );
        require(
            balanceOf(_msgSender(), _tokenId) > 0,
            "Seller does not own token anymore"
        );
        uint256 currentBid = _tokenListings[_tokenId][_msgSender()].price;
        address currentBidder =
            _tokenListings[_tokenId][_msgSender()].currentBidder;
        if (!_tokenListings[_tokenId][_msgSender()].operatorBid) {
            payout(_tokenId, _msgSender());
        }
        transferFrom(_msgSender(), currentBidder, _tokenId, 1);
        clearBid(_tokenId, _msgSender());
        emit AcceptBid(currentBidder, _msgSender(), currentBid, _tokenId);
    }

    function payout(uint256 _tokenId, address _seller) private {
        uint256 totalPrice = _tokenListings[_tokenId][_seller].price;
        uint256 allFees = 0;

        if (_seller == _owners[_tokenId]) {
            Fee[] memory fees = getCreatorFees(_tokenId);
            for (uint256 i = 0; i < fees.length; ++i) {
                if (fees[i].percentage) {
                    uint256 fee = (fees[i].value * totalPrice) / 10000;
                    allFees += fee;
                    fees[i].recipient.transfer(fee);
                } else {
                    allFees += fees[i].value;
                    fees[i].recipient.transfer(fees[i].value);
                }
            }
        } else {
            Fee[] memory fees = getResellerFees(_tokenId);
            for (uint256 i = 0; i < fees.length; ++i) {
                if (fees[i].percentage) {
                    uint256 fee = (fees[i].value * totalPrice) / 10000;
                    allFees += fee;
                    fees[i].recipient.transfer(fee);
                } else {
                    allFees += fees[i].value;
                    fees[i].recipient.transfer(fees[i].value);
                }
            }
        }
        payable(_seller).transfer(totalPrice - allFees);
    }

    function cancelBid(uint256 _tokenId, address seller) public {
        address payable bidder = _tokenListings[_tokenId][seller].currentBidder;
        require(
            _msgSender() == bidder || _msgSender() == seller,
            "You must be last bidder or owner"
        );
        uint256 bidAmount = _tokenListings[_tokenId][seller].price;
        returnCurrentBid(_tokenId, seller);
        clearBid(_tokenId, seller);
        emit CancelBid(bidder, bidAmount, _tokenId);
    }

    function buy(uint256 _tokenId, address seller)
        public
        payable
        notOwnerOf(_tokenId)
        notPaused(_tokenId)
    {
        uint256 salePrice = _tokenListings[_tokenId][seller].price;
        uint256 sentPrice = msg.value;
        address buyer = _msgSender();
        require(
            balanceOf(seller, _tokenId) > 0,
            "Seller does not own token anymore"
        );
        require(salePrice > 0, "Cannot buy this token");
        require(
            _tokenListings[_tokenId][seller].biddingEnabled == false,
            "Cannot buy, auction in progress"
        );
        require(sentPrice >= salePrice, "Insufficient value sent");
        if (_tokenListings[_tokenId][seller].activeTill != 0) {
            require(
                _tokenListings[_tokenId][seller].activeTill > block.timestamp,
                "Listing expired"
            );
        }
        payout(_tokenId, seller);
        clearBid(_tokenId, seller);
        transferFrom(seller, buyer, _tokenId, 1);
        emit Sold(buyer, seller, sentPrice, _tokenId);
    }
}

File 4 of 15 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 5 of 15 : IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;

import "../IERC1155.sol";

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

File 6 of 15 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 7 of 15 : ERC165Storage.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)

pragma solidity ^0.8.0;

import "./ERC165.sol";

/**
 * @dev Storage based implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165Storage is ERC165 {
    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

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

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

File 8 of 15 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

File 9 of 15 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 10 of 15 : EIP712MetaTransaction.sol
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./EIP712Base.sol";

contract EIP712MetaTransaction is EIP712Base {
    using SafeMath for uint256;
    bytes32 private constant META_TRANSACTION_TYPEHASH =
        keccak256(
            bytes(
                "MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
            )
        );

    event MetaTransactionExecuted(
        address userAddress,
        address payable relayerAddress,
        bytes functionSignature
    );
    mapping(address => uint256) nonces;

    /*
     * Meta transaction structure.
     * No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
     * He should call the desired function directly in that case.
     */
    struct MetaTransaction {
        uint256 nonce;
        address from;
        bytes functionSignature;
    }

    constructor(string memory name, string memory version)
        public
        EIP712Base(name, version)
    {}

    function executeMetaTransaction(
        address userAddress,
        bytes memory functionSignature,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) public payable returns (bytes memory) {
        MetaTransaction memory metaTx =
            MetaTransaction({
                nonce: nonces[userAddress],
                from: userAddress,
                functionSignature: functionSignature
            });
        require(
            verify(userAddress, metaTx, sigR, sigS, sigV),
            "Signer and signature do not match"
        );
        // Append userAddress and relayer address at the end to extract it from calling context
        (bool success, bytes memory returnData) =
            address(this).call(
                abi.encodePacked(functionSignature, userAddress)
            );

        require(success, "Function call not successfull");
        nonces[userAddress] = nonces[userAddress].add(1);
        emit MetaTransactionExecuted(
            userAddress,
            payable(msg.sender),
            functionSignature
        );
        return returnData;
    }

    function hashMetaTransaction(MetaTransaction memory metaTx)
        internal
        view
        returns (bytes32)
    {
        return
            keccak256(
                abi.encode(
                    META_TRANSACTION_TYPEHASH,
                    metaTx.nonce,
                    metaTx.from,
                    keccak256(metaTx.functionSignature)
                )
            );
    }

    function getNonce(address user) public view returns (uint256 nonce) {
        nonce = nonces[user];
    }

    function verify(
        address signer,
        MetaTransaction memory metaTx,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) internal view returns (bool) {
        return
            signer ==
            ecrecover(
                toTypedMessageHash(hashMetaTransaction(metaTx)),
                sigV,
                sigR,
                sigS
            );
    }

    function _msgSender() internal view returns (address payable sender) {
        if (msg.sender == address(this)) {
            bytes memory array = msg.data;
            uint256 index = msg.data.length;
            assembly {
                // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
                sender := and(
                    mload(add(array, index)),
                    0xffffffffffffffffffffffffffffffffffffffff
                )
            }
        } else {
            sender = payable(msg.sender);
        }
        return sender;
    }

    // To recieve ether in contract
    receive() external payable {}
}

File 11 of 15 : Ownable.sol
pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;

abstract contract Ownable {
    mapping(uint256 => address payable) internal _owners;

    function msgSender() private view returns (address payable sender) {
        if (msg.sender == address(this)) {
            bytes memory array = msg.data;
            uint256 index = msg.data.length;
            assembly {
                // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
                sender := and(
                    mload(add(array, index)),
                    0xffffffffffffffffffffffffffffffffffffffff
                )
            }
        } else {
            sender = payable(msg.sender);
        }
        return sender;
    }

    modifier notOwnerOf(uint256 _tokenId) {
        require(creatorOf(_tokenId) != msgSender());
        _;
    }

    modifier onlyOwnerOf(uint256 _tokenId) {
        require(creatorOf(_tokenId) == msgSender());
        _;
    }

    function creatorOf(uint256 _tokenId) public view returns (address payable) {
        address payable owner = _owners[_tokenId];
        require(owner != address(0));
        return owner;
    }
}

File 12 of 15 : Strings.sol
pragma solidity ^0.8.0;

library Strings {
    function uint2str(uint256 _i)
        internal
        pure
        returns (string memory _uintAsString)
    {
        if (_i == 0) {
            return "0";
        }
        uint256 j = _i;
        uint256 len;
        while (j != 0) {
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint256 k = len;
        while (_i != 0) {
            k = k - 1;
            uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
            bytes1 b1 = bytes1(temp);
            bstr[k] = b1;
            _i /= 10;
        }
        return string(bstr);
    }
}

File 13 of 15 : 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 14 of 15 : 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;
    }
}

File 15 of 15 : EIP712Base.sol
pragma solidity ^0.8.0;

contract EIP712Base {
    struct EIP712Domain {
        string name;
        string version;
        uint256 chainId;
        address verifyingContract;
    }

    bytes32 internal constant EIP712_DOMAIN_TYPEHASH =
        keccak256(
            bytes(
                "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
            )
        );

    bytes32 internal domainSeperator;

    constructor(string memory name, string memory version) public {
        domainSeperator = keccak256(
            abi.encode(
                EIP712_DOMAIN_TYPEHASH,
                keccak256(bytes(name)),
                keccak256(bytes(version)),
                getChainID(),
                address(this)
            )
        );
    }

    function getChainID() internal view returns (uint256 id) {
        assembly {
            id := chainid()
        }
    }

    function getDomainSeperator() private view returns (bytes32) {
        return domainSeperator;
    }

    /**
     * Accept message hash and returns hash message in EIP712 compatible form
     * So that it can be used to recover signer from signature signed using EIP712 formatted data
     * https://eips.ethereum.org/EIPS/eip-712
     * "\\x19" makes the encoding deterministic
     * "\\x01" is the version byte to make it compatible to EIP-191
     */
    function toTypedMessageHash(bytes32 messageHash)
        internal
        view
        returns (bytes32)
    {
        return
            keccak256(
                abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash)
            );
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_bidder","type":"address"},{"indexed":true,"internalType":"address","name":"_seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"AcceptBid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_bidder","type":"address"},{"indexed":true,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Bid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_bidder","type":"address"},{"indexed":true,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"CancelBid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address payable","name":"relayerAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_buyer","type":"address"},{"indexed":true,"internalType":"address","name":"_seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Sold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newId","type":"uint256"}],"name":"TokenUpgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"acceptBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bool","name":"percentage","type":"bool"}],"internalType":"struct CreatorsHubBase.Fee[]","name":"fees","type":"tuple[]"}],"name":"addCreatorFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"url","type":"string"}],"name":"addMetaFileUrl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string[]","name":"checksums","type":"string[]"}],"name":"addProofChecksums","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bool","name":"percentage","type":"bool"}],"internalType":"struct CreatorsHubBase.Fee[]","name":"fees","type":"tuple[]"}],"name":"addResellerFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"allowRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"}],"name":"bid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"}],"name":"cancelBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"creatorOf","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes","name":"functionSignature","type":"bytes"},{"internalType":"bytes32","name":"sigR","type":"bytes32"},{"internalType":"bytes32","name":"sigS","type":"bytes32"},{"internalType":"uint8","name":"sigV","type":"uint8"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getChecksums","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCreatorFees","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bool","name":"percentage","type":"bool"}],"internalType":"struct CreatorsHubBase.Fee[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"}],"name":"getListing","outputs":[{"components":[{"internalType":"uint256","name":"initialPrice","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bool","name":"biddingEnabled","type":"bool"},{"internalType":"uint256","name":"activeTill","type":"uint256"},{"internalType":"address payable","name":"currentBidder","type":"address"},{"internalType":"bool","name":"operatorBid","type":"bool"}],"internalType":"struct CreatorsHubBase.Listing","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getMetaFileUrl","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getResellerFees","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bool","name":"percentage","type":"bool"}],"internalType":"struct CreatorsHubBase.Fee[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getSecretField","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"lockFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"bidder","type":"address"}],"name":"operatorBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"seller","type":"address"}],"name":"operatorCancelBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"isPausedFlag","type":"bool"}],"name":"pauseToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"customerAddr","type":"address"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"redeemedBy","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"secret","type":"string"}],"name":"setSecretField","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bool","name":"biddingEnabled","type":"bool"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"setTokenPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"ownerAddr","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bool","name":"biddingEnabled","type":"bool"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"setTokenPriceOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b506040518060600160405280603681526020016200593d60369139604051806040016040528060078152602001664552433131353560c81b815250604051806040016040528060018152602001603160f81b815250818160405180608001604052806052815260200162005973605291398051906020012082805190602001208280519060200120620000a96200015d60201b60201c565b604080516020810195909552840192909252606083015260808201523060a082015260c00160408051601f19818403018152919052805160209091012060015550620000fa92508391505062000161565b6200010c636cdb3d1360e11b6200017a565b6200011e6303a24d0760e21b6200017a565b6001600760006200012e620001fe565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790555062000340565b4690565b8051620001769060129060208401906200025d565b5050565b6001600160e01b03198082161415620001d95760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b6000333014156200025757600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031691506200025a9050565b50335b90565b8280546200026b9062000303565b90600052602060002090601f0160209004810192826200028f5760008555620002da565b82601f10620002aa57805160ff1916838001178555620002da565b82800160010185558215620002da579182015b82811115620002da578251825591602001919060010190620002bd565b50620002e8929150620002ec565b5090565b5b80821115620002e85760008155600101620002ed565b600181811c908216806200031857607f821691505b602082108114156200033a57634e487b7160e01b600052602260045260246000fd5b50919050565b6155ed80620003506000396000f3fe60806040526004361061021d5760003560e01c8063731133e911610123578063a22cb465116100ab578063cbd21f591161006f578063cbd21f5914610785578063d66675ed14610798578063dcee692b146107b8578063e985e9c5146107d8578063f242432a1461082157600080fd5b8063a22cb465146106cb578063b901fd87146106eb578063c1b362671461070b578063c7d7203514610738578063cb462a4b1461076557600080fd5b80637bde82f2116100f25780637bde82f2146105495780637deb602514610569578063935b74c81461057c5780639a8a2f78146106985780639f04996d146106b857600080fd5b8063731133e9146104c9578063744561ac146104e95780637463688514610509578063781a1d1b1461052957600080fd5b80632eb2c2d6116101a65780634e1273f4116101755780634e1273f414610404578063589a17431461043157806359d79c911461046957806361ab63d6146104895780636d3b493d146104a957600080fd5b80632eb2c2d614610391578063314a9767146103b1578063474c819e146103d15780634c23a525146103f157600080fd5b80631f7fdffa116101ed5780631f7fdffa146102cc578063242b83f5146102ee57806325ee6ee91461030e5780632b1fd58a1461033b5780632d0335ab1461035b57600080fd5b8062fdd58e1461022957806301ffc9a71461025c5780630c53c51c1461028c5780630e89341c146102ac57600080fd5b3661022457005b600080fd5b34801561023557600080fd5b50610249610244366004614768565b610841565b6040519081526020015b60405180910390f35b34801561026857600080fd5b5061027c610277366004614902565b6108da565b6040519015158152602001610253565b61029f61029a3660046146ee565b61091a565b6040516102539190614ff4565b3480156102b857600080fd5b5061029f6102c736600461493a565b610b04565b3480156102d857600080fd5b506102ec6102e7366004614624565b610bfe565b005b3480156102fa57600080fd5b506102ec610309366004614793565b610e23565b34801561031a57600080fd5b5061032e61032936600461493a565b6110f0565b6040516102539190614f27565b34801561034757600080fd5b506102ec61035636600461493a565b611226565b34801561036757600080fd5b506102496103763660046144c1565b6001600160a01b031660009081526002602052604090205490565b34801561039d57600080fd5b506102ec6103ac366004614515565b611432565b3480156103bd57600080fd5b506102ec6103cc366004614bb9565b611673565b3480156103dd57600080fd5b506102ec6103ec366004614bb9565b61176a565b6102ec6103ff366004614976565b61185e565b34801561041057600080fd5b5061042461041f366004614836565b611a84565b6040516102539190614fbc565b34801561043d57600080fd5b5061045161044c36600461493a565b611cb6565b6040516001600160a01b039091168152602001610253565b34801561047557600080fd5b506102ec610484366004614bf3565b611cd8565b34801561049557600080fd5b506102ec6104a4366004614952565b611fce565b3480156104b557600080fd5b506102ec6104c436600461493a565b6120f0565b3480156104d557600080fd5b506102ec6104e43660046147e2565b6121fe565b3480156104f557600080fd5b5061029f61050436600461493a565b612375565b34801561051557600080fd5b506102ec610524366004614a83565b612417565b34801561053557600080fd5b506102ec6105443660046149bf565b61267b565b34801561055557600080fd5b506102ec610564366004614952565b612772565b6102ec610577366004614952565b61288a565b34801561058857600080fd5b50610644610597366004614952565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525060009182526011602090815260408084206001600160a01b039384168552825292839020835160c08101855281548152600182015492810192909252600281015460ff90811615159483019490945260038101546060830152600401549182166080820152600160a01b909104909116151560a082015290565b60405161025391908151815260208083015190820152604080830151151590820152606080830151908201526080808301516001600160a01b03169082015260a09182015115159181019190915260c00190565b3480156106a457600080fd5b506102ec6106b3366004614b97565b612b40565b6102ec6106c6366004614952565b612baa565b3480156106d757600080fd5b506102ec6106e63660046146ba565b612df9565b3480156106f757600080fd5b506102ec610706366004614a83565b612f0d565b34801561071757600080fd5b5061072b61072636600461493a565b6130a2565b6040516102539190614ec6565b34801561074457600080fd5b5061075861075336600461493a565b613183565b6040516102539190614e79565b34801561077157600080fd5b506102ec61078036600461493a565b613245565b6102ec610793366004614952565b6132d6565b3480156107a457600080fd5b5061032e6107b336600461493a565b613407565b3480156107c457600080fd5b5061029f6107d336600461493a565b613532565b3480156107e457600080fd5b5061027c6107f33660046144dd565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561082d57600080fd5b506102ec61083c3660046145be565b61354f565b60006001600160a01b0383166108b25760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b60648201526084015b60405180910390fd5b5060009081526004602090815260408083206001600160a01b03949094168352929052205490565b60006301ffc9a760e01b6001600160e01b03198316148061091457506001600160e01b0319821660009081526020819052604090205460ff165b92915050565b60408051606081810183526001600160a01b0388166000818152600260209081529085902054845283015291810186905261095887828787876136cd565b6109ae5760405162461bcd60e51b815260206004820152602160248201527f5369676e657220616e64207369676e617475726520646f206e6f74206d6174636044820152600d60fb1b60648201526084016108a9565b600080306001600160a01b0316888a6040516020016109ce929190614ccd565b60408051601f19818403018152908290526109e891614cb1565b6000604051808303816000865af19150503d8060008114610a25576040519150601f19603f3d011682016040523d82523d6000602084013e610a2a565b606091505b509150915081610a7c5760405162461bcd60e51b815260206004820152601d60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c6c00000060448201526064016108a9565b6001600160a01b038916600090815260026020526040902054610aa0906001613759565b6001600160a01b038a166000908152600260205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b90610af0908b9033908c90614daa565b60405180910390a198975050505050505050565b6000818152600860205260409020805460609190610b21906153a9565b15159050610b5b576012610b348361376c565b604051602001610b45929190614d04565b6040516020818303038152906040529050919050565b60008281526008602052604090208054610b74906153a9565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba0906153a9565b8015610bed5780601f10610bc257610100808354040283529160200191610bed565b820191906000526020600020905b815481529060010190602001808311610bd057829003601f168201915b50505050509050919050565b919050565b60076000610c0a6138b0565b6001600160a01b0316815260208101919091526040016000205460ff161515600114610c485760405162461bcd60e51b81526004016108a9906150b0565b6001600160a01b038416610c6e5760405162461bcd60e51b81526004016108a990615286565b8151835114610c8f5760405162461bcd60e51b81526004016108a990615215565b6000610c996138b0565b905060005b8451811015610db457838181518110610cc757634e487b7160e01b600052603260045260246000fd5b602002602001015160046000878481518110610cf357634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254610d3b91906152ea565b925050819055508560036000878481518110610d6757634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080610dac90615435565b915050610c9e565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610e05929190614fcf565b60405180910390a4610e1c8160008787878761390d565b5050505050565b60076000610e2f6138b0565b6001600160a01b0316815260208101919091526040016000205460ff161515600114610e6d5760405162461bcd60e51b81526004016108a99061504f565b60008481526004602090815260408083206001600160a01b0389168452909152902054610edc5760405162461bcd60e51b815260206004820152601a60248201527f4f776e6572206d757374206f776e20676976656e20746f6b656e00000000000060448201526064016108a9565b60008481526011602090815260408083206001600160a01b038916845290915290206002015460ff1615610f755760008481526011602090815260408083206001600160a01b0389811685529252909120600401541615610f755760405162461bcd60e51b815260206004820152601360248201527241756374696f6e20696e2070726f677265737360681b60448201526064016108a9565b801561104d576040518060c0016040528084815260200184815260200183151581526020018262015180610fa99190615347565b610fb390426152ea565b8152600060208083018290526040928301829052878252601181528282206001600160a01b038a8116845290825291839020845181559084015160018201559183015160028301805460ff19169115159190911790556060830151600383015560808301516004909201805460a090940151929091166001600160a81b031990931692909217600160a01b91151591909102179055610e1c565b506040805160c08101825283815260208082019485529215158183019081526000606083018181526080840182815260a08501838152988352601187528583206001600160a01b039a8b1684529096529390209151825593516001820155925160028401805491151560ff19909216919091179055516003830155516004909101805492511515600160a01b026001600160a81b03199093169190931617179055565b6060600f6000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561121b5783829060005260206000209060040201604051806080016040529081600082018054611158906153a9565b80601f0160208091040260200160405190810160405280929190818152602001828054611184906153a9565b80156111d15780601f106111a6576101008083540402835291602001916111d1565b820191906000526020600020905b8154815290600101906020018083116111b457829003601f168201915b50505091835250506001828101546001600160a01b03166020808401919091526002840154604084015260039093015460ff16151560609092019190915291835292019101611125565b505050509050919050565b6000818152600c6020526040902054819060ff1615156001141561125c5760405162461bcd60e51b81526004016108a990615079565b6000828152601160205260408120906112736138b0565b6001600160a01b0316815260208101919091526040016000206002015460ff166112af5760405162461bcd60e51b81526004016108a9906151ab565b60006112c26112bc6138b0565b84610841565b116112df5760405162461bcd60e51b81526004016108a9906151d4565b6000828152601160205260408120816112f66138b0565b6001600160a01b03166001600160a01b03168152602001908152602001600020600101549050600060116000858152602001908152602001600020600061133b6138b0565b6001600160a01b03908116825260208083019390935260409182016000908120600401548882526011909452918220921692506113766138b0565b6001600160a01b03168152602081019190915260400160002060040154600160a01b900460ff166113b2576113b2846113ad6138b0565b613a81565b6113c66113bd6138b0565b82866001613ed1565b6113d7846113d26138b0565b61404d565b836113e06138b0565b6001600160a01b0316826001600160a01b03167fd6deddb2e105b46d4644d24aac8c58493a0f107e7973b2fe8d8fa7931a2912be8560405161142491815260200190565b60405180910390a450505050565b81518351146114535760405162461bcd60e51b81526004016108a990615215565b6001600160a01b0384166114795760405162461bcd60e51b81526004016108a99061512f565b600760006114856138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001146114c35760405162461bcd60e51b81526004016108a9906150b0565b60006114cd6138b0565b905060005b84518110156116055760008582815181106114fd57634e487b7160e01b600052603260045260246000fd5b60200260200101519050600085838151811061152957634e487b7160e01b600052603260045260246000fd5b60200260200101519050611596816040518060600160405280602a815260200161558e602a91396004600086815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020546140929092919063ffffffff16565b60008381526004602090815260408083206001600160a01b038e811685529252808320939093558a16815220546115cd9082613759565b60009283526004602090815260408085206001600160a01b038c16865290915290922091909155506115fe81615435565b90506114d2565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611655929190614fcf565b60405180910390a461166b81878787878761390d565b505050505050565b61167b6138b0565b6000838152600360205260409020546001600160a01b03908116911614806116cd5750600760006116aa6138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6116e95760405162461bcd60e51b81526004016108a990615174565b6000828152600a602052604090208054611702906153a9565b1590506117465760405162461bcd60e51b815260206004820152601260248201527114d958dc995d08185b1c9958591e481cd95d60721b60448201526064016108a9565b6000828152600a60209081526040909120825161176592840190614336565b505050565b6117726138b0565b6000838152600360205260409020546001600160a01b03908116911614806117c45750600760006117a16138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6117e05760405162461bcd60e51b81526004016108a990615174565b600082815260086020526040902080546117f9906153a9565b15905061183f5760405162461bcd60e51b8152602060048201526014602482015273119a5b19481d5c9b08185b1c9958591e481cd95d60621b60448201526064016108a9565b6000828152600860209081526040909120825161176592840190614336565b6000848152600c6020526040902054849060ff161515600114156118945760405162461bcd60e51b81526004016108a990615079565b600760006118a06138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001146118de5760405162461bcd60e51b81526004016108a99061504f565b60008581526011602090815260408083206001600160a01b038816845290915290206002015460ff166119235760405162461bcd60e51b81526004016108a9906151ab565b60008581526011602090815260408083206001600160a01b0388168452909152902060010154831161198f5760405162461bcd60e51b815260206004820152601560248201527421bab93932b73a103134b21034b9903434b3b432b960591b60448201526064016108a9565b60008581526011602090815260408083206001600160a01b0388168452909152902060030154156119fe5760008581526011602090815260408083206001600160a01b038816845290915290206003015442106119fe5760405162461bcd60e51b81526004016108a99061525d565b611a0885856140be565b60008581526011602090815260408083206001600160a01b038881168552925280832060048101805460019092018890556001600160a81b0319909116928616928317600160a01b1790555187928692917f19421268847f42dd61705778018ddfc43bcdce8517e7a630acb12f122c7094819190a45050505050565b60608151835114611ae95760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016108a9565b600083516001600160401b03811115611b1257634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611b3b578160200160208202803683370190505b50905060005b8451811015611cae5760006001600160a01b0316858281518110611b7557634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415611bee5760405162461bcd60e51b815260206004820152603160248201527f455243313135353a2062617463682062616c616e636520717565727920666f7260448201527020746865207a65726f206164647265737360781b60648201526084016108a9565b60046000858381518110611c1257634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000868381518110611c4a57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110611c9357634e487b7160e01b600052603260045260246000fd5b6020908102919091010152611ca781615435565b9050611b41565b509392505050565b6000818152600360205260408120546001600160a01b03168061091457600080fd5b600084815260046020526040812081611cef6138b0565b6001600160a01b03166001600160a01b031681526020019081526020016000205411611d5d5760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206d757374206f776e20676976656e20746f6b656e000000000060448201526064016108a9565b600084815260116020526040812090611d746138b0565b6001600160a01b0316815260208101919091526040016000206002015460ff1615611e1357600084815260116020526040812081611db06138b0565b6001600160a01b0390811682526020820192909252604001600020600401541614611e135760405162461bcd60e51b815260206004820152601360248201527241756374696f6e20696e2070726f677265737360681b60448201526064016108a9565b8015611efe576040518060c0016040528084815260200184815260200183151581526020018262015180611e479190615347565b611e5190426152ea565b81526000602080830182905260409283018290528782526011905290812090611e786138b0565b6001600160a01b0390811682526020808301939093526040918201600020845181559284015160018401559083015160028301805460ff19169115159190911790556060830151600383015560808301516004909201805460a090940151929091166001600160a81b031990931692909217600160a01b91151591909102179055611fc8565b6040805160c0810182528481526020808201869052841515828401526000606083018190526080830181905260a0830181905287815260119091529182209091611f466138b0565b6001600160a01b0390811682526020808301939093526040918201600020845181559284015160018401559083015160028301805460ff19169115159190911790556060830151600383015560808301516004909201805460a090940151929091166001600160a81b031990931692909217600160a01b911515919091021790555b50505050565b60008281526011602090815260408083206001600160a01b0380861685529252909120600401541680611fff6138b0565b6001600160a01b0316148061202c5750816001600160a01b03166120216138b0565b6001600160a01b0316145b6120785760405162461bcd60e51b815260206004820181905260248201527f596f75206d757374206265206c61737420626964646572206f72206f776e657260448201526064016108a9565b60008381526011602090815260408083206001600160a01b03861684529091529020600101546120a884846140be565b6120b2848461404d565b8381836001600160a01b03167f09dcebe16a733e22cc47e4959c50d4f21624d9f1815db32c2e439fbbd7b3eda060405160405180910390a450505050565b6120f86138b0565b6000828152600360205260409020546001600160a01b039081169116148061214a5750600760006121276138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6121665760405162461bcd60e51b81526004016108a990615174565b6000818152600d6020526040902054156121bb5760405162461bcd60e51b815260206004820152601660248201527514995919595b48185b1c9958591e48185b1b1bddd95960521b60448201526064016108a9565b6000818152600460205260408120906121d26138b0565b6001600160a01b031681526020808201929092526040908101600090812054938152600d909252902055565b6001600160a01b0384166122245760405162461bcd60e51b81526004016108a990615286565b6000838152600360205260409020546001600160a01b0316156122955760405162461bcd60e51b8152602060048201526024808201527f596f7520617265206e6f7420616c6c6f77656420746f206d696e7420676976656044820152631b881a5960e21b60648201526084016108a9565b600061229f6138b0565b90506122ba816000876122b188614166565b610e1c88614166565b60008481526004602090815260408083206001600160a01b03891684529091529020546122e79084613759565b60008581526004602090815260408083206001600160a01b038a8116808652918452828520959095558884526003835281842080546001600160a01b0319169587169586179055815189815292830188905293917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610e1c816000878787876141bf565b600081815260046020526040812060609190816123906138b0565b6001600160a01b03166001600160a01b0316815260200190815260200160002054116123fe5760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206d757374206f776e20676976656e20746f6b656e000000000060448201526064016108a9565b6000828152600a602052604090208054610b74906153a9565b6000828152600b602052604090205460ff16156124645760405162461bcd60e51b815260206004820152600b60248201526a1199595cc81b1bd8dad95960aa1b60448201526064016108a9565b61246c6138b0565b6000838152600360205260409020546001600160a01b03908116911614806124be57506007600061249b6138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6124da5760405162461bcd60e51b81526004016108a990615174565b60005b81518110156117655781818151811061250657634e487b7160e01b600052603260045260246000fd5b60200260200101516060015115156001151514156125b55761271082828151811061254157634e487b7160e01b600052603260045260246000fd5b6020026020010151604001511061256a5760405162461bcd60e51b81526004016108a9906150e7565b600082828151811061258c57634e487b7160e01b600052603260045260246000fd5b602002602001015160400151116125b55760405162461bcd60e51b81526004016108a9906150e7565b6000838152600f6020526040902082518390839081106125e557634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182546001810184556000938452928290208151805192946004029091019261261e92849290910190614336565b5060208201516001820180546001600160a01b0319166001600160a01b03909216919091179055604082015160028201556060909101516003909101805460ff19169115159190911790558061267381615435565b9150506124dd565b6126836138b0565b6000838152600360205260409020546001600160a01b03908116911614806126d55750600760006126b26138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6126f15760405162461bcd60e51b81526004016108a990615174565b60005b8151811015611765576000838152600960205260409020825183908390811061272d57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518254600181018455600093845292829020815161275f9491909101929190910190614336565b508061276a81615435565b9150506126f4565b61277a6138b0565b6000838152600360205260409020546001600160a01b03908116911614806127cc5750600760006127a96138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6127e85760405162461bcd60e51b81526004016108a990615174565b6000828152600d6020908152604080832054600e909252909120541061284b5760405162461bcd60e51b8152602060048201526018602482015277151bdad95b8818d85b9b9bdd081899481c995919595b595960421b60448201526064016108a9565b6000918252600e6020908152604083208054600181018255908452922090910180546001600160a01b0319166001600160a01b03909216919091179055565b816128936138b0565b6001600160a01b03166128a582611cb6565b6001600160a01b031614156128b957600080fd5b6000838152600c6020526040902054839060ff161515600114156128ef5760405162461bcd60e51b81526004016108a990615079565b60008481526011602090815260408083206001600160a01b03871684529091528120600101549034906129206138b0565b9050600061292e8789610841565b1161294b5760405162461bcd60e51b81526004016108a9906151d4565b600083116129935760405162461bcd60e51b815260206004820152601560248201527421b0b73737ba10313abc903a3434b9903a37b5b2b760591b60448201526064016108a9565b60008781526011602090815260408083206001600160a01b038a16845290915290206002015460ff1615612a095760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74206275792c2061756374696f6e20696e2070726f67726573730060448201526064016108a9565b82821015612a595760405162461bcd60e51b815260206004820152601760248201527f496e73756666696369656e742076616c75652073656e7400000000000000000060448201526064016108a9565b60008781526011602090815260408083206001600160a01b038a16845290915290206003015415612ac85760008781526011602090815260408083206001600160a01b038a1684529091529020600301544210612ac85760405162461bcd60e51b81526004016108a99061525d565b612ad28787613a81565b612adc878761404d565b612ae98682896001613ed1565b86866001600160a01b0316826001600160a01b03167f16dd16959a056953a63cf14bf427881e762e54f03d86b864efea8238dd3b822f85604051612b2f91815260200190565b60405180910390a450505050505050565b60076000612b4c6138b0565b6001600160a01b0316815260208101919091526040016000205460ff161515600114612b8a5760405162461bcd60e51b81526004016108a99061504f565b6000918252600c6020526040909120805460ff1916911515919091179055565b6000828152600c6020526040902054829060ff16151560011415612be05760405162461bcd60e51b81526004016108a990615079565b60008381526011602090815260408083206001600160a01b038616845290915290206002015460ff16612c255760405162461bcd60e51b81526004016108a9906151ab565b612c2d6138b0565b6001600160a01b0316826001600160a01b03161415612c825760405162461bcd60e51b815260206004820152601160248201527014d95b1b195c8818d85b9b9bdd08189a59607a1b60448201526064016108a9565b60008381526011602090815260408083206001600160a01b03861684529091529020600101543411612cee5760405162461bcd60e51b815260206004820152601560248201527421bab93932b73a103134b21034b9903434b3b432b960591b60448201526064016108a9565b60008381526011602090815260408083206001600160a01b038616845290915290206003015415612d5d5760008381526011602090815260408083206001600160a01b03861684529091529020600301544210612d5d5760405162461bcd60e51b81526004016108a99061525d565b612d6783836140be565b612d6f6138b0565b60008481526011602090815260408083206001600160a01b03878116855292529091206004810180543460019093018390556001600160a81b031916939092169290921790558390612dbf6138b0565b6001600160a01b03167f19421268847f42dd61705778018ddfc43bcdce8517e7a630acb12f122c70948160405160405180910390a4505050565b816001600160a01b0316612e0b6138b0565b6001600160a01b03161415612e745760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016108a9565b8060056000612e816138b0565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155612ec56138b0565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612f01911515815260200190565b60405180910390a35050565b6000828152600b602052604090205460ff1615612f5a5760405162461bcd60e51b815260206004820152600b60248201526a1199595cc81b1bd8dad95960aa1b60448201526064016108a9565b612f626138b0565b6000838152600360205260409020546001600160a01b0390811691161480612fb4575060076000612f916138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b612fd05760405162461bcd60e51b81526004016108a990615174565b60005b8151811015611765576000838152601060205260409020825183908390811061300c57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182546001810184556000938452928290208151805192946004029091019261304592849290910190614336565b5060208201516001820180546001600160a01b0319166001600160a01b03909216919091179055604082015160028201556060909101516003909101805460ff19169115159190911790558061309a81615435565b915050612fd3565b606060096000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561121b5783829060005260206000200180546130f6906153a9565b80601f0160208091040260200160405190810160405280929190818152602001828054613122906153a9565b801561316f5780601f106131445761010080835404028352916020019161316f565b820191906000526020600020905b81548152906001019060200180831161315257829003601f168201915b5050505050815260200190600101906130d7565b6000818152600d60205260409020546060906131dc5760405162461bcd60e51b8152602060048201526018602482015277151bdad95b8818d85b9b9bdd081899481c995919595b595960421b60448201526064016108a9565b6000828152600e602090815260409182902080548351818402810184019094528084529091830182828015610bed57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161321c5750505050509050919050565b61324d6138b0565b6000828152600360205260409020546001600160a01b039081169116148061329f57506007600061327c6138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6132bb5760405162461bcd60e51b81526004016108a990615174565b6000908152600b60205260409020805460ff19166001179055565b600760006132e26138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001146133205760405162461bcd60e51b81526004016108a99061504f565b60008281526011602090815260408083206001600160a01b038516845290915290206002015460ff166133655760405162461bcd60e51b81526004016108a9906151ab565b60008281526011602090815260408083206001600160a01b038581168552925290912060040154166133cc5760405162461bcd60e51b815260206004820152601060248201526f139bc8189a59081d1bc818d85b98d95b60821b60448201526064016108a9565b60008281526011602090815260408083206001600160a01b038581168552925290912060048101546001909101549116906120a884846140be565b606060106000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561121b578382906000526020600020906004020160405180608001604052908160008201805461346f906153a9565b80601f016020809104026020016040519081016040528092919081815260200182805461349b906153a9565b80156134e85780601f106134bd576101008083540402835291602001916134e8565b820191906000526020600020905b8154815290600101906020018083116134cb57829003601f168201915b50505091835250506001828101546001600160a01b03166020808401919091526002840154604084015260039093015460ff1615156060909201919091529183529201910161343c565b6000818152600860205260409020805460609190610b74906153a9565b6001600160a01b0384166135755760405162461bcd60e51b81526004016108a99061512f565b600760006135816138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001146135bf5760405162461bcd60e51b81526004016108a9906150b0565b60006135c96138b0565b90506135da8187876122b188614166565b613621836040518060600160405280602a815260200161558e602a913960008781526004602090815260408083206001600160a01b038d1684529091529020549190614092565b60008581526004602090815260408083206001600160a01b038b811685529252808320939093558716815220546136589084613759565b60008581526004602090815260408083206001600160a01b038a811680865291845293829020949094558051888152918201879052898316928516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461166b8187878787876141bf565b600060016136e26136dd87614289565b614306565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015613730573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b600061376582846152ea565b9392505050565b6060816137905750506040805180820190915260018152600360fc1b602082015290565b8160005b81156137ba57806137a481615435565b91506137b39050600a83615327565b9150613794565b6000816001600160401b038111156137e257634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561380c576020820181803683370190505b509050815b85156138a757613822600182615366565b90506000613831600a88615327565b61383c90600a615347565b6138469088615366565b613851906030615302565b905060008160f81b90508084848151811061387c57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061389e600a89615327565b97505050613811565b50949350505050565b60003330141561390757600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b0316915061390a9050565b50335b90565b6001600160a01b0384163b1561166b5760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906139519089908990889088908890600401614dd6565b602060405180830381600087803b15801561396b57600080fd5b505af192505050801561399b575060408051601f3d908101601f191682019092526139989181019061491e565b60015b613a48576139a761547c565b806308c379a014156139e157506139bc615493565b806139c757506139e3565b8060405162461bcd60e51b81526004016108a99190614ff4565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016108a9565b6001600160e01b0319811663bc197c8160e01b14613a785760405162461bcd60e51b81526004016108a990615007565b50505050505050565b60008281526011602090815260408083206001600160a01b03808616808652918452828520600101548786526003909452918420549293929091161415613cac576000613acd856110f0565b905060005b8151811015613ca557818181518110613afb57634e487b7160e01b600052603260045260246000fd5b60200260200101516060015115613bcb57600061271085848481518110613b3257634e487b7160e01b600052603260045260246000fd5b602002602001015160400151613b489190615347565b613b529190615327565b9050613b5e81856152ea565b9350828281518110613b8057634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015613bc4573d6000803e3d6000fd5b5050613c95565b818181518110613beb57634e487b7160e01b600052603260045260246000fd5b60200260200101516040015183613c0291906152ea565b9250818181518110613c2457634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166108fc838381518110613c5c57634e487b7160e01b600052603260045260246000fd5b6020026020010151604001519081150290604051600060405180830381858888f19350505050158015613c93573d6000803e3d6000fd5b505b613c9e81615435565b9050613ad2565b5050613e92565b6000613cb785613407565b905060005b8151811015613e8f57818181518110613ce557634e487b7160e01b600052603260045260246000fd5b60200260200101516060015115613db557600061271085848481518110613d1c57634e487b7160e01b600052603260045260246000fd5b602002602001015160400151613d329190615347565b613d3c9190615327565b9050613d4881856152ea565b9350828281518110613d6a57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015613dae573d6000803e3d6000fd5b5050613e7f565b818181518110613dd557634e487b7160e01b600052603260045260246000fd5b60200260200101516040015183613dec91906152ea565b9250818181518110613e0e57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166108fc838381518110613e4657634e487b7160e01b600052603260045260246000fd5b6020026020010151604001519081150290604051600060405180830381858888f19350505050158015613e7d573d6000803e3d6000fd5b505b613e8881615435565b9050613cbc565b50505b6001600160a01b0383166108fc613ea98385615366565b6040518115909202916000818181858888f19350505050158015610e1c573d6000803e3d6000fd5b6001600160a01b038316613ef75760405162461bcd60e51b81526004016108a99061512f565b6000613f016138b0565b9050613f3f818686613f1287614166565b613f1b87614166565b6040518060400160405280600381526020016203078360ec1b815250505050505050565b613f86826040518060600160405280602a815260200161558e602a913960008681526004602090815260408083206001600160a01b038c1684529091529020549190614092565b60008481526004602090815260408083206001600160a01b038a81168552925280832093909355861681522054613fbd9083613759565b60008481526004602090815260408083206001600160a01b0389811680865291845293829020949094558051878152918201869052888316928516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610e1c81868686866040518060400160405280600381526020016203078360ec1b8152506141bf565b60009182526011602090815260408084206001600160a01b03939093168452919052902060048101805482546001909301929092556001600160a81b03199091169055565b600081848411156140b65760405162461bcd60e51b81526004016108a99190614ff4565b505050900390565b60008281526011602090815260408083206001600160a01b03858116855292529091206001810154600490910154909116801580159061412b575060008481526011602090815260408083206001600160a01b0387168452909152902060040154600160a01b900460ff16155b15611fc8576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610e1c573d6000803e3d6000fd5b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106141ae57634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b6001600160a01b0384163b1561166b5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906142039089908990889088908890600401614e34565b602060405180830381600087803b15801561421d57600080fd5b505af192505050801561424d575060408051601f3d908101601f1916820190925261424a9181019061491e565b60015b614259576139a761547c565b6001600160e01b0319811663f23a6e6160e01b14613a785760405162461bcd60e51b81526004016108a990615007565b600060405180608001604052806043815260200161554b60439139805160209182012083518483015160408087015180519086012090516142e9950193845260208401929092526001600160a01b03166040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b600061431160015490565b60405161190160f01b60208201526022810191909152604281018390526062016142e9565b828054614342906153a9565b90600052602060002090601f01602090048101928261436457600085556143aa565b82601f1061437d57805160ff19168380011785556143aa565b828001600101855582156143aa579182015b828111156143aa57825182559160200191906001019061438f565b506143b69291506143ba565b5090565b5b808211156143b657600081556001016143bb565b600082601f8301126143df578081fd5b813560206143ec826152c7565b6040516143f98282615409565b8381528281019150858301600585901b87018401881015614418578586fd5b855b858110156144365781358452928401929084019060010161441a565b5090979650505050505050565b80358015158114610bf957600080fd5b600082601f830112614463578081fd5b81356001600160401b0381111561447c5761447c615466565b604051614493601f8301601f191660200182615409565b8181528460208386010111156144a7578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156144d2578081fd5b81356137658161551c565b600080604083850312156144ef578081fd5b82356144fa8161551c565b9150602083013561450a8161551c565b809150509250929050565b600080600080600060a0868803121561452c578081fd5b85356145378161551c565b945060208601356145478161551c565b935060408601356001600160401b0380821115614562578283fd5b61456e89838a016143cf565b94506060880135915080821115614583578283fd5b61458f89838a016143cf565b935060808801359150808211156145a4578283fd5b506145b188828901614453565b9150509295509295909350565b600080600080600060a086880312156145d5578283fd5b85356145e08161551c565b945060208601356145f08161551c565b9350604086013592506060860135915060808601356001600160401b03811115614618578182fd5b6145b188828901614453565b60008060008060808587031215614639578182fd5b84356146448161551c565b935060208501356001600160401b038082111561465f578384fd5b61466b888389016143cf565b94506040870135915080821115614680578384fd5b61468c888389016143cf565b935060608701359150808211156146a1578283fd5b506146ae87828801614453565b91505092959194509250565b600080604083850312156146cc578182fd5b82356146d78161551c565b91506146e560208401614443565b90509250929050565b600080600080600060a08688031215614705578283fd5b85356147108161551c565b945060208601356001600160401b0381111561472a578384fd5b61473688828901614453565b9450506040860135925060608601359150608086013560ff8116811461475a578182fd5b809150509295509295909350565b6000806040838503121561477a578182fd5b82356147858161551c565b946020939093013593505050565b600080600080600060a086880312156147aa578283fd5b85356147b58161551c565b945060208601359350604086013592506147d160608701614443565b949793965091946080013592915050565b600080600080608085870312156147f7578182fd5b84356148028161551c565b9350602085013592506040850135915060608501356001600160401b0381111561482a578182fd5b6146ae87828801614453565b60008060408385031215614848578182fd5b82356001600160401b038082111561485e578384fd5b818501915085601f830112614871578384fd5b8135602061487e826152c7565b60405161488b8282615409565b8381528281019150858301600585901b870184018b10156148aa578889fd5b8896505b848710156148d55780356148c18161551c565b8352600196909601959183019183016148ae565b50965050860135925050808211156148eb578283fd5b506148f8858286016143cf565b9150509250929050565b600060208284031215614913578081fd5b813561376581615534565b60006020828403121561492f578081fd5b815161376581615534565b60006020828403121561494b578081fd5b5035919050565b60008060408385031215614964578182fd5b82359150602083013561450a8161551c565b6000806000806080858703121561498b578182fd5b84359350602085013561499d8161551c565b92506040850135915060608501356149b48161551c565b939692955090935050565b600080604083850312156149d1578182fd5b823591506020808401356001600160401b03808211156149ef578384fd5b818601915086601f830112614a02578384fd5b8135614a0d816152c7565b604051614a1a8282615409565b8281528581019150848601600584901b860187018b1015614a39578788fd5b875b84811015614a7257813586811115614a5157898afd5b614a5f8d8a838b0101614453565b8552509287019290870190600101614a3b565b50979a909950975050505050505050565b60008060408385031215614a95578182fd5b823591506020808401356001600160401b0380821115614ab3578384fd5b818601915086601f830112614ac6578384fd5b8135614ad1816152c7565b604051614ade8282615409565b8281528581019150848601600584901b860187018b1015614afd578788fd5b875b84811015614a7257813586811115614b1557898afd5b87016080818e03601f19011215614b2a57898afd5b604051614b36816153e4565b8982013588811115614b46578b8cfd5b614b548f8c83860101614453565b8252506040820135614b658161551c565b818b015260608201356040820152614b7f60808301614443565b60608201528552509287019290870190600101614aff565b60008060408385031215614ba9578182fd5b823591506146e560208401614443565b60008060408385031215614bcb578182fd5b8235915060208301356001600160401b03811115614be7578182fd5b6148f885828601614453565b60008060008060808587031215614c08578182fd5b8435935060208501359250614c1f60408601614443565b9396929550929360600135925050565b6000815180845260208085019450808401835b83811015614c5e57815187529582019590820190600101614c42565b509495945050505050565b60008151808452614c8181602086016020860161537d565b601f01601f19169290920160200192915050565b60008151614ca781856020860161537d565b9290920192915050565b60008251614cc381846020870161537d565b9190910192915050565b60008351614cdf81846020880161537d565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b600080845482600182811c915080831680614d2057607f831692505b6020808410821415614d4057634e487b7160e01b87526022600452602487fd5b818015614d545760018114614d6557614d91565b60ff19861689528489019650614d91565b60008b815260209020885b86811015614d895781548b820152908501908301614d70565b505084890196505b505050505050614da18185614c95565b95945050505050565b6001600160a01b03848116825283166020820152606060408201819052600090614da190830184614c69565b6001600160a01b0386811682528516602082015260a060408201819052600090614e0290830186614c2f565b8281036060840152614e148186614c2f565b90508281036080840152614e288185614c69565b98975050505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090614e6e90830184614c69565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614eba5783516001600160a01b031683529284019291840191600101614e95565b50909695505050505050565b6000602080830181845280855180835260408601915060408160051b8701019250838701855b82811015614f1a57603f19888603018452614f08858351614c69565b94509285019290850190600101614eec565b5092979650505050505050565b60006020808301818452808551808352604092508286019150828160051b870101848801865b83811015614fae57603f19898403018552815160808151818652614f7382870182614c69565b838b01516001600160a01b0316878c0152898401518a8801526060938401511515939096019290925250509386019390860190600101614f4d565b509098975050505050505050565b6020815260006137656020830184614c2f565b604081526000614fe26040830185614c2f565b8281036020840152614da18185614c2f565b6020815260006137656020830184614c69565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b60208082526010908201526f26bab9ba1031329037b832b930ba37b960811b604082015260600190565b60208082526019908201527f43616e6e6f742074726164652070617573656420746f6b656e00000000000000604082015260600190565b6020808252601b908201527f43616c6c6572206973206e6f7420726f6f74206f70657261746f720000000000604082015260600190565b60208082526028908201527f466565206d757374206265206265747765656e20312d313030303020626173696040820152677320706f696e747360c01b606082015260800190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526019908201527f4d757374206265206f776e6572206f72206f70657261746f7200000000000000604082015260600190565b6020808252600f908201526e26bab9ba1031329030bab1ba34b7b760891b604082015260600190565b60208082526021908201527f53656c6c657220646f6573206e6f74206f776e20746f6b656e20616e796d6f726040820152606560f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b6020808252600f908201526e131a5cdd1a5b99c8195e1c1a5c9959608a1b604082015260600190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60006001600160401b038211156152e0576152e0615466565b5060051b60200190565b600082198211156152fd576152fd615450565b500190565b600060ff821660ff84168060ff0382111561531f5761531f615450565b019392505050565b60008261534257634e487b7160e01b81526012600452602481fd5b500490565b600081600019048311821515161561536157615361615450565b500290565b60008282101561537857615378615450565b500390565b60005b83811015615398578181015183820152602001615380565b83811115611fc85750506000910152565b600181811c908216806153bd57607f821691505b602082108114156153de57634e487b7160e01b600052602260045260246000fd5b50919050565b608081018181106001600160401b038211171561540357615403615466565b60405250565b601f8201601f191681016001600160401b038111828210171561542e5761542e615466565b6040525050565b600060001982141561544957615449615450565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d111561390a57600481823e5160e01c90565b600060443d10156154a15790565b6040516003193d81016004833e81513d6001600160401b0381602484011181841117156154d057505050505090565b82850191508151818111156154e85750505050505090565b843d87010160208285010111156155025750505050505090565b61551160208286010187615409565b509095945050505050565b6001600160a01b038116811461553157600080fd5b50565b6001600160e01b03198116811461553157600080fdfe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e73666572a264697066735822122045c03501346eedfdaa7a014474ac9287416bfa663be87c29f481d55b5075bc5964736f6c6343000804003368747470733a2f2f63726561746f72736875622e6c6963656e73652e726f636b732f6170692f7075626c69632f6d65746146696c652f454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429

Deployed Bytecode

0x60806040526004361061021d5760003560e01c8063731133e911610123578063a22cb465116100ab578063cbd21f591161006f578063cbd21f5914610785578063d66675ed14610798578063dcee692b146107b8578063e985e9c5146107d8578063f242432a1461082157600080fd5b8063a22cb465146106cb578063b901fd87146106eb578063c1b362671461070b578063c7d7203514610738578063cb462a4b1461076557600080fd5b80637bde82f2116100f25780637bde82f2146105495780637deb602514610569578063935b74c81461057c5780639a8a2f78146106985780639f04996d146106b857600080fd5b8063731133e9146104c9578063744561ac146104e95780637463688514610509578063781a1d1b1461052957600080fd5b80632eb2c2d6116101a65780634e1273f4116101755780634e1273f414610404578063589a17431461043157806359d79c911461046957806361ab63d6146104895780636d3b493d146104a957600080fd5b80632eb2c2d614610391578063314a9767146103b1578063474c819e146103d15780634c23a525146103f157600080fd5b80631f7fdffa116101ed5780631f7fdffa146102cc578063242b83f5146102ee57806325ee6ee91461030e5780632b1fd58a1461033b5780632d0335ab1461035b57600080fd5b8062fdd58e1461022957806301ffc9a71461025c5780630c53c51c1461028c5780630e89341c146102ac57600080fd5b3661022457005b600080fd5b34801561023557600080fd5b50610249610244366004614768565b610841565b6040519081526020015b60405180910390f35b34801561026857600080fd5b5061027c610277366004614902565b6108da565b6040519015158152602001610253565b61029f61029a3660046146ee565b61091a565b6040516102539190614ff4565b3480156102b857600080fd5b5061029f6102c736600461493a565b610b04565b3480156102d857600080fd5b506102ec6102e7366004614624565b610bfe565b005b3480156102fa57600080fd5b506102ec610309366004614793565b610e23565b34801561031a57600080fd5b5061032e61032936600461493a565b6110f0565b6040516102539190614f27565b34801561034757600080fd5b506102ec61035636600461493a565b611226565b34801561036757600080fd5b506102496103763660046144c1565b6001600160a01b031660009081526002602052604090205490565b34801561039d57600080fd5b506102ec6103ac366004614515565b611432565b3480156103bd57600080fd5b506102ec6103cc366004614bb9565b611673565b3480156103dd57600080fd5b506102ec6103ec366004614bb9565b61176a565b6102ec6103ff366004614976565b61185e565b34801561041057600080fd5b5061042461041f366004614836565b611a84565b6040516102539190614fbc565b34801561043d57600080fd5b5061045161044c36600461493a565b611cb6565b6040516001600160a01b039091168152602001610253565b34801561047557600080fd5b506102ec610484366004614bf3565b611cd8565b34801561049557600080fd5b506102ec6104a4366004614952565b611fce565b3480156104b557600080fd5b506102ec6104c436600461493a565b6120f0565b3480156104d557600080fd5b506102ec6104e43660046147e2565b6121fe565b3480156104f557600080fd5b5061029f61050436600461493a565b612375565b34801561051557600080fd5b506102ec610524366004614a83565b612417565b34801561053557600080fd5b506102ec6105443660046149bf565b61267b565b34801561055557600080fd5b506102ec610564366004614952565b612772565b6102ec610577366004614952565b61288a565b34801561058857600080fd5b50610644610597366004614952565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091525060009182526011602090815260408084206001600160a01b039384168552825292839020835160c08101855281548152600182015492810192909252600281015460ff90811615159483019490945260038101546060830152600401549182166080820152600160a01b909104909116151560a082015290565b60405161025391908151815260208083015190820152604080830151151590820152606080830151908201526080808301516001600160a01b03169082015260a09182015115159181019190915260c00190565b3480156106a457600080fd5b506102ec6106b3366004614b97565b612b40565b6102ec6106c6366004614952565b612baa565b3480156106d757600080fd5b506102ec6106e63660046146ba565b612df9565b3480156106f757600080fd5b506102ec610706366004614a83565b612f0d565b34801561071757600080fd5b5061072b61072636600461493a565b6130a2565b6040516102539190614ec6565b34801561074457600080fd5b5061075861075336600461493a565b613183565b6040516102539190614e79565b34801561077157600080fd5b506102ec61078036600461493a565b613245565b6102ec610793366004614952565b6132d6565b3480156107a457600080fd5b5061032e6107b336600461493a565b613407565b3480156107c457600080fd5b5061029f6107d336600461493a565b613532565b3480156107e457600080fd5b5061027c6107f33660046144dd565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561082d57600080fd5b506102ec61083c3660046145be565b61354f565b60006001600160a01b0383166108b25760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b60648201526084015b60405180910390fd5b5060009081526004602090815260408083206001600160a01b03949094168352929052205490565b60006301ffc9a760e01b6001600160e01b03198316148061091457506001600160e01b0319821660009081526020819052604090205460ff165b92915050565b60408051606081810183526001600160a01b0388166000818152600260209081529085902054845283015291810186905261095887828787876136cd565b6109ae5760405162461bcd60e51b815260206004820152602160248201527f5369676e657220616e64207369676e617475726520646f206e6f74206d6174636044820152600d60fb1b60648201526084016108a9565b600080306001600160a01b0316888a6040516020016109ce929190614ccd565b60408051601f19818403018152908290526109e891614cb1565b6000604051808303816000865af19150503d8060008114610a25576040519150601f19603f3d011682016040523d82523d6000602084013e610a2a565b606091505b509150915081610a7c5760405162461bcd60e51b815260206004820152601d60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c6c00000060448201526064016108a9565b6001600160a01b038916600090815260026020526040902054610aa0906001613759565b6001600160a01b038a166000908152600260205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b90610af0908b9033908c90614daa565b60405180910390a198975050505050505050565b6000818152600860205260409020805460609190610b21906153a9565b15159050610b5b576012610b348361376c565b604051602001610b45929190614d04565b6040516020818303038152906040529050919050565b60008281526008602052604090208054610b74906153a9565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba0906153a9565b8015610bed5780601f10610bc257610100808354040283529160200191610bed565b820191906000526020600020905b815481529060010190602001808311610bd057829003601f168201915b50505050509050919050565b919050565b60076000610c0a6138b0565b6001600160a01b0316815260208101919091526040016000205460ff161515600114610c485760405162461bcd60e51b81526004016108a9906150b0565b6001600160a01b038416610c6e5760405162461bcd60e51b81526004016108a990615286565b8151835114610c8f5760405162461bcd60e51b81526004016108a990615215565b6000610c996138b0565b905060005b8451811015610db457838181518110610cc757634e487b7160e01b600052603260045260246000fd5b602002602001015160046000878481518110610cf357634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254610d3b91906152ea565b925050819055508560036000878481518110610d6757634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080610dac90615435565b915050610c9e565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610e05929190614fcf565b60405180910390a4610e1c8160008787878761390d565b5050505050565b60076000610e2f6138b0565b6001600160a01b0316815260208101919091526040016000205460ff161515600114610e6d5760405162461bcd60e51b81526004016108a99061504f565b60008481526004602090815260408083206001600160a01b0389168452909152902054610edc5760405162461bcd60e51b815260206004820152601a60248201527f4f776e6572206d757374206f776e20676976656e20746f6b656e00000000000060448201526064016108a9565b60008481526011602090815260408083206001600160a01b038916845290915290206002015460ff1615610f755760008481526011602090815260408083206001600160a01b0389811685529252909120600401541615610f755760405162461bcd60e51b815260206004820152601360248201527241756374696f6e20696e2070726f677265737360681b60448201526064016108a9565b801561104d576040518060c0016040528084815260200184815260200183151581526020018262015180610fa99190615347565b610fb390426152ea565b8152600060208083018290526040928301829052878252601181528282206001600160a01b038a8116845290825291839020845181559084015160018201559183015160028301805460ff19169115159190911790556060830151600383015560808301516004909201805460a090940151929091166001600160a81b031990931692909217600160a01b91151591909102179055610e1c565b506040805160c08101825283815260208082019485529215158183019081526000606083018181526080840182815260a08501838152988352601187528583206001600160a01b039a8b1684529096529390209151825593516001820155925160028401805491151560ff19909216919091179055516003830155516004909101805492511515600160a01b026001600160a81b03199093169190931617179055565b6060600f6000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561121b5783829060005260206000209060040201604051806080016040529081600082018054611158906153a9565b80601f0160208091040260200160405190810160405280929190818152602001828054611184906153a9565b80156111d15780601f106111a6576101008083540402835291602001916111d1565b820191906000526020600020905b8154815290600101906020018083116111b457829003601f168201915b50505091835250506001828101546001600160a01b03166020808401919091526002840154604084015260039093015460ff16151560609092019190915291835292019101611125565b505050509050919050565b6000818152600c6020526040902054819060ff1615156001141561125c5760405162461bcd60e51b81526004016108a990615079565b6000828152601160205260408120906112736138b0565b6001600160a01b0316815260208101919091526040016000206002015460ff166112af5760405162461bcd60e51b81526004016108a9906151ab565b60006112c26112bc6138b0565b84610841565b116112df5760405162461bcd60e51b81526004016108a9906151d4565b6000828152601160205260408120816112f66138b0565b6001600160a01b03166001600160a01b03168152602001908152602001600020600101549050600060116000858152602001908152602001600020600061133b6138b0565b6001600160a01b03908116825260208083019390935260409182016000908120600401548882526011909452918220921692506113766138b0565b6001600160a01b03168152602081019190915260400160002060040154600160a01b900460ff166113b2576113b2846113ad6138b0565b613a81565b6113c66113bd6138b0565b82866001613ed1565b6113d7846113d26138b0565b61404d565b836113e06138b0565b6001600160a01b0316826001600160a01b03167fd6deddb2e105b46d4644d24aac8c58493a0f107e7973b2fe8d8fa7931a2912be8560405161142491815260200190565b60405180910390a450505050565b81518351146114535760405162461bcd60e51b81526004016108a990615215565b6001600160a01b0384166114795760405162461bcd60e51b81526004016108a99061512f565b600760006114856138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001146114c35760405162461bcd60e51b81526004016108a9906150b0565b60006114cd6138b0565b905060005b84518110156116055760008582815181106114fd57634e487b7160e01b600052603260045260246000fd5b60200260200101519050600085838151811061152957634e487b7160e01b600052603260045260246000fd5b60200260200101519050611596816040518060600160405280602a815260200161558e602a91396004600086815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020546140929092919063ffffffff16565b60008381526004602090815260408083206001600160a01b038e811685529252808320939093558a16815220546115cd9082613759565b60009283526004602090815260408085206001600160a01b038c16865290915290922091909155506115fe81615435565b90506114d2565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611655929190614fcf565b60405180910390a461166b81878787878761390d565b505050505050565b61167b6138b0565b6000838152600360205260409020546001600160a01b03908116911614806116cd5750600760006116aa6138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6116e95760405162461bcd60e51b81526004016108a990615174565b6000828152600a602052604090208054611702906153a9565b1590506117465760405162461bcd60e51b815260206004820152601260248201527114d958dc995d08185b1c9958591e481cd95d60721b60448201526064016108a9565b6000828152600a60209081526040909120825161176592840190614336565b505050565b6117726138b0565b6000838152600360205260409020546001600160a01b03908116911614806117c45750600760006117a16138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6117e05760405162461bcd60e51b81526004016108a990615174565b600082815260086020526040902080546117f9906153a9565b15905061183f5760405162461bcd60e51b8152602060048201526014602482015273119a5b19481d5c9b08185b1c9958591e481cd95d60621b60448201526064016108a9565b6000828152600860209081526040909120825161176592840190614336565b6000848152600c6020526040902054849060ff161515600114156118945760405162461bcd60e51b81526004016108a990615079565b600760006118a06138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001146118de5760405162461bcd60e51b81526004016108a99061504f565b60008581526011602090815260408083206001600160a01b038816845290915290206002015460ff166119235760405162461bcd60e51b81526004016108a9906151ab565b60008581526011602090815260408083206001600160a01b0388168452909152902060010154831161198f5760405162461bcd60e51b815260206004820152601560248201527421bab93932b73a103134b21034b9903434b3b432b960591b60448201526064016108a9565b60008581526011602090815260408083206001600160a01b0388168452909152902060030154156119fe5760008581526011602090815260408083206001600160a01b038816845290915290206003015442106119fe5760405162461bcd60e51b81526004016108a99061525d565b611a0885856140be565b60008581526011602090815260408083206001600160a01b038881168552925280832060048101805460019092018890556001600160a81b0319909116928616928317600160a01b1790555187928692917f19421268847f42dd61705778018ddfc43bcdce8517e7a630acb12f122c7094819190a45050505050565b60608151835114611ae95760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016108a9565b600083516001600160401b03811115611b1257634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611b3b578160200160208202803683370190505b50905060005b8451811015611cae5760006001600160a01b0316858281518110611b7557634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415611bee5760405162461bcd60e51b815260206004820152603160248201527f455243313135353a2062617463682062616c616e636520717565727920666f7260448201527020746865207a65726f206164647265737360781b60648201526084016108a9565b60046000858381518110611c1257634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000868381518110611c4a57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110611c9357634e487b7160e01b600052603260045260246000fd5b6020908102919091010152611ca781615435565b9050611b41565b509392505050565b6000818152600360205260408120546001600160a01b03168061091457600080fd5b600084815260046020526040812081611cef6138b0565b6001600160a01b03166001600160a01b031681526020019081526020016000205411611d5d5760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206d757374206f776e20676976656e20746f6b656e000000000060448201526064016108a9565b600084815260116020526040812090611d746138b0565b6001600160a01b0316815260208101919091526040016000206002015460ff1615611e1357600084815260116020526040812081611db06138b0565b6001600160a01b0390811682526020820192909252604001600020600401541614611e135760405162461bcd60e51b815260206004820152601360248201527241756374696f6e20696e2070726f677265737360681b60448201526064016108a9565b8015611efe576040518060c0016040528084815260200184815260200183151581526020018262015180611e479190615347565b611e5190426152ea565b81526000602080830182905260409283018290528782526011905290812090611e786138b0565b6001600160a01b0390811682526020808301939093526040918201600020845181559284015160018401559083015160028301805460ff19169115159190911790556060830151600383015560808301516004909201805460a090940151929091166001600160a81b031990931692909217600160a01b91151591909102179055611fc8565b6040805160c0810182528481526020808201869052841515828401526000606083018190526080830181905260a0830181905287815260119091529182209091611f466138b0565b6001600160a01b0390811682526020808301939093526040918201600020845181559284015160018401559083015160028301805460ff19169115159190911790556060830151600383015560808301516004909201805460a090940151929091166001600160a81b031990931692909217600160a01b911515919091021790555b50505050565b60008281526011602090815260408083206001600160a01b0380861685529252909120600401541680611fff6138b0565b6001600160a01b0316148061202c5750816001600160a01b03166120216138b0565b6001600160a01b0316145b6120785760405162461bcd60e51b815260206004820181905260248201527f596f75206d757374206265206c61737420626964646572206f72206f776e657260448201526064016108a9565b60008381526011602090815260408083206001600160a01b03861684529091529020600101546120a884846140be565b6120b2848461404d565b8381836001600160a01b03167f09dcebe16a733e22cc47e4959c50d4f21624d9f1815db32c2e439fbbd7b3eda060405160405180910390a450505050565b6120f86138b0565b6000828152600360205260409020546001600160a01b039081169116148061214a5750600760006121276138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6121665760405162461bcd60e51b81526004016108a990615174565b6000818152600d6020526040902054156121bb5760405162461bcd60e51b815260206004820152601660248201527514995919595b48185b1c9958591e48185b1b1bddd95960521b60448201526064016108a9565b6000818152600460205260408120906121d26138b0565b6001600160a01b031681526020808201929092526040908101600090812054938152600d909252902055565b6001600160a01b0384166122245760405162461bcd60e51b81526004016108a990615286565b6000838152600360205260409020546001600160a01b0316156122955760405162461bcd60e51b8152602060048201526024808201527f596f7520617265206e6f7420616c6c6f77656420746f206d696e7420676976656044820152631b881a5960e21b60648201526084016108a9565b600061229f6138b0565b90506122ba816000876122b188614166565b610e1c88614166565b60008481526004602090815260408083206001600160a01b03891684529091529020546122e79084613759565b60008581526004602090815260408083206001600160a01b038a8116808652918452828520959095558884526003835281842080546001600160a01b0319169587169586179055815189815292830188905293917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610e1c816000878787876141bf565b600081815260046020526040812060609190816123906138b0565b6001600160a01b03166001600160a01b0316815260200190815260200160002054116123fe5760405162461bcd60e51b815260206004820152601b60248201527f43616c6c6572206d757374206f776e20676976656e20746f6b656e000000000060448201526064016108a9565b6000828152600a602052604090208054610b74906153a9565b6000828152600b602052604090205460ff16156124645760405162461bcd60e51b815260206004820152600b60248201526a1199595cc81b1bd8dad95960aa1b60448201526064016108a9565b61246c6138b0565b6000838152600360205260409020546001600160a01b03908116911614806124be57506007600061249b6138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6124da5760405162461bcd60e51b81526004016108a990615174565b60005b81518110156117655781818151811061250657634e487b7160e01b600052603260045260246000fd5b60200260200101516060015115156001151514156125b55761271082828151811061254157634e487b7160e01b600052603260045260246000fd5b6020026020010151604001511061256a5760405162461bcd60e51b81526004016108a9906150e7565b600082828151811061258c57634e487b7160e01b600052603260045260246000fd5b602002602001015160400151116125b55760405162461bcd60e51b81526004016108a9906150e7565b6000838152600f6020526040902082518390839081106125e557634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182546001810184556000938452928290208151805192946004029091019261261e92849290910190614336565b5060208201516001820180546001600160a01b0319166001600160a01b03909216919091179055604082015160028201556060909101516003909101805460ff19169115159190911790558061267381615435565b9150506124dd565b6126836138b0565b6000838152600360205260409020546001600160a01b03908116911614806126d55750600760006126b26138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6126f15760405162461bcd60e51b81526004016108a990615174565b60005b8151811015611765576000838152600960205260409020825183908390811061272d57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518254600181018455600093845292829020815161275f9491909101929190910190614336565b508061276a81615435565b9150506126f4565b61277a6138b0565b6000838152600360205260409020546001600160a01b03908116911614806127cc5750600760006127a96138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6127e85760405162461bcd60e51b81526004016108a990615174565b6000828152600d6020908152604080832054600e909252909120541061284b5760405162461bcd60e51b8152602060048201526018602482015277151bdad95b8818d85b9b9bdd081899481c995919595b595960421b60448201526064016108a9565b6000918252600e6020908152604083208054600181018255908452922090910180546001600160a01b0319166001600160a01b03909216919091179055565b816128936138b0565b6001600160a01b03166128a582611cb6565b6001600160a01b031614156128b957600080fd5b6000838152600c6020526040902054839060ff161515600114156128ef5760405162461bcd60e51b81526004016108a990615079565b60008481526011602090815260408083206001600160a01b03871684529091528120600101549034906129206138b0565b9050600061292e8789610841565b1161294b5760405162461bcd60e51b81526004016108a9906151d4565b600083116129935760405162461bcd60e51b815260206004820152601560248201527421b0b73737ba10313abc903a3434b9903a37b5b2b760591b60448201526064016108a9565b60008781526011602090815260408083206001600160a01b038a16845290915290206002015460ff1615612a095760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74206275792c2061756374696f6e20696e2070726f67726573730060448201526064016108a9565b82821015612a595760405162461bcd60e51b815260206004820152601760248201527f496e73756666696369656e742076616c75652073656e7400000000000000000060448201526064016108a9565b60008781526011602090815260408083206001600160a01b038a16845290915290206003015415612ac85760008781526011602090815260408083206001600160a01b038a1684529091529020600301544210612ac85760405162461bcd60e51b81526004016108a99061525d565b612ad28787613a81565b612adc878761404d565b612ae98682896001613ed1565b86866001600160a01b0316826001600160a01b03167f16dd16959a056953a63cf14bf427881e762e54f03d86b864efea8238dd3b822f85604051612b2f91815260200190565b60405180910390a450505050505050565b60076000612b4c6138b0565b6001600160a01b0316815260208101919091526040016000205460ff161515600114612b8a5760405162461bcd60e51b81526004016108a99061504f565b6000918252600c6020526040909120805460ff1916911515919091179055565b6000828152600c6020526040902054829060ff16151560011415612be05760405162461bcd60e51b81526004016108a990615079565b60008381526011602090815260408083206001600160a01b038616845290915290206002015460ff16612c255760405162461bcd60e51b81526004016108a9906151ab565b612c2d6138b0565b6001600160a01b0316826001600160a01b03161415612c825760405162461bcd60e51b815260206004820152601160248201527014d95b1b195c8818d85b9b9bdd08189a59607a1b60448201526064016108a9565b60008381526011602090815260408083206001600160a01b03861684529091529020600101543411612cee5760405162461bcd60e51b815260206004820152601560248201527421bab93932b73a103134b21034b9903434b3b432b960591b60448201526064016108a9565b60008381526011602090815260408083206001600160a01b038616845290915290206003015415612d5d5760008381526011602090815260408083206001600160a01b03861684529091529020600301544210612d5d5760405162461bcd60e51b81526004016108a99061525d565b612d6783836140be565b612d6f6138b0565b60008481526011602090815260408083206001600160a01b03878116855292529091206004810180543460019093018390556001600160a81b031916939092169290921790558390612dbf6138b0565b6001600160a01b03167f19421268847f42dd61705778018ddfc43bcdce8517e7a630acb12f122c70948160405160405180910390a4505050565b816001600160a01b0316612e0b6138b0565b6001600160a01b03161415612e745760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016108a9565b8060056000612e816138b0565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155612ec56138b0565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612f01911515815260200190565b60405180910390a35050565b6000828152600b602052604090205460ff1615612f5a5760405162461bcd60e51b815260206004820152600b60248201526a1199595cc81b1bd8dad95960aa1b60448201526064016108a9565b612f626138b0565b6000838152600360205260409020546001600160a01b0390811691161480612fb4575060076000612f916138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b612fd05760405162461bcd60e51b81526004016108a990615174565b60005b8151811015611765576000838152601060205260409020825183908390811061300c57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182546001810184556000938452928290208151805192946004029091019261304592849290910190614336565b5060208201516001820180546001600160a01b0319166001600160a01b03909216919091179055604082015160028201556060909101516003909101805460ff19169115159190911790558061309a81615435565b915050612fd3565b606060096000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561121b5783829060005260206000200180546130f6906153a9565b80601f0160208091040260200160405190810160405280929190818152602001828054613122906153a9565b801561316f5780601f106131445761010080835404028352916020019161316f565b820191906000526020600020905b81548152906001019060200180831161315257829003601f168201915b5050505050815260200190600101906130d7565b6000818152600d60205260409020546060906131dc5760405162461bcd60e51b8152602060048201526018602482015277151bdad95b8818d85b9b9bdd081899481c995919595b595960421b60448201526064016108a9565b6000828152600e602090815260409182902080548351818402810184019094528084529091830182828015610bed57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161321c5750505050509050919050565b61324d6138b0565b6000828152600360205260409020546001600160a01b039081169116148061329f57506007600061327c6138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001145b6132bb5760405162461bcd60e51b81526004016108a990615174565b6000908152600b60205260409020805460ff19166001179055565b600760006132e26138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001146133205760405162461bcd60e51b81526004016108a99061504f565b60008281526011602090815260408083206001600160a01b038516845290915290206002015460ff166133655760405162461bcd60e51b81526004016108a9906151ab565b60008281526011602090815260408083206001600160a01b038581168552925290912060040154166133cc5760405162461bcd60e51b815260206004820152601060248201526f139bc8189a59081d1bc818d85b98d95b60821b60448201526064016108a9565b60008281526011602090815260408083206001600160a01b038581168552925290912060048101546001909101549116906120a884846140be565b606060106000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561121b578382906000526020600020906004020160405180608001604052908160008201805461346f906153a9565b80601f016020809104026020016040519081016040528092919081815260200182805461349b906153a9565b80156134e85780601f106134bd576101008083540402835291602001916134e8565b820191906000526020600020905b8154815290600101906020018083116134cb57829003601f168201915b50505091835250506001828101546001600160a01b03166020808401919091526002840154604084015260039093015460ff1615156060909201919091529183529201910161343c565b6000818152600860205260409020805460609190610b74906153a9565b6001600160a01b0384166135755760405162461bcd60e51b81526004016108a99061512f565b600760006135816138b0565b6001600160a01b0316815260208101919091526040016000205460ff1615156001146135bf5760405162461bcd60e51b81526004016108a9906150b0565b60006135c96138b0565b90506135da8187876122b188614166565b613621836040518060600160405280602a815260200161558e602a913960008781526004602090815260408083206001600160a01b038d1684529091529020549190614092565b60008581526004602090815260408083206001600160a01b038b811685529252808320939093558716815220546136589084613759565b60008581526004602090815260408083206001600160a01b038a811680865291845293829020949094558051888152918201879052898316928516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461166b8187878787876141bf565b600060016136e26136dd87614289565b614306565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015613730573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b600061376582846152ea565b9392505050565b6060816137905750506040805180820190915260018152600360fc1b602082015290565b8160005b81156137ba57806137a481615435565b91506137b39050600a83615327565b9150613794565b6000816001600160401b038111156137e257634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561380c576020820181803683370190505b509050815b85156138a757613822600182615366565b90506000613831600a88615327565b61383c90600a615347565b6138469088615366565b613851906030615302565b905060008160f81b90508084848151811061387c57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061389e600a89615327565b97505050613811565b50949350505050565b60003330141561390757600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b0316915061390a9050565b50335b90565b6001600160a01b0384163b1561166b5760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906139519089908990889088908890600401614dd6565b602060405180830381600087803b15801561396b57600080fd5b505af192505050801561399b575060408051601f3d908101601f191682019092526139989181019061491e565b60015b613a48576139a761547c565b806308c379a014156139e157506139bc615493565b806139c757506139e3565b8060405162461bcd60e51b81526004016108a99190614ff4565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016108a9565b6001600160e01b0319811663bc197c8160e01b14613a785760405162461bcd60e51b81526004016108a990615007565b50505050505050565b60008281526011602090815260408083206001600160a01b03808616808652918452828520600101548786526003909452918420549293929091161415613cac576000613acd856110f0565b905060005b8151811015613ca557818181518110613afb57634e487b7160e01b600052603260045260246000fd5b60200260200101516060015115613bcb57600061271085848481518110613b3257634e487b7160e01b600052603260045260246000fd5b602002602001015160400151613b489190615347565b613b529190615327565b9050613b5e81856152ea565b9350828281518110613b8057634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015613bc4573d6000803e3d6000fd5b5050613c95565b818181518110613beb57634e487b7160e01b600052603260045260246000fd5b60200260200101516040015183613c0291906152ea565b9250818181518110613c2457634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166108fc838381518110613c5c57634e487b7160e01b600052603260045260246000fd5b6020026020010151604001519081150290604051600060405180830381858888f19350505050158015613c93573d6000803e3d6000fd5b505b613c9e81615435565b9050613ad2565b5050613e92565b6000613cb785613407565b905060005b8151811015613e8f57818181518110613ce557634e487b7160e01b600052603260045260246000fd5b60200260200101516060015115613db557600061271085848481518110613d1c57634e487b7160e01b600052603260045260246000fd5b602002602001015160400151613d329190615347565b613d3c9190615327565b9050613d4881856152ea565b9350828281518110613d6a57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166108fc829081150290604051600060405180830381858888f19350505050158015613dae573d6000803e3d6000fd5b5050613e7f565b818181518110613dd557634e487b7160e01b600052603260045260246000fd5b60200260200101516040015183613dec91906152ea565b9250818181518110613e0e57634e487b7160e01b600052603260045260246000fd5b6020026020010151602001516001600160a01b03166108fc838381518110613e4657634e487b7160e01b600052603260045260246000fd5b6020026020010151604001519081150290604051600060405180830381858888f19350505050158015613e7d573d6000803e3d6000fd5b505b613e8881615435565b9050613cbc565b50505b6001600160a01b0383166108fc613ea98385615366565b6040518115909202916000818181858888f19350505050158015610e1c573d6000803e3d6000fd5b6001600160a01b038316613ef75760405162461bcd60e51b81526004016108a99061512f565b6000613f016138b0565b9050613f3f818686613f1287614166565b613f1b87614166565b6040518060400160405280600381526020016203078360ec1b815250505050505050565b613f86826040518060600160405280602a815260200161558e602a913960008681526004602090815260408083206001600160a01b038c1684529091529020549190614092565b60008481526004602090815260408083206001600160a01b038a81168552925280832093909355861681522054613fbd9083613759565b60008481526004602090815260408083206001600160a01b0389811680865291845293829020949094558051878152918201869052888316928516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4610e1c81868686866040518060400160405280600381526020016203078360ec1b8152506141bf565b60009182526011602090815260408084206001600160a01b03939093168452919052902060048101805482546001909301929092556001600160a81b03199091169055565b600081848411156140b65760405162461bcd60e51b81526004016108a99190614ff4565b505050900390565b60008281526011602090815260408083206001600160a01b03858116855292529091206001810154600490910154909116801580159061412b575060008481526011602090815260408083206001600160a01b0387168452909152902060040154600160a01b900460ff16155b15611fc8576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610e1c573d6000803e3d6000fd5b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106141ae57634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b6001600160a01b0384163b1561166b5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906142039089908990889088908890600401614e34565b602060405180830381600087803b15801561421d57600080fd5b505af192505050801561424d575060408051601f3d908101601f1916820190925261424a9181019061491e565b60015b614259576139a761547c565b6001600160e01b0319811663f23a6e6160e01b14613a785760405162461bcd60e51b81526004016108a990615007565b600060405180608001604052806043815260200161554b60439139805160209182012083518483015160408087015180519086012090516142e9950193845260208401929092526001600160a01b03166040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b600061431160015490565b60405161190160f01b60208201526022810191909152604281018390526062016142e9565b828054614342906153a9565b90600052602060002090601f01602090048101928261436457600085556143aa565b82601f1061437d57805160ff19168380011785556143aa565b828001600101855582156143aa579182015b828111156143aa57825182559160200191906001019061438f565b506143b69291506143ba565b5090565b5b808211156143b657600081556001016143bb565b600082601f8301126143df578081fd5b813560206143ec826152c7565b6040516143f98282615409565b8381528281019150858301600585901b87018401881015614418578586fd5b855b858110156144365781358452928401929084019060010161441a565b5090979650505050505050565b80358015158114610bf957600080fd5b600082601f830112614463578081fd5b81356001600160401b0381111561447c5761447c615466565b604051614493601f8301601f191660200182615409565b8181528460208386010111156144a7578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156144d2578081fd5b81356137658161551c565b600080604083850312156144ef578081fd5b82356144fa8161551c565b9150602083013561450a8161551c565b809150509250929050565b600080600080600060a0868803121561452c578081fd5b85356145378161551c565b945060208601356145478161551c565b935060408601356001600160401b0380821115614562578283fd5b61456e89838a016143cf565b94506060880135915080821115614583578283fd5b61458f89838a016143cf565b935060808801359150808211156145a4578283fd5b506145b188828901614453565b9150509295509295909350565b600080600080600060a086880312156145d5578283fd5b85356145e08161551c565b945060208601356145f08161551c565b9350604086013592506060860135915060808601356001600160401b03811115614618578182fd5b6145b188828901614453565b60008060008060808587031215614639578182fd5b84356146448161551c565b935060208501356001600160401b038082111561465f578384fd5b61466b888389016143cf565b94506040870135915080821115614680578384fd5b61468c888389016143cf565b935060608701359150808211156146a1578283fd5b506146ae87828801614453565b91505092959194509250565b600080604083850312156146cc578182fd5b82356146d78161551c565b91506146e560208401614443565b90509250929050565b600080600080600060a08688031215614705578283fd5b85356147108161551c565b945060208601356001600160401b0381111561472a578384fd5b61473688828901614453565b9450506040860135925060608601359150608086013560ff8116811461475a578182fd5b809150509295509295909350565b6000806040838503121561477a578182fd5b82356147858161551c565b946020939093013593505050565b600080600080600060a086880312156147aa578283fd5b85356147b58161551c565b945060208601359350604086013592506147d160608701614443565b949793965091946080013592915050565b600080600080608085870312156147f7578182fd5b84356148028161551c565b9350602085013592506040850135915060608501356001600160401b0381111561482a578182fd5b6146ae87828801614453565b60008060408385031215614848578182fd5b82356001600160401b038082111561485e578384fd5b818501915085601f830112614871578384fd5b8135602061487e826152c7565b60405161488b8282615409565b8381528281019150858301600585901b870184018b10156148aa578889fd5b8896505b848710156148d55780356148c18161551c565b8352600196909601959183019183016148ae565b50965050860135925050808211156148eb578283fd5b506148f8858286016143cf565b9150509250929050565b600060208284031215614913578081fd5b813561376581615534565b60006020828403121561492f578081fd5b815161376581615534565b60006020828403121561494b578081fd5b5035919050565b60008060408385031215614964578182fd5b82359150602083013561450a8161551c565b6000806000806080858703121561498b578182fd5b84359350602085013561499d8161551c565b92506040850135915060608501356149b48161551c565b939692955090935050565b600080604083850312156149d1578182fd5b823591506020808401356001600160401b03808211156149ef578384fd5b818601915086601f830112614a02578384fd5b8135614a0d816152c7565b604051614a1a8282615409565b8281528581019150848601600584901b860187018b1015614a39578788fd5b875b84811015614a7257813586811115614a5157898afd5b614a5f8d8a838b0101614453565b8552509287019290870190600101614a3b565b50979a909950975050505050505050565b60008060408385031215614a95578182fd5b823591506020808401356001600160401b0380821115614ab3578384fd5b818601915086601f830112614ac6578384fd5b8135614ad1816152c7565b604051614ade8282615409565b8281528581019150848601600584901b860187018b1015614afd578788fd5b875b84811015614a7257813586811115614b1557898afd5b87016080818e03601f19011215614b2a57898afd5b604051614b36816153e4565b8982013588811115614b46578b8cfd5b614b548f8c83860101614453565b8252506040820135614b658161551c565b818b015260608201356040820152614b7f60808301614443565b60608201528552509287019290870190600101614aff565b60008060408385031215614ba9578182fd5b823591506146e560208401614443565b60008060408385031215614bcb578182fd5b8235915060208301356001600160401b03811115614be7578182fd5b6148f885828601614453565b60008060008060808587031215614c08578182fd5b8435935060208501359250614c1f60408601614443565b9396929550929360600135925050565b6000815180845260208085019450808401835b83811015614c5e57815187529582019590820190600101614c42565b509495945050505050565b60008151808452614c8181602086016020860161537d565b601f01601f19169290920160200192915050565b60008151614ca781856020860161537d565b9290920192915050565b60008251614cc381846020870161537d565b9190910192915050565b60008351614cdf81846020880161537d565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b600080845482600182811c915080831680614d2057607f831692505b6020808410821415614d4057634e487b7160e01b87526022600452602487fd5b818015614d545760018114614d6557614d91565b60ff19861689528489019650614d91565b60008b815260209020885b86811015614d895781548b820152908501908301614d70565b505084890196505b505050505050614da18185614c95565b95945050505050565b6001600160a01b03848116825283166020820152606060408201819052600090614da190830184614c69565b6001600160a01b0386811682528516602082015260a060408201819052600090614e0290830186614c2f565b8281036060840152614e148186614c2f565b90508281036080840152614e288185614c69565b98975050505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090614e6e90830184614c69565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614eba5783516001600160a01b031683529284019291840191600101614e95565b50909695505050505050565b6000602080830181845280855180835260408601915060408160051b8701019250838701855b82811015614f1a57603f19888603018452614f08858351614c69565b94509285019290850190600101614eec565b5092979650505050505050565b60006020808301818452808551808352604092508286019150828160051b870101848801865b83811015614fae57603f19898403018552815160808151818652614f7382870182614c69565b838b01516001600160a01b0316878c0152898401518a8801526060938401511515939096019290925250509386019390860190600101614f4d565b509098975050505050505050565b6020815260006137656020830184614c2f565b604081526000614fe26040830185614c2f565b8281036020840152614da18185614c2f565b6020815260006137656020830184614c69565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b60208082526010908201526f26bab9ba1031329037b832b930ba37b960811b604082015260600190565b60208082526019908201527f43616e6e6f742074726164652070617573656420746f6b656e00000000000000604082015260600190565b6020808252601b908201527f43616c6c6572206973206e6f7420726f6f74206f70657261746f720000000000604082015260600190565b60208082526028908201527f466565206d757374206265206265747765656e20312d313030303020626173696040820152677320706f696e747360c01b606082015260800190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526019908201527f4d757374206265206f776e6572206f72206f70657261746f7200000000000000604082015260600190565b6020808252600f908201526e26bab9ba1031329030bab1ba34b7b760891b604082015260600190565b60208082526021908201527f53656c6c657220646f6573206e6f74206f776e20746f6b656e20616e796d6f726040820152606560f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b6020808252600f908201526e131a5cdd1a5b99c8195e1c1a5c9959608a1b604082015260600190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60006001600160401b038211156152e0576152e0615466565b5060051b60200190565b600082198211156152fd576152fd615450565b500190565b600060ff821660ff84168060ff0382111561531f5761531f615450565b019392505050565b60008261534257634e487b7160e01b81526012600452602481fd5b500490565b600081600019048311821515161561536157615361615450565b500290565b60008282101561537857615378615450565b500390565b60005b83811015615398578181015183820152602001615380565b83811115611fc85750506000910152565b600181811c908216806153bd57607f821691505b602082108114156153de57634e487b7160e01b600052602260045260246000fd5b50919050565b608081018181106001600160401b038211171561540357615403615466565b60405250565b601f8201601f191681016001600160401b038111828210171561542e5761542e615466565b6040525050565b600060001982141561544957615449615450565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d111561390a57600481823e5160e01c90565b600060443d10156154a15790565b6040516003193d81016004833e81513d6001600160401b0381602484011181841117156154d057505050505090565b82850191508151818111156154e85750505050505090565b843d87010160208285010111156155025750505050505090565b61551160208286010187615409565b509095945050505050565b6001600160a01b038116811461553157600080fd5b50565b6001600160e01b03198116811461553157600080fdfe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e73666572a264697066735822122045c03501346eedfdaa7a014474ac9287416bfa663be87c29f481d55b5075bc5964736f6c63430008040033

Loading...
Loading
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.