ETH Price: $3,384.36 (+0.55%)

XPON (XPON)
 

Overview

TokenID

41

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

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

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

Contract Source Code Verified (Exact Match)

Contract Name:
XPON

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion, MIT license
File 1 of 1 : new_token.sol
/*
https://twitter.com/Xpokemon_tech
https://t.me/Xpokemon_tech
https://xpokemon.tech/
*/

// SPDX-License-Identifier: MIT

pragma solidity 0.8.23;

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

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

/**
 * @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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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 {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _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);
    }
}

interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

interface IERC20Metadata is IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
}

interface IERC20Errors {
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
    error ERC20InvalidSender(address sender);
    error ERC20InvalidReceiver(address receiver);
    error ERC20TransferYourself(address receiver);
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
    error ERC20InvalidApprover(address approver);
    error ERC20InvalidSpender(address spender);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

    /**
     * Cannot burn from the zero address.
     */
    error BurnFromZeroAddress();

    /**
     * Cannot burn from the address that doesn't owne the token.
     */
    error BurnFromNonOnwerAddress();

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

    /**
     * The token must be owned by `from` or the `amount` is not 1.
     */
    error TransferFromIncorrectOwnerOrInvalidAmount();

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

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

    /**
     * The length of input arraies is not matching.
     */
    error InputLengthMistmatch();

    function isOwnerOf(address account, uint256 id) external view returns(bool);
}

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

/**
 * @dev Interface that must be implemented by smart contracts in order to receive
 * ERC-1155 token transfers.
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

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


abstract contract ERC721Receiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721Receiver.onERC721Received.selector;
    }
}

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

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

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

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

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

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

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

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

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

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

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

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


/// @notice Library for bit twiddling and boolean operations.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBit.sol)
/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html)
library LibBit {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  BIT TWIDDLING OPERATIONS                  */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Find last set.
    /// Returns the index of the most significant bit of `x`,
    /// counting from the least significant bit position.
    /// If `x` is zero, returns 256.
    function fls(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, x)))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            // forgefmt: disable-next-item
            r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
                0x0706060506020504060203020504030106050205030304010505030400000000))
        }
    }

    /// @dev Count leading zeros.
    /// Returns the number of zeros preceding the most significant one bit.
    /// If `x` is zero, returns 256.
    function clz(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
            r := or(r, shl(4, lt(0xffff, shr(r, x))))
            r := or(r, shl(3, lt(0xff, shr(r, x))))
            // forgefmt: disable-next-item
            r := add(xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
                0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff)), iszero(x))
        }
    }

    /// @dev Find first set.
    /// Returns the index of the least significant bit of `x`,
    /// counting from the least significant bit position.
    /// If `x` is zero, returns 256.
    /// Equivalent to `ctz` (count trailing zeros), which gives
    /// the number of zeros following the least significant one bit.
    function ffs(uint256 x) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Isolate the least significant bit.
            let b := and(x, add(not(x), 1))

            r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, b)))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, b))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, b))))

            // For the remaining 32 bits, use a De Bruijn lookup.
            // forgefmt: disable-next-item
            r := or(r, byte(and(div(0xd76453e0, shr(r, b)), 0x1f),
                0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405))
        }
    }

    /// @dev Returns the number of set bits in `x`.
    function popCount(uint256 x) internal pure returns (uint256 c) {
        /// @solidity memory-safe-assembly
        assembly {
            let max := not(0)
            let isMax := eq(x, max)
            x := sub(x, and(shr(1, x), div(max, 3)))
            x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5)))
            x := and(add(x, shr(4, x)), div(max, 17))
            c := or(shl(8, isMax), shr(248, mul(x, div(max, 255))))
        }
    }

    /// @dev Returns whether `x` is a power of 2.
    function isPo2(uint256 x) internal pure returns (bool result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to `x && !(x & (x - 1))`.
            result := iszero(add(and(x, sub(x, 1)), iszero(x)))
        }
    }

    /// @dev Returns `x` reversed at the bit level.
    function reverseBits(uint256 x) internal pure returns (uint256 r) {
        uint256 m0 = 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f;
        uint256 m1 = m0 ^ (m0 << 2);
        uint256 m2 = m1 ^ (m1 << 1);
        r = reverseBytes(x);
        r = (m2 & (r >> 1)) | ((m2 & r) << 1);
        r = (m1 & (r >> 2)) | ((m1 & r) << 2);
        r = (m0 & (r >> 4)) | ((m0 & r) << 4);
    }

    /// @dev Returns `x` reversed at the byte level.
    function reverseBytes(uint256 x) internal pure returns (uint256 r) {
        unchecked {
            // Computing masks on-the-fly reduces bytecode size by about 200 bytes.
            uint256 m0 = 0x100000000000000000000000000000001 * (~toUint(x == 0) >> 192);
            uint256 m1 = m0 ^ (m0 << 32);
            uint256 m2 = m1 ^ (m1 << 16);
            uint256 m3 = m2 ^ (m2 << 8);
            r = (m3 & (x >> 8)) | ((m3 & x) << 8);
            r = (m2 & (r >> 16)) | ((m2 & r) << 16);
            r = (m1 & (r >> 32)) | ((m1 & r) << 32);
            r = (m0 & (r >> 64)) | ((m0 & r) << 64);
            r = (r >> 128) | (r << 128);
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     BOOLEAN OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // A Solidity bool on the stack or memory is represented as a 256-bit word.
    // Non-zero values are true, zero is false.
    // A clean bool is either 0 (false) or 1 (true) under the hood.
    // Usually, if not always, the bool result of a regular Solidity expression,
    // or the argument of a public/external function will be a clean bool.
    // You can usually use the raw variants for more performance.
    // If uncertain, test (best with exact compiler settings).
    // Or use the non-raw variants (compiler can sometimes optimize out the double `iszero`s).

    /// @dev Returns `x & y`. Inputs must be clean.
    function rawAnd(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := and(x, y)
        }
    }

    /// @dev Returns `x & y`.
    function and(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := and(iszero(iszero(x)), iszero(iszero(y)))
        }
    }

    /// @dev Returns `x | y`. Inputs must be clean.
    function rawOr(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := or(x, y)
        }
    }

    /// @dev Returns `x | y`.
    function or(bool x, bool y) internal pure returns (bool z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := or(iszero(iszero(x)), iszero(iszero(y)))
        }
    }

    /// @dev Returns 1 if `b` is true, else 0. Input must be clean.
    function rawToUint(bool b) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := b
        }
    }

    /// @dev Returns 1 if `b` is true, else 0.
    function toUint(bool b) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            z := iszero(iszero(b))
        }
    }
}

/// @notice Library for storage of packed unsigned booleans.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibBitmap.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibBitmap.sol)
/// @author Modified from Solidity-Bits (https://github.com/estarriolvetch/solidity-bits/blob/main/contracts/BitMaps.sol)
library LibBitmap {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The constant returned when a bitmap scan does not find a result.
    uint256 internal constant NOT_FOUND = type(uint256).max;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STRUCTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev A bitmap in storage.
    struct Bitmap {
        mapping(uint256 => uint256) map;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         OPERATIONS                         */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the boolean value of the bit at `index` in `bitmap`.
    function get(Bitmap storage bitmap, uint256 index) internal view returns (bool isSet) {
        // It is better to set `isSet` to either 0 or 1, than zero vs non-zero.
        // Both cost the same amount of gas, but the former allows the returned value
        // to be reused without cleaning the upper bits.
        uint256 b = (bitmap.map[index >> 8] >> (index & 0xff)) & 1;
        /// @solidity memory-safe-assembly
        assembly {
            isSet := b
        }
    }

    /// @dev Updates the bit at `index` in `bitmap` to true.
    function set(Bitmap storage bitmap, uint256 index) internal {
        bitmap.map[index >> 8] |= (1 << (index & 0xff));
    }

    /// @dev Updates the bit at `index` in `bitmap` to false.
    function unset(Bitmap storage bitmap, uint256 index) internal {
        bitmap.map[index >> 8] &= ~(1 << (index & 0xff));
    }

    /// @dev Flips the bit at `index` in `bitmap`.
    /// Returns the boolean result of the flipped bit.
    function toggle(Bitmap storage bitmap, uint256 index) internal returns (bool newIsSet) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, index))
            let storageSlot := keccak256(0x00, 0x40)
            let shift := and(index, 0xff)
            let storageValue := xor(sload(storageSlot), shl(shift, 1))
            // It makes sense to return the `newIsSet`,
            // as it allow us to skip an additional warm `sload`,
            // and it costs minimal gas (about 15),
            // which may be optimized away if the returned value is unused.
            newIsSet := and(1, shr(shift, storageValue))
            sstore(storageSlot, storageValue)
        }
    }

    /// @dev Updates the bit at `index` in `bitmap` to `shouldSet`.
    function setTo(Bitmap storage bitmap, uint256 index, bool shouldSet) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, index))
            let storageSlot := keccak256(0x00, 0x40)
            let storageValue := sload(storageSlot)
            let shift := and(index, 0xff)
            sstore(
                storageSlot,
                // Unsets the bit at `shift` via `and`, then sets its new value via `or`.
                or(and(storageValue, not(shl(shift, 1))), shl(shift, iszero(iszero(shouldSet))))
            )
        }
    }

    /// @dev Consecutively sets `amount` of bits starting from the bit at `start`.
    function setBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let max := not(0)
            let shift := and(start, 0xff)
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, start))
            if iszero(lt(add(shift, amount), 257)) {
                let storageSlot := keccak256(0x00, 0x40)
                sstore(storageSlot, or(sload(storageSlot), shl(shift, max)))
                let bucket := add(mload(0x00), 1)
                let bucketEnd := add(mload(0x00), shr(8, add(amount, shift)))
                amount := and(add(amount, shift), 0xff)
                shift := 0
                for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } {
                    mstore(0x00, bucket)
                    sstore(keccak256(0x00, 0x40), max)
                }
                mstore(0x00, bucket)
            }
            let storageSlot := keccak256(0x00, 0x40)
            sstore(storageSlot, or(sload(storageSlot), shl(shift, shr(sub(256, amount), max))))
        }
    }

    /// @dev Consecutively unsets `amount` of bits starting from the bit at `start`.
    function unsetBatch(Bitmap storage bitmap, uint256 start, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let shift := and(start, 0xff)
            mstore(0x20, bitmap.slot)
            mstore(0x00, shr(8, start))
            if iszero(lt(add(shift, amount), 257)) {
                let storageSlot := keccak256(0x00, 0x40)
                sstore(storageSlot, and(sload(storageSlot), not(shl(shift, not(0)))))
                let bucket := add(mload(0x00), 1)
                let bucketEnd := add(mload(0x00), shr(8, add(amount, shift)))
                amount := and(add(amount, shift), 0xff)
                shift := 0
                for {} iszero(eq(bucket, bucketEnd)) { bucket := add(bucket, 1) } {
                    mstore(0x00, bucket)
                    sstore(keccak256(0x00, 0x40), 0)
                }
                mstore(0x00, bucket)
            }
            let storageSlot := keccak256(0x00, 0x40)
            sstore(
                storageSlot, and(sload(storageSlot), not(shl(shift, shr(sub(256, amount), not(0)))))
            )
        }
    }

    /// @dev Returns number of set bits within a range by
    /// scanning `amount` of bits starting from the bit at `start`.
    function popCount(Bitmap storage bitmap, uint256 start, uint256 amount)
        internal
        view
        returns (uint256 count)
    {
        unchecked {
            uint256 bucket = start >> 8;
            uint256 shift = start & 0xff;
            if (!(amount + shift < 257)) {
                count = LibBit.popCount(bitmap.map[bucket] >> shift);
                uint256 bucketEnd = bucket + ((amount + shift) >> 8);
                amount = (amount + shift) & 0xff;
                shift = 0;
                for (++bucket; bucket != bucketEnd; ++bucket) {
                    count += LibBit.popCount(bitmap.map[bucket]);
                }
            }
            count += LibBit.popCount((bitmap.map[bucket] >> shift) << (256 - amount));
        }
    }

    /// @dev Returns the index of the most significant set bit before the bit at `before`.
    /// If no set bit is found, returns `NOT_FOUND`.
    function findLastSet(Bitmap storage bitmap, uint256 before)
        internal
        view
        returns (uint256 setBitIndex)
    {
        uint256 bucket;
        uint256 bucketBits;
        /// @solidity memory-safe-assembly
        assembly {
            setBitIndex := not(0)
            bucket := shr(8, before)
            mstore(0x00, bucket)
            mstore(0x20, bitmap.slot)
            let offset := and(0xff, not(before)) // `256 - (255 & before) - 1`.
            bucketBits := shr(offset, shl(offset, sload(keccak256(0x00, 0x40))))
            if iszero(or(bucketBits, iszero(bucket))) {
                for {} 1 {} {
                    bucket := add(bucket, setBitIndex) // `sub(bucket, 1)`.
                    mstore(0x00, bucket)
                    bucketBits := sload(keccak256(0x00, 0x40))
                    if or(bucketBits, iszero(bucket)) { break }
                }
            }
        }
        if (bucketBits != 0) {
            setBitIndex = (bucket << 8) | LibBit.fls(bucketBits);
            /// @solidity memory-safe-assembly
            assembly {
                setBitIndex := or(setBitIndex, sub(0, gt(setBitIndex, before)))
            }
        }
    }
}

