ETH Price: $2,932.95 (-0.81%)

Token

Poopzter Linea (POO)

Overview

Max Total Supply

6,028 POO

Holders

4,424

Transfers

-
0

Market

Onchain Market Cap

-

Circulating Supply Market Cap

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

Click here to update the token information / general information

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xdad2d131...39df4Eac1
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
OmniseaONFT721Psi

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 1 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

import "../interfaces/IOmniseaONFT721Psi.sol";
import "../interfaces/IOmniseaDropsScheduler.sol";
import "../interfaces/IERC2981Royalties.sol";
import "../onft/ONFT721Core.sol";
import {CreateParams, Phase} from "../structs/erc721/ERC721Structs.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "../ERC721Psi/ERC721Psi.sol";
import "../ERC721Psi/extensions/ERC721PsiAddressData.sol";

contract OmniseaONFT721Psi is ONFT721Core, IOmniseaONFT721Psi, ERC721PsiAddressData {
    using Strings for uint256;

    IOmniseaDropsScheduler private immutable _scheduler = IOmniseaDropsScheduler(0x6ef0871ed810f323eA516A77B0988353b667dfa4);

    uint24 public maxSupply;
    string public collectionURI;
    address public dropsManager;
    bool public isZeroIndexed;
    string public tokensURI;
    uint256 endTime;

    constructor(
        CreateParams memory params,
        address _owner,
        address _dropsManagerAddress
    ) ERC721Psi(params.name, params.symbol) ONFT721Core(250000, address(0xb6319cC6c8c27A8F5dAF0dD3DF91EA35C4720dd7)) {
        dropsManager = _dropsManagerAddress;
        tokensURI = params.tokensURI;
        maxSupply = params.maxSupply;
        collectionURI = params.uri;
        isZeroIndexed = params.isZeroIndexed;
        endTime = params.endTime;
        _setNextTokenId(isZeroIndexed ? 0 : 1);
        owner = _owner;
        royaltyAmount = params.royaltyAmount;
    }

    function contractURI() public view returns (string memory) {
        return string(abi.encodePacked("ipfs://", collectionURI));
    }

    function tokenURI(uint256 tokenId) public view returns (string memory) {
        if (maxSupply == 0 || bytes(tokensURI).length == 0) {
            return contractURI();
        }

        return string(abi.encodePacked("ipfs://", tokensURI, "/", tokenId.toString(), ".json"));
    }

    function mint(address _minter, uint24 _quantity, bytes32[] memory _merkleProof, uint8 _phaseId) external override nonReentrant {
        require(msg.sender == dropsManager);
        require(isAllowed(_minter, _quantity, _merkleProof, _phaseId), "!isAllowed");
        _scheduler.increasePhaseMintedCount(_minter, _phaseId, _quantity);
        _mint(_minter, _quantity);
    }

    function mintPrice(uint8 _phaseId) public view override returns (uint256) {
        return _scheduler.mintPrice(_phaseId);
    }

    function getOwner() external view override returns (address) {
        return owner;
    }

    function isAllowed(address _account, uint24 _quantity, bytes32[] memory _merkleProof, uint8 _phaseId) internal view returns (bool) {
        require(block.timestamp < endTime);
        uint256 _newTotalMinted = totalMinted() + _quantity;
        if (maxSupply > 0) require(maxSupply >= _newTotalMinted);

        return _scheduler.isAllowed(_account, _quantity, _merkleProof, _phaseId);
    }

    function setPhase(
        uint8 _phaseId,
        uint256 _from,
        uint256 _to,
        bytes32 _merkleRoot,
        uint24 _maxPerAddress,
        uint256 _price
    ) external onlyOwner {
        _scheduler.setPhase(_phaseId, _from, _to, _merkleRoot, _maxPerAddress, _price);
    }

    function setTokensURI(string memory _uri) external onlyOwner {
        require(block.timestamp < endTime);
        tokensURI = _uri;
    }

    function preMintToTeam(uint256 _quantity) external onlyOwner {
        require(block.timestamp < endTime);
        if (maxSupply > 0) require(maxSupply >= totalMinted() + _quantity);
        _safeMint(owner, _quantity);
    }

    function setTrustedRemoteAndLimits(
        uint16 _remoteChainId,
        bytes calldata _remoteAddress,
        uint256 _dstChainIdToTransferGas,
        uint256 _dstChainIdToBatchLimit
    ) external onlyOwner {
        require(_dstChainIdToTransferGas > 0 && _dstChainIdToBatchLimit > 0);
        dstChainIdToTransferGas[_remoteChainId] = _dstChainIdToTransferGas;
        dstChainIdToBatchLimit[_remoteChainId] = _dstChainIdToBatchLimit;
        trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));
        emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);
    }

    function _startTokenId() internal view override returns (uint256) {
        return isZeroIndexed ? 0 : 1;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Psi, ONFT721Core) returns (bool) {
        return interfaceId == type(IOmniseaONFT721Psi).interfaceId || super.supportsInterface(interfaceId);
    }

    function _debitFrom(address _from, uint16, bytes memory, uint _tokenId) internal virtual override {
        require(ownerOf(_tokenId) == _from);
        require(_isApprovedOrOwner(_from, _tokenId));
        transferFrom(_from, address(this), _tokenId);
    }

    function _creditTo(uint16, address _toAddress, uint _tokenId) internal virtual override {
        require(_exists(_tokenId) && ownerOf(_tokenId) == address(this));
        transferFrom(address(this), _toAddress, _tokenId);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

interface IOmniseaONFT721Psi {
    function mint(address minter, uint24 quantity, bytes32[] memory _merkleProof, uint8 _phaseId) external;
    function mintPrice(uint8 _phaseId) external view returns (uint256);
    function getOwner() external view returns (address);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import {Phase} from "../structs/erc721/ERC721Structs.sol";

interface IOmniseaDropsScheduler {
    function isAllowed(address _account, uint24 _quantity, bytes32[] memory _merkleProof, uint8 _phaseId) external view returns (bool);
    function setPhase(
        uint8 _phaseId,
        uint256 _from,
        uint256 _to,
        bytes32 _merkleRoot,
        uint24 _maxPerAddress,
        uint256 _price
    ) external;
    function increasePhaseMintedCount(address _account,uint8 _phaseId, uint24 _quantity) external;
    function mintPrice(uint8 _phaseId) external view returns (uint256);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC2981Royalties {
    function royaltyInfo(uint256 _tokenId, uint256 _value) external view returns (address _receiver, uint256 _royaltyAmount);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IONFT721Core.sol";
import "../lzApp/NonblockingLzApp.sol";
import "../interfaces/IERC2981Royalties.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

abstract contract ONFT721Core is NonblockingLzApp, ERC165, ReentrancyGuard, IONFT721Core, IERC2981Royalties {
    uint16 public constant FUNCTION_TYPE_SEND = 1;
    uint private constant BP_DENOMINATOR = 10000;
    uint16 public feeBp;
    address internal revenueManager;
    uint24 public royaltyAmount;

    struct StoredCredit {
        uint16 srcChainId;
        address toAddress;
        uint256 index;
        bool creditsRemain;
    }

    uint256 public minGasToTransferAndStore; // min amount of gas required to transfer, and also store the payload
    mapping(uint16 => uint256) public dstChainIdToBatchLimit;
    mapping(uint16 => uint256) public dstChainIdToTransferGas; // per transfer amount of gas required to mint/transfer on the dst
    mapping(bytes32 => StoredCredit) public storedCredits;

    constructor(uint256 _minGasToTransferAndStore, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        require(_minGasToTransferAndStore > 0);
        minGasToTransferAndStore = _minGasToTransferAndStore;
        revenueManager = address(0x61104fBe07ecc735D8d84422c7f045f8d29DBf15);
        feeBp = 1000;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC2981Royalties).interfaceId
        || interfaceId == type(IONFT721Core).interfaceId
        || super.supportsInterface(interfaceId);
    }

    function estimateSendFee(uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, bool _useZro, bytes memory _adapterParams) public view virtual override returns (uint nativeFee, uint zroFee) {
        return estimateSendBatchFee(_dstChainId, _toAddress, _toSingletonArray(_tokenId), _useZro, _adapterParams);
    }

    function estimateSendBatchFee(uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, bool _useZro, bytes memory _adapterParams) public view virtual override returns (uint nativeFee, uint zroFee) {
        bytes memory payload = abi.encode(_toAddress, _tokenIds);
        (nativeFee, zroFee) = lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);
        uint fee = nativeFee * feeBp / BP_DENOMINATOR;
        nativeFee += fee;
    }

    function sendFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable virtual override {
        _send(_from, _dstChainId, _toAddress, _toSingletonArray(_tokenId), _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function sendBatchFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable virtual override {
        _send(_from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function _send(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual {
        require(_tokenIds.length > 0, "tokenIds[] is empty");
        require(_tokenIds.length <= dstChainIdToBatchLimit[_dstChainId], "batch size exceeds dst batch limit");

        for (uint i = 0; i < _tokenIds.length; i++) {
            _debitFrom(_from, _dstChainId, _toAddress, _tokenIds[i]);
        }

        bytes memory payload = abi.encode(_toAddress, _tokenIds);
        _checkGasLimit(_dstChainId, FUNCTION_TYPE_SEND, _adapterParams, dstChainIdToTransferGas[_dstChainId] * _tokenIds.length);
        (uint nativeFee) = _payONFTFee(msg.value);
        _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams, nativeFee);
        emit SendToChain(_dstChainId, _from, _toAddress, _tokenIds);
    }

    function _nonblockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64, /*_nonce*/
        bytes memory _payload
    ) internal virtual override {
        (bytes memory toAddressBytes, uint[] memory tokenIds) = abi.decode(_payload, (bytes, uint[]));

        address toAddress;
        assembly {
            toAddress := mload(add(toAddressBytes, 20))
        }

        uint nextIndex = _creditTill(_srcChainId, toAddress, 0, tokenIds);
        if (nextIndex < tokenIds.length) {
            // not enough gas to complete transfers, store to be cleared in another tx
            bytes32 hashedPayload = keccak256(_payload);
            storedCredits[hashedPayload] = StoredCredit(_srcChainId, toAddress, nextIndex, true);
            emit CreditStored(hashedPayload, _payload);
        }

        emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, tokenIds);
    }

    // Public function for anyone to clear and deliver the remaining batch sent tokenIds
    function clearCredits(bytes memory _payload) external virtual nonReentrant {
        bytes32 hashedPayload = keccak256(_payload);
        require(storedCredits[hashedPayload].creditsRemain);

        (,uint[] memory tokenIds) = abi.decode(_payload, (bytes, uint[]));

        uint nextIndex = _creditTill(storedCredits[hashedPayload].srcChainId, storedCredits[hashedPayload].toAddress, storedCredits[hashedPayload].index, tokenIds);
        require(nextIndex > storedCredits[hashedPayload].index);

        if (nextIndex == tokenIds.length) {
            // cleared the credits, delete the element
            delete storedCredits[hashedPayload];
            emit CreditCleared(hashedPayload);
        } else {
            // store the next index to mint
            storedCredits[hashedPayload] = StoredCredit(storedCredits[hashedPayload].srcChainId, storedCredits[hashedPayload].toAddress, nextIndex, true);
        }
    }

    // When a srcChain has the ability to transfer more chainIds in a single tx than the dst can do.
    // Needs the ability to iterate and stop if the minGasToTransferAndStore is not met
    function _creditTill(uint16 _srcChainId, address _toAddress, uint _startIndex, uint[] memory _tokenIds) internal returns (uint256){
        uint i = _startIndex;
        while (i < _tokenIds.length) {
            // if not enough gas to process, store this index for next loop
            if (gasleft() < minGasToTransferAndStore) break;

            _creditTo(_srcChainId, _toAddress, _tokenIds[i]);
            i++;
        }

        // indicates the next index to send of tokenIds,
        // if i == tokenIds.length, we are finished
        return i;
    }

    function setMinGasToTransferAndStore(uint256 _minGasToTransferAndStore) external onlyOwner {
        require(_minGasToTransferAndStore > 0);
        minGasToTransferAndStore = _minGasToTransferAndStore;
    }

    // ensures enough gas in adapter params to handle batch transfer gas amounts on the dst
    function setDstChainIdToTransferGas(uint16 _dstChainId, uint256 _dstChainIdToTransferGas) external onlyOwner {
        require(_dstChainIdToTransferGas > 0);
        dstChainIdToTransferGas[_dstChainId] = _dstChainIdToTransferGas;
    }

    // limit on src the amount of tokens to batch send
    function setDstChainIdToBatchLimit(uint16 _dstChainId, uint256 _dstChainIdToBatchLimit) external onlyOwner {
        require(_dstChainIdToBatchLimit > 0);
        dstChainIdToBatchLimit[_dstChainId] = _dstChainIdToBatchLimit;
    }

    function setRevenueManager(address _manager) external {
        require(msg.sender == revenueManager);
        revenueManager = _manager;
    }

    function setFeeBp(uint16 _feeBp) public virtual {
        require(msg.sender == revenueManager);
        require(_feeBp <= BP_DENOMINATOR);
        feeBp = _feeBp;
    }

    function _payONFTFee(uint _nativeFee) internal virtual returns (uint amount) {
        uint fee = _nativeFee * feeBp / BP_DENOMINATOR;
        amount = _nativeFee - fee;
        if (fee > 0) {
            (bool p,) = payable(revenueManager).call{value : (fee)}("");
            require(p, "!fee");
        }
    }

    function royaltyInfo(uint256, uint256 value) external view returns (address _receiver, uint256 _royaltyAmount) {
        _receiver = owner;
        _royaltyAmount = (value * royaltyAmount) / 10000;
    }

    function setRoyaltyAmount(uint24 _amount) external onlyOwner {
        royaltyAmount = _amount;
    }

    function transferOwnership(address _owner) external onlyOwner {
        owner = _owner;
    }

    function _debitFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId) internal virtual;

    function _creditTo(uint16 _srcChainId, address _toAddress, uint _tokenId) internal virtual;

    function _toSingletonArray(uint element) internal pure returns (uint[] memory) {
        uint[] memory array = new uint[](1);
        array[0] = element;
        return array;
    }
}

File 6 of 25 : ERC721Structs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

struct CreateParams {
    string name;
    string symbol;
    string uri;
    string tokensURI;
    uint24 maxSupply;
    bool isZeroIndexed;
    uint24 royaltyAmount;
    uint256 endTime;
}

struct MintParams {
    address collection;
    uint24 quantity;
    bytes32[] merkleProof;
    uint8 phaseId;
}

struct OmnichainMintParams {
    address collection;
    uint24 quantity;
    uint256 paid;
    uint8 phaseId;
    address minter;
}

struct Phase {
    uint256 from;
    uint256 to;
    uint24 maxPerAddress;
    uint256 price;
    bytes32 merkleRoot;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// SPDX-License-Identifier: MIT
/**
  ______ _____   _____ ______ ___  __ _  _  _ 
 |  ____|  __ \ / ____|____  |__ \/_ | || || |
 | |__  | |__) | |        / /   ) || | \| |/ |
 |  __| |  _  /| |       / /   / / | |\_   _/ 
 | |____| | \ \| |____  / /   / /_ | |  | |   
 |______|_|  \_\\_____|/_/   |____||_|  |_|   

 - github: https://github.com/estarriolvetch/ERC721Psi
 - npm: https://www.npmjs.com/package/erc721psi
                                          
 */

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "./solidity-bits/BitMaps.sol";


contract ERC721Psi is ERC165, IERC721 {
    using Strings for uint256;
    using BitMaps for BitMaps.BitMap;

    BitMaps.BitMap private _batchHead;

    string private _name;
    string private _symbol;

    mapping(uint256 => address) internal _owners;
    uint256 private _currentIndex;

    mapping(uint256 => address) private _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    function _setNextTokenId(uint256 _index) internal virtual {
        require(_currentIndex == 0);
        _currentIndex = _index;
    }

    function _nextTokenId() internal view virtual returns (uint256) {
        return _currentIndex;
    }

    function totalMinted() public view virtual returns (uint256) {
        return _currentIndex - _startTokenId();
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC165, IERC165)
        returns (bool)
    {
        return
            interfaceId == type(IERC721).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    function balanceOf(address owner)
        public 
        view 
        virtual 
        override 
        returns (uint) 
    {
        require(owner != address(0), "ERC721Psi: balance query for the zero address");

        uint count;
        for( uint i = _startTokenId(); i < _nextTokenId(); ++i ){
            if(_exists(i)){
                if( owner == ownerOf(i)){
                    ++count;
                }
            }
        }
        return count;
    }

    function ownerOf(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        (address owner, ) = _ownerAndBatchHeadOf(tokenId);
        return owner;
    }

    function _ownerAndBatchHeadOf(uint256 tokenId) internal view returns (address owner, uint256 tokenIdBatchHead){
        require(_exists(tokenId), "ERC721Psi: owner query for nonexistent token");
        tokenIdBatchHead = _getBatchHead(tokenId);
        owner = _owners[tokenIdBatchHead];
    }

    function name() public view virtual returns (string memory) {
        return _name;
    }

    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721Psi: approval to current owner");

        require(
            msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "ERC721Psi: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    function getApproved(uint256 tokenId)
        public
        view
        virtual
        override
        returns (address)
    {
        require(
            _exists(tokenId),
            "ERC721Psi: approved query for nonexistent token"
        );

        return _tokenApprovals[tokenId];
    }

    function setApprovalForAll(address operator, bool approved)
        public
        virtual
        override
    {
        require(operator != msg.sender, "ERC721Psi: approve to caller");

        _operatorApprovals[msg.sender][operator] = approved;
        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function isApprovedForAll(address owner, address operator)
        public
        view
        virtual
        override
        returns (bool)
    {
        return _operatorApprovals[owner][operator];
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        require(
            _isApprovedOrOwner(msg.sender, tokenId),
            "ERC721Psi: transfer caller is not owner nor approved"
        );

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(
            _isApprovedOrOwner(msg.sender, tokenId),
            "ERC721Psi: transfer caller is not owner nor approved"
        );
        _safeTransfer(from, to, tokenId, _data);
    }

    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(
            _checkOnERC721Received(from, to, tokenId, 1,_data),
            "ERC721Psi: transfer to non ERC721Receiver implementer"
        );
    }

    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return tokenId < _nextTokenId() && _startTokenId() <= tokenId;
    }

    function _isApprovedOrOwner(address spender, uint256 tokenId)
        internal
        view
        virtual
        returns (bool)
    {
        require(
            _exists(tokenId),
            "ERC721Psi: operator query for nonexistent token"
        );
        address owner = ownerOf(tokenId);
        return (spender == owner ||
            getApproved(tokenId) == spender ||
            isApprovedForAll(owner, spender));
    }

    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, quantity, "");
    }

    
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        uint256 nextTokenId = _nextTokenId();
        _mint(to, quantity);
        require(
            _checkOnERC721Received(address(0), to, nextTokenId, quantity, _data),
            "ERC721Psi: transfer to non ERC721Receiver implementer"
        );
    }


    function _mint(
        address to,
        uint256 quantity
    ) internal virtual {
        uint256 nextTokenId = _nextTokenId();
        
        require(quantity > 0, "ERC721Psi: quantity must be greater 0");
        require(to != address(0), "ERC721Psi: mint to the zero address");
        
        _beforeTokenTransfers(address(0), to, nextTokenId, quantity);
        _currentIndex += quantity;
        _owners[nextTokenId] = to;
        _batchHead.set(nextTokenId);

        uint256 toMasked;
        uint256 end = nextTokenId + quantity;

        assembly {
            toMasked := and(to, _BITMASK_ADDRESS)
            log4(
                0,
                0,
                _TRANSFER_EVENT_SIGNATURE,
                0,
                toMasked,
                nextTokenId
            )

            for {
                let tokenId := add(nextTokenId, 1)
            } iszero(eq(tokenId, end)) {
                tokenId := add(tokenId, 1)
            } {
                log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
            }
        }

        _afterTokenTransfers(address(0), to, nextTokenId, quantity);
    }

    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        (address owner, uint256 tokenIdBatchHead) = _ownerAndBatchHeadOf(tokenId);

        require(
            owner == from,
            "ERC721Psi: transfer of token that is not own"
        );
        require(to != address(0), "ERC721Psi: transfer to the zero address");

        _beforeTokenTransfers(from, to, tokenId, 1);

        _approve(address(0), tokenId);

        uint256 subsequentTokenId = tokenId + 1;

        if(!_batchHead.get(subsequentTokenId) &&  
            subsequentTokenId < _nextTokenId()
        ) {
            _owners[subsequentTokenId] = from;
            _batchHead.set(subsequentTokenId);
        }

        _owners[tokenId] = to;
        if(tokenId != tokenIdBatchHead) {
            _batchHead.set(tokenId);
        }

        emit Transfer(from, to, tokenId);

        _afterTokenTransfers(from, to, tokenId, 1);
    }

    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ownerOf(tokenId), to, tokenId);
    }

    function _checkOnERC721Received(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity,
        bytes memory _data
    ) private returns (bool r) {
        if (isContract(to)) {
            r = true;
            for(uint256 tokenId = startTokenId; tokenId < startTokenId + quantity; tokenId++){
                try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data) returns (bytes4 retval) {
                    r = r && retval == IERC721Receiver.onERC721Received.selector;
                } catch (bytes memory reason) {
                    if (reason.length == 0) {
                        revert("ERC721Psi: transfer to non ERC721Receiver implementer");
                    } else {
                        assembly {
                            revert(add(32, reason), mload(reason))
                        }
                    }
                }
            }
            return r;
        } else {
            return true;
        }
    }

    function _getBatchHead(uint256 tokenId) internal view returns (uint256 tokenIdBatchHead) {
        tokenIdBatchHead = _batchHead.scanForward(tokenId); 
    }

    function isContract(address account) internal view returns (bool) {
        return account.code.length > 0;
    }

    function totalSupply() public virtual view returns (uint256) {
        return totalMinted();
    }

    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}

