ETH Price: $3,277.24 (-1.62%)

Token

Who is Banksy (ETH)
 

Overview

Max Total Supply

999 ETH

Holders

490

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
*0️⃣-2️⃣-6️⃣.eth
Balance
2 ETH
0xff431392992bdf7a1c2330c7b0195c222495595d
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
WhoIsBanksy

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-02-04
*/

// File: node_modules\erc721a\contracts\IERC721A.sol

// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721A.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the
     * ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    // =============================================================
    //                            IERC721
    // =============================================================

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Transfers `tokenId` 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 payable;

    /**
     * @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 payable;

    /**
     * @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);

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

// File: erc721a\contracts\ERC721A.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721 token receiver.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant _BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant _BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant _BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant _BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See {_packedOwnershipOf} implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

    // Mapping from token ID to approved address.
    mapping(uint256 => TokenApprovalRef) private _tokenApprovals;

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

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

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view virtual returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        // Counter underflow is impossible as `_currentIndex` does not decrement,
        // and it is initialized to `_startTokenId()`.
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view virtual returns (uint256) {
        return _burnCounter;
    }

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal virtual {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

    /**
     * @dev Returns the token collection name.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @dev Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around over time.
     */
    function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal virtual {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

    /**
     * @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) public payable virtual override {
        address owner = ownerOf(tokenId);

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId].value = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @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) public virtual override {
        _operatorApprovals[_msgSenderERC721A()][operator] = approved;
        emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
    }

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @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 memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token IDs
     * are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token IDs
     * have been transferred. This includes minting.
     * And also called after one token has been burned.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns whether the call correctly returned the expected magic value.
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, quantity, '');
    }

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value) internal pure virtual returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }
}

// File: @openzeppelin\contracts\utils\Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin\contracts\access\Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin\contracts\security\ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

// File: @openzeppelin\contracts\utils\cryptography\MerkleProof.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// File: node_modules\operator-filter-registry\src\IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}

// File: node_modules\operator-filter-registry\src\lib\Constants.sol


pragma solidity ^0.8.17;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

// File: node_modules\operator-filter-registry\src\OperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 *         Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract OperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS);

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            if (subscribe) {
                OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    OPERATOR_FILTER_REGISTRY.register(address(this));
                }
            }
        }
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    /**
     * @dev A helper function to check if an operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

// File: operator-filter-registry\src\DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 * @dev    Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract DefaultOperatorFilterer is OperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {}
}

// File: contracts\Banksy.sol





pragma solidity >=0.7.0 <0.9.0;
contract WhoIsBanksy is ERC721A, Ownable, ReentrancyGuard, DefaultOperatorFilterer {


  string public baseURI;
  string public notRevealedUri;
  uint256 public cost = 0.0077 ether;
  uint256 public maxSupply = 999;
  uint256 public MaxperWallet = 3;
  uint256 public MaxperWalletWl = 3;
  bool public paused = false;
  bool public revealed = false;
  bool public preSale = true;
  bytes32 public merkleRoot;

  constructor() ERC721A("Who is Banksy", "ETH") {}

  // internal
  function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
  }
      function _startTokenId() internal view virtual override returns (uint256) {
        return 1;
    }

  // public
  /// @dev Public mint 
  function mint(uint256 tokens) public payable nonReentrant {
    require(!paused, "ETH: oops contract is paused");
    require(!preSale, "ETH: Sale Hasn't started yet");
    require(tokens <= MaxperWallet, "ETH: max mint amount per tx exceeded");
    require(totalSupply() + tokens <= maxSupply, "ETH: We Soldout");
    require(_numberMinted(_msgSenderERC721A()) + tokens <= MaxperWallet, "ETH: Max NFT Per Wallet exceeded");
    require(msg.value >= cost * tokens, "ETH: insufficient funds");

      _safeMint(_msgSenderERC721A(), tokens);
    
  }
/// @dev presale mint for whitelisted
    function presalemint(uint256 tokens, bytes32[] calldata merkleProof) public payable nonReentrant {
    require(!paused, "ETH: oops contract is paused");
    require(preSale, "ETH: Presale Hasnt't started yet");
    require(MerkleProof.verify(merkleProof, merkleRoot, keccak256(abi.encodePacked(msg.sender))), "ETH: You are not Whitelisted");
    require(_numberMinted(_msgSenderERC721A()) + tokens <= MaxperWalletWl, "ETH: Max NFT Per Wallet exceeded");
    require(tokens <= MaxperWalletWl, "ETH: max mint per Tx exceeded");
    require(totalSupply() + tokens <= maxSupply, "ETH: Whitelist MaxSupply exceeded");
    require(msg.value >= cost * tokens, "ETH: insufficient funds");

      _safeMint(_msgSenderERC721A(), tokens);
    
  }

  /// @dev use it for giveaway and team mint
     function airdrop(uint256 _mintAmount, address destination) public onlyOwner nonReentrant {
    require(totalSupply() + _mintAmount <= maxSupply, "max NFT limit exceeded");

      _safeMint(destination, _mintAmount);
  }

/// @notice returns metadata link of tokenid
  function tokenURI(uint256 tokenId)
    public
    view
    virtual
    override
    returns (string memory)
  {
    require(
      _exists(tokenId),
      "ERC721AMetadata: URI query for nonexistent token"
    );
    
    if(revealed == false) {
        return notRevealedUri;
    }

    string memory currentBaseURI = _baseURI();
    return bytes(currentBaseURI).length > 0
        ? string(abi.encodePacked(currentBaseURI, _toString(tokenId), ".json"))
        : "";
  }

     /// @notice return the number minted by an address
    function numberMinted(address owner) public view returns (uint256) {
    return _numberMinted(owner);
  }

    /// @notice return the tokens owned by an address
      function tokensOfOwner(address owner) public view returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }

  //only owner
  function reveal(bool _state) public onlyOwner {
      revealed = _state;
  }

    /// @dev change the merkle root for the whitelist phase
  function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
        merkleRoot = _merkleRoot;
    }

  /// @dev change the public max per wallet
  function setMaxPerWallet(uint256 _limit) public onlyOwner {
    MaxperWallet = _limit;
  }

  /// @dev change the whitelist max per wallet
    function setWlMaxPerWallet(uint256 _limit) public onlyOwner {
    MaxperWalletWl = _limit;
  }

   /// @dev change the public price(amount need to be in wei)
  function setCost(uint256 _newCost) public onlyOwner {
    cost = _newCost;
  }


  /// @dev cut the supply if we dont sold out
    function setMaxsupply(uint256 _newsupply) public onlyOwner {
    maxSupply = _newsupply;
  }

 /// @dev set your baseuri
  function setBaseURI(string memory _newBaseURI) public onlyOwner {
    baseURI = _newBaseURI;
  }

   /// @dev set hidden uri
  function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
    notRevealedUri = _notRevealedURI;
  }

 /// @dev to pause and unpause your contract(use booleans true or false)
  function pause(bool _state) public onlyOwner {
    paused = _state;
  }

     /// @dev activate whitelist sale(use booleans true or false)
    function togglepreSale(bool _state) external onlyOwner {
        preSale = _state;
    }
  
  /// @dev withdraw funds from contract
  function withdraw() public payable onlyOwner nonReentrant {
      uint256 balance = address(this).balance;
      payable(0x51C14c89DB72fCf4350c48d8eB3e85C0578Af924).transfer(balance);
  }

      /// Opensea Royalties

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable override onlyAllowedOperator(from) {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public payable override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId, data);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":"MaxperWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MaxperWalletWl","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"destination","type":"address"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"bool","name":"_state","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"preSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokens","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"presalemint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"payable","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":"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":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newsupply","type":"uint256"}],"name":"setMaxsupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setWlMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"togglepreSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","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":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

6080604052661b5b1bf4c54000600c556103e7600d556003600e819055600f556010805462ffffff1916620100001790553480156200003d57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600d81526020016c57686f2069732042616e6b737960981b8152506040518060400160405280600381526020016208aa8960eb1b8152508160029081620000a8919062000313565b506003620000b7828262000313565b5050600160005550620000ca336200021c565b60016009556daaeb6d7670e522a718067333cd4e3b15620002145780156200016257604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200014357600080fd5b505af115801562000158573d6000803e3d6000fd5b5050505062000214565b6001600160a01b03821615620001b35760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af29039060440162000128565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620001fa57600080fd5b505af11580156200020f573d6000803e3d6000fd5b505050505b5050620003df565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200029957607f821691505b602082108103620002ba57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200030e57600081815260208120601f850160051c81016020861015620002e95750805b601f850160051c820191505b818110156200030a57828155600101620002f5565b5050505b505050565b81516001600160401b038111156200032f576200032f6200026e565b620003478162000340845462000284565b84620002c0565b602080601f8311600181146200037f5760008415620003665750858301515b600019600386901b1c1916600185901b1785556200030a565b600085815260208120601f198616915b82811015620003b0578886015182559484019460019091019084016200038f565b5085821015620003cf5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61246480620003ef6000396000f3fe6080604052600436106102665760003560e01c80636c0360eb11610144578063bc63f02e116100b6578063dc33e6811161007a578063dc33e681146106aa578063e268e4d3146106ca578063e985e9c5146106ea578063f2c4ce1e1461070a578063f2fde38b1461072a578063fea0e0581461074a57600080fd5b8063bc63f02e1461061e578063bd7a19981461063e578063bde0608a14610654578063c87b56dd14610674578063d5abeb011461069457600080fd5b80638da5cb5b116101085780638da5cb5b14610585578063940cd05b146105a357806395d89b41146105c3578063a0712d68146105d8578063a22cb465146105eb578063b88d4fde1461060b57600080fd5b80636c0360eb146104ee57806370a0823114610503578063715018a6146105235780637cb64759146105385780638462151c1461055857600080fd5b806323b872dd116101dd57806344a0d68a116101a157806344a0d68a14610435578063518302271461045557806355f804b3146104745780635a7adf7f146104945780635c975abb146104b45780636352211e146104ce57600080fd5b806323b872dd146103cf5780632eb4a7ab146103e25780633ccfd60b146103f857806341f434341461040057806342842e0e1461042257600080fd5b8063081812fc1161022f578063081812fc1461031b578063081c8c4414610353578063095ea7b31461036857806313faede61461037b578063149835a01461039157806318160ddd146103b157600080fd5b806277ec051461026b57806301ffc9a71461029457806302329a29146102c4578063036e4cb5146102e657806306fdde03146102f9575b600080fd5b34801561027757600080fd5b50610281600f5481565b6040519081526020015b60405180910390f35b3480156102a057600080fd5b506102b46102af366004611dd3565b61076a565b604051901515815260200161028b565b3480156102d057600080fd5b506102e46102df366004611dfe565b6107bc565b005b6102e46102f4366004611e1b565b6107d7565b34801561030557600080fd5b5061030e610aee565b60405161028b9190611eea565b34801561032757600080fd5b5061033b610336366004611efd565b610b80565b6040516001600160a01b03909116815260200161028b565b34801561035f57600080fd5b5061030e610bc4565b6102e4610376366004611f32565b610c52565b34801561038757600080fd5b50610281600c5481565b34801561039d57600080fd5b506102e46103ac366004611efd565b610cf2565b3480156103bd57600080fd5b50610281600154600054036000190190565b6102e46103dd366004611f5c565b610cff565b3480156103ee57600080fd5b5061028160115481565b6102e4610d2a565b34801561040c57600080fd5b5061033b6daaeb6d7670e522a718067333cd4e81565b6102e4610430366004611f5c565b610d8b565b34801561044157600080fd5b506102e4610450366004611efd565b610db0565b34801561046157600080fd5b506010546102b490610100900460ff1681565b34801561048057600080fd5b506102e461048f366004612024565b610dbd565b3480156104a057600080fd5b506010546102b49062010000900460ff1681565b3480156104c057600080fd5b506010546102b49060ff1681565b3480156104da57600080fd5b5061033b6104e9366004611efd565b610dd5565b3480156104fa57600080fd5b5061030e610de0565b34801561050f57600080fd5b5061028161051e36600461206d565b610ded565b34801561052f57600080fd5b506102e4610e3c565b34801561054457600080fd5b506102e4610553366004611efd565b610e4e565b34801561056457600080fd5b5061057861057336600461206d565b610e5b565b60405161028b9190612088565b34801561059157600080fd5b506008546001600160a01b031661033b565b3480156105af57600080fd5b506102e46105be366004611dfe565b610f64565b3480156105cf57600080fd5b5061030e610f86565b6102e46105e6366004611efd565b610f95565b3480156105f757600080fd5b506102e46106063660046120c0565b6111d9565b6102e46106193660046120f7565b611245565b34801561062a57600080fd5b506102e4610639366004612173565b611272565b34801561064a57600080fd5b50610281600e5481565b34801561066057600080fd5b506102e461066f366004611efd565b6112fc565b34801561068057600080fd5b5061030e61068f366004611efd565b611309565b3480156106a057600080fd5b50610281600d5481565b3480156106b657600080fd5b506102816106c536600461206d565b61147b565b3480156106d657600080fd5b506102e46106e5366004611efd565b611486565b3480156106f657600080fd5b506102b461070536600461219f565b611493565b34801561071657600080fd5b506102e4610725366004612024565b6114c1565b34801561073657600080fd5b506102e461074536600461206d565b6114d5565b34801561075657600080fd5b506102e4610765366004611dfe565b61154b565b60006301ffc9a760e01b6001600160e01b03198316148061079b57506380ac58cd60e01b6001600160e01b03198316145b806107b65750635b5e139f60e01b6001600160e01b03198316145b92915050565b6107c461156f565b6010805460ff1916911515919091179055565b6107df6115c9565b60105460ff16156108375760405162461bcd60e51b815260206004820152601c60248201527f4554483a206f6f707320636f6e7472616374206973207061757365640000000060448201526064015b60405180910390fd5b60105462010000900460ff1661088f5760405162461bcd60e51b815260206004820181905260248201527f4554483a2050726573616c65204861736e742774207374617274656420796574604482015260640161082e565b610904828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506011546040516bffffffffffffffffffffffff193360601b166020820152909250603401905060405160208183030381529060405280519060200120611622565b6109505760405162461bcd60e51b815260206004820152601c60248201527f4554483a20596f7520617265206e6f742057686974656c697374656400000000604482015260640161082e565b600f548361095d33611638565b61096791906121df565b11156109b55760405162461bcd60e51b815260206004820181905260248201527f4554483a204d6178204e4654205065722057616c6c6574206578636565646564604482015260640161082e565b600f54831115610a075760405162461bcd60e51b815260206004820152601d60248201527f4554483a206d6178206d696e7420706572205478206578636565646564000000604482015260640161082e565b600d5483610a1c600154600054036000190190565b610a2691906121df565b1115610a7e5760405162461bcd60e51b815260206004820152602160248201527f4554483a2057686974656c697374204d6178537570706c7920657863656564656044820152601960fa1b606482015260840161082e565b82600c54610a8c91906121f2565b341015610ad55760405162461bcd60e51b81526020600482015260176024820152764554483a20696e73756666696369656e742066756e647360481b604482015260640161082e565b610adf3384611661565b610ae96001600955565b505050565b606060028054610afd90612209565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2990612209565b8015610b765780601f10610b4b57610100808354040283529160200191610b76565b820191906000526020600020905b815481529060010190602001808311610b5957829003601f168201915b5050505050905090565b6000610b8b8261167b565b610ba8576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600b8054610bd190612209565b80601f0160208091040260200160405190810160405280929190818152602001828054610bfd90612209565b8015610c4a5780601f10610c1f57610100808354040283529160200191610c4a565b820191906000526020600020905b815481529060010190602001808311610c2d57829003601f168201915b505050505081565b6000610c5d82610dd5565b9050336001600160a01b03821614610c9657610c798133611493565b610c96576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b610cfa61156f565b600d55565b826001600160a01b0381163314610d1957610d19336116b0565b610d24848484611769565b50505050565b610d3261156f565b610d3a6115c9565b60405147907351c14c89db72fcf4350c48d8eb3e85c0578af9249082156108fc029083906000818181858888f19350505050158015610d7d573d6000803e3d6000fd5b5050610d896001600955565b565b826001600160a01b0381163314610da557610da5336116b0565b610d24848484611902565b610db861156f565b600c55565b610dc561156f565b600a610dd18282612289565b5050565b60006107b68261191d565b600a8054610bd190612209565b60006001600160a01b038216610e16576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b610e4461156f565b610d89600061198c565b610e5661156f565b601155565b60606000806000610e6b85610ded565b905060008167ffffffffffffffff811115610e8857610e88611f98565b604051908082528060200260200182016040528015610eb1578160200160208202803683370190505b509050610ede60408051608081018252600080825260208201819052918101829052606081019190915290565b60015b838614610f5857610ef1816119de565b91508160400151610f505781516001600160a01b031615610f1157815194505b876001600160a01b0316856001600160a01b031603610f505780838780600101985081518110610f4357610f43612349565b6020026020010181815250505b600101610ee1565b50909695505050505050565b610f6c61156f565b601080549115156101000261ff0019909216919091179055565b606060038054610afd90612209565b610f9d6115c9565b60105460ff1615610ff05760405162461bcd60e51b815260206004820152601c60248201527f4554483a206f6f707320636f6e74726163742069732070617573656400000000604482015260640161082e565b60105462010000900460ff16156110495760405162461bcd60e51b815260206004820152601c60248201527f4554483a2053616c65204861736e277420737461727465642079657400000000604482015260640161082e565b600e548111156110a75760405162461bcd60e51b8152602060048201526024808201527f4554483a206d6178206d696e7420616d6f756e742070657220747820657863656044820152631959195960e21b606482015260840161082e565b600d54816110bc600154600054036000190190565b6110c691906121df565b11156111065760405162461bcd60e51b815260206004820152600f60248201526e1155120e8815d94814dbdb191bdd5d608a1b604482015260640161082e565b600e548161111333611638565b61111d91906121df565b111561116b5760405162461bcd60e51b815260206004820181905260248201527f4554483a204d6178204e4654205065722057616c6c6574206578636565646564604482015260640161082e565b80600c5461117991906121f2565b3410156111c25760405162461bcd60e51b81526020600482015260176024820152764554483a20696e73756666696369656e742066756e647360481b604482015260640161082e565b6111cc3382611661565b6111d66001600955565b50565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b836001600160a01b038116331461125f5761125f336116b0565b61126b85858585611a5d565b5050505050565b61127a61156f565b6112826115c9565b600d5482611297600154600054036000190190565b6112a191906121df565b11156112e85760405162461bcd60e51b81526020600482015260166024820152751b585e08139195081b1a5b5a5d08195e18d95959195960521b604482015260640161082e565b6112f28183611661565b610dd16001600955565b61130461156f565b600f55565b60606113148261167b565b6113795760405162461bcd60e51b815260206004820152603060248201527f455243373231414d657461646174613a2055524920717565727920666f72206e60448201526f37b732bc34b9ba32b73a103a37b5b2b760811b606482015260840161082e565b601054610100900460ff16151560000361141f57600b805461139a90612209565b80601f01602080910402602001604051908101604052809291908181526020018280546113c690612209565b80156114135780601f106113e857610100808354040283529160200191611413565b820191906000526020600020905b8154815290600101906020018083116113f657829003601f168201915b50505050509050919050565b6000611429611aa1565b905060008151116114495760405180602001604052806000815250611474565b8061145384611ab0565b60405160200161146492919061235f565b6040516020818303038152906040525b9392505050565b60006107b682611638565b61148e61156f565b600e55565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6114c961156f565b600b610dd18282612289565b6114dd61156f565b6001600160a01b0381166115425760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161082e565b6111d68161198c565b61155361156f565b60108054911515620100000262ff000019909216919091179055565b6008546001600160a01b03163314610d895760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161082e565b60026009540361161b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161082e565b6002600955565b60008261162f8584611af4565b14949350505050565b6001600160a01b03166000908152600560205260409081902054901c67ffffffffffffffff1690565b610dd1828260405180602001604052806000815250611b41565b60008160011115801561168f575060005482105b80156107b6575050600090815260046020526040902054600160e01b161590565b6daaeb6d7670e522a718067333cd4e3b156111d657604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa15801561171d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611741919061239e565b6111d657604051633b79c77360e21b81526001600160a01b038216600482015260240161082e565b60006117748261191d565b9050836001600160a01b0316816001600160a01b0316146117a75760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b038816909114176117f4576117d78633611493565b6117f457604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661181b57604051633a954ecd60e21b815260040160405180910390fd5b801561182657600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b841690036118b8576001840160008181526004602052604081205490036118b65760005481146118b65760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b610ae983838360405180602001604052806000815250611245565b60008180600111611973576000548110156119735760008181526004602052604081205490600160e01b82169003611971575b80600003611474575060001901600081815260046020526040902054611950565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040805160808101825260008082526020820181905291810182905260608101919091526000828152600460205260409020546107b690604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b611a68848484610cff565b6001600160a01b0383163b15610d2457611a8484848484611ba7565b610d24576040516368d2bf6b60e11b815260040160405180910390fd5b6060600a8054610afd90612209565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a900480611aca5750819003601f19909101908152919050565b600081815b8451811015611b3957611b2582868381518110611b1857611b18612349565b6020026020010151611c93565b915080611b31816123bb565b915050611af9565b509392505050565b611b4b8383611cbf565b6001600160a01b0383163b15610ae9576000548281035b611b756000868380600101945086611ba7565b611b92576040516368d2bf6b60e11b815260040160405180910390fd5b818110611b6257816000541461126b57600080fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611bdc9033908990889088906004016123d4565b6020604051808303816000875af1925050508015611c17575060408051601f3d908101601f19168201909252611c1491810190612411565b60015b611c75573d808015611c45576040519150601f19603f3d011682016040523d82523d6000602084013e611c4a565b606091505b508051600003611c6d576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6000818310611caf576000828152602084905260409020611474565b5060009182526020526040902090565b6000805490829003611ce45760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114611d9357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101611d5b565b5081600003611db457604051622e076360e81b815260040160405180910390fd5b60005550505050565b6001600160e01b0319811681146111d657600080fd5b600060208284031215611de557600080fd5b813561147481611dbd565b80151581146111d657600080fd5b600060208284031215611e1057600080fd5b813561147481611df0565b600080600060408486031215611e3057600080fd5b83359250602084013567ffffffffffffffff80821115611e4f57600080fd5b818601915086601f830112611e6357600080fd5b813581811115611e7257600080fd5b8760208260051b8501011115611e8757600080fd5b6020830194508093505050509250925092565b60005b83811015611eb5578181015183820152602001611e9d565b50506000910152565b60008151808452611ed6816020860160208601611e9a565b601f01601f19169290920160200192915050565b6020815260006114746020830184611ebe565b600060208284031215611f0f57600080fd5b5035919050565b80356001600160a01b0381168114611f2d57600080fd5b919050565b60008060408385031215611f4557600080fd5b611f4e83611f16565b946020939093013593505050565b600080600060608486031215611f7157600080fd5b611f7a84611f16565b9250611f8860208501611f16565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115611fc957611fc9611f98565b604051601f8501601f19908116603f01168101908282118183101715611ff157611ff1611f98565b8160405280935085815286868601111561200a57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561203657600080fd5b813567ffffffffffffffff81111561204d57600080fd5b8201601f8101841361205e57600080fd5b611c8b84823560208401611fae565b60006020828403121561207f57600080fd5b61147482611f16565b6020808252825182820181905260009190848201906040850190845b81811015610f58578351835292840192918401916001016120a4565b600080604083850312156120d357600080fd5b6120dc83611f16565b915060208301356120ec81611df0565b809150509250929050565b6000806000806080858703121561210d57600080fd5b61211685611f16565b935061212460208601611f16565b925060408501359150606085013567ffffffffffffffff81111561214757600080fd5b8501601f8101871361215857600080fd5b61216787823560208401611fae565b91505092959194509250565b6000806040838503121561218657600080fd5b8235915061219660208401611f16565b90509250929050565b600080604083850312156121b257600080fd5b6121bb83611f16565b915061219660208401611f16565b634e487b7160e01b600052601160045260246000fd5b808201808211156107b6576107b66121c9565b80820281158282048414176107b6576107b66121c9565b600181811c9082168061221d57607f821691505b60208210810361223d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610ae957600081815260208120601f850160051c8101602086101561226a5750805b601f850160051c820191505b818110156118fa57828155600101612276565b815167ffffffffffffffff8111156122a3576122a3611f98565b6122b7816122b18454612209565b84612243565b602080601f8311600181146122ec57600084156122d45750858301515b600019600386901b1c1916600185901b1785556118fa565b600085815260208120601f198616915b8281101561231b578886015182559484019460019091019084016122fc565b50858210156123395787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b60008351612371818460208801611e9a565b835190830190612385818360208801611e9a565b64173539b7b760d91b9101908152600501949350505050565b6000602082840312156123b057600080fd5b815161147481611df0565b6000600182016123cd576123cd6121c9565b5060010190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061240790830184611ebe565b9695505050505050565b60006020828403121561242357600080fd5b815161147481611dbd56fea264697066735822122054ebdb4263fe6844f46c4e2ff576d54be70f3d39c4daf5f52ac9bab8ec8436ca64736f6c63430008110033

Deployed Bytecode

0x6080604052600436106102665760003560e01c80636c0360eb11610144578063bc63f02e116100b6578063dc33e6811161007a578063dc33e681146106aa578063e268e4d3146106ca578063e985e9c5146106ea578063f2c4ce1e1461070a578063f2fde38b1461072a578063fea0e0581461074a57600080fd5b8063bc63f02e1461061e578063bd7a19981461063e578063bde0608a14610654578063c87b56dd14610674578063d5abeb011461069457600080fd5b80638da5cb5b116101085780638da5cb5b14610585578063940cd05b146105a357806395d89b41146105c3578063a0712d68146105d8578063a22cb465146105eb578063b88d4fde1461060b57600080fd5b80636c0360eb146104ee57806370a0823114610503578063715018a6146105235780637cb64759146105385780638462151c1461055857600080fd5b806323b872dd116101dd57806344a0d68a116101a157806344a0d68a14610435578063518302271461045557806355f804b3146104745780635a7adf7f146104945780635c975abb146104b45780636352211e146104ce57600080fd5b806323b872dd146103cf5780632eb4a7ab146103e25780633ccfd60b146103f857806341f434341461040057806342842e0e1461042257600080fd5b8063081812fc1161022f578063081812fc1461031b578063081c8c4414610353578063095ea7b31461036857806313faede61461037b578063149835a01461039157806318160ddd146103b157600080fd5b806277ec051461026b57806301ffc9a71461029457806302329a29146102c4578063036e4cb5146102e657806306fdde03146102f9575b600080fd5b34801561027757600080fd5b50610281600f5481565b6040519081526020015b60405180910390f35b3480156102a057600080fd5b506102b46102af366004611dd3565b61076a565b604051901515815260200161028b565b3480156102d057600080fd5b506102e46102df366004611dfe565b6107bc565b005b6102e46102f4366004611e1b565b6107d7565b34801561030557600080fd5b5061030e610aee565b60405161028b9190611eea565b34801561032757600080fd5b5061033b610336366004611efd565b610b80565b6040516001600160a01b03909116815260200161028b565b34801561035f57600080fd5b5061030e610bc4565b6102e4610376366004611f32565b610c52565b34801561038757600080fd5b50610281600c5481565b34801561039d57600080fd5b506102e46103ac366004611efd565b610cf2565b3480156103bd57600080fd5b50610281600154600054036000190190565b6102e46103dd366004611f5c565b610cff565b3480156103ee57600080fd5b5061028160115481565b6102e4610d2a565b34801561040c57600080fd5b5061033b6daaeb6d7670e522a718067333cd4e81565b6102e4610430366004611f5c565b610d8b565b34801561044157600080fd5b506102e4610450366004611efd565b610db0565b34801561046157600080fd5b506010546102b490610100900460ff1681565b34801561048057600080fd5b506102e461048f366004612024565b610dbd565b3480156104a057600080fd5b506010546102b49062010000900460ff1681565b3480156104c057600080fd5b506010546102b49060ff1681565b3480156104da57600080fd5b5061033b6104e9366004611efd565b610dd5565b3480156104fa57600080fd5b5061030e610de0565b34801561050f57600080fd5b5061028161051e36600461206d565b610ded565b34801561052f57600080fd5b506102e4610e3c565b34801561054457600080fd5b506102e4610553366004611efd565b610e4e565b34801561056457600080fd5b5061057861057336600461206d565b610e5b565b60405161028b9190612088565b34801561059157600080fd5b506008546001600160a01b031661033b565b3480156105af57600080fd5b506102e46105be366004611dfe565b610f64565b3480156105cf57600080fd5b5061030e610f86565b6102e46105e6366004611efd565b610f95565b3480156105f757600080fd5b506102e46106063660046120c0565b6111d9565b6102e46106193660046120f7565b611245565b34801561062a57600080fd5b506102e4610639366004612173565b611272565b34801561064a57600080fd5b50610281600e5481565b34801561066057600080fd5b506102e461066f366004611efd565b6112fc565b34801561068057600080fd5b5061030e61068f366004611efd565b611309565b3480156106a057600080fd5b50610281600d5481565b3480156106b657600080fd5b506102816106c536600461206d565b61147b565b3480156106d657600080fd5b506102e46106e5366004611efd565b611486565b3480156106f657600080fd5b506102b461070536600461219f565b611493565b34801561071657600080fd5b506102e4610725366004612024565b6114c1565b34801561073657600080fd5b506102e461074536600461206d565b6114d5565b34801561075657600080fd5b506102e4610765366004611dfe565b61154b565b60006301ffc9a760e01b6001600160e01b03198316148061079b57506380ac58cd60e01b6001600160e01b03198316145b806107b65750635b5e139f60e01b6001600160e01b03198316145b92915050565b6107c461156f565b6010805460ff1916911515919091179055565b6107df6115c9565b60105460ff16156108375760405162461bcd60e51b815260206004820152601c60248201527f4554483a206f6f707320636f6e7472616374206973207061757365640000000060448201526064015b60405180910390fd5b60105462010000900460ff1661088f5760405162461bcd60e51b815260206004820181905260248201527f4554483a2050726573616c65204861736e742774207374617274656420796574604482015260640161082e565b610904828280806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506011546040516bffffffffffffffffffffffff193360601b166020820152909250603401905060405160208183030381529060405280519060200120611622565b6109505760405162461bcd60e51b815260206004820152601c60248201527f4554483a20596f7520617265206e6f742057686974656c697374656400000000604482015260640161082e565b600f548361095d33611638565b61096791906121df565b11156109b55760405162461bcd60e51b815260206004820181905260248201527f4554483a204d6178204e4654205065722057616c6c6574206578636565646564604482015260640161082e565b600f54831115610a075760405162461bcd60e51b815260206004820152601d60248201527f4554483a206d6178206d696e7420706572205478206578636565646564000000604482015260640161082e565b600d5483610a1c600154600054036000190190565b610a2691906121df565b1115610a7e5760405162461bcd60e51b815260206004820152602160248201527f4554483a2057686974656c697374204d6178537570706c7920657863656564656044820152601960fa1b606482015260840161082e565b82600c54610a8c91906121f2565b341015610ad55760405162461bcd60e51b81526020600482015260176024820152764554483a20696e73756666696369656e742066756e647360481b604482015260640161082e565b610adf3384611661565b610ae96001600955565b505050565b606060028054610afd90612209565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2990612209565b8015610b765780601f10610b4b57610100808354040283529160200191610b76565b820191906000526020600020905b815481529060010190602001808311610b5957829003601f168201915b5050505050905090565b6000610b8b8261167b565b610ba8576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600b8054610bd190612209565b80601f0160208091040260200160405190810160405280929190818152602001828054610bfd90612209565b8015610c4a5780601f10610c1f57610100808354040283529160200191610c4a565b820191906000526020600020905b815481529060010190602001808311610c2d57829003601f168201915b505050505081565b6000610c5d82610dd5565b9050336001600160a01b03821614610c9657610c798133611493565b610c96576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b610cfa61156f565b600d55565b826001600160a01b0381163314610d1957610d19336116b0565b610d24848484611769565b50505050565b610d3261156f565b610d3a6115c9565b60405147907351c14c89db72fcf4350c48d8eb3e85c0578af9249082156108fc029083906000818181858888f19350505050158015610d7d573d6000803e3d6000fd5b5050610d896001600955565b565b826001600160a01b0381163314610da557610da5336116b0565b610d24848484611902565b610db861156f565b600c55565b610dc561156f565b600a610dd18282612289565b5050565b60006107b68261191d565b600a8054610bd190612209565b60006001600160a01b038216610e16576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b610e4461156f565b610d89600061198c565b610e5661156f565b601155565b60606000806000610e6b85610ded565b905060008167ffffffffffffffff811115610e8857610e88611f98565b604051908082528060200260200182016040528015610eb1578160200160208202803683370190505b509050610ede60408051608081018252600080825260208201819052918101829052606081019190915290565b60015b838614610f5857610ef1816119de565b91508160400151610f505781516001600160a01b031615610f1157815194505b876001600160a01b0316856001600160a01b031603610f505780838780600101985081518110610f4357610f43612349565b6020026020010181815250505b600101610ee1565b50909695505050505050565b610f6c61156f565b601080549115156101000261ff0019909216919091179055565b606060038054610afd90612209565b610f9d6115c9565b60105460ff1615610ff05760405162461bcd60e51b815260206004820152601c60248201527f4554483a206f6f707320636f6e74726163742069732070617573656400000000604482015260640161082e565b60105462010000900460ff16156110495760405162461bcd60e51b815260206004820152601c60248201527f4554483a2053616c65204861736e277420737461727465642079657400000000604482015260640161082e565b600e548111156110a75760405162461bcd60e51b8152602060048201526024808201527f4554483a206d6178206d696e7420616d6f756e742070657220747820657863656044820152631959195960e21b606482015260840161082e565b600d54816110bc600154600054036000190190565b6110c691906121df565b11156111065760405162461bcd60e51b815260206004820152600f60248201526e1155120e8815d94814dbdb191bdd5d608a1b604482015260640161082e565b600e548161111333611638565b61111d91906121df565b111561116b5760405162461bcd60e51b815260206004820181905260248201527f4554483a204d6178204e4654205065722057616c6c6574206578636565646564604482015260640161082e565b80600c5461117991906121f2565b3410156111c25760405162461bcd60e51b81526020600482015260176024820152764554483a20696e73756666696369656e742066756e647360481b604482015260640161082e565b6111cc3382611661565b6111d66001600955565b50565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b836001600160a01b038116331461125f5761125f336116b0565b61126b85858585611a5d565b5050505050565b61127a61156f565b6112826115c9565b600d5482611297600154600054036000190190565b6112a191906121df565b11156112e85760405162461bcd60e51b81526020600482015260166024820152751b585e08139195081b1a5b5a5d08195e18d95959195960521b604482015260640161082e565b6112f28183611661565b610dd16001600955565b61130461156f565b600f55565b60606113148261167b565b6113795760405162461bcd60e51b815260206004820152603060248201527f455243373231414d657461646174613a2055524920717565727920666f72206e60448201526f37b732bc34b9ba32b73a103a37b5b2b760811b606482015260840161082e565b601054610100900460ff16151560000361141f57600b805461139a90612209565b80601f01602080910402602001604051908101604052809291908181526020018280546113c690612209565b80156114135780601f106113e857610100808354040283529160200191611413565b820191906000526020600020905b8154815290600101906020018083116113f657829003601f168201915b50505050509050919050565b6000611429611aa1565b905060008151116114495760405180602001604052806000815250611474565b8061145384611ab0565b60405160200161146492919061235f565b6040516020818303038152906040525b9392505050565b60006107b682611638565b61148e61156f565b600e55565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6114c961156f565b600b610dd18282612289565b6114dd61156f565b6001600160a01b0381166115425760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161082e565b6111d68161198c565b61155361156f565b60108054911515620100000262ff000019909216919091179055565b6008546001600160a01b03163314610d895760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161082e565b60026009540361161b5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161082e565b6002600955565b60008261162f8584611af4565b14949350505050565b6001600160a01b03166000908152600560205260409081902054901c67ffffffffffffffff1690565b610dd1828260405180602001604052806000815250611b41565b60008160011115801561168f575060005482105b80156107b6575050600090815260046020526040902054600160e01b161590565b6daaeb6d7670e522a718067333cd4e3b156111d657604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c617113490604401602060405180830381865afa15801561171d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611741919061239e565b6111d657604051633b79c77360e21b81526001600160a01b038216600482015260240161082e565b60006117748261191d565b9050836001600160a01b0316816001600160a01b0316146117a75760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b038816909114176117f4576117d78633611493565b6117f457604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661181b57604051633a954ecd60e21b815260040160405180910390fd5b801561182657600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040812091909155600160e11b841690036118b8576001840160008181526004602052604081205490036118b65760005481146118b65760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b610ae983838360405180602001604052806000815250611245565b60008180600111611973576000548110156119735760008181526004602052604081205490600160e01b82169003611971575b80600003611474575060001901600081815260046020526040902054611950565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040805160808101825260008082526020820181905291810182905260608101919091526000828152600460205260409020546107b690604080516080810182526001600160a01b038316815260a083901c67ffffffffffffffff166020820152600160e01b831615159181019190915260e89190911c606082015290565b611a68848484610cff565b6001600160a01b0383163b15610d2457611a8484848484611ba7565b610d24576040516368d2bf6b60e11b815260040160405180910390fd5b6060600a8054610afd90612209565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a900480611aca5750819003601f19909101908152919050565b600081815b8451811015611b3957611b2582868381518110611b1857611b18612349565b6020026020010151611c93565b915080611b31816123bb565b915050611af9565b509392505050565b611b4b8383611cbf565b6001600160a01b0383163b15610ae9576000548281035b611b756000868380600101945086611ba7565b611b92576040516368d2bf6b60e11b815260040160405180910390fd5b818110611b6257816000541461126b57600080fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611bdc9033908990889088906004016123d4565b6020604051808303816000875af1925050508015611c17575060408051601f3d908101601f19168201909252611c1491810190612411565b60015b611c75573d808015611c45576040519150601f19603f3d011682016040523d82523d6000602084013e611c4a565b606091505b508051600003611c6d576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6000818310611caf576000828152602084905260409020611474565b5060009182526020526040902090565b6000805490829003611ce45760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526005602090815260408083208054680100000000000000018802019055848352600490915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114611d9357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101611d5b565b5081600003611db457604051622e076360e81b815260040160405180910390fd5b60005550505050565b6001600160e01b0319811681146111d657600080fd5b600060208284031215611de557600080fd5b813561147481611dbd565b80151581146111d657600080fd5b600060208284031215611e1057600080fd5b813561147481611df0565b600080600060408486031215611e3057600080fd5b83359250602084013567ffffffffffffffff80821115611e4f57600080fd5b818601915086601f830112611e6357600080fd5b813581811115611e7257600080fd5b8760208260051b8501011115611e8757600080fd5b6020830194508093505050509250925092565b60005b83811015611eb5578181015183820152602001611e9d565b50506000910152565b60008151808452611ed6816020860160208601611e9a565b601f01601f19169290920160200192915050565b6020815260006114746020830184611ebe565b600060208284031215611f0f57600080fd5b5035919050565b80356001600160a01b0381168114611f2d57600080fd5b919050565b60008060408385031215611f4557600080fd5b611f4e83611f16565b946020939093013593505050565b600080600060608486031215611f7157600080fd5b611f7a84611f16565b9250611f8860208501611f16565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115611fc957611fc9611f98565b604051601f8501601f19908116603f01168101908282118183101715611ff157611ff1611f98565b8160405280935085815286868601111561200a57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561203657600080fd5b813567ffffffffffffffff81111561204d57600080fd5b8201601f8101841361205e57600080fd5b611c8b84823560208401611fae565b60006020828403121561207f57600080fd5b61147482611f16565b6020808252825182820181905260009190848201906040850190845b81811015610f58578351835292840192918401916001016120a4565b600080604083850312156120d357600080fd5b6120dc83611f16565b915060208301356120ec81611df0565b809150509250929050565b6000806000806080858703121561210d57600080fd5b61211685611f16565b935061212460208601611f16565b925060408501359150606085013567ffffffffffffffff81111561214757600080fd5b8501601f8101871361215857600080fd5b61216787823560208401611fae565b91505092959194509250565b6000806040838503121561218657600080fd5b8235915061219660208401611f16565b90509250929050565b600080604083850312156121b257600080fd5b6121bb83611f16565b915061219660208401611f16565b634e487b7160e01b600052601160045260246000fd5b808201808211156107b6576107b66121c9565b80820281158282048414176107b6576107b66121c9565b600181811c9082168061221d57607f821691505b60208210810361223d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610ae957600081815260208120601f850160051c8101602086101561226a5750805b601f850160051c820191505b818110156118fa57828155600101612276565b815167ffffffffffffffff8111156122a3576122a3611f98565b6122b7816122b18454612209565b84612243565b602080601f8311600181146122ec57600084156122d45750858301515b600019600386901b1c1916600185901b1785556118fa565b600085815260208120601f198616915b8281101561231b578886015182559484019460019091019084016122fc565b50858210156123395787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b60008351612371818460208801611e9a565b835190830190612385818360208801611e9a565b64173539b7b760d91b9101908152600501949350505050565b6000602082840312156123b057600080fd5b815161147481611df0565b6000600182016123cd576123cd6121c9565b5060010190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061240790830184611ebe565b9695505050505050565b60006020828403121561242357600080fd5b815161147481611dbd56fea264697066735822122054ebdb4263fe6844f46c4e2ff576d54be70f3d39c4daf5f52ac9bab8ec8436ca64736f6c63430008110033

Deployed Bytecode Sourcemap

78776:6474:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79037:33;;;;;;;;;;;;;;;;;;;160:25:1;;;148:2;133:18;79037:33:0;;;;;;;;18446:639;;;;;;;;;;-1:-1:-1;18446:639:0;;;;;:::i;:::-;;:::i;:::-;;;747:14:1;;740:22;722:41;;710:2;695:18;18446:639:0;582:187:1;84050:73:0;;;;;;;;;;-1:-1:-1;84050:73:0;;;;;:::i;:::-;;:::i;:::-;;80129:747;;;;;;:::i;:::-;;:::i;19348:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;25839:218::-;;;;;;;;;;-1:-1:-1;25839:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2936:32:1;;;2918:51;;2906:2;2891:18;25839:218:0;2772:203:1;78894:28:0;;;;;;;;;;;;;:::i;25272:408::-;;;;;;:::i;:::-;;:::i;78927:34::-;;;;;;;;;;;;;;;;83590:94;;;;;;;;;;-1:-1:-1;83590:94:0;;;;;:::i;:::-;;:::i;15099:323::-;;;;;;;;;;;;79473:1;15373:12;15160:7;15357:13;:28;-1:-1:-1;;15357:46:0;;15099:323;84566:205;;;;;;:::i;:::-;;:::i;79170:25::-;;;;;;;;;;;;;;;;84337:190;;;:::i;75349:143::-;;;;;;;;;;;;74138:42;75349:143;;84779:213;;;;;;:::i;:::-;;:::i;83453:80::-;;;;;;;;;;-1:-1:-1;83453:80:0;;;;;:::i;:::-;;:::i;79106:28::-;;;;;;;;;;-1:-1:-1;79106:28:0;;;;;;;;;;;83718:98;;;;;;;;;;-1:-1:-1;83718:98:0;;;;;:::i;:::-;;:::i;79139:26::-;;;;;;;;;;-1:-1:-1;79139:26:0;;;;;;;;;;;79075;;;;;;;;;;-1:-1:-1;79075:26:0;;;;;;;;20741:152;;;;;;;;;;-1:-1:-1;20741:152:0;;;;;:::i;:::-;;:::i;78868:21::-;;;;;;;;;;;;;:::i;16283:233::-;;;;;;;;;;-1:-1:-1;16283:233:0;;;;;:::i;:::-;;:::i;54251:103::-;;;;;;;;;;;;;:::i;82983:106::-;;;;;;;;;;-1:-1:-1;82983:106:0;;;;;:::i;:::-;;:::i;81935:881::-;;;;;;;;;;-1:-1:-1;81935:881:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;53603:87::-;;;;;;;;;;-1:-1:-1;53676:6:0;;-1:-1:-1;;;;;53676:6:0;53603:87;;82838:78;;;;;;;;;;-1:-1:-1;82838:78:0;;;;;:::i;:::-;;:::i;19524:104::-;;;;;;;;;;;;;:::i;79526:558::-;;;;;;:::i;:::-;;:::i;26397:234::-;;;;;;;;;;-1:-1:-1;26397:234:0;;;;;:::i;:::-;;:::i;85000:247::-;;;;;;:::i;:::-;;:::i;80931:223::-;;;;;;;;;;-1:-1:-1;80931:223:0;;;;;:::i;:::-;;:::i;79001:31::-;;;;;;;;;;;;;;;;83288:96;;;;;;;;;;-1:-1:-1;83288:96:0;;;;;:::i;:::-;;:::i;81206:492::-;;;;;;;;;;-1:-1:-1;81206:492:0;;;;;:::i;:::-;;:::i;78966:30::-;;;;;;;;;;;;;;;;81763:107;;;;;;;;;;-1:-1:-1;81763:107:0;;;;;:::i;:::-;;:::i;83140:92::-;;;;;;;;;;-1:-1:-1;83140:92:0;;;;;:::i;:::-;;:::i;26788:164::-;;;;;;;;;;-1:-1:-1;26788:164:0;;;;;:::i;:::-;;:::i;83850:120::-;;;;;;;;;;-1:-1:-1;83850:120:0;;;;;:::i;:::-;;:::i;54509:201::-;;;;;;;;;;-1:-1:-1;54509:201:0;;;;;:::i;:::-;;:::i;84198:90::-;;;;;;;;;;-1:-1:-1;84198:90:0;;;;;:::i;:::-;;:::i;18446:639::-;18531:4;-1:-1:-1;;;;;;;;;18855:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;18932:25:0;;;18855:102;:179;;;-1:-1:-1;;;;;;;;;;19009:25:0;;;18855:179;18835:199;18446:639;-1:-1:-1;;18446:639:0:o;84050:73::-;53489:13;:11;:13::i;:::-;84102:6:::1;:15:::0;;-1:-1:-1;;84102:15:0::1;::::0;::::1;;::::0;;;::::1;::::0;;84050:73::o;80129:747::-;57413:21;:19;:21::i;:::-;80242:6:::1;::::0;::::1;;80241:7;80233:48;;;::::0;-1:-1:-1;;;80233:48:0;;8128:2:1;80233:48:0::1;::::0;::::1;8110:21:1::0;8167:2;8147:18;;;8140:30;8206;8186:18;;;8179:58;8254:18;;80233:48:0::1;;;;;;;;;80296:7;::::0;;;::::1;;;80288:52;;;::::0;-1:-1:-1;;;80288:52:0;;8485:2:1;80288:52:0::1;::::0;::::1;8467:21:1::0;;;8504:18;;;8497:30;8563:34;8543:18;;;8536:62;8615:18;;80288:52:0::1;8283:356:1::0;80288:52:0::1;80355:84;80374:11;;80355:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;80387:10:0::1;::::0;80409:28:::1;::::0;-1:-1:-1;;80426:10:0::1;8793:2:1::0;8789:15;8785:53;80409:28:0::1;::::0;::::1;8773:66:1::0;80387:10:0;;-1:-1:-1;8855:12:1;;;-1:-1:-1;80409:28:0::1;;;;;;;;;;;;80399:39;;;;;;80355:18;:84::i;:::-;80347:125;;;::::0;-1:-1:-1;;;80347:125:0;;9080:2:1;80347:125:0::1;::::0;::::1;9062:21:1::0;9119:2;9099:18;;;9092:30;9158;9138:18;;;9131:58;9206:18;;80347:125:0::1;8878:352:1::0;80347:125:0::1;80534:14;::::0;80524:6;80487:34:::1;49605:10:::0;80487:13:::1;:34::i;:::-;:43;;;;:::i;:::-;:61;;80479:106;;;::::0;-1:-1:-1;;;80479:106:0;;9699:2:1;80479:106:0::1;::::0;::::1;9681:21:1::0;;;9718:18;;;9711:30;9777:34;9757:18;;;9750:62;9829:18;;80479:106:0::1;9497:356:1::0;80479:106:0::1;80610:14;;80600:6;:24;;80592:66;;;::::0;-1:-1:-1;;;80592:66:0;;10060:2:1;80592:66:0::1;::::0;::::1;10042:21:1::0;10099:2;10079:18;;;10072:30;10138:31;10118:18;;;10111:59;10187:18;;80592:66:0::1;9858:353:1::0;80592:66:0::1;80699:9;;80689:6;80673:13;79473:1:::0;15373:12;15160:7;15357:13;:28;-1:-1:-1;;15357:46:0;;15099:323;80673:13:::1;:22;;;;:::i;:::-;:35;;80665:81;;;::::0;-1:-1:-1;;;80665:81:0;;10418:2:1;80665:81:0::1;::::0;::::1;10400:21:1::0;10457:2;10437:18;;;10430:30;10496:34;10476:18;;;10469:62;-1:-1:-1;;;10547:18:1;;;10540:31;10588:19;;80665:81:0::1;10216:397:1::0;80665:81:0::1;80781:6;80774:4;;:13;;;;:::i;:::-;80761:9;:26;;80753:62;;;::::0;-1:-1:-1;;;80753:62:0;;10993:2:1;80753:62:0::1;::::0;::::1;10975:21:1::0;11032:2;11012:18;;;11005:30;-1:-1:-1;;;11051:18:1;;;11044:53;11114:18;;80753:62:0::1;10791:347:1::0;80753:62:0::1;80826:38;49605:10:::0;80857:6:::1;80826:9;:38::i;:::-;57457:20:::0;56851:1;57977:7;:22;57794:213;57457:20;80129:747;;;:::o;19348:100::-;19402:13;19435:5;19428:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19348:100;:::o;25839:218::-;25915:7;25940:16;25948:7;25940;:16::i;:::-;25935:64;;25965:34;;-1:-1:-1;;;25965:34:0;;;;;;;;;;;25935:64;-1:-1:-1;26019:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;26019:30:0;;25839:218::o;78894:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;25272:408::-;25361:13;25377:16;25385:7;25377;:16::i;:::-;25361:32;-1:-1:-1;49605:10:0;-1:-1:-1;;;;;25410:28:0;;;25406:175;;25458:44;25475:5;49605:10;26788:164;:::i;25458:44::-;25453:128;;25530:35;;-1:-1:-1;;;25530:35:0;;;;;;;;;;;25453:128;25593:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;25593:35:0;-1:-1:-1;;;;;25593:35:0;;;;;;;;;25644:28;;25593:24;;25644:28;;;;;;;25350:330;25272:408;;:::o;83590:94::-;53489:13;:11;:13::i;:::-;83656:9:::1;:22:::0;83590:94::o;84566:205::-;84709:4;-1:-1:-1;;;;;76857:18:0;;76865:10;76857:18;76853:83;;76892:32;76913:10;76892:20;:32::i;:::-;84726:37:::1;84745:4;84751:2;84755:7;84726:18;:37::i;:::-;84566:205:::0;;;;:::o;84337:190::-;53489:13;:11;:13::i;:::-;57413:21:::1;:19;:21::i;:::-;84452:69:::2;::::0;84422:21:::2;::::0;84460:42:::2;::::0;84452:69;::::2;;;::::0;84422:21;;84404:15:::2;84452:69:::0;84404:15;84452:69;84422:21;84460:42;84452:69;::::2;;;;;;;;;;;;;::::0;::::2;;;;;;84395:132;57457:20:::1;56851:1:::0;57977:7;:22;57794:213;57457:20:::1;84337:190::o:0;84779:213::-;84926:4;-1:-1:-1;;;;;76857:18:0;;76865:10;76857:18;76853:83;;76892:32;76913:10;76892:20;:32::i;:::-;84943:41:::1;84966:4;84972:2;84976:7;84943:22;:41::i;83453:80::-:0;53489:13;:11;:13::i;:::-;83512:4:::1;:15:::0;83453:80::o;83718:98::-;53489:13;:11;:13::i;:::-;83789:7:::1;:21;83799:11:::0;83789:7;:21:::1;:::i;:::-;;83718:98:::0;:::o;20741:152::-;20813:7;20856:27;20875:7;20856:18;:27::i;78868:21::-;;;;;;;:::i;16283:233::-;16355:7;-1:-1:-1;;;;;16379:19:0;;16375:60;;16407:28;;-1:-1:-1;;;16407:28:0;;;;;;;;;;;16375:60;-1:-1:-1;;;;;;16453:25:0;;;;;:18;:25;;;;;;10442:13;16453:55;;16283:233::o;54251:103::-;53489:13;:11;:13::i;:::-;54316:30:::1;54343:1;54316:18;:30::i;82983:106::-:0;53489:13;:11;:13::i;:::-;83057:10:::1;:24:::0;82983:106::o;81935:881::-;81994:16;82048:19;82082:25;82122:22;82147:16;82157:5;82147:9;:16::i;:::-;82122:41;;82178:25;82220:14;82206:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82206:29:0;;82178:57;;82250:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82250:31:0;79473:1;82296:472;82345:14;82330:11;:29;82296:472;;82397:15;82410:1;82397:12;:15::i;:::-;82385:27;;82435:9;:16;;;82476:8;82431:73;82526:14;;-1:-1:-1;;;;;82526:28:0;;82522:111;;82599:14;;;-1:-1:-1;82522:111:0;82676:5;-1:-1:-1;;;;;82655:26:0;:17;-1:-1:-1;;;;;82655:26:0;;82651:102;;82732:1;82706:8;82715:13;;;;;;82706:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;82651:102;82361:3;;82296:472;;;-1:-1:-1;82789:8:0;;81935:881;-1:-1:-1;;;;;;81935:881:0:o;82838:78::-;53489:13;:11;:13::i;:::-;82893:8:::1;:17:::0;;;::::1;;;;-1:-1:-1::0;;82893:17:0;;::::1;::::0;;;::::1;::::0;;82838:78::o;19524:104::-;19580:13;19613:7;19606:14;;;;;:::i;79526:558::-;57413:21;:19;:21::i;:::-;79600:6:::1;::::0;::::1;;79599:7;79591:48;;;::::0;-1:-1:-1;;;79591:48:0;;8128:2:1;79591:48:0::1;::::0;::::1;8110:21:1::0;8167:2;8147:18;;;8140:30;8206;8186:18;;;8179:58;8254:18;;79591:48:0::1;7926:352:1::0;79591:48:0::1;79655:7;::::0;;;::::1;;;79654:8;79646:49;;;::::0;-1:-1:-1;;;79646:49:0;;14066:2:1;79646:49:0::1;::::0;::::1;14048:21:1::0;14105:2;14085:18;;;14078:30;14144;14124:18;;;14117:58;14192:18;;79646:49:0::1;13864:352:1::0;79646:49:0::1;79720:12;;79710:6;:22;;79702:71;;;::::0;-1:-1:-1;;;79702:71:0;;14423:2:1;79702:71:0::1;::::0;::::1;14405:21:1::0;14462:2;14442:18;;;14435:30;14501:34;14481:18;;;14474:62;-1:-1:-1;;;14552:18:1;;;14545:34;14596:19;;79702:71:0::1;14221:400:1::0;79702:71:0::1;79814:9;;79804:6;79788:13;79473:1:::0;15373:12;15160:7;15357:13;:28;-1:-1:-1;;15357:46:0;;15099:323;79788:13:::1;:22;;;;:::i;:::-;:35;;79780:63;;;::::0;-1:-1:-1;;;79780:63:0;;14828:2:1;79780:63:0::1;::::0;::::1;14810:21:1::0;14867:2;14847:18;;;14840:30;-1:-1:-1;;;14886:18:1;;;14879:45;14941:18;;79780:63:0::1;14626:339:1::0;79780:63:0::1;79905:12;::::0;79895:6;79858:34:::1;49605:10:::0;80487:13:::1;:34::i;79858:::-;:43;;;;:::i;:::-;:59;;79850:104;;;::::0;-1:-1:-1;;;79850:104:0;;9699:2:1;79850:104:0::1;::::0;::::1;9681:21:1::0;;;9718:18;;;9711:30;9777:34;9757:18;;;9750:62;9829:18;;79850:104:0::1;9497:356:1::0;79850:104:0::1;79989:6;79982:4;;:13;;;;:::i;:::-;79969:9;:26;;79961:62;;;::::0;-1:-1:-1;;;79961:62:0;;10993:2:1;79961:62:0::1;::::0;::::1;10975:21:1::0;11032:2;11012:18;;;11005:30;-1:-1:-1;;;11051:18:1;;;11044:53;11114:18;;79961:62:0::1;10791:347:1::0;79961:62:0::1;80034:38;49605:10:::0;80065:6:::1;80034:9;:38::i;:::-;57457:20:::0;56851:1;57977:7;:22;57794:213;57457:20;79526:558;:::o;26397:234::-;49605:10;26492:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;26492:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;26492:60:0;;;;;;;;;;26568:55;;722:41:1;;;26492:49:0;;49605:10;26568:55;;695:18:1;26568:55:0;;;;;;;26397:234;;:::o;85000:247::-;85175:4;-1:-1:-1;;;;;76857:18:0;;76865:10;76857:18;76853:83;;76892:32;76913:10;76892:20;:32::i;:::-;85192:47:::1;85215:4;85221:2;85225:7;85234:4;85192:22;:47::i;:::-;85000:247:::0;;;;;:::o;80931:223::-;53489:13;:11;:13::i;:::-;57413:21:::1;:19;:21::i;:::-;81066:9:::2;;81051:11;81035:13;79473:1:::0;15373:12;15160:7;15357:13;:28;-1:-1:-1;;15357:46:0;;15099:323;81035:13:::2;:27;;;;:::i;:::-;:40;;81027:75;;;::::0;-1:-1:-1;;;81027:75:0;;15172:2:1;81027:75:0::2;::::0;::::2;15154:21:1::0;15211:2;15191:18;;;15184:30;-1:-1:-1;;;15230:18:1;;;15223:52;15292:18;;81027:75:0::2;14970:346:1::0;81027:75:0::2;81113:35;81123:11;81136;81113:9;:35::i;:::-;57457:20:::1;56851:1:::0;57977:7;:22;57794:213;83288:96;53489:13;:11;:13::i;:::-;83355:14:::1;:23:::0;83288:96::o;81206:492::-;81304:13;81345:16;81353:7;81345;:16::i;:::-;81329:98;;;;-1:-1:-1;;;81329:98:0;;15523:2:1;81329:98:0;;;15505:21:1;15562:2;15542:18;;;15535:30;15601:34;15581:18;;;15574:62;-1:-1:-1;;;15652:18:1;;;15645:46;15708:19;;81329:98:0;15321:412:1;81329:98:0;81443:8;;;;;;;:17;;81455:5;81443:17;81440:62;;81480:14;81473:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81206:492;;;:::o;81440:62::-;81510:28;81541:10;:8;:10::i;:::-;81510:41;;81596:1;81571:14;81565:28;:32;:127;;;;;;;;;;;;;;;;;81633:14;81649:18;81659:7;81649:9;:18::i;:::-;81616:61;;;;;;;;;:::i;:::-;;;;;;;;;;;;;81565:127;81558:134;81206:492;-1:-1:-1;;;81206:492:0:o;81763:107::-;81821:7;81844:20;81858:5;81844:13;:20::i;83140:92::-;53489:13;:11;:13::i;:::-;83205:12:::1;:21:::0;83140:92::o;26788:164::-;-1:-1:-1;;;;;26909:25:0;;;26885:4;26909:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;26788:164::o;83850:120::-;53489:13;:11;:13::i;:::-;83932:14:::1;:32;83949:15:::0;83932:14;:32:::1;:::i;54509:201::-:0;53489:13;:11;:13::i;:::-;-1:-1:-1;;;;;54598:22:0;::::1;54590:73;;;::::0;-1:-1:-1;;;54590:73:0;;16608:2:1;54590:73:0::1;::::0;::::1;16590:21:1::0;16647:2;16627:18;;;16620:30;16686:34;16666:18;;;16659:62;-1:-1:-1;;;16737:18:1;;;16730:36;16783:19;;54590:73:0::1;16406:402:1::0;54590:73:0::1;54674:28;54693:8;54674:18;:28::i;84198:90::-:0;53489:13;:11;:13::i;:::-;84264:7:::1;:16:::0;;;::::1;;::::0;::::1;-1:-1:-1::0;;84264:16:0;;::::1;::::0;;;::::1;::::0;;84198:90::o;53768:132::-;53676:6;;-1:-1:-1;;;;;53676:6:0;49605:10;53832:23;53824:68;;;;-1:-1:-1;;;53824:68:0;;17015:2:1;53824:68:0;;;16997:21:1;;;17034:18;;;17027:30;17093:34;17073:18;;;17066:62;17145:18;;53824:68:0;16813:356:1;57493:293:0;56895:1;57627:7;;:19;57619:63;;;;-1:-1:-1;;;57619:63:0;;17376:2:1;57619:63:0;;;17358:21:1;17415:2;17395:18;;;17388:30;17454:33;17434:18;;;17427:61;17505:18;;57619:63:0;17174:355:1;57619:63:0;56895:1;57760:7;:18;57493:293::o;59236:190::-;59361:4;59414;59385:25;59398:5;59405:4;59385:12;:25::i;:::-;:33;;59236:190;-1:-1:-1;;;;59236:190:0:o;16598:178::-;-1:-1:-1;;;;;16687:25:0;16659:7;16687:25;;;:18;:25;;10580:2;16687:25;;;;;:50;;10442:13;16686:82;;16598:178::o;43350:112::-;43427:27;43437:2;43441:8;43427:27;;;;;;;;;;;;:9;:27::i;27210:282::-;27275:4;27331:7;79473:1;27312:26;;:66;;;;;27365:13;;27355:7;:23;27312:66;:153;;;;-1:-1:-1;;27416:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;27416:44:0;:49;;27210:282::o;77274:647::-;74138:42;77465:45;:49;77461:453;;77764:67;;-1:-1:-1;;;77764:67:0;;77815:4;77764:67;;;17746:34:1;-1:-1:-1;;;;;17816:15:1;;17796:18;;;17789:43;74138:42:0;;77764;;17681:18:1;;77764:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77759:144;;77859:28;;-1:-1:-1;;;77859:28:0;;-1:-1:-1;;;;;2936:32:1;;77859:28:0;;;2918:51:1;2891:18;;77859:28:0;2772:203:1;29478:2825:0;29620:27;29650;29669:7;29650:18;:27::i;:::-;29620:57;;29735:4;-1:-1:-1;;;;;29694:45:0;29710:19;-1:-1:-1;;;;;29694:45:0;;29690:86;;29748:28;;-1:-1:-1;;;29748:28:0;;;;;;;;;;;29690:86;29790:27;28586:24;;;:15;:24;;;;;28814:26;;49605:10;28211:30;;;-1:-1:-1;;;;;27904:28:0;;28189:20;;;28186:56;29976:180;;30069:43;30086:4;49605:10;26788:164;:::i;30069:43::-;30064:92;;30121:35;;-1:-1:-1;;;30121:35:0;;;;;;;;;;;30064:92;-1:-1:-1;;;;;30173:16:0;;30169:52;;30198:23;;-1:-1:-1;;;30198:23:0;;;;;;;;;;;30169:52;30370:15;30367:160;;;30510:1;30489:19;30482:30;30367:160;-1:-1:-1;;;;;30907:24:0;;;;;;;:18;:24;;;;;;30905:26;;-1:-1:-1;;30905:26:0;;;30976:22;;;;;;;;;30974:24;;-1:-1:-1;30974:24:0;;;24130:11;24105:23;24101:41;24088:63;-1:-1:-1;;;24088:63:0;31269:26;;;;:17;:26;;;;;:175;;;;-1:-1:-1;;;31564:47:0;;:52;;31560:627;;31669:1;31659:11;;31637:19;31792:30;;;:17;:30;;;;;;:35;;31788:384;;31930:13;;31915:11;:28;31911:242;;32077:30;;;;:17;:30;;;;;:52;;;31911:242;31618:569;31560:627;32234:7;32230:2;-1:-1:-1;;;;;32215:27:0;32224:4;-1:-1:-1;;;;;32215:27:0;;;;;;;;;;;32253:42;29609:2694;;;29478:2825;;;:::o;32399:193::-;32545:39;32562:4;32568:2;32572:7;32545:39;;;;;;;;;;;;:16;:39::i;21896:1275::-;21963:7;21998;;79473:1;22047:23;22043:1061;;22100:13;;22093:4;:20;22089:1015;;;22138:14;22155:23;;;:17;:23;;;;;;;-1:-1:-1;;;22244:24:0;;:29;;22240:845;;22909:113;22916:6;22926:1;22916:11;22909:113;;-1:-1:-1;;;22987:6:0;22969:25;;;;:17;:25;;;;;;22909:113;;22240:845;22115:989;22089:1015;23132:31;;-1:-1:-1;;;23132:31:0;;;;;;;;;;;54870:191;54963:6;;;-1:-1:-1;;;;;54980:17:0;;;-1:-1:-1;;;;;;54980:17:0;;;;;;;55013:40;;54963:6;;;54980:17;54963:6;;55013:40;;54944:16;;55013:40;54933:128;54870:191;:::o;21344:161::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21472:24:0;;;;:17;:24;;;;;;21453:44;;-1:-1:-1;;;;;;;;;;;;;23380:41:0;;;;11101:3;23466:33;;;23432:68;;-1:-1:-1;;;23432:68:0;-1:-1:-1;;;23530:24:0;;:29;;-1:-1:-1;;;23511:48:0;;;;11622:3;23599:28;;;;-1:-1:-1;;;23570:58:0;-1:-1:-1;23270:366:0;33190:407;33365:31;33378:4;33384:2;33388:7;33365:12;:31::i;:::-;-1:-1:-1;;;;;33411:14:0;;;:19;33407:183;;33450:56;33481:4;33487:2;33491:7;33500:5;33450:30;:56::i;:::-;33445:145;;33534:40;;-1:-1:-1;;;33534:40:0;;;;;;;;;;;79271:102;79331:13;79360:7;79353:14;;;;;:::i;49725:1745::-;49790:17;50224:4;50217;50211:11;50207:22;50316:1;50310:4;50303:15;50391:4;50388:1;50384:12;50377:19;;;50473:1;50468:3;50461:14;50577:3;50816:5;50798:428;50864:1;50859:3;50855:11;50848:18;;51035:2;51029:4;51025:13;51021:2;51017:22;51012:3;51004:36;51129:2;51119:13;;51186:25;50798:428;51186:25;-1:-1:-1;51256:13:0;;;-1:-1:-1;;51371:14:0;;;51433:19;;;51371:14;49725:1745;-1:-1:-1;49725:1745:0:o;60103:296::-;60186:7;60229:4;60186:7;60244:118;60268:5;:12;60264:1;:16;60244:118;;;60317:33;60327:12;60341:5;60347:1;60341:8;;;;;;;;:::i;:::-;;;;;;;60317:9;:33::i;:::-;60302:48;-1:-1:-1;60282:3:0;;;;:::i;:::-;;;;60244:118;;;-1:-1:-1;60379:12:0;60103:296;-1:-1:-1;;;60103:296:0:o;42577:689::-;42708:19;42714:2;42718:8;42708:5;:19::i;:::-;-1:-1:-1;;;;;42769:14:0;;;:19;42765:483;;42809:11;42823:13;42871:14;;;42904:233;42935:62;42974:1;42978:2;42982:7;;;;;;42991:5;42935:30;:62::i;:::-;42930:167;;43033:40;;-1:-1:-1;;;43033:40:0;;;;;;;;;;;42930:167;43132:3;43124:5;:11;42904:233;;43219:3;43202:13;;:20;43198:34;;43224:8;;;35681:716;35865:88;;-1:-1:-1;;;35865:88:0;;35844:4;;-1:-1:-1;;;;;35865:45:0;;;;;:88;;49605:10;;35932:4;;35938:7;;35947:5;;35865:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35865:88:0;;;;;;;;-1:-1:-1;;35865:88:0;;;;;;;;;;;;:::i;:::-;;;35861:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36148:6;:13;36165:1;36148:18;36144:235;;36194:40;;-1:-1:-1;;;36194:40:0;;;;;;;;;;;36144:235;36337:6;36331:13;36322:6;36318:2;36314:15;36307:38;35861:529;-1:-1:-1;;;;;;36024:64:0;-1:-1:-1;;;36024:64:0;;-1:-1:-1;35861:529:0;35681:716;;;;;;:::o;67143:149::-;67206:7;67237:1;67233;:5;:51;;67368:13;67462:15;;;67498:4;67491:15;;;67545:4;67529:21;;67233:51;;;-1:-1:-1;67368:13:0;67462:15;;;67498:4;67491:15;67545:4;67529:21;;;67143:149::o;36859:2966::-;36932:20;36955:13;;;36983;;;36979:44;;37005:18;;-1:-1:-1;;;37005:18:0;;;;;;;;;;;36979:44;-1:-1:-1;;;;;37511:22:0;;;;;;:18;:22;;;;10580:2;37511:22;;;:71;;37549:32;37537:45;;37511:71;;;37825:31;;;:17;:31;;;;;-1:-1:-1;24561:15:0;;24535:24;24531:46;24130:11;24105:23;24101:41;24098:52;24088:63;;37825:173;;38060:23;;;;37825:31;;37511:22;;38825:25;37511:22;;38678:335;39339:1;39325:12;39321:20;39279:346;39380:3;39371:7;39368:16;39279:346;;39598:7;39588:8;39585:1;39558:25;39555:1;39552;39547:59;39433:1;39420:15;39279:346;;;39283:77;39658:8;39670:1;39658:13;39654:45;;39680:19;;-1:-1:-1;;;39680:19:0;;;;;;;;;;;39654:45;39716:13;:19;-1:-1:-1;80129:747:0;;;:::o;196:131:1:-;-1:-1:-1;;;;;;270:32:1;;260:43;;250:71;;317:1;314;307:12;332:245;390:6;443:2;431:9;422:7;418:23;414:32;411:52;;;459:1;456;449:12;411:52;498:9;485:23;517:30;541:5;517:30;:::i;774:118::-;860:5;853:13;846:21;839:5;836:32;826:60;;882:1;879;872:12;897:241;953:6;1006:2;994:9;985:7;981:23;977:32;974:52;;;1022:1;1019;1012:12;974:52;1061:9;1048:23;1080:28;1102:5;1080:28;:::i;1143:683::-;1238:6;1246;1254;1307:2;1295:9;1286:7;1282:23;1278:32;1275:52;;;1323:1;1320;1313:12;1275:52;1359:9;1346:23;1336:33;;1420:2;1409:9;1405:18;1392:32;1443:18;1484:2;1476:6;1473:14;1470:34;;;1500:1;1497;1490:12;1470:34;1538:6;1527:9;1523:22;1513:32;;1583:7;1576:4;1572:2;1568:13;1564:27;1554:55;;1605:1;1602;1595:12;1554:55;1645:2;1632:16;1671:2;1663:6;1660:14;1657:34;;;1687:1;1684;1677:12;1657:34;1740:7;1735:2;1725:6;1722:1;1718:14;1714:2;1710:23;1706:32;1703:45;1700:65;;;1761:1;1758;1751:12;1700:65;1792:2;1788;1784:11;1774:21;;1814:6;1804:16;;;;;1143:683;;;;;:::o;1831:250::-;1916:1;1926:113;1940:6;1937:1;1934:13;1926:113;;;2016:11;;;2010:18;1997:11;;;1990:39;1962:2;1955:10;1926:113;;;-1:-1:-1;;2073:1:1;2055:16;;2048:27;1831:250::o;2086:271::-;2128:3;2166:5;2160:12;2193:6;2188:3;2181:19;2209:76;2278:6;2271:4;2266:3;2262:14;2255:4;2248:5;2244:16;2209:76;:::i;:::-;2339:2;2318:15;-1:-1:-1;;2314:29:1;2305:39;;;;2346:4;2301:50;;2086:271;-1:-1:-1;;2086:271:1:o;2362:220::-;2511:2;2500:9;2493:21;2474:4;2531:45;2572:2;2561:9;2557:18;2549:6;2531:45;:::i;2587:180::-;2646:6;2699:2;2687:9;2678:7;2674:23;2670:32;2667:52;;;2715:1;2712;2705:12;2667:52;-1:-1:-1;2738:23:1;;2587:180;-1:-1:-1;2587:180:1:o;2980:173::-;3048:20;;-1:-1:-1;;;;;3097:31:1;;3087:42;;3077:70;;3143:1;3140;3133:12;3077:70;2980:173;;;:::o;3158:254::-;3226:6;3234;3287:2;3275:9;3266:7;3262:23;3258:32;3255:52;;;3303:1;3300;3293:12;3255:52;3326:29;3345:9;3326:29;:::i;:::-;3316:39;3402:2;3387:18;;;;3374:32;;-1:-1:-1;;;3158:254:1:o;3417:328::-;3494:6;3502;3510;3563:2;3551:9;3542:7;3538:23;3534:32;3531:52;;;3579:1;3576;3569:12;3531:52;3602:29;3621:9;3602:29;:::i;:::-;3592:39;;3650:38;3684:2;3673:9;3669:18;3650:38;:::i;:::-;3640:48;;3735:2;3724:9;3720:18;3707:32;3697:42;;3417:328;;;;;:::o;4172:127::-;4233:10;4228:3;4224:20;4221:1;4214:31;4264:4;4261:1;4254:15;4288:4;4285:1;4278:15;4304:632;4369:5;4399:18;4440:2;4432:6;4429:14;4426:40;;;4446:18;;:::i;:::-;4521:2;4515:9;4489:2;4575:15;;-1:-1:-1;;4571:24:1;;;4597:2;4567:33;4563:42;4551:55;;;4621:18;;;4641:22;;;4618:46;4615:72;;;4667:18;;:::i;:::-;4707:10;4703:2;4696:22;4736:6;4727:15;;4766:6;4758;4751:22;4806:3;4797:6;4792:3;4788:16;4785:25;4782:45;;;4823:1;4820;4813:12;4782:45;4873:6;4868:3;4861:4;4853:6;4849:17;4836:44;4928:1;4921:4;4912:6;4904;4900:19;4896:30;4889:41;;;;4304:632;;;;;:::o;4941:451::-;5010:6;5063:2;5051:9;5042:7;5038:23;5034:32;5031:52;;;5079:1;5076;5069:12;5031:52;5119:9;5106:23;5152:18;5144:6;5141:30;5138:50;;;5184:1;5181;5174:12;5138:50;5207:22;;5260:4;5252:13;;5248:27;-1:-1:-1;5238:55:1;;5289:1;5286;5279:12;5238:55;5312:74;5378:7;5373:2;5360:16;5355:2;5351;5347:11;5312:74;:::i;5397:186::-;5456:6;5509:2;5497:9;5488:7;5484:23;5480:32;5477:52;;;5525:1;5522;5515:12;5477:52;5548:29;5567:9;5548:29;:::i;5773:632::-;5944:2;5996:21;;;6066:13;;5969:18;;;6088:22;;;5915:4;;5944:2;6167:15;;;;6141:2;6126:18;;;5915:4;6210:169;6224:6;6221:1;6218:13;6210:169;;;6285:13;;6273:26;;6354:15;;;;6319:12;;;;6246:1;6239:9;6210:169;;6410:315;6475:6;6483;6536:2;6524:9;6515:7;6511:23;6507:32;6504:52;;;6552:1;6549;6542:12;6504:52;6575:29;6594:9;6575:29;:::i;:::-;6565:39;;6654:2;6643:9;6639:18;6626:32;6667:28;6689:5;6667:28;:::i;:::-;6714:5;6704:15;;;6410:315;;;;;:::o;6730:667::-;6825:6;6833;6841;6849;6902:3;6890:9;6881:7;6877:23;6873:33;6870:53;;;6919:1;6916;6909:12;6870:53;6942:29;6961:9;6942:29;:::i;:::-;6932:39;;6990:38;7024:2;7013:9;7009:18;6990:38;:::i;:::-;6980:48;;7075:2;7064:9;7060:18;7047:32;7037:42;;7130:2;7119:9;7115:18;7102:32;7157:18;7149:6;7146:30;7143:50;;;7189:1;7186;7179:12;7143:50;7212:22;;7265:4;7257:13;;7253:27;-1:-1:-1;7243:55:1;;7294:1;7291;7284:12;7243:55;7317:74;7383:7;7378:2;7365:16;7360:2;7356;7352:11;7317:74;:::i;:::-;7307:84;;;6730:667;;;;;;;:::o;7402:254::-;7470:6;7478;7531:2;7519:9;7510:7;7506:23;7502:32;7499:52;;;7547:1;7544;7537:12;7499:52;7583:9;7570:23;7560:33;;7612:38;7646:2;7635:9;7631:18;7612:38;:::i;:::-;7602:48;;7402:254;;;;;:::o;7661:260::-;7729:6;7737;7790:2;7778:9;7769:7;7765:23;7761:32;7758:52;;;7806:1;7803;7796:12;7758:52;7829:29;7848:9;7829:29;:::i;:::-;7819:39;;7877:38;7911:2;7900:9;7896:18;7877:38;:::i;9235:127::-;9296:10;9291:3;9287:20;9284:1;9277:31;9327:4;9324:1;9317:15;9351:4;9348:1;9341:15;9367:125;9432:9;;;9453:10;;;9450:36;;;9466:18;;:::i;10618:168::-;10691:9;;;10722;;10739:15;;;10733:22;;10719:37;10709:71;;10760:18;;:::i;11143:380::-;11222:1;11218:12;;;;11265;;;11286:61;;11340:4;11332:6;11328:17;11318:27;;11286:61;11393:2;11385:6;11382:14;11362:18;11359:38;11356:161;;11439:10;11434:3;11430:20;11427:1;11420:31;11474:4;11471:1;11464:15;11502:4;11499:1;11492:15;11356:161;;11143:380;;;:::o;11654:545::-;11756:2;11751:3;11748:11;11745:448;;;11792:1;11817:5;11813:2;11806:17;11862:4;11858:2;11848:19;11932:2;11920:10;11916:19;11913:1;11909:27;11903:4;11899:38;11968:4;11956:10;11953:20;11950:47;;;-1:-1:-1;11991:4:1;11950:47;12046:2;12041:3;12037:12;12034:1;12030:20;12024:4;12020:31;12010:41;;12101:82;12119:2;12112:5;12109:13;12101:82;;;12164:17;;;12145:1;12134:13;12101:82;;12375:1352;12501:3;12495:10;12528:18;12520:6;12517:30;12514:56;;;12550:18;;:::i;:::-;12579:97;12669:6;12629:38;12661:4;12655:11;12629:38;:::i;:::-;12623:4;12579:97;:::i;:::-;12731:4;;12795:2;12784:14;;12812:1;12807:663;;;;13514:1;13531:6;13528:89;;;-1:-1:-1;13583:19:1;;;13577:26;13528:89;-1:-1:-1;;12332:1:1;12328:11;;;12324:24;12320:29;12310:40;12356:1;12352:11;;;12307:57;13630:81;;12777:944;;12807:663;11601:1;11594:14;;;11638:4;11625:18;;-1:-1:-1;;12843:20:1;;;12961:236;12975:7;12972:1;12969:14;12961:236;;;13064:19;;;13058:26;13043:42;;13156:27;;;;13124:1;13112:14;;;;12991:19;;12961:236;;;12965:3;13225:6;13216:7;13213:19;13210:201;;;13286:19;;;13280:26;-1:-1:-1;;13369:1:1;13365:14;;;13381:3;13361:24;13357:37;13353:42;13338:58;13323:74;;13210:201;-1:-1:-1;;;;;13457:1:1;13441:14;;;13437:22;13424:36;;-1:-1:-1;12375:1352:1:o;13732:127::-;13793:10;13788:3;13784:20;13781:1;13774:31;13824:4;13821:1;13814:15;13848:4;13845:1;13838:15;15738:663;16018:3;16056:6;16050:13;16072:66;16131:6;16126:3;16119:4;16111:6;16107:17;16072:66;:::i;:::-;16201:13;;16160:16;;;;16223:70;16201:13;16160:16;16270:4;16258:17;;16223:70;:::i;:::-;-1:-1:-1;;;16315:20:1;;16344:22;;;16393:1;16382:13;;15738:663;-1:-1:-1;;;;15738:663:1:o;17843:245::-;17910:6;17963:2;17951:9;17942:7;17938:23;17934:32;17931:52;;;17979:1;17976;17969:12;17931:52;18011:9;18005:16;18030:28;18052:5;18030:28;:::i;18093:135::-;18132:3;18153:17;;;18150:43;;18173:18;;:::i;:::-;-1:-1:-1;18220:1:1;18209:13;;18093:135::o;18233:489::-;-1:-1:-1;;;;;18502:15:1;;;18484:34;;18554:15;;18549:2;18534:18;;18527:43;18601:2;18586:18;;18579:34;;;18649:3;18644:2;18629:18;;18622:31;;;18427:4;;18670:46;;18696:19;;18688:6;18670:46;:::i;:::-;18662:54;18233:489;-1:-1:-1;;;;;;18233:489:1:o;18727:249::-;18796:6;18849:2;18837:9;18828:7;18824:23;18820:32;18817:52;;;18865:1;18862;18855:12;18817:52;18897:9;18891:16;18916:30;18940:5;18916:30;:::i

Swarm Source

ipfs://54ebdb4263fe6844f46c4e2ff576d54be70f3d39c4daf5f52ac9bab8ec8436ca
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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