ETH Price: $2,684.88 (-2.13%)

Contract

0xE53c5FcE669d16F61204C1ae0DBD699085d07CC9
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MultiStageAllowlistCloneable

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 18 : MultistageAllowlistCloneable.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.6;

// Imports.
import { ICollection } from "./interfaces/ICollection.sol";
import { ICollectionCloneable } from "./interfaces/ICollectionCloneable.sol";
import { ICollectionNFTEligibilityPredicate } from "./interfaces/ICollectionNFTEligibilityPredicate.sol";
import { ICollectionNFTMintFeePredicate } from "./interfaces/ICollectionNFTMintFeePredicate.sol";
import { IHashes } from "./interfaces/IHashes.sol";
import { OwnableCloneable } from "./lib/OwnableCloneable.sol";

/**
 * @title The interface for the NFT smart contract.
 * @dev The following interface is used to properly call functions of the NFT smart contract.
 *      The interface is necessary as it describes the functions that are present in the CollectionNFTCloneableV1
 *      smart contract but are not specified in its interfaces.
 */
interface INFT {
    /**
     * @notice Returns the current token ID (number of minted NFTs).
     * @return The current token ID.
     */
    function nonce() external view returns (uint256);

    /**
     * @notice Returns the owner of the tokenId token.
     * @param tokenId The token ID to get the owner of.
     * @return The owner address.
     */
    function ownerOf(uint256 tokenId) external view returns (address);

    /**
     * @notice Returns the number of Hashes qualifying for governance.
     * @return The number of Hashes qualifying for governance.
     */
    function governanceCap() external view returns (uint256);
}

/**
 * @title Cloneable Multi-stage Allowlist.
 * @notice This contract is a cloneable extension to the Hashes ecosystem. Its main goal is to introduce
 *         a decentralized allowlist and the ability to control mint eligibility and fees.  The contract
 *         allows owners to create and manage staged minting NFT events, including allowlists,
 *         maximum numbers of tokens, prices, etc. It can be directly integrated into the ecosystem and
 *         used with the CollectionNFTCloneableV1 smart contracts.
 * @author PopBlocks (popblocks.org)
 */