pragma solidity ^0.8.7;

import "../solidity-bits/BitMaps.sol";
import "../ERC721Psi.sol";

/**
    @dev This extension follows the AddressData format of ERC721A, so
    it can be a dropped-in replacement for the contract that requires AddressData
*/
abstract contract ERC721PsiAddressData is ERC721Psi {
    // Mapping owner address to address data
    mapping(address => AddressData) _addressData;

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }


    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address _owner)
    public
    view
    virtual
    override
    returns (uint)
    {
        return uint256(_addressData[_owner].balance);
    }

    function mintedOf(address _owner)
    public
    view
    virtual
    returns (uint)
    {
        return uint256(_addressData[_owner].numberMinted);
    }

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal override virtual {
        require(quantity < 2 ** 64);
        uint64 _quantity = uint64(quantity);

        if(from != address(0)){
            _addressData[from].balance -= _quantity;
        } else {
            // Mint
            _addressData[to].numberMinted += _quantity;
        }

        if(to != address(0)){
            _addressData[to].balance += _quantity;
        } else {
            // Burn
            _addressData[from].numberBurned += _quantity;
        }
        super._afterTokenTransfers(from, to, startTokenId, quantity);
    }
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/**
 * @dev Interface of the ONFT Core standard
 */
interface IONFT721Core is IERC165 {
    /**
     * @dev Emitted when `_tokenIds[]` are moved from the `_sender` to (`_dstChainId`, `_toAddress`)
     * `_nonce` is the outbound nonce from
     */
    event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes indexed _toAddress, uint[] _tokenIds);
    event ReceiveFromChain(uint16 indexed _srcChainId, bytes indexed _srcAddress, address indexed _toAddress, uint[] _tokenIds);

    /**
     * @dev Emitted when `_payload` was received from lz, but not enough gas to deliver all tokenIds
     */
    event CreditStored(bytes32 _hashedPayload, bytes _payload);
    /**
     * @dev Emitted when `_hashedPayload` has been completely delivered
     */
    event CreditCleared(bytes32 _hashedPayload);

    event CallONFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, address indexed _receiver);

    /**
     * @dev send token `_tokenId` to (`_dstChainId`, `_toAddress`) from `_from`
     * `_toAddress` can be any size depending on the `dstChainId`.
     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services
     */
    function sendFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;

    /**
     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
     * _dstChainId - L0 defined chain id to send tokens too
     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
     * _tokenId - token Id to transfer
     * _useZro - indicates to use zro to pay L0 fees
     * _adapterParams - flexible bytes array to indicate messaging adapter services in L0
     */
    function estimateSendFee(uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);

    /**
     * @dev send tokens `_tokenIds[]` to (`_dstChainId`, `_toAddress`) from `_from`
     * `_toAddress` can be any size depending on the `dstChainId`.
     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services
     */
    function sendBatchFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;

    /**
     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
     * _dstChainId - L0 defined chain id to send tokens too
     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
     * _tokenIds[] - token Ids to transfer
     * _useZro - indicates to use zro to pay L0 fees
     * _adapterParams - flexible bytes array to indicate messaging adapter services in L0
     */
    function estimateSendBatchFee(uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./LzApp.sol";
import "../util/ExcessivelySafeCall.sol";

abstract contract NonblockingLzApp is LzApp {
    using ExcessivelySafeCall for address;

    constructor(address _endpoint) LzApp(_endpoint) {}

    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;

    event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);
    event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);

    function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual override {
        (bool success, bytes memory reason) = address(this).excessivelySafeCall(gasleft(), 150, abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload));
        if (!success) {
            _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);
        }
    }

    function _storeFailedMessage(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload, bytes memory _reason) internal virtual {
        failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);
        emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);
    }

    function nonblockingLzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual {
        require(msg.sender == address(this), "NonblockingLzApp: caller must be LzApp");
        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
    }

    function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;

    function retryMessage(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public payable virtual {
        bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];
        require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message");
        require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload");
        failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);
        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
        emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);
    }
}

// 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 14 of 25 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

// 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);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../interfaces/ILayerZeroReceiver.sol";
import "../interfaces/ILayerZeroUserApplicationConfig.sol";
import "../interfaces/ILayerZeroEndpoint.sol";
import "../util/BytesLib.sol";

abstract contract LzApp is ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
    uint constant public DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;

    ILayerZeroEndpoint public immutable lzEndpoint;
    mapping(uint16 => bytes) public trustedRemoteLookup;
    mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;
    address public owner;

    event SetTrustedRemote(uint16 _remoteChainId, bytes _path);
    event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);
    event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);

    modifier onlyOwner {
        require(msg.sender == owner, "LzApp: caller is not the owner");
        _;
    }

    constructor(address _endpoint) {
        lzEndpoint = ILayerZeroEndpoint(_endpoint);
        owner = msg.sender;
    }

    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual override {
        require(msg.sender == address(lzEndpoint), "LzApp: invalid endpoint caller");

        bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];
        require(_srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote), "LzApp: invalid source sending contract");

        _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
    }

    function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;

    function _lzSend(uint16 _dstChainId, bytes memory _payload, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, uint _nativeFee) internal virtual {
        bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];
        require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
        lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function _checkGasLimit(uint16 _dstChainId, uint16 _type, bytes memory _adapterParams, uint _extraGas) internal view virtual {
        uint providedGasLimit = _getGasLimit(_adapterParams);
        uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;
        require(minGasLimit > 0, "LzApp: minGasLimit not set");
        require(providedGasLimit >= minGasLimit, "LzApp: gas limit is too low");
    }

    function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {
        require(_adapterParams.length >= 34, "LzApp: invalid adapterParams");
        assembly {
            gasLimit := mload(add(_adapterParams, 34))
        }
    }

    function getConfig(uint16 _version, uint16 _chainId, address, uint _configType) external view returns (bytes memory) {
        return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);
    }

    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external override onlyOwner {
        lzEndpoint.setConfig(_version, _chainId, _configType, _config);
    }

    function setSendVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setSendVersion(_version);
    }

    function setReceiveVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setReceiveVersion(_version);
    }

    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
        lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
    }

    function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {
        trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));
        emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);
    }

    function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner {
        require(_minGas > 0);
        minDstGasLookup[_dstChainId][_packetType] = _minGas;
        emit SetMinDstGas(_dstChainId, _packetType, _minGas);
    }

    function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {
        bytes memory trustedSource = trustedRemoteLookup[_srcChainId];
        return keccak256(trustedSource) == keccak256(_srcAddress);
    }
}

