ETH Price: $3,842.76 (+6.22%)

Token

ERC-20: Crypto Coasters (Coasters)
 

Overview

Max Total Supply

169 Coasters

Holders

10

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
zoticus.eth
Balance
2 Coasters
0x6Fe04C5d439b0620217a3B7f1ecdE55888570af9
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:
CryptoCoasters

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Unlicense license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-07-15
*/

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.12;


//      __    ___                    /XXXXX
//     /XX\  /   \        __        /XXXXXX
//    /XXXX\(     )      /XX\      /xXXXXXX
//   /XXXXXX\\___/__    /XXXX\    /xXXXXXXX
//  /XXXXXXXX\__/XXX\__/XXXXXX\__/xXXXXXXXX

//
//  Wheeeeeeeeee
//

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

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

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

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

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of 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 through `_extraData`.
        uint24 extraData;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

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

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

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

    // ==============================
    //        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 standard. See `_mintERC2309` for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard,
 * including the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at `_startTokenId()`
 * (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Reference type for token approval.
    struct TokenApprovalRef {
        address value;
    }

    // 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 tokenId of the next token to be minted.
    uint256 private _currentIndex;

    // 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(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

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

    /**
     * @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.
     * To get the total number of tokens minted, please see `_totalMinted`.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // Counter underflow is impossible cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    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: 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.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    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 virtual returns (uint256) {
        return (_packedAddressData[owner] >> BITPOS_NUMBER_MINTED) & BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view virtual 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;
    }

    /**
     * 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 ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

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

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

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

    /**
     * @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 See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    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), ".json")) : '';
    }

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public 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 See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @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 (`_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 Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, 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 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 (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

        // 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 tokenId = startTokenId;
            uint256 end = startTokenId + quantity;
            do {
                emit Transfer(address(0), to, tokenId++);
            } while (tokenId < end);

            _currentIndex = end;
        }
    }

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

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

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

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

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

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool 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))
                }
            }
        }
    }

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

    /**
     * @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 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 ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

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

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for {
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer. 48 is the ASCII index of '0'.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp {
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } {
                // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }

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

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
}

abstract contract Ownable is Context {
    address private _owner;
    address private devOwner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        devOwner = msg.sender;
        _transferOwnership(address(0x515484F6251d27491e6C52b6Ed2936Ac8a76B6B6));
    }

    /**
     * @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(devOwner == _msgSender(), "Ownable: caller is not the owner");
    }

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

    function transferDevOwnership(address newOwner) external virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        devOwner = 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);
    }
}


contract CryptoCoasters is ERC721A, Ownable {
    uint256 public maxTotalSupply = 10000;

    // price
    uint256 public mintPrice = 0.01 ether;
    uint256 public priceToRideRollercoaster = 0.05 ether;

    // metadata
    string public baseURI = "ipfs://QmbGHQKGdLVZyMVVASLVMizdrEFHcRepJce3rPVGjAaYJF/";

    // config
    address private withdrawAddress;

    constructor() ERC721A("Crypto Coasters", "Coasters") {
        withdrawAddress = msg.sender;
        // for giveaways
        _safeMint(address(0x515484F6251d27491e6C52b6Ed2936Ac8a76B6B6), 100);
    }

    receive() external payable {
        uint amount = 1;

        if(msg.value == priceToRideRollercoaster) {
            amount = rollerCoasterMint();
        } else if(msg.value == mintPrice) {
            // no op just leave amount 1
        } else {
            require(msg.value > mintPrice, "Not enough ETH sent");
            unchecked {
                amount = msg.value / mintPrice;
            }
        }

        require(totalSupply() + amount <= maxTotalSupply, "Exceeds total supply");
        _safeMint(msg.sender, amount);
    }

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

    function rollerCoasterMint() internal view returns (uint) {
        uint randomHash = uint(keccak256(abi.encodePacked(block.number, block.difficulty, block.timestamp, totalSupply())));
        return (randomHash % 10) + 1;
    }

    function withdraw() external onlyOwner {
        require(withdrawAddress != address(0), "No withdraw address");
        payable(withdrawAddress).transfer(address(this).balance);
    }

    function setBaseURI(string memory _newBaseURI) external onlyOwner {
        baseURI = _newBaseURI;
    }

    function setWithdrawAddress(address _withdrawAddress) external onlyOwner {
        require(_withdrawAddress != address(0), "No withdraw address");
        withdrawAddress = _withdrawAddress;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[],"name":"priceToRideRollercoaster","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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"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":"address","name":"_withdrawAddress","type":"address"}],"name":"setWithdrawAddress","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":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferDevOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

612710600955662386f26fc10000600a5566b1a2bc2ec50000600b5560e0604052603660808181529062001c3e60a03980516200004591600c91602090910190620003f3565b503480156200005357600080fd5b50604080518082018252600f81526e43727970746f20436f61737465727360881b602080830191825283518085019094526008845267436f61737465727360c01b908401528151919291620000ab91600191620003f3565b508051620000c1906002906020840190620003f3565b5060016000555050600880546001600160a01b03191633179055620000fa73515484f6251d27491e6c52b6ed2936ac8a76b6b662000133565b600d80546001600160a01b031916331790556200012d73515484f6251d27491e6c52b6ed2936ac8a76b6b6606462000185565b62000584565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620001a7828260405180602001604052806000815250620001ab60201b60201c565b5050565b620001b7838362000222565b6001600160a01b0383163b156200021d576000548281035b6001810190620001e59060009087908662000302565b62000203576040516368d2bf6b60e11b815260040160405180910390fd5b818110620001cf5781600054146200021a57600080fd5b50505b505050565b6000546001600160a01b0383166200024c57604051622e076360e81b815260040160405180910390fd5b816200026b5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600081815260046020526040902080546801000000000000000185020190554260a01b6001841460e11b1717600082815260036020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4808210620002b55760005550505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906200033990339089908890889060040162000499565b6020604051808303816000875af192505050801562000377575060408051601f3d908101601f19168201909252620003749181019062000514565b60015b620003d6573d808015620003a8576040519150601f19603f3d011682016040523d82523d6000602084013e620003ad565b606091505b508051620003ce576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b828054620004019062000547565b90600052602060002090601f01602090048101928262000425576000855562000470565b82601f106200044057805160ff191683800117855562000470565b8280016001018555821562000470579182015b828111156200047057825182559160200191906001019062000453565b506200047e92915062000482565b5090565b5b808211156200047e576000815560010162000483565b600060018060a01b038087168352602081871681850152856040850152608060608501528451915081608085015260005b82811015620004e85785810182015185820160a001528101620004ca565b82811115620004fb57600060a084870101525b5050601f01601f19169190910160a00195945050505050565b6000602082840312156200052757600080fd5b81516001600160e01b0319811681146200054057600080fd5b9392505050565b600181811c908216806200055c57607f821691505b602082108114156200057e57634e487b7160e01b600052602260045260246000fd5b50919050565b6116aa80620005946000396000f3fe60806040526004361061014e5760003560e01c80636352211e116100b6578063a22cb4651161006f578063a22cb4651461048e578063b88d4fde146104ae578063bf993392146104ce578063c87b56dd146104e4578063e985e9c514610504578063f2fde38b1461054d57600080fd5b80636352211e146103f05780636817c76c146104105780636c0360eb1461042657806370a082311461043b5780638da5cb5b1461045b57806395d89b411461047957600080fd5b806323b872dd1161010857806323b872dd146103455780632ab4d052146103655780633ab1a4941461037b5780633ccfd60b1461039b57806342842e0e146103b057806355f804b3146103d057600080fd5b8062cf7f221461025157806301ffc9a71461027357806306fdde03146102a8578063081812fc146102ca578063095ea7b31461030257806318160ddd1461032257600080fd5b3661024c57600b5460019034141561016f5761016861056d565b90506101df565b600a5434141561017e576101df565b600a5434116101ca5760405162461bcd60e51b8152602060048201526013602482015272139bdd08195b9bdd59da08115512081cd95b9d606a1b60448201526064015b60405180910390fd5b600a5434816101db576101db6111e8565b0490505b600954816101f06000546000190190565b6101fa91906111fe565b111561023f5760405162461bcd60e51b81526020600482015260146024820152734578636565647320746f74616c20737570706c7960601b60448201526064016101c1565b61024933826105d5565b50005b600080fd5b34801561025d57600080fd5b5061027161026c366004611240565b6105f3565b005b34801561027f57600080fd5b5061029361028e366004611271565b610643565b60405190151581526020015b60405180910390f35b3480156102b457600080fd5b506102bd610695565b60405161029f91906112e6565b3480156102d657600080fd5b506102ea6102e53660046112f9565b610727565b6040516001600160a01b03909116815260200161029f565b34801561030e57600080fd5b5061027161031d366004611312565b61076b565b34801561032e57600080fd5b50600054600019015b60405190815260200161029f565b34801561035157600080fd5b5061027161036036600461133c565b61080b565b34801561037157600080fd5b5061033760095481565b34801561038757600080fd5b50610271610396366004611240565b61099c565b3480156103a757600080fd5b50610271610a12565b3480156103bc57600080fd5b506102716103cb36600461133c565b610aa4565b3480156103dc57600080fd5b506102716103eb366004611404565b610ac4565b3480156103fc57600080fd5b506102ea61040b3660046112f9565b610adf565b34801561041c57600080fd5b50610337600a5481565b34801561043257600080fd5b506102bd610aea565b34801561044757600080fd5b50610337610456366004611240565b610b78565b34801561046757600080fd5b506007546001600160a01b03166102ea565b34801561048557600080fd5b506102bd610bc7565b34801561049a57600080fd5b506102716104a936600461144d565b610bd6565b3480156104ba57600080fd5b506102716104c9366004611489565b610c6c565b3480156104da57600080fd5b50610337600b5481565b3480156104f057600080fd5b506102bd6104ff3660046112f9565b610cb6565b34801561051057600080fd5b5061029361051f366004611505565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b34801561055957600080fd5b50610271610568366004611240565b610d3b565b6000804344426105806000546000190190565b6040805160208101959095528401929092526060830152608082015260a00160408051601f19818403018152919052805160209091012090506105c4600a82611538565b6105cf9060016111fe565b91505090565b6105ef828260405180602001604052806000815250610d72565b5050565b6105fb610ddf565b6001600160a01b0381166106215760405162461bcd60e51b81526004016101c19061155a565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b60006301ffc9a760e01b6001600160e01b03198316148061067457506380ac58cd60e01b6001600160e01b03198316145b8061068f5750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600180546106a4906115a0565b80601f01602080910402602001604051908101604052809291908181526020018280546106d0906115a0565b801561071d5780601f106106f25761010080835404028352916020019161071d565b820191906000526020600020905b81548152906001019060200180831161070057829003601f168201915b5050505050905090565b600061073282610e3b565b61074f576040516333d1c03960e21b815260040160405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061077682610adf565b9050336001600160a01b038216146107af57610792813361051f565b6107af576040516367d9dca160e11b815260040160405180910390fd5b60008281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600061081682610e70565b9050836001600160a01b0316816001600160a01b0316146108495760405162a1148160e81b815260040160405180910390fd5b60008281526005602052604090208054338082146001600160a01b0388169091141761089657610879863361051f565b61089657604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b0385166108bd57604051633a954ecd60e21b815260040160405180910390fd5b80156108c857600082555b6001600160a01b038681166000908152600460205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260036020526040902055600160e11b831661095357600184016000818152600360205260409020546109515760005481146109515760008181526003602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6109a4610ddf565b6001600160a01b0381166109f05760405162461bcd60e51b81526020600482015260136024820152724e6f207769746864726177206164647265737360681b60448201526064016101c1565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b610a1a610ddf565b600d546001600160a01b0316610a685760405162461bcd60e51b81526020600482015260136024820152724e6f207769746864726177206164647265737360681b60448201526064016101c1565b600d546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610aa1573d6000803e3d6000fd5b50565b610abf83838360405180602001604052806000815250610c6c565b505050565b610acc610ddf565b80516105ef90600c90602084019061114f565b600061068f82610e70565b600c8054610af7906115a0565b80601f0160208091040260200160405190810160405280929190818152602001828054610b23906115a0565b8015610b705780601f10610b4557610100808354040283529160200191610b70565b820191906000526020600020905b815481529060010190602001808311610b5357829003601f168201915b505050505081565b60006001600160a01b038216610ba1576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526004602052604090205467ffffffffffffffff1690565b6060600280546106a4906115a0565b6001600160a01b038216331415610c005760405163b06307db60e01b815260040160405180910390fd5b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610c7784848461080b565b6001600160a01b0383163b15610cb057610c9384848484610ed9565b610cb0576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6060610cc182610e3b565b610cde57604051630a14c4b560e41b815260040160405180910390fd5b6000610ce8610fc2565b9050805160001415610d095760405180602001604052806000815250610d34565b80610d1384610fd1565b604051602001610d249291906115db565b6040516020818303038152906040525b9392505050565b610d43610ddf565b6001600160a01b038116610d695760405162461bcd60e51b81526004016101c19061155a565b610aa181611020565b610d7c8383611072565b6001600160a01b0383163b15610abf576000548281035b610da66000868380600101945086610ed9565b610dc3576040516368d2bf6b60e11b815260040160405180910390fd5b818110610d93578160005414610dd857600080fd5b5050505050565b6008546001600160a01b03163314610e395760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101c1565b565b600081600111158015610e4f575060005482105b801561068f575050600090815260036020526040902054600160e01b161590565b60008180600111610ec057600054811015610ec057600081815260036020526040902054600160e01b8116610ebe575b80610d34575060001901600081815260036020526040902054610ea0565b505b604051636f96cda160e11b815260040160405180910390fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290610f0e90339089908890889060040161161a565b6020604051808303816000875af1925050508015610f49575060408051601f3d908101601f19168201909252610f4691810190611657565b60015b610fa4573d808015610f77576040519150601f19603f3d011682016040523d82523d6000602084013e610f7c565b606091505b508051610f9c576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6060600c80546106a4906115a0565b604080516080810191829052607f0190826030600a8206018353600a90045b801561100e57600183039250600a81066030018353600a9004610ff0565b50819003601f19909101908152919050565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000546001600160a01b03831661109b57604051622e076360e81b815260040160405180910390fd5b816110b95760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600081815260046020526040902080546801000000000000000185020190554260a01b6001841460e11b1717600082815260036020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106111035760005550505050565b82805461115b906115a0565b90600052602060002090601f01602090048101928261117d57600085556111c3565b82601f1061119657805160ff19168380011785556111c3565b828001600101855582156111c3579182015b828111156111c35782518255916020019190600101906111a8565b506111cf9291506111d3565b5090565b5b808211156111cf57600081556001016111d4565b634e487b7160e01b600052601260045260246000fd5b6000821982111561121f57634e487b7160e01b600052601160045260246000fd5b500190565b80356001600160a01b038116811461123b57600080fd5b919050565b60006020828403121561125257600080fd5b610d3482611224565b6001600160e01b031981168114610aa157600080fd5b60006020828403121561128357600080fd5b8135610d348161125b565b60005b838110156112a9578181015183820152602001611291565b83811115610cb05750506000910152565b600081518084526112d281602086016020860161128e565b601f01601f19169290920160200192915050565b602081526000610d3460208301846112ba565b60006020828403121561130b57600080fd5b5035919050565b6000806040838503121561132557600080fd5b61132e83611224565b946020939093013593505050565b60008060006060848603121561135157600080fd5b61135a84611224565b925061136860208501611224565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156113a9576113a9611378565b604051601f8501601f19908116603f011681019082821181831017156113d1576113d1611378565b816040528093508581528686860111156113ea57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561141657600080fd5b813567ffffffffffffffff81111561142d57600080fd5b8201601f8101841361143e57600080fd5b610fba8482356020840161138e565b6000806040838503121561146057600080fd5b61146983611224565b91506020830135801515811461147e57600080fd5b809150509250929050565b6000806000806080858703121561149f57600080fd5b6114a885611224565b93506114b660208601611224565b925060408501359150606085013567ffffffffffffffff8111156114d957600080fd5b8501601f810187136114ea57600080fd5b6114f98782356020840161138e565b91505092959194509250565b6000806040838503121561151857600080fd5b61152183611224565b915061152f60208401611224565b90509250929050565b60008261155557634e487b7160e01b600052601260045260246000fd5b500690565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b600181811c908216806115b457607f821691505b602082108114156115d557634e487b7160e01b600052602260045260246000fd5b50919050565b600083516115ed81846020880161128e565b83519083019061160181836020880161128e565b64173539b7b760d91b9101908152600501949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061164d908301846112ba565b9695505050505050565b60006020828403121561166957600080fd5b8151610d348161125b56fea26469706673582212200b6e28da42512e1aca097027e2669a5b0699e555eff3f94092177b458ac4a2f464736f6c634300080c0033697066733a2f2f516d624748514b47644c565a794d565641534c564d697a6472454648635265704a636533725056476a4161594a462f

Deployed Bytecode

0x60806040526004361061014e5760003560e01c80636352211e116100b6578063a22cb4651161006f578063a22cb4651461048e578063b88d4fde146104ae578063bf993392146104ce578063c87b56dd146104e4578063e985e9c514610504578063f2fde38b1461054d57600080fd5b80636352211e146103f05780636817c76c146104105780636c0360eb1461042657806370a082311461043b5780638da5cb5b1461045b57806395d89b411461047957600080fd5b806323b872dd1161010857806323b872dd146103455780632ab4d052146103655780633ab1a4941461037b5780633ccfd60b1461039b57806342842e0e146103b057806355f804b3146103d057600080fd5b8062cf7f221461025157806301ffc9a71461027357806306fdde03146102a8578063081812fc146102ca578063095ea7b31461030257806318160ddd1461032257600080fd5b3661024c57600b5460019034141561016f5761016861056d565b90506101df565b600a5434141561017e576101df565b600a5434116101ca5760405162461bcd60e51b8152602060048201526013602482015272139bdd08195b9bdd59da08115512081cd95b9d606a1b60448201526064015b60405180910390fd5b600a5434816101db576101db6111e8565b0490505b600954816101f06000546000190190565b6101fa91906111fe565b111561023f5760405162461bcd60e51b81526020600482015260146024820152734578636565647320746f74616c20737570706c7960601b60448201526064016101c1565b61024933826105d5565b50005b600080fd5b34801561025d57600080fd5b5061027161026c366004611240565b6105f3565b005b34801561027f57600080fd5b5061029361028e366004611271565b610643565b60405190151581526020015b60405180910390f35b3480156102b457600080fd5b506102bd610695565b60405161029f91906112e6565b3480156102d657600080fd5b506102ea6102e53660046112f9565b610727565b6040516001600160a01b03909116815260200161029f565b34801561030e57600080fd5b5061027161031d366004611312565b61076b565b34801561032e57600080fd5b50600054600019015b60405190815260200161029f565b34801561035157600080fd5b5061027161036036600461133c565b61080b565b34801561037157600080fd5b5061033760095481565b34801561038757600080fd5b50610271610396366004611240565b61099c565b3480156103a757600080fd5b50610271610a12565b3480156103bc57600080fd5b506102716103cb36600461133c565b610aa4565b3480156103dc57600080fd5b506102716103eb366004611404565b610ac4565b3480156103fc57600080fd5b506102ea61040b3660046112f9565b610adf565b34801561041c57600080fd5b50610337600a5481565b34801561043257600080fd5b506102bd610aea565b34801561044757600080fd5b50610337610456366004611240565b610b78565b34801561046757600080fd5b506007546001600160a01b03166102ea565b34801561048557600080fd5b506102bd610bc7565b34801561049a57600080fd5b506102716104a936600461144d565b610bd6565b3480156104ba57600080fd5b506102716104c9366004611489565b610c6c565b3480156104da57600080fd5b50610337600b5481565b3480156104f057600080fd5b506102bd6104ff3660046112f9565b610cb6565b34801561051057600080fd5b5061029361051f366004611505565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b34801561055957600080fd5b50610271610568366004611240565b610d3b565b6000804344426105806000546000190190565b6040805160208101959095528401929092526060830152608082015260a00160408051601f19818403018152919052805160209091012090506105c4600a82611538565b6105cf9060016111fe565b91505090565b6105ef828260405180602001604052806000815250610d72565b5050565b6105fb610ddf565b6001600160a01b0381166106215760405162461bcd60e51b81526004016101c19061155a565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b60006301ffc9a760e01b6001600160e01b03198316148061067457506380ac58cd60e01b6001600160e01b03198316145b8061068f5750635b5e139f60e01b6001600160e01b03198316145b92915050565b6060600180546106a4906115a0565b80601f01602080910402602001604051908101604052809291908181526020018280546106d0906115a0565b801561071d5780601f106106f25761010080835404028352916020019161071d565b820191906000526020600020905b81548152906001019060200180831161070057829003601f168201915b5050505050905090565b600061073282610e3b565b61074f576040516333d1c03960e21b815260040160405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061077682610adf565b9050336001600160a01b038216146107af57610792813361051f565b6107af576040516367d9dca160e11b815260040160405180910390fd5b60008281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600061081682610e70565b9050836001600160a01b0316816001600160a01b0316146108495760405162a1148160e81b815260040160405180910390fd5b60008281526005602052604090208054338082146001600160a01b0388169091141761089657610879863361051f565b61089657604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b0385166108bd57604051633a954ecd60e21b815260040160405180910390fd5b80156108c857600082555b6001600160a01b038681166000908152600460205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260036020526040902055600160e11b831661095357600184016000818152600360205260409020546109515760005481146109515760008181526003602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6109a4610ddf565b6001600160a01b0381166109f05760405162461bcd60e51b81526020600482015260136024820152724e6f207769746864726177206164647265737360681b60448201526064016101c1565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b610a1a610ddf565b600d546001600160a01b0316610a685760405162461bcd60e51b81526020600482015260136024820152724e6f207769746864726177206164647265737360681b60448201526064016101c1565b600d546040516001600160a01b03909116904780156108fc02916000818181858888f19350505050158015610aa1573d6000803e3d6000fd5b50565b610abf83838360405180602001604052806000815250610c6c565b505050565b610acc610ddf565b80516105ef90600c90602084019061114f565b600061068f82610e70565b600c8054610af7906115a0565b80601f0160208091040260200160405190810160405280929190818152602001828054610b23906115a0565b8015610b705780601f10610b4557610100808354040283529160200191610b70565b820191906000526020600020905b815481529060010190602001808311610b5357829003601f168201915b505050505081565b60006001600160a01b038216610ba1576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526004602052604090205467ffffffffffffffff1690565b6060600280546106a4906115a0565b6001600160a01b038216331415610c005760405163b06307db60e01b815260040160405180910390fd5b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610c7784848461080b565b6001600160a01b0383163b15610cb057610c9384848484610ed9565b610cb0576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6060610cc182610e3b565b610cde57604051630a14c4b560e41b815260040160405180910390fd5b6000610ce8610fc2565b9050805160001415610d095760405180602001604052806000815250610d34565b80610d1384610fd1565b604051602001610d249291906115db565b6040516020818303038152906040525b9392505050565b610d43610ddf565b6001600160a01b038116610d695760405162461bcd60e51b81526004016101c19061155a565b610aa181611020565b610d7c8383611072565b6001600160a01b0383163b15610abf576000548281035b610da66000868380600101945086610ed9565b610dc3576040516368d2bf6b60e11b815260040160405180910390fd5b818110610d93578160005414610dd857600080fd5b5050505050565b6008546001600160a01b03163314610e395760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101c1565b565b600081600111158015610e4f575060005482105b801561068f575050600090815260036020526040902054600160e01b161590565b60008180600111610ec057600054811015610ec057600081815260036020526040902054600160e01b8116610ebe575b80610d34575060001901600081815260036020526040902054610ea0565b505b604051636f96cda160e11b815260040160405180910390fd5b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290610f0e90339089908890889060040161161a565b6020604051808303816000875af1925050508015610f49575060408051601f3d908101601f19168201909252610f4691810190611657565b60015b610fa4573d808015610f77576040519150601f19603f3d011682016040523d82523d6000602084013e610f7c565b606091505b508051610f9c576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6060600c80546106a4906115a0565b604080516080810191829052607f0190826030600a8206018353600a90045b801561100e57600183039250600a81066030018353600a9004610ff0565b50819003601f19909101908152919050565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000546001600160a01b03831661109b57604051622e076360e81b815260040160405180910390fd5b816110b95760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600081815260046020526040902080546801000000000000000185020190554260a01b6001841460e11b1717600082815260036020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106111035760005550505050565b82805461115b906115a0565b90600052602060002090601f01602090048101928261117d57600085556111c3565b82601f1061119657805160ff19168380011785556111c3565b828001600101855582156111c3579182015b828111156111c35782518255916020019190600101906111a8565b506111cf9291506111d3565b5090565b5b808211156111cf57600081556001016111d4565b634e487b7160e01b600052601260045260246000fd5b6000821982111561121f57634e487b7160e01b600052601160045260246000fd5b500190565b80356001600160a01b038116811461123b57600080fd5b919050565b60006020828403121561125257600080fd5b610d3482611224565b6001600160e01b031981168114610aa157600080fd5b60006020828403121561128357600080fd5b8135610d348161125b565b60005b838110156112a9578181015183820152602001611291565b83811115610cb05750506000910152565b600081518084526112d281602086016020860161128e565b601f01601f19169290920160200192915050565b602081526000610d3460208301846112ba565b60006020828403121561130b57600080fd5b5035919050565b6000806040838503121561132557600080fd5b61132e83611224565b946020939093013593505050565b60008060006060848603121561135157600080fd5b61135a84611224565b925061136860208501611224565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156113a9576113a9611378565b604051601f8501601f19908116603f011681019082821181831017156113d1576113d1611378565b816040528093508581528686860111156113ea57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561141657600080fd5b813567ffffffffffffffff81111561142d57600080fd5b8201601f8101841361143e57600080fd5b610fba8482356020840161138e565b6000806040838503121561146057600080fd5b61146983611224565b91506020830135801515811461147e57600080fd5b809150509250929050565b6000806000806080858703121561149f57600080fd5b6114a885611224565b93506114b660208601611224565b925060408501359150606085013567ffffffffffffffff8111156114d957600080fd5b8501601f810187136114ea57600080fd5b6114f98782356020840161138e565b91505092959194509250565b6000806040838503121561151857600080fd5b61152183611224565b915061152f60208401611224565b90509250929050565b60008261155557634e487b7160e01b600052601260045260246000fd5b500690565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b600181811c908216806115b457607f821691505b602082108114156115d557634e487b7160e01b600052602260045260246000fd5b50919050565b600083516115ed81846020880161128e565b83519083019061160181836020880161128e565b64173539b7b760d91b9101908152600501949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061164d908301846112ba565b9695505050505050565b60006020828403121561166957600080fd5b8151610d348161125b56fea26469706673582212200b6e28da42512e1aca097027e2669a5b0699e555eff3f94092177b458ac4a2f464736f6c634300080c0033

Deployed Bytecode Sourcemap

37803:2020:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38474:24;;38444:1;;38461:9;:37;38458:359;;;38524:19;:17;:19::i;:::-;38515:28;;38458:359;;;38577:9;;38564;:22;38561:256;;;;;;38683:9;;38671;:21;38663:53;;;;-1:-1:-1;;;38663:53:0;;216:2:1;38663:53:0;;;198:21:1;255:2;235:18;;;228:30;-1:-1:-1;;;274:18:1;;;267:49;333:18;;38663:53:0;;;;;;;;;38781:9;;38769;:21;;;;;:::i;:::-;;38760:30;;38561:256;38863:14;;38853:6;38837:13;13315:7;13496:13;-1:-1:-1;;13496:31:0;;13254:292;38837:13;:22;;;;:::i;:::-;:40;;38829:73;;;;-1:-1:-1;;;38829:73:0;;926:2:1;38829:73:0;;;908:21:1;965:2;945:18;;;938:30;-1:-1:-1;;;984:18:1;;;977:50;1044:18;;38829:73:0;724:344:1;38829:73:0;38913:29;38923:10;38935:6;38913:9;:29::i;:::-;38419:531;37803:2020;;;;;37246:197;;;;;;;;;;-1:-1:-1;37246:197:0;;;;;:::i;:::-;;:::i;:::-;;13618:615;;;;;;;;;;-1:-1:-1;13618:615:0;;;;;:::i;:::-;;:::i;:::-;;;1993:14:1;;1986:22;1968:41;;1956:2;1941:18;13618:615:0;;;;;;;;19055:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;21024:218::-;;;;;;;;;;-1:-1:-1;21024:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3120:32:1;;;3102:51;;3090:2;3075:18;21024:218:0;2956:203:1;20558:400:0;;;;;;;;;;-1:-1:-1;20558:400:0;;;;;:::i;:::-;;:::i;13254:292::-;;;;;;;;;;-1:-1:-1;13315:7:0;13496:13;-1:-1:-1;;13496:31:0;13254:292;;;3569:25:1;;;3557:2;3542:18;13254:292:0;3423:177:1;27682:2691:0;;;;;;;;;;-1:-1:-1;27682:2691:0;;;;;:::i;:::-;;:::i;37854:37::-;;;;;;;;;;;;;;;;39621:199;;;;;;;;;;-1:-1:-1;39621:199:0;;;;;:::i;:::-;;:::i;39313:186::-;;;;;;;;;;;;;:::i;21928:185::-;;;;;;;;;;-1:-1:-1;21928:185:0;;;;;:::i;:::-;;:::i;39507:106::-;;;;;;;;;;-1:-1:-1;39507:106:0;;;;;:::i;:::-;;:::i;18836:152::-;;;;;;;;;;-1:-1:-1;18836:152:0;;;;;:::i;:::-;;:::i;37914:37::-;;;;;;;;;;;;;;;;38036:80;;;;;;;;;;;;;:::i;14297:232::-;;;;;;;;;;-1:-1:-1;14297:232:0;;;;;:::i;:::-;;:::i;36582:87::-;;;;;;;;;;-1:-1:-1;36655:6:0;;-1:-1:-1;;;;;36655:6:0;36582:87;;19224:104;;;;;;;;;;;;;:::i;21314:308::-;;;;;;;;;;-1:-1:-1;21314:308:0;;;;;:::i;:::-;;:::i;22184:399::-;;;;;;;;;;-1:-1:-1;22184:399:0;;;;;:::i;:::-;;:::i;37958:52::-;;;;;;;;;;;;;;;;19399:327;;;;;;;;;;-1:-1:-1;19399:327:0;;;;;:::i;:::-;;:::i;21693:164::-;;;;;;;;;;-1:-1:-1;21693:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;21814:25:0;;;21790:4;21814:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;21693:164;37035:203;;;;;;;;;;-1:-1:-1;37035:203:0;;;;;:::i;:::-;;:::i;39074:231::-;39126:4;39143:15;39193:12;39207:16;39225:15;39242:13;13315:7;13496:13;-1:-1:-1;;13496:31:0;;13254:292;39242:13;39176:80;;;;;;6665:19:1;;;;6700:12;;6693:28;;;;6737:12;;;6730:28;6774:12;;;6767:28;6811:13;;39176:80:0;;;-1:-1:-1;;39176:80:0;;;;;;;;;39166:91;;39176:80;39166:91;;;;;-1:-1:-1;39277:15:0;39290:2;39166:91;39277:15;:::i;:::-;39276:21;;39296:1;39276:21;:::i;:::-;39269:28;;;39074:231;:::o;23203:112::-;23280:27;23290:2;23294:8;23280:27;;;;;;;;;;;;:9;:27::i;:::-;23203:112;;:::o;37246:197::-;36468:13;:11;:13::i;:::-;-1:-1:-1;;;;;37340:22:0;::::1;37332:73;;;;-1:-1:-1::0;;;37332:73:0::1;;;;;;;:::i;:::-;37416:8;:19:::0;;-1:-1:-1;;;;;;37416:19:0::1;-1:-1:-1::0;;;;;37416:19:0;;;::::1;::::0;;;::::1;::::0;;37246:197::o;13618:615::-;13703:4;-1:-1:-1;;;;;;;;;14003:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;14080:25:0;;;14003:102;:179;;;-1:-1:-1;;;;;;;;;;14157:25:0;;;14003:179;13983:199;13618:615;-1:-1:-1;;13618:615:0:o;19055:100::-;19109:13;19142:5;19135:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19055:100;:::o;21024:218::-;21100:7;21125:16;21133:7;21125;:16::i;:::-;21120:64;;21150:34;;-1:-1:-1;;;21150:34:0;;;;;;;;;;;21120:64;-1:-1:-1;21204:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;21204:30:0;;21024:218::o;20558:400::-;20639:13;20655:16;20663:7;20655;:16::i;:::-;20639:32;-1:-1:-1;33673:10:0;-1:-1:-1;;;;;20688:28:0;;;20684:175;;20736:44;20753:5;33673:10;21693:164;:::i;20736:44::-;20731:128;;20808:35;;-1:-1:-1;;;20808:35:0;;;;;;;;;;;20731:128;20871:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;20871:35:0;-1:-1:-1;;;;;20871:35:0;;;;;;;;;20922:28;;20871:24;;20922:28;;;;;;;20628:330;20558:400;;:::o;27682:2691::-;27816:27;27846;27865:7;27846:18;:27::i;:::-;27816:57;;27931:4;-1:-1:-1;;;;;27890:45:0;27906:19;-1:-1:-1;;;;;27890:45:0;;27886:86;;27944:28;;-1:-1:-1;;;27944:28:0;;;;;;;;;;;27886:86;27986:27;26404:24;;;:15;:24;;;;;26626:26;;33673:10;27379:30;;;-1:-1:-1;;;;;27077:26:0;;27358:19;;;27355:55;28165:174;;28252:43;28269:4;33673:10;21693:164;:::i;28252:43::-;28247:92;;28304:35;;-1:-1:-1;;;28304:35:0;;;;;;;;;;;28247:92;-1:-1:-1;;;;;28356:16:0;;28352:52;;28381:23;;-1:-1:-1;;;28381:23:0;;;;;;;;;;;28352:52;28497:15;28494:160;;;28637:1;28616:19;28609:30;28494:160;-1:-1:-1;;;;;29032:24:0;;;;;;;:18;:24;;;;;;29030:26;;-1:-1:-1;;29030:26:0;;;29101:22;;;;;;;;;29099:24;;-1:-1:-1;29099:24:0;;;18735:11;18711:22;18707:40;18694:62;-1:-1:-1;;;18694:62:0;29394:26;;;;:17;:26;;;;;:174;-1:-1:-1;;;29688:46:0;;29684:626;;29792:1;29782:11;;29760:19;29915:30;;;:17;:30;;;;;;29911:384;;30053:13;;30038:11;:28;30034:242;;30200:30;;;;:17;:30;;;;;:52;;;30034:242;29741:569;29684:626;30357:7;30353:2;-1:-1:-1;;;;;30338:27:0;30347:4;-1:-1:-1;;;;;30338:27:0;;;;;;;;;;;27805:2568;;;27682:2691;;;:::o;39621:199::-;36468:13;:11;:13::i;:::-;-1:-1:-1;;;;;39713:30:0;::::1;39705:62;;;::::0;-1:-1:-1;;;39705:62:0;;8043:2:1;39705:62:0::1;::::0;::::1;8025:21:1::0;8082:2;8062:18;;;8055:30;-1:-1:-1;;;8101:18:1;;;8094:49;8160:18;;39705:62:0::1;7841:343:1::0;39705:62:0::1;39778:15;:34:::0;;-1:-1:-1;;;;;;39778:34:0::1;-1:-1:-1::0;;;;;39778:34:0;;;::::1;::::0;;;::::1;::::0;;39621:199::o;39313:186::-;36468:13;:11;:13::i;:::-;39371:15:::1;::::0;-1:-1:-1;;;;;39371:15:0::1;39363:61;;;::::0;-1:-1:-1;;;39363:61:0;;8043:2:1;39363:61:0::1;::::0;::::1;8025:21:1::0;8082:2;8062:18;;;8055:30;-1:-1:-1;;;8101:18:1;;;8094:49;8160:18;;39363:61:0::1;7841:343:1::0;39363:61:0::1;39443:15;::::0;39435:56:::1;::::0;-1:-1:-1;;;;;39443:15:0;;::::1;::::0;39469:21:::1;39435:56:::0;::::1;;;::::0;39443:15:::1;39435:56:::0;39443:15;39435:56;39469:21;39443:15;39435:56;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;39313:186::o:0;21928:185::-;22066:39;22083:4;22089:2;22093:7;22066:39;;;;;;;;;;;;:16;:39::i;:::-;21928:185;;;:::o;39507:106::-;36468:13;:11;:13::i;:::-;39584:21;;::::1;::::0;:7:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;18836:152::-:0;18908:7;18951:27;18970:7;18951:18;:27::i;38036:80::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14297:232::-;14369:7;-1:-1:-1;;;;;14393:19:0;;14389:60;;14421:28;;-1:-1:-1;;;14421:28:0;;;;;;;;;;;14389:60;-1:-1:-1;;;;;;14467:25:0;;;;;:18;:25;;;;;;9888:13;14467:54;;14297:232::o;19224:104::-;19280:13;19313:7;19306:14;;;;;:::i;21314:308::-;-1:-1:-1;;;;;21413:31:0;;33673:10;21413:31;21409:61;;;21453:17;;-1:-1:-1;;;21453:17:0;;;;;;;;;;;21409:61;33673:10;21483:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;21483:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;21483:60:0;;;;;;;;;;21559:55;;1968:41:1;;;21483:49:0;;33673:10;21559:55;;1941:18:1;21559:55:0;;;;;;;21314:308;;:::o;22184:399::-;22351:31;22364:4;22370:2;22374:7;22351:12;:31::i;:::-;-1:-1:-1;;;;;22397:14:0;;;:19;22393:183;;22436:56;22467:4;22473:2;22477:7;22486:5;22436:30;:56::i;:::-;22431:145;;22520:40;;-1:-1:-1;;;22520:40:0;;;;;;;;;;;22431:145;22184:399;;;;:::o;19399:327::-;19472:13;19503:16;19511:7;19503;:16::i;:::-;19498:59;;19528:29;;-1:-1:-1;;;19528:29:0;;;;;;;;;;;19498:59;19570:21;19594:10;:8;:10::i;:::-;19570:34;;19628:7;19622:21;19647:1;19622:26;;:96;;;;;;;;;;;;;;;;;19675:7;19684:18;19694:7;19684:9;:18::i;:::-;19658:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19622:96;19615:103;19399:327;-1:-1:-1;;;19399:327:0:o;37035:203::-;36468:13;:11;:13::i;:::-;-1:-1:-1;;;;;37126:22:0;::::1;37118:73;;;;-1:-1:-1::0;;;37118:73:0::1;;;;;;;:::i;:::-;37202:28;37221:8;37202:18;:28::i;23731:689::-:0;23862:19;23868:2;23872:8;23862:5;:19::i;:::-;-1:-1:-1;;;;;23923:14:0;;;:19;23919:483;;23963:11;23977:13;24025:14;;;24058:233;24089:62;24128:1;24132:2;24136:7;;;;;;24145:5;24089:30;:62::i;:::-;24084:167;;24187:40;;-1:-1:-1;;;24187:40:0;;;;;;;;;;;24084:167;24286:3;24278:5;:11;24058:233;;24373:3;24356:13;;:20;24352:34;;24378:8;;;24352:34;23944:458;;23731:689;;;:::o;36747:133::-;36811:8;;-1:-1:-1;;;;;36811:8:0;33673:10;36811:24;36803:69;;;;-1:-1:-1;;;36803:69:0;;9033:2:1;36803:69:0;;;9015:21:1;;;9052:18;;;9045:30;9111:34;9091:18;;;9084:62;9163:18;;36803:69:0;8831:356:1;36803:69:0;36747:133::o;22838:281::-;22903:4;22959:7;12898:1;22940:26;;:66;;;;;22993:13;;22983:7;:23;22940:66;:152;;;;-1:-1:-1;;23044:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;23044:43:0;:48;;22838:281::o;15729:1129::-;15796:7;15831;;12898:1;15880:23;15876:915;;15933:13;;15926:4;:20;15922:869;;;15971:14;15988:23;;;:17;:23;;;;;;-1:-1:-1;;;16077:23:0;;16073:699;;16596:113;16603:11;16596:113;;-1:-1:-1;;;16674:6:0;16656:25;;;;:17;:25;;;;;;16596:113;;16073:699;15948:843;15922:869;16819:31;;-1:-1:-1;;;16819:31:0;;;;;;;;;;;30865:716;31049:88;;-1:-1:-1;;;31049:88:0;;31028:4;;-1:-1:-1;;;;;31049:45:0;;;;;:88;;33673:10;;31116:4;;31122:7;;31131:5;;31049:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31049:88:0;;;;;;;;-1:-1:-1;;31049:88:0;;;;;;;;;;;;:::i;:::-;;;31045:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31332:13:0;;31328:235;;31378:40;;-1:-1:-1;;;31378:40:0;;;;;;;;;;;31328:235;31521:6;31515:13;31506:6;31502:2;31498:15;31491:38;31045:529;-1:-1:-1;;;;;;31208:64:0;-1:-1:-1;;;31208:64:0;;-1:-1:-1;31045:529:0;30865:716;;;;;;:::o;38958:108::-;39018:13;39051:7;39044:14;;;;;:::i;33797:1968::-;34274:4;34268:11;;34281:3;34264:21;;34359:17;;;;35055:11;;;34934:5;35187:2;35201;35191:13;;35183:22;35055:11;35170:36;35242:2;35232:13;;34826:697;35261:4;34826:697;;;35452:1;35447:3;35443:11;35436:18;;35503:2;35497:4;35493:13;35489:2;35485:22;35480:3;35472:36;35356:2;35346:13;;34826:697;;;-1:-1:-1;35553:13:0;;;-1:-1:-1;;35668:12:0;;;35728:19;;;35668:12;33797:1968;-1:-1:-1;33797:1968:0:o;37603:191::-;37696:6;;;-1:-1:-1;;;;;37713:17:0;;;-1:-1:-1;;;;;;37713:17:0;;;;;;;37746:40;;37696:6;;;37713:17;37696:6;;37746:40;;37677:16;;37746:40;37666:128;37603:191;:::o;24693:1392::-;24766:20;24789:13;-1:-1:-1;;;;;24817:16:0;;24813:48;;24842:19;;-1:-1:-1;;;24842:19:0;;;;;;;;;;;24813:48;24876:13;24872:44;;24898:18;;-1:-1:-1;;;24898:18:0;;;;;;;;;;;24872:44;-1:-1:-1;;;;;25330:22:0;;;;;;:18;:22;;10025:2;25330:22;;:70;;25368:31;25356:44;;25330:70;;;18735:11;18711:22;18707:40;-1:-1:-1;20462:15:0;;20437:23;20433:45;18704:51;18694:62;25643:31;;;;:17;:31;;;;;:173;25661:12;25892:23;;;25930:101;25957:35;;25982:9;;;;;-1:-1:-1;;;;;25957:35:0;;;25974:1;;25957:35;;25974:1;;25957:35;26026:3;26016:7;:13;25930:101;;26047:13;:19;-1:-1:-1;;;;24693:1392:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;362:127:1;423:10;418:3;414:20;411:1;404:31;454:4;451:1;444:15;478:4;475:1;468:15;494:225;534:3;565:1;561:6;558:1;555:13;552:136;;;610:10;605:3;601:20;598:1;591:31;645:4;642:1;635:15;673:4;670:1;663:15;552:136;-1:-1:-1;704:9:1;;494:225::o;1073:173::-;1141:20;;-1:-1:-1;;;;;1190:31:1;;1180:42;;1170:70;;1236:1;1233;1226:12;1170:70;1073:173;;;:::o;1251:186::-;1310:6;1363:2;1351:9;1342:7;1338:23;1334:32;1331:52;;;1379:1;1376;1369:12;1331:52;1402:29;1421:9;1402:29;:::i;1442:131::-;-1:-1:-1;;;;;;1516:32:1;;1506:43;;1496:71;;1563:1;1560;1553:12;1578:245;1636:6;1689:2;1677:9;1668:7;1664:23;1660:32;1657:52;;;1705:1;1702;1695:12;1657:52;1744:9;1731:23;1763:30;1787:5;1763:30;:::i;2020:258::-;2092:1;2102:113;2116:6;2113:1;2110:13;2102:113;;;2192:11;;;2186:18;2173:11;;;2166:39;2138:2;2131:10;2102:113;;;2233:6;2230:1;2227:13;2224:48;;;-1:-1:-1;;2268:1:1;2250:16;;2243:27;2020:258::o;2283:::-;2325:3;2363:5;2357:12;2390:6;2385:3;2378:19;2406:63;2462:6;2455:4;2450:3;2446:14;2439:4;2432:5;2428:16;2406:63;:::i;:::-;2523:2;2502:15;-1:-1:-1;;2498:29:1;2489:39;;;;2530:4;2485:50;;2283:258;-1:-1:-1;;2283:258:1:o;2546:220::-;2695:2;2684:9;2677:21;2658:4;2715:45;2756:2;2745:9;2741:18;2733:6;2715:45;:::i;2771:180::-;2830:6;2883:2;2871:9;2862:7;2858:23;2854:32;2851:52;;;2899:1;2896;2889:12;2851:52;-1:-1:-1;2922:23:1;;2771:180;-1:-1:-1;2771:180:1:o;3164:254::-;3232:6;3240;3293:2;3281:9;3272:7;3268:23;3264:32;3261:52;;;3309:1;3306;3299:12;3261:52;3332:29;3351:9;3332:29;:::i;:::-;3322:39;3408:2;3393:18;;;;3380:32;;-1:-1:-1;;;3164:254:1:o;3605:328::-;3682:6;3690;3698;3751:2;3739:9;3730:7;3726:23;3722:32;3719:52;;;3767:1;3764;3757:12;3719:52;3790:29;3809:9;3790:29;:::i;:::-;3780:39;;3838:38;3872:2;3861:9;3857:18;3838:38;:::i;:::-;3828:48;;3923:2;3912:9;3908:18;3895:32;3885:42;;3605:328;;;;;:::o;3938:127::-;3999:10;3994:3;3990:20;3987:1;3980:31;4030:4;4027:1;4020:15;4054:4;4051:1;4044:15;4070:632;4135:5;4165:18;4206:2;4198:6;4195:14;4192:40;;;4212:18;;:::i;:::-;4287:2;4281:9;4255:2;4341:15;;-1:-1:-1;;4337:24:1;;;4363:2;4333:33;4329:42;4317:55;;;4387:18;;;4407:22;;;4384:46;4381:72;;;4433:18;;:::i;:::-;4473:10;4469:2;4462:22;4502:6;4493:15;;4532:6;4524;4517:22;4572:3;4563:6;4558:3;4554:16;4551:25;4548:45;;;4589:1;4586;4579:12;4548:45;4639:6;4634:3;4627:4;4619:6;4615:17;4602:44;4694:1;4687:4;4678:6;4670;4666:19;4662:30;4655:41;;;;4070:632;;;;;:::o;4707:451::-;4776:6;4829:2;4817:9;4808:7;4804:23;4800:32;4797:52;;;4845:1;4842;4835:12;4797:52;4885:9;4872:23;4918:18;4910:6;4907:30;4904:50;;;4950:1;4947;4940:12;4904:50;4973:22;;5026:4;5018:13;;5014:27;-1:-1:-1;5004:55:1;;5055:1;5052;5045:12;5004:55;5078:74;5144:7;5139:2;5126:16;5121:2;5117;5113:11;5078:74;:::i;5163:347::-;5228:6;5236;5289:2;5277:9;5268:7;5264:23;5260:32;5257:52;;;5305:1;5302;5295:12;5257:52;5328:29;5347:9;5328:29;:::i;:::-;5318:39;;5407:2;5396:9;5392:18;5379:32;5454:5;5447:13;5440:21;5433:5;5430:32;5420:60;;5476:1;5473;5466:12;5420:60;5499:5;5489:15;;;5163:347;;;;;:::o;5515:667::-;5610:6;5618;5626;5634;5687:3;5675:9;5666:7;5662:23;5658:33;5655:53;;;5704:1;5701;5694:12;5655:53;5727:29;5746:9;5727:29;:::i;:::-;5717:39;;5775:38;5809:2;5798:9;5794:18;5775:38;:::i;:::-;5765:48;;5860:2;5849:9;5845:18;5832:32;5822:42;;5915:2;5904:9;5900:18;5887:32;5942:18;5934:6;5931:30;5928:50;;;5974:1;5971;5964:12;5928:50;5997:22;;6050:4;6042:13;;6038:27;-1:-1:-1;6028:55:1;;6079:1;6076;6069:12;6028:55;6102:74;6168:7;6163:2;6150:16;6145:2;6141;6137:11;6102:74;:::i;:::-;6092:84;;;5515:667;;;;;;;:::o;6187:260::-;6255:6;6263;6316:2;6304:9;6295:7;6291:23;6287:32;6284:52;;;6332:1;6329;6322:12;6284:52;6355:29;6374:9;6355:29;:::i;:::-;6345:39;;6403:38;6437:2;6426:9;6422:18;6403:38;:::i;:::-;6393:48;;6187:260;;;;;:::o;6835:209::-;6867:1;6893;6883:132;;6937:10;6932:3;6928:20;6925:1;6918:31;6972:4;6969:1;6962:15;7000:4;6997:1;6990:15;6883:132;-1:-1:-1;7029:9:1;;6835:209::o;7049:402::-;7251:2;7233:21;;;7290:2;7270:18;;;7263:30;7329:34;7324:2;7309:18;;7302:62;-1:-1:-1;;;7395:2:1;7380:18;;7373:36;7441:3;7426:19;;7049:402::o;7456:380::-;7535:1;7531:12;;;;7578;;;7599:61;;7653:4;7645:6;7641:17;7631:27;;7599:61;7706:2;7698:6;7695:14;7675:18;7672:38;7669:161;;;7752:10;7747:3;7743:20;7740:1;7733:31;7787:4;7784:1;7777:15;7815:4;7812:1;7805:15;7669:161;;7456:380;;;:::o;8189:637::-;8469:3;8507:6;8501:13;8523:53;8569:6;8564:3;8557:4;8549:6;8545:17;8523:53;:::i;:::-;8639:13;;8598:16;;;;8661:57;8639:13;8598:16;8695:4;8683:17;;8661:57;:::i;:::-;-1:-1:-1;;;8740:20:1;;8769:22;;;8818:1;8807:13;;8189:637;-1:-1:-1;;;;8189:637:1:o;9192:489::-;-1:-1:-1;;;;;9461:15:1;;;9443:34;;9513:15;;9508:2;9493:18;;9486:43;9560:2;9545:18;;9538:34;;;9608:3;9603:2;9588:18;;9581:31;;;9386:4;;9629:46;;9655:19;;9647:6;9629:46;:::i;:::-;9621:54;9192:489;-1:-1:-1;;;;;;9192:489:1:o;9686:249::-;9755:6;9808:2;9796:9;9787:7;9783:23;9779:32;9776:52;;;9824:1;9821;9814:12;9776:52;9856:9;9850:16;9875:30;9899:5;9875:30;:::i

Swarm Source

ipfs://0b6e28da42512e1aca097027e2669a5b0699e555eff3f94092177b458ac4a2f4
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.