contract ERC5588 is Context, ERC165, IERC1155, IERC1155MetadataURI, IERCX, IERC20Metadata, IERC20Errors, Ownable {

    using Address for address;
    using LibBitmap for LibBitmap.Bitmap;

    error InvalidQueryRange();

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // Mapping from accout to owned tokens
    mapping(address => LibBitmap.Bitmap) internal _owned;

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

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

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

    // NFT Approval
    mapping(uint256 => address) public getApproved;

    //Token balances
    mapping(address => uint256) internal _balances;

    //Token allowances
    mapping(address account => mapping(address spender => uint256)) private _allowances;

    // Token name
    string public name;

    // Token symbol
    string public symbol;

    // Decimals for supply
    uint8 public immutable decimals;

    // Total ERC20 supply
    uint256 public immutable totalSupply;

    // Tokens Per NFT
    uint256 public immutable decimalFactor;
    uint256 public immutable tokensPerNFT;

    // Don't mint for these wallets
    mapping(address => bool) public whitelist;

    struct PokemonInfo {
        uint level; // level of pokemon
        uint power; // power of pokemon
        uint pkmType; // type of pokemon
        bytes extendData;
    }

    uint8[] private types;
    uint256[] private rarityThresholds;

    mapping(uint256 => PokemonInfo) public pokemonInfo;

    bool private initialized = false;

    // Easy Launch - auto-whitelist first transfer which is probably the LP
    uint256 public easyLaunch = 2;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_, string memory _name, string memory _symbol, uint8 _decimals, uint256 _totalNativeSupply, uint256 _tokensPerNFT) Ownable(msg.sender) {
        _setURI(uri_);
        _currentIndex = _startTokenId();
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        decimalFactor = 10 ** decimals;
        tokensPerNFT = _tokensPerNFT * decimalFactor;
        totalSupply = _totalNativeSupply * decimalFactor;
        whitelist[msg.sender] = true;
        _balances[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);
    }

    /** @notice Initialization function to set pairs / etc
     *  saving gas by avoiding mint / burn on unnecessary targets
     */
    function setWhitelist(address target, bool state) public virtual onlyOwner {
        whitelist[target] = state;
    }

    function initializeTypesAndRarities() public onlyOwner {
        require(!initialized, "Already initialized.");

        types = [0, 1, 2, 3, 4];

        rarityThresholds = [5500, 3000, 1000, 450, 50];

        initialized = true;
    }


    function _getRandomType(
        uint256 _randomNumber
    ) private view returns (uint8) {
        uint256 rand = _randomNumber % 10000;
        uint256 cumulative = 0;
        for (uint8 i = 0; i < rarityThresholds.length; i++) {
            cumulative += rarityThresholds[i];
            if (rand < cumulative) {
                return types[i];
            }
        }
        return types[types.length - 1];
    }

    function _pseudoRandomNumber(
        uint256 _salt
    ) private view returns (uint256) {
        uint256 _seed = uint256(
            keccak256(
                abi.encodePacked(
                    (block.timestamp),
                    block.gaslimit,
                    blockhash(block.number - 1),
                    blockhash(block.number - 100),
                    block.coinbase,
                    tx.origin,
                    _salt
                )
            )
        );
        return _seed;

    }

    function getRandomTypeForMint(
        uint256 _nonce
    ) internal view returns (uint8) {
        uint256 randomNumber = _pseudoRandomNumber(_nonce);
        return _getRandomType(randomNumber);
    }

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

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

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        return _nextTokenId() - _startTokenId();
    }

    /**
     * @dev Returns true if the account owns the `id` token.
     */
    function isOwnerOf(address account, uint256 id) public view virtual override returns(bool) {
        return _owned[account].get(id);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC1155).interfaceId ||
            interfaceId == type(IERC1155MetadataURI).interfaceId ||
            interfaceId == type(IERCX).interfaceId ||
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f || // ERC165 interface ID for ERC721Metadata.
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev Returns the number of tokens owned by `owner`.
     */
    function balanceOf(address owner) public view virtual returns (uint256) {
        return _balances[owner];
    }

    /**
     * @dev Returns the number of nfts owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function balanceOf(address owner, uint256 start, uint256 stop) public view virtual returns (uint256) {
        return _owned[owner].popCount(start, stop - start);
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        if(account == address(0)) {
            revert BalanceQueryForZeroAddress();
        }
        if(_owned[account].get(id)) {
            return 1;
        } else {
            return 0;
        }
    }

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

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

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        if(from == _msgSender() || isApprovedForAll(from, _msgSender())){
            _safeTransferFrom(from, to, id, amount, data, true);
        } else {
            revert TransferCallerNotOwnerNorApproved();
        }
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        if(!(from == _msgSender() || isApprovedForAll(from, _msgSender()))) {
            revert TransferCallerNotOwnerNorApproved();
        }
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `amount` cannot be zero.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data,
        bool check
    ) internal virtual {
        if(to == address(0)) {
            revert TransferToZeroAddress();
        }

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);

        _beforeTokenTransfer(operator, from, to, ids);

        if(amount == 1 && _owned[from].get(id)) {
            _owned[from].unset(id);
            _owned[to].set(id);
            _transfer(from, to, tokensPerNFT, false);
        } else {
            revert TransferFromIncorrectOwnerOrInvalidAmount();
        }

        uint256 toMasked;
        uint256 fromMasked;
        assembly {
            // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
            toMasked := and(to, _BITMASK_ADDRESS)
            fromMasked := and(from, _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.
                fromMasked, // `from`.
                toMasked, // `to`.
                amount // `tokenId`.
            )
        }

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

        _afterTokenTransfer(operator, from, to, ids);

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

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        if(ids.length != amounts.length) {
            revert InputLengthMistmatch();
        }

        if(to == address(0)) {
            revert TransferToZeroAddress();
        }
        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            if(amount == 1 && _owned[from].get(id)) {
                _owned[from].unset(id);
                _owned[to].set(id);
            } else {
                revert TransferFromIncorrectOwnerOrInvalidAmount();
            }
        }
        _transfer(from, to, tokensPerNFT * ids.length, false);

        uint256 toMasked;
        uint256 fromMasked;
        uint256 end = ids.length + 1;

        // 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.
            fromMasked := and(from, _BITMASK_ADDRESS)
            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.
                fromMasked, // `from`.
                toMasked, // `to`.
                mload(add(ids, 0x20)) // `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 arrayId := 2
            } iszero(eq(arrayId, end)) {
                arrayId := add(arrayId, 1)
            } {
                // Emit the `Transfer` event. Similar to above.
                log4(0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, toMasked, mload(add(ids, mul(0x20, arrayId))))
            }
        }

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

        _afterTokenTransfer(operator, from, to, ids);

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

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

    function _mint(
        address to,
        uint256 amount
    ) internal virtual {
        _mint(to, amount, "");
    }

    /**
     * @dev Creates `amount` tokens, and assigns them to `to`.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `amount` cannot be zero.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address to,
        uint256 amount,
        bytes memory data
    ) internal virtual {
       (uint256[] memory ids, uint256[] memory amounts) =  _mintWithoutCheck(to, amount);

        uint256 end = _currentIndex;
        _doSafeBatchTransferAcceptanceCheck(_msgSender(), address(0), to, ids, amounts, data);
        if (_currentIndex != end) revert();
    }

    function _mintWithoutCheck(
        address to,
        uint256 amount
    ) internal virtual returns(uint256[] memory ids, uint256[] memory amounts) {

        if(to == address(0)) {
            revert MintToZeroAddress();
        }
        if(amount == 0) {
            revert MintZeroQuantity();
        }

        address operator = _msgSender();

        ids = new uint256[](amount);
        amounts = new uint256[](amount);
        uint256 startTokenId = _nextTokenId();

        unchecked {
            require(type(uint256).max - amount >= startTokenId);
            for(uint256 i = 0; i < amount; i++) {
                ids[i] = startTokenId + i;
                amounts[i] = 1;
            }
        }

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

        _owned[to].setBatch(startTokenId, amount);
        _currentIndex += amount;

        uint256 toMasked;
        uint256 end = startTokenId + amount;

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

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

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

        _afterTokenTransfer(operator, address(0), to, ids);

    }

    /**
     * @dev Destroys token of token type `id` from `from`
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have the token of token type `id`.
     */
    function _burn(
        address from,
        uint256 id
    ) internal virtual {
        if(from == address(0)){
            revert BurnFromZeroAddress();
        }

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);

        _beforeTokenTransfer(operator, from, address(0), ids);

        if(!_owned[from].get(id)) {
            revert BurnFromNonOnwerAddress();
        }

        _owned[from].unset(id);

        uint256 fromMasked;
        assembly {
            fromMasked := and(from, _BITMASK_ADDRESS)
            log4(
                0,
                0,
                _TRANSFER_EVENT_SIGNATURE,
                fromMasked,
                0,
                id
            )
        }

        emit TransferSingle(operator, from, address(0), id, 1);

        _afterTokenTransfer(operator, from, address(0), ids);
    }

    function _burnBatch(
        address from,
        uint256 amount
    ) internal virtual returns (uint256[] memory) {
        if(from == address(0)){
            revert BurnFromZeroAddress();
        }

        address operator = _msgSender();

        uint256 searchFrom = _nextTokenId();

        uint256[] memory amounts = new uint256[](amount);
        uint256[] memory ids = new uint256[](amount);

        unchecked {
            for(uint256 i = 0; i < amount; i++) {
                amounts[i] = 1;
                uint256 id = _owned[from].findLastSet(searchFrom);
                ids[i] = id;
                _owned[from].unset(id);
                searchFrom = id;
            }
        }

        //technically after, but we didn't have the IDs then
        _beforeTokenTransfer(operator, from, address(0), ids);

        uint256 fromMasked;
        uint256 end = amount + 1;

        assembly {
            fromMasked := and(from, _BITMASK_ADDRESS)
            log4(
                0,
                0,
                _TRANSFER_EVENT_SIGNATURE,
                fromMasked,
                0,
                mload(add(ids, 0x20))
            )

            for {
                let arrayId := 2
            } iszero(eq(arrayId, end)) {
                arrayId := add(arrayId, 1)
            } {
                log4(0, 0, _TRANSFER_EVENT_SIGNATURE, fromMasked, 0, mload(add(ids, mul(0x20, arrayId))))
            }
        }

        if(amount == 1)
            emit TransferSingle(operator, from, address(0), ids[0], 1);
        else
            emit TransferBatch(operator, from, address(0), ids, amounts);


        _afterTokenTransfer(operator, from, address(0), ids);

        return ids;
    }


     /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

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

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

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            if (IERC165(to).supportsInterface(type(IERC1155).interfaceId)) {
                try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                    if (response != IERC1155Receiver.onERC1155Received.selector) {
                        revert TransferToNonERC1155ReceiverImplementer();
                    }
                } catch Error(string memory reason) {
                    revert(reason);
                } catch {
                    revert TransferToNonERC1155ReceiverImplementer();
                }
            }
            else {
                try ERC721Receiver(to).onERC721Received(operator, from, id, data) returns (bytes4 response) {
                    if (response != ERC721Receiver.onERC721Received.selector) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } catch Error(string memory reason) {
                    revert(reason);
                } catch {
                    revert TransferToNonERC721ReceiverImplementer();
                }
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert TransferToNonERC1155ReceiverImplementer();
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert TransferToNonERC1155ReceiverImplementer();
            }
        }
    }

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

    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = msg.sender;
        _transfer(owner, to, value, true);
        return true;
    }

    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = msg.sender;
        if (value < _nextTokenId() && value > 0) {

            if(!isOwnerOf(owner, value)) {
                revert ERC20InvalidSender(owner);
            }

            getApproved[value] = spender;

            emit Approval(owner, spender, value);
        } else {
            _approve(owner, spender, value);
        }
        return true;
    }

    /// @notice Function for mixed transfers
    /// @dev This function assumes id / native if amount less than or equal to current max id
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        if (value < _nextTokenId()) {
            if(!_owned[from].get(value)) {
                revert ERC20InvalidSpender(from);
            }

            if (
                msg.sender != from &&
                !isApprovedForAll(from, msg.sender) &&
                msg.sender != getApproved[value]
            ) {
                revert ERC20InvalidSpender(msg.sender);
            }

            delete getApproved[value];

            _safeTransferFrom(from, to, value, 1, "", false);

        } else {
            _spendAllowance(from, msg.sender, value);
            _transfer(from, to, value, true);
        }
        return true;
    }

    function _transfer(address from, address to, uint256 value, bool mint) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        if(from == to) {
            revert ERC20TransferYourself(from);
        }
        _update(from, to, value, mint);
    }

    function _update(address from, address to, uint256 value, bool mint) internal virtual {
        uint256 fromBalance = _balances[from];
        uint256 toBalance = _balances[to];
        if (fromBalance < value) {
            revert ERC20InsufficientBalance(from, fromBalance, value);
        }
        unchecked {
            if(from == to) {
                _balances[to] = fromBalance;
            } else {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;

                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] = toBalance + value;
            }
        }

        emit Transfer(from, to, value);

        if(mint) {
            // Skip burn for certain addresses to save gas
            bool wlf = whitelist[from];
            uint256[] memory ids_burn;
            uint256[] memory ids_mint;
            uint256 tokens_to_burn;
            uint256 tokens_to_mint;

            if (!wlf) {
                tokens_to_burn = (fromBalance / tokensPerNFT) - ((fromBalance - value) / tokensPerNFT);
                if(tokens_to_burn > 0)
                    ids_burn = _burnBatch(from, tokens_to_burn);
            }

            // Skip minting for certain addresses to save gas
            if (!whitelist[to]) {
                if(easyLaunch == 1 && wlf && from == owner()) {
                    //auto-initialize first (assumed) LP
                    whitelist[to] = true;
                    easyLaunch = 2;
                } else {
                    tokens_to_mint = ((toBalance + value) / tokensPerNFT) - (toBalance / tokensPerNFT);
                    if(tokens_to_mint > 0)
                        (ids_mint,) = _mintWithoutCheck(to, tokens_to_mint);
                }
            }

            _update_data_nft(ids_burn, ids_mint, tokens_to_burn, tokens_to_mint);
        }
    }

    function _update_data_nft(
        uint256[] memory ids_burn,
        uint256[] memory ids_mint,
        uint256 tokens_to_burn,
        uint256 tokens_to_mint
    ) internal {
        if (tokens_to_mint == 0) return;

        if (tokens_to_burn == 0) {
            for (uint i = 0; i < ids_mint.length; i++) {
                uint256 id = ids_mint[i];
                uint8 nftType = getRandomTypeForMint(id);

                pokemonInfo[id].pkmType = nftType;
                pokemonInfo[id].power = 10000;
                pokemonInfo[id].level = 0;
                pokemonInfo[id].extendData = new bytes(0);
            }
            return;
        }

        for (uint i = 0; i < ids_mint.length; i++) {
            uint256 id_mint = ids_mint[i];

            // Case tokens_to_burn == tokens_to_mint
            // Case tokens_to_burn > tokens_to_mint (skip last token)
            if (i < ids_burn.length) {
                uint256 id_burn = ids_burn[i];
                pokemonInfo[id_mint].pkmType = pokemonInfo[id_burn].pkmType;
                pokemonInfo[id_mint].power = pokemonInfo[id_burn].power;
                pokemonInfo[id_mint].level = pokemonInfo[id_burn].level;
                pokemonInfo[id_mint].extendData = pokemonInfo[id_burn].extendData;
            }
            else {
                // Bonus case tokens_to_burn < tokens_to_mint
                uint8 nftType = getRandomTypeForMint(id_mint);
                pokemonInfo[id_mint].pkmType = nftType;
                pokemonInfo[id_mint].power = 10000;
                pokemonInfo[id_mint].level = 0;
                pokemonInfo[id_mint].extendData = new bytes(0);
            }
        }
    }

    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC1155DelataQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start < stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) public view virtual returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();


            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }

            // Set `stop = min(stop, stopLimit)`.
            uint256 stopLimit = _nextTokenId();
            if (stop > stopLimit) {
                stop = stopLimit;
            }

            uint256 tokenIdsLength;
            if(start < stop) {
                tokenIdsLength = balanceOf(owner, start, stop);
            } else {
                tokenIdsLength = 0;
            }

            uint256[] memory tokenIds = new uint256[](tokenIdsLength);

            LibBitmap.Bitmap storage bmap = _owned[owner];

            for ((uint256 i, uint256 tokenIdsIdx) = (start, 0); tokenIdsIdx != tokenIdsLength; ++i) {
                if(bmap.get(i) ) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC1155DeltaQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K collections should be fine).
     */
    function tokensOfOwner(address owner) public view virtual returns (uint256[] memory) {
        if(_totalMinted() == 0) {
            return new uint256[](0);
        }
        return tokensOfOwnerIn(owner, _startTokenId(), _nextTokenId());
    }

    function getPokemon(
        uint256 tokenId
    ) public view returns (uint256 type_, uint256 level_, uint256 power_, bytes memory data_) {
        return (pokemonInfo[tokenId].pkmType, pokemonInfo[tokenId].level, pokemonInfo[tokenId].power, pokemonInfo[tokenId].extendData);
    }

    function _setNameSymbol(
        string memory _name,
        string memory _symbol
    ) internal {
        name = _name;
        symbol = _symbol;
    }

    function _handlePokemonGame(
        uint256 pkmId_,
        uint256 level_,
        uint256 power_,
        bytes memory data_
    ) internal {
        PokemonInfo storage _pkm = pokemonInfo[pkmId_];
        _pkm.level = level_;
        _pkm.power = power_;
        _pkm.extendData = data_;
    }

}