File 17 of 25 : ExcessivelySafeCall.sol
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.7.6;

library ExcessivelySafeCall {
    uint256 constant LOW_28_MASK =
    0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    function excessivelySafeCall(
        address _target,
        uint256 _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal returns (bool, bytes memory) {
        // set up for assembly call
        uint256 _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := call(
            _gas, // gas
            _target, // recipient
            0, // ether value
            add(_calldata, 0x20), // inloc
            mload(_calldata), // inlen
            0, // outloc
            0 // outlen
            )
        // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
        // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
        // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

interface ILayerZeroReceiver {
    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

interface ILayerZeroUserApplicationConfig {
    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;

    function setSendVersion(uint16 _version) external;

    function setReceiveVersion(uint16 _version) external;

    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}

// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

import "./ILayerZeroUserApplicationConfig.sol";

interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
    function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;

    function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external;

    function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);

    function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);

    function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee);

    function getChainId() external view returns (uint16);

    function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;

    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);

    function getSendLibraryAddress(address _userApplication) external view returns (address);

    function getReceiveLibraryAddress(address _userApplication) external view returns (address);

    function isSendingPayload() external view returns (bool);

    function isReceivingPayload() external view returns (bool);

    function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory);

    function getSendVersion(address _userApplication) external view returns (uint16);

    function getReceiveVersion(address _userApplication) external view returns (uint16);
}

// SPDX-License-Identifier: Unlicense
/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <[email protected]>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity >=0.8.0 <0.9.0;


