ETH Price: $3,467.93 (+2.18%)
Gas: 14 Gwei

Token

Chain Dreamers (DRE)
 

Overview

Max Total Supply

504 DRE

Holders

190

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
yelow.eth
Balance
1 DRE
0x8513FAfE1813B6ec3BBD9fc4BAF5340bda8D670B
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:
ChainDreamers

Compiler Version
v0.8.8+commit.dddeac2f

Optimization Enabled:
No with 2000 runs

Other Settings:
default evmVersion, MIT license
File 1 of 17 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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

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

File 2 of 17 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

File 3 of 17 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

File 4 of 17 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 5 of 17 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

File 6 of 17 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

File 7 of 17 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

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

File 8 of 17 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

pragma solidity ^0.8.0;

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

File 11 of 17 : ChainDreamers.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol";
import {ERC721Enumerable, ERC721} from "../tokens/ERC721Enumerable.sol";
import "../interfaces/IDreamersRenderer.sol";
import "../interfaces/ICandyShop.sol";
import "../interfaces/IChainRunners.sol";

contract OwnableDelegateProxy {}

contract ProxyRegistry {
    mapping(address => OwnableDelegateProxy) public proxies;
}

contract ChainDreamers is ERC721Enumerable, Ownable, ReentrancyGuard {
    // Linked contracts
    address public renderingContractAddress;
    address public candyShopAddress;
    address public chainRunnersAddress;
    IDreamersRenderer renderer;
    ICandyShop candyShop;
    IChainRunners chainRunners;

    uint8[MAX_NUMBER_OF_TOKENS] public dreamersCandies;
    uint8 private constant candyMask = 252; // "11111100" binary string, last 2 bits kept for candyId
    /// @dev Copied from \@naomsa's contract
    /// @notice OpenSea proxy registry.
    address public opensea;
    /// @notice LooksRare marketplace transfer manager.
    address public looksrare;
    /// @notice Check if marketplaces pre-approve is enabled.
    bool public marketplacesApproved = true;

    mapping(address => bool) proxyToApproved;

    /// @notice Set opensea to `opensea_`.
    function setOpensea(address opensea_) external onlyOwner {
        opensea = opensea_;
    }

    /// @notice Set looksrare to `looksrare_`.
    function setLooksrare(address looksrare_) external onlyOwner {
        looksrare = looksrare_;
    }

    /// @notice Toggle pre-approve feature state for sender.
    function toggleMarketplacesApproved() external onlyOwner {
        marketplacesApproved = !marketplacesApproved;
    }

    /// @notice Approve the communication and interaction with cross-collection interactions.
    function flipProxyState(address proxyAddress) public onlyOwner {
        proxyToApproved[proxyAddress] = !proxyToApproved[proxyAddress];
    }

    /// @dev Modified for opensea and looksrare pre-approve so users can make truly gas less sales.
    function isApprovedForAll(address owner, address operator)
        public
        view
        override
        returns (bool)
    {
        if (!marketplacesApproved)
            return super.isApprovedForAll(owner, operator);

        return
            operator == address(ProxyRegistry(opensea).proxies(owner)) ||
            operator == looksrare ||
            proxyToApproved[operator] ||
            super.isApprovedForAll(owner, operator);
    }

    // Constants
    uint256 public maxDreamersMintPublicSale;
    uint256 public constant MINT_PUBLIC_PRICE = 0.05 ether;
    uint256 public constant MAX_MINT_FOUNDERS = 50;
    bool public foundersMinted = false;

    // State variables
    uint256 public publicSaleStartTimestamp;

    function setPublicSaleTimestamp(uint256 timestamp) external onlyOwner {
        publicSaleStartTimestamp = timestamp;
    }

    function isPublicSaleOpen() public view returns (bool) {
        return
            block.timestamp > publicSaleStartTimestamp &&
            publicSaleStartTimestamp != 0;
    }

    modifier whenPublicSaleActive() {
        require(isPublicSaleOpen(), "Public sale not open");
        _;
    }

    function setRenderingContractAddress(address _renderingContractAddress)
        public
        onlyOwner
    {
        renderingContractAddress = _renderingContractAddress;
        renderer = IDreamersRenderer(renderingContractAddress);
    }

    function setCandyShopAddress(address _candyShopContractAddress)
        public
        onlyOwner
    {
        candyShopAddress = _candyShopContractAddress;
        candyShop = ICandyShop(candyShopAddress);
    }

    function setMaxDreamersMintPublicSale(uint256 _maxDreamersMintPublicSale)
        public
        onlyOwner
    {
        maxDreamersMintPublicSale = _maxDreamersMintPublicSale;
    }

    function setChainRunnersContractAddress(
        address _chainRunnersContractAddress
    ) public onlyOwner {
        chainRunnersAddress = _chainRunnersContractAddress;
        chainRunners = IChainRunners(_chainRunnersContractAddress);
    }

    constructor(string memory name_, string memory symbol_)
        ERC721(name_, symbol_)
    {}

    /// @dev This mint function wraps the safeMintBatch to:
    ///      1) check that the minter owns the runner 2) use the candies 3) burn the candies
    /// @param tokenIds a bytes interpreted as an array of uint16
    /// @param candyIds the same indexes as above but as a uint8 array
    /// @param candyAmounts should be an array of 1
    function mintBatchRunnersAccess(
        bytes calldata tokenIds,
        uint256[] calldata candyIds,
        uint256[] calldata candyAmounts
    ) public nonReentrant returns (bool) {
        require(
            tokenIds.length == candyIds.length * 2,
            "Each runner needs one and only one candy"
        );

        safeMintBatch(_msgSender(), tokenIds);

        bytes32 candies = keccak256(
            abi.encodePacked(
                tokenIds,
                msg.sender,
                candyIds,
                block.timestamp,
                block.difficulty
            )
        );
        for (uint256 i = 0; i < candyIds.length; i++) {
            uint16 tokenId = BytesLib.toUint16(tokenIds, i * 2);
            // ownerOf uses a simple mapping in OZ's ERC721 so should be cheap
            require(
                chainRunners.ownerOf(tokenId) == _msgSender(),
                "You cannot give candies to a runner that you do not own"
            );
            require(
                candyAmounts[i] == 1,
                "Your runner needs one and only one candy, who knows what could happen otherwise"
            );
            dreamersCandies[tokenId] =
                (uint8(candies[i % 32]) & candyMask) +
                (uint8(candyIds[i]) % 4);
            if (i % 32 == 31) {
                candies = keccak256(abi.encodePacked(candies));
            }
        }

        candyShop.burnBatch(_msgSender(), candyIds, candyAmounts);
        return true;
    }

    function mintBatchPublicSale(bytes calldata tokenIds)
        public
        payable
        nonReentrant
        whenPublicSaleActive
        returns (bool)
    {
        require(
            (tokenIds.length / 2) * MINT_PUBLIC_PRICE == msg.value,
            "You have to pay the bail bond"
        );
        require(
            ERC721.balanceOf(_msgSender()) + tokenIds.length / 2 <=
                maxDreamersMintPublicSale,
            "Your home is to small to welcome so many dreamers"
        );
        safeMintBatch(_msgSender(), tokenIds);

        bytes32 candies = keccak256(
            abi.encodePacked(
                tokenIds,
                msg.sender,
                msg.value,
                block.timestamp,
                block.difficulty
            )
        );
        for (uint256 i = 0; i < tokenIds.length; i += 2) {
            uint16 tokenId = BytesLib.toUint16(tokenIds, i);
            dreamersCandies[tokenId] = uint8(candies[i / 2]);
        }

        return true;
    }

    function mintBatchFounders(bytes calldata tokenIds)
        public
        nonReentrant
        onlyOwner
        whenPublicSaleActive
        returns (bool)
    {
        require(!foundersMinted, "Don't be too greedy");
        require(
            tokenIds.length <= MAX_MINT_FOUNDERS * 2,
            "Even if you are a founder, you don't deserve that many Dreamers"
        );
        safeMintBatch(_msgSender(), tokenIds);

        bytes32 candies = keccak256(
            abi.encodePacked(
                tokenIds,
                msg.sender,
                block.timestamp,
                block.difficulty
            )
        );
        for (uint256 i = 0; i < tokenIds.length / 2; i++) {
            uint16 tokenId = BytesLib.toUint16(tokenIds, i * 2);
            dreamersCandies[tokenId] = uint8(candies[i % 32]);
            if (i % 32 == 31) {
                candies = keccak256(abi.encodePacked(candies));
            }
        }
        foundersMinted = true;
        return true;
    }

    function tokenURI(uint256 _tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(uint16(_tokenId)),
            "ERC721: URI query for nonexistent token"
        );

        if (renderingContractAddress == address(0)) {
            return "";
        }

        return renderer.tokenURI(_tokenId, dreamersCandies[_tokenId]);
    }

    receive() external payable {}

    function withdraw() public onlyOwner {
        (bool success, ) = _msgSender().call{value: address(this).balance}("");
        require(success, "Withdrawal failed");
    }
}

File 12 of 17 : ICandyShop.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface ICandyShop {
    function burnBatch(
        address from,
        uint256[] calldata tokenIds,
        uint256[] calldata amounts
    ) external;

    function burn(
        address from,
        uint256 tokenId,
        uint256 amount
    ) external;
}

File 13 of 17 : IChainRunners.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface IChainRunners {
    function getDna(uint256 _tokenId) external view returns (uint256);

    function ownerOf(uint256 tokenId) external view returns (address);
}

File 14 of 17 : IDreamersRenderer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

interface IDreamersRenderer {
    function tokenURI(uint256 tokenId, uint8 candy)
        external
        view
        returns (string memory);
}

File 15 of 17 : ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "solidity-bytes-utils/contracts/BytesLib.sol";
import "@openzeppelin/contracts/utils/Address.sol";

/**
 * @title ERC-721 Non-Fungible Token optimized for batch minting
 * @notice a bytes2 (uint16) is used to store the token id so the collection should be lower than 2^16 = 65536 items
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 *      Based on the study for writing indexes and addresses, we use a single mapping for storing all the data
 *      We use the uint16 / bytes2 tokenId
 */