contract MultiStageAllowlistCloneable is
    ICollection,
    ICollectionCloneable,
    ICollectionNFTEligibilityPredicate,
    ICollectionNFTMintFeePredicate,
    OwnableCloneable
{
    /**
     * @notice The struct specifies a selling stage.
     * @dev param onlyDaoHashes - The flag indicates that only DAO hashes are eligible to mint during the stage.
     * @dev param allowlistActivated - Specifies if the tokenIdAllowlist and walletAllowlist should be considered.
     * @dev param size - The max number of tokens available to mint during the stage.
     * @dev param eligibilityExtension - An additional smart contract that can be used to check eligibility to mint.
                                         Set to address(0) to disable the functionality.
     * @dev param price - The mint price during the stage.
     * @dev param allowlistSize - The size of the mapping of bitfields.
     * @dev param tokenIdAllowlist - The bitmaps that specify what token IDs are eligible to mint during the stage.
     * @dev param walletAllowlist - The additional mapping of allowed or blocked wallet addresses.
     */
    struct Stage {
        bool onlyDaoHashes;
        bool allowlistActivated;
        uint32 size;
        ICollectionNFTEligibilityPredicate eligibilityExtension;
        uint256 price;
        uint256 allowlistSize;
        mapping(uint256 => uint256) tokenIdAllowlist;
        mapping(address => bool) walletAllowlist;
    }

    /**
     * @notice The struct specifies a selling stage.
     * @dev param onlyDaoHashes - The flag indicates that only DAO hashes are eligible to mint during the stage.
     * @dev param allowlistActivated - Specifies if the tokenIdAllowlist and walletAllowlist should be considered.
     * @dev param eligibilityExtension - An additional smart contract that can be used to check eligibility to mint.
                                         Set to address(0) to disable the functionality.
     * @dev param size - The max number of tokens available to mint during the stage.
     * @dev param price - The mint price during the stage.
     * @dev param walletAllowlist - The additional mapping of allowed wallet addresses.
     * @dev param tokenIdAllowlist - The bitmaps that specify what token IDs are eligible to mint during the stage.
     */
    struct InitializerSettings {
        bool onlyDaoHashes;
        bool allowlistActivated;
        address eligibilityExtension;
        uint32 size;
        uint256 price;
        address[] walletAllowlist;
        uint256[] tokenIdAllowlist;
    }

    /// @notice The constant that specifies that the size of a stage is not limited.
    uint8 public constant UNLIMITED_TOKENS = 0;
    /// @notice The number of token ID positions per single element of the allowlist array.
    uint256 public constant IDS_PER_ELEMENT = 256;
    /// @notice The starting token ID for the current round.
    uint256 public startTokenId;
    /// @notice The Hashes NFT smart contract interface.
    INFT public hashesContract;
    /// @notice The NFT smart contract interface.
    INFT public collectionNFTContract;
    /// @notice The number of Hashes qualifying for governance.
    uint256 public hashesGovernanceCap;
    /// @notice The available stages.
    Stage[] public stages;
    /// @notice The number of stages.
    uint8 public numStages;
    /// @notice The flag controls stage activation.
    bool public stagesActive;
    /// @notice The switch turns off minting forever.
    bool public mintingClosed;
    /// @notice The current active stage.
    uint8 public currentStage;
    /// @notice The initialization state of the current smart contract.
    bool private _initialized;

    /**
     * @notice Checks if a stage index is valid.
     * @dev Reverts when the stage index is out of bound.
     * @param stage The index of a stage.
     */
    modifier validStage(uint8 stage) {
        require(stage < stages.length, "Stage ID is out of bound.");
        _;
    }

    /**
     * @notice Checks if the current smart contract is properly initialized.
     */
    modifier isInitialized() {
        require(
            _initialized && address(collectionNFTContract) != address(0),
            "The smart contract needs to be initialized before using."
        );
        _;
    }

    /**
     * @notice This function initializes a cloneable implementation contract.
     * @param hashesToken_ The Hashes NFT contract address.
     * @param factoryMaintainerAddress_ The address of the current factory maintainer.
     * @param createCollectionCaller_ The address which has called createCollection on the factory.
     *        This will be the Owner role of this collection.
     * @param initializationData_ ABI encoded initialization data. This expected encoding is a struct
     *        with the properties described in the InitializerSettings structure.
     */
    function initialize(
        IHashes hashesToken_,
        address factoryMaintainerAddress_,
        address createCollectionCaller_,
        bytes memory initializationData_
    ) external override {
        require(!_initialized, "The smart contract has been already initialized.");
        // Set initialization state.
        _initialized = true;
        // Initialize the owner.
        initializeOwnership(createCollectionCaller_);
        // Set the state variables.
        hashesContract = INFT(address(hashesToken_));
        hashesGovernanceCap = hashesContract.governanceCap();
        // Decode initialization data.
        InitializerSettings[] memory newStages = abi.decode(initializationData_, (InitializerSettings[]));

        for (uint8 i = 0; i < newStages.length; i++) {
            stages.push();
            stages[i].size = newStages[i].size;
            stages[i].price = newStages[i].price;
            stages[i].onlyDaoHashes = newStages[i].onlyDaoHashes;
            stages[i].allowlistActivated = newStages[i].allowlistActivated;
            stages[i].eligibilityExtension = ICollectionNFTEligibilityPredicate(newStages[i].eligibilityExtension);
            stages[i].allowlistSize = newStages[i].tokenIdAllowlist.length;

            for (uint256 k = 0; k < newStages[i].tokenIdAllowlist.length; k++) {
                stages[i].tokenIdAllowlist[k] = newStages[i].tokenIdAllowlist[k];
            }
            
            for (uint256 j = 0; j < newStages[i].walletAllowlist.length; j++) {
                stages[i].walletAllowlist[newStages[i].walletAllowlist[j]] = true;
            }
        }

        currentStage = type(uint8).max;
        numStages = uint8(stages.length);
    }

    /**
     * @notice Sets the NFT smart contract address to be used during minting.
     * @param nftAddress The address of the NFT smart contract.
     */
    function setNftAddress(address nftAddress) external onlyOwner {
        require(address(collectionNFTContract) == address(0), "The NFT address has already been set.");
        require(nftAddress != address(0), "The NFT address cannot be a zero address.");
        collectionNFTContract = INFT(nftAddress);
    }

    /**
     * @notice Sets eligibility to mint for a specific token ID.
     * @param stage The ID of the stage.
     * @param tokenId The ID of the token.
     * @param eligibility Eligibility status.
     */
    function setTokenIdEligibility(
        uint8 stage,
        uint256 tokenId,
        bool eligibility
    ) external onlyOwner isInitialized validStage(stage) {
        (uint256 elementIndex, uint256 bitIndex) = _getTokenElementPositions(tokenId);
        if (eligibility) {
            stages[stage].tokenIdAllowlist[elementIndex] = _setBit(
                stages[stage].tokenIdAllowlist[elementIndex],
                bitIndex
            );
        } else {
            stages[stage].tokenIdAllowlist[elementIndex] = _clearBit(
                stages[stage].tokenIdAllowlist[elementIndex],
                bitIndex
            );
        }
    }

    /**
     * @notice Sets a token ID allowlist for a specified stage.
     * @param stage The ID of the stage.
     * @param tokenIdAllowlist The bitmaps that specify what token IDs are eligible to mint during the stage.
     */
    function setTokenIdAllowlist(uint8 stage, uint256[] memory tokenIdAllowlist)
        external
        onlyOwner
        isInitialized
        validStage(stage)
    {
        for (uint256 i = 0; i < tokenIdAllowlist.length; i++) {
            stages[stage].tokenIdAllowlist[i] = tokenIdAllowlist[i];
        }

        stages[stage].allowlistSize = tokenIdAllowlist.length;
    }

    /**
     * @notice Sets eligibility to mint for a specific wallet.
     * @param stage The ID of the stage.
     * @param walletAddress The wallet address.
     * @param eligibility Eligibility status.
     */
    function setWalletEligibility(
        uint8 stage,
        address walletAddress,
        bool eligibility
    ) external onlyOwner isInitialized validStage(stage) {
        stages[stage].walletAllowlist[walletAddress] = eligibility;
    }

    /**
     * @notice Sets the eligibility extension.
     * @param stage The ID of the stage.
     * @param extensionAddress The address of a CollectionNFTEligibilityPredicate smart contract.
     */
    function setEligibilityExtension(uint8 stage, address extensionAddress)
        external
        onlyOwner
        isInitialized
        validStage(stage)
    {
        stages[stage].eligibilityExtension = ICollectionNFTEligibilityPredicate(extensionAddress);
    }

    /**
     * @notice Turns minting on and off.
     * @param state Set to true to turn the minting process on, else set to false.
     */
    function setStageState(bool state) external onlyOwner isInitialized {
        stagesActive = state;
    }

    /**
     * @notice Turns off minting forever.
     */
    function closeMinting() external onlyOwner isInitialized {
        mintingClosed = true;
    }

    /**
     * @notice Starts next stage.
     */
    function startNextStage() external isInitialized onlyOwner {
        if (currentStage == type(uint8).max) {
            currentStage = 0;
        } else {
            require(++currentStage < stages.length, "No more available stages.");
        }

        startTokenId = collectionNFTContract.nonce();
    }

    /**
     * @notice Starts a specific stage.
     * @param stageIndex The index of a stage to start.
     */
    function startStage(uint8 stageIndex) external isInitialized validStage(stageIndex) onlyOwner {
        if (currentStage != type(uint256).max) {
            require(stageIndex > currentStage, "Cannot set previous stages as active.");
        }

        currentStage = stageIndex;
        startTokenId = collectionNFTContract.nonce();
    }

    /**
     * @notice Checks if a user is eligible to mint a token.
     * @param _tokenId The token ID to be minted.
     * @param _hashesTokenId The hashes token ID used to mint.
     * @return True, if the user is eligible to mint, else - false.
     */
    function isTokenEligibleToMint(uint256 _tokenId, uint256 _hashesTokenId)
        external
        view
        override
        isInitialized
        returns (bool)
    {
        if (
            mintingClosed ||
            !stagesActive ||
            (stages[currentStage].size != UNLIMITED_TOKENS && _tokenId >= startTokenId + stages[currentStage].size) ||
            _tokenId < startTokenId ||
            (stages[currentStage].onlyDaoHashes && _hashesTokenId >= hashesGovernanceCap)
        ) {
            return false;
        }

        bool eligibilityExtensionStatus = true;
        bool allowlistStatus = true;

        if (stages[currentStage].allowlistActivated) {
            allowlistStatus =
                _isTokenIdAllowed(currentStage, _hashesTokenId) ||
                stages[currentStage].walletAllowlist[hashesContract.ownerOf(_hashesTokenId)];
        }

        if (address(stages[currentStage].eligibilityExtension) != address(0)) {
            eligibilityExtensionStatus = stages[currentStage].eligibilityExtension.isTokenEligibleToMint(
                _tokenId,
                _hashesTokenId
            );
        }

        return allowlistStatus && eligibilityExtensionStatus;
    }

    /**
     * @notice Gets the mint fee for the current stage.
     * @param _tokenId The token ID to be minted.
     * @param _hashesTokenId The hashes token ID used to mint.
     * @return The mint fee.
     */
    function getTokenMintFee(uint256 _tokenId, uint256 _hashesTokenId)
        external
        view
        override
        isInitialized
        returns (uint256)
    {
        return stages[currentStage].price;
    }

    /**
     * @notice This function is used by the Factory to verify the format of ecosystem settings.
     * @dev The Default ecosystem doesn't use any ecosystem settings.
     * @param _settings ABI encoded ecosystem settings data.
     * @return The boolean result of the validation.
     */
    function verifyEcosystemSettings(bytes memory _settings) external pure override returns (bool) {
        return _settings.length == 0;
    }

    /**
     * @notice Checks if a token ID is in the allowlist.
     * @param stage The ID of the stage.
     * @param tokenId The ID of the token.
     * @return True, if token ID is allowed, else - false.
     */
    function _isTokenIdAllowed(uint8 stage, uint256 tokenId) internal view validStage(stage) returns (bool) {
        // Check if provided token ID is out of the bounds of the allowlist.
        if (tokenId >= stages[stage].allowlistSize * IDS_PER_ELEMENT) return false;

        (uint256 elementIndex, uint256 bitIndex) = _getTokenElementPositions(tokenId);
        uint256 element = stages[stage].tokenIdAllowlist[elementIndex];
        uint256 bit = 1;
        return (element & (bit << bitIndex)) > 0;
    }

    /**
     * @notice Gets token ID bit position in the allowlist array.
     * @param tokenId The ID of the token.
     * @return The element index of the array and the token bit position in the element.
     */
    function _getTokenElementPositions(uint256 tokenId) internal pure returns (uint256, uint256) {
        // The index of the element in the array of the allowlist bitfields.
        uint256 elementIndex = tokenId / IDS_PER_ELEMENT;
        // The index of the bit in the bitfield.
        uint256 bitIndex = tokenId % IDS_PER_ELEMENT;

        return (elementIndex, bitIndex);
    }

    /**
     * @notice Sets a bit in a bitfield.
     * @param bitField The bitfield.
     * @param position The position of the bit to set.
     */
    function _setBit(uint256 bitField, uint256 position) internal pure returns (uint256) {
        require(position < 256, "Exceeds the number of bits in uint256.");
        return bitField | (uint256(1) << position);
    }

    /**
     * @notice Clears a bit in a bitfield.
     * @param bitField The bitfield.
     * @param position The position of the bit to clear.
     */
    function _clearBit(uint256 bitField, uint256 position) internal pure returns (uint256) {
        require(position < 256, "Exceeds the number of bits in uint256.");
        return bitField & ~(uint256(1) << position);
    }
}

