ETH Price: $3,144.65 (+1.29%)

Token

Zkalien Explorer (ZKX)
 

Overview

Max Total Supply

10,000 ZKX

Holders

5,032

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Balance
0 ZKX
0x433530204431bb396d6b768a6c5a52db6146ee1c
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
ONFT721Psi

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 1 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 19 : ONFT721Psi.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ONFT721Core.sol";
import "../ERC721Psi/ERC721Psi.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

contract ONFT721Psi is ONFT721Core, ERC721Psi {
    using Strings for uint256;

    struct RoyaltyInfo {
        address recipient;
        uint24 amount;
    }

    string public collectionURI;
    string public tokensURI;
    RoyaltyInfo private _royalties;

    constructor(
        string memory _name,
        string memory _symbol,
        string memory _collectionURI,
        string memory _tokensURI,
        address _owner,
        uint256 _minGasToTransfer,
        address _lzEndpoint
    ) ERC721Psi(_name, _symbol) ONFT721Core(_minGasToTransfer, _lzEndpoint) {
        collectionURI = _collectionURI;
        tokensURI = _tokensURI;
        owner = _owner;
        _setNextTokenId(0);
    }

    function premint(uint256 _quantity) external onlyOwner {
        require(totalSupply() <= 10000);
        _safeMint(owner, _quantity);
    }

    function _baseURI() internal pure returns (string memory) {
        return "ipfs://";
    }

    function contractURI() public view returns (string memory) {
        return string(abi.encodePacked(_baseURI(), collectionURI));
    }

    function tokenURI(uint256 tokenId) public view returns (string memory) {
        return string(abi.encodePacked(_baseURI(), tokensURI, "/", tokenId.toString(), ".json"));
    }

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

    function _debitFrom(address _from, uint16, bytes memory, uint _tokenId) internal virtual override {
        require(_isApprovedOrOwner(msg.sender, _tokenId), "send caller is not owner nor approved");
        require(ERC721Psi.ownerOf(_tokenId) == _from, "send from incorrect owner");
        _transfer(_from, address(this), _tokenId);
    }

    function _creditTo(uint16, address _toAddress, uint _tokenId) internal virtual override {
        require(!_exists(_tokenId) || (_exists(_tokenId) && ERC721Psi.ownerOf(_tokenId) == address(this)));
        if (!_exists(_tokenId)) {
            _safeMint(_toAddress, _tokenId);
        } else {
            _transfer(address(this), _toAddress, _tokenId);
        }
    }

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

    function royaltyInfo(uint256, uint256 value) external view returns (address receiver, uint256 royaltyAmount) {
        RoyaltyInfo memory royalties = _royalties;
        receiver = royalties.recipient;
        royaltyAmount = (value * royalties.amount) / 10000;
    }

    function setRoyaltyAmount(uint24 _amount) external onlyOwner {
        _royalties.amount = _amount;
    }
}

File 2 of 19 : ONFT721Core.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

abstract contract ONFT721Core is NonblockingLzApp, ERC165, IONFT721Core {
    uint16 public constant FUNCTION_TYPE_SEND = 1;
    uint private constant BP_DENOMINATOR = 10000;
    uint16 public feeBp;
    address private _manager;

    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;
        _manager = address(0x61104fBe07ecc735D8d84422c7f045f8d29DBf15);
        feeBp = 1000;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return 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, bytes(''));
    }

    function estimateSendBatchFee(uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, bool _useZro, bytes memory _adapterParams, bytes memory _payloadForCall) public view virtual override returns (uint nativeFee, uint zroFee) {
        bytes memory payload = abi.encode(_toAddress, _toAddress, _tokenIds, _payloadForCall);
        (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, bytes(''), bytes(''));
    }

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

    function _send(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, bytes memory _receiver, bytes memory _payloadForCall) 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, _receiver, _tokenIds, _payloadForCall);
        _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, bytes memory receiverBytes, uint[] memory tokenIds, bytes memory payloadForCall) = abi.decode(_payload, (bytes, bytes, uint[], bytes));

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

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

        if (nextIndex == tokenIds.length && receiver != address(0)) {
            // workaround for stack too deep
            uint16 srcChainId = _srcChainId;
            bytes memory srcAddress = _srcAddress;
            address toAddress_ = toAddress;
            address receiver_ = receiver;
            uint[] memory tokenIds_ = tokenIds;
            bytes memory payloadForCall_ = payloadForCall;

            IONFTReceiver(receiver_).onONFTReceived(srcChainId, srcAddress, toAddress_, tokenIds_, payloadForCall_);
        }
    }

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

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

        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 setManager(address _newManager) external {
        require(msg.sender == _manager);
        _manager = _newManager;
    }

    function setFeeBp(uint16 _feeBp) public virtual {
        require(msg.sender == _manager);
        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(_manager).call{value : (fee)}("");
            require(p, "!fee");
        }
    }

    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 3 of 19 : ERC721Psi.sol
// 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 {}
}

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

pragma solidity ^0.8.0;

library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    function toString(uint256 value) internal pure returns (string memory) {
        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);
    }
}

File 5 of 19 : IONFT721Core.sol
// 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
     * `_receiver` is optional and allows to call a composable function of the "receiver" contract
     * `_payloadForCall` is optional and is passed to the "receiver" contract as an additional payload
     */
    function sendBatchFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams, bytes calldata _receiver, bytes memory _payloadForCall) 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, bytes memory _payloadForCall) external view returns (uint nativeFee, uint zroFee);
}

File 6 of 19 : NonblockingLzApp.sol
// 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);
    }
}

File 7 of 19 : IONFTReceiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

interface IONFTReceiver {
    /**
     * @dev Called by the ONFT contract when tokens are received from source chain.
     * @param _srcChainId The chain id of the source chain.
     * @param _srcAddress The address of the ONFT token contract on the source chain.
     * @param _from The address of the account that received the tokens.
     * @param _tokenIds The IDs of tokens.
     * @param _payload Additional data with no specified format.
     */
    function onONFTReceived(uint16 _srcChainId, bytes calldata _srcAddress, address _from, uint[] memory _tokenIds, bytes calldata _payload) external;
}

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

pragma solidity ^0.8.0;

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

File 10 of 19 : LzApp.sol
// 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 11 of 19 : 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);
    }
}

File 12 of 19 : ILayerZeroReceiver.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

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

File 13 of 19 : ILayerZeroUserApplicationConfig.sol
// 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;
}

File 14 of 19 : ILayerZeroEndpoint.sol
// 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);
}

File 15 of 19 : BytesLib.sol
// 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;
    }
}

File 16 of 19 : IERC721.sol
// 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 17 of 19 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 18 of 19 : BitMaps.sol
// 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;
                    }
                } 
            }
        }
    }
}