abstract contract ERC721 is IERC721, IERC721Metadata, Context, ERC165 {
    using Address for address;

    // Mapping from address to tokenIds. This is the single source of truth for the data
    mapping(address => bytes) internal _tokensByOwner;

    // Because mapping in solidity are not real hash tables, one needs to keep track of the keys.
    // One address is 20 bytes
    bytes internal owners;

    // Number of tokens
    uint16 public constant MAX_NUMBER_OF_TOKENS = 10_000;

    // Bool array to store if the token is minted. To save on gas for token lookup in _tokensByOwner.
    bool[MAX_NUMBER_OF_TOKENS] internal tokenExists;

    // Mapping from token ID to approved address
    mapping(uint16 => address) internal _tokenApprovals;

    string private _name;
    string private _symbol;

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

    function name() external view override returns (string memory) {
        return _name;
    }

    function symbol() external view override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC165, IERC165)
        returns (bool)
    {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev There are two bytes per tokenId
     * @param owner address The address we retrieve the balance for
     * @return uint256 The number of tokens owned by the address
     */
    function balanceOf(address owner) public view override returns (uint256) {
        return _tokensByOwner[owner].length / 2;
    }

    function _balanceOf(uint256 ownerIndex) internal view returns (uint256) {
        require(ownerIndex < owners.length, "ERC721: ownerIndex out of bound");
        return balanceOf(BytesLib.toAddress(owners, ownerIndex));
    }

    /// @dev Returns the index of owner in the internal array of owners. Revert if not found.
    /// @param owner address The address we retrieve the index for
    function getOwnerIndex(address owner) public view returns (uint256) {
        uint256 index = 0;
        while (index < owners.length) {
            if (BytesLib.toAddress(owners, index) == owner) {
                return index / 20;
            }
            index += 20;
        }
        revert("ERC721: Owner not found");
    }

    /// @dev Returns the array of bool telling if a token exists or not.
    function getTokenExists()
        external
        view
        returns (bool[MAX_NUMBER_OF_TOKENS] memory)
    {
        return tokenExists;
    }

    /**
     * @param tokenId uint16 A given token id
     * @return bool True if the token exists, false otherwise
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return tokenExists[tokenId];
    }

    /**
     * @dev This is copied from OpenZeppelin's implementation
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try
                IERC721Receiver(to).onERC721Received(
                    _msgSender(),
                    from,
                    tokenId,
                    _data
                )
            returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert(
                        "ERC721: transfer to non ERC721Receiver implementer"
                    );
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
        return true;
    }

    /// @dev This is the core unsafe implementation of a transfer.
    /// @param from address The address which you want to transfer the token from
    /// @param fromIndex uint256 The index of "from" in the owners bytes. This is to avoid a search in the array.
    /// @param to address The address which you want to transfer the token to
    /// @param tokenIndex uint256 The index of the token to transfer in the from's token list.
    function _transfer(
        address from,
        uint256 fromIndex,
        address to,
        uint256 tokenIndex
    ) private {
        require(
            BytesLib.toAddress(owners, fromIndex * 20) == from,
            "ERC721: transfer from address is invalid"
        );
        if (_tokensByOwner[to].length == 0) {
            owners = bytes.concat(owners, bytes20(to));
        }
        bytes memory tokenId = BytesLib.slice(
            _tokensByOwner[from],
            tokenIndex,
            tokenIndex + 2
        );
        if (_tokensByOwner[from].length == 2) {
            owners = bytes.concat(
                BytesLib.slice(owners, 0, fromIndex * 20),
                BytesLib.slice(
                    owners,
                    (fromIndex + 1) * 20,
                    owners.length - (fromIndex + 1) * 20
                )
            );
            delete _tokensByOwner[from];
        } else {
            _tokensByOwner[from] = bytes.concat(
                BytesLib.slice(_tokensByOwner[from], 0, tokenIndex),
                BytesLib.slice(
                    _tokensByOwner[from],
                    tokenIndex + 2,
                    _tokensByOwner[from].length - tokenIndex - 2
                )
            );
        }
        _tokensByOwner[to] = bytes.concat(_tokensByOwner[to], tokenId);
        emit Transfer(from, to, BytesLib.toUint16(tokenId, 0));
    }

    /// @dev Transfer token with minimal computing since all the required data to check is given
    /// @param from address The address which you want to transfer the token from
    /// @param fromIndex uint256 The index of "from" in the owners bytes. This is to avoid a search in the array.
    /// @param to address The address which you want to transfer the token to
    /// @param tokenIndex uint256 The index of the token to transfer in the from's token list.
    function safeTransferFrom(
        address from,
        uint256 fromIndex,
        address to,
        uint256 tokenIndex
    ) external {
        require(from != address(0), "ERC721: from cannot be the zero address");
        require(to != address(0), "ERC721: to cannot be the zero address");
        require(
            tokenIndex < _tokensByOwner[from].length / 2,
            "ERC721: token index out of range"
        );
        uint16 tokenId = BytesLib.toUint16(
            _tokensByOwner[from],
            tokenIndex * 2
        );
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );
        _transfer(from, fromIndex, to, tokenIndex);
        _checkOnERC721Received(from, to, tokenId, "");
    }

    /**
     * @dev This is the core unsafe implementation of a mint.
     * @param to address The receiver of the tokens
     * @param tokenIds bytes The token ids to mint
     */
    function _mintBatch(address to, bytes calldata tokenIds) private {
        require(tokenIds.length > 0, "ERC721: cannot mint with no token Ids");
        require(
            tokenIds.length % 2 == 0,
            "ERC721: tokenIds should be bytes of uint16"
        );
        if (_tokensByOwner[to].length == 0) {
            owners = bytes.concat(owners, bytes20(to));
        }
        for (uint256 i = 0; i < tokenIds.length; i += 2) {
            require(
                !tokenExists[BytesLib.toUint16(tokenIds, i)],
                "ERC721: token already exists"
            );
            tokenExists[BytesLib.toUint16(tokenIds, i)] = true;
            emit Transfer(address(0), to, BytesLib.toUint16(tokenIds, i));
        }
        _tokensByOwner[to] = bytes.concat(_tokensByOwner[to], tokenIds);
    }

    /// @dev Add a batch of token Ids given as a bytes array to the sender
    /// @param to address minting token to this address
    /// @param tokenIds bytes a bytes of tokenIds as bytes2 (uint16)
    function safeMintBatch(address to, bytes calldata tokenIds)
        internal
        virtual
    {
        _mintBatch(to, tokenIds);
        _checkOnERC721Received(
            address(0),
            to,
            BytesLib.toUint16(tokenIds, 0),
            ""
        );
    }

    /// @dev Approve "to" to manage token Id
    /// @param to address The address which will manage the token Id
    /// @param tokenId uint256 The token Id to manage
    /// @param tokenIndex uint256 The index of the token in the owner's list
    function approve(
        address to,
        uint256 tokenId,
        uint256 tokenIndex
    ) external {
        if (_tokenApprovals[uint16(tokenId)] != _msgSender()) {
            // if sender is not approved, they need to be the owner
            require(
                tokenIndex * 2 < _tokensByOwner[_msgSender()].length,
                "ERC721: token index out of range"
            );
            require(
                BytesLib.toUint16(
                    _tokensByOwner[_msgSender()],
                    tokenIndex * 2
                ) == tokenId,
                "ERC721: caller is neither approved nor owner"
            );
            emit Approval(_msgSender(), to, tokenId);
        }
        _tokenApprovals[uint16(tokenId)] = to;
    }

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId)
        public
        view
        override
        returns (address)
    {
        require(_exists(tokenId), "ERC721: token does not exist");
        return _tokenApprovals[uint16(tokenId)];
    }

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     * @param operator The address of the operator to add or remove.
     * @param _approved Whether to add or remove `operator` as an operator.
     */
    function setApprovalForAll(address operator, bool _approved)
        external
        override
    {
        require(
            operator != _msgSender(),
            "ERC721: cannot approve caller as operator"
        );
        bytes memory tokens = _tokensByOwner[_msgSender()];
        for (uint256 i = 0; i < tokens.length; i += 2) {
            _tokenApprovals[BytesLib.toUint16(tokens, i)] = _approved
                ? operator
                : address(0);
        }

        emit ApprovalForAll(_msgSender(), operator, _approved);
    }

    /**
     * @dev Returns whether `operator` is an approved operator for the caller.
     * @param owner The address of the owner to check.
     * @param operator The address of the operator to check.
     */
    function isApprovedForAll(address owner, address operator)
        public
        view
        virtual
        override
        returns (bool)
    {
        bytes memory tokens = _tokensByOwner[owner];
        for (uint256 i = 0; i < tokens.length; i += 2) {
            if (_tokenApprovals[BytesLib.toUint16(tokens, i)] != operator) {
                return false;
            }
        }
        return true;
    }

    /// @dev Copied from OpenZeppelin ERC721.sol
    function _isApprovedOrOwner(address spender, uint256 tokenId)
        internal
        view
        virtual
        returns (bool)
    {
        require(
            _exists(tokenId),
            "ERC721: operator query for nonexistent token"
        );
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner ||
            getApproved(tokenId) == spender ||
            isApprovedForAll(owner, spender));
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Functions that should not be used but here for compatibility with ERC721
    // These are gassy.
    ///////////////////////////////////////////////////////////////////////////////

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal {
        require(from != address(0), "ERC721: from cannot be the zero address");
        require(to != address(0), "ERC721: to cannot be the zero address");
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );
        uint256 tokenIndex = 0;
        while (
            BytesLib.toUint16(_tokensByOwner[from], tokenIndex) != tokenId &&
            tokenIndex < _tokensByOwner[from].length
        ) {
            tokenIndex += 2;
        }
        require(
            tokenIndex < _tokensByOwner[from].length,
            "ERC721: from does not own the token"
        );

        uint256 fromIndex;
        for (fromIndex = 0; fromIndex < owners.length; fromIndex += 20) {
            if (BytesLib.toAddress(owners, fromIndex) == from) {
                break;
            }
        }
        require(
            BytesLib.toAddress(owners, fromIndex) == from,
            "ERC721: from is not in owners list"
        );
        _transfer(from, fromIndex, to, tokenIndex);
        _checkOnERC721Received(from, to, tokenId, data);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external override {
        _safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) external override {
        _safeTransferFrom(from, to, tokenId, data);
    }

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external override {
        require(from != address(0), "ERC721: from cannot be the zero address");
        require(to != address(0), "ERC721: to cannot be the zero address");
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );
        uint256 tokenIndex = 0;
        while (
            BytesLib.toUint16(_tokensByOwner[from], tokenIndex) != tokenId &&
            tokenIndex < _tokensByOwner[from].length
        ) {
            tokenIndex += 2;
        }
        require(
            tokenIndex < _tokensByOwner[from].length,
            "ERC721: from does not own the token"
        );

        uint256 fromIndex;
        for (fromIndex = 0; fromIndex < owners.length; fromIndex += 20) {
            if (BytesLib.toAddress(owners, fromIndex) == from) {
                break;
            }
        }
        require(
            BytesLib.toAddress(owners, fromIndex) == from,
            "ERC721: from is not in owners list"
        );
        _transfer(from, fromIndex, to, tokenIndex);
    }

    /**
     * @dev For each owner, we go through all their tokens and check if the sought token is in the list. This lookup
     *      is gassy but we do not expect to pay them often as we provide other mean of doing the transfers.
     * @param tokenId uint16 A given token id
     * @return address The owner of the token, might be 0x0 if not found
     */
    function _ownerOf(uint256 tokenId) private view returns (address) {
        address owner = address(0);
        for (uint256 i = 0; i < owners.length; i += 20) {
            address currentOwner = BytesLib.toAddress(owners, i);
            for (
                uint256 j = 0;
                j < _tokensByOwner[currentOwner].length;
                j += 2
            ) {
                if (
                    BytesLib.toUint16(_tokensByOwner[currentOwner], j) ==
                    tokenId
                ) {
                    owner = currentOwner;
                    break;
                }
            }
            if (owner != address(0)) {
                break;
            }
        }
        return owner;
    }

    /**
     * @dev This is the public ownerOf, see IERC721. We fail fast with the initial check. There is no good
     *      reason to call this function on chain.
     * @param tokenId uint265 A given token id
     * @return address The owner of the token.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        require(_exists(tokenId), "ERC721: owner query for nonexistent token");
        return _ownerOf(tokenId);
    }

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external override {
        address owner = _ownerOf(tokenId);
        require(
            owner != address(0),
            "ERC721: approve query for nonexistent token"
        );
        require(
            _tokenApprovals[uint16(tokenId)] == _msgSender() ||
                owner == _msgSender(),
            "ERC721: caller is not the owner nor an approved operator for the token"
        );
        _tokenApprovals[uint16(tokenId)] = to;
        emit Approval(owner, to, tokenId);
    }
}

File 16 of 17 : ERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {ERC721} from "./ERC721.sol";
import {IERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "solidity-bytes-utils/contracts/BytesLib.sol";

/**
 * @title ERC-721 Non-Fungible Token optimized for batch minting with enumerable interface
 * @notice a bytes2 (uint16) is used to store the token id so the collection should be lower than 2^16 = 65536 items
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 *      Based on the study for writing indexes and addresses, we use a single mapping for storing all the data
 *      We use the uint16 / bytes2 tokenId
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    function totalSupply() external view override returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < owners.length; i += 20) {
            total += _balanceOf(i);
        }
        return total;
    }

    function tokenOfOwnerByIndex(address owner, uint256 index)
        external
        view
        override
        returns (uint256 tokenId)
    {
        require(
            index * 2 < _tokensByOwner[owner].length,
            "ERC721Enumerable: index out of range"
        );
        return BytesLib.toUint16(_tokensByOwner[owner], index * 2);
    }

    function tokenByIndex(uint256 index)
        external
        view
        override
        returns (uint256)
    {
        uint256 ownerIndex = 0;
        uint256 count;
        while (count <= index) {
            count += _balanceOf(ownerIndex);
            ownerIndex += 20;
        }
        ownerIndex -= 20;
        count -= _balanceOf(ownerIndex);
        return
            BytesLib.toUint16(
                _tokensByOwner[BytesLib.toAddress(owners, ownerIndex)],
                (index - count) * 2
            );
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(IERC165, ERC721)
        returns (bool)
    {
        return
            interfaceId == type(IERC721Enumerable).interfaceId ||
            super.supportsInterface(interfaceId);
    }
}

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


library BytesLib {
    function concat(
        bytes memory _preBytes,
        bytes memory _postBytes
    )
        internal
        pure
        returns (bytes memory)
    {
        bytes memory tempBytes;

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

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(0x40, and(
              add(add(end, iszero(add(length, mload(_preBytes)))), 31),
              not(31) // Round down to the nearest 32 bytes.
            ))
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes.slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes.slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                    sc,
                    add(
                        and(
                            fslot,
                            0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
                        ),
                        and(mload(mc), mask)
                    )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))

                for {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

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

        bytes memory tempBytes;

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

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

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

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

                mstore(tempBytes, _length)

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

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

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

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

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

        return tempUint;
    }

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

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

        return tempUint;
    }

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

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

        return tempUint;
    }

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

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

        return tempUint;
    }

    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
        require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
        uint96 tempUint;

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

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

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

        return tempUint;
    }

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

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

        return tempUint;
    }

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

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

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                // the next line is the loop condition:
                // while(uint256(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(
        bytes storage _preBytes,
        bytes memory _postBytes
    )
        internal
        view
        returns (bool)
    {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes.slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes.slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint256(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "details": {
      "constantOptimizer": true,
      "cse": true,
      "deduplicate": true,
      "inliner": true,
      "jumpdestRemover": true,
      "orderLiterals": true,
      "peephole": true,
      "yul": true,
      "yulDetails": {
        "optimizerSteps": "dhfoDgvulfnTUtnIf",
        "stackAllocation": true
      }
    },
    "runs": 2000
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_MINT_FOUNDERS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NUMBER_OF_TOKENS","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PUBLIC_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"tokenIndex","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"candyShopAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainRunnersAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dreamersCandies","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"name":"flipProxyState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"foundersMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getOwnerIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenExists","outputs":[{"internalType":"bool[10000]","name":"","type":"bool[10000]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicSaleOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"looksrare","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketplacesApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDreamersMintPublicSale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"tokenIds","type":"bytes"}],"name":"mintBatchFounders","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"tokenIds","type":"bytes"}],"name":"mintBatchPublicSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"tokenIds","type":"bytes"},{"internalType":"uint256[]","name":"candyIds","type":"uint256[]"},{"internalType":"uint256[]","name":"candyAmounts","type":"uint256[]"}],"name":"mintBatchRunnersAccess","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"opensea","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renderingContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"fromIndex","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenIndex","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_candyShopContractAddress","type":"address"}],"name":"setCandyShopAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_chainRunnersContractAddress","type":"address"}],"name":"setChainRunnersContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"looksrare_","type":"address"}],"name":"setLooksrare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxDreamersMintPublicSale","type":"uint256"}],"name":"setMaxDreamersMintPublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"opensea_","type":"address"}],"name":"setOpensea","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"setPublicSaleTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_renderingContractAddress","type":"address"}],"name":"setRenderingContractAddress","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":"toggleMarketplacesApproved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052610280805460ff60a01b1916600160a01b179055610283805460ff191690553480156200003057600080fd5b5060405162005677380380620056778339810160408190526200005391620002e9565b8151829082906200006d9061013c90602085019062000106565b508051620000849061013d90602084019062000106565b505050620000a16200009b620000af60201b60201c565b620000b3565b5050600161013f55620003ac565b3390565b61013e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805462000114906200037b565b90600052602060002090601f01602090048101928262000138576000855562000183565b82601f106200015357805160ff191683800117855562000183565b8280016001018555821562000183579182015b828111156200018357825182559160200191906001019062000166565b506200019192915062000195565b5090565b5b8082111562000191576000815560010162000196565b634e487b7160e01b600052604160045260246000fd5b601f19601f83011681016001600160401b0381118282101715620001ea57620001ea620001ac565b6040525050565b6000620001fd60405190565b90506200020b8282620001c2565b919050565b60006001600160401b038211156200022c576200022c620001ac565b601f19601f83011660200192915050565b60005b838110156200025a57818101518382015260200162000240565b838111156200026a576000848401525b50505050565b600062000287620002818462000210565b620001f1565b905082815260208101848484011115620002a457620002a4600080fd5b620002b18482856200023d565b509392505050565b600082601f830112620002cf57620002cf600080fd5b8151620002e184826020860162000270565b949350505050565b60008060408385031215620003015762000301600080fd5b82516001600160401b038111156200031c576200031c600080fd5b6200032a85828601620002b9565b602085015190935090506001600160401b038111156200034d576200034d600080fd5b6200035b85828601620002b9565b9150509250929050565b634e487b7160e01b600052602260045260246000fd5b6002810460018216806200039057607f821691505b60208210811415620003a657620003a662000365565b50919050565b6152bb80620003bc6000396000f3fe60806040526004361061032d5760003560e01c806370a08231116101a5578063b776c8a6116100ec578063d7822c9911610095578063f2fde38b1161006f578063f2fde38b146108ec578063f4b994241461090c578063f73c814b1461091f578063fac913231461093f57600080fd5b8063d7822c991461089a578063e985e9c5146108b1578063f0658ac9146108d157600080fd5b8063c87b56dd116100c6578063c87b56dd1461083a578063cb95f0691461085a578063d3d6005b1461087a57600080fd5b8063b776c8a6146107d9578063b88d4fde146107f9578063c074f4121461081957600080fd5b806395d89b411161014e578063a22cb46511610128578063a22cb46514610778578063a8e90b5714610798578063b5fcb339146107b957600080fd5b806395d89b41146107265780639913fc631461073b5780639c51792a1461075d57600080fd5b806389c8af831161017f57806389c8af83146106c75780638da5cb5b146106e75780639343eaa61461070657600080fd5b806370a0823114610671578063715018a6146106915780638392d804146106a657600080fd5b806323b872dd1161027457806342842e0e1161021d578063511ed382116101f7578063511ed382146105ec578063633574db1461060d5780636352211e1461063a5780636b318e6e1461065a57600080fd5b806342842e0e1461058c5780634f6ccce7146105ac578063511a9605146105cc57600080fd5b806333c12e171161024e57806333c12e17146105425780633ccfd60b14610557578063426a84931461056c57600080fd5b806323b872dd146104e257806325174f0e146105025780632f745c591461052257600080fd5b80630d77c756116102d65780631a6949e3116102b05780631a6949e3146104985780631e8858fb146104ad57806322afee07146104cd57600080fd5b80630d77c7561461043657806312b40a9f1461045657806318160ddd1461047657600080fd5b806306fdde031161030757806306fdde03146103c5578063081812fc146103e7578063095ea7b31461041457600080fd5b806301ffc9a7146103395780630216e3041461036f578063026ae1021461039257600080fd5b3661033457005b600080fd5b34801561034557600080fd5b506103596103543660046138e0565b610960565b604051610366919061390b565b60405180910390f35b34801561037b57600080fd5b5061038561271081565b6040516103669190613923565b34801561039e57600080fd5b50610280546103599074010000000000000000000000000000000000000000900460ff1681565b3480156103d157600080fd5b506103da6109bc565b604051610366919061398f565b3480156103f357600080fd5b506104076104023660046139b1565b610a4f565b60405161036691906139ec565b34801561042057600080fd5b5061043461042f366004613a0e565b610aa0565b005b34801561044257600080fd5b506104346104513660046139b1565b610b91565b34801561046257600080fd5b50610434610471366004613a4b565b610bc2565b34801561048257600080fd5b5061048b610c28565b6040516103669190613a72565b3480156104a457600080fd5b50610359610c70565b3480156104b957600080fd5b506104346104c8366004613a4b565b610c8b565b3480156104d957600080fd5b5061048b603281565b3480156104ee57600080fd5b506104346104fd366004613a80565b610ce6565b34801561050e57600080fd5b5061048b61051d366004613a4b565b610fc7565b34801561052e57600080fd5b5061048b61053d366004613a0e565b611046565b34801561054e57600080fd5b50610434611156565b34801561056357600080fd5b506104346111cf565b34801561057857600080fd5b50610434610587366004613ad0565b611265565b34801561059857600080fd5b506104346105a7366004613a80565b611388565b3480156105b857600080fd5b5061048b6105c73660046139b1565b6113a8565b3480156105d857600080fd5b506104346105e73660046139b1565b611563565b3480156105f857600080fd5b5061027f54610407906001600160a01b031681565b34801561061957600080fd5b5061062d6106283660046139b1565b611594565b6040516103669190613b0e565b34801561064657600080fd5b506104076106553660046139b1565b6115c0565b34801561066657600080fd5b5061048b6102825481565b34801561067d57600080fd5b5061048b61068c366004613a4b565b6115f0565b34801561069d57600080fd5b50610434611622565b3480156106b257600080fd5b5061014254610407906001600160a01b031681565b3480156106d357600080fd5b506104346106e2366004613b1c565b611659565b3480156106f357600080fd5b5061013e546001600160a01b0316610407565b34801561071257600080fd5b50610359610721366004613bd2565b61177c565b34801561073257600080fd5b506103da6119ae565b34801561074757600080fd5b506107506119be565b6040516103669190613c5d565b34801561076957600080fd5b5061048b66b1a2bc2ec5000081565b34801561078457600080fd5b50610434610793366004613c80565b611a1b565b3480156107a457600080fd5b5061028054610407906001600160a01b031681565b3480156107c557600080fd5b506104346107d4366004613a4b565b611ba9565b3480156107e557600080fd5b506104346107f4366004613a4b565b611c0f565b34801561080557600080fd5b50610434610814366004613dae565b611c6a565b34801561082557600080fd5b5061014054610407906001600160a01b031681565b34801561084657600080fd5b506103da6108553660046139b1565b611c7c565b34801561086657600080fd5b50610359610875366004613e6c565b611d7b565b34801561088657600080fd5b50610434610895366004613a4b565b6120c0565b3480156108a657600080fd5b5061048b6102845481565b3480156108bd57600080fd5b506103596108cc366004613f19565b612126565b3480156108dd57600080fd5b50610283546103599060ff1681565b3480156108f857600080fd5b50610434610907366004613a4b565b612258565b61035961091a366004613bd2565b6122b2565b34801561092b57600080fd5b5061043461093a366004613a4b565b612488565b34801561094b57600080fd5b5061014154610407906001600160a01b031681565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d630000000000000000000000000000000000000000000000000000000014806109b657506109b6826124dd565b92915050565b606061013c80546109cc90613f62565b80601f01602080910402602001604051908101604052809291908181526020018280546109f890613f62565b8015610a455780601f10610a1a57610100808354040283529160200191610a45565b820191906000526020600020905b815481529060010190602001808311610a2857829003601f168201915b5050505050905090565b6000610a5a826125c0565b610a7f5760405162461bcd60e51b8152600401610a7690613fbb565b60405180910390fd5b5061ffff16600090815261013b60205260409020546001600160a01b031690565b6000610aab826125f2565b90506001600160a01b038116610ad35760405162461bcd60e51b8152600401610a7690614025565b61ffff8216600090815261013b60205260409020546001600160a01b0316331480610b0657506001600160a01b03811633145b610b225760405162461bcd60e51b8152600401610a76906140b5565b61ffff8216600090815261013b6020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b61013e546001600160a01b03163314610bbc5760405162461bcd60e51b8152600401610a76906140f5565b61028255565b61013e546001600160a01b03163314610bed5760405162461bcd60e51b8152600401610a76906140f5565b61014080546001600160a01b0390921673ffffffffffffffffffffffffffffffffffffffff1992831681179091556101438054909216179055565b600080805b60018054610c3a90613f62565b9050811015610c6a57610c4c816126cd565b610c56908361411b565b9150610c6360148261411b565b9050610c2d565b50919050565b60006102845442118015610c8657506102845415155b905090565b61013e546001600160a01b03163314610cb65760405162461bcd60e51b8152600401610a76906140f5565b610280805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6001600160a01b038316610d0c5760405162461bcd60e51b8152600401610a769061418b565b6001600160a01b038216610d325760405162461bcd60e51b8152600401610a76906141f3565b610d3c3382612793565b610d585760405162461bcd60e51b8152600401610a769061425b565b60005b6001600160a01b038416600090815260208190526040902080548391610e0891610d8490613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054610db090613f62565b8015610dfd5780601f10610dd257610100808354040283529160200191610dfd565b820191906000526020600020905b815481529060010190602001808311610de057829003601f168201915b505050505083612818565b61ffff1614158015610e3d57506001600160a01b03841660009081526020819052604090208054610e3890613f62565b905081105b15610e5457610e4d60028261411b565b9050610d5b565b6001600160a01b03841660009081526020819052604090208054610e7790613f62565b90508110610e975760405162461bcd60e51b8152600401610a76906142c3565b60005b60018054610ea790613f62565b9050811015610f7457846001600160a01b0316610f4e60018054610eca90613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054610ef690613f62565b8015610f435780601f10610f1857610100808354040283529160200191610f43565b820191906000526020600020905b815481529060010190602001808311610f2657829003601f168201915b50505050508361284e565b6001600160a01b03161415610f6257610f74565b610f6d60148261411b565b9050610e9a565b846001600160a01b0316610f8e60018054610eca90613f62565b6001600160a01b031614610fb45760405162461bcd60e51b8152600401610a769061432b565b610fc085828685612894565b5050505050565b6000805b60018054610fd890613f62565b905081101561102e57826001600160a01b0316610ffb60018054610eca90613f62565b6001600160a01b0316141561101c57611015601482614351565b9392505050565b61102760148261411b565b9050610fcb565b60405162461bcd60e51b8152600401610a7690614397565b6001600160a01b0382166000908152602081905260408120805461106990613f62565b90506110768360026143a7565b106110935760405162461bcd60e51b8152600401610a769061441e565b6001600160a01b0383166000908152602081905260409020805461114b91906110bb90613f62565b80601f01602080910402602001604051908101604052809291908181526020018280546110e790613f62565b80156111345780601f1061110957610100808354040283529160200191611134565b820191906000526020600020905b81548152906001019060200180831161111757829003601f168201915b505050505083600261114691906143a7565b612818565b61ffff169392505050565b61013e546001600160a01b031633146111815760405162461bcd60e51b8152600401610a76906140f5565b61028080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff8116740100000000000000000000000000000000000000009182900460ff1615909102179055565b61013e546001600160a01b031633146111fa5760405162461bcd60e51b8152600401610a76906140f5565b604051600090339047908381818185875af1925050503d806000811461123c576040519150601f19603f3d011682016040523d82523d6000602084013e611241565b606091505b50509050806112625760405162461bcd60e51b8152600401610a7690614460565b50565b61ffff8216600090815261013b60205260409020546001600160a01b031633146113475733600090815260208190526040902080546112a390613f62565b90506112b08260026143a7565b106112cd5760405162461bcd60e51b8152600401610a76906144a0565b336000908152602081905260409020805483916112ed916110bb90613f62565b61ffff161461130e5760405162461bcd60e51b8152600401610a7690614508565b60405182906001600160a01b0385169033907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590600090a45b5061ffff16600090815261013b60205260409020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6113a383838360405180602001604052806000815250612f24565b505050565b600080805b8381116113db576113bd826126cd565b6113c7908261411b565b90506113d460148361411b565b91506113ad565b6113e6601483614518565b91506113f1826126cd565b6113fb9082614518565b90506115576000806114976001805461141390613f62565b80601f016020809104026020016040519081016040528092919081815260200182805461143f90613f62565b801561148c5780601f106114615761010080835404028352916020019161148c565b820191906000526020600020905b81548152906001019060200180831161146f57829003601f168201915b50505050508661284e565b6001600160a01b03166001600160a01b0316815260200190815260200160002080546114c290613f62565b80601f01602080910402602001604051908101604052809291908181526020018280546114ee90613f62565b801561153b5780601f106115105761010080835404028352916020019161153b565b820191906000526020600020905b81548152906001019060200180831161151e57829003601f168201915b5050505050828661154c9190614518565b6111469060026143a7565b61ffff16949350505050565b61013e546001600160a01b0316331461158e5760405162461bcd60e51b8152600401610a76906140f5565b61028455565b6101468161271081106115a657600080fd5b60209182820401919006915054906101000a900460ff1681565b60006115cb826125c0565b6115e75760405162461bcd60e51b8152600401610a7690614587565b6109b6826125f2565b6001600160a01b038116600090815260208190526040812080546002919061161790613f62565b6109b6929150614351565b61013e546001600160a01b0316331461164d5760405162461bcd60e51b8152600401610a76906140f5565b611657600061310b565b565b6001600160a01b03841661167f5760405162461bcd60e51b8152600401610a769061418b565b6001600160a01b0382166116a55760405162461bcd60e51b8152600401610a76906141f3565b6001600160a01b03841660009081526020819052604090208054600291906116cc90613f62565b6116d7929150614351565b81106116f55760405162461bcd60e51b8152600401610a76906144a0565b6001600160a01b0384166000908152602081905260408120805461171d91906110bb90613f62565b905061172d338261ffff16612793565b6117495760405162461bcd60e51b8152600401610a769061425b565b61175585858585612894565b61177485848361ffff166040518060200160405280600081525061316b565b505050505050565b6000600261013f5414156117a25760405162461bcd60e51b8152600401610a76906145c9565b600261013f5561013e546001600160a01b031633146117d35760405162461bcd60e51b8152600401610a76906140f5565b6117db610c70565b6117f75760405162461bcd60e51b8152600401610a769061460b565b6102835460ff161561181b5760405162461bcd60e51b8152600401610a769061464d565b611827603260026143a7565b8211156118465760405162461bcd60e51b8152600401610a76906146b5565b611852335b84846132c2565b6000838333424460405160200161186d9594939291906146fb565b60405160208183030381529060405280519060200120905060005b611893600285614351565b81101561198d5760006118e386868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111469250869150600290506143a7565b9050826118f1602084614738565b6020811061190157611901614750565b1a61014661ffff8316612710811061191b5761191b614750565b602091828204019190066101000a81548160ff021916908360ff1602179055506020826119489190614738565b601f141561197a57826040516020016119619190614766565b6040516020818303038152906040528051906020012092505b508061198581614778565b915050611888565b5050610283805460ff191660019081179091559050600161013f5592915050565b606061013d80546109cc90613f62565b6119c66137b6565b604080516204e2008101918290529060029061271090826000855b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116119e15790505050505050905090565b6001600160a01b038216331415611a445760405162461bcd60e51b8152600401610a76906147eb565b3360009081526020819052604081208054611a5e90613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8a90613f62565b8015611ad75780601f10611aac57610100808354040283529160200191611ad7565b820191906000526020600020905b815481529060010190602001808311611aba57829003601f168201915b5050505050905060005b8151811015611b585782611af6576000611af8565b835b61013b6000611b078585612818565b61ffff1681526020810191909152604001600020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055611b5160028261411b565b9050611ae1565b506001600160a01b038316336001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3184604051611b9c919061390b565b60405180910390a3505050565b61013e546001600160a01b03163314611bd45760405162461bcd60e51b8152600401610a76906140f5565b61014180546001600160a01b0390921673ffffffffffffffffffffffffffffffffffffffff1992831681179091556101448054909216179055565b61013e546001600160a01b03163314611c3a5760405162461bcd60e51b8152600401610a76906140f5565b61027f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b611c7684848484612f24565b50505050565b6060611c8b8261ffff166125c0565b611ca75760405162461bcd60e51b8152600401610a7690614853565b610140546001600160a01b0316611ccc57505060408051602081019091526000815290565b610143546001600160a01b0316635cc518ba83610146816127108110611cf457611cf4614750565b602091828204019190069054906101000a900460ff166040518363ffffffff1660e01b8152600401611d27929190614863565b60006040518083038186803b158015611d3f57600080fd5b505afa158015611d53573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109b691908101906148d6565b6000600261013f541415611da15760405162461bcd60e51b8152600401610a76906145c9565b600261013f819055611db49085906143a7565b8614611dd25760405162461bcd60e51b8152600401610a7690614969565b611ddd3388886132c2565b600087873388884244604051602001611dfc97969594939291906149c6565b60405160208183030381529060405280519060200120905060005b85811015612041576000611e688a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111469250869150600290506143a7565b610145546040517f6352211e00000000000000000000000000000000000000000000000000000000815291925033916001600160a01b0390911690636352211e90611eb7908590600401614a2b565b60206040518083038186803b158015611ecf57600080fd5b505afa158015611ee3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f079190614a44565b6001600160a01b031614611f2d5760405162461bcd60e51b8152600401610a7690614abd565b858583818110611f3f57611f3f614750565b90506020020135600114611f655760405162461bcd60e51b8152600401610a7690614b4b565b6004888884818110611f7957611f79614750565b90506020020135611f8a9190614b5b565b60fc84611f98602086614738565b60208110611fa857611fa8614750565b611fb6939291901a16614b68565b6101468261ffff166127108110611fcf57611fcf614750565b602091828204019190066101000a81548160ff021916908360ff160217905550602082611ffc9190614738565b601f141561202e57826040516020016120159190614766565b6040516020818303038152906040528051906020012092505b508061203981614778565b915050611e17565b50610144546001600160a01b0316636b20c45433888888886040518663ffffffff1660e01b8152600401612079959493929190614b95565b600060405180830381600087803b15801561209357600080fd5b505af11580156120a7573d6000803e3d6000fd5b505050506001915050600161013f559695505050505050565b61013e546001600160a01b031633146120eb5760405162461bcd60e51b8152600401610a76906140f5565b61014280546001600160a01b0390921673ffffffffffffffffffffffffffffffffffffffff1992831681179091556101458054909216179055565b6102805460009074010000000000000000000000000000000000000000900460ff1661215d57612156838361332b565b90506109b6565b61027f546040517fc45527910000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063c4552791906121a79086906004016139ec565b60206040518083038186803b1580156121bf57600080fd5b505afa1580156121d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f79190614bf5565b6001600160a01b0316826001600160a01b031614806122245750610280546001600160a01b038381169116145b8061224857506001600160a01b0382166000908152610281602052604090205460ff165b806110155750611015838361332b565b61013e546001600160a01b031633146122835760405162461bcd60e51b8152600401610a76906140f5565b6001600160a01b0381166122a95760405162461bcd60e51b8152600401610a7690614c6e565b6112628161310b565b6000600261013f5414156122d85760405162461bcd60e51b8152600401610a76906145c9565b600261013f556122e6610c70565b6123025760405162461bcd60e51b8152600401610a769061460b565b3466b1a2bc2ec50000612316600285614351565b61232091906143a7565b1461233d5760405162461bcd60e51b8152600401610a7690614cb0565b6102825461234c600284614351565b612355336115f0565b61235f919061411b565b111561237d5760405162461bcd60e51b8152600401610a7690614d18565b6123863361184b565b60008383333442446040516020016123a396959493929190614d28565b60405160208183030381529060405280519060200120905060005b8381101561247657600061240986868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250612818915050565b905082612417600284614351565b6020811061242757612427614750565b1a61014661ffff8316612710811061244157612441614750565b602091828204019190066101000a81548160ff021916908360ff1602179055505060028161246f919061411b565b90506123be565b506001915050600161013f5592915050565b61013e546001600160a01b031633146124b35760405162461bcd60e51b8152600401610a76906140f5565b6001600160a01b0316600090815261028160205260409020805460ff19811660ff90911615179055565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061257057507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806109b657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146109b6565b600060028261271081106125d6576125d6614750565b602081049091015460ff601f9092166101000a90041692915050565b600080805b6001805461260490613f62565b90508110156126c657600061261f60018054610eca90613f62565b905060005b6001600160a01b0382166000908152602081905260409020805461264790613f62565b905081101561269d576001600160a01b03821660009081526020819052604090208054879161267991610d8490613f62565b61ffff16141561268b5781935061269d565b61269660028261411b565b9050612624565b506001600160a01b038316156126b357506126c6565b506126bf60148261411b565b90506125f7565b5092915050565b6000600180546126dc90613f62565b905082106126fc5760405162461bcd60e51b8152600401610a7690614da5565b6109b661068c6001805461270f90613f62565b80601f016020809104026020016040519081016040528092919081815260200182805461273b90613f62565b80156127885780601f1061275d57610100808354040283529160200191612788565b820191906000526020600020905b81548152906001019060200180831161276b57829003601f168201915b50505050508461284e565b600061279e826125c0565b6127ba5760405162461bcd60e51b8152600401610a7690614e0d565b60006127c5836115c0565b9050806001600160a01b0316846001600160a01b031614806128005750836001600160a01b03166127f584610a4f565b6001600160a01b0316145b8061281057506128108185612126565b949350505050565b600061282582600261411b565b835110156128455760405162461bcd60e51b8152600401610a7690614e4f565b50016002015190565b600061285b82601461411b565b8351101561287b5760405162461bcd60e51b8152600401610a7690614e91565b5001602001516c01000000000000000000000000900490565b836001600160a01b031661293e600180546128ae90613f62565b80601f01602080910402602001604051908101604052809291908181526020018280546128da90613f62565b80156129275780601f106128fc57610100808354040283529160200191612927565b820191906000526020600020905b81548152906001019060200180831161290a57829003601f168201915b505050505085601461293991906143a7565b61284e565b6001600160a01b0316146129645760405162461bcd60e51b8152600401610a7690614ef9565b6001600160a01b0382166000908152602081905260409020805461298790613f62565b151590506129cc5760018260601b6040516020016129a6929190614f9f565b604051602081830303815290604052600190805190602001906129ca9291906137d7565b505b6001600160a01b03841660009081526020819052604081208054612a8591906129f490613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612a2090613f62565b8015612a6d5780601f10612a4257610100808354040283529160200191612a6d565b820191906000526020600020905b815481529060010190602001808311612a5057829003601f168201915b505050505083846002612a80919061411b565b613436565b6001600160a01b0386166000908152602081905260409020805491925090612aac90613f62565b905060021415612c8357612b5360018054612ac690613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612af290613f62565b8015612b3f5780601f10612b1457610100808354040283529160200191612b3f565b820191906000526020600020905b815481529060010190602001808311612b2257829003601f168201915b50505050506000866014612a8091906143a7565b612c2760018054612b6390613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612b8f90613f62565b8015612bdc5780601f10612bb157610100808354040283529160200191612bdc565b820191906000526020600020905b815481529060010190602001808311612bbf57829003601f168201915b5050505050866001612bee919061411b565b612bf99060146143a7565b612c0488600161411b565b612c0f9060146143a7565b60018054612c1c90613f62565b612a80929150614518565b604051602001612c38929190614fe0565b60405160208183030381529060405260019080519060200190612c5c9291906137d7565b506001600160a01b0385166000908152602081905260408120612c7e9161385b565b612e6c565b6001600160a01b03851660009081526020819052604090208054612d319190612cab90613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612cd790613f62565b8015612d245780601f10612cf957610100808354040283529160200191612d24565b820191906000526020600020905b815481529060010190602001808311612d0757829003601f168201915b5050505050600084613436565b6001600160a01b03861660009081526020819052604090208054612e219190612d5990613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612d8590613f62565b8015612dd25780601f10612da757610100808354040283529160200191612dd2565b820191906000526020600020905b815481529060010190602001808311612db557829003601f168201915b5050505050846002612de4919061411b565b6001600160a01b038916600090815260208190526040902080546002918891612e0c90613f62565b612e17929150614518565b612a809190614518565b604051602001612e32929190614fe0565b60408051601f198184030181529181526001600160a01b038716600090815260208181529190208251612e6a939192909101906137d7565b505b6001600160a01b038316600090815260208181526040918290209151612e959291849101614ff6565b60408051601f198184030181529181526001600160a01b038516600090815260208181529190208251612ecd939192909101906137d7565b50612ed9816000612818565b61ffff16836001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b6001600160a01b038416612f4a5760405162461bcd60e51b8152600401610a769061418b565b6001600160a01b038316612f705760405162461bcd60e51b8152600401610a76906141f3565b612f7a3383612793565b612f965760405162461bcd60e51b8152600401610a769061425b565b60005b6001600160a01b038516600090815260208190526040902080548491612fc291610d8490613f62565b61ffff1614158015612ff757506001600160a01b03851660009081526020819052604090208054612ff290613f62565b905081105b1561300e5761300760028261411b565b9050612f99565b6001600160a01b0385166000908152602081905260409020805461303190613f62565b905081106130515760405162461bcd60e51b8152600401610a76906142c3565b60005b6001805461306190613f62565b90508110156130aa57856001600160a01b031661308460018054610eca90613f62565b6001600160a01b03161415613098576130aa565b6130a360148261411b565b9050613054565b856001600160a01b03166130c460018054610eca90613f62565b6001600160a01b0316146130ea5760405162461bcd60e51b8152600401610a769061432b565b6130f686828785612894565b6131028686868661316b565b50505050505050565b61013e80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b156132b7576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a02906131c8903390899088908890600401615000565b602060405180830381600087803b1580156131e257600080fd5b505af1925050508015613212575060408051601f3d908101601f1916820190925261320f9181019061504f565b60015b61326c573d808015613240576040519150601f19603f3d011682016040523d82523d6000602084013e613245565b606091505b5080516132645760405162461bcd60e51b8152600401610a76906150c8565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050612810565b506001949350505050565b6132cd8383836134fe565b611c7660008461331285858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250612818915050565b61ffff166040518060200160405280600081525061316b565b6001600160a01b0382166000908152602081905260408120805482919061335190613f62565b80601f016020809104026020016040519081016040528092919081815260200182805461337d90613f62565b80156133ca5780601f1061339f576101008083540402835291602001916133ca565b820191906000526020600020905b8154815290600101906020018083116133ad57829003601f168201915b5050505050905060005b81518110156132b757836001600160a01b031661013b60006133f68585612818565b61ffff1681526020810191909152604001600020546001600160a01b031614613424576000925050506109b6565b61342f60028261411b565b90506133d4565b60608161344481601f61411b565b10156134625760405162461bcd60e51b8152600401610a769061510a565b61346c828461411b565b8451101561348c5760405162461bcd60e51b8152600401610a769061514c565b6060821580156134ab57604051915060008252602082016040526134f5565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156134e45780518352602092830192016134cc565b5050858452601f01601f1916604052505b50949350505050565b8061351b5760405162461bcd60e51b8152600401610a76906151b4565b613526600282614738565b156135435760405162461bcd60e51b8152600401610a769061521c565b6001600160a01b0383166000908152602081905260409020805461356690613f62565b151590506135ab5760018360601b604051602001613585929190614f9f565b604051602081830303815290604052600190805190602001906135a99291906137d7565b505b60005b818110156137525760026135f984848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250612818915050565b61ffff16612710811061360e5761360e614750565b602081049091015460ff601f9092166101000a900416156136415760405162461bcd60e51b8152600401610a769061525e565b6001600261368685858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250612818915050565b61ffff16612710811061369b5761369b614750565b602091828204019190066101000a81548160ff0219169083151502179055506136fb83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859250612818915050565b61ffff16846001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461374b60028261411b565b90506135ae565b506001600160a01b03831660009081526020818152604091829020915161377e9291859185910161526e565b60408051601f198184030181529181526001600160a01b038516600090815260208181529190208251611c76939192909101906137d7565b604051806204e2000160405280612710906020820280368337509192915050565b8280546137e390613f62565b90600052602060002090601f016020900481019282613805576000855561384b565b82601f1061381e57805160ff191683800117855561384b565b8280016001018555821561384b579182015b8281111561384b578251825591602001919060010190613830565b50613857929150613891565b5090565b50805461386790613f62565b6000825580601f10613877575050565b601f01602090049060005260206000209081019061126291905b5b808211156138575760008155600101613892565b7fffffffff0000000000000000000000000000000000000000000000000000000081165b811461126257600080fd5b80356109b6816138a6565b6000602082840312156138f5576138f5600080fd5b600061281084846138d5565b8015155b82525050565b602081016109b68284613901565b61ffff8116613905565b602081016109b68284613919565b60005b8381101561394c578181015183820152602001613934565b83811115611c765750506000910152565b6000613967825190565b80845260208401935061397e818560208601613931565b601f01601f19169290920192915050565b60208082528101611015818461395d565b806138ca565b80356109b6816139a0565b6000602082840312156139c6576139c6600080fd5b600061281084846139a6565b60006001600160a01b0382166109b6565b613905816139d2565b602081016109b682846139e3565b6138ca816139d2565b80356109b6816139fa565b60008060408385031215613a2457613a24600080fd5b6000613a308585613a03565b9250506020613a41858286016139a6565b9150509250929050565b600060208284031215613a6057613a60600080fd5b60006128108484613a03565b80613905565b602081016109b68284613a6c565b600080600060608486031215613a9857613a98600080fd5b6000613aa48686613a03565b9350506020613ab586828701613a03565b9250506040613ac6868287016139a6565b9150509250925092565b600080600060608486031215613ae857613ae8600080fd5b6000613af48686613a03565b9350506020613ab5868287016139a6565b60ff8116613905565b602081016109b68284613b05565b60008060008060808587031215613b3557613b35600080fd5b6000613b418787613a03565b9450506020613b52878288016139a6565b9350506040613b6387828801613a03565b9250506060613b74878288016139a6565b91505092959194509250565b60008083601f840112613b9557613b95600080fd5b50813567ffffffffffffffff811115613bb057613bb0600080fd5b602083019150836001820283011115613bcb57613bcb600080fd5b9250929050565b60008060208385031215613be857613be8600080fd5b823567ffffffffffffffff811115613c0257613c02600080fd5b613c0e85828601613b80565b92509250509250929050565b613c248282613901565b5060200190565b60200190565b6127108160005b82811015610fc0578151613c4c8682613c1a565b955050602082019150600101613c38565b6204e20081016109b68284613c31565b8015156138ca565b80356109b681613c6d565b60008060408385031215613c9657613c96600080fd5b6000613ca28585613a03565b9250506020613a4185828601613c75565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff82111715613cef57613cef613cb3565b6040525050565b6000613d0160405190565b9050613d0d8282613cc9565b919050565b600067ffffffffffffffff821115613d2c57613d2c613cb3565b601f19601f83011660200192915050565b82818337506000910152565b6000613d5c613d5784613d12565b613cf6565b905082815260208101848484011115613d7757613d77600080fd5b613d82848285613d3d565b509392505050565b600082601f830112613d9e57613d9e600080fd5b8135612810848260208601613d49565b60008060008060808587031215613dc757613dc7600080fd5b6000613dd38787613a03565b9450506020613de487828801613a03565b9350506040613df5878288016139a6565b925050606085013567ffffffffffffffff811115613e1557613e15600080fd5b613b7487828801613d8a565b60008083601f840112613e3657613e36600080fd5b50813567ffffffffffffffff811115613e5157613e51600080fd5b602083019150836020820283011115613bcb57613bcb600080fd5b60008060008060008060608789031215613e8857613e88600080fd5b863567ffffffffffffffff811115613ea257613ea2600080fd5b613eae89828a01613b80565b9650965050602087013567ffffffffffffffff811115613ed057613ed0600080fd5b613edc89828a01613e21565b9450945050604087013567ffffffffffffffff811115613efe57613efe600080fd5b613f0a89828a01613e21565b92509250509295509295509295565b60008060408385031215613f2f57613f2f600080fd5b6000613f3b8585613a03565b9250506020613a4185828601613a03565b634e487b7160e01b600052602260045260246000fd5b600281046001821680613f7657607f821691505b60208210811415610c6a57610c6a613f4c565b601c8152602081017f4552433732313a20746f6b656e20646f6573206e6f742065786973740000000081529050613c2b565b602080825281016109b681613f89565b602b8152602081017f4552433732313a20617070726f766520717565727920666f72206e6f6e65786981527f7374656e7420746f6b656e000000000000000000000000000000000000000000602082015290505b60400190565b602080825281016109b681613fcb565b60468152602081017f4552433732313a2063616c6c6572206973206e6f7420746865206f776e65722081527f6e6f7220616e20617070726f766564206f70657261746f7220666f722074686560208201527f20746f6b656e0000000000000000000000000000000000000000000000000000604082015290505b60600190565b602080825281016109b681614035565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65729101908152613c2b565b602080825281016109b6816140c5565b634e487b7160e01b600052601160045260246000fd5b6000821982111561412e5761412e614105565b500190565b60278152602081017f4552433732313a2066726f6d2063616e6e6f7420626520746865207a65726f2081527f61646472657373000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614133565b60258152602081017f4552433732313a20746f2063616e6e6f7420626520746865207a65726f20616481527f64726573730000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b68161419b565b60318152602081017f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f81527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020820152905061401f565b602080825281016109b681614203565b60238152602081017f4552433732313a2066726f6d20646f6573206e6f74206f776e2074686520746f81527f6b656e00000000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b68161426b565b60228152602081017f4552433732313a2066726f6d206973206e6f7420696e206f776e657273206c6981527f73740000000000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816142d3565b634e487b7160e01b600052601260045260246000fd5b6000826143605761436061433b565b500490565b60178152602081017f4552433732313a204f776e6572206e6f7420666f756e6400000000000000000081529050613c2b565b602080825281016109b681614365565b60008160001904831182151516156143c1576143c1614105565b500290565b60248152602081017f455243373231456e756d657261626c653a20696e646578206f7574206f66207281527f616e6765000000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816143c6565b60118152602081017f5769746864726177616c206661696c656400000000000000000000000000000081529050613c2b565b602080825281016109b68161442e565b60208082527f4552433732313a20746f6b656e20696e646578206f7574206f662072616e67659101908152613c2b565b602080825281016109b681614470565b602c8152602081017f4552433732313a2063616c6c6572206973206e65697468657220617070726f7681527f6564206e6f72206f776e657200000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816144b0565b60008282101561452a5761452a614105565b500390565b60298152602081017f4552433732313a206f776e657220717565727920666f72206e6f6e657869737481527f656e7420746f6b656e00000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b68161452f565b601f8152602081017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081529050613c2b565b602080825281016109b681614597565b60148152602081017f5075626c69632073616c65206e6f74206f70656e00000000000000000000000081529050613c2b565b602080825281016109b6816145d9565b60138152602081017f446f6e277420626520746f6f206772656564790000000000000000000000000081529050613c2b565b602080825281016109b68161461b565b603f8152602081017f4576656e20696620796f7520617265206120666f756e6465722c20796f75206481527f6f6e277420646573657276652074686174206d616e7920447265616d657273006020820152905061401f565b602080825281016109b68161465d565b61412e828483613d3d565b60006109b68260601b90565b60006109b6826146d0565b6139056146f3826139d2565b6146dc565b90565b6147068186886146c5565b905061471281856146e7565b60140161471f8184613a6c565b60200161472c8183613a6c565b60200195945050505050565b815b915060008261474b5761474b61433b565b500690565b634e487b7160e01b600052603260045260246000fd5b6147708183613a6c565b602001919050565b600060001982141561478c5761478c614105565b5060010190565b60298152602081017f4552433732313a2063616e6e6f7420617070726f76652063616c6c657220617381527f206f70657261746f7200000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614793565b60278152602081017f4552433732313a2055524920717565727920666f72206e6f6e6578697374656e81527f7420746f6b656e000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816147fb565b604081016148718285613a6c565b6110156020830184613b05565b600061488c613d5784613d12565b9050828152602081018484840111156148a7576148a7600080fd5b613d82848285613931565b600082601f8301126148c6576148c6600080fd5b815161281084826020860161487e565b6000602082840312156148eb576148eb600080fd5b815167ffffffffffffffff81111561490557614905600080fd5b612810848285016148b2565b60288152602081017f456163682072756e6e6572206e65656473206f6e6520616e64206f6e6c79206f81527f6e652063616e64790000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614911565b825b925060007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156149af576149af600080fd5b6020830292506149c0838584613d3d565b50500190565b6149d181888a6146c5565b90506149dd81876146e7565b6014016149eb818587614979565b90506149f78184613a6c565b602001614a048183613a6c565b602001979650505050505050565b60006109b66146f861ffff841681565b61390581614a12565b602081016109b68284614a22565b80516109b6816139fa565b600060208284031215614a5957614a59600080fd5b60006128108484614a39565b60378152602081017f596f752063616e6e6f7420676976652063616e6469657320746f20612072756e81527f6e6572207468617420796f7520646f206e6f74206f776e0000000000000000006020820152905061401f565b602080825281016109b681614a65565b604f8152602081017f596f75722072756e6e6572206e65656473206f6e6520616e64206f6e6c79206f81527f6e652063616e64792c2077686f206b6e6f7773207768617420636f756c64206860208201527f617070656e206f74686572776973650000000000000000000000000000000000604082015290506140af565b602080825281016109b681614acd565b60ff90811690821661473a565b60ff8116905060ff8216915060008260ff0382111561412e5761412e614105565b8183526020830161497b565b60608101614ba382886139e3565b8181036020830152614bb6818688614b89565b90508181036040830152614bcb818486614b89565b979650505050505050565b60006109b6826139d2565b6138ca81614bd6565b80516109b681614be1565b600060208284031215614c0a57614c0a600080fd5b60006128108484614bea565b60268152602081017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181527f64647265737300000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614c16565b601d8152602081017f596f75206861766520746f2070617920746865206261696c20626f6e6400000081529050613c2b565b602080825281016109b681614c7e565b60318152602081017f596f757220686f6d6520697320746f20736d616c6c20746f2077656c636f6d6581527f20736f206d616e7920647265616d6572730000000000000000000000000000006020820152905061401f565b602080825281016109b681614cc0565b614d338187896146c5565b9050614d3f81866146e7565b601401614d4c8185613a6c565b602001614d598184613a6c565b602001614d668183613a6c565b6020019695505050505050565b601f8152602081017f4552433732313a206f776e6572496e646578206f7574206f6620626f756e640081529050613c2b565b602080825281016109b681614d73565b602c8152602081017f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657881527f697374656e7420746f6b656e00000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614db5565b60148152602081017f746f55696e7431365f6f75744f66426f756e647300000000000000000000000081529050613c2b565b602080825281016109b681614e1d565b60158152602081017f746f416464726573735f6f75744f66426f756e6473000000000000000000000081529050613c2b565b602080825281016109b681614e5f565b60288152602081017f4552433732313a207472616e736665722066726f6d206164647265737320697381527f20696e76616c69640000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614ea1565b60008154614f1681613f62565b600182168015614f2d5760018114614f3e57614f6e565b60ff19831686528186019350614f6e565b60008581526020902060005b83811015614f6657815488820152600190910190602001614f4a565b505081860193505b50505092915050565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116613905565b614fa98184614f09565b9050614fb58183614f77565b60140192915050565b6000614fc8825190565b614fd6818560208601613931565b9290920192915050565b614fea8184614fbe565b90506110158183614fbe565b614fea8184614f09565b6080810161500e82876139e3565b61501b60208301866139e3565b6150286040830185613a6c565b818103606083015261503a818461395d565b9695505050505050565b80516109b6816138a6565b60006020828403121561506457615064600080fd5b60006128108484615044565b60328152602081017f4552433732313a207472616e7366657220746f206e6f6e20455243373231526581527f63656976657220696d706c656d656e74657200000000000000000000000000006020820152905061401f565b602080825281016109b681615070565b600e8152602081017f736c6963655f6f766572666c6f7700000000000000000000000000000000000081529050613c2b565b602080825281016109b6816150d8565b60118152602081017f736c6963655f6f75744f66426f756e647300000000000000000000000000000081529050613c2b565b602080825281016109b68161511a565b60258152602081017f4552433732313a2063616e6e6f74206d696e742077697468206e6f20746f6b6581527f6e204964730000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b68161515c565b602a8152602081017f4552433732313a20746f6b656e4964732073686f756c6420626520627974657381527f206f662075696e743136000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816151c4565b601c8152602081017f4552433732313a20746f6b656e20616c7265616479206578697374730000000081529050613c2b565b602080825281016109b68161522c565b6152788185614f09565b90506128108183856146c556fea264697066735822122046587b314b050c95aee2c01fa6c16505ba58492e42a5f478d8f70aa704ed6ad964736f6c6343000808003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000e436861696e20447265616d65727300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034452450000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361061032d5760003560e01c806370a08231116101a5578063b776c8a6116100ec578063d7822c9911610095578063f2fde38b1161006f578063f2fde38b146108ec578063f4b994241461090c578063f73c814b1461091f578063fac913231461093f57600080fd5b8063d7822c991461089a578063e985e9c5146108b1578063f0658ac9146108d157600080fd5b8063c87b56dd116100c6578063c87b56dd1461083a578063cb95f0691461085a578063d3d6005b1461087a57600080fd5b8063b776c8a6146107d9578063b88d4fde146107f9578063c074f4121461081957600080fd5b806395d89b411161014e578063a22cb46511610128578063a22cb46514610778578063a8e90b5714610798578063b5fcb339146107b957600080fd5b806395d89b41146107265780639913fc631461073b5780639c51792a1461075d57600080fd5b806389c8af831161017f57806389c8af83146106c75780638da5cb5b146106e75780639343eaa61461070657600080fd5b806370a0823114610671578063715018a6146106915780638392d804146106a657600080fd5b806323b872dd1161027457806342842e0e1161021d578063511ed382116101f7578063511ed382146105ec578063633574db1461060d5780636352211e1461063a5780636b318e6e1461065a57600080fd5b806342842e0e1461058c5780634f6ccce7146105ac578063511a9605146105cc57600080fd5b806333c12e171161024e57806333c12e17146105425780633ccfd60b14610557578063426a84931461056c57600080fd5b806323b872dd146104e257806325174f0e146105025780632f745c591461052257600080fd5b80630d77c756116102d65780631a6949e3116102b05780631a6949e3146104985780631e8858fb146104ad57806322afee07146104cd57600080fd5b80630d77c7561461043657806312b40a9f1461045657806318160ddd1461047657600080fd5b806306fdde031161030757806306fdde03146103c5578063081812fc146103e7578063095ea7b31461041457600080fd5b806301ffc9a7146103395780630216e3041461036f578063026ae1021461039257600080fd5b3661033457005b600080fd5b34801561034557600080fd5b506103596103543660046138e0565b610960565b604051610366919061390b565b60405180910390f35b34801561037b57600080fd5b5061038561271081565b6040516103669190613923565b34801561039e57600080fd5b50610280546103599074010000000000000000000000000000000000000000900460ff1681565b3480156103d157600080fd5b506103da6109bc565b604051610366919061398f565b3480156103f357600080fd5b506104076104023660046139b1565b610a4f565b60405161036691906139ec565b34801561042057600080fd5b5061043461042f366004613a0e565b610aa0565b005b34801561044257600080fd5b506104346104513660046139b1565b610b91565b34801561046257600080fd5b50610434610471366004613a4b565b610bc2565b34801561048257600080fd5b5061048b610c28565b6040516103669190613a72565b3480156104a457600080fd5b50610359610c70565b3480156104b957600080fd5b506104346104c8366004613a4b565b610c8b565b3480156104d957600080fd5b5061048b603281565b3480156104ee57600080fd5b506104346104fd366004613a80565b610ce6565b34801561050e57600080fd5b5061048b61051d366004613a4b565b610fc7565b34801561052e57600080fd5b5061048b61053d366004613a0e565b611046565b34801561054e57600080fd5b50610434611156565b34801561056357600080fd5b506104346111cf565b34801561057857600080fd5b50610434610587366004613ad0565b611265565b34801561059857600080fd5b506104346105a7366004613a80565b611388565b3480156105b857600080fd5b5061048b6105c73660046139b1565b6113a8565b3480156105d857600080fd5b506104346105e73660046139b1565b611563565b3480156105f857600080fd5b5061027f54610407906001600160a01b031681565b34801561061957600080fd5b5061062d6106283660046139b1565b611594565b6040516103669190613b0e565b34801561064657600080fd5b506104076106553660046139b1565b6115c0565b34801561066657600080fd5b5061048b6102825481565b34801561067d57600080fd5b5061048b61068c366004613a4b565b6115f0565b34801561069d57600080fd5b50610434611622565b3480156106b257600080fd5b5061014254610407906001600160a01b031681565b3480156106d357600080fd5b506104346106e2366004613b1c565b611659565b3480156106f357600080fd5b5061013e546001600160a01b0316610407565b34801561071257600080fd5b50610359610721366004613bd2565b61177c565b34801561073257600080fd5b506103da6119ae565b34801561074757600080fd5b506107506119be565b6040516103669190613c5d565b34801561076957600080fd5b5061048b66b1a2bc2ec5000081565b34801561078457600080fd5b50610434610793366004613c80565b611a1b565b3480156107a457600080fd5b5061028054610407906001600160a01b031681565b3480156107c557600080fd5b506104346107d4366004613a4b565b611ba9565b3480156107e557600080fd5b506104346107f4366004613a4b565b611c0f565b34801561080557600080fd5b50610434610814366004613dae565b611c6a565b34801561082557600080fd5b5061014054610407906001600160a01b031681565b34801561084657600080fd5b506103da6108553660046139b1565b611c7c565b34801561086657600080fd5b50610359610875366004613e6c565b611d7b565b34801561088657600080fd5b50610434610895366004613a4b565b6120c0565b3480156108a657600080fd5b5061048b6102845481565b3480156108bd57600080fd5b506103596108cc366004613f19565b612126565b3480156108dd57600080fd5b50610283546103599060ff1681565b3480156108f857600080fd5b50610434610907366004613a4b565b612258565b61035961091a366004613bd2565b6122b2565b34801561092b57600080fd5b5061043461093a366004613a4b565b612488565b34801561094b57600080fd5b5061014154610407906001600160a01b031681565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d630000000000000000000000000000000000000000000000000000000014806109b657506109b6826124dd565b92915050565b606061013c80546109cc90613f62565b80601f01602080910402602001604051908101604052809291908181526020018280546109f890613f62565b8015610a455780601f10610a1a57610100808354040283529160200191610a45565b820191906000526020600020905b815481529060010190602001808311610a2857829003601f168201915b5050505050905090565b6000610a5a826125c0565b610a7f5760405162461bcd60e51b8152600401610a7690613fbb565b60405180910390fd5b5061ffff16600090815261013b60205260409020546001600160a01b031690565b6000610aab826125f2565b90506001600160a01b038116610ad35760405162461bcd60e51b8152600401610a7690614025565b61ffff8216600090815261013b60205260409020546001600160a01b0316331480610b0657506001600160a01b03811633145b610b225760405162461bcd60e51b8152600401610a76906140b5565b61ffff8216600090815261013b6020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b61013e546001600160a01b03163314610bbc5760405162461bcd60e51b8152600401610a76906140f5565b61028255565b61013e546001600160a01b03163314610bed5760405162461bcd60e51b8152600401610a76906140f5565b61014080546001600160a01b0390921673ffffffffffffffffffffffffffffffffffffffff1992831681179091556101438054909216179055565b600080805b60018054610c3a90613f62565b9050811015610c6a57610c4c816126cd565b610c56908361411b565b9150610c6360148261411b565b9050610c2d565b50919050565b60006102845442118015610c8657506102845415155b905090565b61013e546001600160a01b03163314610cb65760405162461bcd60e51b8152600401610a76906140f5565b610280805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6001600160a01b038316610d0c5760405162461bcd60e51b8152600401610a769061418b565b6001600160a01b038216610d325760405162461bcd60e51b8152600401610a76906141f3565b610d3c3382612793565b610d585760405162461bcd60e51b8152600401610a769061425b565b60005b6001600160a01b038416600090815260208190526040902080548391610e0891610d8490613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054610db090613f62565b8015610dfd5780601f10610dd257610100808354040283529160200191610dfd565b820191906000526020600020905b815481529060010190602001808311610de057829003601f168201915b505050505083612818565b61ffff1614158015610e3d57506001600160a01b03841660009081526020819052604090208054610e3890613f62565b905081105b15610e5457610e4d60028261411b565b9050610d5b565b6001600160a01b03841660009081526020819052604090208054610e7790613f62565b90508110610e975760405162461bcd60e51b8152600401610a76906142c3565b60005b60018054610ea790613f62565b9050811015610f7457846001600160a01b0316610f4e60018054610eca90613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054610ef690613f62565b8015610f435780601f10610f1857610100808354040283529160200191610f43565b820191906000526020600020905b815481529060010190602001808311610f2657829003601f168201915b50505050508361284e565b6001600160a01b03161415610f6257610f74565b610f6d60148261411b565b9050610e9a565b846001600160a01b0316610f8e60018054610eca90613f62565b6001600160a01b031614610fb45760405162461bcd60e51b8152600401610a769061432b565b610fc085828685612894565b5050505050565b6000805b60018054610fd890613f62565b905081101561102e57826001600160a01b0316610ffb60018054610eca90613f62565b6001600160a01b0316141561101c57611015601482614351565b9392505050565b61102760148261411b565b9050610fcb565b60405162461bcd60e51b8152600401610a7690614397565b6001600160a01b0382166000908152602081905260408120805461106990613f62565b90506110768360026143a7565b106110935760405162461bcd60e51b8152600401610a769061441e565b6001600160a01b0383166000908152602081905260409020805461114b91906110bb90613f62565b80601f01602080910402602001604051908101604052809291908181526020018280546110e790613f62565b80156111345780601f1061110957610100808354040283529160200191611134565b820191906000526020600020905b81548152906001019060200180831161111757829003601f168201915b505050505083600261114691906143a7565b612818565b61ffff169392505050565b61013e546001600160a01b031633146111815760405162461bcd60e51b8152600401610a76906140f5565b61028080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff8116740100000000000000000000000000000000000000009182900460ff1615909102179055565b61013e546001600160a01b031633146111fa5760405162461bcd60e51b8152600401610a76906140f5565b604051600090339047908381818185875af1925050503d806000811461123c576040519150601f19603f3d011682016040523d82523d6000602084013e611241565b606091505b50509050806112625760405162461bcd60e51b8152600401610a7690614460565b50565b61ffff8216600090815261013b60205260409020546001600160a01b031633146113475733600090815260208190526040902080546112a390613f62565b90506112b08260026143a7565b106112cd5760405162461bcd60e51b8152600401610a76906144a0565b336000908152602081905260409020805483916112ed916110bb90613f62565b61ffff161461130e5760405162461bcd60e51b8152600401610a7690614508565b60405182906001600160a01b0385169033907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590600090a45b5061ffff16600090815261013b60205260409020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6113a383838360405180602001604052806000815250612f24565b505050565b600080805b8381116113db576113bd826126cd565b6113c7908261411b565b90506113d460148361411b565b91506113ad565b6113e6601483614518565b91506113f1826126cd565b6113fb9082614518565b90506115576000806114976001805461141390613f62565b80601f016020809104026020016040519081016040528092919081815260200182805461143f90613f62565b801561148c5780601f106114615761010080835404028352916020019161148c565b820191906000526020600020905b81548152906001019060200180831161146f57829003601f168201915b50505050508661284e565b6001600160a01b03166001600160a01b0316815260200190815260200160002080546114c290613f62565b80601f01602080910402602001604051908101604052809291908181526020018280546114ee90613f62565b801561153b5780601f106115105761010080835404028352916020019161153b565b820191906000526020600020905b81548152906001019060200180831161151e57829003601f168201915b5050505050828661154c9190614518565b6111469060026143a7565b61ffff16949350505050565b61013e546001600160a01b0316331461158e5760405162461bcd60e51b8152600401610a76906140f5565b61028455565b6101468161271081106115a657600080fd5b60209182820401919006915054906101000a900460ff1681565b60006115cb826125c0565b6115e75760405162461bcd60e51b8152600401610a7690614587565b6109b6826125f2565b6001600160a01b038116600090815260208190526040812080546002919061161790613f62565b6109b6929150614351565b61013e546001600160a01b0316331461164d5760405162461bcd60e51b8152600401610a76906140f5565b611657600061310b565b565b6001600160a01b03841661167f5760405162461bcd60e51b8152600401610a769061418b565b6001600160a01b0382166116a55760405162461bcd60e51b8152600401610a76906141f3565b6001600160a01b03841660009081526020819052604090208054600291906116cc90613f62565b6116d7929150614351565b81106116f55760405162461bcd60e51b8152600401610a76906144a0565b6001600160a01b0384166000908152602081905260408120805461171d91906110bb90613f62565b905061172d338261ffff16612793565b6117495760405162461bcd60e51b8152600401610a769061425b565b61175585858585612894565b61177485848361ffff166040518060200160405280600081525061316b565b505050505050565b6000600261013f5414156117a25760405162461bcd60e51b8152600401610a76906145c9565b600261013f5561013e546001600160a01b031633146117d35760405162461bcd60e51b8152600401610a76906140f5565b6117db610c70565b6117f75760405162461bcd60e51b8152600401610a769061460b565b6102835460ff161561181b5760405162461bcd60e51b8152600401610a769061464d565b611827603260026143a7565b8211156118465760405162461bcd60e51b8152600401610a76906146b5565b611852335b84846132c2565b6000838333424460405160200161186d9594939291906146fb565b60405160208183030381529060405280519060200120905060005b611893600285614351565b81101561198d5760006118e386868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111469250869150600290506143a7565b9050826118f1602084614738565b6020811061190157611901614750565b1a61014661ffff8316612710811061191b5761191b614750565b602091828204019190066101000a81548160ff021916908360ff1602179055506020826119489190614738565b601f141561197a57826040516020016119619190614766565b6040516020818303038152906040528051906020012092505b508061198581614778565b915050611888565b5050610283805460ff191660019081179091559050600161013f5592915050565b606061013d80546109cc90613f62565b6119c66137b6565b604080516204e2008101918290529060029061271090826000855b825461010083900a900460ff1615158152602060019283018181049485019490930390920291018084116119e15790505050505050905090565b6001600160a01b038216331415611a445760405162461bcd60e51b8152600401610a76906147eb565b3360009081526020819052604081208054611a5e90613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8a90613f62565b8015611ad75780601f10611aac57610100808354040283529160200191611ad7565b820191906000526020600020905b815481529060010190602001808311611aba57829003601f168201915b5050505050905060005b8151811015611b585782611af6576000611af8565b835b61013b6000611b078585612818565b61ffff1681526020810191909152604001600020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055611b5160028261411b565b9050611ae1565b506001600160a01b038316336001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3184604051611b9c919061390b565b60405180910390a3505050565b61013e546001600160a01b03163314611bd45760405162461bcd60e51b8152600401610a76906140f5565b61014180546001600160a01b0390921673ffffffffffffffffffffffffffffffffffffffff1992831681179091556101448054909216179055565b61013e546001600160a01b03163314611c3a5760405162461bcd60e51b8152600401610a76906140f5565b61027f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b611c7684848484612f24565b50505050565b6060611c8b8261ffff166125c0565b611ca75760405162461bcd60e51b8152600401610a7690614853565b610140546001600160a01b0316611ccc57505060408051602081019091526000815290565b610143546001600160a01b0316635cc518ba83610146816127108110611cf457611cf4614750565b602091828204019190069054906101000a900460ff166040518363ffffffff1660e01b8152600401611d27929190614863565b60006040518083038186803b158015611d3f57600080fd5b505afa158015611d53573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109b691908101906148d6565b6000600261013f541415611da15760405162461bcd60e51b8152600401610a76906145c9565b600261013f819055611db49085906143a7565b8614611dd25760405162461bcd60e51b8152600401610a7690614969565b611ddd3388886132c2565b600087873388884244604051602001611dfc97969594939291906149c6565b60405160208183030381529060405280519060200120905060005b85811015612041576000611e688a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506111469250869150600290506143a7565b610145546040517f6352211e00000000000000000000000000000000000000000000000000000000815291925033916001600160a01b0390911690636352211e90611eb7908590600401614a2b565b60206040518083038186803b158015611ecf57600080fd5b505afa158015611ee3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f079190614a44565b6001600160a01b031614611f2d5760405162461bcd60e51b8152600401610a7690614abd565b858583818110611f3f57611f3f614750565b90506020020135600114611f655760405162461bcd60e51b8152600401610a7690614b4b565b6004888884818110611f7957611f79614750565b90506020020135611f8a9190614b5b565b60fc84611f98602086614738565b60208110611fa857611fa8614750565b611fb6939291901a16614b68565b6101468261ffff166127108110611fcf57611fcf614750565b602091828204019190066101000a81548160ff021916908360ff160217905550602082611ffc9190614738565b601f141561202e57826040516020016120159190614766565b6040516020818303038152906040528051906020012092505b508061203981614778565b915050611e17565b50610144546001600160a01b0316636b20c45433888888886040518663ffffffff1660e01b8152600401612079959493929190614b95565b600060405180830381600087803b15801561209357600080fd5b505af11580156120a7573d6000803e3d6000fd5b505050506001915050600161013f559695505050505050565b61013e546001600160a01b031633146120eb5760405162461bcd60e51b8152600401610a76906140f5565b61014280546001600160a01b0390921673ffffffffffffffffffffffffffffffffffffffff1992831681179091556101458054909216179055565b6102805460009074010000000000000000000000000000000000000000900460ff1661215d57612156838361332b565b90506109b6565b61027f546040517fc45527910000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063c4552791906121a79086906004016139ec565b60206040518083038186803b1580156121bf57600080fd5b505afa1580156121d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121f79190614bf5565b6001600160a01b0316826001600160a01b031614806122245750610280546001600160a01b038381169116145b8061224857506001600160a01b0382166000908152610281602052604090205460ff165b806110155750611015838361332b565b61013e546001600160a01b031633146122835760405162461bcd60e51b8152600401610a76906140f5565b6001600160a01b0381166122a95760405162461bcd60e51b8152600401610a7690614c6e565b6112628161310b565b6000600261013f5414156122d85760405162461bcd60e51b8152600401610a76906145c9565b600261013f556122e6610c70565b6123025760405162461bcd60e51b8152600401610a769061460b565b3466b1a2bc2ec50000612316600285614351565b61232091906143a7565b1461233d5760405162461bcd60e51b8152600401610a7690614cb0565b6102825461234c600284614351565b612355336115f0565b61235f919061411b565b111561237d5760405162461bcd60e51b8152600401610a7690614d18565b6123863361184b565b60008383333442446040516020016123a396959493929190614d28565b60405160208183030381529060405280519060200120905060005b8381101561247657600061240986868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250612818915050565b905082612417600284614351565b6020811061242757612427614750565b1a61014661ffff8316612710811061244157612441614750565b602091828204019190066101000a81548160ff021916908360ff1602179055505060028161246f919061411b565b90506123be565b506001915050600161013f5592915050565b61013e546001600160a01b031633146124b35760405162461bcd60e51b8152600401610a76906140f5565b6001600160a01b0316600090815261028160205260409020805460ff19811660ff90911615179055565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061257057507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806109b657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146109b6565b600060028261271081106125d6576125d6614750565b602081049091015460ff601f9092166101000a90041692915050565b600080805b6001805461260490613f62565b90508110156126c657600061261f60018054610eca90613f62565b905060005b6001600160a01b0382166000908152602081905260409020805461264790613f62565b905081101561269d576001600160a01b03821660009081526020819052604090208054879161267991610d8490613f62565b61ffff16141561268b5781935061269d565b61269660028261411b565b9050612624565b506001600160a01b038316156126b357506126c6565b506126bf60148261411b565b90506125f7565b5092915050565b6000600180546126dc90613f62565b905082106126fc5760405162461bcd60e51b8152600401610a7690614da5565b6109b661068c6001805461270f90613f62565b80601f016020809104026020016040519081016040528092919081815260200182805461273b90613f62565b80156127885780601f1061275d57610100808354040283529160200191612788565b820191906000526020600020905b81548152906001019060200180831161276b57829003601f168201915b50505050508461284e565b600061279e826125c0565b6127ba5760405162461bcd60e51b8152600401610a7690614e0d565b60006127c5836115c0565b9050806001600160a01b0316846001600160a01b031614806128005750836001600160a01b03166127f584610a4f565b6001600160a01b0316145b8061281057506128108185612126565b949350505050565b600061282582600261411b565b835110156128455760405162461bcd60e51b8152600401610a7690614e4f565b50016002015190565b600061285b82601461411b565b8351101561287b5760405162461bcd60e51b8152600401610a7690614e91565b5001602001516c01000000000000000000000000900490565b836001600160a01b031661293e600180546128ae90613f62565b80601f01602080910402602001604051908101604052809291908181526020018280546128da90613f62565b80156129275780601f106128fc57610100808354040283529160200191612927565b820191906000526020600020905b81548152906001019060200180831161290a57829003601f168201915b505050505085601461293991906143a7565b61284e565b6001600160a01b0316146129645760405162461bcd60e51b8152600401610a7690614ef9565b6001600160a01b0382166000908152602081905260409020805461298790613f62565b151590506129cc5760018260601b6040516020016129a6929190614f9f565b604051602081830303815290604052600190805190602001906129ca9291906137d7565b505b6001600160a01b03841660009081526020819052604081208054612a8591906129f490613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612a2090613f62565b8015612a6d5780601f10612a4257610100808354040283529160200191612a6d565b820191906000526020600020905b815481529060010190602001808311612a5057829003601f168201915b505050505083846002612a80919061411b565b613436565b6001600160a01b0386166000908152602081905260409020805491925090612aac90613f62565b905060021415612c8357612b5360018054612ac690613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612af290613f62565b8015612b3f5780601f10612b1457610100808354040283529160200191612b3f565b820191906000526020600020905b815481529060010190602001808311612b2257829003601f168201915b50505050506000866014612a8091906143a7565b612c2760018054612b6390613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612b8f90613f62565b8015612bdc5780601f10612bb157610100808354040283529160200191612bdc565b820191906000526020600020905b815481529060010190602001808311612bbf57829003601f168201915b5050505050866001612bee919061411b565b612bf99060146143a7565b612c0488600161411b565b612c0f9060146143a7565b60018054612c1c90613f62565b612a80929150614518565b604051602001612c38929190614fe0565b60405160208183030381529060405260019080519060200190612c5c9291906137d7565b506001600160a01b0385166000908152602081905260408120612c7e9161385b565b612e6c565b6001600160a01b03851660009081526020819052604090208054612d319190612cab90613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612cd790613f62565b8015612d245780601f10612cf957610100808354040283529160200191612d24565b820191906000526020600020905b815481529060010190602001808311612d0757829003601f168201915b5050505050600084613436565b6001600160a01b03861660009081526020819052604090208054612e219190612d5990613f62565b80601f0160208091040260200160405190810160405280929190818152602001828054612d8590613f62565b8015612dd25780601f10612da757610100808354040283529160200191612dd2565b820191906000526020600020905b815481529060010190602001808311612db557829003601f168201915b5050505050846002612de4919061411b565b6001600160a01b038916600090815260208190526040902080546002918891612e0c90613f62565b612e17929150614518565b612a809190614518565b604051602001612e32929190614fe0565b60408051601f198184030181529181526001600160a01b038716600090815260208181529190208251612e6a939192909101906137d7565b505b6001600160a01b038316600090815260208181526040918290209151612e959291849101614ff6565b60408051601f198184030181529181526001600160a01b038516600090815260208181529190208251612ecd939192909101906137d7565b50612ed9816000612818565b61ffff16836001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b6001600160a01b038416612f4a5760405162461bcd60e51b8152600401610a769061418b565b6001600160a01b038316612f705760405162461bcd60e51b8152600401610a76906141f3565b612f7a3383612793565b612f965760405162461bcd60e51b8152600401610a769061425b565b60005b6001600160a01b038516600090815260208190526040902080548491612fc291610d8490613f62565b61ffff1614158015612ff757506001600160a01b03851660009081526020819052604090208054612ff290613f62565b905081105b1561300e5761300760028261411b565b9050612f99565b6001600160a01b0385166000908152602081905260409020805461303190613f62565b905081106130515760405162461bcd60e51b8152600401610a76906142c3565b60005b6001805461306190613f62565b90508110156130aa57856001600160a01b031661308460018054610eca90613f62565b6001600160a01b03161415613098576130aa565b6130a360148261411b565b9050613054565b856001600160a01b03166130c460018054610eca90613f62565b6001600160a01b0316146130ea5760405162461bcd60e51b8152600401610a769061432b565b6130f686828785612894565b6131028686868661316b565b50505050505050565b61013e80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b156132b7576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a02906131c8903390899088908890600401615000565b602060405180830381600087803b1580156131e257600080fd5b505af1925050508015613212575060408051601f3d908101601f1916820190925261320f9181019061504f565b60015b61326c573d808015613240576040519150601f19603f3d011682016040523d82523d6000602084013e613245565b606091505b5080516132645760405162461bcd60e51b8152600401610a76906150c8565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050612810565b506001949350505050565b6132cd8383836134fe565b611c7660008461331285858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250612818915050565b61ffff166040518060200160405280600081525061316b565b6001600160a01b0382166000908152602081905260408120805482919061335190613f62565b80601f016020809104026020016040519081016040528092919081815260200182805461337d90613f62565b80156133ca5780601f1061339f576101008083540402835291602001916133ca565b820191906000526020600020905b8154815290600101906020018083116133ad57829003601f168201915b5050505050905060005b81518110156132b757836001600160a01b031661013b60006133f68585612818565b61ffff1681526020810191909152604001600020546001600160a01b031614613424576000925050506109b6565b61342f60028261411b565b90506133d4565b60608161344481601f61411b565b10156134625760405162461bcd60e51b8152600401610a769061510a565b61346c828461411b565b8451101561348c5760405162461bcd60e51b8152600401610a769061514c565b6060821580156134ab57604051915060008252602082016040526134f5565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156134e45780518352602092830192016134cc565b5050858452601f01601f1916604052505b50949350505050565b8061351b5760405162461bcd60e51b8152600401610a76906151b4565b613526600282614738565b156135435760405162461bcd60e51b8152600401610a769061521c565b6001600160a01b0383166000908152602081905260409020805461356690613f62565b151590506135ab5760018360601b604051602001613585929190614f9f565b604051602081830303815290604052600190805190602001906135a99291906137d7565b505b60005b818110156137525760026135f984848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250612818915050565b61ffff16612710811061360e5761360e614750565b602081049091015460ff601f9092166101000a900416156136415760405162461bcd60e51b8152600401610a769061525e565b6001600261368685858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250879250612818915050565b61ffff16612710811061369b5761369b614750565b602091828204019190066101000a81548160ff0219169083151502179055506136fb83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859250612818915050565b61ffff16846001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461374b60028261411b565b90506135ae565b506001600160a01b03831660009081526020818152604091829020915161377e9291859185910161526e565b60408051601f198184030181529181526001600160a01b038516600090815260208181529190208251611c76939192909101906137d7565b604051806204e2000160405280612710906020820280368337509192915050565b8280546137e390613f62565b90600052602060002090601f016020900481019282613805576000855561384b565b82601f1061381e57805160ff191683800117855561384b565b8280016001018555821561384b579182015b8281111561384b578251825591602001919060010190613830565b50613857929150613891565b5090565b50805461386790613f62565b6000825580601f10613877575050565b601f01602090049060005260206000209081019061126291905b5b808211156138575760008155600101613892565b7fffffffff0000000000000000000000000000000000000000000000000000000081165b811461126257600080fd5b80356109b6816138a6565b6000602082840312156138f5576138f5600080fd5b600061281084846138d5565b8015155b82525050565b602081016109b68284613901565b61ffff8116613905565b602081016109b68284613919565b60005b8381101561394c578181015183820152602001613934565b83811115611c765750506000910152565b6000613967825190565b80845260208401935061397e818560208601613931565b601f01601f19169290920192915050565b60208082528101611015818461395d565b806138ca565b80356109b6816139a0565b6000602082840312156139c6576139c6600080fd5b600061281084846139a6565b60006001600160a01b0382166109b6565b613905816139d2565b602081016109b682846139e3565b6138ca816139d2565b80356109b6816139fa565b60008060408385031215613a2457613a24600080fd5b6000613a308585613a03565b9250506020613a41858286016139a6565b9150509250929050565b600060208284031215613a6057613a60600080fd5b60006128108484613a03565b80613905565b602081016109b68284613a6c565b600080600060608486031215613a9857613a98600080fd5b6000613aa48686613a03565b9350506020613ab586828701613a03565b9250506040613ac6868287016139a6565b9150509250925092565b600080600060608486031215613ae857613ae8600080fd5b6000613af48686613a03565b9350506020613ab5868287016139a6565b60ff8116613905565b602081016109b68284613b05565b60008060008060808587031215613b3557613b35600080fd5b6000613b418787613a03565b9450506020613b52878288016139a6565b9350506040613b6387828801613a03565b9250506060613b74878288016139a6565b91505092959194509250565b60008083601f840112613b9557613b95600080fd5b50813567ffffffffffffffff811115613bb057613bb0600080fd5b602083019150836001820283011115613bcb57613bcb600080fd5b9250929050565b60008060208385031215613be857613be8600080fd5b823567ffffffffffffffff811115613c0257613c02600080fd5b613c0e85828601613b80565b92509250509250929050565b613c248282613901565b5060200190565b60200190565b6127108160005b82811015610fc0578151613c4c8682613c1a565b955050602082019150600101613c38565b6204e20081016109b68284613c31565b8015156138ca565b80356109b681613c6d565b60008060408385031215613c9657613c96600080fd5b6000613ca28585613a03565b9250506020613a4185828601613c75565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff82111715613cef57613cef613cb3565b6040525050565b6000613d0160405190565b9050613d0d8282613cc9565b919050565b600067ffffffffffffffff821115613d2c57613d2c613cb3565b601f19601f83011660200192915050565b82818337506000910152565b6000613d5c613d5784613d12565b613cf6565b905082815260208101848484011115613d7757613d77600080fd5b613d82848285613d3d565b509392505050565b600082601f830112613d9e57613d9e600080fd5b8135612810848260208601613d49565b60008060008060808587031215613dc757613dc7600080fd5b6000613dd38787613a03565b9450506020613de487828801613a03565b9350506040613df5878288016139a6565b925050606085013567ffffffffffffffff811115613e1557613e15600080fd5b613b7487828801613d8a565b60008083601f840112613e3657613e36600080fd5b50813567ffffffffffffffff811115613e5157613e51600080fd5b602083019150836020820283011115613bcb57613bcb600080fd5b60008060008060008060608789031215613e8857613e88600080fd5b863567ffffffffffffffff811115613ea257613ea2600080fd5b613eae89828a01613b80565b9650965050602087013567ffffffffffffffff811115613ed057613ed0600080fd5b613edc89828a01613e21565b9450945050604087013567ffffffffffffffff811115613efe57613efe600080fd5b613f0a89828a01613e21565b92509250509295509295509295565b60008060408385031215613f2f57613f2f600080fd5b6000613f3b8585613a03565b9250506020613a4185828601613a03565b634e487b7160e01b600052602260045260246000fd5b600281046001821680613f7657607f821691505b60208210811415610c6a57610c6a613f4c565b601c8152602081017f4552433732313a20746f6b656e20646f6573206e6f742065786973740000000081529050613c2b565b602080825281016109b681613f89565b602b8152602081017f4552433732313a20617070726f766520717565727920666f72206e6f6e65786981527f7374656e7420746f6b656e000000000000000000000000000000000000000000602082015290505b60400190565b602080825281016109b681613fcb565b60468152602081017f4552433732313a2063616c6c6572206973206e6f7420746865206f776e65722081527f6e6f7220616e20617070726f766564206f70657261746f7220666f722074686560208201527f20746f6b656e0000000000000000000000000000000000000000000000000000604082015290505b60600190565b602080825281016109b681614035565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65729101908152613c2b565b602080825281016109b6816140c5565b634e487b7160e01b600052601160045260246000fd5b6000821982111561412e5761412e614105565b500190565b60278152602081017f4552433732313a2066726f6d2063616e6e6f7420626520746865207a65726f2081527f61646472657373000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614133565b60258152602081017f4552433732313a20746f2063616e6e6f7420626520746865207a65726f20616481527f64726573730000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b68161419b565b60318152602081017f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f81527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020820152905061401f565b602080825281016109b681614203565b60238152602081017f4552433732313a2066726f6d20646f6573206e6f74206f776e2074686520746f81527f6b656e00000000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b68161426b565b60228152602081017f4552433732313a2066726f6d206973206e6f7420696e206f776e657273206c6981527f73740000000000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816142d3565b634e487b7160e01b600052601260045260246000fd5b6000826143605761436061433b565b500490565b60178152602081017f4552433732313a204f776e6572206e6f7420666f756e6400000000000000000081529050613c2b565b602080825281016109b681614365565b60008160001904831182151516156143c1576143c1614105565b500290565b60248152602081017f455243373231456e756d657261626c653a20696e646578206f7574206f66207281527f616e6765000000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816143c6565b60118152602081017f5769746864726177616c206661696c656400000000000000000000000000000081529050613c2b565b602080825281016109b68161442e565b60208082527f4552433732313a20746f6b656e20696e646578206f7574206f662072616e67659101908152613c2b565b602080825281016109b681614470565b602c8152602081017f4552433732313a2063616c6c6572206973206e65697468657220617070726f7681527f6564206e6f72206f776e657200000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816144b0565b60008282101561452a5761452a614105565b500390565b60298152602081017f4552433732313a206f776e657220717565727920666f72206e6f6e657869737481527f656e7420746f6b656e00000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b68161452f565b601f8152602081017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081529050613c2b565b602080825281016109b681614597565b60148152602081017f5075626c69632073616c65206e6f74206f70656e00000000000000000000000081529050613c2b565b602080825281016109b6816145d9565b60138152602081017f446f6e277420626520746f6f206772656564790000000000000000000000000081529050613c2b565b602080825281016109b68161461b565b603f8152602081017f4576656e20696620796f7520617265206120666f756e6465722c20796f75206481527f6f6e277420646573657276652074686174206d616e7920447265616d657273006020820152905061401f565b602080825281016109b68161465d565b61412e828483613d3d565b60006109b68260601b90565b60006109b6826146d0565b6139056146f3826139d2565b6146dc565b90565b6147068186886146c5565b905061471281856146e7565b60140161471f8184613a6c565b60200161472c8183613a6c565b60200195945050505050565b815b915060008261474b5761474b61433b565b500690565b634e487b7160e01b600052603260045260246000fd5b6147708183613a6c565b602001919050565b600060001982141561478c5761478c614105565b5060010190565b60298152602081017f4552433732313a2063616e6e6f7420617070726f76652063616c6c657220617381527f206f70657261746f7200000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614793565b60278152602081017f4552433732313a2055524920717565727920666f72206e6f6e6578697374656e81527f7420746f6b656e000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816147fb565b604081016148718285613a6c565b6110156020830184613b05565b600061488c613d5784613d12565b9050828152602081018484840111156148a7576148a7600080fd5b613d82848285613931565b600082601f8301126148c6576148c6600080fd5b815161281084826020860161487e565b6000602082840312156148eb576148eb600080fd5b815167ffffffffffffffff81111561490557614905600080fd5b612810848285016148b2565b60288152602081017f456163682072756e6e6572206e65656473206f6e6520616e64206f6e6c79206f81527f6e652063616e64790000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614911565b825b925060007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156149af576149af600080fd5b6020830292506149c0838584613d3d565b50500190565b6149d181888a6146c5565b90506149dd81876146e7565b6014016149eb818587614979565b90506149f78184613a6c565b602001614a048183613a6c565b602001979650505050505050565b60006109b66146f861ffff841681565b61390581614a12565b602081016109b68284614a22565b80516109b6816139fa565b600060208284031215614a5957614a59600080fd5b60006128108484614a39565b60378152602081017f596f752063616e6e6f7420676976652063616e6469657320746f20612072756e81527f6e6572207468617420796f7520646f206e6f74206f776e0000000000000000006020820152905061401f565b602080825281016109b681614a65565b604f8152602081017f596f75722072756e6e6572206e65656473206f6e6520616e64206f6e6c79206f81527f6e652063616e64792c2077686f206b6e6f7773207768617420636f756c64206860208201527f617070656e206f74686572776973650000000000000000000000000000000000604082015290506140af565b602080825281016109b681614acd565b60ff90811690821661473a565b60ff8116905060ff8216915060008260ff0382111561412e5761412e614105565b8183526020830161497b565b60608101614ba382886139e3565b8181036020830152614bb6818688614b89565b90508181036040830152614bcb818486614b89565b979650505050505050565b60006109b6826139d2565b6138ca81614bd6565b80516109b681614be1565b600060208284031215614c0a57614c0a600080fd5b60006128108484614bea565b60268152602081017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181527f64647265737300000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614c16565b601d8152602081017f596f75206861766520746f2070617920746865206261696c20626f6e6400000081529050613c2b565b602080825281016109b681614c7e565b60318152602081017f596f757220686f6d6520697320746f20736d616c6c20746f2077656c636f6d6581527f20736f206d616e7920647265616d6572730000000000000000000000000000006020820152905061401f565b602080825281016109b681614cc0565b614d338187896146c5565b9050614d3f81866146e7565b601401614d4c8185613a6c565b602001614d598184613a6c565b602001614d668183613a6c565b6020019695505050505050565b601f8152602081017f4552433732313a206f776e6572496e646578206f7574206f6620626f756e640081529050613c2b565b602080825281016109b681614d73565b602c8152602081017f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657881527f697374656e7420746f6b656e00000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614db5565b60148152602081017f746f55696e7431365f6f75744f66426f756e647300000000000000000000000081529050613c2b565b602080825281016109b681614e1d565b60158152602081017f746f416464726573735f6f75744f66426f756e6473000000000000000000000081529050613c2b565b602080825281016109b681614e5f565b60288152602081017f4552433732313a207472616e736665722066726f6d206164647265737320697381527f20696e76616c69640000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b681614ea1565b60008154614f1681613f62565b600182168015614f2d5760018114614f3e57614f6e565b60ff19831686528186019350614f6e565b60008581526020902060005b83811015614f6657815488820152600190910190602001614f4a565b505081860193505b50505092915050565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116613905565b614fa98184614f09565b9050614fb58183614f77565b60140192915050565b6000614fc8825190565b614fd6818560208601613931565b9290920192915050565b614fea8184614fbe565b90506110158183614fbe565b614fea8184614f09565b6080810161500e82876139e3565b61501b60208301866139e3565b6150286040830185613a6c565b818103606083015261503a818461395d565b9695505050505050565b80516109b6816138a6565b60006020828403121561506457615064600080fd5b60006128108484615044565b60328152602081017f4552433732313a207472616e7366657220746f206e6f6e20455243373231526581527f63656976657220696d706c656d656e74657200000000000000000000000000006020820152905061401f565b602080825281016109b681615070565b600e8152602081017f736c6963655f6f766572666c6f7700000000000000000000000000000000000081529050613c2b565b602080825281016109b6816150d8565b60118152602081017f736c6963655f6f75744f66426f756e647300000000000000000000000000000081529050613c2b565b602080825281016109b68161511a565b60258152602081017f4552433732313a2063616e6e6f74206d696e742077697468206e6f20746f6b6581527f6e204964730000000000000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b68161515c565b602a8152602081017f4552433732313a20746f6b656e4964732073686f756c6420626520627974657381527f206f662075696e743136000000000000000000000000000000000000000000006020820152905061401f565b602080825281016109b6816151c4565b601c8152602081017f4552433732313a20746f6b656e20616c7265616479206578697374730000000081529050613c2b565b602080825281016109b68161522c565b6152788185614f09565b90506128108183856146c556fea264697066735822122046587b314b050c95aee2c01fa6c16505ba58492e42a5f478d8f70aa704ed6ad964736f6c63430008080033

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

00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000e436861696e20447265616d65727300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034452450000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): Chain Dreamers
Arg [1] : symbol_ (string): DRE

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [3] : 436861696e20447265616d657273000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [5] : 4452450000000000000000000000000000000000000000000000000000000000


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

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