File 2 of 18 : ICollection.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.6;

interface ICollection {
    function verifyEcosystemSettings(bytes memory _settings) external pure returns (bool);
}

File 3 of 18 : ICollectionCloneable.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.6;

import { IHashes } from "./IHashes.sol";

interface ICollectionCloneable {
    function initialize(
        IHashes _hashesToken,
        address _factoryMaintainerAddress,
        address _createCollectionCaller,
        bytes memory _initializationData
    ) external;
}

File 4 of 18 : ICollectionNFTEligibilityPredicate.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.6;

interface ICollectionNFTEligibilityPredicate {
    function isTokenEligibleToMint(uint256 _tokenId, uint256 _hashesTokenId) external view returns (bool);
}

File 5 of 18 : ICollectionNFTMintFeePredicate.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.6;

interface ICollectionNFTMintFeePredicate {
    function getTokenMintFee(uint256 _tokenId, uint256 _hashesTokenId) external view returns (uint256);
}

File 6 of 18 : IHashes.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.6;

import { IERC721Enumerable } from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";

interface IHashes is IERC721Enumerable {
    function deactivateTokens(
        address _owner,
        uint256 _proposalId,
        bytes memory _signature
    ) external returns (uint256);

    function deactivated(uint256 _tokenId) external view returns (bool);

    function activationFee() external view returns (uint256);

    function verify(
        uint256 _tokenId,
        address _minter,
        string memory _phrase
    ) external view returns (bool);

    function getHash(uint256 _tokenId) external view returns (bytes32);

    function getPriorVotes(address account, uint256 blockNumber) external view returns (uint256);
}

File 7 of 18 : OwnableCloneable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;

import "@openzeppelin/contracts/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.
 *
 * This is a modified version of the openzeppelin Ownable contract which works
 * with the cloneable contract pattern. Instead of initializing ownership in the
 * constructor, we have an empty constructor and then perform setup in the
 * initializeOwnership function.
 */