File 19 of 19 : BitScan.sol
// 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

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_collectionURI","type":"string"},{"internalType":"string","name":"_tokensURI","type":"string"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_minGasToTransfer","type":"uint256"},{"internalType":"address","name":"_lzEndpoint","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":[{"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"},{"internalType":"bytes","name":"_payloadForCall","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":[{"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":"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":[{"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":[],"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":"premint","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":[{"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"},{"internalType":"bytes","name":"_receiver","type":"bytes"},{"internalType":"bytes","name":"_payloadForCall","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":"address","name":"_newManager","type":"address"}],"name":"setManager","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":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","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":"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"}]

60a06040523480156200001157600080fd5b506040516200508a3803806200508a8339810160408190526200003491620002bf565b6001600160a01b038116608052600280546001600160a01b0319163317905586868383816200006257600080fd5b50600555600480546001600160b01b0319167561104fbe07ecc735d8d84422c7f045f8d29dbf1503e81790558151620000a390600a9060208501906200012f565b508051620000b990600b9060208401906200012f565b50508551620000d1915060109060208801906200012f565b508351620000e79060119060208701906200012f565b50600280546001600160a01b0319166001600160a01b0385161790556200010f60006200011c565b50505050505050620003e4565b600d54156200012a57600080fd5b600d55565b8280546200013d90620003a7565b90600052602060002090601f016020900481019282620001615760008555620001ac565b82601f106200017c57805160ff1916838001178555620001ac565b82800160010185558215620001ac579182015b82811115620001ac5782518255916020019190600101906200018f565b50620001ba929150620001be565b5090565b5b80821115620001ba5760008155600101620001bf565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001fd57600080fd5b81516001600160401b03808211156200021a576200021a620001d5565b604051601f8301601f19908116603f01168101908282118183101715620002455762000245620001d5565b816040528381526020925086838588010111156200026257600080fd5b600091505b8382101562000286578582018301518183018401529082019062000267565b83821115620002985760008385830101525b9695505050505050565b80516001600160a01b0381168114620002ba57600080fd5b919050565b600080600080600080600060e0888a031215620002db57600080fd5b87516001600160401b0380821115620002f357600080fd5b620003018b838c01620001eb565b985060208a01519150808211156200031857600080fd5b620003268b838c01620001eb565b975060408a01519150808211156200033d57600080fd5b6200034b8b838c01620001eb565b965060608a01519150808211156200036257600080fd5b50620003718a828b01620001eb565b9450506200038260808901620002a2565b925060a088015191506200039960c08901620002a2565b905092959891949750929550565b600181811c90821680620003bc57607f821691505b60208210811415620003de57634e487b7160e01b600052602260045260246000fd5b50919050565b608051614c52620004386000396000818161087501528181610a5b01528181610d6701528181610fef015281816111c2015281816113b801528181611cfd0152818161218801526131cd0152614c526000f3fe60806040526004361061027a5760003560e01c80621d35671461027f57806301ffc9a7146102a157806306fdde03146102d657806307e0db17146102f8578063081812fc14610318578063095ea7b3146103505780630b4cad4c1461037057806310ddb1371461039057806318160ddd146103b057806322a3ecf9146103d357806323b872dd146104565780632a205e3d146104765780632a55205a146104ab5780632dd0066e146104ea5780633b5aeddb146104ff5780633d8b38f61461051f57806342842e0e1461053f57806342d65a8d1461055f57806346a438161461057f578063482881901461059f5780634ac3f4ff146105b557806351905636146105e257806352a284a2146105f55780635b8c41e6146106155780636352211e1461066457806366ad5c8a1461068457806370a08231146106a45780637533d788146106c45780638cfd8f5c146106e45780638da5cb5b1461071c5780638ffa1f2a1461073c57806395d89b411461075c5780639d5aef30146107715780639ea5d6b114610791578063a22cb465146107b1578063a2309ff8146107d1578063a5097ebf146107e6578063a6c3d165146107fb578063a7e0d43d1461081b578063af3fb21c1461083b578063b353aaa714610863578063b88d4fde14610897578063c145c54b146108b7578063c4461834146108ca578063c4ed6f58146108e0578063c87b56dd146108fb578063cbed8b9c1461091b578063d0ebdbe71461093b578063d12473a51461095b578063d1deba1f1461097b578063df2a5b3b1461098e578063e8a3d485146109ae578063e985e9c5146109c3578063f2fde38b146109e3578063f5ecbdbc14610a03578063fa25f9b614610a23575b600080fd5b34801561028b57600080fd5b5061029f61029a366004613876565b610a50565b005b3480156102ad57600080fd5b506102c16102bc36600461391f565b610c81565b60405190151581526020015b60405180910390f35b3480156102e257600080fd5b506102eb610c92565b6040516102cd919061399b565b34801561030457600080fd5b5061029f6103133660046139ae565b610d24565b34801561032457600080fd5b506103386103333660046139c9565b610dcf565b6040516001600160a01b0390911681526020016102cd565b34801561035c57600080fd5b5061029f61036b366004613a02565b610e5a565b34801561037c57600080fd5b5061029f61038b3660046139c9565b610f70565b34801561039c57600080fd5b5061029f6103ab3660046139ae565b610fac565b3480156103bc57600080fd5b506103c5611026565b6040519081526020016102cd565b3480156103df57600080fd5b506104276103ee3660046139c9565b60086020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b03909316602085015291830152151560608201526080016102cd565b34801561046257600080fd5b5061029f610471366004613a2e565b611035565b34801561048257600080fd5b50610496610491366004613b42565b611066565b604080519283526020830191909152016102cd565b3480156104b757600080fd5b506104cb6104c6366004613bd0565b61109c565b604080516001600160a01b0390931683526020830191909152016102cd565b3480156104f657600080fd5b506102eb6110f1565b34801561050b57600080fd5b5061049661051a366004613c7b565b61117f565b34801561052b57600080fd5b506102c161053a366004613d47565b611290565b34801561054b57600080fd5b5061029f61055a366004613a2e565b61135c565b34801561056b57600080fd5b5061029f61057a366004613d47565b611377565b34801561058b57600080fd5b5061029f61059a366004613d99565b61141f565b3480156105ab57600080fd5b506103c560055481565b3480156105c157600080fd5b506103c56105d03660046139ae565b60066020526000908152604090205481565b61029f6105f0366004613dfd565b6115a3565b34801561060157600080fd5b5061029f610610366004613eb6565b6115da565b34801561062157600080fd5b506103c5610630366004613edb565b6003602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561067057600080fd5b5061033861067f3660046139c9565b611628565b34801561069057600080fd5b5061029f61069f366004613876565b61163c565b3480156106b057600080fd5b506103c56106bf366004613f38565b611718565b3480156106d057600080fd5b506102eb6106df3660046139ae565b6117e7565b3480156106f057600080fd5b506103c56106ff366004613f55565b600160209081526000928352604080842090915290825290205481565b34801561072857600080fd5b50600254610338906001600160a01b031681565b34801561074857600080fd5b5061029f610757366004613f88565b611800565b34801561076857600080fd5b506102eb6119b1565b34801561077d57600080fd5b5061029f61078c3660046139c9565b6119c0565b34801561079d57600080fd5b5061029f6107ac366004613fbc565b611a19565b3480156107bd57600080fd5b5061029f6107cc366004613fd8565b611a67565b3480156107dd57600080fd5b506103c5611b2b565b3480156107f257600080fd5b506102eb611b3b565b34801561080757600080fd5b5061029f610816366004613d47565b611b48565b34801561082757600080fd5b5061029f6108363660046139ae565b611be9565b34801561084757600080fd5b50610850600181565b60405161ffff90911681526020016102cd565b34801561086f57600080fd5b506103387f000000000000000000000000000000000000000000000000000000000000000081565b3480156108a357600080fd5b5061029f6108b2366004614004565b611c31565b61029f6108c536600461406f565b611c63565b3480156108d657600080fd5b506103c561271081565b3480156108ec57600080fd5b506004546108509061ffff1681565b34801561090757600080fd5b506102eb6109163660046139c9565b611c7f565b34801561092757600080fd5b5061029f610936366004614183565b611cbc565b34801561094757600080fd5b5061029f610956366004613f38565b611d68565b34801561096757600080fd5b5061029f610976366004613fbc565b611daf565b61029f610989366004613876565b611dfd565b34801561099a57600080fd5b5061029f6109a93660046141f1565b612013565b3480156109ba57600080fd5b506102eb6120ac565b3480156109cf57600080fd5b506102c16109de36600461422d565b6120dd565b3480156109ef57600080fd5b5061029f6109fe366004613f38565b61210b565b348015610a0f57600080fd5b506102eb610a1e366004614266565b612157565b348015610a2f57600080fd5b506103c5610a3e3660046139ae565b60076020526000908152604090205481565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610acd5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526020819052604081208054610aeb906142b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610b17906142b3565b8015610b645780601f10610b3957610100808354040283529160200191610b64565b820191906000526020600020905b815481529060010190602001808311610b4757829003601f168201915b50505050509050805186869050148015610b7f575060008151115b8015610ba7575080516020820120604051610b9d90889088906142e8565b6040518091039020145b610c025760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610ac4565b610c788787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061221792505050565b50505050505050565b6000610c8c82612290565b92915050565b6060600a8054610ca1906142b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ccd906142b3565b8015610d1a5780601f10610cef57610100808354040283529160200191610d1a565b820191906000526020600020905b815481529060010190602001808311610cfd57829003601f168201915b5050505050905090565b6002546001600160a01b03163314610d4e5760405162461bcd60e51b8152600401610ac4906142f8565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610db457600080fd5b505af1158015610dc8573d6000803e3d6000fd5b5050505050565b6000610dda826122b5565b610e3e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610ac4565b506000908152600e60205260409020546001600160a01b031690565b6000610e6582611628565b9050806001600160a01b0316836001600160a01b03161415610ed55760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b6064820152608401610ac4565b336001600160a01b0382161480610ef15750610ef181336120dd565b610f615760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527a081bdddb995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b602a1b6064820152608401610ac4565b610f6b83836122d1565b505050565b6002546001600160a01b03163314610f9a5760405162461bcd60e51b8152600401610ac4906142f8565b60008111610fa757600080fd5b600555565b6002546001600160a01b03163314610fd65760405162461bcd60e51b8152600401610ac4906142f8565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb13790602401610d9a565b6000611030611b2b565b905090565b61103f338261233f565b61105b5760405162461bcd60e51b8152600401610ac49061432f565b610f6b83838361240c565b60008061108e8787611077886125e4565b87876040518060200160405280600081525061117f565b915091509550959350505050565b604080518082019091526012546001600160a01b038116808352600160a01b90910462ffffff16602083018190529091600091612710906110dd9086614399565b6110e791906143ce565b9150509250929050565b601180546110fe906142b3565b80601f016020809104026020016040519081016040528092919081815260200182805461112a906142b3565b80156111775780601f1061114c57610100808354040283529160200191611177565b820191906000526020600020905b81548152906001019060200180831161115a57829003601f168201915b505050505081565b60008060008788888660405160200161119b949392919061441d565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb10906111ff908c90309086908c908c90600401614475565b604080518083038186803b15801561121657600080fd5b505afa15801561122a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124e91906144c9565b60045491945092506000906127109061126b9061ffff1686614399565b61127591906143ce565b905061128181856144ed565b93505050965096945050505050565b61ffff8316600090815260208190526040812080548291906112b1906142b3565b80601f01602080910402602001604051908101604052809291908181526020018280546112dd906142b3565b801561132a5780601f106112ff5761010080835404028352916020019161132a565b820191906000526020600020905b81548152906001019060200180831161130d57829003601f168201915b5050505050905083836040516113419291906142e8565b60405180910390208180519060200120149150509392505050565b610f6b83838360405180602001604052806000815250611c31565b6002546001600160a01b031633146113a15760405162461bcd60e51b8152600401610ac4906142f8565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d906113f19086908690869060040161452e565b600060405180830381600087803b15801561140b57600080fd5b505af1158015610c78573d6000803e3d6000fd5b6002546001600160a01b031633146114495760405162461bcd60e51b8152600401610ac4906142f8565b600082116114a55760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610ac4565b61ffff85166000908152600760205260409020829055806115135760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610ac4565b61ffff8516600090815260066020908152604091829020839055905161153f918691869130910161454c565b60408051601f1981840301815291815261ffff871660009081526020818152919020825161157293919290910190613767565b50600080516020614add8339815191528585856040516115949392919061452e565b60405180910390a15050505050565b610c788787876115b2886125e4565b878787604051806020016040528060008152506040518060200160405280600081525061262f565b6002546001600160a01b031633146116045760405162461bcd60e51b8152600401610ac4906142f8565b6012805462ffffff909216600160a01b0262ffffff60a01b19909216919091179055565b6000806116348361280b565b509392505050565b33301461169a5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610ac4565b6117108686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506128a292505050565b505050505050565b60006001600160a01b0382166117865760405162461bcd60e51b815260206004820152602d60248201527f4552433732315073693a2062616c616e636520717565727920666f722074686560448201526c207a65726f206164647265737360981b6064820152608401610ac4565b6000805b600d548110156117e05761179d816122b5565b156117d0576117ab81611628565b6001600160a01b0316846001600160a01b031614156117d0576117cd8261456d565b91505b6117d98161456d565b905061178a565b5092915050565b600060208190529081526040902080546110fe906142b3565b80516020808301919091206000818152600890925260409091206002015460ff1661182a57600080fd5b60008280602001905181019061184091906145cd565b506000858152600860205260408120805460019091015492955090935061187f925061ffff811691620100009091046001600160a01b03169085612af2565b600084815260086020526040902060010154909150811161189f57600080fd5b81518114156119175760008381526008602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba2339061190a9085815260200190565b60405180910390a16119ab565b60408051608081018252600085815260086020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b50505050565b6060600b8054610ca1906142b3565b6002546001600160a01b031633146119ea5760405162461bcd60e51b8152600401610ac4906142f8565b6127106119f5611026565b1115611a0057600080fd5b600254611a16906001600160a01b031682612b44565b50565b6002546001600160a01b03163314611a435760405162461bcd60e51b8152600401610ac4906142f8565b60008111611a5057600080fd5b61ffff909116600090815260066020526040902055565b6001600160a01b038216331415611abf5760405162461bcd60e51b815260206004820152601c60248201527b22a9219b9918a839b49d1030b8383937bb32903a379031b0b63632b960211b6044820152606401610ac4565b336000818152600f602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600080600d5461103091906146c1565b601080546110fe906142b3565b6002546001600160a01b03163314611b725760405162461bcd60e51b8152600401610ac4906142f8565b818130604051602001611b879392919061454c565b60408051601f1981840301815291815261ffff8516600090815260208181529190208251611bba93919290910190613767565b50600080516020614add833981519152838383604051611bdc9392919061452e565b60405180910390a1505050565b6004546201000090046001600160a01b03163314611c0657600080fd5b6127108161ffff161115611c1957600080fd5b6004805461ffff191661ffff92909216919091179055565b611c3b338361233f565b611c575760405162461bcd60e51b8152600401610ac49061432f565b6119ab84848484612b62565b611c7489898989898989898961262f565b505050505050505050565b6060611c89612b97565b6011611c9484612bb8565b604051602001611ca693929190614772565b6040516020818303038152906040529050919050565b6002546001600160a01b03163314611ce65760405162461bcd60e51b8152600401610ac4906142f8565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c90611d3a90889088908890889088906004016147cb565b600060405180830381600087803b158015611d5457600080fd5b505af1158015611c74573d6000803e3d6000fd5b6004546201000090046001600160a01b03163314611d8557600080fd5b600480546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6002546001600160a01b03163314611dd95760405162461bcd60e51b8152600401610ac4906142f8565b60008111611de657600080fd5b61ffff909116600090815260076020526040902055565b61ffff86166000908152600360205260408082209051611e2090889088906142e8565b90815260408051602092819003830190206001600160401b03871660009081529252902054905080611ea05760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610ac4565b808383604051611eb19291906142e8565b604051809103902014611f105760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610ac4565b61ffff87166000908152600360205260408082209051611f3390899089906142e8565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252611fcb918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506128a292505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516120029594939291906147f9565b60405180910390a150505050505050565b6002546001600160a01b0316331461203d5760405162461bcd60e51b8152600401610ac4906142f8565b6000811161204a57600080fd5b61ffff83811660008181526001602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611bdc565b60606120b6612b97565b60106040516020016120c9929190614834565b604051602081830303815290604052905090565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b6002546001600160a01b031633146121355760405162461bcd60e51b8152600401610ac4906142f8565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc9060840160006040518083038186803b1580156121d257600080fd5b505afa1580156121e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261220e9190810190614852565b95945050505050565b60008061227a5a60966366ad5c8a60e01b8989898960405160240161223f9493929190614886565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190612cb5565b9150915081611710576117108686868685612d3f565b60006001600160e01b031982166380ac58cd60e01b1480610c8c5750610c8c82612dcd565b60006122c0600d5490565b82108015610c8c5750600192915050565b6000818152600e6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061230682611628565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061234a826122b5565b6123ae5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610ac4565b60006123b983611628565b9050806001600160a01b0316846001600160a01b031614806123f45750836001600160a01b03166123e984610dcf565b6001600160a01b0316145b80612404575061240481856120dd565b949350505050565b6000806124188361280b565b91509150846001600160a01b0316826001600160a01b0316146124925760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b6064820152608401610ac4565b6001600160a01b0384166124f85760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b6064820152608401610ac4565b6125036000846122d1565b60006125108460016144ed565b600881901c600090815260096020526040902054909150600160ff1b60ff83161c161580156125405750600d5481105b15612577576000818152600c6020526040902080546001600160a01b0319166001600160a01b038816179055612577600982612e02565b6000848152600c6020526040902080546001600160a01b0319166001600160a01b0387161790558184146125b0576125b0600985612e02565b83856001600160a01b0316876001600160a01b0316600080516020614afd83398151915260405160405180910390a4611710565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061261e5761261e6148c4565b602090810291909101015292915050565b60008651116126765760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610ac4565b61ffff8816600090815260066020526040902054865111156126e55760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610ac4565b60005b8651811015612728576127168a8a8a8a8581518110612709576127096148c4565b6020026020010151612e2e565b806127208161456d565b9150506126e8565b50600087838884604051602001612742949392919061441d565b6040516020818303038152906040529050612787896001868a51600760008f61ffff1661ffff168152602001908152602001600020546127829190614399565b612f02565b600061279234612fdc565b90506127a28a83898989866130ae565b886040516127b091906148da565b60405180910390208b6001600160a01b03168b61ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a8b6040516127f691906148f6565b60405180910390a45050505050505050505050565b600080612817836122b5565b6128785760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ac4565b61288183613249565b6000818152600c60205260409020546001600160a01b031694909350915050565b600080600080848060200190518101906128bc91906145cd565b6014840151602884015194985092965090945092509060006128e08b848388612af2565b905084518110156129f35760008880519060200120905060405180608001604052808d61ffff168152602001856001600160a01b03168152602001838152602001600115158152506008600083815260200190815260200160002060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816001015560608201518160020160006101000a81548160ff0219169083151502179055509050507f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad7818a6040516129e9929190614909565b60405180910390a1505b826001600160a01b03168a604051612a0b91906148da565b60405180910390208c61ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026588604051612a4791906148f6565b60405180910390a4845181148015612a6757506001600160a01b03821615155b15612ae55760405163bace587f60e01b81528b908b9085908590899089906001600160a01b0384169063bace587f90612aac9089908990899088908890600401614922565b600060405180830381600087803b158015612ac657600080fd5b505af1158015612ada573d6000803e3d6000fd5b505050505050505050505b5050505050505050505050565b6000825b825181101561220e576005545a1015612b0e5761220e565b612b328686858481518110612b2557612b256148c4565b6020026020010151613256565b80612b3c8161456d565b915050612af6565b612b5e8282604051806020016040528060008152506132b6565b5050565b612b6d84848461240c565b612b7b8484846001856132d7565b6119ab5760405162461bcd60e51b8152600401610ac490614974565b604080518082019091526007815266697066733a2f2f60c81b602082015290565b606081612bdc5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612c065780612bf08161456d565b9150612bff9050600a836143ce565b9150612be0565b6000816001600160401b03811115612c2057612c20613a6f565b6040519080825280601f01601f191660200182016040528015612c4a576020820181803683370190505b5090505b841561240457612c5f6001836146c1565b9150612c6c600a866149c9565b612c779060306144ed565b60f81b818381518110612c8c57612c8c6148c4565b60200101906001600160f81b031916908160001a905350612cae600a866143ce565b9450612c4e565b6000606060008060008661ffff166001600160401b03811115612cda57612cda613a6f565b6040519080825280601f01601f191660200182016040528015612d04576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612d26578692505b828152826000602083013e909890975095505050505050565b8180519060200120600360008761ffff1661ffff16815260200190815260200160002085604051612d7091906148da565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c9061159490879087908790879087906149dd565b60006001600160e01b031982166381af209b60e01b1480610c8c57506301ffc9a760e01b6001600160e01b0319831614610c8c565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b612e38338261233f565b612e925760405162461bcd60e51b815260206004820152602560248201527f73656e642063616c6c6572206973206e6f74206f776e6572206e6f72206170706044820152641c9bdd995960da1b6064820152608401610ac4565b836001600160a01b0316612ea582611628565b6001600160a01b031614612ef75760405162461bcd60e51b815260206004820152601960248201527839b2b73210333937b69034b731b7b93932b1ba1037bbb732b960391b6044820152606401610ac4565b6119ab84308361240c565b6000612f0d83613419565b61ffff808716600090815260016020908152604080832093891683529290529081205491925090612f3f9084906144ed565b905060008111612f8e5760405162461bcd60e51b815260206004820152601a602482015279131e905c1c0e881b5a5b91d85cd31a5b5a5d081b9bdd081cd95d60321b6044820152606401610ac4565b808210156117105760405162461bcd60e51b815260206004820152601b60248201527a4c7a4170703a20676173206c696d697420697320746f6f206c6f7760281b6044820152606401610ac4565b600454600090819061271090612ff69061ffff1685614399565b61300091906143ce565b905061300c81846146c1565b915080156130a8576004546040516000916201000090046001600160a01b03169083908381818185875af1925050503d8060008114613067576040519150601f19603f3d011682016040523d82523d6000602084013e61306c565b606091505b50509050806130a65760405162461bcd60e51b8152600401610ac4906020808252600490820152632166656560e01b604082015260600190565b505b50919050565b61ffff8616600090815260208190526040812080546130cc906142b3565b80601f01602080910402602001604051908101604052809291908181526020018280546130f8906142b3565b80156131455780601f1061311a57610100808354040283529160200191613145565b820191906000526020600020905b81548152906001019060200180831161312857829003601f168201915b505050505090508051600014156131b75760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610ac4565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c580310090849061320e908b9086908c908c908c908c90600401614a1b565b6000604051808303818588803b15801561322757600080fd5b505af115801561323b573d6000803e3d6000fd5b505050505050505050505050565b6000610c8c600983613474565b61325f816122b5565b158061328b575061326f816122b5565b801561328b57503061328082611628565b6001600160a01b0316145b61329457600080fd5b61329d816122b5565b6132ab57610f6b8282612b44565b610f6b30838361240c565b60006132c1600d5490565b90506132cd848461356c565b612b7b6000858386865b60006001600160a01b0385163b1561340d57506001835b6132f884866144ed565b81101561340757604051630a85bd0160e11b81526001600160a01b0387169063150b7a02906133319033908b9086908990600401614a82565b602060405180830381600087803b15801561334b57600080fd5b505af192505050801561337b575060408051601f3d908101601f1916820190925261337891810190614abf565b60015b6133d5573d8080156133a9576040519150601f19603f3d011682016040523d82523d6000602084013e6133ae565b606091505b5080516133cd5760405162461bcd60e51b8152600401610ac490614974565b805181602001fd5b8280156133f257506001600160e01b03198116630a85bd0160e11b145b925050806133ff8161456d565b9150506132ee565b5061220e565b50600195945050505050565b600060228251101561346c5760405162461bcd60e51b815260206004820152601c60248201527b4c7a4170703a20696e76616c69642061646170746572506172616d7360201b6044820152606401610ac4565b506022015190565b600881901c60008181526020849052604081205490919060ff808516919082181c80156134b6576134a4816136e5565b60ff168203600884901b179350613563565b600083116135235760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b6064820152608401610ac4565b50600019909101600081815260208690526040902054909190801561355e5761354b816136e5565b60ff0360ff16600884901b179350613563565b6134b6565b50505092915050565b6000613577600d5490565b9050600082116135d75760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b6064820152608401610ac4565b6001600160a01b0383166136395760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ac4565b81600d600082825461364b91906144ed565b90915550506000818152600c6020526040902080546001600160a01b0319166001600160a01b038516179055613682600982612e02565b60008061368f84846144ed565b90506001600160a01b038516915082826000600080516020614afd833981519152600080a4600183015b8181146136df5780836000600080516020614afd833981519152600080a46001016136b9565b50610dc8565b60006040518061012001604052806101008152602001614b1d610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff61372e8561374f565b02901c81518110613741576137416148c4565b016020015160f81c92915050565b600080821161375d57600080fd5b5060008190031690565b828054613773906142b3565b90600052602060002090601f01602090048101928261379557600085556137db565b82601f106137ae57805160ff19168380011785556137db565b828001600101855582156137db579182015b828111156137db5782518255916020019190600101906137c0565b506137e79291506137eb565b5090565b5b808211156137e757600081556001016137ec565b803561ffff8116811461381257600080fd5b919050565b60008083601f84011261382957600080fd5b5081356001600160401b0381111561384057600080fd5b60208301915083602082850101111561385857600080fd5b9250929050565b80356001600160401b038116811461381257600080fd5b6000806000806000806080878903121561388f57600080fd5b61389887613800565b955060208701356001600160401b03808211156138b457600080fd5b6138c08a838b01613817565b90975095508591506138d460408a0161385f565b945060608901359150808211156138ea57600080fd5b506138f789828a01613817565b979a9699509497509295939492505050565b6001600160e01b031981168114611a1657600080fd5b60006020828403121561393157600080fd5b813561393c81613909565b9392505050565b60005b8381101561395e578181015183820152602001613946565b838111156119ab5750506000910152565b60008151808452613987816020860160208601613943565b601f01601f19169290920160200192915050565b60208152600061393c602083018461396f565b6000602082840312156139c057600080fd5b61393c82613800565b6000602082840312156139db57600080fd5b5035919050565b6001600160a01b0381168114611a1657600080fd5b8035613812816139e2565b60008060408385031215613a1557600080fd5b8235613a20816139e2565b946020939093013593505050565b600080600060608486031215613a4357600080fd5b8335613a4e816139e2565b92506020840135613a5e816139e2565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613aad57613aad613a6f565b604052919050565b60006001600160401b03821115613ace57613ace613a6f565b50601f01601f191660200190565b600082601f830112613aed57600080fd5b8135613b00613afb82613ab5565b613a85565b818152846020838601011115613b1557600080fd5b816020850160208301376000918101602001919091529392505050565b8035801515811461381257600080fd5b600080600080600060a08688031215613b5a57600080fd5b613b6386613800565b945060208601356001600160401b0380821115613b7f57600080fd5b613b8b89838a01613adc565b955060408801359450613ba060608901613b32565b93506080880135915080821115613bb657600080fd5b50613bc388828901613adc565b9150509295509295909350565b60008060408385031215613be357600080fd5b50508035926020909101359150565b60006001600160401b03821115613c0b57613c0b613a6f565b5060051b60200190565b600082601f830112613c2657600080fd5b81356020613c36613afb83613bf2565b82815260059290921b84018101918181019086841115613c5557600080fd5b8286015b84811015613c705780358352918301918301613c59565b509695505050505050565b60008060008060008060c08789031215613c9457600080fd5b613c9d87613800565b955060208701356001600160401b0380821115613cb957600080fd5b613cc58a838b01613adc565b96506040890135915080821115613cdb57600080fd5b613ce78a838b01613c15565b9550613cf560608a01613b32565b94506080890135915080821115613d0b57600080fd5b613d178a838b01613adc565b935060a0890135915080821115613d2d57600080fd5b50613d3a89828a01613adc565b9150509295509295509295565b600080600060408486031215613d5c57600080fd5b613d6584613800565b925060208401356001600160401b03811115613d8057600080fd5b613d8c86828701613817565b9497909650939450505050565b600080600080600060808688031215613db157600080fd5b613dba86613800565b945060208601356001600160401b03811115613dd557600080fd5b613de188828901613817565b9699909850959660408101359660609091013595509350505050565b600080600080600080600060e0888a031215613e1857600080fd5b8735613e23816139e2565b9650613e3160208901613800565b955060408801356001600160401b0380821115613e4d57600080fd5b613e598b838c01613adc565b965060608a0135955060808a01359150613e72826139e2565b90935060a089013590613e84826139e2565b90925060c08901359080821115613e9a57600080fd5b50613ea78a828b01613adc565b91505092959891949750929550565b600060208284031215613ec857600080fd5b813562ffffff8116811461393c57600080fd5b600080600060608486031215613ef057600080fd5b613ef984613800565b925060208401356001600160401b03811115613f1457600080fd5b613f2086828701613adc565b925050613f2f6040850161385f565b90509250925092565b600060208284031215613f4a57600080fd5b813561393c816139e2565b60008060408385031215613f6857600080fd5b613f7183613800565b9150613f7f60208401613800565b90509250929050565b600060208284031215613f9a57600080fd5b81356001600160401b03811115613fb057600080fd5b61240484828501613adc565b60008060408385031215613fcf57600080fd5b613a2083613800565b60008060408385031215613feb57600080fd5b8235613ff6816139e2565b9150613f7f60208401613b32565b6000806000806080858703121561401a57600080fd5b8435614025816139e2565b93506020850135614035816139e2565b92506040850135915060608501356001600160401b0381111561405757600080fd5b61406387828801613adc565b91505092959194509250565b60008060008060008060008060006101208a8c03121561408e57600080fd5b6140978a6139f7565b98506140a560208b01613800565b975060408a01356001600160401b03808211156140c157600080fd5b6140cd8d838e01613adc565b985060608c01359150808211156140e357600080fd5b6140ef8d838e01613c15565b97506140fd60808d016139f7565b965061410b60a08d016139f7565b955060c08c013591508082111561412157600080fd5b61412d8d838e01613adc565b945060e08c013591508082111561414357600080fd5b61414f8d838e01613adc565b93506101008c013591508082111561416657600080fd5b506141738c828d01613adc565b9150509295985092959850929598565b60008060008060006080868803121561419b57600080fd5b6141a486613800565b94506141b260208701613800565b93506040860135925060608601356001600160401b038111156141d457600080fd5b6141e088828901613817565b969995985093965092949392505050565b60008060006060848603121561420657600080fd5b61420f84613800565b925061421d60208501613800565b9150604084013590509250925092565b6000806040838503121561424057600080fd5b823561424b816139e2565b9150602083013561425b816139e2565b809150509250929050565b6000806000806080858703121561427c57600080fd5b61428585613800565b935061429360208601613800565b925060408501356142a3816139e2565b9396929550929360600135925050565b600181811c908216806142c757607f821691505b602082108114156130a857634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b6020808252601e908201527f4c7a4170703a2063616c6c6572206973206e6f7420746865206f776e65720000604082015260600190565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156143b3576143b3614383565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826143dd576143dd6143b8565b500490565b600081518084526020808501945080840160005b83811015614412578151875295820195908201906001016143f6565b509495945050505050565b608081526000614430608083018761396f565b8281036020840152614442818761396f565b9050828103604084015261445681866143e2565b9050828103606084015261446a818561396f565b979650505050505050565b61ffff861681526001600160a01b038516602082015260a0604082018190526000906144a39083018661396f565b841515606084015282810360808401526144bd818561396f565b98975050505050505050565b600080604083850312156144dc57600080fd5b505080516020909101519092909150565b6000821982111561450057614500614383565b500190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff8416815260406020820152600061220e604083018486614505565b8284823760609190911b6001600160601b0319169101908152601401919050565b600060001982141561458157614581614383565b5060010190565b600082601f83011261459957600080fd5b81516145a7613afb82613ab5565b8181528460208386010111156145bc57600080fd5b612404826020830160208701613943565b600080600080608085870312156145e357600080fd5b84516001600160401b03808211156145fa57600080fd5b61460688838901614588565b955060209150818701518181111561461d57600080fd5b61462989828a01614588565b95505060408701518181111561463e57600080fd5b8701601f8101891361464f57600080fd5b805161465d613afb82613bf2565b81815260059190911b8201840190848101908b83111561467c57600080fd5b928501925b8284101561469a57835182529285019290850190614681565b60608b01519097509450505050808211156146b457600080fd5b5061406387828801614588565b6000828210156146d3576146d3614383565b500390565b8054600090600181811c90808316806146f257607f831692505b602080841082141561471457634e487b7160e01b600052602260045260246000fd5b818015614728576001811461473957614766565b60ff19861689528489019650614766565b60008881526020902060005b8681101561475e5781548b820152908501908301614745565b505084890196505b50505050505092915050565b60008451614784818460208901613943565b614790818401866146d8565b9050602f60f81b815283516147ac816001840160208801613943565b64173539b7b760d91b6001929091019182015260060195945050505050565b600061ffff80881683528087166020840152508460408301526080606083015261446a608083018486614505565b61ffff86168152608060208201526000614817608083018688614505565b6001600160401b0394909416604083015250606001529392505050565b60008351614846818460208801613943565b61220e818401856146d8565b60006020828403121561486457600080fd5b81516001600160401b0381111561487a57600080fd5b61240484828501614588565b61ffff851681526080602082015260006148a3608083018661396f565b6001600160401b0385166040840152828103606084015261446a818561396f565b634e487b7160e01b600052603260045260246000fd5b600082516148ec818460208701613943565b9190910192915050565b60208152600061393c60208301846143e2565b828152604060208201526000612404604083018461396f565b61ffff8616815260a06020820152600061493f60a083018761396f565b6001600160a01b0386166040840152828103606084015261496081866143e2565b905082810360808401526144bd818561396f565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b6000826149d8576149d86143b8565b500690565b61ffff8616815260a0602082015260006149fa60a083018761396f565b6001600160401b03861660408401528281036060840152614960818661396f565b61ffff8716815260c060208201526000614a3860c083018861396f565b8281036040840152614a4a818861396f565b6001600160a01b0387811660608601528616608085015283810360a08501529050614a75818561396f565b9998505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614ab59083018461396f565b9695505050505050565b600060208284031215614ad157600080fd5b815161393c8161390956fe8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ceddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212205419fe7d71e8c77355e02a9e369bccd3b08210e7c851dd210beebbe96d0cd76364736f6c6343000809003300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000f285e70ca2002b796a575e473285282bbf39d790000000000000000000000000000000000000000000000000000000000003d0900000000000000000000000003c2269811836af69497e5f486a85d7316753cf6200000000000000000000000000000000000000000000000000000000000000105a6b616c69656e204578706c6f7265720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035a4b580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b6261666b726569677a346773623472326263756e736468377532736233717233686667646f6868796d73697774703271636177746b616d367264610000000000000000000000000000000000000000000000000000000000000000000000003b6261667962656966746d756f786e686c6d6d6f62666872616c6c69616233707471757764787033646a6979343261357067643236326f6d6a3335710000000000

Deployed Bytecode

0x60806040526004361061027a5760003560e01c80621d35671461027f57806301ffc9a7146102a157806306fdde03146102d657806307e0db17146102f8578063081812fc14610318578063095ea7b3146103505780630b4cad4c1461037057806310ddb1371461039057806318160ddd146103b057806322a3ecf9146103d357806323b872dd146104565780632a205e3d146104765780632a55205a146104ab5780632dd0066e146104ea5780633b5aeddb146104ff5780633d8b38f61461051f57806342842e0e1461053f57806342d65a8d1461055f57806346a438161461057f578063482881901461059f5780634ac3f4ff146105b557806351905636146105e257806352a284a2146105f55780635b8c41e6146106155780636352211e1461066457806366ad5c8a1461068457806370a08231146106a45780637533d788146106c45780638cfd8f5c146106e45780638da5cb5b1461071c5780638ffa1f2a1461073c57806395d89b411461075c5780639d5aef30146107715780639ea5d6b114610791578063a22cb465146107b1578063a2309ff8146107d1578063a5097ebf146107e6578063a6c3d165146107fb578063a7e0d43d1461081b578063af3fb21c1461083b578063b353aaa714610863578063b88d4fde14610897578063c145c54b146108b7578063c4461834146108ca578063c4ed6f58146108e0578063c87b56dd146108fb578063cbed8b9c1461091b578063d0ebdbe71461093b578063d12473a51461095b578063d1deba1f1461097b578063df2a5b3b1461098e578063e8a3d485146109ae578063e985e9c5146109c3578063f2fde38b146109e3578063f5ecbdbc14610a03578063fa25f9b614610a23575b600080fd5b34801561028b57600080fd5b5061029f61029a366004613876565b610a50565b005b3480156102ad57600080fd5b506102c16102bc36600461391f565b610c81565b60405190151581526020015b60405180910390f35b3480156102e257600080fd5b506102eb610c92565b6040516102cd919061399b565b34801561030457600080fd5b5061029f6103133660046139ae565b610d24565b34801561032457600080fd5b506103386103333660046139c9565b610dcf565b6040516001600160a01b0390911681526020016102cd565b34801561035c57600080fd5b5061029f61036b366004613a02565b610e5a565b34801561037c57600080fd5b5061029f61038b3660046139c9565b610f70565b34801561039c57600080fd5b5061029f6103ab3660046139ae565b610fac565b3480156103bc57600080fd5b506103c5611026565b6040519081526020016102cd565b3480156103df57600080fd5b506104276103ee3660046139c9565b60086020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b03909316602085015291830152151560608201526080016102cd565b34801561046257600080fd5b5061029f610471366004613a2e565b611035565b34801561048257600080fd5b50610496610491366004613b42565b611066565b604080519283526020830191909152016102cd565b3480156104b757600080fd5b506104cb6104c6366004613bd0565b61109c565b604080516001600160a01b0390931683526020830191909152016102cd565b3480156104f657600080fd5b506102eb6110f1565b34801561050b57600080fd5b5061049661051a366004613c7b565b61117f565b34801561052b57600080fd5b506102c161053a366004613d47565b611290565b34801561054b57600080fd5b5061029f61055a366004613a2e565b61135c565b34801561056b57600080fd5b5061029f61057a366004613d47565b611377565b34801561058b57600080fd5b5061029f61059a366004613d99565b61141f565b3480156105ab57600080fd5b506103c560055481565b3480156105c157600080fd5b506103c56105d03660046139ae565b60066020526000908152604090205481565b61029f6105f0366004613dfd565b6115a3565b34801561060157600080fd5b5061029f610610366004613eb6565b6115da565b34801561062157600080fd5b506103c5610630366004613edb565b6003602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561067057600080fd5b5061033861067f3660046139c9565b611628565b34801561069057600080fd5b5061029f61069f366004613876565b61163c565b3480156106b057600080fd5b506103c56106bf366004613f38565b611718565b3480156106d057600080fd5b506102eb6106df3660046139ae565b6117e7565b3480156106f057600080fd5b506103c56106ff366004613f55565b600160209081526000928352604080842090915290825290205481565b34801561072857600080fd5b50600254610338906001600160a01b031681565b34801561074857600080fd5b5061029f610757366004613f88565b611800565b34801561076857600080fd5b506102eb6119b1565b34801561077d57600080fd5b5061029f61078c3660046139c9565b6119c0565b34801561079d57600080fd5b5061029f6107ac366004613fbc565b611a19565b3480156107bd57600080fd5b5061029f6107cc366004613fd8565b611a67565b3480156107dd57600080fd5b506103c5611b2b565b3480156107f257600080fd5b506102eb611b3b565b34801561080757600080fd5b5061029f610816366004613d47565b611b48565b34801561082757600080fd5b5061029f6108363660046139ae565b611be9565b34801561084757600080fd5b50610850600181565b60405161ffff90911681526020016102cd565b34801561086f57600080fd5b506103387f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6281565b3480156108a357600080fd5b5061029f6108b2366004614004565b611c31565b61029f6108c536600461406f565b611c63565b3480156108d657600080fd5b506103c561271081565b3480156108ec57600080fd5b506004546108509061ffff1681565b34801561090757600080fd5b506102eb6109163660046139c9565b611c7f565b34801561092757600080fd5b5061029f610936366004614183565b611cbc565b34801561094757600080fd5b5061029f610956366004613f38565b611d68565b34801561096757600080fd5b5061029f610976366004613fbc565b611daf565b61029f610989366004613876565b611dfd565b34801561099a57600080fd5b5061029f6109a93660046141f1565b612013565b3480156109ba57600080fd5b506102eb6120ac565b3480156109cf57600080fd5b506102c16109de36600461422d565b6120dd565b3480156109ef57600080fd5b5061029f6109fe366004613f38565b61210b565b348015610a0f57600080fd5b506102eb610a1e366004614266565b612157565b348015610a2f57600080fd5b506103c5610a3e3660046139ae565b60076020526000908152604090205481565b336001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf621614610acd5760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526020819052604081208054610aeb906142b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610b17906142b3565b8015610b645780601f10610b3957610100808354040283529160200191610b64565b820191906000526020600020905b815481529060010190602001808311610b4757829003601f168201915b50505050509050805186869050148015610b7f575060008151115b8015610ba7575080516020820120604051610b9d90889088906142e8565b6040518091039020145b610c025760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610ac4565b610c788787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061221792505050565b50505050505050565b6000610c8c82612290565b92915050565b6060600a8054610ca1906142b3565b80601f0160208091040260200160405190810160405280929190818152602001828054610ccd906142b3565b8015610d1a5780601f10610cef57610100808354040283529160200191610d1a565b820191906000526020600020905b815481529060010190602001808311610cfd57829003601f168201915b5050505050905090565b6002546001600160a01b03163314610d4e5760405162461bcd60e51b8152600401610ac4906142f8565b6040516307e0db1760e01b815261ffff821660048201527f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610db457600080fd5b505af1158015610dc8573d6000803e3d6000fd5b5050505050565b6000610dda826122b5565b610e3e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a20617070726f76656420717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610ac4565b506000908152600e60205260409020546001600160a01b031690565b6000610e6582611628565b9050806001600160a01b0316836001600160a01b03161415610ed55760405162461bcd60e51b8152602060048201526024808201527f4552433732315073693a20617070726f76616c20746f2063757272656e74206f6044820152633bb732b960e11b6064820152608401610ac4565b336001600160a01b0382161480610ef15750610ef181336120dd565b610f615760405162461bcd60e51b815260206004820152603b60248201527f4552433732315073693a20617070726f76652063616c6c6572206973206e6f7460448201527a081bdddb995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b602a1b6064820152608401610ac4565b610f6b83836122d1565b505050565b6002546001600160a01b03163314610f9a5760405162461bcd60e51b8152600401610ac4906142f8565b60008111610fa757600080fd5b600555565b6002546001600160a01b03163314610fd65760405162461bcd60e51b8152600401610ac4906142f8565b6040516310ddb13760e01b815261ffff821660048201527f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b0316906310ddb13790602401610d9a565b6000611030611b2b565b905090565b61103f338261233f565b61105b5760405162461bcd60e51b8152600401610ac49061432f565b610f6b83838361240c565b60008061108e8787611077886125e4565b87876040518060200160405280600081525061117f565b915091509550959350505050565b604080518082019091526012546001600160a01b038116808352600160a01b90910462ffffff16602083018190529091600091612710906110dd9086614399565b6110e791906143ce565b9150509250929050565b601180546110fe906142b3565b80601f016020809104026020016040519081016040528092919081815260200182805461112a906142b3565b80156111775780601f1061114c57610100808354040283529160200191611177565b820191906000526020600020905b81548152906001019060200180831161115a57829003601f168201915b505050505081565b60008060008788888660405160200161119b949392919061441d565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216906340a7bb10906111ff908c90309086908c908c90600401614475565b604080518083038186803b15801561121657600080fd5b505afa15801561122a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061124e91906144c9565b60045491945092506000906127109061126b9061ffff1686614399565b61127591906143ce565b905061128181856144ed565b93505050965096945050505050565b61ffff8316600090815260208190526040812080548291906112b1906142b3565b80601f01602080910402602001604051908101604052809291908181526020018280546112dd906142b3565b801561132a5780601f106112ff5761010080835404028352916020019161132a565b820191906000526020600020905b81548152906001019060200180831161130d57829003601f168201915b5050505050905083836040516113419291906142e8565b60405180910390208180519060200120149150509392505050565b610f6b83838360405180602001604052806000815250611c31565b6002546001600160a01b031633146113a15760405162461bcd60e51b8152600401610ac4906142f8565b6040516342d65a8d60e01b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216906342d65a8d906113f19086908690869060040161452e565b600060405180830381600087803b15801561140b57600080fd5b505af1158015610c78573d6000803e3d6000fd5b6002546001600160a01b031633146114495760405162461bcd60e51b8152600401610ac4906142f8565b600082116114a55760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610ac4565b61ffff85166000908152600760205260409020829055806115135760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610ac4565b61ffff8516600090815260066020908152604091829020839055905161153f918691869130910161454c565b60408051601f1981840301815291815261ffff871660009081526020818152919020825161157293919290910190613767565b50600080516020614add8339815191528585856040516115949392919061452e565b60405180910390a15050505050565b610c788787876115b2886125e4565b878787604051806020016040528060008152506040518060200160405280600081525061262f565b6002546001600160a01b031633146116045760405162461bcd60e51b8152600401610ac4906142f8565b6012805462ffffff909216600160a01b0262ffffff60a01b19909216919091179055565b6000806116348361280b565b509392505050565b33301461169a5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610ac4565b6117108686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506128a292505050565b505050505050565b60006001600160a01b0382166117865760405162461bcd60e51b815260206004820152602d60248201527f4552433732315073693a2062616c616e636520717565727920666f722074686560448201526c207a65726f206164647265737360981b6064820152608401610ac4565b6000805b600d548110156117e05761179d816122b5565b156117d0576117ab81611628565b6001600160a01b0316846001600160a01b031614156117d0576117cd8261456d565b91505b6117d98161456d565b905061178a565b5092915050565b600060208190529081526040902080546110fe906142b3565b80516020808301919091206000818152600890925260409091206002015460ff1661182a57600080fd5b60008280602001905181019061184091906145cd565b506000858152600860205260408120805460019091015492955090935061187f925061ffff811691620100009091046001600160a01b03169085612af2565b600084815260086020526040902060010154909150811161189f57600080fd5b81518114156119175760008381526008602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba2339061190a9085815260200190565b60405180910390a16119ab565b60408051608081018252600085815260086020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b50505050565b6060600b8054610ca1906142b3565b6002546001600160a01b031633146119ea5760405162461bcd60e51b8152600401610ac4906142f8565b6127106119f5611026565b1115611a0057600080fd5b600254611a16906001600160a01b031682612b44565b50565b6002546001600160a01b03163314611a435760405162461bcd60e51b8152600401610ac4906142f8565b60008111611a5057600080fd5b61ffff909116600090815260066020526040902055565b6001600160a01b038216331415611abf5760405162461bcd60e51b815260206004820152601c60248201527b22a9219b9918a839b49d1030b8383937bb32903a379031b0b63632b960211b6044820152606401610ac4565b336000818152600f602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600080600d5461103091906146c1565b601080546110fe906142b3565b6002546001600160a01b03163314611b725760405162461bcd60e51b8152600401610ac4906142f8565b818130604051602001611b879392919061454c565b60408051601f1981840301815291815261ffff8516600090815260208181529190208251611bba93919290910190613767565b50600080516020614add833981519152838383604051611bdc9392919061452e565b60405180910390a1505050565b6004546201000090046001600160a01b03163314611c0657600080fd5b6127108161ffff161115611c1957600080fd5b6004805461ffff191661ffff92909216919091179055565b611c3b338361233f565b611c575760405162461bcd60e51b8152600401610ac49061432f565b6119ab84848484612b62565b611c7489898989898989898961262f565b505050505050505050565b6060611c89612b97565b6011611c9484612bb8565b604051602001611ca693929190614772565b6040516020818303038152906040529050919050565b6002546001600160a01b03163314611ce65760405162461bcd60e51b8152600401610ac4906142f8565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62169063cbed8b9c90611d3a90889088908890889088906004016147cb565b600060405180830381600087803b158015611d5457600080fd5b505af1158015611c74573d6000803e3d6000fd5b6004546201000090046001600160a01b03163314611d8557600080fd5b600480546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6002546001600160a01b03163314611dd95760405162461bcd60e51b8152600401610ac4906142f8565b60008111611de657600080fd5b61ffff909116600090815260076020526040902055565b61ffff86166000908152600360205260408082209051611e2090889088906142e8565b90815260408051602092819003830190206001600160401b03871660009081529252902054905080611ea05760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610ac4565b808383604051611eb19291906142e8565b604051809103902014611f105760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610ac4565b61ffff87166000908152600360205260408082209051611f3390899089906142e8565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252611fcb918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506128a292505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516120029594939291906147f9565b60405180910390a150505050505050565b6002546001600160a01b0316331461203d5760405162461bcd60e51b8152600401610ac4906142f8565b6000811161204a57600080fd5b61ffff83811660008181526001602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611bdc565b60606120b6612b97565b60106040516020016120c9929190614834565b604051602081830303815290604052905090565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b6002546001600160a01b031633146121355760405162461bcd60e51b8152600401610ac4906142f8565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b03169063f5ecbdbc9060840160006040518083038186803b1580156121d257600080fd5b505afa1580156121e6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261220e9190810190614852565b95945050505050565b60008061227a5a60966366ad5c8a60e01b8989898960405160240161223f9493929190614886565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190612cb5565b9150915081611710576117108686868685612d3f565b60006001600160e01b031982166380ac58cd60e01b1480610c8c5750610c8c82612dcd565b60006122c0600d5490565b82108015610c8c5750600192915050565b6000818152600e6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061230682611628565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061234a826122b5565b6123ae5760405162461bcd60e51b815260206004820152602f60248201527f4552433732315073693a206f70657261746f7220717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610ac4565b60006123b983611628565b9050806001600160a01b0316846001600160a01b031614806123f45750836001600160a01b03166123e984610dcf565b6001600160a01b0316145b80612404575061240481856120dd565b949350505050565b6000806124188361280b565b91509150846001600160a01b0316826001600160a01b0316146124925760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a207472616e73666572206f6620746f6b656e2074686160448201526b3a1034b9903737ba1037bbb760a11b6064820152608401610ac4565b6001600160a01b0384166124f85760405162461bcd60e51b815260206004820152602760248201527f4552433732315073693a207472616e7366657220746f20746865207a65726f206044820152666164647265737360c81b6064820152608401610ac4565b6125036000846122d1565b60006125108460016144ed565b600881901c600090815260096020526040902054909150600160ff1b60ff83161c161580156125405750600d5481105b15612577576000818152600c6020526040902080546001600160a01b0319166001600160a01b038816179055612577600982612e02565b6000848152600c6020526040902080546001600160a01b0319166001600160a01b0387161790558184146125b0576125b0600985612e02565b83856001600160a01b0316876001600160a01b0316600080516020614afd83398151915260405160405180910390a4611710565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061261e5761261e6148c4565b602090810291909101015292915050565b60008651116126765760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610ac4565b61ffff8816600090815260066020526040902054865111156126e55760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610ac4565b60005b8651811015612728576127168a8a8a8a8581518110612709576127096148c4565b6020026020010151612e2e565b806127208161456d565b9150506126e8565b50600087838884604051602001612742949392919061441d565b6040516020818303038152906040529050612787896001868a51600760008f61ffff1661ffff168152602001908152602001600020546127829190614399565b612f02565b600061279234612fdc565b90506127a28a83898989866130ae565b886040516127b091906148da565b60405180910390208b6001600160a01b03168b61ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a8b6040516127f691906148f6565b60405180910390a45050505050505050505050565b600080612817836122b5565b6128785760405162461bcd60e51b815260206004820152602c60248201527f4552433732315073693a206f776e657220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ac4565b61288183613249565b6000818152600c60205260409020546001600160a01b031694909350915050565b600080600080848060200190518101906128bc91906145cd565b6014840151602884015194985092965090945092509060006128e08b848388612af2565b905084518110156129f35760008880519060200120905060405180608001604052808d61ffff168152602001856001600160a01b03168152602001838152602001600115158152506008600083815260200190815260200160002060008201518160000160006101000a81548161ffff021916908361ffff16021790555060208201518160000160026101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816001015560608201518160020160006101000a81548160ff0219169083151502179055509050507f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad7818a6040516129e9929190614909565b60405180910390a1505b826001600160a01b03168a604051612a0b91906148da565b60405180910390208c61ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026588604051612a4791906148f6565b60405180910390a4845181148015612a6757506001600160a01b03821615155b15612ae55760405163bace587f60e01b81528b908b9085908590899089906001600160a01b0384169063bace587f90612aac9089908990899088908890600401614922565b600060405180830381600087803b158015612ac657600080fd5b505af1158015612ada573d6000803e3d6000fd5b505050505050505050505b5050505050505050505050565b6000825b825181101561220e576005545a1015612b0e5761220e565b612b328686858481518110612b2557612b256148c4565b6020026020010151613256565b80612b3c8161456d565b915050612af6565b612b5e8282604051806020016040528060008152506132b6565b5050565b612b6d84848461240c565b612b7b8484846001856132d7565b6119ab5760405162461bcd60e51b8152600401610ac490614974565b604080518082019091526007815266697066733a2f2f60c81b602082015290565b606081612bdc5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612c065780612bf08161456d565b9150612bff9050600a836143ce565b9150612be0565b6000816001600160401b03811115612c2057612c20613a6f565b6040519080825280601f01601f191660200182016040528015612c4a576020820181803683370190505b5090505b841561240457612c5f6001836146c1565b9150612c6c600a866149c9565b612c779060306144ed565b60f81b818381518110612c8c57612c8c6148c4565b60200101906001600160f81b031916908160001a905350612cae600a866143ce565b9450612c4e565b6000606060008060008661ffff166001600160401b03811115612cda57612cda613a6f565b6040519080825280601f01601f191660200182016040528015612d04576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115612d26578692505b828152826000602083013e909890975095505050505050565b8180519060200120600360008761ffff1661ffff16815260200190815260200160002085604051612d7091906148da565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c9061159490879087908790879087906149dd565b60006001600160e01b031982166381af209b60e01b1480610c8c57506301ffc9a760e01b6001600160e01b0319831614610c8c565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b612e38338261233f565b612e925760405162461bcd60e51b815260206004820152602560248201527f73656e642063616c6c6572206973206e6f74206f776e6572206e6f72206170706044820152641c9bdd995960da1b6064820152608401610ac4565b836001600160a01b0316612ea582611628565b6001600160a01b031614612ef75760405162461bcd60e51b815260206004820152601960248201527839b2b73210333937b69034b731b7b93932b1ba1037bbb732b960391b6044820152606401610ac4565b6119ab84308361240c565b6000612f0d83613419565b61ffff808716600090815260016020908152604080832093891683529290529081205491925090612f3f9084906144ed565b905060008111612f8e5760405162461bcd60e51b815260206004820152601a602482015279131e905c1c0e881b5a5b91d85cd31a5b5a5d081b9bdd081cd95d60321b6044820152606401610ac4565b808210156117105760405162461bcd60e51b815260206004820152601b60248201527a4c7a4170703a20676173206c696d697420697320746f6f206c6f7760281b6044820152606401610ac4565b600454600090819061271090612ff69061ffff1685614399565b61300091906143ce565b905061300c81846146c1565b915080156130a8576004546040516000916201000090046001600160a01b03169083908381818185875af1925050503d8060008114613067576040519150601f19603f3d011682016040523d82523d6000602084013e61306c565b606091505b50509050806130a65760405162461bcd60e51b8152600401610ac4906020808252600490820152632166656560e01b604082015260600190565b505b50919050565b61ffff8616600090815260208190526040812080546130cc906142b3565b80601f01602080910402602001604051908101604052809291908181526020018280546130f8906142b3565b80156131455780601f1061311a57610100808354040283529160200191613145565b820191906000526020600020905b81548152906001019060200180831161312857829003601f168201915b505050505090508051600014156131b75760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610ac4565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62169063c580310090849061320e908b9086908c908c908c908c90600401614a1b565b6000604051808303818588803b15801561322757600080fd5b505af115801561323b573d6000803e3d6000fd5b505050505050505050505050565b6000610c8c600983613474565b61325f816122b5565b158061328b575061326f816122b5565b801561328b57503061328082611628565b6001600160a01b0316145b61329457600080fd5b61329d816122b5565b6132ab57610f6b8282612b44565b610f6b30838361240c565b60006132c1600d5490565b90506132cd848461356c565b612b7b6000858386865b60006001600160a01b0385163b1561340d57506001835b6132f884866144ed565b81101561340757604051630a85bd0160e11b81526001600160a01b0387169063150b7a02906133319033908b9086908990600401614a82565b602060405180830381600087803b15801561334b57600080fd5b505af192505050801561337b575060408051601f3d908101601f1916820190925261337891810190614abf565b60015b6133d5573d8080156133a9576040519150601f19603f3d011682016040523d82523d6000602084013e6133ae565b606091505b5080516133cd5760405162461bcd60e51b8152600401610ac490614974565b805181602001fd5b8280156133f257506001600160e01b03198116630a85bd0160e11b145b925050806133ff8161456d565b9150506132ee565b5061220e565b50600195945050505050565b600060228251101561346c5760405162461bcd60e51b815260206004820152601c60248201527b4c7a4170703a20696e76616c69642061646170746572506172616d7360201b6044820152606401610ac4565b506022015190565b600881901c60008181526020849052604081205490919060ff808516919082181c80156134b6576134a4816136e5565b60ff168203600884901b179350613563565b600083116135235760405162461bcd60e51b815260206004820152603460248201527f4269744d6170733a205468652073657420626974206265666f7265207468652060448201527334b73232bc103237b2b9b713ba1032bc34b9ba1760611b6064820152608401610ac4565b50600019909101600081815260208690526040902054909190801561355e5761354b816136e5565b60ff0360ff16600884901b179350613563565b6134b6565b50505092915050565b6000613577600d5490565b9050600082116135d75760405162461bcd60e51b815260206004820152602560248201527f4552433732315073693a207175616e74697479206d7573742062652067726561604482015264074657220360dc1b6064820152608401610ac4565b6001600160a01b0383166136395760405162461bcd60e51b815260206004820152602360248201527f4552433732315073693a206d696e7420746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ac4565b81600d600082825461364b91906144ed565b90915550506000818152600c6020526040902080546001600160a01b0319166001600160a01b038516179055613682600982612e02565b60008061368f84846144ed565b90506001600160a01b038516915082826000600080516020614afd833981519152600080a4600183015b8181146136df5780836000600080516020614afd833981519152600080a46001016136b9565b50610dc8565b60006040518061012001604052806101008152602001614b1d610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff61372e8561374f565b02901c81518110613741576137416148c4565b016020015160f81c92915050565b600080821161375d57600080fd5b5060008190031690565b828054613773906142b3565b90600052602060002090601f01602090048101928261379557600085556137db565b82601f106137ae57805160ff19168380011785556137db565b828001600101855582156137db579182015b828111156137db5782518255916020019190600101906137c0565b506137e79291506137eb565b5090565b5b808211156137e757600081556001016137ec565b803561ffff8116811461381257600080fd5b919050565b60008083601f84011261382957600080fd5b5081356001600160401b0381111561384057600080fd5b60208301915083602082850101111561385857600080fd5b9250929050565b80356001600160401b038116811461381257600080fd5b6000806000806000806080878903121561388f57600080fd5b61389887613800565b955060208701356001600160401b03808211156138b457600080fd5b6138c08a838b01613817565b90975095508591506138d460408a0161385f565b945060608901359150808211156138ea57600080fd5b506138f789828a01613817565b979a9699509497509295939492505050565b6001600160e01b031981168114611a1657600080fd5b60006020828403121561393157600080fd5b813561393c81613909565b9392505050565b60005b8381101561395e578181015183820152602001613946565b838111156119ab5750506000910152565b60008151808452613987816020860160208601613943565b601f01601f19169290920160200192915050565b60208152600061393c602083018461396f565b6000602082840312156139c057600080fd5b61393c82613800565b6000602082840312156139db57600080fd5b5035919050565b6001600160a01b0381168114611a1657600080fd5b8035613812816139e2565b60008060408385031215613a1557600080fd5b8235613a20816139e2565b946020939093013593505050565b600080600060608486031215613a4357600080fd5b8335613a4e816139e2565b92506020840135613a5e816139e2565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613aad57613aad613a6f565b604052919050565b60006001600160401b03821115613ace57613ace613a6f565b50601f01601f191660200190565b600082601f830112613aed57600080fd5b8135613b00613afb82613ab5565b613a85565b818152846020838601011115613b1557600080fd5b816020850160208301376000918101602001919091529392505050565b8035801515811461381257600080fd5b600080600080600060a08688031215613b5a57600080fd5b613b6386613800565b945060208601356001600160401b0380821115613b7f57600080fd5b613b8b89838a01613adc565b955060408801359450613ba060608901613b32565b93506080880135915080821115613bb657600080fd5b50613bc388828901613adc565b9150509295509295909350565b60008060408385031215613be357600080fd5b50508035926020909101359150565b60006001600160401b03821115613c0b57613c0b613a6f565b5060051b60200190565b600082601f830112613c2657600080fd5b81356020613c36613afb83613bf2565b82815260059290921b84018101918181019086841115613c5557600080fd5b8286015b84811015613c705780358352918301918301613c59565b509695505050505050565b60008060008060008060c08789031215613c9457600080fd5b613c9d87613800565b955060208701356001600160401b0380821115613cb957600080fd5b613cc58a838b01613adc565b96506040890135915080821115613cdb57600080fd5b613ce78a838b01613c15565b9550613cf560608a01613b32565b94506080890135915080821115613d0b57600080fd5b613d178a838b01613adc565b935060a0890135915080821115613d2d57600080fd5b50613d3a89828a01613adc565b9150509295509295509295565b600080600060408486031215613d5c57600080fd5b613d6584613800565b925060208401356001600160401b03811115613d8057600080fd5b613d8c86828701613817565b9497909650939450505050565b600080600080600060808688031215613db157600080fd5b613dba86613800565b945060208601356001600160401b03811115613dd557600080fd5b613de188828901613817565b9699909850959660408101359660609091013595509350505050565b600080600080600080600060e0888a031215613e1857600080fd5b8735613e23816139e2565b9650613e3160208901613800565b955060408801356001600160401b0380821115613e4d57600080fd5b613e598b838c01613adc565b965060608a0135955060808a01359150613e72826139e2565b90935060a089013590613e84826139e2565b90925060c08901359080821115613e9a57600080fd5b50613ea78a828b01613adc565b91505092959891949750929550565b600060208284031215613ec857600080fd5b813562ffffff8116811461393c57600080fd5b600080600060608486031215613ef057600080fd5b613ef984613800565b925060208401356001600160401b03811115613f1457600080fd5b613f2086828701613adc565b925050613f2f6040850161385f565b90509250925092565b600060208284031215613f4a57600080fd5b813561393c816139e2565b60008060408385031215613f6857600080fd5b613f7183613800565b9150613f7f60208401613800565b90509250929050565b600060208284031215613f9a57600080fd5b81356001600160401b03811115613fb057600080fd5b61240484828501613adc565b60008060408385031215613fcf57600080fd5b613a2083613800565b60008060408385031215613feb57600080fd5b8235613ff6816139e2565b9150613f7f60208401613b32565b6000806000806080858703121561401a57600080fd5b8435614025816139e2565b93506020850135614035816139e2565b92506040850135915060608501356001600160401b0381111561405757600080fd5b61406387828801613adc565b91505092959194509250565b60008060008060008060008060006101208a8c03121561408e57600080fd5b6140978a6139f7565b98506140a560208b01613800565b975060408a01356001600160401b03808211156140c157600080fd5b6140cd8d838e01613adc565b985060608c01359150808211156140e357600080fd5b6140ef8d838e01613c15565b97506140fd60808d016139f7565b965061410b60a08d016139f7565b955060c08c013591508082111561412157600080fd5b61412d8d838e01613adc565b945060e08c013591508082111561414357600080fd5b61414f8d838e01613adc565b93506101008c013591508082111561416657600080fd5b506141738c828d01613adc565b9150509295985092959850929598565b60008060008060006080868803121561419b57600080fd5b6141a486613800565b94506141b260208701613800565b93506040860135925060608601356001600160401b038111156141d457600080fd5b6141e088828901613817565b969995985093965092949392505050565b60008060006060848603121561420657600080fd5b61420f84613800565b925061421d60208501613800565b9150604084013590509250925092565b6000806040838503121561424057600080fd5b823561424b816139e2565b9150602083013561425b816139e2565b809150509250929050565b6000806000806080858703121561427c57600080fd5b61428585613800565b935061429360208601613800565b925060408501356142a3816139e2565b9396929550929360600135925050565b600181811c908216806142c757607f821691505b602082108114156130a857634e487b7160e01b600052602260045260246000fd5b8183823760009101908152919050565b6020808252601e908201527f4c7a4170703a2063616c6c6572206973206e6f7420746865206f776e65720000604082015260600190565b60208082526034908201527f4552433732315073693a207472616e736665722063616c6c6572206973206e6f6040820152731d081bdddb995c881b9bdc88185c1c1c9bdd995960621b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156143b3576143b3614383565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826143dd576143dd6143b8565b500490565b600081518084526020808501945080840160005b83811015614412578151875295820195908201906001016143f6565b509495945050505050565b608081526000614430608083018761396f565b8281036020840152614442818761396f565b9050828103604084015261445681866143e2565b9050828103606084015261446a818561396f565b979650505050505050565b61ffff861681526001600160a01b038516602082015260a0604082018190526000906144a39083018661396f565b841515606084015282810360808401526144bd818561396f565b98975050505050505050565b600080604083850312156144dc57600080fd5b505080516020909101519092909150565b6000821982111561450057614500614383565b500190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff8416815260406020820152600061220e604083018486614505565b8284823760609190911b6001600160601b0319169101908152601401919050565b600060001982141561458157614581614383565b5060010190565b600082601f83011261459957600080fd5b81516145a7613afb82613ab5565b8181528460208386010111156145bc57600080fd5b612404826020830160208701613943565b600080600080608085870312156145e357600080fd5b84516001600160401b03808211156145fa57600080fd5b61460688838901614588565b955060209150818701518181111561461d57600080fd5b61462989828a01614588565b95505060408701518181111561463e57600080fd5b8701601f8101891361464f57600080fd5b805161465d613afb82613bf2565b81815260059190911b8201840190848101908b83111561467c57600080fd5b928501925b8284101561469a57835182529285019290850190614681565b60608b01519097509450505050808211156146b457600080fd5b5061406387828801614588565b6000828210156146d3576146d3614383565b500390565b8054600090600181811c90808316806146f257607f831692505b602080841082141561471457634e487b7160e01b600052602260045260246000fd5b818015614728576001811461473957614766565b60ff19861689528489019650614766565b60008881526020902060005b8681101561475e5781548b820152908501908301614745565b505084890196505b50505050505092915050565b60008451614784818460208901613943565b614790818401866146d8565b9050602f60f81b815283516147ac816001840160208801613943565b64173539b7b760d91b6001929091019182015260060195945050505050565b600061ffff80881683528087166020840152508460408301526080606083015261446a608083018486614505565b61ffff86168152608060208201526000614817608083018688614505565b6001600160401b0394909416604083015250606001529392505050565b60008351614846818460208801613943565b61220e818401856146d8565b60006020828403121561486457600080fd5b81516001600160401b0381111561487a57600080fd5b61240484828501614588565b61ffff851681526080602082015260006148a3608083018661396f565b6001600160401b0385166040840152828103606084015261446a818561396f565b634e487b7160e01b600052603260045260246000fd5b600082516148ec818460208701613943565b9190910192915050565b60208152600061393c60208301846143e2565b828152604060208201526000612404604083018461396f565b61ffff8616815260a06020820152600061493f60a083018761396f565b6001600160a01b0386166040840152828103606084015261496081866143e2565b905082810360808401526144bd818561396f565b60208082526035908201527f4552433732315073693a207472616e7366657220746f206e6f6e20455243373260408201527418a932b1b2b4bb32b91034b6b83632b6b2b73a32b960591b606082015260800190565b6000826149d8576149d86143b8565b500690565b61ffff8616815260a0602082015260006149fa60a083018761396f565b6001600160401b03861660408401528281036060840152614960818661396f565b61ffff8716815260c060208201526000614a3860c083018861396f565b8281036040840152614a4a818861396f565b6001600160a01b0387811660608601528616608085015283810360a08501529050614a75818561396f565b9998505050505050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614ab59083018461396f565b9695505050505050565b600060208284031215614ad157600080fd5b815161393c8161390956fe8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ceddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212205419fe7d71e8c77355e02a9e369bccd3b08210e7c851dd210beebbe96d0cd76364736f6c63430008090033

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

00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000f285e70ca2002b796a575e473285282bbf39d790000000000000000000000000000000000000000000000000000000000003d0900000000000000000000000003c2269811836af69497e5f486a85d7316753cf6200000000000000000000000000000000000000000000000000000000000000105a6b616c69656e204578706c6f7265720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035a4b580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b6261666b726569677a346773623472326263756e736468377532736233717233686667646f6868796d73697774703271636177746b616d367264610000000000000000000000000000000000000000000000000000000000000000000000003b6261667962656966746d756f786e686c6d6d6f62666872616c6c69616233707471757764787033646a6979343261357067643236326f6d6a3335710000000000

-----Decoded View---------------
Arg [0] : _name (string): Zkalien Explorer
Arg [1] : _symbol (string): ZKX
Arg [2] : _collectionURI (string): bafkreigz4gsb4r2bcunsdh7u2sb3qr3hfgdohhymsiwtp2qcawtkam6rda
Arg [3] : _tokensURI (string): bafybeiftmuoxnhlmmobfhralliab3ptquwdxp3djiy42a5pgd262omj35q
Arg [4] : _owner (address): 0xF285E70Ca2002b796A575E473285282BBf39D790
Arg [5] : _minGasToTransfer (uint256): 250000
Arg [6] : _lzEndpoint (address): 0x3c2269811836af69497E5F486A85D7316753cf62

-----Encoded View---------------
17 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [4] : 000000000000000000000000f285e70ca2002b796a575e473285282bbf39d790
Arg [5] : 000000000000000000000000000000000000000000000000000000000003d090
Arg [6] : 0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [8] : 5a6b616c69656e204578706c6f72657200000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [10] : 5a4b580000000000000000000000000000000000000000000000000000000000
Arg [11] : 000000000000000000000000000000000000000000000000000000000000003b
Arg [12] : 6261666b726569677a346773623472326263756e736468377532736233717233
Arg [13] : 686667646f6868796d73697774703271636177746b616d367264610000000000
Arg [14] : 000000000000000000000000000000000000000000000000000000000000003b
Arg [15] : 6261667962656966746d756f786e686c6d6d6f62666872616c6c696162337074
Arg [16] : 71757764787033646a6979343261357067643236326f6d6a3335710000000000


[ 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.