library BytesLib {
    function slice(
        bytes memory _bytes,
        uint256 _start,
        uint256 _length
    )
    internal
    pure
    returns (bytes memory)
    {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
                tempBytes := mload(0x40)

            // The first word of the slice result is potentially a partial
            // word read from the original array. To read it, we calculate
            // the length of that partial word and start copying that many
            // bytes into the array. The first word we copy will start with
            // data we don't care about, but the last `lengthmod` bytes will
            // land at the beginning of the contents of the new array. When
            // we're done copying, we overwrite the full first word with
            // the actual length of the slice.
                let lengthmod := and(_length, 31)

            // The multiplication in the next line is necessary
            // because when slicing multiples of 32 bytes (lengthmod == 0)
            // the following copy loop was copying the origin's length
            // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                // The multiplication in the next line has the same exact purpose
                // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

            //update free-memory pointer
            //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
            //zero out the 32 bytes slice we are about to return
            //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
        require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

// SPDX-License-Identifier: MIT
/**
   _____       ___     ___ __           ____  _ __      
  / ___/____  / (_)___/ (_) /___  __   / __ )(_) /______
  \__ \/ __ \/ / / __  / / __/ / / /  / __  / / __/ ___/
 ___/ / /_/ / / / /_/ / / /_/ /_/ /  / /_/ / / /_(__  ) 
/____/\____/_/_/\__,_/_/\__/\__, /  /_____/_/\__/____/  
                           /____/                        

- npm: https://www.npmjs.com/package/solidity-bits
- github: https://github.com/estarriolvetch/solidity-bits

 */
pragma solidity ^0.8.0;

import "./BitScan.sol";

library BitMaps {
    using BitScan for uint256;
    uint256 private constant MASK_INDEX_ZERO = (1 << 255);
    uint256 private constant MASK_FULL = type(uint256).max;

    struct BitMap {
        mapping(uint256 => uint256) _data;
    }

    function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {
        uint256 bucket = index >> 8;
        uint256 mask = MASK_INDEX_ZERO >> (index & 0xff);
        return bitmap._data[bucket] & mask != 0;
    }

    function set(BitMap storage bitmap, uint256 index) internal {
        uint256 bucket = index >> 8;
        uint256 mask = MASK_INDEX_ZERO >> (index & 0xff);
        bitmap._data[bucket] |= mask;
    }

    function scanForward(BitMap storage bitmap, uint256 index) internal view returns (uint256 setBitIndex) {
        uint256 bucket = index >> 8;

        // index within the bucket
        uint256 bucketIndex = (index & 0xff);

        // load a bitboard from the bitmap.
        uint256 bb = bitmap._data[bucket];

        // offset the bitboard to scan from `bucketIndex`.
        bb = bb >> (0xff ^ bucketIndex); // bb >> (255 - bucketIndex)
        
        if(bb > 0) {
            unchecked {
                setBitIndex = (bucket << 8) | (bucketIndex -  bb.bitScanForward256());    
            }
        } else {
            while(true) {
                require(bucket > 0, "BitMaps: The set bit before the index doesn't exist.");
                unchecked {
                    bucket--;
                }
                // No offset. Always scan from the least significiant bit now.
                bb = bitmap._data[bucket];
                
                if(bb > 0) {
                    unchecked {
                        setBitIndex = (bucket << 8) | (255 -  bb.bitScanForward256());
                        break;
                    }
                } 
            }
        }
    }
}

// SPDX-License-Identifier: MIT
/**
   _____       ___     ___ __           ____  _ __      
  / ___/____  / (_)___/ (_) /___  __   / __ )(_) /______
  \__ \/ __ \/ / / __  / / __/ / / /  / __  / / __/ ___/
 ___/ / /_/ / / / /_/ / / /_/ /_/ /  / /_/ / / /_(__  ) 
/____/\____/_/_/\__,_/_/\__/\__, /  /_____/_/\__/____/  
                           /____/                        

- npm: https://www.npmjs.com/package/solidity-bits
- github: https://github.com/estarriolvetch/solidity-bits

 */

pragma solidity ^0.8.0;


library BitScan {
    uint256 constant private DEBRUIJN_256 = 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff;
    bytes constant private LOOKUP_TABLE_256 = hex"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8";

    /**
        @dev Isolate the least significant set bit.
     */ 
    function isolateLS1B256(uint256 bb) pure internal returns (uint256) {
        require(bb > 0);
        unchecked {
            return bb & (0 - bb);
        }
    } 

    /**
        @dev Isolate the most significant set bit.
     */ 
    function isolateMS1B256(uint256 bb) pure internal returns (uint256) {
        require(bb > 0);
        unchecked {
            bb |= bb >> 128;
            bb |= bb >> 64;
            bb |= bb >> 32;
            bb |= bb >> 16;
            bb |= bb >> 8;
            bb |= bb >> 4;
            bb |= bb >> 2;
            bb |= bb >> 1;
            
            return (bb >> 1) + 1;
        }
    } 

    /**
        @dev Find the index of the lest significant set bit. (trailing zero count)
     */ 
    function bitScanForward256(uint256 bb) pure internal returns (uint8) {
        unchecked {
            return uint8(LOOKUP_TABLE_256[(isolateLS1B256(bb) * DEBRUIJN_256) >> 248]);
        }   
    }

    /**
        @dev Find the index of the most significant set bit.
     */ 
    function bitScanReverse256(uint256 bb) pure internal returns (uint8) {
        unchecked {
            return 255 - uint8(LOOKUP_TABLE_256[((isolateMS1B256(bb) * DEBRUIJN_256) >> 248)]);
        }   
    }

    function log2(uint256 bb) pure internal returns (uint8) {
        unchecked {
            return uint8(LOOKUP_TABLE_256[(isolateMS1B256(bb) * DEBRUIJN_256) >> 248]);
        } 
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"uri","type":"string"},{"internalType":"string","name":"tokensURI","type":"string"},{"internalType":"uint24","name":"maxSupply","type":"uint24"},{"internalType":"bool","name":"isZeroIndexed","type":"bool"},{"internalType":"uint24","name":"royaltyAmount","type":"uint24"},{"internalType":"uint256","name":"endTime","type":"uint256"}],"internalType":"struct CreateParams","name":"params","type":"tuple"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_dropsManagerAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","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":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"_receiver","type":"address"}],"name":"CallONFTReceivedSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"}],"name":"CreditCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"CreditStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"_toAddress","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"ReceiveFromChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_payloadHash","type":"bytes32"}],"name":"RetryMessageSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"bytes","name":"_toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"SendToChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_type","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_minDstGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_path","type":"bytes"}],"name":"SetTrustedRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"SetTrustedRemoteAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_PAYLOAD_SIZE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FUNCTION_TYPE_SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"clearCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectionURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dropsManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToBatchLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToTransferGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendBatchFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeBp","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"isTrustedRemote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isZeroIndexed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minGasToTransferAndStore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"},{"internalType":"uint24","name":"_quantity","type":"uint24"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint8","name":"_phaseId","type":"uint8"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_phaseId","type":"uint8"}],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"mintedOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"preMintToTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"royaltyAmount","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendBatchFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"setDstChainIdToBatchLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"}],"name":"setDstChainIdToTransferGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_feeBp","type":"uint16"}],"name":"setFeeBp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"setMinGasToTransferAndStore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_phaseId","type":"uint8"},{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"uint24","name":"_maxPerAddress","type":"uint24"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setRevenueManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"_amount","type":"uint24"}],"name":"setRoyaltyAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setTokensURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"setTrustedRemoteAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"},{"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"},{"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"setTrustedRemoteAndLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storedCredits","outputs":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bool","name":"creditsRemain","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]

0x60c0604052736ef0871ed810f323ea516a77b0988353b667dfa460a0523480156200002957600080fd5b5060405162005883380380620058838339810160408190526200004c91620003ef565b8251602084015173b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76080819052600280546001600160a01b0319163317905560016004556203d0909050600655600580546001600160b01b0319167561104fbe07ecc735d8d84422c7f045f8d29dbf1503e81790558151620000ca90600b906020850190620001fd565b508051620000e090600c906020840190620001fd565b5050601480546001600160a01b0319166001600160a01b03841617905550606083015180516200011991601591602090910190620001fd565b5060808301516012805462ffffff191662ffffff909216919091179055604083015180516200015191601391602090910190620001fd565b5060a08301516014805460ff60a01b1916600160a01b9215158302179081905560e08501516016556200019c9160ff9104166200019057600162000193565b60005b60ff16620001ea565b50600280546001600160a01b039092166001600160a01b031990921691909117905560c001516005805462ffffff909216600160b01b0262ffffff60b01b1990921691909117905562000580565b600e5415620001f857600080fd5b600e55565b8280546200020b9062000543565b90600052602060002090601f0160209004810192826200022f57600085556200027a565b82601f106200024a57805160ff19168380011785556200027a565b828001600101855582156200027a579182015b828111156200027a5782518255916020019190600101906200025d565b50620002889291506200028c565b5090565b5b808211156200028857600081556001016200028d565b634e487b7160e01b600052604160045260246000fd5b60405161010081016001600160401b0381118282101715620002df57620002df620002a3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620003105762000310620002a3565b604052919050565b600082601f8301126200032a57600080fd5b81516001600160401b03811115620003465762000346620002a3565b60206200035c601f8301601f19168201620002e5565b82815285828487010111156200037157600080fd5b60005b838110156200039157858101830151828201840152820162000374565b83811115620003a35760008385840101525b5095945050505050565b805162ffffff81168114620003c157600080fd5b919050565b80518015158114620003c157600080fd5b80516001600160a01b0381168114620003c157600080fd5b6000806000606084860312156200040557600080fd5b83516001600160401b03808211156200041d57600080fd5b9085019061010082880312156200043357600080fd5b6200043d620002b9565b8251828111156200044d57600080fd5b6200045b8982860162000318565b8252506020830151828111156200047157600080fd5b6200047f8982860162000318565b6020830152506040830151828111156200049857600080fd5b620004a68982860162000318565b604083015250606083015182811115620004bf57600080fd5b620004cd8982860162000318565b606083015250620004e160808401620003ad565b6080820152620004f460a08401620003c6565b60a08201526200050760c08401620003ad565b60c082015260e083015160e08201528095505050506200052a60208501620003d7565b91506200053a60408501620003d7565b90509250925092565b600181811c908216806200055857607f821691505b602082108114156200057a57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a051615290620005f36000396000818161183b01528181611f2e0152818161232701526130010152600081816109f001528181610c6001528181610f860152818161120e015281816114ea01528181611e01015281816124000152818161254a015261383801526152906000f3fe6080604052600436106102e85760003560e01c80621d3567146102ed57806301ffc9a71461030f57806306fdde031461034457806307e0db1714610366578063081812fc14610386578063095ea7b3146103be5780630b4cad4c146103de57806310ddb137146103fe57806318160ddd1461041e57806322a3ecf91461044157806323b872dd146104c45780632a205e3d146104e45780632a55205a146105195780632dd0066e146105585780632e4a33cb1461056d5780633d8b38f61461058d57806342842e0e146105ad57806342d65a8d146105cd57806346a43816146105ed578063482881901461060d5780634ac3f4ff14610623578063519056361461065057806352a284a2146106635780635b8c41e614610683578063617692dd146106d25780636352211e1461071857806366ad5c8a146107385780636da7870b1461075857806370a08231146107785780637533d788146107b75780637c6e551d146107d75780638147ef371461080e578063893d20e81461082e5780638cfd8f5c1461084c5780638da5cb5b146108845780638ffa1f2a146108a457806395d89b41146108c45780639ea5d6b1146108d9578063a22cb465146108f9578063a2309ff814610919578063a5097ebf1461092e578063a6c3d16514610943578063a7e0d43d14610963578063ab3ffb9314610983578063af3fb21c14610996578063b19ab245146109be578063b353aaa7146109de578063b88d4fde14610a12578063c446183414610a32578063c4ed6f5814610a48578063c87b56dd14610a63578063cbed8b9c14610a83578063d112fe3314610aa3578063d12473a514610ac3578063d1deba1f14610ae3578063d5abeb0114610af6578063d72822bb14610b12578063df2a5b3b14610b32578063e8a3d48514610b52578063e9038e1f14610b67578063e985e9c514610b87578063efc585ad14610ba7578063f235364114610bc8578063f2fde38b14610be8578063f5ecbdbc14610c08578063fa25f9b614610c28575b600080fd5b3480156102f957600080fd5b5061030d610308366004613d45565b610c55565b005b34801561031b57600080fd5b5061032f61032a366004613dee565b610e86565b60405190151581526020015b60405180910390f35b34801561035057600080fd5b50610359610eb1565b60405161033b9190613e6a565b34801561037257600080fd5b5061030d610381366004613e7d565b610f43565b34801561039257600080fd5b506103a66103a1366004613e98565b610fee565b6040516001600160a01b03909116815260200161033b565b3480156103ca57600080fd5b5061030d6103d9366004613ed1565b611079565b3480156103ea57600080fd5b5061030d6103f9366004613e98565b61118f565b34801561040a57600080fd5b5061030d610419366004613e7d565b6111cb565b34801561042a57600080fd5b50610433611245565b60405190815260200161033b565b34801561044d57600080fd5b5061049561045c366004613e98565b60096020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b039093166020850152918301521515606082015260800161033b565b3480156104d057600080fd5b5061030d6104df366004613efd565b611254565b3480156104f057600080fd5b506105046104ff366004614017565b611285565b6040805192835260208301919091520161033b565b34801561052557600080fd5b506105396105343660046140a9565b6112ab565b604080516001600160a01b03909316835260208301919091520161033b565b34801561056457600080fd5b506103596112ed565b34801561057957600080fd5b5061030d6105883660046140cb565b61137b565b34801561059957600080fd5b5061032f6105a83660046140e8565b6113c2565b3480156105b957600080fd5b5061030d6105c8366004613efd565b61148e565b3480156105d957600080fd5b5061030d6105e83660046140e8565b6114a9565b3480156105f957600080fd5b5061030d61060836600461413a565b611551565b34801561061957600080fd5b5061043360065481565b34801561062f57600080fd5b5061043361063e366004613e7d565b60076020526000908152604090205481565b61030d61065e36600461419e565b61162e565b34801561066f57600080fd5b5061030d61067e36600461426a565b611645565b34801561068f57600080fd5b5061043361069e366004614285565b6003602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b3480156106de57600080fd5b506104336106ed3660046140cb565b6001600160a01b0316600090815260116020526040902054600160401b90046001600160401b031690565b34801561072457600080fd5b506103a6610733366004613e98565b611693565b34801561074457600080fd5b5061030d610753366004613d45565b6116a7565b34801561076457600080fd5b5061030d610773366004613e98565b611783565b34801561078457600080fd5b506104336107933660046140cb565b6001600160a01b03166000908152601160205260409020546001600160401b031690565b3480156107c357600080fd5b506103596107d2366004613e7d565b611807565b3480156107e357600080fd5b506005546107fa90600160b01b900462ffffff1681565b60405162ffffff909116815260200161033b565b34801561081a57600080fd5b506104336108293660046142f3565b611820565b34801561083a57600080fd5b506002546001600160a01b03166103a6565b34801561085857600080fd5b5061043361086736600461430e565b600160209081526000928352604080842090915290825290205481565b34801561089057600080fd5b506002546103a6906001600160a01b031681565b3480156108b057600080fd5b5061030d6108bf366004614338565b6118bd565b3480156108d057600080fd5b50610359611a9a565b3480156108e557600080fd5b5061030d6108f436600461436c565b611aa9565b34801561090557600080fd5b5061030d610914366004614388565b611af7565b34801561092557600080fd5b50610433611bbb565b34801561093a57600080fd5b50610359611bd2565b34801561094f57600080fd5b5061030d61095e3660046140e8565b611bdf565b34801561096f57600080fd5b5061030d61097e366004613e7d565b611c80565b61030d61099136600461444a565b611cc8565b3480156109a257600080fd5b506109ab600181565b60405161ffff909116815260200161033b565b3480156109ca57600080fd5b5061030d6109d93660046144ff565b611cd7565b3480156109ea57600080fd5b506103a67f000000000000000000000000000000000000000000000000000000000000000081565b348015610a1e57600080fd5b5061030d610a2d366004614547565b611d26565b348015610a3e57600080fd5b5061043361271081565b348015610a5457600080fd5b506005546109ab9061ffff1681565b348015610a6f57600080fd5b50610359610a7e366004613e98565b611d5e565b348015610a8f57600080fd5b5061030d610a9e3660046145b2565b611dc0565b348015610aaf57600080fd5b5061030d610abe366004614620565b611e77565b348015610acf57600080fd5b5061030d610ade36600461436c565b611f99565b61030d610af1366004613d45565b611fe7565b348015610b0257600080fd5b506012546107fa9062ffffff1681565b348015610b1e57600080fd5b506014546103a6906001600160a01b031681565b348015610b3e57600080fd5b5061030d610b4d3660046146e6565b6121fd565b348015610b5e57600080fd5b50610359612296565b348015610b7357600080fd5b5061030d610b82366004614722565b6122be565b348015610b9357600080fd5b5061032f610ba236600461477a565b612393565b348015610bb357600080fd5b5060145461032f90600160a01b900460ff1681565b348015610bd457600080fd5b50610504610be33660046147a8565b6123c1565b348015610bf457600080fd5b5061030d610c033660046140cb565b6124cd565b348015610c1457600080fd5b50610359610c23366004614825565b612519565b348015610c3457600080fd5b50610433610c43366004613e7d565b60086020526000908152604090205481565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610cd25760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526020819052604081208054610cf090614872565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1c90614872565b8015610d695780601f10610d3e57610100808354040283529160200191610d69565b820191906000526020600020905b815481529060010190602001808311610d4c57829003601f168201915b50505050509050805186869050148015610d84575060008151115b8015610dac575080516020820120604051610da290889088906148a7565b6040518091039020145b610e075760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610cc9565b610e7d8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506125d992505050565b50505050505050565b60006001600160e01b0319821663365a0c7b60e21b1480610eab5750610eab82612652565b92915050565b6060600b8054610ec090614872565b80601f0160208091040260200160405190810160405280929190818152602001828054610eec90614872565b8015610f395780601f10610f0e57610100808354040283529160200191610f39565b820191906000526020600020905b815481529060010190602001808311610f1c57829003601f168201915b5050505050905090565b6002546001600160a01b03163314610f6d5760405162461bcd60e51b8152600401610cc9906148b7565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610fd357600080fd5b505af1158015610fe7573d6000803e3d6000fd5b5050505050565b6000610ff982612677565b61105d5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610cc9565b506000908152600f60205260409020546001600160a01b031690565b600061108482611693565b9050806001600160a01b0316836001600160a01b031614156110f45760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b6064820152608401610cc9565b336001600160a01b038216148061111057506111108133612393565b6111805760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527a081bdddb995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b602a1b6064820152608401610cc9565b61118a838361269c565b505050565b6002546001600160a01b031633146111b95760405162461bcd60e51b8152600401610cc9906148b7565b600081116111c657600080fd5b600655565b6002546001600160a01b031633146111f55760405162461bcd60e51b8152600401610cc9906148b7565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb13790602401610fb9565b600061124f611bbb565b905090565b61125e338261270a565b61127a5760405162461bcd60e51b8152600401610cc9906148ee565b61118a8383836127d7565b60008061129d8787611296886129b7565b87876123c1565b915091509550959350505050565b6002546005546001600160a01b0390911690600090612710906112da90600160b01b900462ffffff1685614958565b6112e4919061498d565b90509250929050565b601580546112fa90614872565b80601f016020809104026020016040519081016040528092919081815260200182805461132690614872565b80156113735780601f1061134857610100808354040283529160200191611373565b820191906000526020600020905b81548152906001019060200180831161135657829003601f168201915b505050505081565b6005546201000090046001600160a01b0316331461139857600080fd5b600580546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b61ffff8316600090815260208190526040812080548291906113e390614872565b80601f016020809104026020016040519081016040528092919081815260200182805461140f90614872565b801561145c5780601f106114315761010080835404028352916020019161145c565b820191906000526020600020905b81548152906001019060200180831161143f57829003601f168201915b5050505050905083836040516114739291906148a7565b60405180910390208180519060200120149150509392505050565b61118a83838360405180602001604052806000815250611d26565b6002546001600160a01b031633146114d35760405162461bcd60e51b8152600401610cc9906148b7565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d90611523908690869086906004016149ca565b600060405180830381600087803b15801561153d57600080fd5b505af1158015610e7d573d6000803e3d6000fd5b6002546001600160a01b0316331461157b5760405162461bcd60e51b8152600401610cc9906148b7565b60008211801561158b5750600081115b61159457600080fd5b61ffff85166000908152600860209081526040808320859055600782529182902083905590516115ca91869186913091016149e8565b60408051601f1981840301815291815261ffff87166000908152602081815291902082516115fd93919290910190613c36565b5060008051602061511b83398151915285858560405161161f939291906149ca565b60405180910390a15050505050565b610e7d87878761163d886129b7565b878787612a02565b6002546001600160a01b0316331461166f5760405162461bcd60e51b8152600401610cc9906148b7565b6005805462ffffff909216600160b01b0262ffffff60b01b19909216919091179055565b60008061169f83612bd8565b509392505050565b3330146117055760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610cc9565b61177b8686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612c6f92505050565b505050505050565b6002546001600160a01b031633146117ad5760405162461bcd60e51b8152600401610cc9906148b7565b60165442106117bb57600080fd5b60125462ffffff16156117ee57806117d1611bbb565b6117db9190614a09565b60125462ffffff1610156117ee57600080fd5b600254611804906001600160a01b031682612dd8565b50565b600060208190529081526040902080546112fa90614872565b604051638147ef3760e01b815260ff821660048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638147ef379060240160206040518083038186803b15801561188557600080fd5b505afa158015611899573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eab9190614a21565b600260045414156118e05760405162461bcd60e51b8152600401610cc990614a3a565b6002600481905581516020808401919091206000818152600990925260409091209091015460ff1661191157600080fd5b6000828060200190518101906119279190614ab6565b600084815260096020526040812080546001909101549294509092506119639161ffff8216916201000090046001600160a01b03169085612df2565b600084815260096020526040902060010154909150811161198357600080fd5b81518114156119fb5760008381526009602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba233906119ee9085815260200190565b60405180910390a1611a8f565b60408051608081018252600085815260096020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b505060016004555050565b6060600c8054610ec090614872565b6002546001600160a01b03163314611ad35760405162461bcd60e51b8152600401610cc9906148b7565b60008111611ae057600080fd5b61ffff909116600090815260076020526040902055565b6001600160a01b038216331415611b4f5760405162461bcd60e51b815260206004820152601c60248201527b22a9219b9918a839b49d1030b8383937bb32903a379031b0b63632b960211b6044820152606401610cc9565b3360008181526010602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000611bc5612e44565b600e5461124f9190614b70565b601380546112fa90614872565b6002546001600160a01b03163314611c095760405162461bcd60e51b8152600401610cc9906148b7565b818130604051602001611c1e939291906149e8565b60408051601f1981840301815291815261ffff8516600090815260208181529190208251611c5193919290910190613c36565b5060008051602061511b833981519152838383604051611c73939291906149ca565b60405180910390a1505050565b6005546201000090046001600160a01b03163314611c9d57600080fd5b6127108161ffff161115611cb057600080fd5b6005805461ffff191661ffff92909216919091179055565b610e7d87878787878787612a02565b6002546001600160a01b03163314611d015760405162461bcd60e51b8152600401610cc9906148b7565b6016544210611d0f57600080fd5b8051611d22906015906020840190613c36565b5050565b611d30338361270a565b611d4c5760405162461bcd60e51b8152600401610cc9906148ee565b611d5884848484612e6a565b50505050565b60125460609062ffffff161580611d81575060158054611d7d90614872565b1590505b15611d8e57610eab612296565b6015611d9983612e9f565b604051602001611daa929190614c21565b6040516020818303038152906040529050919050565b6002546001600160a01b03163314611dea5760405162461bcd60e51b8152600401610cc9906148b7565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c90611e3e9088908890889088908890600401614c75565b600060405180830381600087803b158015611e5857600080fd5b505af1158015611e6c573d6000803e3d6000fd5b505050505050505050565b60026004541415611e9a5760405162461bcd60e51b8152600401610cc990614a3a565b60026004556014546001600160a01b03163314611eb657600080fd5b611ec284848484612f9c565b611efb5760405162461bcd60e51b815260206004820152600a602482015269085a5cd05b1b1bddd95960b21b6044820152606401610cc9565b60405163b124e2f760e01b81526001600160a01b03858116600483015260ff8316602483015262ffffff851660448301527f0000000000000000000000000000000000000000000000000000000000000000169063b124e2f790606401600060405180830381600087803b158015611f7257600080fd5b505af1158015611f86573d6000803e3d6000fd5b50505050611a8f848462ffffff16613096565b6002546001600160a01b03163314611fc35760405162461bcd60e51b8152600401610cc9906148b7565b60008111611fd057600080fd5b61ffff909116600090815260086020526040902055565b61ffff8616600090815260036020526040808220905161200a90889088906148a7565b90815260408051602092819003830190206001600160401b0387166000908152925290205490508061208a5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610cc9565b80838360405161209b9291906148a7565b6040518091039020146120fa5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610cc9565b61ffff8716600090815260036020526040808220905161211d90899089906148a7565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f880182900482028301820190528682526121b5918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612c6f92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516121ec959493929190614cae565b60405180910390a150505050505050565b6002546001600160a01b031633146122275760405162461bcd60e51b8152600401610cc9906148b7565b6000811161223457600080fd5b61ffff83811660008181526001602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611c73565b606060136040516020016122aa9190614ce9565b604051602081830303815290604052905090565b6002546001600160a01b031633146122e85760405162461bcd60e51b8152600401610cc9906148b7565b60405163e9038e1f60e01b815260ff8716600482015260248101869052604481018590526064810184905262ffffff8316608482015260a481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9038e1f9060c401600060405180830381600087803b15801561237357600080fd5b505af1158015612387573d6000803e3d6000fd5b50505050505050505050565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b600080600086866040516020016123d9929190614d40565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb109061243d908b90309086908b908b90600401614d65565b604080518083038186803b15801561245457600080fd5b505afa158015612468573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248c9190614db9565b6005549194509250600090612710906124a99061ffff1686614958565b6124b3919061498d565b90506124bf8185614a09565b935050509550959350505050565b6002546001600160a01b031633146124f75760405162461bcd60e51b8152600401610cc9906148b7565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc9060840160006040518083038186803b15801561259457600080fd5b505afa1580156125a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125d09190810190614ddd565b95945050505050565b60008061263c5a60966366ad5c8a60e01b898989896040516024016126019493929190614e11565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190613217565b915091508161177b5761177b86868686856132a1565b60006001600160e01b031982166380ac58cd60e01b1480610eab5750610eab8261332f565b6000612682600e5490565b82108015610eab575081612694612e44565b111592915050565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b03841690811790915581906126d182611693565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061271582612677565b6127795760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610cc9565b600061278483611693565b9050806001600160a01b0316846001600160a01b031614806127bf5750836001600160a01b03166127b484610fee565b6001600160a01b0316145b806127cf57506127cf8185612393565b949350505050565b6000806127e383612bd8565b91509150846001600160a01b0316826001600160a01b03161461285d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b6064820152608401610cc9565b6001600160a01b0384166128c35760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b6064820152608401610cc9565b6128ce60008461269c565b60006128db846001614a09565b600881901c6000908152600a6020526040902054909150600160ff1b60ff83161c1615801561290b5750600e5481105b15612942576000818152600d6020526040902080546001600160a01b0319166001600160a01b038816179055612942600a8261337f565b6000848152600d6020526040902080546001600160a01b0319166001600160a01b03871617905581841461297b5761297b600a8561337f565b83856001600160a01b0316876001600160a01b031660008051602061513b83398151915260405160405180910390a461177b86868660016133ab565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106129f1576129f1614e4f565b602090810291909101015292915050565b6000845111612a495760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610cc9565b61ffff861660009081526007602052604090205484511115612ab85760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610cc9565b60005b8451811015612afb57612ae9888888888581518110612adc57612adc614e4f565b6020026020010151613529565b80612af381614e65565b915050612abb565b5060008585604051602001612b11929190614d40565b6040516020818303038152906040529050612b56876001848851600860008d61ffff1661ffff16815260200190815260200160002054612b519190614958565b61356d565b6000612b6134613647565b9050612b71888387878786613719565b86604051612b7f9190614e80565b6040518091039020896001600160a01b03168961ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a89604051612bc59190614e9c565b60405180910390a4505050505050505050565b600080612be483612677565b612c455760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610cc9565b612c4e836138b4565b6000818152600d60205260409020546001600160a01b031694909350915050565b60008082806020019051810190612c869190614ab6565b601482015191935091506000612c9e88838386612df2565b90508251811015612d725784516020808701919091206040805160808101825261ffff808d1682526001600160a01b0380881683870190815283850188815260016060860181815260008981526009909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612d689083908990614eaf565b60405180910390a1505b816001600160a01b031687604051612d8a9190614e80565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612dc69190614e9c565b60405180910390a45050505050505050565b611d228282604051806020016040528060008152506138c1565b6000825b82518110156125d0576006545a1015612e0e576125d0565b612e328686858481518110612e2557612e25614e4f565b60200260200101516138e6565b80612e3c81614e65565b915050612df6565b601454600090600160a01b900460ff16612e5f576001612e62565b60005b60ff16905090565b612e758484846127d7565b612e8384848460018561391f565b611d585760405162461bcd60e51b8152600401610cc990614ec8565b606081612ec35750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612eed5780612ed781614e65565b9150612ee69050600a8361498d565b9150612ec7565b6000816001600160401b03811115612f0757612f07613f3e565b6040519080825280601f01601f191660200182016040528015612f31576020820181803683370190505b5090505b84156127cf57612f46600183614b70565b9150612f53600a86614f1d565b612f5e906030614a09565b60f81b818381518110612f7357612f73614e4f565b60200101906001600160f81b031916908160001a905350612f95600a8661498d565b9450612f35565b60006016544210612fac57600080fd5b60008462ffffff16612fbc611bbb565b612fc69190614a09565b60125490915062ffffff1615612fea5760125462ffffff16811115612fea57600080fd5b60405163d7ec901960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d7ec90199061303c908990899089908990600401614f31565b60206040518083038186803b15801561305457600080fd5b505afa158015613068573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061308c9190614fa1565b9695505050505050565b60006130a1600e5490565b9050600082116131015760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b6064820152608401610cc9565b6001600160a01b0383166131635760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610cc9565b81600e60008282546131759190614a09565b90915550506000818152600d6020526040902080546001600160a01b0319166001600160a01b0385161790556131ac600a8261337f565b6000806131b98484614a09565b90506001600160a01b03851691508282600060008051602061513b833981519152600080a4600183015b818114613209578083600060008051602061513b833981519152600080a46001016131e3565b50610fe760008685876133ab565b6000606060008060008661ffff166001600160401b0381111561323c5761323c613f3e565b6040519080825280601f01601f191660200182016040528015613266576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613288578692505b828152826000602083013e909890975095505050505050565b8180519060200120600360008761ffff1661ffff168152602001908152602001600020856040516132d29190614e80565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c9061161f9087908790879087908790614fbe565b60006001600160e01b0319821663152a902d60e11b148061336057506001600160e01b031982166322bac5d960e01b145b80610eab57506301ffc9a760e01b6001600160e01b0319831614610eab565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b600160401b81106133bb57600080fd5b806001600160a01b03851615613425576001600160a01b038516600090815260116020526040812080548392906133fc9084906001600160401b0316615010565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550613485565b6001600160a01b03841660009081526011602052604090208054829190600890613460908490600160401b90046001600160401b0316615038565b92506101000a8154816001600160401b0302191690836001600160401b031602179055505b6001600160a01b038416156134ee576001600160a01b038416600090815260116020526040812080548392906134c59084906001600160401b0316615038565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610fe7565b6001600160a01b038516600090815260116020526040902080548291906010906134c5908490600160801b90046001600160401b0316615038565b836001600160a01b031661353c82611693565b6001600160a01b03161461354f57600080fd5b613559848261270a565b61356257600080fd5b611d58843083611254565b600061357883613a61565b61ffff8087166000908152600160209081526040808320938916835292905290812054919250906135aa908490614a09565b9050600081116135f95760405162461bcd60e51b815260206004820152601a602482015279131e905c1c0e881b5a5b91d85cd31a5b5a5d081b9bdd081cd95d60321b6044820152606401610cc9565b8082101561177b5760405162461bcd60e51b815260206004820152601b60248201527a4c7a4170703a20676173206c696d697420697320746f6f206c6f7760281b6044820152606401610cc9565b6005546000908190612710906136619061ffff1685614958565b61366b919061498d565b90506136778184614b70565b91508015613713576005546040516000916201000090046001600160a01b03169083908381818185875af1925050503d80600081146136d2576040519150601f19603f3d011682016040523d82523d6000602084013e6136d7565b606091505b50509050806137115760405162461bcd60e51b8152600401610cc9906020808252600490820152632166656560e01b604082015260600190565b505b50919050565b61ffff86166000908152602081905260408120805461373790614872565b80601f016020809104026020016040519081016040528092919081815260200182805461376390614872565b80156137b05780601f10613785576101008083540402835291602001916137b0565b820191906000526020600020905b81548152906001019060200180831161379357829003601f168201915b505050505090508051600014156138225760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610cc9565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c5803100908490613879908b9086908c908c908c908c90600401615063565b6000604051808303818588803b15801561389257600080fd5b505af11580156138a6573d6000803e3d6000fd5b505050505050505050505050565b6000610eab600a83613abc565b60006138cc600e5490565b90506138d88484613096565b612e8360008583868661391f565b6138ef81612677565b801561390b57503061390082611693565b6001600160a01b0316145b61391457600080fd5b61118a308383611254565b60006001600160a01b0385163b15613a5557506001835b6139408486614a09565b811015613a4f57604051630a85bd0160e11b81526001600160a01b0387169063150b7a02906139799033908b90869089906004016150ca565b602060405180830381600087803b15801561399357600080fd5b505af19250505080156139c3575060408051601f3d908101601f191682019092526139c0918101906150fd565b60015b613a1d573d8080156139f1576040519150601f19603f3d011682016040523d82523d6000602084013e6139f6565b606091505b508051613a155760405162461bcd60e51b8152600401610cc990614ec8565b805181602001fd5b828015613a3a57506001600160e01b03198116630a85bd0160e11b145b92505080613a4781614e65565b915050613936565b506125d0565b50600195945050505050565b6000602282511015613ab45760405162461bcd60e51b815260206004820152601c60248201527b4c7a4170703a20696e76616c69642061646170746572506172616d7360201b6044820152606401610cc9565b506022015190565b600881901c60008181526020849052604081205490919060ff808516919082181c8015613afe57613aec81613bb4565b60ff168203600884901b179350613bab565b60008311613b6b5760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b6064820152608401610cc9565b506000199091016000818152602086905260409020549091908015613ba657613b9381613bb4565b60ff0360ff16600884901b179350613bab565b613afe565b50505092915050565b6000604051806101200160405280610100815260200161515b610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff613bfd85613c1e565b02901c81518110613c1057613c10614e4f565b016020015160f81c92915050565b6000808211613c2c57600080fd5b5060008190031690565b828054613c4290614872565b90600052602060002090601f016020900481019282613c645760008555613caa565b82601f10613c7d57805160ff1916838001178555613caa565b82800160010185558215613caa579182015b82811115613caa578251825591602001919060010190613c8f565b50613cb6929150613cba565b5090565b5b80821115613cb65760008155600101613cbb565b803561ffff81168114613ce157600080fd5b919050565b60008083601f840112613cf857600080fd5b5081356001600160401b03811115613d0f57600080fd5b602083019150836020828501011115613d2757600080fd5b9250929050565b80356001600160401b0381168114613ce157600080fd5b60008060008060008060808789031215613d5e57600080fd5b613d6787613ccf565b955060208701356001600160401b0380821115613d8357600080fd5b613d8f8a838b01613ce6565b9097509550859150613da360408a01613d2e565b94506060890135915080821115613db957600080fd5b50613dc689828a01613ce6565b979a9699509497509295939492505050565b6001600160e01b03198116811461180457600080fd5b600060208284031215613e0057600080fd5b8135613e0b81613dd8565b9392505050565b60005b83811015613e2d578181015183820152602001613e15565b83811115611d585750506000910152565b60008151808452613e56816020860160208601613e12565b601f01601f19169290920160200192915050565b602081526000613e0b6020830184613e3e565b600060208284031215613e8f57600080fd5b613e0b82613ccf565b600060208284031215613eaa57600080fd5b5035919050565b6001600160a01b038116811461180457600080fd5b8035613ce181613eb1565b60008060408385031215613ee457600080fd5b8235613eef81613eb1565b946020939093013593505050565b600080600060608486031215613f1257600080fd5b8335613f1d81613eb1565b92506020840135613f2d81613eb1565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613f7c57613f7c613f3e565b604052919050565b60006001600160401b03821115613f9d57613f9d613f3e565b50601f01601f191660200190565b6000613fbe613fb984613f84565b613f54565b9050828152838383011115613fd257600080fd5b828260208301376000602084830101529392505050565b600082601f830112613ffa57600080fd5b613e0b83833560208501613fab565b801515811461180457600080fd5b600080600080600060a0868803121561402f57600080fd5b61403886613ccf565b945060208601356001600160401b038082111561405457600080fd5b61406089838a01613fe9565b9550604088013594506060880135915061407982614009565b9092506080870135908082111561408f57600080fd5b5061409c88828901613fe9565b9150509295509295909350565b600080604083850312156140bc57600080fd5b50508035926020909101359150565b6000602082840312156140dd57600080fd5b8135613e0b81613eb1565b6000806000604084860312156140fd57600080fd5b61410684613ccf565b925060208401356001600160401b0381111561412157600080fd5b61412d86828701613ce6565b9497909650939450505050565b60008060008060006080868803121561415257600080fd5b61415b86613ccf565b945060208601356001600160401b0381111561417657600080fd5b61418288828901613ce6565b9699909850959660408101359660609091013595509350505050565b600080600080600080600060e0888a0312156141b957600080fd5b87356141c481613eb1565b96506141d260208901613ccf565b955060408801356001600160401b03808211156141ee57600080fd5b6141fa8b838c01613fe9565b965060608a0135955060808a0135915061421382613eb1565b90935060a08901359061422582613eb1565b90925060c0890135908082111561423b57600080fd5b506142488a828b01613fe9565b91505092959891949750929550565b803562ffffff81168114613ce157600080fd5b60006020828403121561427c57600080fd5b613e0b82614257565b60008060006060848603121561429a57600080fd5b6142a384613ccf565b925060208401356001600160401b038111156142be57600080fd5b6142ca86828701613fe9565b9250506142d960408501613d2e565b90509250925092565b803560ff81168114613ce157600080fd5b60006020828403121561430557600080fd5b613e0b826142e2565b6000806040838503121561432157600080fd5b61432a83613ccf565b91506112e460208401613ccf565b60006020828403121561434a57600080fd5b81356001600160401b0381111561436057600080fd5b6127cf84828501613fe9565b6000806040838503121561437f57600080fd5b613eef83613ccf565b6000806040838503121561439b57600080fd5b82356143a681613eb1565b915060208301356143b681614009565b809150509250929050565b60006001600160401b038211156143da576143da613f3e565b5060051b60200190565b600082601f8301126143f557600080fd5b81356020614405613fb9836143c1565b82815260059290921b8401810191818101908684111561442457600080fd5b8286015b8481101561443f5780358352918301918301614428565b509695505050505050565b600080600080600080600060e0888a03121561446557600080fd5b873561447081613eb1565b965061447e60208901613ccf565b955060408801356001600160401b038082111561449a57600080fd5b6144a68b838c01613fe9565b965060608a01359150808211156144bc57600080fd5b6144c88b838c016143e4565b955060808a013591506144da82613eb1565b8194506144e960a08b01613ec6565b935060c08a013591508082111561423b57600080fd5b60006020828403121561451157600080fd5b81356001600160401b0381111561452757600080fd5b8201601f8101841361453857600080fd5b6127cf84823560208401613fab565b6000806000806080858703121561455d57600080fd5b843561456881613eb1565b9350602085013561457881613eb1565b92506040850135915060608501356001600160401b0381111561459a57600080fd5b6145a687828801613fe9565b91505092959194509250565b6000806000806000608086880312156145ca57600080fd5b6145d386613ccf565b94506145e160208701613ccf565b93506040860135925060608601356001600160401b0381111561460357600080fd5b61460f88828901613ce6565b969995985093965092949392505050565b6000806000806080858703121561463657600080fd5b843561464181613eb1565b93506020614650868201614257565b935060408601356001600160401b0381111561466b57600080fd5b8601601f8101881361467c57600080fd5b803561468a613fb9826143c1565b81815260059190911b8201830190838101908a8311156146a957600080fd5b928401925b828410156146c7578335825292840192908401906146ae565b80965050505050506146db606086016142e2565b905092959194509250565b6000806000606084860312156146fb57600080fd5b61470484613ccf565b925061471260208501613ccf565b9150604084013590509250925092565b60008060008060008060c0878903121561473b57600080fd5b614744876142e2565b955060208701359450604087013593506060870135925061476760808801614257565b915060a087013590509295509295509295565b6000806040838503121561478d57600080fd5b823561479881613eb1565b915060208301356143b681613eb1565b600080600080600060a086880312156147c057600080fd5b6147c986613ccf565b945060208601356001600160401b03808211156147e557600080fd5b6147f189838a01613fe9565b9550604088013591508082111561480757600080fd5b61481389838a016143e4565b94506060880135915061407982614009565b6000806000806080858703121561483b57600080fd5b61484485613ccf565b935061485260208601613ccf565b9250604085013561486281613eb1565b9396929550929360600135925050565b600181811c9082168061488657607f821691505b6020821081141561371357634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b6020808252601e908201527f4c7a4170703a2063616c6c6572206973206e6f7420746865206f776e65720000604082015260600190565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561497257614972614942565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261499c5761499c614977565b500490565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff841681526040602082015260006125d06040830184866149a1565b8284823760609190911b6001600160601b0319169101908152601401919050565b60008219821115614a1c57614a1c614942565b500190565b600060208284031215614a3357600080fd5b5051919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082601f830112614a8257600080fd5b8151614a90613fb982613f84565b818152846020838601011115614aa557600080fd5b6127cf826020830160208701613e12565b60008060408385031215614ac957600080fd5b82516001600160401b0380821115614ae057600080fd5b614aec86838701614a71565b9350602091508185015181811115614b0357600080fd5b85019050601f81018613614b1657600080fd5b8051614b24613fb9826143c1565b81815260059190911b82018301908381019088831115614b4357600080fd5b928401925b82841015614b6157835182529284019290840190614b48565b80955050505050509250929050565b600082821015614b8257614b82614942565b500390565b8054600090600181811c9080831680614ba157607f831692505b6020808410821415614bc357634e487b7160e01b600052602260045260246000fd5b818015614bd75760018114614be857614c15565b60ff19861689528489019650614c15565b60008881526020902060005b86811015614c0d5781548b820152908501908301614bf4565b505084890196505b50505050505092915050565b66697066733a2f2f60c81b81526000614c3d6007830185614b87565b602f60f81b81528351614c57816001840160208801613e12565b64173539b7b760d91b60019290910191820152600601949350505050565b600061ffff808816835280871660208401525084604083015260806060830152614ca36080830184866149a1565b979650505050505050565b61ffff86168152608060208201526000614ccc6080830186886149a1565b6001600160401b0394909416604083015250606001529392505050565b66697066733a2f2f60c81b81526000613e0b6007830184614b87565b600081518084526020808501945080840160005b83811015614d3557815187529582019590820190600101614d19565b509495945050505050565b604081526000614d536040830185613e3e565b82810360208401526125d08185614d05565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614d9390830186613e3e565b84151560608401528281036080840152614dad8185613e3e565b98975050505050505050565b60008060408385031215614dcc57600080fd5b505080516020909101519092909150565b600060208284031215614def57600080fd5b81516001600160401b03811115614e0557600080fd5b6127cf84828501614a71565b61ffff85168152608060208201526000614e2e6080830186613e3e565b6001600160401b03851660408401528281036060840152614ca38185613e3e565b634e487b7160e01b600052603260045260246000fd5b6000600019821415614e7957614e79614942565b5060010190565b60008251614e92818460208701613e12565b9190910192915050565b602081526000613e0b6020830184614d05565b8281526040602082015260006127cf6040830184613e3e565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b600082614f2c57614f2c614977565b500690565b6001600160a01b038516815262ffffff841660208083019190915260806040830181905284519083018190526000918581019160a0850190845b81811015614f8757845183529383019391830191600101614f6b565b505080935050505060ff8316606083015295945050505050565b600060208284031215614fb357600080fd5b8151613e0b81614009565b61ffff8616815260a060208201526000614fdb60a0830187613e3e565b6001600160401b03861660408401528281036060840152614ffc8186613e3e565b90508281036080840152614dad8185613e3e565b60006001600160401b038381169083168181101561503057615030614942565b039392505050565b60006001600160401b0382811684821680830382111561505a5761505a614942565b01949350505050565b61ffff8716815260c06020820152600061508060c0830188613e3e565b82810360408401526150928188613e3e565b6001600160a01b0387811660608601528616608085015283810360a085015290506150bd8185613e3e565b9998505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061308c90830184613e3e565b60006020828403121561510f57600080fd5b8151613e0b81613dd856fe8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ceddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212205c7bea165035100bfc3fc6503244634106f4efe4f7ced683386e641c7cdeaf3b64736f6c63430008090033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000059c5ef981ddf319e7dae5328b4f54e8d1ea1d4300000000000000000000000007adccfb3ebbc589c3b4080dcf396d00a72e0070800000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000022b8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000065919df1000000000000000000000000000000000000000000000000000000000000000e506f6f707a746572204c696e65610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003504f4f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d6177426952457963566a70735433706b725133543776544e4a3669584c5074673372666e7a52683255433538000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b626166796265696463776c756e64706934626c6e6d327836377935346a7034616f666e6c7676346376777a326a743436336d68626a66736d6b65710000000000

Deployed Bytecode

0x6080604052600436106102e85760003560e01c80621d3567146102ed57806301ffc9a71461030f57806306fdde031461034457806307e0db1714610366578063081812fc14610386578063095ea7b3146103be5780630b4cad4c146103de57806310ddb137146103fe57806318160ddd1461041e57806322a3ecf91461044157806323b872dd146104c45780632a205e3d146104e45780632a55205a146105195780632dd0066e146105585780632e4a33cb1461056d5780633d8b38f61461058d57806342842e0e146105ad57806342d65a8d146105cd57806346a43816146105ed578063482881901461060d5780634ac3f4ff14610623578063519056361461065057806352a284a2146106635780635b8c41e614610683578063617692dd146106d25780636352211e1461071857806366ad5c8a146107385780636da7870b1461075857806370a08231146107785780637533d788146107b75780637c6e551d146107d75780638147ef371461080e578063893d20e81461082e5780638cfd8f5c1461084c5780638da5cb5b146108845780638ffa1f2a146108a457806395d89b41146108c45780639ea5d6b1146108d9578063a22cb465146108f9578063a2309ff814610919578063a5097ebf1461092e578063a6c3d16514610943578063a7e0d43d14610963578063ab3ffb9314610983578063af3fb21c14610996578063b19ab245146109be578063b353aaa7146109de578063b88d4fde14610a12578063c446183414610a32578063c4ed6f5814610a48578063c87b56dd14610a63578063cbed8b9c14610a83578063d112fe3314610aa3578063d12473a514610ac3578063d1deba1f14610ae3578063d5abeb0114610af6578063d72822bb14610b12578063df2a5b3b14610b32578063e8a3d48514610b52578063e9038e1f14610b67578063e985e9c514610b87578063efc585ad14610ba7578063f235364114610bc8578063f2fde38b14610be8578063f5ecbdbc14610c08578063fa25f9b614610c28575b600080fd5b3480156102f957600080fd5b5061030d610308366004613d45565b610c55565b005b34801561031b57600080fd5b5061032f61032a366004613dee565b610e86565b60405190151581526020015b60405180910390f35b34801561035057600080fd5b50610359610eb1565b60405161033b9190613e6a565b34801561037257600080fd5b5061030d610381366004613e7d565b610f43565b34801561039257600080fd5b506103a66103a1366004613e98565b610fee565b6040516001600160a01b03909116815260200161033b565b3480156103ca57600080fd5b5061030d6103d9366004613ed1565b611079565b3480156103ea57600080fd5b5061030d6103f9366004613e98565b61118f565b34801561040a57600080fd5b5061030d610419366004613e7d565b6111cb565b34801561042a57600080fd5b50610433611245565b60405190815260200161033b565b34801561044d57600080fd5b5061049561045c366004613e98565b60096020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b039093166020850152918301521515606082015260800161033b565b3480156104d057600080fd5b5061030d6104df366004613efd565b611254565b3480156104f057600080fd5b506105046104ff366004614017565b611285565b6040805192835260208301919091520161033b565b34801561052557600080fd5b506105396105343660046140a9565b6112ab565b604080516001600160a01b03909316835260208301919091520161033b565b34801561056457600080fd5b506103596112ed565b34801561057957600080fd5b5061030d6105883660046140cb565b61137b565b34801561059957600080fd5b5061032f6105a83660046140e8565b6113c2565b3480156105b957600080fd5b5061030d6105c8366004613efd565b61148e565b3480156105d957600080fd5b5061030d6105e83660046140e8565b6114a9565b3480156105f957600080fd5b5061030d61060836600461413a565b611551565b34801561061957600080fd5b5061043360065481565b34801561062f57600080fd5b5061043361063e366004613e7d565b60076020526000908152604090205481565b61030d61065e36600461419e565b61162e565b34801561066f57600080fd5b5061030d61067e36600461426a565b611645565b34801561068f57600080fd5b5061043361069e366004614285565b6003602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b3480156106de57600080fd5b506104336106ed3660046140cb565b6001600160a01b0316600090815260116020526040902054600160401b90046001600160401b031690565b34801561072457600080fd5b506103a6610733366004613e98565b611693565b34801561074457600080fd5b5061030d610753366004613d45565b6116a7565b34801561076457600080fd5b5061030d610773366004613e98565b611783565b34801561078457600080fd5b506104336107933660046140cb565b6001600160a01b03166000908152601160205260409020546001600160401b031690565b3480156107c357600080fd5b506103596107d2366004613e7d565b611807565b3480156107e357600080fd5b506005546107fa90600160b01b900462ffffff1681565b60405162ffffff909116815260200161033b565b34801561081a57600080fd5b506104336108293660046142f3565b611820565b34801561083a57600080fd5b506002546001600160a01b03166103a6565b34801561085857600080fd5b5061043361086736600461430e565b600160209081526000928352604080842090915290825290205481565b34801561089057600080fd5b506002546103a6906001600160a01b031681565b3480156108b057600080fd5b5061030d6108bf366004614338565b6118bd565b3480156108d057600080fd5b50610359611a9a565b3480156108e557600080fd5b5061030d6108f436600461436c565b611aa9565b34801561090557600080fd5b5061030d610914366004614388565b611af7565b34801561092557600080fd5b50610433611bbb565b34801561093a57600080fd5b50610359611bd2565b34801561094f57600080fd5b5061030d61095e3660046140e8565b611bdf565b34801561096f57600080fd5b5061030d61097e366004613e7d565b611c80565b61030d61099136600461444a565b611cc8565b3480156109a257600080fd5b506109ab600181565b60405161ffff909116815260200161033b565b3480156109ca57600080fd5b5061030d6109d93660046144ff565b611cd7565b3480156109ea57600080fd5b506103a67f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd781565b348015610a1e57600080fd5b5061030d610a2d366004614547565b611d26565b348015610a3e57600080fd5b5061043361271081565b348015610a5457600080fd5b506005546109ab9061ffff1681565b348015610a6f57600080fd5b50610359610a7e366004613e98565b611d5e565b348015610a8f57600080fd5b5061030d610a9e3660046145b2565b611dc0565b348015610aaf57600080fd5b5061030d610abe366004614620565b611e77565b348015610acf57600080fd5b5061030d610ade36600461436c565b611f99565b61030d610af1366004613d45565b611fe7565b348015610b0257600080fd5b506012546107fa9062ffffff1681565b348015610b1e57600080fd5b506014546103a6906001600160a01b031681565b348015610b3e57600080fd5b5061030d610b4d3660046146e6565b6121fd565b348015610b5e57600080fd5b50610359612296565b348015610b7357600080fd5b5061030d610b82366004614722565b6122be565b348015610b9357600080fd5b5061032f610ba236600461477a565b612393565b348015610bb357600080fd5b5060145461032f90600160a01b900460ff1681565b348015610bd457600080fd5b50610504610be33660046147a8565b6123c1565b348015610bf457600080fd5b5061030d610c033660046140cb565b6124cd565b348015610c1457600080fd5b50610359610c23366004614825565b612519565b348015610c3457600080fd5b50610433610c43366004613e7d565b60086020526000908152604090205481565b336001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd71614610cd25760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526020819052604081208054610cf090614872565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1c90614872565b8015610d695780601f10610d3e57610100808354040283529160200191610d69565b820191906000526020600020905b815481529060010190602001808311610d4c57829003601f168201915b50505050509050805186869050148015610d84575060008151115b8015610dac575080516020820120604051610da290889088906148a7565b6040518091039020145b610e075760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610cc9565b610e7d8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506125d992505050565b50505050505050565b60006001600160e01b0319821663365a0c7b60e21b1480610eab5750610eab82612652565b92915050565b6060600b8054610ec090614872565b80601f0160208091040260200160405190810160405280929190818152602001828054610eec90614872565b8015610f395780601f10610f0e57610100808354040283529160200191610f39565b820191906000526020600020905b815481529060010190602001808311610f1c57829003601f168201915b5050505050905090565b6002546001600160a01b03163314610f6d5760405162461bcd60e51b8152600401610cc9906148b7565b6040516307e0db1760e01b815261ffff821660048201527f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610fd357600080fd5b505af1158015610fe7573d6000803e3d6000fd5b5050505050565b6000610ff982612677565b61105d5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610cc9565b506000908152600f60205260409020546001600160a01b031690565b600061108482611693565b9050806001600160a01b0316836001600160a01b031614156110f45760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b6064820152608401610cc9565b336001600160a01b038216148061111057506111108133612393565b6111805760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527a081bdddb995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b602a1b6064820152608401610cc9565b61118a838361269c565b505050565b6002546001600160a01b031633146111b95760405162461bcd60e51b8152600401610cc9906148b7565b600081116111c657600080fd5b600655565b6002546001600160a01b031633146111f55760405162461bcd60e51b8152600401610cc9906148b7565b6040516310ddb13760e01b815261ffff821660048201527f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b0316906310ddb13790602401610fb9565b600061124f611bbb565b905090565b61125e338261270a565b61127a5760405162461bcd60e51b8152600401610cc9906148ee565b61118a8383836127d7565b60008061129d8787611296886129b7565b87876123c1565b915091509550959350505050565b6002546005546001600160a01b0390911690600090612710906112da90600160b01b900462ffffff1685614958565b6112e4919061498d565b90509250929050565b601580546112fa90614872565b80601f016020809104026020016040519081016040528092919081815260200182805461132690614872565b80156113735780601f1061134857610100808354040283529160200191611373565b820191906000526020600020905b81548152906001019060200180831161135657829003601f168201915b505050505081565b6005546201000090046001600160a01b0316331461139857600080fd5b600580546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b61ffff8316600090815260208190526040812080548291906113e390614872565b80601f016020809104026020016040519081016040528092919081815260200182805461140f90614872565b801561145c5780601f106114315761010080835404028352916020019161145c565b820191906000526020600020905b81548152906001019060200180831161143f57829003601f168201915b5050505050905083836040516114739291906148a7565b60405180910390208180519060200120149150509392505050565b61118a83838360405180602001604052806000815250611d26565b6002546001600160a01b031633146114d35760405162461bcd60e51b8152600401610cc9906148b7565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd716906342d65a8d90611523908690869086906004016149ca565b600060405180830381600087803b15801561153d57600080fd5b505af1158015610e7d573d6000803e3d6000fd5b6002546001600160a01b0316331461157b5760405162461bcd60e51b8152600401610cc9906148b7565b60008211801561158b5750600081115b61159457600080fd5b61ffff85166000908152600860209081526040808320859055600782529182902083905590516115ca91869186913091016149e8565b60408051601f1981840301815291815261ffff87166000908152602081815291902082516115fd93919290910190613c36565b5060008051602061511b83398151915285858560405161161f939291906149ca565b60405180910390a15050505050565b610e7d87878761163d886129b7565b878787612a02565b6002546001600160a01b0316331461166f5760405162461bcd60e51b8152600401610cc9906148b7565b6005805462ffffff909216600160b01b0262ffffff60b01b19909216919091179055565b60008061169f83612bd8565b509392505050565b3330146117055760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610cc9565b61177b8686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612c6f92505050565b505050505050565b6002546001600160a01b031633146117ad5760405162461bcd60e51b8152600401610cc9906148b7565b60165442106117bb57600080fd5b60125462ffffff16156117ee57806117d1611bbb565b6117db9190614a09565b60125462ffffff1610156117ee57600080fd5b600254611804906001600160a01b031682612dd8565b50565b600060208190529081526040902080546112fa90614872565b604051638147ef3760e01b815260ff821660048201526000907f0000000000000000000000006ef0871ed810f323ea516a77b0988353b667dfa46001600160a01b031690638147ef379060240160206040518083038186803b15801561188557600080fd5b505afa158015611899573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eab9190614a21565b600260045414156118e05760405162461bcd60e51b8152600401610cc990614a3a565b6002600481905581516020808401919091206000818152600990925260409091209091015460ff1661191157600080fd5b6000828060200190518101906119279190614ab6565b600084815260096020526040812080546001909101549294509092506119639161ffff8216916201000090046001600160a01b03169085612df2565b600084815260096020526040902060010154909150811161198357600080fd5b81518114156119fb5760008381526009602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba233906119ee9085815260200190565b60405180910390a1611a8f565b60408051608081018252600085815260096020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b505060016004555050565b6060600c8054610ec090614872565b6002546001600160a01b03163314611ad35760405162461bcd60e51b8152600401610cc9906148b7565b60008111611ae057600080fd5b61ffff909116600090815260076020526040902055565b6001600160a01b038216331415611b4f5760405162461bcd60e51b815260206004820152601c60248201527b22a9219b9918a839b49d1030b8383937bb32903a379031b0b63632b960211b6044820152606401610cc9565b3360008181526010602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000611bc5612e44565b600e5461124f9190614b70565b601380546112fa90614872565b6002546001600160a01b03163314611c095760405162461bcd60e51b8152600401610cc9906148b7565b818130604051602001611c1e939291906149e8565b60408051601f1981840301815291815261ffff8516600090815260208181529190208251611c5193919290910190613c36565b5060008051602061511b833981519152838383604051611c73939291906149ca565b60405180910390a1505050565b6005546201000090046001600160a01b03163314611c9d57600080fd5b6127108161ffff161115611cb057600080fd5b6005805461ffff191661ffff92909216919091179055565b610e7d87878787878787612a02565b6002546001600160a01b03163314611d015760405162461bcd60e51b8152600401610cc9906148b7565b6016544210611d0f57600080fd5b8051611d22906015906020840190613c36565b5050565b611d30338361270a565b611d4c5760405162461bcd60e51b8152600401610cc9906148ee565b611d5884848484612e6a565b50505050565b60125460609062ffffff161580611d81575060158054611d7d90614872565b1590505b15611d8e57610eab612296565b6015611d9983612e9f565b604051602001611daa929190614c21565b6040516020818303038152906040529050919050565b6002546001600160a01b03163314611dea5760405162461bcd60e51b8152600401610cc9906148b7565b6040516332fb62e760e21b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7169063cbed8b9c90611e3e9088908890889088908890600401614c75565b600060405180830381600087803b158015611e5857600080fd5b505af1158015611e6c573d6000803e3d6000fd5b505050505050505050565b60026004541415611e9a5760405162461bcd60e51b8152600401610cc990614a3a565b60026004556014546001600160a01b03163314611eb657600080fd5b611ec284848484612f9c565b611efb5760405162461bcd60e51b815260206004820152600a602482015269085a5cd05b1b1bddd95960b21b6044820152606401610cc9565b60405163b124e2f760e01b81526001600160a01b03858116600483015260ff8316602483015262ffffff851660448301527f0000000000000000000000006ef0871ed810f323ea516a77b0988353b667dfa4169063b124e2f790606401600060405180830381600087803b158015611f7257600080fd5b505af1158015611f86573d6000803e3d6000fd5b50505050611a8f848462ffffff16613096565b6002546001600160a01b03163314611fc35760405162461bcd60e51b8152600401610cc9906148b7565b60008111611fd057600080fd5b61ffff909116600090815260086020526040902055565b61ffff8616600090815260036020526040808220905161200a90889088906148a7565b90815260408051602092819003830190206001600160401b0387166000908152925290205490508061208a5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610cc9565b80838360405161209b9291906148a7565b6040518091039020146120fa5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610cc9565b61ffff8716600090815260036020526040808220905161211d90899089906148a7565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f880182900482028301820190528682526121b5918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612c6f92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516121ec959493929190614cae565b60405180910390a150505050505050565b6002546001600160a01b031633146122275760405162461bcd60e51b8152600401610cc9906148b7565b6000811161223457600080fd5b61ffff83811660008181526001602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611c73565b606060136040516020016122aa9190614ce9565b604051602081830303815290604052905090565b6002546001600160a01b031633146122e85760405162461bcd60e51b8152600401610cc9906148b7565b60405163e9038e1f60e01b815260ff8716600482015260248101869052604481018590526064810184905262ffffff8316608482015260a481018290527f0000000000000000000000006ef0871ed810f323ea516a77b0988353b667dfa46001600160a01b03169063e9038e1f9060c401600060405180830381600087803b15801561237357600080fd5b505af1158015612387573d6000803e3d6000fd5b50505050505050505050565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b600080600086866040516020016123d9929190614d40565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd716906340a7bb109061243d908b90309086908b908b90600401614d65565b604080518083038186803b15801561245457600080fd5b505afa158015612468573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248c9190614db9565b6005549194509250600090612710906124a99061ffff1686614958565b6124b3919061498d565b90506124bf8185614a09565b935050509550959350505050565b6002546001600160a01b031633146124f75760405162461bcd60e51b8152600401610cc9906148b7565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd76001600160a01b03169063f5ecbdbc9060840160006040518083038186803b15801561259457600080fd5b505afa1580156125a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125d09190810190614ddd565b95945050505050565b60008061263c5a60966366ad5c8a60e01b898989896040516024016126019493929190614e11565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190613217565b915091508161177b5761177b86868686856132a1565b60006001600160e01b031982166380ac58cd60e01b1480610eab5750610eab8261332f565b6000612682600e5490565b82108015610eab575081612694612e44565b111592915050565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b03841690811790915581906126d182611693565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061271582612677565b6127795760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610cc9565b600061278483611693565b9050806001600160a01b0316846001600160a01b031614806127bf5750836001600160a01b03166127b484610fee565b6001600160a01b0316145b806127cf57506127cf8185612393565b949350505050565b6000806127e383612bd8565b91509150846001600160a01b0316826001600160a01b03161461285d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b6064820152608401610cc9565b6001600160a01b0384166128c35760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b6064820152608401610cc9565b6128ce60008461269c565b60006128db846001614a09565b600881901c6000908152600a6020526040902054909150600160ff1b60ff83161c1615801561290b5750600e5481105b15612942576000818152600d6020526040902080546001600160a01b0319166001600160a01b038816179055612942600a8261337f565b6000848152600d6020526040902080546001600160a01b0319166001600160a01b03871617905581841461297b5761297b600a8561337f565b83856001600160a01b0316876001600160a01b031660008051602061513b83398151915260405160405180910390a461177b86868660016133ab565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106129f1576129f1614e4f565b602090810291909101015292915050565b6000845111612a495760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610cc9565b61ffff861660009081526007602052604090205484511115612ab85760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610cc9565b60005b8451811015612afb57612ae9888888888581518110612adc57612adc614e4f565b6020026020010151613529565b80612af381614e65565b915050612abb565b5060008585604051602001612b11929190614d40565b6040516020818303038152906040529050612b56876001848851600860008d61ffff1661ffff16815260200190815260200160002054612b519190614958565b61356d565b6000612b6134613647565b9050612b71888387878786613719565b86604051612b7f9190614e80565b6040518091039020896001600160a01b03168961ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a89604051612bc59190614e9c565b60405180910390a4505050505050505050565b600080612be483612677565b612c455760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610cc9565b612c4e836138b4565b6000818152600d60205260409020546001600160a01b031694909350915050565b60008082806020019051810190612c869190614ab6565b601482015191935091506000612c9e88838386612df2565b90508251811015612d725784516020808701919091206040805160808101825261ffff808d1682526001600160a01b0380881683870190815283850188815260016060860181815260008981526009909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612d689083908990614eaf565b60405180910390a1505b816001600160a01b031687604051612d8a9190614e80565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612dc69190614e9c565b60405180910390a45050505050505050565b611d228282604051806020016040528060008152506138c1565b6000825b82518110156125d0576006545a1015612e0e576125d0565b612e328686858481518110612e2557612e25614e4f565b60200260200101516138e6565b80612e3c81614e65565b915050612df6565b601454600090600160a01b900460ff16612e5f576001612e62565b60005b60ff16905090565b612e758484846127d7565b612e8384848460018561391f565b611d585760405162461bcd60e51b8152600401610cc990614ec8565b606081612ec35750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612eed5780612ed781614e65565b9150612ee69050600a8361498d565b9150612ec7565b6000816001600160401b03811115612f0757612f07613f3e565b6040519080825280601f01601f191660200182016040528015612f31576020820181803683370190505b5090505b84156127cf57612f46600183614b70565b9150612f53600a86614f1d565b612f5e906030614a09565b60f81b818381518110612f7357612f73614e4f565b60200101906001600160f81b031916908160001a905350612f95600a8661498d565b9450612f35565b60006016544210612fac57600080fd5b60008462ffffff16612fbc611bbb565b612fc69190614a09565b60125490915062ffffff1615612fea5760125462ffffff16811115612fea57600080fd5b60405163d7ec901960e01b81526001600160a01b037f0000000000000000000000006ef0871ed810f323ea516a77b0988353b667dfa4169063d7ec90199061303c908990899089908990600401614f31565b60206040518083038186803b15801561305457600080fd5b505afa158015613068573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061308c9190614fa1565b9695505050505050565b60006130a1600e5490565b9050600082116131015760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b6064820152608401610cc9565b6001600160a01b0383166131635760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610cc9565b81600e60008282546131759190614a09565b90915550506000818152600d6020526040902080546001600160a01b0319166001600160a01b0385161790556131ac600a8261337f565b6000806131b98484614a09565b90506001600160a01b03851691508282600060008051602061513b833981519152600080a4600183015b818114613209578083600060008051602061513b833981519152600080a46001016131e3565b50610fe760008685876133ab565b6000606060008060008661ffff166001600160401b0381111561323c5761323c613f3e565b6040519080825280601f01601f191660200182016040528015613266576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613288578692505b828152826000602083013e909890975095505050505050565b8180519060200120600360008761ffff1661ffff168152602001908152602001600020856040516132d29190614e80565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c9061161f9087908790879087908790614fbe565b60006001600160e01b0319821663152a902d60e11b148061336057506001600160e01b031982166322bac5d960e01b145b80610eab57506301ffc9a760e01b6001600160e01b0319831614610eab565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b600160401b81106133bb57600080fd5b806001600160a01b03851615613425576001600160a01b038516600090815260116020526040812080548392906133fc9084906001600160401b0316615010565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550613485565b6001600160a01b03841660009081526011602052604090208054829190600890613460908490600160401b90046001600160401b0316615038565b92506101000a8154816001600160401b0302191690836001600160401b031602179055505b6001600160a01b038416156134ee576001600160a01b038416600090815260116020526040812080548392906134c59084906001600160401b0316615038565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610fe7565b6001600160a01b038516600090815260116020526040902080548291906010906134c5908490600160801b90046001600160401b0316615038565b836001600160a01b031661353c82611693565b6001600160a01b03161461354f57600080fd5b613559848261270a565b61356257600080fd5b611d58843083611254565b600061357883613a61565b61ffff8087166000908152600160209081526040808320938916835292905290812054919250906135aa908490614a09565b9050600081116135f95760405162461bcd60e51b815260206004820152601a602482015279131e905c1c0e881b5a5b91d85cd31a5b5a5d081b9bdd081cd95d60321b6044820152606401610cc9565b8082101561177b5760405162461bcd60e51b815260206004820152601b60248201527a4c7a4170703a20676173206c696d697420697320746f6f206c6f7760281b6044820152606401610cc9565b6005546000908190612710906136619061ffff1685614958565b61366b919061498d565b90506136778184614b70565b91508015613713576005546040516000916201000090046001600160a01b03169083908381818185875af1925050503d80600081146136d2576040519150601f19603f3d011682016040523d82523d6000602084013e6136d7565b606091505b50509050806137115760405162461bcd60e51b8152600401610cc9906020808252600490820152632166656560e01b604082015260600190565b505b50919050565b61ffff86166000908152602081905260408120805461373790614872565b80601f016020809104026020016040519081016040528092919081815260200182805461376390614872565b80156137b05780601f10613785576101008083540402835291602001916137b0565b820191906000526020600020905b81548152906001019060200180831161379357829003601f168201915b505050505090508051600014156138225760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610cc9565b60405162c5803160e81b81526001600160a01b037f000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7169063c5803100908490613879908b9086908c908c908c908c90600401615063565b6000604051808303818588803b15801561389257600080fd5b505af11580156138a6573d6000803e3d6000fd5b505050505050505050505050565b6000610eab600a83613abc565b60006138cc600e5490565b90506138d88484613096565b612e8360008583868661391f565b6138ef81612677565b801561390b57503061390082611693565b6001600160a01b0316145b61391457600080fd5b61118a308383611254565b60006001600160a01b0385163b15613a5557506001835b6139408486614a09565b811015613a4f57604051630a85bd0160e11b81526001600160a01b0387169063150b7a02906139799033908b90869089906004016150ca565b602060405180830381600087803b15801561399357600080fd5b505af19250505080156139c3575060408051601f3d908101601f191682019092526139c0918101906150fd565b60015b613a1d573d8080156139f1576040519150601f19603f3d011682016040523d82523d6000602084013e6139f6565b606091505b508051613a155760405162461bcd60e51b8152600401610cc990614ec8565b805181602001fd5b828015613a3a57506001600160e01b03198116630a85bd0160e11b145b92505080613a4781614e65565b915050613936565b506125d0565b50600195945050505050565b6000602282511015613ab45760405162461bcd60e51b815260206004820152601c60248201527b4c7a4170703a20696e76616c69642061646170746572506172616d7360201b6044820152606401610cc9565b506022015190565b600881901c60008181526020849052604081205490919060ff808516919082181c8015613afe57613aec81613bb4565b60ff168203600884901b179350613bab565b60008311613b6b5760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b6064820152608401610cc9565b506000199091016000818152602086905260409020549091908015613ba657613b9381613bb4565b60ff0360ff16600884901b179350613bab565b613afe565b50505092915050565b6000604051806101200160405280610100815260200161515b610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff613bfd85613c1e565b02901c81518110613c1057613c10614e4f565b016020015160f81c92915050565b6000808211613c2c57600080fd5b5060008190031690565b828054613c4290614872565b90600052602060002090601f016020900481019282613c645760008555613caa565b82601f10613c7d57805160ff1916838001178555613caa565b82800160010185558215613caa579182015b82811115613caa578251825591602001919060010190613c8f565b50613cb6929150613cba565b5090565b5b80821115613cb65760008155600101613cbb565b803561ffff81168114613ce157600080fd5b919050565b60008083601f840112613cf857600080fd5b5081356001600160401b03811115613d0f57600080fd5b602083019150836020828501011115613d2757600080fd5b9250929050565b80356001600160401b0381168114613ce157600080fd5b60008060008060008060808789031215613d5e57600080fd5b613d6787613ccf565b955060208701356001600160401b0380821115613d8357600080fd5b613d8f8a838b01613ce6565b9097509550859150613da360408a01613d2e565b94506060890135915080821115613db957600080fd5b50613dc689828a01613ce6565b979a9699509497509295939492505050565b6001600160e01b03198116811461180457600080fd5b600060208284031215613e0057600080fd5b8135613e0b81613dd8565b9392505050565b60005b83811015613e2d578181015183820152602001613e15565b83811115611d585750506000910152565b60008151808452613e56816020860160208601613e12565b601f01601f19169290920160200192915050565b602081526000613e0b6020830184613e3e565b600060208284031215613e8f57600080fd5b613e0b82613ccf565b600060208284031215613eaa57600080fd5b5035919050565b6001600160a01b038116811461180457600080fd5b8035613ce181613eb1565b60008060408385031215613ee457600080fd5b8235613eef81613eb1565b946020939093013593505050565b600080600060608486031215613f1257600080fd5b8335613f1d81613eb1565b92506020840135613f2d81613eb1565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613f7c57613f7c613f3e565b604052919050565b60006001600160401b03821115613f9d57613f9d613f3e565b50601f01601f191660200190565b6000613fbe613fb984613f84565b613f54565b9050828152838383011115613fd257600080fd5b828260208301376000602084830101529392505050565b600082601f830112613ffa57600080fd5b613e0b83833560208501613fab565b801515811461180457600080fd5b600080600080600060a0868803121561402f57600080fd5b61403886613ccf565b945060208601356001600160401b038082111561405457600080fd5b61406089838a01613fe9565b9550604088013594506060880135915061407982614009565b9092506080870135908082111561408f57600080fd5b5061409c88828901613fe9565b9150509295509295909350565b600080604083850312156140bc57600080fd5b50508035926020909101359150565b6000602082840312156140dd57600080fd5b8135613e0b81613eb1565b6000806000604084860312156140fd57600080fd5b61410684613ccf565b925060208401356001600160401b0381111561412157600080fd5b61412d86828701613ce6565b9497909650939450505050565b60008060008060006080868803121561415257600080fd5b61415b86613ccf565b945060208601356001600160401b0381111561417657600080fd5b61418288828901613ce6565b9699909850959660408101359660609091013595509350505050565b600080600080600080600060e0888a0312156141b957600080fd5b87356141c481613eb1565b96506141d260208901613ccf565b955060408801356001600160401b03808211156141ee57600080fd5b6141fa8b838c01613fe9565b965060608a0135955060808a0135915061421382613eb1565b90935060a08901359061422582613eb1565b90925060c0890135908082111561423b57600080fd5b506142488a828b01613fe9565b91505092959891949750929550565b803562ffffff81168114613ce157600080fd5b60006020828403121561427c57600080fd5b613e0b82614257565b60008060006060848603121561429a57600080fd5b6142a384613ccf565b925060208401356001600160401b038111156142be57600080fd5b6142ca86828701613fe9565b9250506142d960408501613d2e565b90509250925092565b803560ff81168114613ce157600080fd5b60006020828403121561430557600080fd5b613e0b826142e2565b6000806040838503121561432157600080fd5b61432a83613ccf565b91506112e460208401613ccf565b60006020828403121561434a57600080fd5b81356001600160401b0381111561436057600080fd5b6127cf84828501613fe9565b6000806040838503121561437f57600080fd5b613eef83613ccf565b6000806040838503121561439b57600080fd5b82356143a681613eb1565b915060208301356143b681614009565b809150509250929050565b60006001600160401b038211156143da576143da613f3e565b5060051b60200190565b600082601f8301126143f557600080fd5b81356020614405613fb9836143c1565b82815260059290921b8401810191818101908684111561442457600080fd5b8286015b8481101561443f5780358352918301918301614428565b509695505050505050565b600080600080600080600060e0888a03121561446557600080fd5b873561447081613eb1565b965061447e60208901613ccf565b955060408801356001600160401b038082111561449a57600080fd5b6144a68b838c01613fe9565b965060608a01359150808211156144bc57600080fd5b6144c88b838c016143e4565b955060808a013591506144da82613eb1565b8194506144e960a08b01613ec6565b935060c08a013591508082111561423b57600080fd5b60006020828403121561451157600080fd5b81356001600160401b0381111561452757600080fd5b8201601f8101841361453857600080fd5b6127cf84823560208401613fab565b6000806000806080858703121561455d57600080fd5b843561456881613eb1565b9350602085013561457881613eb1565b92506040850135915060608501356001600160401b0381111561459a57600080fd5b6145a687828801613fe9565b91505092959194509250565b6000806000806000608086880312156145ca57600080fd5b6145d386613ccf565b94506145e160208701613ccf565b93506040860135925060608601356001600160401b0381111561460357600080fd5b61460f88828901613ce6565b969995985093965092949392505050565b6000806000806080858703121561463657600080fd5b843561464181613eb1565b93506020614650868201614257565b935060408601356001600160401b0381111561466b57600080fd5b8601601f8101881361467c57600080fd5b803561468a613fb9826143c1565b81815260059190911b8201830190838101908a8311156146a957600080fd5b928401925b828410156146c7578335825292840192908401906146ae565b80965050505050506146db606086016142e2565b905092959194509250565b6000806000606084860312156146fb57600080fd5b61470484613ccf565b925061471260208501613ccf565b9150604084013590509250925092565b60008060008060008060c0878903121561473b57600080fd5b614744876142e2565b955060208701359450604087013593506060870135925061476760808801614257565b915060a087013590509295509295509295565b6000806040838503121561478d57600080fd5b823561479881613eb1565b915060208301356143b681613eb1565b600080600080600060a086880312156147c057600080fd5b6147c986613ccf565b945060208601356001600160401b03808211156147e557600080fd5b6147f189838a01613fe9565b9550604088013591508082111561480757600080fd5b61481389838a016143e4565b94506060880135915061407982614009565b6000806000806080858703121561483b57600080fd5b61484485613ccf565b935061485260208601613ccf565b9250604085013561486281613eb1565b9396929550929360600135925050565b600181811c9082168061488657607f821691505b6020821081141561371357634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b6020808252601e908201527f4c7a4170703a2063616c6c6572206973206e6f7420746865206f776e65720000604082015260600190565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561497257614972614942565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261499c5761499c614977565b500490565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff841681526040602082015260006125d06040830184866149a1565b8284823760609190911b6001600160601b0319169101908152601401919050565b60008219821115614a1c57614a1c614942565b500190565b600060208284031215614a3357600080fd5b5051919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b600082601f830112614a8257600080fd5b8151614a90613fb982613f84565b818152846020838601011115614aa557600080fd5b6127cf826020830160208701613e12565b60008060408385031215614ac957600080fd5b82516001600160401b0380821115614ae057600080fd5b614aec86838701614a71565b9350602091508185015181811115614b0357600080fd5b85019050601f81018613614b1657600080fd5b8051614b24613fb9826143c1565b81815260059190911b82018301908381019088831115614b4357600080fd5b928401925b82841015614b6157835182529284019290840190614b48565b80955050505050509250929050565b600082821015614b8257614b82614942565b500390565b8054600090600181811c9080831680614ba157607f831692505b6020808410821415614bc357634e487b7160e01b600052602260045260246000fd5b818015614bd75760018114614be857614c15565b60ff19861689528489019650614c15565b60008881526020902060005b86811015614c0d5781548b820152908501908301614bf4565b505084890196505b50505050505092915050565b66697066733a2f2f60c81b81526000614c3d6007830185614b87565b602f60f81b81528351614c57816001840160208801613e12565b64173539b7b760d91b60019290910191820152600601949350505050565b600061ffff808816835280871660208401525084604083015260806060830152614ca36080830184866149a1565b979650505050505050565b61ffff86168152608060208201526000614ccc6080830186886149a1565b6001600160401b0394909416604083015250606001529392505050565b66697066733a2f2f60c81b81526000613e0b6007830184614b87565b600081518084526020808501945080840160005b83811015614d3557815187529582019590820190600101614d19565b509495945050505050565b604081526000614d536040830185613e3e565b82810360208401526125d08185614d05565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614d9390830186613e3e565b84151560608401528281036080840152614dad8185613e3e565b98975050505050505050565b60008060408385031215614dcc57600080fd5b505080516020909101519092909150565b600060208284031215614def57600080fd5b81516001600160401b03811115614e0557600080fd5b6127cf84828501614a71565b61ffff85168152608060208201526000614e2e6080830186613e3e565b6001600160401b03851660408401528281036060840152614ca38185613e3e565b634e487b7160e01b600052603260045260246000fd5b6000600019821415614e7957614e79614942565b5060010190565b60008251614e92818460208701613e12565b9190910192915050565b602081526000613e0b6020830184614d05565b8281526040602082015260006127cf6040830184613e3e565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b600082614f2c57614f2c614977565b500690565b6001600160a01b038516815262ffffff841660208083019190915260806040830181905284519083018190526000918581019160a0850190845b81811015614f8757845183529383019391830191600101614f6b565b505080935050505060ff8316606083015295945050505050565b600060208284031215614fb357600080fd5b8151613e0b81614009565b61ffff8616815260a060208201526000614fdb60a0830187613e3e565b6001600160401b03861660408401528281036060840152614ffc8186613e3e565b90508281036080840152614dad8185613e3e565b60006001600160401b038381169083168181101561503057615030614942565b039392505050565b60006001600160401b0382811684821680830382111561505a5761505a614942565b01949350505050565b61ffff8716815260c06020820152600061508060c0830188613e3e565b82810360408401526150928188613e3e565b6001600160a01b0387811660608601528616608085015283810360a085015290506150bd8185613e3e565b9998505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061308c90830184613e3e565b60006020828403121561510f57600080fd5b8151613e0b81613dd856fe8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ceddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212205c7bea165035100bfc3fc6503244634106f4efe4f7ced683386e641c7cdeaf3b64736f6c63430008090033

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ 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.