abstract contract OwnableCloneable is Context {
    bool ownableInitialized;
    address private _owner;

    modifier ownershipInitialized() {
        require(ownableInitialized, "OwnableCloneable: hasn't been initialized yet.");
        _;
    }

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

    /**
     * @dev Initializes the contract setting the initialize caller as the initial owner.
     */
    function initializeOwnership(address initialOwner) public virtual {
        require(!ownableInitialized, "OwnableCloneable: already initialized.");
        ownableInitialized = true;
        _setOwner(initialOwner);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "OwnableCloneable: 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 ownershipInitialized onlyOwner {
        _setOwner(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 ownershipInitialized onlyOwner {
        require(newOwner != address(0), "OwnableCloneable: new owner is the zero address");
        _setOwner(newOwner);
    }

    // This is set to internal so overriden versions of renounce/transfer ownership
    // can also be carried out by DAO address.
    function _setOwner(address newOwner) internal ownershipInitialized {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 8 of 18 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (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);

    /**
     * @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 9 of 18 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

File 10 of 18 : 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 18 : 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 12 of 18 : MultistageAllowlistCloneable.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../contracts/MultistageAllowlistCloneable.sol";

abstract contract $INFT is INFT {
    constructor() {}
}

contract $MultiStageAllowlistCloneable is MultiStageAllowlistCloneable {
    constructor() {}

    function $ownableInitialized() external view returns (bool) {
        return ownableInitialized;
    }

    function $_isTokenIdAllowed(uint8 stage,uint256 tokenId) external view returns (bool) {
        return super._isTokenIdAllowed(stage,tokenId);
    }

    function $_getTokenElementPositions(uint256 tokenId) external pure returns (uint256, uint256) {
        return super._getTokenElementPositions(tokenId);
    }

    function $_setBit(uint256 bitField,uint256 position) external pure returns (uint256) {
        return super._setBit(bitField,position);
    }

    function $_clearBit(uint256 bitField,uint256 position) external pure returns (uint256) {
        return super._clearBit(bitField,position);
    }

    function $_setOwner(address newOwner) external {
        return super._setOwner(newOwner);
    }

    function $_msgSender() external view returns (address) {
        return super._msgSender();
    }

    function $_msgData() external view returns (bytes memory) {
        return super._msgData();
    }
}

File 13 of 18 : ICollection.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/interfaces/ICollection.sol";

abstract contract $ICollection is ICollection {
    constructor() {}
}

File 14 of 18 : ICollectionCloneable.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/interfaces/ICollectionCloneable.sol";

abstract contract $ICollectionCloneable is ICollectionCloneable {
    constructor() {}
}

File 15 of 18 : ICollectionNFTEligibilityPredicate.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/interfaces/ICollectionNFTEligibilityPredicate.sol";

abstract contract $ICollectionNFTEligibilityPredicate is ICollectionNFTEligibilityPredicate {
    constructor() {}
}

File 16 of 18 : ICollectionNFTMintFeePredicate.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/interfaces/ICollectionNFTMintFeePredicate.sol";

abstract contract $ICollectionNFTMintFeePredicate is ICollectionNFTMintFeePredicate {
    constructor() {}
}

File 17 of 18 : IHashes.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/interfaces/IHashes.sol";

abstract contract $IHashes is IHashes {
    constructor() {}
}

File 18 of 18 : OwnableCloneable.sol
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.6.0;

import "../../contracts/lib/OwnableCloneable.sol";

contract $OwnableCloneable is OwnableCloneable {
    constructor() {}

    function $ownableInitialized() external view returns (bool) {
        return ownableInitialized;
    }

    function $_setOwner(address newOwner) external {
        return super._setOwner(newOwner);
    }

    function $_msgSender() external view returns (address) {
        return super._msgSender();
    }

    function $_msgData() external view returns (bytes memory) {
        return super._msgData();
    }
}

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

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"IDS_PER_ELEMENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNLIMITED_TOKENS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closeMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectionNFTContract","outputs":[{"internalType":"contract INFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentStage","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_hashesTokenId","type":"uint256"}],"name":"getTokenMintFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hashesContract","outputs":[{"internalType":"contract INFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hashesGovernanceCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IHashes","name":"hashesToken_","type":"address"},{"internalType":"address","name":"factoryMaintainerAddress_","type":"address"},{"internalType":"address","name":"createCollectionCaller_","type":"address"},{"internalType":"bytes","name":"initializationData_","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"}],"name":"initializeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_hashesTokenId","type":"uint256"}],"name":"isTokenEligibleToMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintingClosed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numStages","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"stage","type":"uint8"},{"internalType":"address","name":"extensionAddress","type":"address"}],"name":"setEligibilityExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"}],"name":"setNftAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"setStageState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"stage","type":"uint8"},{"internalType":"uint256[]","name":"tokenIdAllowlist","type":"uint256[]"}],"name":"setTokenIdAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"stage","type":"uint8"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"eligibility","type":"bool"}],"name":"setTokenIdEligibility","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"stage","type":"uint8"},{"internalType":"address","name":"walletAddress","type":"address"},{"internalType":"bool","name":"eligibility","type":"bool"}],"name":"setWalletEligibility","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stages","outputs":[{"internalType":"bool","name":"onlyDaoHashes","type":"bool"},{"internalType":"bool","name":"allowlistActivated","type":"bool"},{"internalType":"uint32","name":"size","type":"uint32"},{"internalType":"contract ICollectionNFTEligibilityPredicate","name":"eligibilityExtension","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"allowlistSize","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stagesActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startNextStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"stageIndex","type":"uint8"}],"name":"startStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_settings","type":"bytes"}],"name":"verifyEcosystemSettings","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}]

608060405234801561001057600080fd5b506124be806100206000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806371fd2c38116100f9578063a4908f2311610097578063e04f9e8211610071578063e04f9e82146103d2578063e6798baa146103e5578063efbd676b146103ee578063f2fde38b1461040157600080fd5b8063a4908f2314610399578063ae2bd56b146103ac578063b2b93b73146103bf57600080fd5b8063845ddcb2116100d3578063845ddcb21461032057806387491c60146103765780638da5cb5b1461037e5780639626f09c1461038657600080fd5b806371fd2c38146102df578063788fe59d146102e857806382eb71c11461031357600080fd5b8063246581f7116101665780635cd9205f116101405780635cd9205f146102a95780635ee6509a146102bc57806362fbcf9a146102c4578063715018a6146102d757600080fd5b8063246581f714610279578063485722221461028c5780635bf5d54c1461029557600080fd5b806315f7485b116101a257806315f7485b146102205780631bed2a26146102325780631cc1fddb146102455780631d19e1811461026657600080fd5b806304eff22f146101c957806307b5dfde146101f15780630b102d1a1461020b575b600080fd5b6101dc6101d7366004611f03565b511590565b60405190151581526020015b60405180910390f35b6101f9600081565b60405160ff90911681526020016101e8565b61021e610219366004611d2b565b610414565b005b6006546101dc90610100900460ff1681565b61021e6102403660046120a4565b61053d565b610258610253366004611fe7565b610672565b6040519081526020016101e8565b61021e61027436600461205b565b6106f1565b61021e610287366004611f40565b6107dd565b61025860045481565b6006546101f9906301000000900460ff1681565b61021e6102b7366004611d2b565b610d08565b61021e610d83565b61021e6102d2366004612024565b610f27565b61021e61100c565b61025861010081565b6003546102fb906001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b6006546101f99060ff1681565b61033361032e366004611fb5565b611069565b604080519615158752941515602087015263ffffffff909316938501939093526001600160a01b03166060840152608083019190915260a082015260c0016101e8565b61021e6110c5565b6102fb611146565b6101dc610394366004611fe7565b61117e565b61021e6103a7366004611ec9565b611530565b61021e6103ba36600461214f565b6115b8565b6006546101dc9062010000900460ff1681565b61021e6103e0366004612009565b611760565b61025860015481565b6002546102fb906001600160a01b031681565b61021e61040f366004611d2b565b611913565b3361041d611146565b6001600160a01b03161461044c5760405162461bcd60e51b8152600401610443906121d2565b60405180910390fd5b6003546001600160a01b0316156104b35760405162461bcd60e51b815260206004820152602560248201527f546865204e465420616464726573732068617320616c7265616479206265656e6044820152641039b2ba1760d91b6064820152608401610443565b6001600160a01b03811661051b5760405162461bcd60e51b815260206004820152602960248201527f546865204e465420616464726573732063616e6e6f742062652061207a65726f6044820152681030b2323932b9b99760b91b6064820152608401610443565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b33610546611146565b6001600160a01b03161461056c5760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561058f57506003546001600160a01b031615155b6105ab5760405162461bcd60e51b815260040161044390612261565b600554829060ff8216106105d15760405162461bcd60e51b8152600401610443906122be565b60005b825181101561063f578281815181106105ef576105ef612439565b602002602001015160058560ff168154811061060d5761060d612439565b600091825260208083208584526003600590930201919091019052604090205580610637816123be565b9150506105d4565b50815160058460ff168154811061065857610658612439565b906000526020600020906005020160020181905550505050565b600654600090600160201b900460ff16801561069857506003546001600160a01b031615155b6106b45760405162461bcd60e51b815260040161044390612261565b6006546005805490916301000000900460ff169081106106d6576106d6612439565b90600052602060002090600502016001015490505b92915050565b336106fa611146565b6001600160a01b0316146107205760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561074357506003546001600160a01b031615155b61075f5760405162461bcd60e51b815260040161044390612261565b600554839060ff8216106107855760405162461bcd60e51b8152600401610443906122be565b8160058560ff168154811061079c5761079c612439565b600091825260208083206001600160a01b03909716835260046005909202909601019094526040909320805493151560ff1990941693909317909255505050565b600654600160201b900460ff16156108505760405162461bcd60e51b815260206004820152603060248201527f54686520736d61727420636f6e747261637420686173206265656e20616c726560448201526f30b23c9034b734ba34b0b634bd32b21760811b6064820152608401610443565b6006805464ff000000001916600160201b17905561086d82610d08565b600280546001600160a01b0319166001600160a01b0386169081179091556040805163b233b38960e01b8152905163b233b38991600480820192602092909190829003018186803b1580156108c157600080fd5b505afa1580156108d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f99190611fce565b60045580516000906109149083016020908101908401611d6c565b905060005b81518160ff161015610ce4576005805460010181556000528151829060ff831690811061094857610948612439565b60200260200101516060015160058260ff168154811061096a5761096a612439565b906000526020600020906005020160000160026101000a81548163ffffffff021916908363ffffffff160217905550818160ff16815181106109ae576109ae612439565b60200260200101516080015160058260ff16815481106109d0576109d0612439565b906000526020600020906005020160010181905550818160ff16815181106109fa576109fa612439565b60200260200101516000015160058260ff1681548110610a1c57610a1c612439565b60009182526020909120600590910201805460ff19169115159190911790558151829060ff8316908110610a5257610a52612439565b60200260200101516020015160058260ff1681548110610a7457610a74612439565b906000526020600020906005020160000160016101000a81548160ff021916908315150217905550818160ff1681518110610ab157610ab1612439565b60200260200101516040015160058260ff1681548110610ad357610ad3612439565b906000526020600020906005020160000160066101000a8154816001600160a01b0302191690836001600160a01b03160217905550818160ff1681518110610b1d57610b1d612439565b602002602001015160c001515160058260ff1681548110610b4057610b40612439565b90600052602060002090600502016002018190555060005b828260ff1681518110610b6d57610b6d612439565b602002602001015160c0015151811015610c0357828260ff1681518110610b9657610b96612439565b602002602001015160c001518181518110610bb357610bb3612439565b602002602001015160058360ff1681548110610bd157610bd1612439565b600091825260208083208584526003600590930201919091019052604090205580610bfb816123be565b915050610b58565b5060005b828260ff1681518110610c1c57610c1c612439565b602002602001015160a0015151811015610cd157600160058360ff1681548110610c4857610c48612439565b90600052602060002090600502016004016000858560ff1681518110610c7057610c70612439565b602002602001015160a001518481518110610c8d57610c8d612439565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580610cc9816123be565b915050610c07565b5080610cdc816123d9565b915050610919565b50506006805460055460ff1663ff0000ff199091161763ff00000017905550505050565b60005460ff1615610d6a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c65436c6f6e6561626c653a20616c726561647920696e697469616044820152653634bd32b21760d11b6064820152608401610443565b6000805460ff19166001179055610d80816119d7565b50565b600654600160201b900460ff168015610da657506003546001600160a01b031615155b610dc25760405162461bcd60e51b815260040161044390612261565b33610dcb611146565b6001600160a01b031614610df15760405162461bcd60e51b8152600401610443906121d2565b6006546301000000900460ff9081161415610e18576006805463ff00000019169055610e9c565b60055460068054600390610e35906301000000900460ff166123d9565b91906101000a81548160ff021916908360ff160217905560ff1610610e9c5760405162461bcd60e51b815260206004820152601960248201527f4e6f206d6f726520617661696c61626c65207374616765732e000000000000006044820152606401610443565b600360009054906101000a90046001600160a01b03166001600160a01b031663affed0e06040518163ffffffff1660e01b815260040160206040518083038186803b158015610eea57600080fd5b505afa158015610efe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f229190611fce565b600155565b33610f30611146565b6001600160a01b031614610f565760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff168015610f7957506003546001600160a01b031615155b610f955760405162461bcd60e51b815260040161044390612261565b600554829060ff821610610fbb5760405162461bcd60e51b8152600401610443906122be565b8160058460ff1681548110610fd257610fd2612439565b906000526020600020906005020160000160066101000a8154816001600160a01b0302191690836001600160a01b03160217905550505050565b60005460ff1661102e5760405162461bcd60e51b815260040161044390612184565b33611037611146565b6001600160a01b03161461105d5760405162461bcd60e51b8152600401610443906121d2565b61106760006119d7565b565b6005818154811061107957600080fd5b600091825260209091206005909102018054600182015460029092015460ff80831694506101008304169262010000830463ffffffff1692600160301b90046001600160a01b03169186565b336110ce611146565b6001600160a01b0316146110f45760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561111757506003546001600160a01b031615155b6111335760405162461bcd60e51b815260040161044390612261565b6006805462ff0000191662010000179055565b6000805460ff166111695760405162461bcd60e51b815260040161044390612184565b5060005461010090046001600160a01b031690565b600654600090600160201b900460ff1680156111a457506003546001600160a01b031615155b6111c05760405162461bcd60e51b815260040161044390612261565b60065462010000900460ff16806111df5750600654610100900460ff16155b8061127e5750600654600580546000926301000000900460ff1690811061120857611208612439565b600091825260209091206005909102015462010000900463ffffffff161480159061127e57506006546005805490916301000000900460ff1690811061125057611250612439565b600091825260209091206005909102015460015461127a9162010000900463ffffffff1690612373565b8310155b8061128a575060015483105b806112d457506006546005805490916301000000900460ff169081106112b2576112b2612439565b600091825260209091206005909102015460ff1680156112d457506004548210155b156112e1575060006106eb565b60065460058054600192839291630100000090910460ff1690811061130857611308612439565b6000918252602090912060059091020154610100900460ff16156114185760065461133d906301000000900460ff1685611a52565b8061141557506006546005805490916301000000900460ff1690811061136557611365612439565b6000918252602082206002546040516331a9108f60e11b815260048082018a905260059490940290920190920192916001600160a01b031690636352211e9060240160206040518083038186803b1580156113bf57600080fd5b505afa1580156113d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f79190611d4f565b6001600160a01b0316815260208101919091526040016000205460ff165b90505b600654600580546000926301000000900460ff1690811061143b5761143b612439565b6000918252602090912060059091020154600160301b90046001600160a01b03161461151d576006546005805490916301000000900460ff1690811061148357611483612439565b6000918252602090912060059091020154604051632589bc2760e21b81526004810187905260248101869052600160301b9091046001600160a01b031690639626f09c9060440160206040518083038186803b1580156114e257600080fd5b505afa1580156114f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151a9190611ee6565b91505b8080156115275750815b95945050505050565b33611539611146565b6001600160a01b03161461155f5760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561158257506003546001600160a01b031615155b61159e5760405162461bcd60e51b815260040161044390612261565b600680549115156101000261ff0019909216919091179055565b336115c1611146565b6001600160a01b0316146115e75760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561160a57506003546001600160a01b031615155b6116265760405162461bcd60e51b815260040161044390612261565b600554839060ff82161061164c5760405162461bcd60e51b8152600401610443906122be565b60008061165885611b1b565b9150915083156116df576116a460058760ff168154811061167b5761167b612439565b906000526020600020906005020160030160008481526020019081526020016000205482611b47565b60058760ff16815481106116ba576116ba612439565b6000918252602080832086845260036005909302019190910190526040902055611758565b61172160058760ff16815481106116f8576116f8612439565b906000526020600020906005020160030160008481526020019081526020016000205482611b73565b60058760ff168154811061173757611737612439565b60009182526020808320868452600360059093020191909101905260409020555b505050505050565b600654600160201b900460ff16801561178357506003546001600160a01b031615155b61179f5760405162461bcd60e51b815260040161044390612261565b600554819060ff8216106117c55760405162461bcd60e51b8152600401610443906122be565b336117ce611146565b6001600160a01b0316146117f45760405162461bcd60e51b8152600401610443906121d2565b60065460ff630100000090910416600019146118775760065460ff63010000009091048116908316116118775760405162461bcd60e51b815260206004820152602560248201527f43616e6e6f74207365742070726576696f7573207374616765732061732061636044820152643a34bb329760d91b6064820152608401610443565b6006805463ff0000001916630100000060ff8516021790556003546040805163057ff68760e51b815290516001600160a01b039092169163affed0e091600480820192602092909190829003018186803b1580156118d457600080fd5b505afa1580156118e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190c9190611fce565b6001555050565b60005460ff166119355760405162461bcd60e51b815260040161044390612184565b3361193e611146565b6001600160a01b0316146119645760405162461bcd60e51b8152600401610443906121d2565b6001600160a01b0381166119d25760405162461bcd60e51b815260206004820152602f60248201527f4f776e61626c65436c6f6e6561626c653a206e6577206f776e6572206973207460448201526e6865207a65726f206164647265737360881b6064820152608401610443565b610d80815b60005460ff166119f95760405162461bcd60e51b815260040161044390612184565b600080546001600160a01b03838116610100818102610100600160a81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b600554600090839060ff821610611a7b5760405162461bcd60e51b8152600401610443906122be565b61010060058560ff1681548110611a9457611a94612439565b906000526020600020906005020160020154611ab0919061239f565b8310611abf5760009150611b14565b600080611acb85611b1b565b91509150600060058760ff1681548110611ae757611ae7612439565b60009182526020808320958352600360059092029095010190935250604090912054600190911b16151591505b5092915050565b60008080611b2b6101008561238b565b90506000611b3b610100866123f9565b91959194509092505050565b60006101008210611b6a5760405162461bcd60e51b81526004016104439061221b565b506001901b1790565b60006101008210611b965760405162461bcd60e51b81526004016104439061221b565b506001901b191690565b8051611bab81612465565b919050565b600082601f830112611bc157600080fd5b81516020611bd6611bd18361234f565b61231e565b80838252828201915082860187848660051b8901011115611bf657600080fd5b60005b85811015611c1e578151611c0c81612465565b84529284019290840190600101611bf9565b5090979650505050505050565b600082601f830112611c3c57600080fd5b81516020611c4c611bd18361234f565b80838252828201915082860187848660051b8901011115611c6c57600080fd5b60005b85811015611c1e57815184529284019290840190600101611c6f565b8051611bab8161247a565b600082601f830112611ca757600080fd5b813567ffffffffffffffff811115611cc157611cc161244f565b611cd4601f8201601f191660200161231e565b818152846020838601011115611ce957600080fd5b816020850160208301376000918101602001919091529392505050565b805163ffffffff81168114611bab57600080fd5b803560ff81168114611bab57600080fd5b600060208284031215611d3d57600080fd5b8135611d4881612465565b9392505050565b600060208284031215611d6157600080fd5b8151611d4881612465565b60006020808385031215611d7f57600080fd5b825167ffffffffffffffff80821115611d9757600080fd5b818501915085601f830112611dab57600080fd5b8151611db9611bd18261234f565b80828252858201915085850189878560051b8801011115611dd957600080fd5b60005b84811015611eba57815186811115611df357600080fd5b870160e0818d03601f19011215611e0957600080fd5b611e116122f5565b611e1c8a8301611c8b565b8152611e2a60408301611c8b565b8a820152611e3a60608301611ba0565b6040820152611e4b60808301611d06565b606082015260a080830151608083015260c083015189811115611e6d57600080fd5b611e7b8f8d83870101611bb0565b82840152505060e082015188811115611e9357600080fd5b611ea18e8c83860101611c2b565b60c0830152508552509287019290870190600101611ddc565b50909998505050505050505050565b600060208284031215611edb57600080fd5b8135611d488161247a565b600060208284031215611ef857600080fd5b8151611d488161247a565b600060208284031215611f1557600080fd5b813567ffffffffffffffff811115611f2c57600080fd5b611f3884828501611c96565b949350505050565b60008060008060808587031215611f5657600080fd5b8435611f6181612465565b93506020850135611f7181612465565b92506040850135611f8181612465565b9150606085013567ffffffffffffffff811115611f9d57600080fd5b611fa987828801611c96565b91505092959194509250565b600060208284031215611fc757600080fd5b5035919050565b600060208284031215611fe057600080fd5b5051919050565b60008060408385031215611ffa57600080fd5b50508035926020909101359150565b60006020828403121561201b57600080fd5b611d4882611d1a565b6000806040838503121561203757600080fd5b61204083611d1a565b9150602083013561205081612465565b809150509250929050565b60008060006060848603121561207057600080fd5b61207984611d1a565b9250602084013561208981612465565b915060408401356120998161247a565b809150509250925092565b600080604083850312156120b757600080fd5b6120c083611d1a565b915060208084013567ffffffffffffffff8111156120dd57600080fd5b8401601f810186136120ee57600080fd5b80356120fc611bd18261234f565b80828252848201915084840189868560051b870101111561211c57600080fd5b600094505b8385101561213f578035835260019490940193918501918501612121565b5080955050505050509250929050565b60008060006060848603121561216457600080fd5b61216d84611d1a565b92506020840135915060408401356120998161247a565b6020808252602e908201527f4f776e61626c65436c6f6e6561626c653a206861736e2774206265656e20696e60408201526d34ba34b0b634bd32b2103cb2ba1760911b606082015260800190565b60208082526029908201527f4f776e61626c65436c6f6e6561626c653a2063616c6c6572206973206e6f74206040820152683a34329037bbb732b960b91b606082015260800190565b60208082526026908201527f4578636565647320746865206e756d626572206f66206269747320696e207569604082015265373a191a9b1760d11b606082015260800190565b60208082526038908201527f54686520736d61727420636f6e7472616374206e6565647320746f206265206960408201527f6e697469616c697a6564206265666f7265207573696e672e0000000000000000606082015260800190565b60208082526019908201527f5374616765204944206973206f7574206f6620626f756e642e00000000000000604082015260600190565b60405160e0810167ffffffffffffffff811182821017156123185761231861244f565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156123475761234761244f565b604052919050565b600067ffffffffffffffff8211156123695761236961244f565b5060051b60200190565b600082198211156123865761238661240d565b500190565b60008261239a5761239a612423565b500490565b60008160001904831182151516156123b9576123b961240d565b500290565b60006000198214156123d2576123d261240d565b5060010190565b600060ff821660ff8114156123f0576123f061240d565b60010192915050565b60008261240857612408612423565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610d8057600080fd5b8015158114610d8057600080fdfea2646970667358221220687a719816703f7b6a9e92feebdb75a5e3961d4bc18f98ee0f3849a6b832690464736f6c63430008060033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806371fd2c38116100f9578063a4908f2311610097578063e04f9e8211610071578063e04f9e82146103d2578063e6798baa146103e5578063efbd676b146103ee578063f2fde38b1461040157600080fd5b8063a4908f2314610399578063ae2bd56b146103ac578063b2b93b73146103bf57600080fd5b8063845ddcb2116100d3578063845ddcb21461032057806387491c60146103765780638da5cb5b1461037e5780639626f09c1461038657600080fd5b806371fd2c38146102df578063788fe59d146102e857806382eb71c11461031357600080fd5b8063246581f7116101665780635cd9205f116101405780635cd9205f146102a95780635ee6509a146102bc57806362fbcf9a146102c4578063715018a6146102d757600080fd5b8063246581f714610279578063485722221461028c5780635bf5d54c1461029557600080fd5b806315f7485b116101a257806315f7485b146102205780631bed2a26146102325780631cc1fddb146102455780631d19e1811461026657600080fd5b806304eff22f146101c957806307b5dfde146101f15780630b102d1a1461020b575b600080fd5b6101dc6101d7366004611f03565b511590565b60405190151581526020015b60405180910390f35b6101f9600081565b60405160ff90911681526020016101e8565b61021e610219366004611d2b565b610414565b005b6006546101dc90610100900460ff1681565b61021e6102403660046120a4565b61053d565b610258610253366004611fe7565b610672565b6040519081526020016101e8565b61021e61027436600461205b565b6106f1565b61021e610287366004611f40565b6107dd565b61025860045481565b6006546101f9906301000000900460ff1681565b61021e6102b7366004611d2b565b610d08565b61021e610d83565b61021e6102d2366004612024565b610f27565b61021e61100c565b61025861010081565b6003546102fb906001600160a01b031681565b6040516001600160a01b0390911681526020016101e8565b6006546101f99060ff1681565b61033361032e366004611fb5565b611069565b604080519615158752941515602087015263ffffffff909316938501939093526001600160a01b03166060840152608083019190915260a082015260c0016101e8565b61021e6110c5565b6102fb611146565b6101dc610394366004611fe7565b61117e565b61021e6103a7366004611ec9565b611530565b61021e6103ba36600461214f565b6115b8565b6006546101dc9062010000900460ff1681565b61021e6103e0366004612009565b611760565b61025860015481565b6002546102fb906001600160a01b031681565b61021e61040f366004611d2b565b611913565b3361041d611146565b6001600160a01b03161461044c5760405162461bcd60e51b8152600401610443906121d2565b60405180910390fd5b6003546001600160a01b0316156104b35760405162461bcd60e51b815260206004820152602560248201527f546865204e465420616464726573732068617320616c7265616479206265656e6044820152641039b2ba1760d91b6064820152608401610443565b6001600160a01b03811661051b5760405162461bcd60e51b815260206004820152602960248201527f546865204e465420616464726573732063616e6e6f742062652061207a65726f6044820152681030b2323932b9b99760b91b6064820152608401610443565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b33610546611146565b6001600160a01b03161461056c5760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561058f57506003546001600160a01b031615155b6105ab5760405162461bcd60e51b815260040161044390612261565b600554829060ff8216106105d15760405162461bcd60e51b8152600401610443906122be565b60005b825181101561063f578281815181106105ef576105ef612439565b602002602001015160058560ff168154811061060d5761060d612439565b600091825260208083208584526003600590930201919091019052604090205580610637816123be565b9150506105d4565b50815160058460ff168154811061065857610658612439565b906000526020600020906005020160020181905550505050565b600654600090600160201b900460ff16801561069857506003546001600160a01b031615155b6106b45760405162461bcd60e51b815260040161044390612261565b6006546005805490916301000000900460ff169081106106d6576106d6612439565b90600052602060002090600502016001015490505b92915050565b336106fa611146565b6001600160a01b0316146107205760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561074357506003546001600160a01b031615155b61075f5760405162461bcd60e51b815260040161044390612261565b600554839060ff8216106107855760405162461bcd60e51b8152600401610443906122be565b8160058560ff168154811061079c5761079c612439565b600091825260208083206001600160a01b03909716835260046005909202909601019094526040909320805493151560ff1990941693909317909255505050565b600654600160201b900460ff16156108505760405162461bcd60e51b815260206004820152603060248201527f54686520736d61727420636f6e747261637420686173206265656e20616c726560448201526f30b23c9034b734ba34b0b634bd32b21760811b6064820152608401610443565b6006805464ff000000001916600160201b17905561086d82610d08565b600280546001600160a01b0319166001600160a01b0386169081179091556040805163b233b38960e01b8152905163b233b38991600480820192602092909190829003018186803b1580156108c157600080fd5b505afa1580156108d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108f99190611fce565b60045580516000906109149083016020908101908401611d6c565b905060005b81518160ff161015610ce4576005805460010181556000528151829060ff831690811061094857610948612439565b60200260200101516060015160058260ff168154811061096a5761096a612439565b906000526020600020906005020160000160026101000a81548163ffffffff021916908363ffffffff160217905550818160ff16815181106109ae576109ae612439565b60200260200101516080015160058260ff16815481106109d0576109d0612439565b906000526020600020906005020160010181905550818160ff16815181106109fa576109fa612439565b60200260200101516000015160058260ff1681548110610a1c57610a1c612439565b60009182526020909120600590910201805460ff19169115159190911790558151829060ff8316908110610a5257610a52612439565b60200260200101516020015160058260ff1681548110610a7457610a74612439565b906000526020600020906005020160000160016101000a81548160ff021916908315150217905550818160ff1681518110610ab157610ab1612439565b60200260200101516040015160058260ff1681548110610ad357610ad3612439565b906000526020600020906005020160000160066101000a8154816001600160a01b0302191690836001600160a01b03160217905550818160ff1681518110610b1d57610b1d612439565b602002602001015160c001515160058260ff1681548110610b4057610b40612439565b90600052602060002090600502016002018190555060005b828260ff1681518110610b6d57610b6d612439565b602002602001015160c0015151811015610c0357828260ff1681518110610b9657610b96612439565b602002602001015160c001518181518110610bb357610bb3612439565b602002602001015160058360ff1681548110610bd157610bd1612439565b600091825260208083208584526003600590930201919091019052604090205580610bfb816123be565b915050610b58565b5060005b828260ff1681518110610c1c57610c1c612439565b602002602001015160a0015151811015610cd157600160058360ff1681548110610c4857610c48612439565b90600052602060002090600502016004016000858560ff1681518110610c7057610c70612439565b602002602001015160a001518481518110610c8d57610c8d612439565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580610cc9816123be565b915050610c07565b5080610cdc816123d9565b915050610919565b50506006805460055460ff1663ff0000ff199091161763ff00000017905550505050565b60005460ff1615610d6a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c65436c6f6e6561626c653a20616c726561647920696e697469616044820152653634bd32b21760d11b6064820152608401610443565b6000805460ff19166001179055610d80816119d7565b50565b600654600160201b900460ff168015610da657506003546001600160a01b031615155b610dc25760405162461bcd60e51b815260040161044390612261565b33610dcb611146565b6001600160a01b031614610df15760405162461bcd60e51b8152600401610443906121d2565b6006546301000000900460ff9081161415610e18576006805463ff00000019169055610e9c565b60055460068054600390610e35906301000000900460ff166123d9565b91906101000a81548160ff021916908360ff160217905560ff1610610e9c5760405162461bcd60e51b815260206004820152601960248201527f4e6f206d6f726520617661696c61626c65207374616765732e000000000000006044820152606401610443565b600360009054906101000a90046001600160a01b03166001600160a01b031663affed0e06040518163ffffffff1660e01b815260040160206040518083038186803b158015610eea57600080fd5b505afa158015610efe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f229190611fce565b600155565b33610f30611146565b6001600160a01b031614610f565760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff168015610f7957506003546001600160a01b031615155b610f955760405162461bcd60e51b815260040161044390612261565b600554829060ff821610610fbb5760405162461bcd60e51b8152600401610443906122be565b8160058460ff1681548110610fd257610fd2612439565b906000526020600020906005020160000160066101000a8154816001600160a01b0302191690836001600160a01b03160217905550505050565b60005460ff1661102e5760405162461bcd60e51b815260040161044390612184565b33611037611146565b6001600160a01b03161461105d5760405162461bcd60e51b8152600401610443906121d2565b61106760006119d7565b565b6005818154811061107957600080fd5b600091825260209091206005909102018054600182015460029092015460ff80831694506101008304169262010000830463ffffffff1692600160301b90046001600160a01b03169186565b336110ce611146565b6001600160a01b0316146110f45760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561111757506003546001600160a01b031615155b6111335760405162461bcd60e51b815260040161044390612261565b6006805462ff0000191662010000179055565b6000805460ff166111695760405162461bcd60e51b815260040161044390612184565b5060005461010090046001600160a01b031690565b600654600090600160201b900460ff1680156111a457506003546001600160a01b031615155b6111c05760405162461bcd60e51b815260040161044390612261565b60065462010000900460ff16806111df5750600654610100900460ff16155b8061127e5750600654600580546000926301000000900460ff1690811061120857611208612439565b600091825260209091206005909102015462010000900463ffffffff161480159061127e57506006546005805490916301000000900460ff1690811061125057611250612439565b600091825260209091206005909102015460015461127a9162010000900463ffffffff1690612373565b8310155b8061128a575060015483105b806112d457506006546005805490916301000000900460ff169081106112b2576112b2612439565b600091825260209091206005909102015460ff1680156112d457506004548210155b156112e1575060006106eb565b60065460058054600192839291630100000090910460ff1690811061130857611308612439565b6000918252602090912060059091020154610100900460ff16156114185760065461133d906301000000900460ff1685611a52565b8061141557506006546005805490916301000000900460ff1690811061136557611365612439565b6000918252602082206002546040516331a9108f60e11b815260048082018a905260059490940290920190920192916001600160a01b031690636352211e9060240160206040518083038186803b1580156113bf57600080fd5b505afa1580156113d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f79190611d4f565b6001600160a01b0316815260208101919091526040016000205460ff165b90505b600654600580546000926301000000900460ff1690811061143b5761143b612439565b6000918252602090912060059091020154600160301b90046001600160a01b03161461151d576006546005805490916301000000900460ff1690811061148357611483612439565b6000918252602090912060059091020154604051632589bc2760e21b81526004810187905260248101869052600160301b9091046001600160a01b031690639626f09c9060440160206040518083038186803b1580156114e257600080fd5b505afa1580156114f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151a9190611ee6565b91505b8080156115275750815b95945050505050565b33611539611146565b6001600160a01b03161461155f5760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561158257506003546001600160a01b031615155b61159e5760405162461bcd60e51b815260040161044390612261565b600680549115156101000261ff0019909216919091179055565b336115c1611146565b6001600160a01b0316146115e75760405162461bcd60e51b8152600401610443906121d2565b600654600160201b900460ff16801561160a57506003546001600160a01b031615155b6116265760405162461bcd60e51b815260040161044390612261565b600554839060ff82161061164c5760405162461bcd60e51b8152600401610443906122be565b60008061165885611b1b565b9150915083156116df576116a460058760ff168154811061167b5761167b612439565b906000526020600020906005020160030160008481526020019081526020016000205482611b47565b60058760ff16815481106116ba576116ba612439565b6000918252602080832086845260036005909302019190910190526040902055611758565b61172160058760ff16815481106116f8576116f8612439565b906000526020600020906005020160030160008481526020019081526020016000205482611b73565b60058760ff168154811061173757611737612439565b60009182526020808320868452600360059093020191909101905260409020555b505050505050565b600654600160201b900460ff16801561178357506003546001600160a01b031615155b61179f5760405162461bcd60e51b815260040161044390612261565b600554819060ff8216106117c55760405162461bcd60e51b8152600401610443906122be565b336117ce611146565b6001600160a01b0316146117f45760405162461bcd60e51b8152600401610443906121d2565b60065460ff630100000090910416600019146118775760065460ff63010000009091048116908316116118775760405162461bcd60e51b815260206004820152602560248201527f43616e6e6f74207365742070726576696f7573207374616765732061732061636044820152643a34bb329760d91b6064820152608401610443565b6006805463ff0000001916630100000060ff8516021790556003546040805163057ff68760e51b815290516001600160a01b039092169163affed0e091600480820192602092909190829003018186803b1580156118d457600080fd5b505afa1580156118e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190c9190611fce565b6001555050565b60005460ff166119355760405162461bcd60e51b815260040161044390612184565b3361193e611146565b6001600160a01b0316146119645760405162461bcd60e51b8152600401610443906121d2565b6001600160a01b0381166119d25760405162461bcd60e51b815260206004820152602f60248201527f4f776e61626c65436c6f6e6561626c653a206e6577206f776e6572206973207460448201526e6865207a65726f206164647265737360881b6064820152608401610443565b610d80815b60005460ff166119f95760405162461bcd60e51b815260040161044390612184565b600080546001600160a01b03838116610100818102610100600160a81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b600554600090839060ff821610611a7b5760405162461bcd60e51b8152600401610443906122be565b61010060058560ff1681548110611a9457611a94612439565b906000526020600020906005020160020154611ab0919061239f565b8310611abf5760009150611b14565b600080611acb85611b1b565b91509150600060058760ff1681548110611ae757611ae7612439565b60009182526020808320958352600360059092029095010190935250604090912054600190911b16151591505b5092915050565b60008080611b2b6101008561238b565b90506000611b3b610100866123f9565b91959194509092505050565b60006101008210611b6a5760405162461bcd60e51b81526004016104439061221b565b506001901b1790565b60006101008210611b965760405162461bcd60e51b81526004016104439061221b565b506001901b191690565b8051611bab81612465565b919050565b600082601f830112611bc157600080fd5b81516020611bd6611bd18361234f565b61231e565b80838252828201915082860187848660051b8901011115611bf657600080fd5b60005b85811015611c1e578151611c0c81612465565b84529284019290840190600101611bf9565b5090979650505050505050565b600082601f830112611c3c57600080fd5b81516020611c4c611bd18361234f565b80838252828201915082860187848660051b8901011115611c6c57600080fd5b60005b85811015611c1e57815184529284019290840190600101611c6f565b8051611bab8161247a565b600082601f830112611ca757600080fd5b813567ffffffffffffffff811115611cc157611cc161244f565b611cd4601f8201601f191660200161231e565b818152846020838601011115611ce957600080fd5b816020850160208301376000918101602001919091529392505050565b805163ffffffff81168114611bab57600080fd5b803560ff81168114611bab57600080fd5b600060208284031215611d3d57600080fd5b8135611d4881612465565b9392505050565b600060208284031215611d6157600080fd5b8151611d4881612465565b60006020808385031215611d7f57600080fd5b825167ffffffffffffffff80821115611d9757600080fd5b818501915085601f830112611dab57600080fd5b8151611db9611bd18261234f565b80828252858201915085850189878560051b8801011115611dd957600080fd5b60005b84811015611eba57815186811115611df357600080fd5b870160e0818d03601f19011215611e0957600080fd5b611e116122f5565b611e1c8a8301611c8b565b8152611e2a60408301611c8b565b8a820152611e3a60608301611ba0565b6040820152611e4b60808301611d06565b606082015260a080830151608083015260c083015189811115611e6d57600080fd5b611e7b8f8d83870101611bb0565b82840152505060e082015188811115611e9357600080fd5b611ea18e8c83860101611c2b565b60c0830152508552509287019290870190600101611ddc565b50909998505050505050505050565b600060208284031215611edb57600080fd5b8135611d488161247a565b600060208284031215611ef857600080fd5b8151611d488161247a565b600060208284031215611f1557600080fd5b813567ffffffffffffffff811115611f2c57600080fd5b611f3884828501611c96565b949350505050565b60008060008060808587031215611f5657600080fd5b8435611f6181612465565b93506020850135611f7181612465565b92506040850135611f8181612465565b9150606085013567ffffffffffffffff811115611f9d57600080fd5b611fa987828801611c96565b91505092959194509250565b600060208284031215611fc757600080fd5b5035919050565b600060208284031215611fe057600080fd5b5051919050565b60008060408385031215611ffa57600080fd5b50508035926020909101359150565b60006020828403121561201b57600080fd5b611d4882611d1a565b6000806040838503121561203757600080fd5b61204083611d1a565b9150602083013561205081612465565b809150509250929050565b60008060006060848603121561207057600080fd5b61207984611d1a565b9250602084013561208981612465565b915060408401356120998161247a565b809150509250925092565b600080604083850312156120b757600080fd5b6120c083611d1a565b915060208084013567ffffffffffffffff8111156120dd57600080fd5b8401601f810186136120ee57600080fd5b80356120fc611bd18261234f565b80828252848201915084840189868560051b870101111561211c57600080fd5b600094505b8385101561213f578035835260019490940193918501918501612121565b5080955050505050509250929050565b60008060006060848603121561216457600080fd5b61216d84611d1a565b92506020840135915060408401356120998161247a565b6020808252602e908201527f4f776e61626c65436c6f6e6561626c653a206861736e2774206265656e20696e60408201526d34ba34b0b634bd32b2103cb2ba1760911b606082015260800190565b60208082526029908201527f4f776e61626c65436c6f6e6561626c653a2063616c6c6572206973206e6f74206040820152683a34329037bbb732b960b91b606082015260800190565b60208082526026908201527f4578636565647320746865206e756d626572206f66206269747320696e207569604082015265373a191a9b1760d11b606082015260800190565b60208082526038908201527f54686520736d61727420636f6e7472616374206e6565647320746f206265206960408201527f6e697469616c697a6564206265666f7265207573696e672e0000000000000000606082015260800190565b60208082526019908201527f5374616765204944206973206f7574206f6620626f756e642e00000000000000604082015260600190565b60405160e0810167ffffffffffffffff811182821017156123185761231861244f565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156123475761234761244f565b604052919050565b600067ffffffffffffffff8211156123695761236961244f565b5060051b60200190565b600082198211156123865761238661240d565b500190565b60008261239a5761239a612423565b500490565b60008160001904831182151516156123b9576123b961240d565b500290565b60006000198214156123d2576123d261240d565b5060010190565b600060ff821660ff8114156123f0576123f061240d565b60010192915050565b60008261240857612408612423565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610d8057600080fd5b8015158114610d8057600080fdfea2646970667358221220687a719816703f7b6a9e92feebdb75a5e3961d4bc18f98ee0f3849a6b832690464736f6c63430008060033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.