contract XPON is ERC5588 {
    using Strings for uint256;
    string public dataURI;
    string public baseTokenURI;
    mapping(address => bool) public gameOperators;

    uint8 private constant _decimals = 18;
    uint256 private constant _totalTokens = 50000;
    uint256 private constant _tokensPerNFT = 1;
    string private constant _name = "XPON";
    string private constant _ticker = "XPON";

    // Snipe reduction tools
    uint256 public maxWallet;
    bool public transferDelay = true;
    mapping (address => uint256) private delayTimer;

    constructor() ERC5588("", _name, _ticker, _decimals, _totalTokens, _tokensPerNFT) {
        dataURI = "";
        maxWallet = (_totalTokens * 10 ** _decimals) * 2 / 100;
    }

    function toggleDelay() external onlyOwner {
        transferDelay = !transferDelay;
    }

    function setMaxWallet(uint256 percent) external onlyOwner {
        maxWallet = totalSupply * percent / 100;
    }

    function setDataURI(string memory _dataURI) public onlyOwner {
        dataURI = _dataURI;
    }

    function setTokenURI(string memory _tokenURI) public onlyOwner {
        baseTokenURI = _tokenURI;
    }

    function setURI(string memory newuri) external onlyOwner {
        _setURI(newuri);
    }

    function tokenURI(uint256 id) public view returns (string memory) {
        if(id >= _nextTokenId()) revert InputLengthMistmatch();

        if (bytes(baseTokenURI).length > 0) {
            uint pkmType = pokemonInfo[id].pkmType;
            uint level = 0;

            if (pokemonInfo[id].level >= 4 && pokemonInfo[id].level < 6) level = 1;
            else if (pokemonInfo[id].level >= 6 && pokemonInfo[id].level < 8) level = 2;
            else if (pokemonInfo[id].level >= 8) level = 3;

            return string(abi.encodePacked(baseTokenURI, pkmType.toString(), "_", level.toString(),".json"));
        }

        else return "";

    }

    function uri(uint256 id) public view override returns (string memory) {
        return tokenURI(id);
    }

    function updateGameOperator(address operator_, bool status_) external onlyOwner {
        gameOperators[operator_] = status_;
    }

    modifier onlyOperator() {
        require(gameOperators[msg.sender], "XPON: only operator");
        _;
    }

    function updatePokemon(
        uint256 pkmId_,
        uint256 level_,
        uint256 power_,
        bytes memory data_
    ) external onlyOperator {
        _handlePokemonGame(pkmId_, level_, power_, data_);
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"BurnFromNonOnwerAddress","type":"error"},{"inputs":[],"name":"BurnFromZeroAddress","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20TransferYourself","type":"error"},{"inputs":[],"name":"InputLengthMistmatch","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwnerOrInvalidAmount","type":"error"},{"inputs":[],"name":"TransferToNonERC1155ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"easyLaunch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gameOperators","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getPokemon","outputs":[{"internalType":"uint256","name":"type_","type":"uint256"},{"internalType":"uint256","name":"level_","type":"uint256"},{"internalType":"uint256","name":"power_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initializeTypesAndRarities","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"isOwnerOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWallet","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":"","type":"uint256"}],"name":"pokemonInfo","outputs":[{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"uint256","name":"pkmType","type":"uint256"},{"internalType":"bytes","name":"extendData","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_dataURI","type":"string"}],"name":"setDataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"percent","type":"uint256"}],"name":"setMaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setWhitelist","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":[],"name":"toggleDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","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":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensPerNFT","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":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferDelay","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":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator_","type":"address"},{"internalType":"bool","name":"status_","type":"bool"}],"name":"updateGameOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pkmId_","type":"uint256"},{"internalType":"uint256","name":"level_","type":"uint256"},{"internalType":"uint256","name":"power_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"updatePokemon","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

610100604052600e805460ff199081169091556002600f556014805490911660011790553480156200003057600080fd5b50604080516020808201835260008252825180840184526004808252632c2827a760e11b8284018190528551808701909652908552918401919091529091601261c350600133806200009c57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b620000a781620001d5565b50620000b38662000225565b60016004556008620000c68682620002de565b506009620000d58582620002de565b5060ff83166080819052620000ec90600a620004bf565b60c0819052620000fd9082620004d7565b60e05260c0516200010f9083620004d7565b60a0819052336000818152600a60209081526040808320805460ff191660011790556006825280832085905551938452919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050505050506040518060200160405280600081525060109081620001949190620002de565b506064620001a56012600a620004bf565b620001b39061c350620004d7565b620001c0906002620004d7565b620001cc9190620004f1565b60135562000514565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6003620002338282620002de565b5050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200026257607f821691505b6020821081036200028357634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620002d9576000816000526020600020601f850160051c81016020861015620002b45750805b601f850160051c820191505b81811015620002d557828155600101620002c0565b5050505b505050565b81516001600160401b03811115620002fa57620002fa62000237565b62000312816200030b84546200024d565b8462000289565b602080601f8311600181146200034a5760008415620003315750858301515b600019600386901b1c1916600185901b178555620002d5565b600085815260208120601f198616915b828110156200037b578886015182559484019460019091019084016200035a565b50858210156200039a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111562000401578160001904821115620003e557620003e5620003aa565b80851615620003f357918102915b93841c9390800290620003c5565b509250929050565b6000826200041a57506001620004b9565b816200042957506000620004b9565b81600181146200044257600281146200044d576200046d565b6001915050620004b9565b60ff841115620004615762000461620003aa565b50506001821b620004b9565b5060208310610133831016604e8410600b841016171562000492575081810a620004b9565b6200049e8383620003c0565b8060001904821115620004b557620004b5620003aa565b0290505b92915050565b6000620004d060ff84168362000409565b9392505050565b8082028115828204841417620004b957620004b9620003aa565b6000826200050f57634e487b7160e01b600052601260045260246000fd5b500490565b60805160a05160c05160e051613a746200057f600039600081816104aa0152818161149e01528181611877015281816120c0015281816120f8015281816121bb01526121e20152600061050701526000818161037a0152610dec015260006104230152613a746000f3fe608060405234801561001057600080fd5b50600436106102895760003560e01c80636d6a6a4d1161015c578063c5b8f772116100ce578063f0b305db11610087578063f0b305db146106a1578063f16df258146106b4578063f242432a146106bc578063f28ca1dd146106cf578063f2fde38b146106d7578063f8b45b05146106ea57600080fd5b8063c5b8f772146105eb578063c87b56dd146105fe578063d547cfb714610611578063dd62ed3e14610619578063e0df5b6f14610652578063e985e9c51461066557600080fd5b806395d89b411161012057806395d89b411461057e57806399a2557a146105865780639b19251a14610599578063a014e6e2146105bc578063a22cb465146105c5578063a9059cbb146105d857600080fd5b80636d6a6a4d1461050257806370a0823114610529578063715018a6146105525780638462151c1461055a5780638da5cb5b1461056d57600080fd5b806323b872dd116102005780634eabf2c6116101b95780634eabf2c61461047757806353d6fd591461047f57806359f7f36e146104925780635afcc2f5146104a55780635d0044ca146104cc5780635d733f47146104df57600080fd5b806323b872dd146103c25780632d760d57146103d55780632eb2c2d6146103e85780632f0750c1146103fb578063313ce5671461041e5780634e1273f41461045757600080fd5b8063095ea7b311610252578063095ea7b3146103425780630a702e8d146103555780630e89341c1461036257806318160ddd1461037557806318d217c31461039c5780632083abb8146103af57600080fd5b8062fdd58e1461028e57806301ffc9a7146102b457806302fe5305146102d757806306fdde03146102ec578063081812fc14610301575b600080fd5b6102a161029c366004612e6b565b6106f3565b6040519081526020015b60405180910390f35b6102c76102c2366004612eab565b610762565b60405190151581526020016102ab565b6102ea6102e5366004612f67565b610803565b005b6102f4610817565b6040516102ab9190612fff565b61032a61030f366004613012565b6005602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016102ab565b6102c7610350366004612e6b565b6108a5565b6014546102c79060ff1681565b6102f4610370366004613012565b610978565b6102a17f000000000000000000000000000000000000000000000000000000000000000081565b6102ea6103aa366004612f67565b610983565b6102ea6103bd366004613039565b61099b565b6102c76103d0366004613070565b6109ce565b6102a16103e33660046130ac565b610b0f565b6102ea6103f6366004613198565b610b46565b61040e610409366004613012565b610b93565b6040516102ab9493929190613241565b6104457f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016102ab565b61046a610465366004613270565b610c46565b6040516102ab9190613376565b6102ea610d26565b6102ea61048d366004613039565b610d42565b6102ea6104a0366004613389565b610d75565b6102a17f000000000000000000000000000000000000000000000000000000000000000081565b6102ea6104da366004613012565b610ddc565b6102c76104ed3660046133e2565b60126020526000908152604090205460ff1681565b6102a17f000000000000000000000000000000000000000000000000000000000000000081565b6102a16105373660046133e2565b6001600160a01b031660009081526006602052604090205490565b6102ea610e20565b61046a6105683660046133e2565b610e34565b6000546001600160a01b031661032a565b6102f4610e67565b61046a6105943660046130ac565b610e74565b6102c76105a73660046133e2565b600a6020526000908152604090205460ff1681565b6102a1600f5481565b6102ea6105d3366004613039565b610fa6565b6102c76105e6366004612e6b565b610fb1565b6102c76105f9366004612e6b565b610fc1565b6102f461060c366004613012565b610ff7565b6102f4611126565b6102a16106273660046133fd565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205490565b6102ea610660366004612f67565b611133565b6102c76106733660046133fd565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b61040e6106af366004613012565b611147565b6102ea61120d565b6102ea6106ca366004613430565b6112e8565b6102f4611336565b6102ea6106e53660046133e2565b611343565b6102a160135481565b60006001600160a01b03831661071c576040516323d3ad8160e21b815260040160405180910390fd5b6001600160a01b0383166000908152600160208181526040808420600887901c85529091529091205460ff84161c16156107585750600161075c565b5060005b92915050565b60006001600160e01b03198216636cdb3d1360e11b148061079357506001600160e01b031982166303a24d0760e21b145b806107ae57506001600160e01b031982166362dc7bb960e11b145b806107c957506380ac58cd60e01b6001600160e01b03198316145b806107e45750635b5e139f60e01b6001600160e01b03198316145b8061075c57506301ffc9a760e01b6001600160e01b031983161461075c565b61080b61137e565b610814816113ab565b50565b6008805461082490613494565b80601f016020809104026020016040519081016040528092919081815260200182805461085090613494565b801561089d5780601f106108725761010080835404028352916020019161089d565b820191906000526020600020905b81548152906001019060200180831161088057829003601f168201915b505050505081565b6000336108b160045490565b831080156108bf5750600083115b15610963576108ce8184610fc1565b6108fb57604051634b637e8f60e11b81526001600160a01b03821660048201526024015b60405180910390fd5b60008381526005602090815260409182902080546001600160a01b0319166001600160a01b038881169182179092559251868152908416917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a361096e565b61096e8185856113b7565b5060019392505050565b606061075c82610ff7565b61098b61137e565b60106109978282613516565b5050565b6109a361137e565b6001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055565b60006109d960045490565b821015610af7576001600160a01b0384166000908152600160208181526040808420600887901c85529091529091205460ff84161c16610a3757604051634a1406b160e11b81526001600160a01b03851660048201526024016108f2565b336001600160a01b03851614801590610a7457506001600160a01b038416600090815260026020908152604080832033845290915290205460ff16155b8015610a9757506000828152600560205260409020546001600160a01b03163314155b15610ab757604051634a1406b160e11b81523360048201526024016108f2565b600082815260056020908152604080832080546001600160a01b031916905580519182019052818152610af2918691869186916001916113c9565b61096e565b610b02843384611585565b61096e84848460016115fd565b6000610b3e83610b1f81856135eb565b6001600160a01b0387166000908152600160205260409020919061169a565b949350505050565b6001600160a01b038516331480610b625750610b628533610673565b610b7f57604051632ce44b5f60e11b815260040160405180910390fd5b610b8c858585858561173d565b5050505050565b600d60205260009081526040902080546001820154600283015460038401805493949293919291610bc390613494565b80601f0160208091040260200160405190810160405280929190818152602001828054610bef90613494565b8015610c3c5780601f10610c1157610100808354040283529160200191610c3c565b820191906000526020600020905b815481529060010190602001808311610c1f57829003601f168201915b5050505050905084565b60608151835114610c6a57604051637801f4e960e01b815260040160405180910390fd5b600083516001600160401b03811115610c8557610c85612ec8565b604051908082528060200260200182016040528015610cae578160200160208202803683370190505b50905060005b8451811015610d1e57610cf9858281518110610cd257610cd26135fe565b6020026020010151858381518110610cec57610cec6135fe565b60200260200101516106f3565b828281518110610d0b57610d0b6135fe565b6020908102919091010152600101610cb4565b509392505050565b610d2e61137e565b6014805460ff19811660ff90911615179055565b610d4a61137e565b6001600160a01b03919091166000908152600a60205260409020805460ff1916911515919091179055565b3360009081526012602052604090205460ff16610dca5760405162461bcd60e51b81526020600482015260136024820152722c2827a71d1037b7363c9037b832b930ba37b960691b60448201526064016108f2565b610dd68484848461198d565b50505050565b610de461137e565b6064610e10827f0000000000000000000000000000000000000000000000000000000000000000613614565b610e1a9190613641565b60135550565b610e2861137e565b610e3260006119bb565b565b6060610e3e611a0b565b600003610e5957505060408051600081526020810190915290565b61075c826001600454610e74565b6009805461082490613494565b6060818310610e9657604051631960ccad60e11b815260040160405180910390fd5b6001831015610ea457600192505b6000610eaf60045490565b905080831115610ebd578092505b600083851015610ed957610ed2868686610b0f565b9050610edd565b5060005b6000816001600160401b03811115610ef757610ef7612ec8565b604051908082528060200260200182016040528015610f20578160200160208202803683370190505b506001600160a01b038816600090815260016020526040812091925087905b848114610f9857600882901c60009081526020849052604090205460ff83161c60011615610f8d5781848280600101935081518110610f8057610f806135fe565b6020026020010181815250505b816001019150610f3f565b509198975050505050505050565b610997338383611a21565b60003361096e81858560016115fd565b6001600160a01b0382166000908152600160208181526040808420600886901c855290915282205460ff84161c165b9392505050565b606061100260045490565b821061102157604051637801f4e960e01b815260040160405180910390fd5b60006011805461103090613494565b9050111561110d576000828152600d602052604081206002810154905490919060041180159061106e57506000848152600d60205260409020546006115b1561107b575060016110cf565b6000848152600d60205260409020546006118015906110a857506000848152600d60205260409020546008115b156110b5575060026110cf565b6000848152600d60205260409020546008116110cf575060035b60116110da83611b01565b6110e383611b01565b6040516020016110f593929190613655565b60405160208183030381529060405292505050919050565b505060408051602081019091526000815290565b919050565b6011805461082490613494565b61113b61137e565b60116109978282613516565b6000818152600d60205260408120600281015481546001830154600390930180548594859460609490939092819061117e90613494565b80601f01602080910402602001604051908101604052809291908181526020018280546111aa90613494565b80156111f75780601f106111cc576101008083540402835291602001916111f7565b820191906000526020600020905b8154815290600101906020018083116111da57829003601f168201915b5050505050905093509350935093509193509193565b61121561137e565b600e5460ff161561125f5760405162461bcd60e51b815260206004820152601460248201527320b63932b0b23c9034b734ba34b0b634bd32b21760611b60448201526064016108f2565b6040805160a0810182526000815260016020820152600291810191909152600360608201526004608082015261129990600b906005612d58565b506040805160a08101825261157c8152610bb860208201526103e8918101919091526101c26060820152603260808201526112d890600c906005612dfe565b50600e805460ff19166001179055565b6001600160a01b03851633148061130457506113048533610673565b1561131d57611318858585858560016113c9565b610b8c565b604051632ce44b5f60e11b815260040160405180910390fd5b6010805461082490613494565b61134b61137e565b6001600160a01b03811661137557604051631e4fbdf760e01b8152600060048201526024016108f2565b610814816119bb565b6000546001600160a01b03163314610e325760405163118cdaa760e01b81523360048201526024016108f2565b60036109978282613516565b6113c48383836001611c01565b505050565b6001600160a01b0385166113f057604051633a954ecd60e21b815260040160405180910390fd5b3360006113fc86611cd6565b905084600114801561143957506001600160a01b038816600090815260016020818152604080842060088b901c85529091529091205460ff88161c165b156114c8576001600160a01b03888116600090815260016020818152604080842060088c901c808652908352818520805460ff8e1686901b8019909116909155958d168552928252808420928452919052812080549092179091556114c390899089907f0000000000000000000000000000000000000000000000000000000000000000906115fd565b6114e1565b6040516337dbad3d60e01b815260040160405180910390fd5b6001600160a01b03878116908916868282600080516020613a1f833981519152600080a4886001600160a01b03168a6001600160a01b0316856001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b8b60405161155d929190918252602082015260400190565b60405180910390a4841561157957611579848b8b8b8b8b611d1d565b50505050505050505050565b6001600160a01b038381166000908152600760209081526040808320938616835292905220546000198114610dd657818110156115ee57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016108f2565b610dd684848484036000611c01565b6001600160a01b03841661162757604051634b637e8f60e11b8152600060048201526024016108f2565b6001600160a01b0383166116515760405163ec442f0560e01b8152600060048201526024016108f2565b826001600160a01b0316846001600160a01b03160361168e576040516373167b5160e01b81526001600160a01b03851660048201526024016108f2565b610dd684848484611f94565b6000600883901c60ff841661010184820110611710576000828152602087905260409020546116ca90821c61224e565b930160ff8116939250600182019160009160081c015b80831461170e576000838152602088905260409020546116ff9061224e565b840193508260010192506116e0565b505b60008281526020879052604090205461173190821c6101008690031b61224e565b90920195945050505050565b815183511461175f57604051637801f4e960e01b815260040160405180910390fd5b6001600160a01b03841661178657604051633a954ecd60e21b815260040160405180910390fd5b3360005b845181101561186d5760008582815181106117a7576117a76135fe565b6020026020010151905060008583815181106117c5576117c56135fe565b6020026020010151905080600114801561180a57506001600160a01b0389166000908152600160208181526040808420600887901c85529091529091205460ff84161c165b156114c857506001600160a01b038881166000908152600160208181526040808420600887901c808652908352818520805460ff90981685901b80199098169055948c16845282825280842094845293905291902080549092179091550161178a565b506118a7868686517f00000000000000000000000000000000000000000000000000000000000000006118a09190613614565b60006115fd565b6000806000865160016118ba9190613715565b90506001600160a01b03891691506001600160a01b038816925060208701518383600080516020613a1f833981519152600080a460025b81811461191c57806020028801518484600080516020613a1f833981519152600080a46001016118f1565b50876001600160a01b0316896001600160a01b0316856001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8a8a60405161196c929190613728565b60405180910390a4611982848a8a8a8a8a6122fe565b505050505050505050565b6000848152600d6020526040902083815560018101839055600381016119b38382613516565b505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006001600454611a1c91906135eb565b905090565b816001600160a01b0316836001600160a01b031603611a945760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016108f2565b6001600160a01b03838116600081815260026020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b606081600003611b285750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611b525780611b3c81613756565b9150611b4b9050600a83613641565b9150611b2c565b6000816001600160401b03811115611b6c57611b6c612ec8565b6040519080825280601f01601f191660200182016040528015611b96576020820181803683370190505b5090505b8415610b3e57611bab6001836135eb565b9150611bb8600a8661376f565b611bc3906030613715565b60f81b818381518110611bd857611bd86135fe565b60200101906001600160f81b031916908160001a905350611bfa600a86613641565b9450611b9a565b6001600160a01b038416611c2b5760405163e602df0560e01b8152600060048201526024016108f2565b6001600160a01b038316611c5557604051634a1406b160e11b8152600060048201526024016108f2565b6001600160a01b0380851660009081526007602090815260408083209387168352929052208290558015610dd657826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611cc891815260200190565b60405180910390a350505050565b604080516001808252818301909252606091602080830190803683370190505090508181600081518110611d0c57611d0c6135fe565b602002602001018181525050919050565b6001600160a01b0384163b156119b3576040516301ffc9a760e01b8152636cdb3d1360e11b60048201526001600160a01b038516906301ffc9a790602401602060405180830381865afa158015611d78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9c9190613783565b15611ea75760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190611dd590899089908890889088906004016137a0565b6020604051808303816000875af1925050508015611e10575060408051601f3d908101601f19168201909252611e0d918101906137da565b60015b611e7057611e1c6137f7565b806308c379a003611e555750611e30613813565b80611e3b5750611e57565b8060405162461bcd60e51b81526004016108f29190612fff565b505b604051639c05499b60e01b815260040160405180910390fd5b6001600160e01b0319811663f23a6e6160e01b14611ea157604051639c05499b60e01b815260040160405180910390fd5b506119b3565b604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611ed990899089908890879060040161389c565b6020604051808303816000875af1925050508015611f14575060408051601f3d908101601f19168201909252611f11918101906137da565b60015b611f5a57611f206137f7565b806308c379a003611f3f5750611f34613813565b80611e3b5750611f41565b505b6040516368d2bf6b60e11b815260040160405180910390fd5b6001600160e01b03198116630a85bd0160e11b14611f8b576040516368d2bf6b60e11b815260040160405180910390fd5b50505050505050565b6001600160a01b0380851660009081526006602052604080822054928616825290205483821015611ff15760405163391434e360e21b81526001600160a01b038716600482015260248101839052604481018590526064016108f2565b846001600160a01b0316866001600160a01b03160361202a576001600160a01b0385166000908152600660205260409020829055612055565b6001600160a01b03808716600090815260066020526040808220878603905591871681522081850190555b846001600160a01b0316866001600160a01b0316600080516020613a1f8339815191528660405161208891815260200190565b60405180910390a382156119b3576001600160a01b0386166000908152600a602052604081205460ff16906060908190808461213c577f00000000000000000000000000000000000000000000000000000000000000006120e98a896135eb565b6120f39190613641565b61211d7f000000000000000000000000000000000000000000000000000000000000000089613641565b61212791906135eb565b9150811561213c576121398b836123ba565b93505b6001600160a01b038a166000908152600a602052604090205460ff1661223557600f54600114801561216b5750845b801561218457506000546001600160a01b038c81169116145b156121b6576001600160a01b038a166000908152600a60205260409020805460ff191660011790556002600f55612235565b6121e07f000000000000000000000000000000000000000000000000000000000000000087613641565b7f000000000000000000000000000000000000000000000000000000000000000061220b8b89613715565b6122159190613641565b61221f91906135eb565b90508015612235576122318a8261267b565b5092505b612241848484846128bc565b5050505050505050505050565b7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c168203600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c6000199190911460081b1790565b6001600160a01b0384163b156119b35760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061234290899089908890889088906004016138cf565b6020604051808303816000875af192505050801561237d575060408051601f3d908101601f1916820190925261237a918101906137da565b60015b61238957611e1c6137f7565b6001600160e01b0319811663bc197c8160e01b14611f8b57604051639c05499b60e01b815260040160405180910390fd5b60606001600160a01b0383166123e35760405163b817eee760e01b815260040160405180910390fd5b60045433906000846001600160401b0381111561240257612402612ec8565b60405190808252806020026020018201604052801561242b578160200160208202803683370190505b5090506000856001600160401b0381111561244857612448612ec8565b604051908082528060200260200182016040528015612471578160200160208202803683370190505b50905060005b86811015612524576001838281518110612493576124936135fe565b6020908102919091018101919091526001600160a01b03891660009081526001909152604081206124c49086612a56565b9050808383815181106124d9576124d96135fe565b6020908102919091018101919091526001600160a01b038a16600090815260018083526040808320600886901c8452909352919020805460ff841683901b1916905590945001612477565b50600080612533886001613715565b90506001600160a01b03891691506020830151600083600080516020613a1f833981519152600080a460025b81811461258b5780602002840151600084600080516020613a1f833981519152600080a460010161255f565b50876001036126155760006001600160a01b0316896001600160a01b0316876001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62866000815181106125e7576125e76135fe565b60200260200101516001604051612608929190918252602082015260400190565b60405180910390a461266e565b60006001600160a01b0316896001600160a01b0316876001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8688604051612665929190613728565b60405180910390a45b5090979650505050505050565b6060806001600160a01b0384166126a457604051622e076360e81b815260040160405180910390fd5b826000036126c55760405163b562e8dd60e01b815260040160405180910390fd5b33836001600160401b038111156126de576126de612ec8565b604051908082528060200260200182016040528015612707578160200160208202803683370190505b509250836001600160401b0381111561272257612722612ec8565b60405190808252806020026020018201604052801561274b578160200160208202803683370190505b509150600061275960045490565b9050808560001903101561276c57600080fd5b60005b858110156127bf5780820185828151811061278c5761278c6135fe565b60200260200101818152505060018482815181106127ac576127ac6135fe565b602090810291909101015260010161276f565b506001600160a01b03861660009081526001602052604090206127e3908287612b47565b84600460008282546127f59190613715565b9091555060009050806128088784613715565b90506001600160a01b038816915082826000600080516020613a1f833981519152600080a4600183015b8181146128585780836000600080516020613a1f833981519152600080a4600101612832565b50876001600160a01b031660006001600160a01b0316856001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb89896040516128a9929190613728565b60405180910390a4505050509250929050565b8015610dd657816000036129585760005b83518110156129525760008482815181106128ea576128ea6135fe565b6020026020010151905060006128ff82612bc4565b6000838152600d6020818152604080842060ff861660028201556127106001820155848155815185815280840190925293879052919052919250600301906129479082613516565b5050506001016128cd565b50610dd6565b60005b8351811015610b8c576000848281518110612978576129786135fe565b6020026020010151905085518210156129f757600086838151811061299f5761299f6135fe565b6020908102919091018101516000818152600d9092526040808320600280820154878652929094209384019190915560018082015490840155805483559092506003918201916129f091018261392d565b5050612a4d565b6000612a0282612bc4565b6000838152600d6020818152604080842060ff86166002820155612710600182015584815581518581528084019092529387905291905291925060030190612a4a9082613516565b50505b5060010161295b565b600881901c600081815260208490526040902054600019919060ff84191690811b901c81158117612a99575b508101600081815260409020548115811715612a82575b8015612b3f57612b2f817f0706060506020504060203020504030106050205030304010505030400000000601f6f8421084210842108cc6318c6db6d54be831560081b6fffffffffffffffffffffffffffffffff851160071b1784811c6001600160401b031060061b1784811c63ffffffff1060051b1784811c61ffff1060041b1784811c60ff1060031b1793841c1c161a1790565b600883901b178481116000031792505b505092915050565b60001960ff8316846020528360081c60005261010183820110612ba9576000805160408220805485851b1790559390910160ff811693600181019160081c015b808214612ba4578160005283604060002055600182019150612b87565b506000525b60406000208284610100031c821b8154178155505050505050565b600080612bd083612bdb565b9050610ff081612c64565b6000804245612beb6001436135eb565b40612bf76064436135eb565b604080516020810195909552840192909252606080840191909152904060808301526bffffffffffffffffffffffff1941821b811660a08401523290911b1660b482015260c8810184905260e80160408051601f1981840301815291905280516020909101209392505050565b600080612c736127108461376f565b90506000805b600c5460ff82161015612d0e57600c8160ff1681548110612c9c57612c9c6135fe565b906000526020600020015482612cb29190613715565b915081831015612cfc57600b8160ff1681548110612cd257612cd26135fe565b90600052602060002090602091828204019190069054906101000a900460ff169350505050919050565b80612d06816139ff565b915050612c79565b50600b8054612d1f906001906135eb565b81548110612d2f57612d2f6135fe565b90600052602060002090602091828204019190069054906101000a900460ff1692505050919050565b82805482825590600052602060002090601f01602090048101928215612dee5791602002820160005b83821115612dbf57835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302612d81565b8015612dec5782816101000a81549060ff0219169055600101602081600001049283019260010302612dbf565b505b50612dfa929150612e3f565b5090565b828054828255906000526020600020908101928215612dee579160200282015b82811115612dee578251829061ffff16905591602001919060010190612e1e565b5b80821115612dfa5760008155600101612e40565b80356001600160a01b038116811461112157600080fd5b60008060408385031215612e7e57600080fd5b612e8783612e54565b946020939093013593505050565b6001600160e01b03198116811461081457600080fd5b600060208284031215612ebd57600080fd5b8135610ff081612e95565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715612f0357612f03612ec8565b6040525050565b60006001600160401b03831115612f2357612f23612ec8565b604051612f3a601f8501601f191660200182612ede565b809150838152848484011115612f4f57600080fd5b83836020830137600060208583010152509392505050565b600060208284031215612f7957600080fd5b81356001600160401b03811115612f8f57600080fd5b8201601f81018413612fa057600080fd5b610b3e84823560208401612f0a565b60005b83811015612fca578181015183820152602001612fb2565b50506000910152565b60008151808452612feb816020860160208601612faf565b601f01601f19169290920160200192915050565b602081526000610ff06020830184612fd3565b60006020828403121561302457600080fd5b5035919050565b801515811461081457600080fd5b6000806040838503121561304c57600080fd5b61305583612e54565b915060208301356130658161302b565b809150509250929050565b60008060006060848603121561308557600080fd5b61308e84612e54565b925061309c60208501612e54565b9150604084013590509250925092565b6000806000606084860312156130c157600080fd5b6130ca84612e54565b95602085013595506040909401359392505050565b60006001600160401b038211156130f8576130f8612ec8565b5060051b60200190565b600082601f83011261311357600080fd5b81356020613120826130df565b60405161312d8282612ede565b80915083815260208101915060208460051b87010193508684111561315157600080fd5b602086015b8481101561316d5780358352918301918301613156565b509695505050505050565b600082601f83011261318957600080fd5b610ff083833560208501612f0a565b600080600080600060a086880312156131b057600080fd5b6131b986612e54565b94506131c760208701612e54565b935060408601356001600160401b03808211156131e357600080fd5b6131ef89838a01613102565b9450606088013591508082111561320557600080fd5b61321189838a01613102565b9350608088013591508082111561322757600080fd5b5061323488828901613178565b9150509295509295909350565b8481528360208201528260408201526080606082015260006132666080830184612fd3565b9695505050505050565b6000806040838503121561328357600080fd5b82356001600160401b038082111561329a57600080fd5b818501915085601f8301126132ae57600080fd5b813560206132bb826130df565b6040516132c88282612ede565b83815260059390931b85018201928281019150898411156132e857600080fd5b948201945b8386101561330d576132fe86612e54565b825294820194908201906132ed565b9650508601359250508082111561332357600080fd5b5061333085828601613102565b9150509250929050565b60008151808452602080850194506020840160005b8381101561336b5781518752958201959082019060010161334f565b509495945050505050565b602081526000610ff0602083018461333a565b6000806000806080858703121561339f57600080fd5b84359350602085013592506040850135915060608501356001600160401b038111156133ca57600080fd5b6133d687828801613178565b91505092959194509250565b6000602082840312156133f457600080fd5b610ff082612e54565b6000806040838503121561341057600080fd5b61341983612e54565b915061342760208401612e54565b90509250929050565b600080600080600060a0868803121561344857600080fd5b61345186612e54565b945061345f60208701612e54565b9350604086013592506060860135915060808601356001600160401b0381111561348857600080fd5b61323488828901613178565b600181811c908216806134a857607f821691505b6020821081036134c857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156113c4576000816000526020600020601f850160051c810160208610156134f75750805b601f850160051c820191505b818110156119b357828155600101613503565b81516001600160401b0381111561352f5761352f612ec8565b6135438161353d8454613494565b846134ce565b602080601f83116001811461357857600084156135605750858301515b600019600386901b1c1916600185901b1785556119b3565b600085815260208120601f198616915b828110156135a757888601518255948401946001909101908401613588565b50858210156135c55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b8181038181111561075c5761075c6135d5565b634e487b7160e01b600052603260045260246000fd5b808202811582820484141761075c5761075c6135d5565b634e487b7160e01b600052601260045260246000fd5b6000826136505761365061362b565b500490565b600080855461366381613494565b6001828116801561367b5760018114613690576136bf565b60ff19841687528215158302870194506136bf565b8960005260208060002060005b858110156136b65781548a82015290840190820161369d565b50505082870194505b5050505084516136d3818360208901612faf565b605f60f81b910190815283516136f0816001840160208801612faf565b61370a60018284010164173539b7b760d91b815260050190565b979650505050505050565b8082018082111561075c5761075c6135d5565b60408152600061373b604083018561333a565b828103602084015261374d818561333a565b95945050505050565b600060018201613768576137686135d5565b5060010190565b60008261377e5761377e61362b565b500690565b60006020828403121561379557600080fd5b8151610ff08161302b565b6001600160a01b03868116825285166020820152604081018490526060810183905260a06080820181905260009061370a90830184612fd3565b6000602082840312156137ec57600080fd5b8151610ff081612e95565b600060033d11156138105760046000803e5060005160e01c5b90565b600060443d10156138215790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561385057505050505090565b82850191508151818111156138685750505050505090565b843d87010160208285010111156138825750505050505090565b61389160208286010187612ede565b509095945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061326690830184612fd3565b6001600160a01b0386811682528516602082015260a0604082018190526000906138fb9083018661333a565b828103606084015261390d818661333a565b905082810360808401526139218185612fd3565b98975050505050505050565b818103613938575050565b6139428254613494565b6001600160401b0381111561395957613959612ec8565b6139678161353d8454613494565b6000601f82116001811461399b57600083156139835750848201545b600019600385901b1c1916600184901b178455610b8c565b600085815260209020601f19841690600086815260209020845b838110156139d557828601548255600195860195909101906020016139b5565b50858310156135c55793015460001960f8600387901b161c19169092555050600190811b01905550565b600060ff821660ff8103613a1557613a156135d5565b6001019291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212204e2f7f377205ebff290475ce617203f95cf0a992686c8d692c57b1538d640b5264736f6c63430008170033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102895760003560e01c80636d6a6a4d1161015c578063c5b8f772116100ce578063f0b305db11610087578063f0b305db146106a1578063f16df258146106b4578063f242432a146106bc578063f28ca1dd146106cf578063f2fde38b146106d7578063f8b45b05146106ea57600080fd5b8063c5b8f772146105eb578063c87b56dd146105fe578063d547cfb714610611578063dd62ed3e14610619578063e0df5b6f14610652578063e985e9c51461066557600080fd5b806395d89b411161012057806395d89b411461057e57806399a2557a146105865780639b19251a14610599578063a014e6e2146105bc578063a22cb465146105c5578063a9059cbb146105d857600080fd5b80636d6a6a4d1461050257806370a0823114610529578063715018a6146105525780638462151c1461055a5780638da5cb5b1461056d57600080fd5b806323b872dd116102005780634eabf2c6116101b95780634eabf2c61461047757806353d6fd591461047f57806359f7f36e146104925780635afcc2f5146104a55780635d0044ca146104cc5780635d733f47146104df57600080fd5b806323b872dd146103c25780632d760d57146103d55780632eb2c2d6146103e85780632f0750c1146103fb578063313ce5671461041e5780634e1273f41461045757600080fd5b8063095ea7b311610252578063095ea7b3146103425780630a702e8d146103555780630e89341c1461036257806318160ddd1461037557806318d217c31461039c5780632083abb8146103af57600080fd5b8062fdd58e1461028e57806301ffc9a7146102b457806302fe5305146102d757806306fdde03146102ec578063081812fc14610301575b600080fd5b6102a161029c366004612e6b565b6106f3565b6040519081526020015b60405180910390f35b6102c76102c2366004612eab565b610762565b60405190151581526020016102ab565b6102ea6102e5366004612f67565b610803565b005b6102f4610817565b6040516102ab9190612fff565b61032a61030f366004613012565b6005602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016102ab565b6102c7610350366004612e6b565b6108a5565b6014546102c79060ff1681565b6102f4610370366004613012565b610978565b6102a17f000000000000000000000000000000000000000000000a968163f0a57b40000081565b6102ea6103aa366004612f67565b610983565b6102ea6103bd366004613039565b61099b565b6102c76103d0366004613070565b6109ce565b6102a16103e33660046130ac565b610b0f565b6102ea6103f6366004613198565b610b46565b61040e610409366004613012565b610b93565b6040516102ab9493929190613241565b6104457f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016102ab565b61046a610465366004613270565b610c46565b6040516102ab9190613376565b6102ea610d26565b6102ea61048d366004613039565b610d42565b6102ea6104a0366004613389565b610d75565b6102a17f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b6102ea6104da366004613012565b610ddc565b6102c76104ed3660046133e2565b60126020526000908152604090205460ff1681565b6102a17f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b6102a16105373660046133e2565b6001600160a01b031660009081526006602052604090205490565b6102ea610e20565b61046a6105683660046133e2565b610e34565b6000546001600160a01b031661032a565b6102f4610e67565b61046a6105943660046130ac565b610e74565b6102c76105a73660046133e2565b600a6020526000908152604090205460ff1681565b6102a1600f5481565b6102ea6105d3366004613039565b610fa6565b6102c76105e6366004612e6b565b610fb1565b6102c76105f9366004612e6b565b610fc1565b6102f461060c366004613012565b610ff7565b6102f4611126565b6102a16106273660046133fd565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205490565b6102ea610660366004612f67565b611133565b6102c76106733660046133fd565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b61040e6106af366004613012565b611147565b6102ea61120d565b6102ea6106ca366004613430565b6112e8565b6102f4611336565b6102ea6106e53660046133e2565b611343565b6102a160135481565b60006001600160a01b03831661071c576040516323d3ad8160e21b815260040160405180910390fd5b6001600160a01b0383166000908152600160208181526040808420600887901c85529091529091205460ff84161c16156107585750600161075c565b5060005b92915050565b60006001600160e01b03198216636cdb3d1360e11b148061079357506001600160e01b031982166303a24d0760e21b145b806107ae57506001600160e01b031982166362dc7bb960e11b145b806107c957506380ac58cd60e01b6001600160e01b03198316145b806107e45750635b5e139f60e01b6001600160e01b03198316145b8061075c57506301ffc9a760e01b6001600160e01b031983161461075c565b61080b61137e565b610814816113ab565b50565b6008805461082490613494565b80601f016020809104026020016040519081016040528092919081815260200182805461085090613494565b801561089d5780601f106108725761010080835404028352916020019161089d565b820191906000526020600020905b81548152906001019060200180831161088057829003601f168201915b505050505081565b6000336108b160045490565b831080156108bf5750600083115b15610963576108ce8184610fc1565b6108fb57604051634b637e8f60e11b81526001600160a01b03821660048201526024015b60405180910390fd5b60008381526005602090815260409182902080546001600160a01b0319166001600160a01b038881169182179092559251868152908416917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a361096e565b61096e8185856113b7565b5060019392505050565b606061075c82610ff7565b61098b61137e565b60106109978282613516565b5050565b6109a361137e565b6001600160a01b03919091166000908152601260205260409020805460ff1916911515919091179055565b60006109d960045490565b821015610af7576001600160a01b0384166000908152600160208181526040808420600887901c85529091529091205460ff84161c16610a3757604051634a1406b160e11b81526001600160a01b03851660048201526024016108f2565b336001600160a01b03851614801590610a7457506001600160a01b038416600090815260026020908152604080832033845290915290205460ff16155b8015610a9757506000828152600560205260409020546001600160a01b03163314155b15610ab757604051634a1406b160e11b81523360048201526024016108f2565b600082815260056020908152604080832080546001600160a01b031916905580519182019052818152610af2918691869186916001916113c9565b61096e565b610b02843384611585565b61096e84848460016115fd565b6000610b3e83610b1f81856135eb565b6001600160a01b0387166000908152600160205260409020919061169a565b949350505050565b6001600160a01b038516331480610b625750610b628533610673565b610b7f57604051632ce44b5f60e11b815260040160405180910390fd5b610b8c858585858561173d565b5050505050565b600d60205260009081526040902080546001820154600283015460038401805493949293919291610bc390613494565b80601f0160208091040260200160405190810160405280929190818152602001828054610bef90613494565b8015610c3c5780601f10610c1157610100808354040283529160200191610c3c565b820191906000526020600020905b815481529060010190602001808311610c1f57829003601f168201915b5050505050905084565b60608151835114610c6a57604051637801f4e960e01b815260040160405180910390fd5b600083516001600160401b03811115610c8557610c85612ec8565b604051908082528060200260200182016040528015610cae578160200160208202803683370190505b50905060005b8451811015610d1e57610cf9858281518110610cd257610cd26135fe565b6020026020010151858381518110610cec57610cec6135fe565b60200260200101516106f3565b828281518110610d0b57610d0b6135fe565b6020908102919091010152600101610cb4565b509392505050565b610d2e61137e565b6014805460ff19811660ff90911615179055565b610d4a61137e565b6001600160a01b03919091166000908152600a60205260409020805460ff1916911515919091179055565b3360009081526012602052604090205460ff16610dca5760405162461bcd60e51b81526020600482015260136024820152722c2827a71d1037b7363c9037b832b930ba37b960691b60448201526064016108f2565b610dd68484848461198d565b50505050565b610de461137e565b6064610e10827f000000000000000000000000000000000000000000000a968163f0a57b400000613614565b610e1a9190613641565b60135550565b610e2861137e565b610e3260006119bb565b565b6060610e3e611a0b565b600003610e5957505060408051600081526020810190915290565b61075c826001600454610e74565b6009805461082490613494565b6060818310610e9657604051631960ccad60e11b815260040160405180910390fd5b6001831015610ea457600192505b6000610eaf60045490565b905080831115610ebd578092505b600083851015610ed957610ed2868686610b0f565b9050610edd565b5060005b6000816001600160401b03811115610ef757610ef7612ec8565b604051908082528060200260200182016040528015610f20578160200160208202803683370190505b506001600160a01b038816600090815260016020526040812091925087905b848114610f9857600882901c60009081526020849052604090205460ff83161c60011615610f8d5781848280600101935081518110610f8057610f806135fe565b6020026020010181815250505b816001019150610f3f565b509198975050505050505050565b610997338383611a21565b60003361096e81858560016115fd565b6001600160a01b0382166000908152600160208181526040808420600886901c855290915282205460ff84161c165b9392505050565b606061100260045490565b821061102157604051637801f4e960e01b815260040160405180910390fd5b60006011805461103090613494565b9050111561110d576000828152600d602052604081206002810154905490919060041180159061106e57506000848152600d60205260409020546006115b1561107b575060016110cf565b6000848152600d60205260409020546006118015906110a857506000848152600d60205260409020546008115b156110b5575060026110cf565b6000848152600d60205260409020546008116110cf575060035b60116110da83611b01565b6110e383611b01565b6040516020016110f593929190613655565b60405160208183030381529060405292505050919050565b505060408051602081019091526000815290565b919050565b6011805461082490613494565b61113b61137e565b60116109978282613516565b6000818152600d60205260408120600281015481546001830154600390930180548594859460609490939092819061117e90613494565b80601f01602080910402602001604051908101604052809291908181526020018280546111aa90613494565b80156111f75780601f106111cc576101008083540402835291602001916111f7565b820191906000526020600020905b8154815290600101906020018083116111da57829003601f168201915b5050505050905093509350935093509193509193565b61121561137e565b600e5460ff161561125f5760405162461bcd60e51b815260206004820152601460248201527320b63932b0b23c9034b734ba34b0b634bd32b21760611b60448201526064016108f2565b6040805160a0810182526000815260016020820152600291810191909152600360608201526004608082015261129990600b906005612d58565b506040805160a08101825261157c8152610bb860208201526103e8918101919091526101c26060820152603260808201526112d890600c906005612dfe565b50600e805460ff19166001179055565b6001600160a01b03851633148061130457506113048533610673565b1561131d57611318858585858560016113c9565b610b8c565b604051632ce44b5f60e11b815260040160405180910390fd5b6010805461082490613494565b61134b61137e565b6001600160a01b03811661137557604051631e4fbdf760e01b8152600060048201526024016108f2565b610814816119bb565b6000546001600160a01b03163314610e325760405163118cdaa760e01b81523360048201526024016108f2565b60036109978282613516565b6113c48383836001611c01565b505050565b6001600160a01b0385166113f057604051633a954ecd60e21b815260040160405180910390fd5b3360006113fc86611cd6565b905084600114801561143957506001600160a01b038816600090815260016020818152604080842060088b901c85529091529091205460ff88161c165b156114c8576001600160a01b03888116600090815260016020818152604080842060088c901c808652908352818520805460ff8e1686901b8019909116909155958d168552928252808420928452919052812080549092179091556114c390899089907f0000000000000000000000000000000000000000000000000de0b6b3a7640000906115fd565b6114e1565b6040516337dbad3d60e01b815260040160405180910390fd5b6001600160a01b03878116908916868282600080516020613a1f833981519152600080a4886001600160a01b03168a6001600160a01b0316856001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b8b60405161155d929190918252602082015260400190565b60405180910390a4841561157957611579848b8b8b8b8b611d1d565b50505050505050505050565b6001600160a01b038381166000908152600760209081526040808320938616835292905220546000198114610dd657818110156115ee57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064016108f2565b610dd684848484036000611c01565b6001600160a01b03841661162757604051634b637e8f60e11b8152600060048201526024016108f2565b6001600160a01b0383166116515760405163ec442f0560e01b8152600060048201526024016108f2565b826001600160a01b0316846001600160a01b03160361168e576040516373167b5160e01b81526001600160a01b03851660048201526024016108f2565b610dd684848484611f94565b6000600883901c60ff841661010184820110611710576000828152602087905260409020546116ca90821c61224e565b930160ff8116939250600182019160009160081c015b80831461170e576000838152602088905260409020546116ff9061224e565b840193508260010192506116e0565b505b60008281526020879052604090205461173190821c6101008690031b61224e565b90920195945050505050565b815183511461175f57604051637801f4e960e01b815260040160405180910390fd5b6001600160a01b03841661178657604051633a954ecd60e21b815260040160405180910390fd5b3360005b845181101561186d5760008582815181106117a7576117a76135fe565b6020026020010151905060008583815181106117c5576117c56135fe565b6020026020010151905080600114801561180a57506001600160a01b0389166000908152600160208181526040808420600887901c85529091529091205460ff84161c165b156114c857506001600160a01b038881166000908152600160208181526040808420600887901c808652908352818520805460ff90981685901b80199098169055948c16845282825280842094845293905291902080549092179091550161178a565b506118a7868686517f0000000000000000000000000000000000000000000000000de0b6b3a76400006118a09190613614565b60006115fd565b6000806000865160016118ba9190613715565b90506001600160a01b03891691506001600160a01b038816925060208701518383600080516020613a1f833981519152600080a460025b81811461191c57806020028801518484600080516020613a1f833981519152600080a46001016118f1565b50876001600160a01b0316896001600160a01b0316856001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8a8a60405161196c929190613728565b60405180910390a4611982848a8a8a8a8a6122fe565b505050505050505050565b6000848152600d6020526040902083815560018101839055600381016119b38382613516565b505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006001600454611a1c91906135eb565b905090565b816001600160a01b0316836001600160a01b031603611a945760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016108f2565b6001600160a01b03838116600081815260026020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b606081600003611b285750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611b525780611b3c81613756565b9150611b4b9050600a83613641565b9150611b2c565b6000816001600160401b03811115611b6c57611b6c612ec8565b6040519080825280601f01601f191660200182016040528015611b96576020820181803683370190505b5090505b8415610b3e57611bab6001836135eb565b9150611bb8600a8661376f565b611bc3906030613715565b60f81b818381518110611bd857611bd86135fe565b60200101906001600160f81b031916908160001a905350611bfa600a86613641565b9450611b9a565b6001600160a01b038416611c2b5760405163e602df0560e01b8152600060048201526024016108f2565b6001600160a01b038316611c5557604051634a1406b160e11b8152600060048201526024016108f2565b6001600160a01b0380851660009081526007602090815260408083209387168352929052208290558015610dd657826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611cc891815260200190565b60405180910390a350505050565b604080516001808252818301909252606091602080830190803683370190505090508181600081518110611d0c57611d0c6135fe565b602002602001018181525050919050565b6001600160a01b0384163b156119b3576040516301ffc9a760e01b8152636cdb3d1360e11b60048201526001600160a01b038516906301ffc9a790602401602060405180830381865afa158015611d78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9c9190613783565b15611ea75760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190611dd590899089908890889088906004016137a0565b6020604051808303816000875af1925050508015611e10575060408051601f3d908101601f19168201909252611e0d918101906137da565b60015b611e7057611e1c6137f7565b806308c379a003611e555750611e30613813565b80611e3b5750611e57565b8060405162461bcd60e51b81526004016108f29190612fff565b505b604051639c05499b60e01b815260040160405180910390fd5b6001600160e01b0319811663f23a6e6160e01b14611ea157604051639c05499b60e01b815260040160405180910390fd5b506119b3565b604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611ed990899089908890879060040161389c565b6020604051808303816000875af1925050508015611f14575060408051601f3d908101601f19168201909252611f11918101906137da565b60015b611f5a57611f206137f7565b806308c379a003611f3f5750611f34613813565b80611e3b5750611f41565b505b6040516368d2bf6b60e11b815260040160405180910390fd5b6001600160e01b03198116630a85bd0160e11b14611f8b576040516368d2bf6b60e11b815260040160405180910390fd5b50505050505050565b6001600160a01b0380851660009081526006602052604080822054928616825290205483821015611ff15760405163391434e360e21b81526001600160a01b038716600482015260248101839052604481018590526064016108f2565b846001600160a01b0316866001600160a01b03160361202a576001600160a01b0385166000908152600660205260409020829055612055565b6001600160a01b03808716600090815260066020526040808220878603905591871681522081850190555b846001600160a01b0316866001600160a01b0316600080516020613a1f8339815191528660405161208891815260200190565b60405180910390a382156119b3576001600160a01b0386166000908152600a602052604081205460ff16906060908190808461213c577f0000000000000000000000000000000000000000000000000de0b6b3a76400006120e98a896135eb565b6120f39190613641565b61211d7f0000000000000000000000000000000000000000000000000de0b6b3a764000089613641565b61212791906135eb565b9150811561213c576121398b836123ba565b93505b6001600160a01b038a166000908152600a602052604090205460ff1661223557600f54600114801561216b5750845b801561218457506000546001600160a01b038c81169116145b156121b6576001600160a01b038a166000908152600a60205260409020805460ff191660011790556002600f55612235565b6121e07f0000000000000000000000000000000000000000000000000de0b6b3a764000087613641565b7f0000000000000000000000000000000000000000000000000de0b6b3a764000061220b8b89613715565b6122159190613641565b61221f91906135eb565b90508015612235576122318a8261267b565b5092505b612241848484846128bc565b5050505050505050505050565b7f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600183901c168203600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c6000199190911460081b1790565b6001600160a01b0384163b156119b35760405163bc197c8160e01b81526001600160a01b0385169063bc197c819061234290899089908890889088906004016138cf565b6020604051808303816000875af192505050801561237d575060408051601f3d908101601f1916820190925261237a918101906137da565b60015b61238957611e1c6137f7565b6001600160e01b0319811663bc197c8160e01b14611f8b57604051639c05499b60e01b815260040160405180910390fd5b60606001600160a01b0383166123e35760405163b817eee760e01b815260040160405180910390fd5b60045433906000846001600160401b0381111561240257612402612ec8565b60405190808252806020026020018201604052801561242b578160200160208202803683370190505b5090506000856001600160401b0381111561244857612448612ec8565b604051908082528060200260200182016040528015612471578160200160208202803683370190505b50905060005b86811015612524576001838281518110612493576124936135fe565b6020908102919091018101919091526001600160a01b03891660009081526001909152604081206124c49086612a56565b9050808383815181106124d9576124d96135fe565b6020908102919091018101919091526001600160a01b038a16600090815260018083526040808320600886901c8452909352919020805460ff841683901b1916905590945001612477565b50600080612533886001613715565b90506001600160a01b03891691506020830151600083600080516020613a1f833981519152600080a460025b81811461258b5780602002840151600084600080516020613a1f833981519152600080a460010161255f565b50876001036126155760006001600160a01b0316896001600160a01b0316876001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62866000815181106125e7576125e76135fe565b60200260200101516001604051612608929190918252602082015260400190565b60405180910390a461266e565b60006001600160a01b0316896001600160a01b0316876001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8688604051612665929190613728565b60405180910390a45b5090979650505050505050565b6060806001600160a01b0384166126a457604051622e076360e81b815260040160405180910390fd5b826000036126c55760405163b562e8dd60e01b815260040160405180910390fd5b33836001600160401b038111156126de576126de612ec8565b604051908082528060200260200182016040528015612707578160200160208202803683370190505b509250836001600160401b0381111561272257612722612ec8565b60405190808252806020026020018201604052801561274b578160200160208202803683370190505b509150600061275960045490565b9050808560001903101561276c57600080fd5b60005b858110156127bf5780820185828151811061278c5761278c6135fe565b60200260200101818152505060018482815181106127ac576127ac6135fe565b602090810291909101015260010161276f565b506001600160a01b03861660009081526001602052604090206127e3908287612b47565b84600460008282546127f59190613715565b9091555060009050806128088784613715565b90506001600160a01b038816915082826000600080516020613a1f833981519152600080a4600183015b8181146128585780836000600080516020613a1f833981519152600080a4600101612832565b50876001600160a01b031660006001600160a01b0316856001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb89896040516128a9929190613728565b60405180910390a4505050509250929050565b8015610dd657816000036129585760005b83518110156129525760008482815181106128ea576128ea6135fe565b6020026020010151905060006128ff82612bc4565b6000838152600d6020818152604080842060ff861660028201556127106001820155848155815185815280840190925293879052919052919250600301906129479082613516565b5050506001016128cd565b50610dd6565b60005b8351811015610b8c576000848281518110612978576129786135fe565b6020026020010151905085518210156129f757600086838151811061299f5761299f6135fe565b6020908102919091018101516000818152600d9092526040808320600280820154878652929094209384019190915560018082015490840155805483559092506003918201916129f091018261392d565b5050612a4d565b6000612a0282612bc4565b6000838152600d6020818152604080842060ff86166002820155612710600182015584815581518581528084019092529387905291905291925060030190612a4a9082613516565b50505b5060010161295b565b600881901c600081815260208490526040902054600019919060ff84191690811b901c81158117612a99575b508101600081815260409020548115811715612a82575b8015612b3f57612b2f817f0706060506020504060203020504030106050205030304010505030400000000601f6f8421084210842108cc6318c6db6d54be831560081b6fffffffffffffffffffffffffffffffff851160071b1784811c6001600160401b031060061b1784811c63ffffffff1060051b1784811c61ffff1060041b1784811c60ff1060031b1793841c1c161a1790565b600883901b178481116000031792505b505092915050565b60001960ff8316846020528360081c60005261010183820110612ba9576000805160408220805485851b1790559390910160ff811693600181019160081c015b808214612ba4578160005283604060002055600182019150612b87565b506000525b60406000208284610100031c821b8154178155505050505050565b600080612bd083612bdb565b9050610ff081612c64565b6000804245612beb6001436135eb565b40612bf76064436135eb565b604080516020810195909552840192909252606080840191909152904060808301526bffffffffffffffffffffffff1941821b811660a08401523290911b1660b482015260c8810184905260e80160408051601f1981840301815291905280516020909101209392505050565b600080612c736127108461376f565b90506000805b600c5460ff82161015612d0e57600c8160ff1681548110612c9c57612c9c6135fe565b906000526020600020015482612cb29190613715565b915081831015612cfc57600b8160ff1681548110612cd257612cd26135fe565b90600052602060002090602091828204019190069054906101000a900460ff169350505050919050565b80612d06816139ff565b915050612c79565b50600b8054612d1f906001906135eb565b81548110612d2f57612d2f6135fe565b90600052602060002090602091828204019190069054906101000a900460ff1692505050919050565b82805482825590600052602060002090601f01602090048101928215612dee5791602002820160005b83821115612dbf57835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302612d81565b8015612dec5782816101000a81549060ff0219169055600101602081600001049283019260010302612dbf565b505b50612dfa929150612e3f565b5090565b828054828255906000526020600020908101928215612dee579160200282015b82811115612dee578251829061ffff16905591602001919060010190612e1e565b5b80821115612dfa5760008155600101612e40565b80356001600160a01b038116811461112157600080fd5b60008060408385031215612e7e57600080fd5b612e8783612e54565b946020939093013593505050565b6001600160e01b03198116811461081457600080fd5b600060208284031215612ebd57600080fd5b8135610ff081612e95565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715612f0357612f03612ec8565b6040525050565b60006001600160401b03831115612f2357612f23612ec8565b604051612f3a601f8501601f191660200182612ede565b809150838152848484011115612f4f57600080fd5b83836020830137600060208583010152509392505050565b600060208284031215612f7957600080fd5b81356001600160401b03811115612f8f57600080fd5b8201601f81018413612fa057600080fd5b610b3e84823560208401612f0a565b60005b83811015612fca578181015183820152602001612fb2565b50506000910152565b60008151808452612feb816020860160208601612faf565b601f01601f19169290920160200192915050565b602081526000610ff06020830184612fd3565b60006020828403121561302457600080fd5b5035919050565b801515811461081457600080fd5b6000806040838503121561304c57600080fd5b61305583612e54565b915060208301356130658161302b565b809150509250929050565b60008060006060848603121561308557600080fd5b61308e84612e54565b925061309c60208501612e54565b9150604084013590509250925092565b6000806000606084860312156130c157600080fd5b6130ca84612e54565b95602085013595506040909401359392505050565b60006001600160401b038211156130f8576130f8612ec8565b5060051b60200190565b600082601f83011261311357600080fd5b81356020613120826130df565b60405161312d8282612ede565b80915083815260208101915060208460051b87010193508684111561315157600080fd5b602086015b8481101561316d5780358352918301918301613156565b509695505050505050565b600082601f83011261318957600080fd5b610ff083833560208501612f0a565b600080600080600060a086880312156131b057600080fd5b6131b986612e54565b94506131c760208701612e54565b935060408601356001600160401b03808211156131e357600080fd5b6131ef89838a01613102565b9450606088013591508082111561320557600080fd5b61321189838a01613102565b9350608088013591508082111561322757600080fd5b5061323488828901613178565b9150509295509295909350565b8481528360208201528260408201526080606082015260006132666080830184612fd3565b9695505050505050565b6000806040838503121561328357600080fd5b82356001600160401b038082111561329a57600080fd5b818501915085601f8301126132ae57600080fd5b813560206132bb826130df565b6040516132c88282612ede565b83815260059390931b85018201928281019150898411156132e857600080fd5b948201945b8386101561330d576132fe86612e54565b825294820194908201906132ed565b9650508601359250508082111561332357600080fd5b5061333085828601613102565b9150509250929050565b60008151808452602080850194506020840160005b8381101561336b5781518752958201959082019060010161334f565b509495945050505050565b602081526000610ff0602083018461333a565b6000806000806080858703121561339f57600080fd5b84359350602085013592506040850135915060608501356001600160401b038111156133ca57600080fd5b6133d687828801613178565b91505092959194509250565b6000602082840312156133f457600080fd5b610ff082612e54565b6000806040838503121561341057600080fd5b61341983612e54565b915061342760208401612e54565b90509250929050565b600080600080600060a0868803121561344857600080fd5b61345186612e54565b945061345f60208701612e54565b9350604086013592506060860135915060808601356001600160401b0381111561348857600080fd5b61323488828901613178565b600181811c908216806134a857607f821691505b6020821081036134c857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156113c4576000816000526020600020601f850160051c810160208610156134f75750805b601f850160051c820191505b818110156119b357828155600101613503565b81516001600160401b0381111561352f5761352f612ec8565b6135438161353d8454613494565b846134ce565b602080601f83116001811461357857600084156135605750858301515b600019600386901b1c1916600185901b1785556119b3565b600085815260208120601f198616915b828110156135a757888601518255948401946001909101908401613588565b50858210156135c55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b8181038181111561075c5761075c6135d5565b634e487b7160e01b600052603260045260246000fd5b808202811582820484141761075c5761075c6135d5565b634e487b7160e01b600052601260045260246000fd5b6000826136505761365061362b565b500490565b600080855461366381613494565b6001828116801561367b5760018114613690576136bf565b60ff19841687528215158302870194506136bf565b8960005260208060002060005b858110156136b65781548a82015290840190820161369d565b50505082870194505b5050505084516136d3818360208901612faf565b605f60f81b910190815283516136f0816001840160208801612faf565b61370a60018284010164173539b7b760d91b815260050190565b979650505050505050565b8082018082111561075c5761075c6135d5565b60408152600061373b604083018561333a565b828103602084015261374d818561333a565b95945050505050565b600060018201613768576137686135d5565b5060010190565b60008261377e5761377e61362b565b500690565b60006020828403121561379557600080fd5b8151610ff08161302b565b6001600160a01b03868116825285166020820152604081018490526060810183905260a06080820181905260009061370a90830184612fd3565b6000602082840312156137ec57600080fd5b8151610ff081612e95565b600060033d11156138105760046000803e5060005160e01c5b90565b600060443d10156138215790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561385057505050505090565b82850191508151818111156138685750505050505090565b843d87010160208285010111156138825750505050505090565b61389160208286010187612ede565b509095945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061326690830184612fd3565b6001600160a01b0386811682528516602082015260a0604082018190526000906138fb9083018661333a565b828103606084015261390d818661333a565b905082810360808401526139218185612fd3565b98975050505050505050565b818103613938575050565b6139428254613494565b6001600160401b0381111561395957613959612ec8565b6139678161353d8454613494565b6000601f82116001811461399b57600083156139835750848201545b600019600385901b1c1916600184901b178455610b8c565b600085815260209020601f19841690600086815260209020845b838110156139d557828601548255600195860195909101906020016139b5565b50858310156135c55793015460001960f8600387901b161c19169092555050600190811b01905550565b600060ff821660ff8103613a1557613a156135d5565b6001019291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212204e2f7f377205ebff290475ce617203f95cf0a992686c8d692c57b1538d640b5264736f6c63430008170033

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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