ETH Price: $3,422.46 (-0.52%)
Gas: 3 Gwei

Token

Pasteurized Cheeze Wizard ()
 

Overview

Max Total Supply

0 Pasteurized Cheeze Wizard

Holders

1,376

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
Carlini8
Balance
37 Pasteurized Cheeze Wizard
0x0d41f957181e584db82d2e316837b2de1738c477
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Each Cheeze Wizard is special. They’re immortal, magical, and capable of world-changing feats. Sadly, they spend most of their time getting into petty disagreements online.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
WizardGuild

Compiler Version
v0.5.8+commit.23d335f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2019-10-17
*/

pragma solidity >=0.5.6 <0.6.0;

/// @title Shared constants used throughout the Cheeze Wizards contracts
contract WizardConstants {
    // Wizards normally have their affinity set when they are first created,
    // but for example Exclusive Wizards can be created with no set affinity.
    // In this case the affinity can be set by the owner.
    uint8 internal constant ELEMENT_NOTSET = 0; //000
    // A neutral Wizard has no particular strength or weakness with specific
    // elements.
    uint8 internal constant ELEMENT_NEUTRAL = 1; //001
    // The fire, water and wind elements are used both to reflect an affinity
    // of Elemental Wizards for a specific element, and as the moves a
    // Wizard can make during a duel.
    // Note that if these values change then `moveMask` and `moveDelta` in
    // ThreeAffinityDuelResolver would need to be updated accordingly.
    uint8 internal constant ELEMENT_FIRE = 2; //010
    uint8 internal constant ELEMENT_WATER = 3; //011
    uint8 internal constant ELEMENT_WIND = 4; //100
    uint8 internal constant MAX_ELEMENT = ELEMENT_WIND;
}



/// @title ERC165Query example
/// @notice see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
contract ERC165Query {
    bytes4 constant _INTERFACE_ID_INVALID = 0xffffffff;
    bytes4 constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    function doesContractImplementInterface(
        address _contract,
        bytes4 _interfaceId
    )
        internal
        view
        returns (bool)
    {
        uint256 success;
        uint256 result;

        (success, result) = noThrowCall(_contract, _INTERFACE_ID_ERC165);
        if ((success == 0) || (result == 0)) {
            return false;
        }

        (success, result) = noThrowCall(_contract, _INTERFACE_ID_INVALID);
        if ((success == 0) || (result != 0)) {
            return false;
        }

        (success, result) = noThrowCall(_contract, _interfaceId);
        if ((success == 1) && (result == 1)) {
            return true;
        }
        return false;
    }

    function noThrowCall(
        address _contract,
        bytes4 _interfaceId
    )
        internal
        view
        returns (
            uint256 success,
            uint256 result
        )
    {
        bytes memory encodedParams = abi.encodeWithSelector(_INTERFACE_ID_ERC165, _interfaceId);

        // solhint-disable-next-line no-inline-assembly
        assembly { // solium-disable-line security/no-inline-assembly
            let encodedParams_data := add(0x20, encodedParams)
            let encodedParams_size := mload(encodedParams)

            let output := mload(0x40)    // Find empty storage location using "free memory pointer"
            mstore(output, 0x0)

            success := staticcall(
                30000,                   // 30k gas
                _contract,               // To addr
                encodedParams_data,
                encodedParams_size,
                output,
                0x20                     // Outputs are 32 bytes long
            )

            result := mload(output)      // Load the result
        }
    }
}








/**
 * @title IERC165
 * @dev https://eips.ethereum.org/EIPS/eip-165
 */
interface IERC165 {
    /**
     * @notice Query if a contract implements an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @dev Interface identification is specified in ERC-165. This function
     * uses less than 30,000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}


/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    function balanceOf(address owner) public view returns (uint256 balance);
    function ownerOf(uint256 tokenId) public view returns (address owner);

    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);

    function transferFrom(address from, address to, uint256 tokenId) public;
    function safeTransferFrom(address from, address to, uint256 tokenId) public;

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}



/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a `safeTransfer`. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
    public returns (bytes4);
}




/// @title ERC165Interface
/// @dev https://eips.ethereum.org/EIPS/eip-165
interface ERC165Interface {
    /// @notice Query if a contract implements an interface
    /// @param interfaceId The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    ///      uses less than 30,000 gas.
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}



/// Utility library of inline functions on address payables.
/// Modified from original by OpenZeppelin.
contract Address {
    /// @notice Returns whether the target address is a contract.
    /// @dev This function will return false if invoked during the constructor of a contract,
    /// as the code is not actually created until after the constructor finishes.
    /// @param account address of the account to check
    /// @return whether the target address is a contract
    function isContract(address account) internal view returns (bool) {
        uint256 size;
        // XXX Currently there is no better way to check if there is a contract in an address
        // than to check the size of the code at that address.
        // See https://ethereum.stackexchange.com/a/14016/36603
        // for more details about how this works.
        // TODO Check this again before the Serenity release, because all addresses will be
        // contracts then.
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) } // solium-disable-line security/no-inline-assembly
        return size > 0;
    }
}




/// @title Wizard Non-Fungible Token
/// @notice The basic ERC-721 functionality for storing Cheeze Wizard NFTs.
///     Derived from: https://github.com/OpenZeppelin/openzeppelin-solidity/tree/v2.2.0
contract WizardNFT is ERC165Interface, IERC721, WizardConstants, Address {

    /// @notice Emitted when a wizard token is created.
    event WizardConjured(uint256 wizardId, uint8 affinity, uint256 innatePower);

    /// @notice Emitted when a Wizard's affinity is set. This only applies for
    ///         Exclusive Wizards who can have the ELEMENT_NOT_SET affinity,
    ///         and should only happen once for each Wizard.
    event WizardAffinityAssigned(uint256 wizardId, uint8 affinity);

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 internal constant _ERC721_RECEIVED = 0x150b7a02;

    /// @dev The base Wizard structure.
    /// Designed to fit in two words.
    struct Wizard {
        // NOTE: Changing the order or meaning of any of these fields requires an update
        //   to the _createWizard() function which assumes a specific order for these fields.
        uint8 affinity;
        uint88 innatePower;
        address owner;
        bytes32 metadata;
    }

    // Mapping from Wizard ID to Wizard struct
    mapping (uint256 => Wizard) public wizardsById;

    // Mapping from Wizard ID to address approved to control them
    mapping (uint256 => address) private wizardApprovals;

    // Mapping from owner address to number of owned Wizards
    mapping (address => uint256) internal ownedWizardsCount;

    // Mapping from owner to Wizard controllers
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /// @dev 0x80ac58cd ===
    ///    bytes4(keccak256('balanceOf(address)')) ^
    ///    bytes4(keccak256('ownerOf(uint256)')) ^
    ///    bytes4(keccak256('approve(address,uint256)')) ^
    ///    bytes4(keccak256('getApproved(uint256)')) ^
    ///    bytes4(keccak256('setApprovalForAll(address,bool)')) ^
    ///    bytes4(keccak256('isApprovedForAll(address,address)')) ^
    ///    bytes4(keccak256('transferFrom(address,address,uint256)')) ^
    ///    bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
    ///    bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    /// @notice Query if a contract implements an interface
    /// @param interfaceId The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    ///      uses less than 30,000 gas.
    function supportsInterface(bytes4 interfaceId) public view returns (bool) {
        return
            interfaceId == this.supportsInterface.selector || // ERC165
            interfaceId == _INTERFACE_ID_ERC721; // ERC721
    }

    /// @notice Gets the number of Wizards owned by the specified address.
    /// @param owner Address to query the balance of.
    /// @return uint256 representing the amount of Wizards owned by the address.
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return ownedWizardsCount[owner];
    }

    /// @notice Gets the owner of the specified Wizard
    /// @param wizardId ID of the Wizard to query the owner of
    /// @return address currently marked as the owner of the given Wizard
    function ownerOf(uint256 wizardId) public view returns (address) {
        address owner = wizardsById[wizardId].owner;
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /// @notice Approves another address to transfer the given Wizard
    /// The zero address indicates there is no approved address.
    /// There can only be one approved address per Wizard at a given time.
    /// Can only be called by the Wizard owner or an approved operator.
    /// @param to address to be approved for the given Wizard
    /// @param wizardId ID of the Wizard to be approved
    function approve(address to, uint256 wizardId) public {
        address owner = ownerOf(wizardId);
        require(to != owner, "ERC721: approval to current owner");
        require(
            msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "ERC721: approve caller is not owner nor approved for all"
        );

        wizardApprovals[wizardId] = to;
        emit Approval(owner, to, wizardId);
    }

    /// @notice Gets the approved address for a Wizard, or zero if no address set
    /// Reverts if the Wizard does not exist.
    /// @param wizardId ID of the Wizard to query the approval of
    /// @return address currently approved for the given Wizard
    function getApproved(uint256 wizardId) public view returns (address) {
        require(_exists(wizardId), "ERC721: approved query for nonexistent token");
        return wizardApprovals[wizardId];
    }

    /// @notice Sets or unsets the approval of a given operator.
    /// An operator is allowed to transfer all Wizards of the sender on their behalf.
    /// @param to operator address to set the approval
    /// @param approved representing the status of the approval to be set
    function setApprovalForAll(address to, bool approved) public {
        require(to != msg.sender, "ERC721: approve to caller");
        _operatorApprovals[msg.sender][to] = approved;
        emit ApprovalForAll(msg.sender, to, approved);
    }

    /// @notice Tells whether an operator is approved by a given owner.
    /// @param owner owner address which you want to query the approval of
    /// @param operator operator address which you want to query the approval of
    /// @return bool whether the given operator is approved by the given owner
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /// @notice Transfers the ownership of a given Wizard to another address.
    /// Usage of this method is discouraged, use `safeTransferFrom` whenever possible.
    /// Requires the msg.sender to be the owner, approved, or operator.
    /// @param from current owner of the Wizard.
    /// @param to address to receive the ownership of the given Wizard.
    /// @param wizardId ID of the Wizard to be transferred.
    function transferFrom(address from, address to, uint256 wizardId) public {
        require(_isApprovedOrOwner(msg.sender, wizardId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, wizardId);
    }

    /// @notice Safely transfers the ownership of a given Wizard to another address
    /// If the target address is a contract, it must implement `onERC721Received`,
    /// which is called upon a safe transfer, and return the magic value
    /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
    /// the transfer is reverted.
    /// Requires the msg.sender to be the owner, approved, or operator.
    /// @param from current owner of the Wizard.
    /// @param to address to receive the ownership of the given Wizard.
    /// @param wizardId ID of the Wizard to be transferred.
    function safeTransferFrom(address from, address to, uint256 wizardId) public {
        safeTransferFrom(from, to, wizardId, "");
    }

    /// @notice Safely transfers the ownership of a given Wizard to another address
    /// If the target address is a contract, it must implement `onERC721Received`,
    /// which is called upon a safe transfer, and return the magic value
    /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
    /// the transfer is reverted.
    /// Requires the msg.sender to be the owner, approved, or operator
    /// @param from current owner of the Wizard.
    /// @param to address to receive the ownership of the given Wizard.
    /// @param wizardId ID of the Wizard to be transferred.
    /// @param _data bytes data to send along with a safe transfer check
    function safeTransferFrom(address from, address to, uint256 wizardId, bytes memory _data) public {
        transferFrom(from, to, wizardId);
        require(_checkOnERC721Received(from, to, wizardId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /// @notice Returns whether the specified Wizard exists.
    /// @param wizardId ID of the Wizard to query the existence of..
    /// @return bool whether the Wizard exists.
    function _exists(uint256 wizardId) internal view returns (bool) {
        address owner = wizardsById[wizardId].owner;
        return owner != address(0);
    }

    /// @notice Returns whether the given spender can transfer a given Wizard.
    /// @param spender address of the spender to query
    /// @param wizardId ID of the Wizard to be transferred
    /// @return bool whether the msg.sender is approved for the given Wizard,
    /// is an operator of the owner, or is the owner of the Wizard.
    function _isApprovedOrOwner(address spender, uint256 wizardId) internal view returns (bool) {
        require(_exists(wizardId), "ERC721: operator query for nonexistent token");
        address owner = ownerOf(wizardId);
        return (spender == owner || getApproved(wizardId) == spender || isApprovedForAll(owner, spender));
    }

    /** @dev Internal function to create a new Wizard; reverts if the Wizard ID is taken.
     *       NOTE: This function heavily depends on the internal format of the Wizard struct
     *       and should always be reassessed if anything about that structure changes.
     *  @param wizardId ID of the new Wizard.
     *  @param owner The address that will own the newly conjured Wizard.
     *  @param innatePower The power level associated with the new Wizard.
     *  @param affinity The elemental affinity of the new Wizard.
     */
    function _createWizard(uint256 wizardId, address owner, uint88 innatePower, uint8 affinity) internal {
        require(owner != address(0), "ERC721: mint to the zero address");
        require(!_exists(wizardId), "ERC721: token already minted");
        require(wizardId > 0, "No 0 token allowed");
        require(innatePower > 0, "Wizard power must be non-zero");

        // Create the Wizard!
        wizardsById[wizardId] = Wizard({
            affinity: affinity,
            innatePower: innatePower,
            owner: owner,
            metadata: 0
        });

        ownedWizardsCount[owner]++;

        // Tell the world!
        emit Transfer(address(0), owner, wizardId);
        emit WizardConjured(wizardId, affinity, innatePower);
    }

    /// @notice Internal function to burn a specific Wizard.
    /// Reverts if the Wizard does not exist.
    /// Deprecated, use _burn(uint256) instead.
    /// @param owner owner of the Wizard to burn.
    /// @param wizardId ID of the Wizard being burned
    function _burn(address owner, uint256 wizardId) internal {
        require(ownerOf(wizardId) == owner, "ERC721: burn of token that is not own");

        _clearApproval(wizardId);

        ownedWizardsCount[owner]--;
        // delete the entire object to recover the most gas
        delete wizardsById[wizardId];

        // required for ERC721 compatibility
        emit Transfer(owner, address(0), wizardId);
    }

    /// @notice Internal function to burn a specific Wizard.
    /// Reverts if the Wizard does not exist.
    /// @param wizardId ID of the Wizard being burned
    function _burn(uint256 wizardId) internal {
        _burn(ownerOf(wizardId), wizardId);
    }

    /// @notice Internal function to transfer ownership of a given Wizard to another address.
    /// As opposed to transferFrom, this imposes no restrictions on msg.sender.
    /// @param from current owner of the Wizard.
    /// @param to address to receive the ownership of the given Wizard
    /// @param wizardId ID of the Wizard to be transferred
    function _transferFrom(address from, address to, uint256 wizardId) internal {
        require(ownerOf(wizardId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(wizardId);

        ownedWizardsCount[from]--;
        ownedWizardsCount[to]++;

        wizardsById[wizardId].owner = to;

        emit Transfer(from, to, wizardId);
    }

    /// @notice Internal function to invoke `onERC721Received` on a target address.
    /// The call is not executed if the target address is not a contract
    /// @param from address representing the previous owner of the given Wizard
    /// @param to target address that will receive the Wizards.
    /// @param wizardId ID of the Wizard 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 wizardId, bytes memory _data)
        internal returns (bool)
    {
        if (!isContract(to)) {
            return true;
        }

        bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, wizardId, _data);
        return (retval == _ERC721_RECEIVED);
    }

    /// @notice Private function to clear current approval of a given Wizard.
    /// @param wizardId ID of the Wizard to be transferred
    function _clearApproval(uint256 wizardId) private {
        if (wizardApprovals[wizardId] != address(0)) {
            wizardApprovals[wizardId] = address(0);
        }
    }
}





contract WizardGuildInterfaceId {
    bytes4 internal constant _INTERFACE_ID_WIZARDGUILD = 0x41d4d437;
}

/// @title The public interface of the Wizard Guild
/// @notice The methods listed in this interface (including the inherited ERC-721 interface),
///         make up the public interface of the Wizard Guild contract. Any contracts that wish
///         to make use of Cheeze Wizard NFTs (such as Cheeze Wizards Tournaments!) should use
///         these methods to ensure they are working correctly with the base NFTs.
contract WizardGuildInterface is IERC721, WizardGuildInterfaceId {

    /// @notice Returns the information associated with the given Wizard
    ///         owner - The address that owns this Wizard
    ///         innatePower - The innate power level of this Wizard, set when minted and entirely
    ///               immutable
    ///         affinity - The Elemental Affinity of this Wizard. For most Wizards, this is set
    ///               when they are minted, but some exclusive Wizards are minted with an affinity
    ///               of 0 (ELEMENT_NOTSET). A Wizard with an NOTSET affinity should NOT be able
    ///               to participate in Tournaments. Once the affinity of a Wizard is set to a non-zero
    ///               value, it can never be changed again.
    ///         metadata - A 256-bit hash of the Wizard's metadata, which is stored off chain. This
    ///               contract doesn't specify format of this hash, nor the off-chain storage mechanism
    ///               but, let's be honest, it's probably an IPFS SHA-256 hash.
    ///
    ///         NOTE: Series zero Wizards have one of four Affinities:  Neutral (1), Fire (2), Water (3)
    ///               or Air (4, sometimes called "Wind" in the code). Future Wizard Series may have
    ///               additional Affinities, and clients of this API should be prepared for that
    ///               eventuality.
    function getWizard(uint256 id) external view returns (address owner, uint88 innatePower, uint8 affinity, bytes32 metadata);

    /// @notice Sets the affinity for a Wizard that doesn't already have its elemental affinity chosen.
    ///         Only usable for Exclusive Wizards (all non-Exclusives must have their affinity chosen when
    ///         conjured.) Even Exclusives can't change their affinity once it's been chosen.
    ///
    ///         NOTE: This function can only be called by the series minter, and (therefore) only while the
    ///         series is open. A Wizard that has no affinity when a series is closed will NEVER have an Affinity.
    ///         BTW- This implies that a minter is responsible for either never minting ELEMENT_NOTSET
    ///         Wizards, or having some public mechanism for a Wizard owner to set the Affinity after minting.
    /// @param wizardId The id of the wizard
    /// @param newAffinity The new affinity of the wizard
    function setAffinity(uint256 wizardId, uint8 newAffinity) external;

    /// @notice A function to be called that conjures a whole bunch of Wizards at once! You know how
    ///         there's "a pride of lions", "a murder of crows", and "a parliament of owls"? Well, with this
    ///         here function you can conjure yourself "a stench of Cheeze Wizards"!
    ///
    ///         Unsurprisingly, this method can only be called by the registered minter for a Series.
    /// @param powers the power level of each wizard
    /// @param affinities the Elements of the wizards to create
    /// @param owner the address that will own the newly created Wizards
    function mintWizards(
        uint88[] calldata powers,
        uint8[] calldata affinities,
        address owner
        ) external returns (uint256[] memory wizardIds);

    /// @notice A function to be called that conjures a series of Wizards in the reserved ID range.
    /// @param wizardIds the ID values to use for each Wizard, must be in the reserved range of the current Series
    /// @param affinities the Elements of the wizards to create
    /// @param powers the power level of each wizard
    /// @param owner the address that will own the newly created Wizards
    function mintReservedWizards(
        uint256[] calldata wizardIds,
        uint88[] calldata powers,
        uint8[] calldata affinities,
        address owner
        ) external;

    /// @notice Sets the metadata values for a list of Wizards. The metadata for a Wizard can only be set once,
    ///         can only be set by the COO or Minter, and can only be set while the Series is still open. Once
    ///         a Series is closed, the metadata is locked forever!
    /// @param wizardIds the ID values of the Wizards to apply metadata changes to.
    /// @param metadata the raw metadata values for each Wizard. This contract does not define how metadata
    ///         should be interpreted, but it is likely to be a 256-bit hash of a complete metadata package
    ///         accessible via IPFS or similar.
    function setMetadata(uint256[] calldata wizardIds, bytes32[] calldata metadata) external;

    /// @notice Returns true if the given "spender" address is allowed to manipulate the given token
    ///         (either because it is the owner of that token, has been given approval to manage that token)
    function isApprovedOrOwner(address spender, uint256 tokenId) external view returns (bool);

    /// @notice Verifies that a given signature represents authority to control the given Wizard ID,
    ///         reverting otherwise. It handles three cases:
    ///             - The simplest case: The signature was signed with the private key associated with
    ///               an external address that is the owner of this Wizard.
    ///             - The signature was generated with the private key associated with an external address
    ///               that is "approved" for working with this Wizard ID. (See the Wizard Guild and/or
    ///               the ERC-721 spec for more information on "approval".)
    ///             - The owner or approval address (as in cases one or two) is a smart contract
    ///               that conforms to ERC-1654, and accepts the given signature as being valid
    ///               using its own internal logic.
    ///
    ///        NOTE: This function DOES NOT accept a signature created by an address that was given "operator
    ///               status" (as granted by ERC-721's setApprovalForAll() functionality). Doing so is
    ///               considered an extreme edge case that can be worked around where necessary.
    /// @param wizardId The Wizard ID whose control is in question
    /// @param hash The message hash we are authenticating against
    /// @param sig the signature data; can be longer than 65 bytes for ERC-1654
    function verifySignature(uint256 wizardId, bytes32 hash, bytes calldata sig) external view;

    /// @notice Convenience function that verifies signatures for two wizards using equivalent logic to
    ///         verifySignature(). Included to save on cross-contract calls in the common case where we
    ///         are verifying the signatures of two Wizards who wish to enter into a Duel.
    /// @param wizardId1 The first Wizard ID whose control is in question
    /// @param wizardId2 The second Wizard ID whose control is in question
    /// @param hash1 The message hash we are authenticating against for the first Wizard
    /// @param hash2 The message hash we are authenticating against for the first Wizard
    /// @param sig1 the signature data corresponding to the first Wizard; can be longer than 65 bytes for ERC-1654
    /// @param sig2 the signature data corresponding to the second Wizard; can be longer than 65 bytes for ERC-1654
    function verifySignatures(
        uint256 wizardId1,
        uint256 wizardId2,
        bytes32 hash1,
        bytes32 hash2,
        bytes calldata sig1,
        bytes calldata sig2) external view;
}



/// @title Contract that manages addresses and access modifiers for certain operations.
/// @author Dapper Labs Inc. (https://www.dapperlabs.com)
contract AccessControl {

    /// @dev The address of the master administrator account that has the power to
    ///      update itself and all of the other administrator addresses.
    ///      The CEO account is not expected to be used regularly, and is intended to
    ///      be stored offline (i.e. a hardware device kept in a safe).
    address public ceoAddress;

    /// @dev The address of the "day-to-day" operator of various privileged
    ///      functions inside the smart contract. Although the CEO has the power
    ///      to replace the COO, the CEO address doesn't actually have the power
    ///      to do "COO-only" operations. This is to discourage the regular use
    ///      of the CEO account.
    address public cooAddress;

    /// @dev The address that is allowed to move money around. Kept separate from
    ///      the COO because the COO address typically lives on an internet-connected
    ///      computer.
    address payable public cfoAddress;

    // Events to indicate when access control role addresses are updated.
    event CEOTransferred(address previousCeo, address newCeo);
    event COOTransferred(address previousCoo, address newCoo);
    event CFOTransferred(address previousCfo, address newCfo);

    /// @dev The AccessControl constructor sets the `ceoAddress` to the sender account. Also
    ///      initializes the COO and CFO to the passed values (CFO is optional and can be address(0)).
    /// @param newCooAddress The initial COO address to set
    /// @param newCfoAddress The initial CFO to set (optional)
    constructor(address newCooAddress, address payable newCfoAddress) public {
        _setCeo(msg.sender);
        setCoo(newCooAddress);

        if (newCfoAddress != address(0)) {
            setCfo(newCfoAddress);
        }
    }

    /// @notice Access modifier for CEO-only functionality
    modifier onlyCEO() {
        require(msg.sender == ceoAddress, "Only CEO");
        _;
    }

    /// @notice Access modifier for COO-only functionality
    modifier onlyCOO() {
        require(msg.sender == cooAddress, "Only COO");
        _;
    }

    /// @notice Access modifier for CFO-only functionality
    modifier onlyCFO() {
        require(msg.sender == cfoAddress, "Only CFO");
        _;
    }

    function checkControlAddress(address newController) internal view {
        require(newController != address(0) && newController != ceoAddress, "Invalid CEO address");
    }

    /// @notice Assigns a new address to act as the CEO. Only available to the current CEO.
    /// @param newCeo The address of the new CEO
    function setCeo(address newCeo) external onlyCEO {
        checkControlAddress(newCeo);
        _setCeo(newCeo);
    }

    /// @dev An internal utility function that updates the CEO variable and emits the
    ///      transfer event. Used from both the public setCeo function and the constructor.
    function _setCeo(address newCeo) private {
        emit CEOTransferred(ceoAddress, newCeo);
        ceoAddress = newCeo;
    }

    /// @notice Assigns a new address to act as the COO. Only available to the current CEO.
    /// @param newCoo The address of the new COO
    function setCoo(address newCoo) public onlyCEO {
        checkControlAddress(newCoo);
        emit COOTransferred(cooAddress, newCoo);
        cooAddress = newCoo;
    }

    /// @notice Assigns a new address to act as the CFO. Only available to the current CEO.
    /// @param newCfo The address of the new CFO
    function setCfo(address payable newCfo) public onlyCEO {
        checkControlAddress(newCfo);
        emit CFOTransferred(cfoAddress, newCfo);
        cfoAddress = newCfo;
    }
}




/// @title Signature utility library
library SigTools {

    /// @notice Splits a signature into r & s values, and v (the verification value).
    /// @dev Note: This does not verify the version, but does require signature length = 65
    /// @param signature the packed signature to be split
    function _splitSignature(bytes memory signature) internal pure returns (bytes32 r, bytes32 s, uint8 v) {
        // Check signature length
        require(signature.length == 65, "Invalid signature length");

        // We need to unpack the signature, which is given as an array of 65 bytes (like eth.sign)
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            r := mload(add(signature, 32))
            s := mload(add(signature, 64))
            v := and(mload(add(signature, 65)), 255)
        }

        if (v < 27) {
            v += 27; // Ethereum versions are 27 or 28 as opposed to 0 or 1 which is submitted by some signing libs
        }

        // check for valid version
        // removed for now, done in another function
        //require((v == 27 || v == 28), "Invalid signature version");

        return (r, s, v);
    }
}



contract ERC1654 {

    /// @dev bytes4(keccak256("isValidSignature(bytes32,bytes)")
    bytes4 public constant ERC1654_VALIDSIGNATURE = 0x1626ba7e;

    /// @dev Should return whether the signature provided is valid for the provided data
    /// @param hash 32-byte hash of the data that is signed
    /// @param _signature Signature byte array associated with _data
    ///  MUST return the bytes4 magic value 0x1626ba7e when function passes.
    ///  MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)
    ///  MUST allow external calls
    function isValidSignature(
        bytes32 hash,
        bytes calldata _signature)
        external
        view
        returns (bytes4);
}



/// @title The master organization behind all Cheeze Wizardry. The source of all them Wiz.
contract WizardGuild is AccessControl, WizardNFT, WizardGuildInterface, ERC165Query {

    /// @notice Emitted when a new Series is opened or closed.
    event SeriesOpen(uint64 seriesIndex, uint256 reservedIds);
    event SeriesClose(uint64 seriesIndex);

    /// @notice Emitted when metadata is associated with a Wizard
    event MetadataSet(uint256 indexed wizardId, bytes32 metadata);

    /// @notice The index of the current Series (zero-based). When no Series is open, this value
    ///         indicates the index of the _upcoming_ Series. (i.e. it is incremented when the
    ///         Series is closed. This makes it easier to bootstrap the first Series.)
    uint64 internal seriesIndex;

    /// @notice The address which is allowed to mint new Wizards in the current Series. When this
    ///         is set to address(0), there is no open Series.
    address internal seriesMinter;

    /// @notice The index number of the next Wizard to be created (Neutral or Elemental).
    ///         NOTE: There is a subtle distinction between a Wizard "ID" and a Wizard "index".
    ///               We use the term "ID" to refer to a value that includes the Series number in the
    ///               top 64 bits, while the term "index" refers to the Wizard number _within_ its
    ///               Series. This is especially confusing when talking about Wizards in the first
    ///               Series (Series 0), because the two values are identical in that case!
    ///
    ///               |---------------|--------------------------|
    ///               |           Wizard ID (256 bits)           |
    ///               |---------------|--------------------------|
    ///               |  Series Index |      Wizard Index        |
    ///               |   (64 bits)   |       (192 bits)         |
    ///               |---------------|--------------------------|
    uint256 internal nextWizardIndex;

    function getNextWizardIndex() external view returns (uint256) {
        return nextWizardIndex;
    }

    // NOTE: uint256(-1) maps to a value with all bits set, both the << and >> operators will fill
    // in with zeros when acting on an unsigned value. So, "uint256(-1) << 192" resolves to "a bunch
    /// of ones, followed by 192 zeros"
    uint256 internal constant SERIES_OFFSET = 192;
    uint256 internal constant SERIES_MASK = uint256(-1) << SERIES_OFFSET;
    uint256 internal constant INDEX_MASK = uint256(-1) >> 64;

    // The ERC1654 function selector value
    bytes4 internal constant ERC1654_VALIDSIGNATURE = 0x1626ba7e;

    /// @notice The Guild constructor.
    /// @param _cooAddress The COO has the ability to create new Series and to update
    ///         the metadata on the currently open Series (if any). It has no other special
    ///         abilities, and (in particular), ALL Wizards in a closed series can never be
    ///         modified or deleted. If the CEO and COO values are ever set to invalid addresses
    ///        (such as address(1)), then no new Series can ever be created, either.
    constructor(address _cooAddress) public AccessControl(_cooAddress, address(0)) {
    }

    /// @notice Require that a Tournament Series is currently open. For example closing
    ///         a Series does not make sense if none is open.
    /// @dev While in other contracts we use separate checking functions to avoid having the same
    ///      string inlined in multiple places, given this modifier is scarcely used it doesn't seem
    ///      worth the per-call gas cost here.
    modifier duringSeries() {
        require(seriesMinter != address(0), "No series is currently open");
        _;
    }

    /// @notice Require that the caller is the minter of the current series. This implicitely
    ///         requires that a Series is open, or the minter address would be invalid (can never
    ///         be matched).
    /// @dev While in other contracts we use separate checking functions to avoid having the same
    ///      string inlined in multiple places, given this modifier is scarcely used it doesn't seem
    ///      worth the per-call gas cost here.
    modifier onlyMinter() {
        require(msg.sender == seriesMinter, "Only callable by minter");
        _;
    }

    /// @notice Open a new Series of Cheeze Wizards! Can only be called by the COO when no Series is open.
    /// @param minter The address which is allowed to mint Wizards in this series. This contract does not
    ///         assume that the minter is a smart contract, but it will presumably be in the vast majority
    ///         of the cases. A minter has absolute control over the creation of new Wizards in an open
    ///         Series, but CAN NOT manipulate a Series after it has been closed, and CAN NOT manipulate
    ///         any Wizards that don't belong to its own Series. (Even if the same minting address is used
    ///         for multiple Series, the Minter only has power over the currently open Series.)
    /// @param reservedIds The number of IDs (from 1 to reservedIds, inclusive) that are reserved for minting
    ///         reserved Wizards. (We use the term "reserved" here, instead of Exclusive, because there
    ///         are times -- such as during the importation of the Presale -- when we need to reserve a
    ///         block of IDs for Wizards that aren't what a user would think of as "exclusive". In Series
    ///         0, the reserved IDs will include all Exclusive Wizards and Presale Wizards. In other Series
    ///         it might also be the case that the set of "reserved IDs" doesn't exactly match the set of
    ///         "exclusive" IDs.)
    function openSeries(address minter, uint256 reservedIds) external onlyCOO returns (uint64 seriesId) {
        require(seriesMinter == address(0), "A series is already open");
        require(minter != address(0), "Minter address cannot be 0");

        if (seriesIndex == 0) {
            // The last wizard sold in the unpasteurized Tournament at the time the Presale contract
            // was destroyed is 6133.
            //
            // The unpasteurized Tournament contract is the Tournament contract that doesn't have the
            // "Same Wizard" check in the resolveTimedOutDuel function.

            // The wizards, which were minted in the unpasteurized Tournament before the Presale contract
            // was destroyed, will be minted again in the new Tournament contract with their ID reserved.
            //
            // So the reason the reservedIds is hardcoded here is to ensure:
            // 1) The next Wizard minted will have its ID continued from this above wizard ID.
            // 2) The Presale wizards and some wizards minted in the unpasteurized Tournament contract,
            //    can be minted in this contract with their ID reserved.
            require(reservedIds == 6133, "Invalid reservedIds for 1st series");
        } else {
            require(reservedIds < 1 << 192, "Invalid reservedIds");
        }

        // NOTE: The seriesIndex is updated when the Series is _closed_, not when it's opened.
        //  (The first Series is Series #0.) So in this function, we just leave the seriesIndex alone.

        seriesMinter = minter;
        nextWizardIndex = reservedIds + 1;

        emit SeriesOpen(seriesIndex, reservedIds);

        return seriesIndex;
    }

    /// @notice Closes the current Wizard Series. Once a Series has been closed, it is forever sealed and
    ///         no more Wizards in that Series can ever be minted! Can only be called by the COO when a Series
    ///         is open.
    ///
    ///    NOTE: A series can be closed by the COO or the Minter. (It's assumed that some minters will
    ///          know when they are done, and others will need to be shut off manually by the COO.)
    function closeSeries() external duringSeries {
        require(
            msg.sender == seriesMinter || msg.sender == cooAddress,
            "Only Minter or COO can close a Series");

        seriesMinter = address(0);
        emit SeriesClose(seriesIndex);

        // Set up the next series.
        seriesIndex += 1;
        nextWizardIndex = 0;
    }

    /// @notice ERC-165 Query Function.
    function supportsInterface(bytes4 interfaceId) public view returns (bool) {
        return interfaceId == _INTERFACE_ID_WIZARDGUILD || super.supportsInterface(interfaceId);
    }

    /// @notice Returns the information associated with the given Wizard
    ///         owner - The address that owns this Wizard
    ///         innatePower - The innate power level of this Wizard, set when minted and entirely
    ///               immutable
    ///         affinity - The Elemental Affinity of this Wizard. For most Wizards, this is set
    ///               when they are minted, but some exclusive Wizards are minted with an affinity
    ///               of 0 (ELEMENT_NOTSET). A Wizard with an NOTSET affinity should NOT be able
    ///               to participate in Tournaments. Once the affinity of a Wizard is set to a non-zero
    ///               value, it can never be changed again.
    ///         metadata - A 256-bit hash of the Wizard's metadata, which is stored off chain. This
    ///               contract doesn't specify format of this hash, nor the off-chain storage mechanism
    ///               but, let's be honest, it's probably an IPFS SHA-256 hash.
    ///
    ///         NOTE: Series zero Wizards have one of four Affinities:  Neutral (1), Fire (2), Water (3)
    ///               or Air (4, sometimes called "Wind" in the code). Future Wizard Series may have
    ///               additional Affinities, and clients of this API should be prepared for that
    ///               eventuality.
    function getWizard(uint256 id) public view returns (address owner, uint88 innatePower, uint8 affinity, bytes32 metadata) {
        Wizard memory wizard = wizardsById[id];
        require(wizard.owner != address(0), "Wizard does not exist");
        (owner, innatePower, affinity, metadata) = (wizard.owner, wizard.innatePower, wizard.affinity, wizard.metadata);
    }

    /// @notice A function to be called that conjures a whole bunch of Wizards at once! You know how
    ///         there's "a pride of lions", "a murder of crows", and "a parliament of owls"? Well, with this
    ///         here function you can conjure yourself "a stench of Cheeze Wizards"!
    ///
    ///         Unsurprisingly, this method can only be called by the registered minter for a Series.
    /// @dev This function DOES NOT CALL onERC721Received() as required by the ERC-721 standard. It is
    ///         REQUIRED that the Minter calls onERC721Received() after calling this function. The following
    ///         code snippet should suffice:
    ///                 // Ensure the Wizard is being assigned to an ERC-721 aware address (either an external address,
    ///                 // or a smart contract that implements onERC721Received()). We must call onERC721Received for
    ///                 // each token created because it's allowed for an ERC-721 receiving contract to reject the
    ///                 // transfer based on the properties of the token.
    ///                 if (isContract(owner)) {
    ///                     for (uint256 i = 0; i < wizardIds.length; i++) {
    ///                         bytes4 retval = IERC721Receiver(owner).onERC721Received(owner, address(0), wizardIds[i], "");
    ///                         require(retval == _ERC721_RECEIVED, "Contract owner didn't accept ERC721 transfer");
    ///                     }
    ///                 }
    ///        Although it would be convenient for mintWizards to call onERC721Received, it opens us up to potential
    ///        reentrancy attacks if the Minter needs to do more state updates after mintWizards() returns.
    /// @param powers the power level of each wizard
    /// @param affinities the Elements of the wizards to create
    /// @param owner the address that will own the newly created Wizards
    function mintWizards(
        uint88[] calldata powers,
        uint8[] calldata affinities,
        address owner
    ) external onlyMinter returns (uint256[] memory wizardIds)
    {
        require(affinities.length == powers.length, "Inconsistent parameter lengths");

        // allocate result array
        wizardIds = new uint256[](affinities.length);

        // We take this storage variables, and turn it into a local variable for the course
        // of this loop to save about 5k gas per wizard.
        uint256 tempWizardId = (uint256(seriesIndex) << SERIES_OFFSET) + nextWizardIndex;

        for (uint256 i = 0; i < affinities.length; i++) {
            wizardIds[i] = tempWizardId;
            tempWizardId++;

            _createWizard(wizardIds[i], owner, powers[i], affinities[i]);
        }

        nextWizardIndex = tempWizardId & INDEX_MASK;
    }

    /// @notice A function to be called that mints a Series of Wizards in the reserved ID range, can only
    ///         be called by the Minter for this Series.
    /// @dev This function DOES NOT CALL onERC721Received() as required by the ERC-721 standard. It is
    ///         REQUIRED that the Minter calls onERC721Received() after calling this function. See the note
    ///         above on mintWizards() for more info.
    /// @param wizardIds the ID values to use for each Wizard, must be in the reserved range of the current Series.
    /// @param powers the power level of each Wizard.
    /// @param affinities the Elements of the Wizards to create.
    /// @param owner the address that will own the newly created Wizards.
    function mintReservedWizards(
        uint256[] calldata wizardIds,
        uint88[] calldata powers,
        uint8[] calldata affinities,
        address owner
    )
    external onlyMinter
    {
        require(
            wizardIds.length == affinities.length &&
            wizardIds.length == powers.length, "Inconsistent parameter lengths");

        for (uint256 i = 0; i < wizardIds.length; i++) {
            uint256 currentId = wizardIds[i];

            require((currentId & SERIES_MASK) == (uint256(seriesIndex) << SERIES_OFFSET), "Wizards not in current series");
            require((currentId & INDEX_MASK) > 0, "Wizards id cannot be zero");

            // Ideally, we would compare the requested Wizard index against the reserved range directly. However,
            // it's a bit wasteful to spend storage on a reserved range variable when we can combine some known
            // true facts instead:
            //         - nextWizardIndex is initialized to reservedRange + 1 when the Series was opened
            //         - nextWizardIndex is only incremented when a new Wizard is created
            //         - therefore, the only empty Wizard IDs less than nextWizardIndex are in the reserved range.
            //         - _conjureWizard() will abort if we try to reuse an ID.
            // Combining all of the above, we know that, if the requested index is less than the next index, it
            // either points to a reserved slot or an occupied slot. Trying to reuse an occupied slot will fail,
            // so just checking against nextWizardIndex is sufficient to ensure we're pointing at a reserved slot.
            require((currentId & INDEX_MASK) < nextWizardIndex, "Wizards not in reserved range");

            _createWizard(currentId, owner, powers[i], affinities[i]);
        }
    }

    /// @notice Sets the metadata values for a list of Wizards. The metadata for a Wizard can only be set once,
    ///         can only be set by the COO or Minter, and can only be set while the Series is still open. Once
    ///         a Series is closed, the metadata is locked forever!
    /// @param wizardIds the ID values of the Wizards to apply metadata changes to.
    /// @param metadata the raw metadata values for each Wizard. This contract does not define how metadata
    ///         should be interpreted, but it is likely to be a 256-bit hash of a complete metadata package
    ///         accessible via IPFS or similar.
    function setMetadata(uint256[] calldata wizardIds, bytes32[] calldata metadata) external duringSeries {
        require(msg.sender == seriesMinter || msg.sender == cooAddress, "Only Minter or COO can set metadata");
        require(wizardIds.length == metadata.length, "Inconsistent parameter lengths");

        for (uint256 i = 0; i < wizardIds.length; i++) {
            uint256 currentId = wizardIds[i];
            bytes32 currentMetadata = metadata[i];

            require((currentId & SERIES_MASK) == (uint256(seriesIndex) << SERIES_OFFSET), "Wizards not in current series");

            require(wizardsById[currentId].metadata == bytes32(0), "Metadata already set");

            require(currentMetadata != bytes32(0), "Invalid metadata");

            wizardsById[currentId].metadata = currentMetadata;

            emit MetadataSet(currentId, currentMetadata);
        }
    }

    /// @notice Sets the affinity for a Wizard that doesn't already have its elemental affinity chosen.
    ///         Only usable for Exclusive Wizards (all non-Exclusives must have their affinity chosen when
    ///         conjured.) Even Exclusives can't change their affinity once it's been chosen.
    ///
    ///         NOTE: This function can only be called by the Series minter, and (therefore) only while the
    ///         Series is open. A Wizard that has no affinity when a Series is closed will NEVER have an Affinity.
    /// @param wizardId The ID of the Wizard to update affinity of.
    /// @param newAffinity The new affinity of the Wizard.
    function setAffinity(uint256 wizardId, uint8 newAffinity) external onlyMinter {
        require((wizardId & SERIES_MASK) == (uint256(seriesIndex) << SERIES_OFFSET), "Wizard not in current series");

        Wizard storage wizard = wizardsById[wizardId];

        require(wizard.affinity == ELEMENT_NOTSET, "Affinity can only be chosen once");

        // set the affinity
        wizard.affinity = newAffinity;

        // Tell the world this wizards now has an affinity!
        emit WizardAffinityAssigned(wizardId, newAffinity);
    }

    /// @notice Returns true if the given "spender" address is allowed to manipulate the given token
    ///         (either because it is the owner of that token, has been given approval to manage that token)
    function isApprovedOrOwner(address spender, uint256 tokenId) external view returns (bool) {
        return _isApprovedOrOwner(spender, tokenId);
    }

    /// @notice Verifies that a given signature represents authority to control the given Wizard ID,
    ///         reverting otherwise. It handles three cases:
    ///             - The simplest case: The signature was signed with the private key associated with
    ///               an external address that is the owner of this Wizard.
    ///             - The signature was generated with the private key associated with an external address
    ///               that is "approved" for working with this Wizard ID. (See the Wizard Guild and/or
    ///               the ERC-721 spec for more information on "approval".)
    ///             - The owner or approval address (as in cases one or two) is a smart contract
    ///               that conforms to ERC-1654, and accepts the given signature as being valid
    ///               using its own internal logic.
    ///
    ///        NOTE: This function DOES NOT accept a signature created by an address that was given "operator
    ///               status" (as granted by ERC-721's setApprovalForAll() functionality). Doing so is
    ///               considered an extreme edge case that can be worked around where necessary.
    /// @param wizardId The Wizard ID whose control is in question
    /// @param hash The message hash we are authenticating against
    /// @param sig the signature data; can be longer than 65 bytes for ERC-1654
    function verifySignature(uint256 wizardId, bytes32 hash, bytes memory sig) public view {
        // First see if the signature belongs to the owner (the most common case)
        address owner = ownerOf(wizardId);

        if (_validSignatureForAddress(owner, hash, sig)) {
            return;
        }

        // Next check if the signature belongs to the approved address
        address approved = getApproved(wizardId);

        if (_validSignatureForAddress(approved, hash, sig)) {
            return;
        }

        revert("Invalid signature");
    }

    /// @notice Convenience function that verifies signatures for two wizards using equivalent logic to
    ///         verifySignature(). Included to save on cross-contract calls in the common case where we
    ///         are verifying the signatures of two Wizards who wish to enter into a Duel.
    /// @param wizardId1 The first Wizard ID whose control is in question
    /// @param wizardId2 The second Wizard ID whose control is in question
    /// @param hash1 The message hash we are authenticating against for the first Wizard
    /// @param hash2 The message hash we are authenticating against for the first Wizard
    /// @param sig1 the signature data corresponding to the first Wizard; can be longer than 65 bytes for ERC-1654
    /// @param sig2 the signature data corresponding to the second Wizard; can be longer than 65 bytes for ERC-1654
    function verifySignatures(
        uint256 wizardId1,
        uint256 wizardId2,
        bytes32 hash1,
        bytes32 hash2,
        bytes calldata sig1,
        bytes calldata sig2) external view
    {
        verifySignature(wizardId1, hash1, sig1);
        verifySignature(wizardId2, hash2, sig2);
    }

    /// @notice An internal function that checks if a given signature is a valid signature for a
    ///         specific address on a particular hash value. Checks for ERC-1654 compatibility
    ///         first (where the possibleSigner is a smart contract that implements its own
    ///         signature validation), and falls back to ecrecover() otherwise.
    function _validSignatureForAddress(address possibleSigner, bytes32 hash, bytes memory signature)
        internal view returns(bool)
    {
        if (possibleSigner == address(0)) {
            // The most basic Bozo check: The zero address can never be a valid signer!
            return false;
        } else if (Address.isContract(possibleSigner)) {
            // If the address is a contract, it either implements ERC-1654 (and will validate the signature
            // itself), or we have no way of confirming that this signature matches this address. In other words,
            // if this address is a contract, there's no point in "falling back" to ecrecover().
            if (doesContractImplementInterface(possibleSigner, ERC1654_VALIDSIGNATURE)) {
                // cast to ERC1654
                ERC1654 tso = ERC1654(possibleSigner);
                bytes4 result = tso.isValidSignature(keccak256(abi.encodePacked(hash)), signature);
                if (result == ERC1654_VALIDSIGNATURE) {
                    return true;
                }
            }

            return false;
        } else {
            // Not a contract, check for a match against an external address
            // assume EIP 191 signature here
            (bytes32 r, bytes32 s, uint8 v) = SigTools._splitSignature(signature);
            address signer = ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)), v, r, s);

            // Note: Signer could be address(0) here, but we already checked that possibleSigner isn't zero
            return (signer == possibleSigner);
        }
    }

}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cfoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"wizardId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"wizardId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ceoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"wizardId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wizardIds","type":"uint256[]"},{"name":"metadata","type":"bytes32[]"}],"name":"setMetadata","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newCfo","type":"address"}],"name":"setCfo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"wizardId","type":"uint256"},{"name":"hash","type":"bytes32"},{"name":"sig","type":"bytes"}],"name":"verifySignature","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"closeSeries","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"wizardId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"spender","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"isApprovedOrOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"minter","type":"address"},{"name":"reservedIds","type":"uint256"}],"name":"openSeries","outputs":[{"name":"seriesId","type":"uint64"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"powers","type":"uint88[]"},{"name":"affinities","type":"uint8[]"},{"name":"owner","type":"address"}],"name":"mintWizards","outputs":[{"name":"wizardIds","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"wizardsById","outputs":[{"name":"affinity","type":"uint8"},{"name":"innatePower","type":"uint88"},{"name":"owner","type":"address"},{"name":"metadata","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"wizardId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newCeo","type":"address"}],"name":"setCeo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wizardId","type":"uint256"},{"name":"newAffinity","type":"uint8"}],"name":"setAffinity","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newCoo","type":"address"}],"name":"setCoo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wizardIds","type":"uint256[]"},{"name":"powers","type":"uint88[]"},{"name":"affinities","type":"uint8[]"},{"name":"owner","type":"address"}],"name":"mintReservedWizards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"wizardId1","type":"uint256"},{"name":"wizardId2","type":"uint256"},{"name":"hash1","type":"bytes32"},{"name":"hash2","type":"bytes32"},{"name":"sig1","type":"bytes"},{"name":"sig2","type":"bytes"}],"name":"verifySignatures","outputs":[],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cooAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"wizardId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getNextWizardIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"getWizard","outputs":[{"name":"owner","type":"address"},{"name":"innatePower","type":"uint88"},{"name":"affinity","type":"uint8"},{"name":"metadata","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_cooAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"seriesIndex","type":"uint64"},{"indexed":false,"name":"reservedIds","type":"uint256"}],"name":"SeriesOpen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"seriesIndex","type":"uint64"}],"name":"SeriesClose","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"wizardId","type":"uint256"},{"indexed":false,"name":"metadata","type":"bytes32"}],"name":"MetadataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"wizardId","type":"uint256"},{"indexed":false,"name":"affinity","type":"uint8"},{"indexed":false,"name":"innatePower","type":"uint256"}],"name":"WizardConjured","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"wizardId","type":"uint256"},{"indexed":false,"name":"affinity","type":"uint8"}],"name":"WizardAffinityAssigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"approved","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousCeo","type":"address"},{"indexed":false,"name":"newCeo","type":"address"}],"name":"CEOTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousCoo","type":"address"},{"indexed":false,"name":"newCoo","type":"address"}],"name":"COOTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousCfo","type":"address"},{"indexed":false,"name":"newCfo","type":"address"}],"name":"CFOTransferred","type":"event"}]

60806040523480156200001157600080fd5b506040516020806200306e833981018060405260208110156200003357600080fd5b50518060006200004a3362000085602090811b901c565b6200005b82620000ef60201b60201c565b6001600160a01b038116156200007c576200007c81620001e460201b60201c565b5050506200036f565b600054604080516001600160a01b039283168152918316602083015280517f9d05f170f1d545b1aa21c4a4f79f17ff737f5f020ea1b333d88f29f0bbfa9fc69281900390910190a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146200016957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f4f6e6c792043454f000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6200017a81620002d960201b60201c565b600154604080516001600160a01b039283168152918316602083015280517f1cd3afc04e6ae479d2b9f74533351b52218c5b2ae4f847f681a5eac514fe11849281900390910190a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146200025e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f4f6e6c792043454f000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6200026f81620002d960201b60201c565b600254604080516001600160a01b039283168152918316602083015280517fe1033d3cc535efc343c53636bdc05c52a44d9e70b089d4ad6e974379f2c651d69281900390910190a1600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116158015906200030057506000546001600160a01b03828116911614155b6200036c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496e76616c69642043454f206164647265737300000000000000000000000000604482015290519081900360640190fd5b50565b612cef806200037f6000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80635938d97a116100f9578063a096d9f011610097578063b88d4fde11610071578063b88d4fde14610950578063c5ffd6e114610a14578063e985e9c514610a1c578063fac8eafc14610a4a576101c4565b8063a096d9f014610844578063a22cb4651461091a578063b047fb5014610948576101c4565b806388975198116100d357806388975198146106bb57806398d7a414146106e15780639986a0c6146107075780639d1580231461072d576101c4565b80635938d97a1461060f5780636352211e1461066657806370a0823114610683576101c4565b80632d46ed561161016657806342842e0e1161014057806342842e0e1461044d578063430c2081146104835780634616c514146104af57806355fdbeec146104f8576101c4565b80632d46ed561461036f5780632f81b15d146103955780634094099a14610445576101c4565b8063095ea7b3116101a2578063095ea7b3146102455780630a0f81681461027357806323b872dd1461027b5780632738ec3c146102b1576101c4565b806301ffc9a7146101c95780630519ce7914610204578063081812fc14610228575b600080fd5b6101f0600480360360208110156101df57600080fd5b50356001600160e01b031916610aa1565b604080519115158252519081900360200190f35b61020c610acf565b604080516001600160a01b039092168252519081900360200190f35b61020c6004803603602081101561023e57600080fd5b5035610ade565b6102716004803603604081101561025b57600080fd5b506001600160a01b038135169060200135610b43565b005b61020c610c5a565b6102716004803603606081101561029157600080fd5b506001600160a01b03813581169160208101359091169060400135610c69565b610271600480360360408110156102c757600080fd5b810190602081018135600160201b8111156102e157600080fd5b8201836020820111156102f357600080fd5b803590602001918460208302840111600160201b8311171561031457600080fd5b919390929091602081019035600160201b81111561033157600080fd5b82018360208201111561034357600080fd5b803590602001918460208302840111600160201b8311171561036457600080fd5b509092509050610cc1565b6102716004803603602081101561038557600080fd5b50356001600160a01b0316610fac565b610271600480360360608110156103ab57600080fd5b813591602081013591810190606081016040820135600160201b8111156103d157600080fd5b8201836020820111156103e357600080fd5b803590602001918460018302840111600160201b8311171561040457600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061106f945050505050565b610271611106565b6102716004803603606081101561046357600080fd5b506001600160a01b03813581169160208101359091169060400135611252565b6101f06004803603604081101561049957600080fd5b506001600160a01b03813516906020013561126d565b6104db600480360360408110156104c557600080fd5b506001600160a01b038135169060200135611280565b6040805167ffffffffffffffff9092168252519081900360200190f35b6105bf6004803603606081101561050e57600080fd5b810190602081018135600160201b81111561052857600080fd5b82018360208201111561053a57600080fd5b803590602001918460208302840111600160201b8311171561055b57600080fd5b919390929091602081019035600160201b81111561057857600080fd5b82018360208201111561058a57600080fd5b803590602001918460208302840111600160201b831117156105ab57600080fd5b9193509150356001600160a01b03166114d3565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156105fb5781810151838201526020016105e3565b505050509050019250505060405180910390f35b61062c6004803603602081101561062557600080fd5b5035611672565b6040805160ff90951685526001600160581b0390931660208501526001600160a01b03909116838301526060830152519081900360800190f35b61020c6004803603602081101561067c57600080fd5b50356116b1565b6106a96004803603602081101561069957600080fd5b50356001600160a01b031661170f565b60408051918252519081900360200190f35b610271600480360360208110156106d157600080fd5b50356001600160a01b0316611775565b610271600480360360408110156106f757600080fd5b508035906020013560ff166117da565b6102716004803603602081101561071d57600080fd5b50356001600160a01b031661196a565b6102716004803603608081101561074357600080fd5b810190602081018135600160201b81111561075d57600080fd5b82018360208201111561076f57600080fd5b803590602001918460208302840111600160201b8311171561079057600080fd5b919390929091602081019035600160201b8111156107ad57600080fd5b8201836020820111156107bf57600080fd5b803590602001918460208302840111600160201b831117156107e057600080fd5b919390929091602081019035600160201b8111156107fd57600080fd5b82018360208201111561080f57600080fd5b803590602001918460208302840111600160201b8311171561083057600080fd5b9193509150356001600160a01b0316611a2d565b610271600480360360c081101561085a57600080fd5b81359160208101359160408201359160608101359181019060a081016080820135600160201b81111561088c57600080fd5b82018360208201111561089e57600080fd5b803590602001918460018302840111600160201b831117156108bf57600080fd5b919390929091602081019035600160201b8111156108dc57600080fd5b8201836020820111156108ee57600080fd5b803590602001918460018302840111600160201b8311171561090f57600080fd5b509092509050611c8f565b6102716004803603604081101561093057600080fd5b506001600160a01b0381351690602001351515611d11565b61020c611de0565b6102716004803603608081101561096657600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156109a057600080fd5b8201836020820111156109b257600080fd5b803590602001918460018302840111600160201b831117156109d357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611def945050505050565b6106a9611e4a565b6101f060048036036040811015610a3257600080fd5b506001600160a01b0381358116916020013516611e50565b610a6760048036036020811015610a6057600080fd5b5035611e7e565b604080516001600160a01b0390951685526001600160581b03909316602085015260ff909116838301526060830152519081900360800190f35b60006001600160e01b03198216600160e01b6341d4d437021480610ac95750610ac982611f5a565b92915050565b6002546001600160a01b031681565b6000610ae982611f93565b610b2757604051600160e51b62461bcd02815260040180806020018281038252602c815260200180612bd5602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610b4e826116b1565b9050806001600160a01b0316836001600160a01b03161415610ba457604051600160e51b62461bcd028152600401808060200182810382526021815260200180612c4f6021913960400191505060405180910390fd5b336001600160a01b0382161480610bc05750610bc08133611e50565b610bfe57604051600160e51b62461bcd028152600401808060200182810382526038815260200180612b286038913960400191505060405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000546001600160a01b031681565b610c733382611fb7565b610cb157604051600160e51b62461bcd028152600401808060200182810382526031815260200180612c706031913960400191505060405180910390fd5b610cbc83838361205e565b505050565b600754600160401b90046001600160a01b0316610d285760408051600160e51b62461bcd02815260206004820152601b60248201527f4e6f207365726965732069732063757272656e746c79206f70656e0000000000604482015290519081900360640190fd5b600754600160401b90046001600160a01b0316331480610d5257506001546001600160a01b031633145b610d9057604051600160e51b62461bcd028152600401808060200182810382526023815260200180612ca16023913960400191505060405180910390fd5b828114610de75760408051600160e51b62461bcd02815260206004820152601e60248201527f496e636f6e73697374656e7420706172616d65746572206c656e677468730000604482015290519081900360640190fd5b60005b83811015610fa5576000858583818110610e0057fe5b9050602002013590506000848484818110610e1757fe5b600754602091909102929092013592505067ffffffffffffffff1660c01b6001600160c01b0319831614610e955760408051600160e51b62461bcd02815260206004820152601d60248201527f57697a61726473206e6f7420696e2063757272656e7420736572696573000000604482015290519081900360640190fd5b60008281526003602052604090206001015415610efc5760408051600160e51b62461bcd02815260206004820152601460248201527f4d6574616461746120616c726561647920736574000000000000000000000000604482015290519081900360640190fd5b80610f515760408051600160e51b62461bcd02815260206004820152601060248201527f496e76616c6964206d6574616461746100000000000000000000000000000000604482015290519081900360640190fd5b6000828152600360209081526040918290206001018390558151838152915184927ff6812173c9728bd3bab2f1a94129341e47af8b8b78e2da481f8c45659d2d59eb92908290030190a25050600101610dea565b5050505050565b6000546001600160a01b03163314610ffc5760408051600160e51b62461bcd0281526020600482015260086024820152600160c01b674f6e6c792043454f02604482015290519081900360640190fd5b61100581612191565b600254604080516001600160a01b039283168152918316602083015280517fe1033d3cc535efc343c53636bdc05c52a44d9e70b089d4ad6e974379f2c651d69281900390910190a1600280546001600160a01b0319166001600160a01b0392909216919091179055565b600061107a846116b1565b905061108781848461220b565b156110925750610cbc565b600061109d85610ade565b90506110aa81858561220b565b156110b6575050610cbc565b60408051600160e51b62461bcd02815260206004820152601160248201527f496e76616c6964207369676e6174757265000000000000000000000000000000604482015290519081900360640190fd5b600754600160401b90046001600160a01b031661116d5760408051600160e51b62461bcd02815260206004820152601b60248201527f4e6f207365726965732069732063757272656e746c79206f70656e0000000000604482015290519081900360640190fd5b600754600160401b90046001600160a01b031633148061119757506001546001600160a01b031633145b6111d557604051600160e51b62461bcd028152600401808060200182810382526025815260200180612c2a6025913960400191505060405180910390fd5b60078054600160401b600160e01b031981169091556040805167ffffffffffffffff9092168252517f05ba38dc3f1ba4a8bd95dbf51dd0f0141267df538cdd31a01819e9929acdce0d9181900360200190a16007805467ffffffffffffffff8082166001011667ffffffffffffffff199091161790556000600855565b610cbc83838360405180602001604052806000815250611def565b60006112798383611fb7565b9392505050565b6001546000906001600160a01b031633146112d35760408051600160e51b62461bcd0281526020600482015260086024820152600160c01b674f6e6c7920434f4f02604482015290519081900360640190fd5b600754600160401b90046001600160a01b03161561133b5760408051600160e51b62461bcd02815260206004820152601860248201527f412073657269657320697320616c7265616479206f70656e0000000000000000604482015290519081900360640190fd5b6001600160a01b0383166113995760408051600160e51b62461bcd02815260206004820152601a60248201527f4d696e74657220616464726573732063616e6e6f742062652030000000000000604482015290519081900360640190fd5b60075467ffffffffffffffff166113f257816117f5146113ed57604051600160e51b62461bcd028152600401808060200182810382526022815260200180612bb36022913960400191505060405180910390fd5b61144d565b600160c01b821061144d5760408051600160e51b62461bcd02815260206004820152601360248201527f496e76616c696420726573657276656449647300000000000000000000000000604482015290519081900360640190fd5b60078054600160401b600160e01b031916600160401b6001600160a01b038616021790819055600183016008556040805167ffffffffffffffff90921682526020820184905280517f5be5961d909b3736a7b784a2d25cea0eb131c6c34ccdf94b2a376819c258ec8a9281900390910190a15060075467ffffffffffffffff1692915050565b600754606090600160401b90046001600160a01b0316331461153f5760408051600160e51b62461bcd02815260206004820152601760248201527f4f6e6c792063616c6c61626c65206279206d696e746572000000000000000000604482015290519081900360640190fd5b8285146115965760408051600160e51b62461bcd02815260206004820152601e60248201527f496e636f6e73697374656e7420706172616d65746572206c656e677468730000604482015290519081900360640190fd5b6040805184815260208086028201019091528380156115bf578160200160208202803883390190505b5060085460075491925067ffffffffffffffff90911660c01b0160005b8481101561165c57818382815181106115f157fe5b602002602001018181525050818060010192505061165483828151811061161457fe5b6020026020010151858a8a8581811061162957fe5b905060200201356001600160581b031689898681811061164557fe5b9050602002013560ff16612465565b6001016115dc565b506001600160c01b031660085595945050505050565b6003602052600090815260409020805460019091015460ff82169161010081046001600160581b031691600160601b9091046001600160a01b03169084565b600081815260036020526040812054600160601b90046001600160a01b031680610ac957604051600160e51b62461bcd028152600401808060200182810382526029815260200180612b8a6029913960400191505060405180910390fd5b60006001600160a01b03821661175957604051600160e51b62461bcd02815260040180806020018281038252602a815260200180612b60602a913960400191505060405180910390fd5b506001600160a01b031660009081526005602052604090205490565b6000546001600160a01b031633146117c55760408051600160e51b62461bcd0281526020600482015260086024820152600160c01b674f6e6c792043454f02604482015290519081900360640190fd5b6117ce81612191565b6117d781612708565b50565b600754600160401b90046001600160a01b031633146118435760408051600160e51b62461bcd02815260206004820152601760248201527f4f6e6c792063616c6c61626c65206279206d696e746572000000000000000000604482015290519081900360640190fd5b60075467ffffffffffffffff1660c01b6001600160c01b03198316146118b35760408051600160e51b62461bcd02815260206004820152601c60248201527f57697a617264206e6f7420696e2063757272656e742073657269657300000000604482015290519081900360640190fd5b6000828152600360205260409020805460ff161561191b5760408051600160e51b62461bcd02815260206004820181905260248201527f416666696e6974792063616e206f6e6c792062652063686f73656e206f6e6365604482015290519081900360640190fd5b805460ff191660ff8316908117825560408051858152602081019290925280517fef597ca22f25aec904866c3228f39dd59d3bc8345b8fd3cbea7ce568c5b1b22a9281900390910190a1505050565b6000546001600160a01b031633146119ba5760408051600160e51b62461bcd0281526020600482015260086024820152600160c01b674f6e6c792043454f02604482015290519081900360640190fd5b6119c381612191565b600154604080516001600160a01b039283168152918316602083015280517f1cd3afc04e6ae479d2b9f74533351b52218c5b2ae4f847f681a5eac514fe11849281900390910190a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b600754600160401b90046001600160a01b03163314611a965760408051600160e51b62461bcd02815260206004820152601760248201527f4f6e6c792063616c6c61626c65206279206d696e746572000000000000000000604482015290519081900360640190fd5b8582148015611aa457508584145b611af85760408051600160e51b62461bcd02815260206004820152601e60248201527f496e636f6e73697374656e7420706172616d65746572206c656e677468730000604482015290519081900360640190fd5b60005b86811015611c85576000888883818110611b1157fe5b600754602091909102929092013592505067ffffffffffffffff1660c01b6001600160c01b0319821614611b8f5760408051600160e51b62461bcd02815260206004820152601d60248201527f57697a61726473206e6f7420696e2063757272656e7420736572696573000000604482015290519081900360640190fd5b6001600160c01b038116611bed5760408051600160e51b62461bcd02815260206004820152601960248201527f57697a617264732069642063616e6e6f74206265207a65726f00000000000000604482015290519081900360640190fd5b6008546001600160c01b03821610611c4f5760408051600160e51b62461bcd02815260206004820152601d60248201527f57697a61726473206e6f7420696e2072657365727665642072616e6765000000604482015290519081900360640190fd5b611c7c8184898986818110611c6057fe5b905060200201356001600160581b031688888781811061164557fe5b50600101611afb565b5050505050505050565b611cd0888786868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061106f92505050565b611c85878684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061106f92505050565b6001600160a01b038216331415611d725760408051600160e51b62461bcd02815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b6001546001600160a01b031681565b611dfa848484610c69565b611e0684848484612772565b611e4457604051600160e51b62461bcd028152600401808060200182810382526032815260200180612aa66032913960400191505060405180910390fd5b50505050565b60085490565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b600080600080611e8c612a7e565b506000858152600360209081526040918290208251608081018452815460ff8116825261010081046001600160581b031693820193909352600160601b9092046001600160a01b031692820183905260010154606082015290611f395760408051600160e51b62461bcd02815260206004820152601560248201527f57697a61726420646f6573206e6f742065786973740000000000000000000000604482015290519081900360640190fd5b60408101516020820151825160609093015191989097509195509350915050565b60006001600160e01b03198216600160e01b6301ffc9a7021480610ac95750506001600160e01b031916600160e01b6380ac58cd021490565b600090815260036020526040902054600160601b90046001600160a01b0316151590565b6000611fc282611f93565b61200057604051600160e51b62461bcd02815260040180806020018281038252602c815260200180612afc602c913960400191505060405180910390fd5b600061200b836116b1565b9050806001600160a01b0316846001600160a01b031614806120465750836001600160a01b031661203b84610ade565b6001600160a01b0316145b8061205657506120568185611e50565b949350505050565b826001600160a01b0316612071826116b1565b6001600160a01b0316146120b957604051600160e51b62461bcd028152600401808060200182810382526029815260200180612c016029913960400191505060405180910390fd5b6001600160a01b03821661210157604051600160e51b62461bcd028152600401808060200182810382526024815260200180612ad86024913960400191505060405180910390fd5b61210a816128a2565b6001600160a01b038381166000818152600560209081526040808320805460001901905593861680835284832080546001019055858352600390915283822080546bffffffffffffffffffffffff16600160601b83021790559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038116158015906121b757506000546001600160a01b03828116911614155b6117d75760408051600160e51b62461bcd02815260206004820152601360248201527f496e76616c69642043454f206164647265737300000000000000000000000000604482015290519081900360640190fd5b60006001600160a01b03841661222357506000611279565b61222c846128dd565b1561237e5761224584600160e11b630b135d3f026128e3565b1561237657604080516020808201869052825180830382018152828401808552815191830191909120600160e11b630b135d3f02909152604483018181526064840194855286516084850152865189956000956001600160a01b03881695631626ba7e95948b9490939260a401918501908083838c5b838110156122d35781810151838201526020016122bb565b50505050905090810190601f1680156123005780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561231e57600080fd5b505afa158015612332573d6000803e3d6000fd5b505050506040513d602081101561234857600080fd5b505190506001600160e01b03198116600160e11b630b135d3f02141561237357600192505050611279565b50505b506000611279565b600080600061238c85612988565b925092509250600060018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012083868660405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561243f573d6000803e3d6000fd5b5050604051601f1901516001600160a01b038a8116911614955050505050509392505050565b6001600160a01b0383166124c35760408051600160e51b62461bcd02815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6124cc84611f93565b156125215760408051600160e51b62461bcd02815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600084116125795760408051600160e51b62461bcd02815260206004820152601260248201527f4e6f203020746f6b656e20616c6c6f7765640000000000000000000000000000604482015290519081900360640190fd5b6000826001600160581b0316116125da5760408051600160e51b62461bcd02815260206004820152601d60248201527f57697a61726420706f776572206d757374206265206e6f6e2d7a65726f000000604482015290519081900360640190fd5b6040805160808101825260ff83811682526001600160581b0385811660208085019182526001600160a01b038981168688018181526000606089018181528e8252600386528a822099518a549751935160ff199098169916989098176bffffffffffffffffffffff0019166101009290971691909102959095176bffffffffffffffffffffffff16600160601b94909216939093021785559251600194850155808252600590925283812080549093019092559151869291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46040805185815260ff831660208201526001600160581b0384168183015290517f3b7fcf44666972972487f1ac302bef03ee0d35027387ba8a897207466a0817259181900360600190a150505050565b600054604080516001600160a01b039283168152918316602083015280517f9d05f170f1d545b1aa21c4a4f79f17ff737f5f020ea1b333d88f29f0bbfa9fc69281900390910190a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b600061277d846128dd565b61278957506001612056565b604051600160e11b630a85bd0102815233600482018181526001600160a01b03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b838110156128065781810151838201526020016127ee565b50505050905090810190601f1680156128335780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561285557600080fd5b505af1158015612869573d6000803e3d6000fd5b505050506040513d602081101561287f57600080fd5b50516001600160e01b031916600160e11b630a85bd010214915050949350505050565b6000818152600460205260409020546001600160a01b0316156117d757600090815260046020526040902080546001600160a01b0319169055565b3b151590565b600080806128fb85600160e01b6301ffc9a702612a0f565b909250905081158061290b575080155b1561291b57600092505050610ac9565b61292d856001600160e01b0319612a0f565b909250905081158061293e57508015155b1561294e57600092505050610ac9565b6129588585612a0f565b909250905060018214801561296d5750806001145b1561297d57600192505050610ac9565b506000949350505050565b600080600083516041146129e65760408051600160e51b62461bcd02815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e6774680000000000000000604482015290519081900360640190fd5b50505060208101516040820151604183015160ff16601b811015612a0857601b015b9193909250565b604080516001600160e01b031983166024808301919091528251808303909101815260449091018252602081810180516001600160e01b0316600160e01b6301ffc9a702178152825193516000808252948594939091908183858b617530fa9051909890975095505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091529056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e496e76616c696420726573657276656449647320666f7220317374207365726965734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4f6e6c79204d696e746572206f7220434f4f2063616e20636c6f73652061205365726965734552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644f6e6c79204d696e746572206f7220434f4f2063616e20736574206d65746164617461a165627a7a72305820f9051f4b625ef0f5d5e2f8daf3cf89c888bf0c1f607887cbf23dac69b8adb1c80029000000000000000000000000d880d895ce716afc1e5e21cb901b5093701842e4

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80635938d97a116100f9578063a096d9f011610097578063b88d4fde11610071578063b88d4fde14610950578063c5ffd6e114610a14578063e985e9c514610a1c578063fac8eafc14610a4a576101c4565b8063a096d9f014610844578063a22cb4651461091a578063b047fb5014610948576101c4565b806388975198116100d357806388975198146106bb57806398d7a414146106e15780639986a0c6146107075780639d1580231461072d576101c4565b80635938d97a1461060f5780636352211e1461066657806370a0823114610683576101c4565b80632d46ed561161016657806342842e0e1161014057806342842e0e1461044d578063430c2081146104835780634616c514146104af57806355fdbeec146104f8576101c4565b80632d46ed561461036f5780632f81b15d146103955780634094099a14610445576101c4565b8063095ea7b3116101a2578063095ea7b3146102455780630a0f81681461027357806323b872dd1461027b5780632738ec3c146102b1576101c4565b806301ffc9a7146101c95780630519ce7914610204578063081812fc14610228575b600080fd5b6101f0600480360360208110156101df57600080fd5b50356001600160e01b031916610aa1565b604080519115158252519081900360200190f35b61020c610acf565b604080516001600160a01b039092168252519081900360200190f35b61020c6004803603602081101561023e57600080fd5b5035610ade565b6102716004803603604081101561025b57600080fd5b506001600160a01b038135169060200135610b43565b005b61020c610c5a565b6102716004803603606081101561029157600080fd5b506001600160a01b03813581169160208101359091169060400135610c69565b610271600480360360408110156102c757600080fd5b810190602081018135600160201b8111156102e157600080fd5b8201836020820111156102f357600080fd5b803590602001918460208302840111600160201b8311171561031457600080fd5b919390929091602081019035600160201b81111561033157600080fd5b82018360208201111561034357600080fd5b803590602001918460208302840111600160201b8311171561036457600080fd5b509092509050610cc1565b6102716004803603602081101561038557600080fd5b50356001600160a01b0316610fac565b610271600480360360608110156103ab57600080fd5b813591602081013591810190606081016040820135600160201b8111156103d157600080fd5b8201836020820111156103e357600080fd5b803590602001918460018302840111600160201b8311171561040457600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061106f945050505050565b610271611106565b6102716004803603606081101561046357600080fd5b506001600160a01b03813581169160208101359091169060400135611252565b6101f06004803603604081101561049957600080fd5b506001600160a01b03813516906020013561126d565b6104db600480360360408110156104c557600080fd5b506001600160a01b038135169060200135611280565b6040805167ffffffffffffffff9092168252519081900360200190f35b6105bf6004803603606081101561050e57600080fd5b810190602081018135600160201b81111561052857600080fd5b82018360208201111561053a57600080fd5b803590602001918460208302840111600160201b8311171561055b57600080fd5b919390929091602081019035600160201b81111561057857600080fd5b82018360208201111561058a57600080fd5b803590602001918460208302840111600160201b831117156105ab57600080fd5b9193509150356001600160a01b03166114d3565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156105fb5781810151838201526020016105e3565b505050509050019250505060405180910390f35b61062c6004803603602081101561062557600080fd5b5035611672565b6040805160ff90951685526001600160581b0390931660208501526001600160a01b03909116838301526060830152519081900360800190f35b61020c6004803603602081101561067c57600080fd5b50356116b1565b6106a96004803603602081101561069957600080fd5b50356001600160a01b031661170f565b60408051918252519081900360200190f35b610271600480360360208110156106d157600080fd5b50356001600160a01b0316611775565b610271600480360360408110156106f757600080fd5b508035906020013560ff166117da565b6102716004803603602081101561071d57600080fd5b50356001600160a01b031661196a565b6102716004803603608081101561074357600080fd5b810190602081018135600160201b81111561075d57600080fd5b82018360208201111561076f57600080fd5b803590602001918460208302840111600160201b8311171561079057600080fd5b919390929091602081019035600160201b8111156107ad57600080fd5b8201836020820111156107bf57600080fd5b803590602001918460208302840111600160201b831117156107e057600080fd5b919390929091602081019035600160201b8111156107fd57600080fd5b82018360208201111561080f57600080fd5b803590602001918460208302840111600160201b8311171561083057600080fd5b9193509150356001600160a01b0316611a2d565b610271600480360360c081101561085a57600080fd5b81359160208101359160408201359160608101359181019060a081016080820135600160201b81111561088c57600080fd5b82018360208201111561089e57600080fd5b803590602001918460018302840111600160201b831117156108bf57600080fd5b919390929091602081019035600160201b8111156108dc57600080fd5b8201836020820111156108ee57600080fd5b803590602001918460018302840111600160201b8311171561090f57600080fd5b509092509050611c8f565b6102716004803603604081101561093057600080fd5b506001600160a01b0381351690602001351515611d11565b61020c611de0565b6102716004803603608081101561096657600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156109a057600080fd5b8201836020820111156109b257600080fd5b803590602001918460018302840111600160201b831117156109d357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611def945050505050565b6106a9611e4a565b6101f060048036036040811015610a3257600080fd5b506001600160a01b0381358116916020013516611e50565b610a6760048036036020811015610a6057600080fd5b5035611e7e565b604080516001600160a01b0390951685526001600160581b03909316602085015260ff909116838301526060830152519081900360800190f35b60006001600160e01b03198216600160e01b6341d4d437021480610ac95750610ac982611f5a565b92915050565b6002546001600160a01b031681565b6000610ae982611f93565b610b2757604051600160e51b62461bcd02815260040180806020018281038252602c815260200180612bd5602c913960400191505060405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610b4e826116b1565b9050806001600160a01b0316836001600160a01b03161415610ba457604051600160e51b62461bcd028152600401808060200182810382526021815260200180612c4f6021913960400191505060405180910390fd5b336001600160a01b0382161480610bc05750610bc08133611e50565b610bfe57604051600160e51b62461bcd028152600401808060200182810382526038815260200180612b286038913960400191505060405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000546001600160a01b031681565b610c733382611fb7565b610cb157604051600160e51b62461bcd028152600401808060200182810382526031815260200180612c706031913960400191505060405180910390fd5b610cbc83838361205e565b505050565b600754600160401b90046001600160a01b0316610d285760408051600160e51b62461bcd02815260206004820152601b60248201527f4e6f207365726965732069732063757272656e746c79206f70656e0000000000604482015290519081900360640190fd5b600754600160401b90046001600160a01b0316331480610d5257506001546001600160a01b031633145b610d9057604051600160e51b62461bcd028152600401808060200182810382526023815260200180612ca16023913960400191505060405180910390fd5b828114610de75760408051600160e51b62461bcd02815260206004820152601e60248201527f496e636f6e73697374656e7420706172616d65746572206c656e677468730000604482015290519081900360640190fd5b60005b83811015610fa5576000858583818110610e0057fe5b9050602002013590506000848484818110610e1757fe5b600754602091909102929092013592505067ffffffffffffffff1660c01b6001600160c01b0319831614610e955760408051600160e51b62461bcd02815260206004820152601d60248201527f57697a61726473206e6f7420696e2063757272656e7420736572696573000000604482015290519081900360640190fd5b60008281526003602052604090206001015415610efc5760408051600160e51b62461bcd02815260206004820152601460248201527f4d6574616461746120616c726561647920736574000000000000000000000000604482015290519081900360640190fd5b80610f515760408051600160e51b62461bcd02815260206004820152601060248201527f496e76616c6964206d6574616461746100000000000000000000000000000000604482015290519081900360640190fd5b6000828152600360209081526040918290206001018390558151838152915184927ff6812173c9728bd3bab2f1a94129341e47af8b8b78e2da481f8c45659d2d59eb92908290030190a25050600101610dea565b5050505050565b6000546001600160a01b03163314610ffc5760408051600160e51b62461bcd0281526020600482015260086024820152600160c01b674f6e6c792043454f02604482015290519081900360640190fd5b61100581612191565b600254604080516001600160a01b039283168152918316602083015280517fe1033d3cc535efc343c53636bdc05c52a44d9e70b089d4ad6e974379f2c651d69281900390910190a1600280546001600160a01b0319166001600160a01b0392909216919091179055565b600061107a846116b1565b905061108781848461220b565b156110925750610cbc565b600061109d85610ade565b90506110aa81858561220b565b156110b6575050610cbc565b60408051600160e51b62461bcd02815260206004820152601160248201527f496e76616c6964207369676e6174757265000000000000000000000000000000604482015290519081900360640190fd5b600754600160401b90046001600160a01b031661116d5760408051600160e51b62461bcd02815260206004820152601b60248201527f4e6f207365726965732069732063757272656e746c79206f70656e0000000000604482015290519081900360640190fd5b600754600160401b90046001600160a01b031633148061119757506001546001600160a01b031633145b6111d557604051600160e51b62461bcd028152600401808060200182810382526025815260200180612c2a6025913960400191505060405180910390fd5b60078054600160401b600160e01b031981169091556040805167ffffffffffffffff9092168252517f05ba38dc3f1ba4a8bd95dbf51dd0f0141267df538cdd31a01819e9929acdce0d9181900360200190a16007805467ffffffffffffffff8082166001011667ffffffffffffffff199091161790556000600855565b610cbc83838360405180602001604052806000815250611def565b60006112798383611fb7565b9392505050565b6001546000906001600160a01b031633146112d35760408051600160e51b62461bcd0281526020600482015260086024820152600160c01b674f6e6c7920434f4f02604482015290519081900360640190fd5b600754600160401b90046001600160a01b03161561133b5760408051600160e51b62461bcd02815260206004820152601860248201527f412073657269657320697320616c7265616479206f70656e0000000000000000604482015290519081900360640190fd5b6001600160a01b0383166113995760408051600160e51b62461bcd02815260206004820152601a60248201527f4d696e74657220616464726573732063616e6e6f742062652030000000000000604482015290519081900360640190fd5b60075467ffffffffffffffff166113f257816117f5146113ed57604051600160e51b62461bcd028152600401808060200182810382526022815260200180612bb36022913960400191505060405180910390fd5b61144d565b600160c01b821061144d5760408051600160e51b62461bcd02815260206004820152601360248201527f496e76616c696420726573657276656449647300000000000000000000000000604482015290519081900360640190fd5b60078054600160401b600160e01b031916600160401b6001600160a01b038616021790819055600183016008556040805167ffffffffffffffff90921682526020820184905280517f5be5961d909b3736a7b784a2d25cea0eb131c6c34ccdf94b2a376819c258ec8a9281900390910190a15060075467ffffffffffffffff1692915050565b600754606090600160401b90046001600160a01b0316331461153f5760408051600160e51b62461bcd02815260206004820152601760248201527f4f6e6c792063616c6c61626c65206279206d696e746572000000000000000000604482015290519081900360640190fd5b8285146115965760408051600160e51b62461bcd02815260206004820152601e60248201527f496e636f6e73697374656e7420706172616d65746572206c656e677468730000604482015290519081900360640190fd5b6040805184815260208086028201019091528380156115bf578160200160208202803883390190505b5060085460075491925067ffffffffffffffff90911660c01b0160005b8481101561165c57818382815181106115f157fe5b602002602001018181525050818060010192505061165483828151811061161457fe5b6020026020010151858a8a8581811061162957fe5b905060200201356001600160581b031689898681811061164557fe5b9050602002013560ff16612465565b6001016115dc565b506001600160c01b031660085595945050505050565b6003602052600090815260409020805460019091015460ff82169161010081046001600160581b031691600160601b9091046001600160a01b03169084565b600081815260036020526040812054600160601b90046001600160a01b031680610ac957604051600160e51b62461bcd028152600401808060200182810382526029815260200180612b8a6029913960400191505060405180910390fd5b60006001600160a01b03821661175957604051600160e51b62461bcd02815260040180806020018281038252602a815260200180612b60602a913960400191505060405180910390fd5b506001600160a01b031660009081526005602052604090205490565b6000546001600160a01b031633146117c55760408051600160e51b62461bcd0281526020600482015260086024820152600160c01b674f6e6c792043454f02604482015290519081900360640190fd5b6117ce81612191565b6117d781612708565b50565b600754600160401b90046001600160a01b031633146118435760408051600160e51b62461bcd02815260206004820152601760248201527f4f6e6c792063616c6c61626c65206279206d696e746572000000000000000000604482015290519081900360640190fd5b60075467ffffffffffffffff1660c01b6001600160c01b03198316146118b35760408051600160e51b62461bcd02815260206004820152601c60248201527f57697a617264206e6f7420696e2063757272656e742073657269657300000000604482015290519081900360640190fd5b6000828152600360205260409020805460ff161561191b5760408051600160e51b62461bcd02815260206004820181905260248201527f416666696e6974792063616e206f6e6c792062652063686f73656e206f6e6365604482015290519081900360640190fd5b805460ff191660ff8316908117825560408051858152602081019290925280517fef597ca22f25aec904866c3228f39dd59d3bc8345b8fd3cbea7ce568c5b1b22a9281900390910190a1505050565b6000546001600160a01b031633146119ba5760408051600160e51b62461bcd0281526020600482015260086024820152600160c01b674f6e6c792043454f02604482015290519081900360640190fd5b6119c381612191565b600154604080516001600160a01b039283168152918316602083015280517f1cd3afc04e6ae479d2b9f74533351b52218c5b2ae4f847f681a5eac514fe11849281900390910190a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b600754600160401b90046001600160a01b03163314611a965760408051600160e51b62461bcd02815260206004820152601760248201527f4f6e6c792063616c6c61626c65206279206d696e746572000000000000000000604482015290519081900360640190fd5b8582148015611aa457508584145b611af85760408051600160e51b62461bcd02815260206004820152601e60248201527f496e636f6e73697374656e7420706172616d65746572206c656e677468730000604482015290519081900360640190fd5b60005b86811015611c85576000888883818110611b1157fe5b600754602091909102929092013592505067ffffffffffffffff1660c01b6001600160c01b0319821614611b8f5760408051600160e51b62461bcd02815260206004820152601d60248201527f57697a61726473206e6f7420696e2063757272656e7420736572696573000000604482015290519081900360640190fd5b6001600160c01b038116611bed5760408051600160e51b62461bcd02815260206004820152601960248201527f57697a617264732069642063616e6e6f74206265207a65726f00000000000000604482015290519081900360640190fd5b6008546001600160c01b03821610611c4f5760408051600160e51b62461bcd02815260206004820152601d60248201527f57697a61726473206e6f7420696e2072657365727665642072616e6765000000604482015290519081900360640190fd5b611c7c8184898986818110611c6057fe5b905060200201356001600160581b031688888781811061164557fe5b50600101611afb565b5050505050505050565b611cd0888786868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061106f92505050565b611c85878684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061106f92505050565b6001600160a01b038216331415611d725760408051600160e51b62461bcd02815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b6001546001600160a01b031681565b611dfa848484610c69565b611e0684848484612772565b611e4457604051600160e51b62461bcd028152600401808060200182810382526032815260200180612aa66032913960400191505060405180910390fd5b50505050565b60085490565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b600080600080611e8c612a7e565b506000858152600360209081526040918290208251608081018452815460ff8116825261010081046001600160581b031693820193909352600160601b9092046001600160a01b031692820183905260010154606082015290611f395760408051600160e51b62461bcd02815260206004820152601560248201527f57697a61726420646f6573206e6f742065786973740000000000000000000000604482015290519081900360640190fd5b60408101516020820151825160609093015191989097509195509350915050565b60006001600160e01b03198216600160e01b6301ffc9a7021480610ac95750506001600160e01b031916600160e01b6380ac58cd021490565b600090815260036020526040902054600160601b90046001600160a01b0316151590565b6000611fc282611f93565b61200057604051600160e51b62461bcd02815260040180806020018281038252602c815260200180612afc602c913960400191505060405180910390fd5b600061200b836116b1565b9050806001600160a01b0316846001600160a01b031614806120465750836001600160a01b031661203b84610ade565b6001600160a01b0316145b8061205657506120568185611e50565b949350505050565b826001600160a01b0316612071826116b1565b6001600160a01b0316146120b957604051600160e51b62461bcd028152600401808060200182810382526029815260200180612c016029913960400191505060405180910390fd5b6001600160a01b03821661210157604051600160e51b62461bcd028152600401808060200182810382526024815260200180612ad86024913960400191505060405180910390fd5b61210a816128a2565b6001600160a01b038381166000818152600560209081526040808320805460001901905593861680835284832080546001019055858352600390915283822080546bffffffffffffffffffffffff16600160601b83021790559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038116158015906121b757506000546001600160a01b03828116911614155b6117d75760408051600160e51b62461bcd02815260206004820152601360248201527f496e76616c69642043454f206164647265737300000000000000000000000000604482015290519081900360640190fd5b60006001600160a01b03841661222357506000611279565b61222c846128dd565b1561237e5761224584600160e11b630b135d3f026128e3565b1561237657604080516020808201869052825180830382018152828401808552815191830191909120600160e11b630b135d3f02909152604483018181526064840194855286516084850152865189956000956001600160a01b03881695631626ba7e95948b9490939260a401918501908083838c5b838110156122d35781810151838201526020016122bb565b50505050905090810190601f1680156123005780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561231e57600080fd5b505afa158015612332573d6000803e3d6000fd5b505050506040513d602081101561234857600080fd5b505190506001600160e01b03198116600160e11b630b135d3f02141561237357600192505050611279565b50505b506000611279565b600080600061238c85612988565b925092509250600060018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012083868660405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561243f573d6000803e3d6000fd5b5050604051601f1901516001600160a01b038a8116911614955050505050509392505050565b6001600160a01b0383166124c35760408051600160e51b62461bcd02815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6124cc84611f93565b156125215760408051600160e51b62461bcd02815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600084116125795760408051600160e51b62461bcd02815260206004820152601260248201527f4e6f203020746f6b656e20616c6c6f7765640000000000000000000000000000604482015290519081900360640190fd5b6000826001600160581b0316116125da5760408051600160e51b62461bcd02815260206004820152601d60248201527f57697a61726420706f776572206d757374206265206e6f6e2d7a65726f000000604482015290519081900360640190fd5b6040805160808101825260ff83811682526001600160581b0385811660208085019182526001600160a01b038981168688018181526000606089018181528e8252600386528a822099518a549751935160ff199098169916989098176bffffffffffffffffffffff0019166101009290971691909102959095176bffffffffffffffffffffffff16600160601b94909216939093021785559251600194850155808252600590925283812080549093019092559151869291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46040805185815260ff831660208201526001600160581b0384168183015290517f3b7fcf44666972972487f1ac302bef03ee0d35027387ba8a897207466a0817259181900360600190a150505050565b600054604080516001600160a01b039283168152918316602083015280517f9d05f170f1d545b1aa21c4a4f79f17ff737f5f020ea1b333d88f29f0bbfa9fc69281900390910190a1600080546001600160a01b0319166001600160a01b0392909216919091179055565b600061277d846128dd565b61278957506001612056565b604051600160e11b630a85bd0102815233600482018181526001600160a01b03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b838110156128065781810151838201526020016127ee565b50505050905090810190601f1680156128335780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561285557600080fd5b505af1158015612869573d6000803e3d6000fd5b505050506040513d602081101561287f57600080fd5b50516001600160e01b031916600160e11b630a85bd010214915050949350505050565b6000818152600460205260409020546001600160a01b0316156117d757600090815260046020526040902080546001600160a01b0319169055565b3b151590565b600080806128fb85600160e01b6301ffc9a702612a0f565b909250905081158061290b575080155b1561291b57600092505050610ac9565b61292d856001600160e01b0319612a0f565b909250905081158061293e57508015155b1561294e57600092505050610ac9565b6129588585612a0f565b909250905060018214801561296d5750806001145b1561297d57600192505050610ac9565b506000949350505050565b600080600083516041146129e65760408051600160e51b62461bcd02815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e6774680000000000000000604482015290519081900360640190fd5b50505060208101516040820151604183015160ff16601b811015612a0857601b015b9193909250565b604080516001600160e01b031983166024808301919091528251808303909101815260449091018252602081810180516001600160e01b0316600160e01b6301ffc9a702178152825193516000808252948594939091908183858b617530fa9051909890975095505050505050565b6040805160808101825260008082526020820181905291810182905260608101919091529056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a207472616e7366657220746f20746865207a65726f20616464726573734552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e496e76616c696420726573657276656449647320666f7220317374207365726965734552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4f6e6c79204d696e746572206f7220434f4f2063616e20636c6f73652061205365726965734552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665644f6e6c79204d696e746572206f7220434f4f2063616e20736574206d65746164617461a165627a7a72305820f9051f4b625ef0f5d5e2f8daf3cf89c888bf0c1f607887cbf23dac69b8adb1c80029

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

000000000000000000000000d880d895ce716afc1e5e21cb901b5093701842e4

-----Decoded View---------------
Arg [0] : _cooAddress (address): 0xD880d895Ce716AfC1E5e21cb901b5093701842e4

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d880d895ce716afc1e5e21cb901b5093701842e4


Deployed Bytecode Sourcemap

35758:24172:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;35758:24172:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44151:180;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;44151:180:0;-1:-1:-1;;;;;;44151:180:0;;:::i;:::-;;;;;;;;;;;;;;;;;;30906:33;;;:::i;:::-;;;;-1:-1:-1;;;;;30906:33:0;;;;;;;;;;;;;;12698:205;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;12698:205:0;;:::i;11991:437::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;11991:437:0;;;;;;;;:::i;:::-;;30288:25;;;:::i;14339:240::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;14339:240:0;;;;;;;;;;;;;;;;;:::i;52201:906::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;52201:906:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;52201:906:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;52201:906:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;52201:906:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;52201:906:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;52201:906:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;52201:906:0;;-1:-1:-1;52201:906:0;-1:-1:-1;52201:906:0;:::i;33512:181::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33512:181:0;-1:-1:-1;;;;;33512:181:0;;:::i;56136:578::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;56136:578:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;56136:578:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;56136:578:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;56136:578:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;56136:578:0;;-1:-1:-1;56136:578:0;;-1:-1:-1;;;;;56136:578:0:i;43734:368::-;;;:::i;15214:136::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;15214:136:0;;;;;;;;;;;;;;;;;:::i;54555:152::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;54555:152:0;;;;;;;;:::i;41518:1749::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;41518:1749:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;48034:894;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;48034:894:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;48034:894:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;48034:894:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;48034:894:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;48034:894:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;48034:894:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;48034:894:0;;-1:-1:-1;48034:894:0;-1:-1:-1;48034:894:0;-1:-1:-1;;;;;48034:894:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;48034:894:0;;;;;;;;;;;;;;;;;9107:46;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;9107:46:0;;:::i;:::-;;;;;;;;;;-1:-1:-1;;;;;9107:46:0;;;;;;;-1:-1:-1;;;;;9107:46:0;;;;;;;;;;;;;;;;;;;;11343:234;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11343:234:0;;:::i;10941:199::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;10941:199:0;-1:-1:-1;;;;;10941:199:0;;:::i;:::-;;;;;;;;;;;;;;;;32599:121;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;32599:121:0;-1:-1:-1;;;;;32599:121:0;;:::i;53786:549::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53786:549:0;;;;;;;;;:::i;33188:173::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33188:173:0;-1:-1:-1;;;;;33188:173:0;;:::i;49682:1865::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;49682:1865:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;49682:1865:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;49682:1865:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;49682:1865:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;49682:1865:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;49682:1865:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;49682:1865:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;49682:1865:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;49682:1865:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;49682:1865:0;;-1:-1:-1;49682:1865:0;-1:-1:-1;49682:1865:0;-1:-1:-1;;;;;49682:1865:0;;:::i;57588:318::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;57588:318:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;57588:318:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;57588:318:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;57588:318:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;57588:318:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;57588:318:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;57588:318:0;;-1:-1:-1;57588:318:0;-1:-1:-1;57588:318:0;:::i;13195:246::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;13195:246:0;;;;;;;;;;:::i;30678:25::-;;;:::i;16058:271::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;16058:271:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;16058:271:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;16058:271:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;16058:271:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;16058:271:0;;-1:-1:-1;16058:271:0;;-1:-1:-1;;;;;16058:271:0:i;37723:103::-;;;:::i;13760:147::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;13760:147:0;;;;;;;;;;:::i;45703:371::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45703:371:0;;:::i;:::-;;;;-1:-1:-1;;;;;45703:371:0;;;;;-1:-1:-1;;;;;45703:371:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;44151:180;44219:4;-1:-1:-1;;;;;;44243:40:0;;-1:-1:-1;;;;;44243:40:0;;:80;;;44287:36;44311:11;44287:23;:36::i;:::-;44236:87;44151:180;-1:-1:-1;;44151:180:0:o;30906:33::-;;;-1:-1:-1;;;;;30906:33:0;;:::o;12698:205::-;12758:7;12786:17;12794:8;12786:7;:17::i;:::-;12778:74;;;;-1:-1:-1;;;;;12778:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12870:25:0;;;;:15;:25;;;;;;-1:-1:-1;;;;;12870:25:0;;12698:205::o;11991:437::-;12056:13;12072:17;12080:8;12072:7;:17::i;:::-;12056:33;;12114:5;-1:-1:-1;;;;;12108:11:0;:2;-1:-1:-1;;;;;12108:11:0;;;12100:57;;;;-1:-1:-1;;;;;12100:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12190:10;-1:-1:-1;;;;;12190:19:0;;;;:58;;;12213:35;12230:5;12237:10;12213:16;:35::i;:::-;12168:164;;;;-1:-1:-1;;;;;12168:164:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12345:25;;;;:15;:25;;;;;;:30;;-1:-1:-1;;;;;;12345:30:0;-1:-1:-1;;;;;12345:30:0;;;;;;;;;12391:29;;12345:25;;12391:29;;;;;;;11991:437;;;:::o;30288:25::-;;;-1:-1:-1;;;;;30288:25:0;;:::o;14339:240::-;14431:40;14450:10;14462:8;14431:18;:40::i;:::-;14423:102;;;;-1:-1:-1;;;;;14423:102:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14538:33;14552:4;14558:2;14562:8;14538:13;:33::i;:::-;14339:240;;;:::o;52201:906::-;39418:12;;-1:-1:-1;;;39418:12:0;;-1:-1:-1;;;;;39418:12:0;39410:66;;;;;-1:-1:-1;;;;;39410:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52336:12;;-1:-1:-1;;;52336:12:0;;-1:-1:-1;;;;;52336:12:0;52322:10;:26;;:54;;-1:-1:-1;52366:10:0;;-1:-1:-1;;;;;52366:10:0;52352;:24;52322:54;52314:102;;;;-1:-1:-1;;;;;52314:102:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52435:35;;;52427:78;;;;;-1:-1:-1;;;;;52427:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52523:9;52518:582;52538:20;;;52518:582;;;52580:17;52600:9;;52610:1;52600:12;;;;;;;;;;;;;52580:32;;52627:23;52653:8;;52662:1;52653:11;;;;;;;52727;;52653;;;;;;;;;;;-1:-1:-1;;52727:11:0;;38119:3;52719:37;-1:-1:-1;;;;;;52690:23:0;;52689:68;52681:110;;;;;-1:-1:-1;;;;;52681:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52859:1;52816:22;;;:11;:22;;;;;:31;;;:45;52808:78;;;;;-1:-1:-1;;;;;52808:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52911:29;52903:58;;;;;-1:-1:-1;;;;;52903:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52978:22;;;;:11;:22;;;;;;;;;:31;;:49;;;53049:39;;;;;;;52990:9;;53049:39;;;;;;;;;-1:-1:-1;;52560:3:0;;52518:582;;;;52201:906;;;;:::o;33512:181::-;31896:10;;-1:-1:-1;;;;;31896:10:0;31882;:24;31874:45;;;;;-1:-1:-1;;;;;31874:45:0;;;;;;;;;;;;-1:-1:-1;;;;;31874:45:0;;;;;;;;;;;;;;;33578:27;33598:6;33578:19;:27::i;:::-;33636:10;;33621:34;;;-1:-1:-1;;;;;33636:10:0;;;33621:34;;;;;;;;;;;;;;;;;;;;;33666:10;:19;;-1:-1:-1;;;;;;33666:19:0;-1:-1:-1;;;;;33666:19:0;;;;;;;;;;33512:181::o;56136:578::-;56317:13;56333:17;56341:8;56333:7;:17::i;:::-;56317:33;;56367:43;56393:5;56400:4;56406:3;56367:25;:43::i;:::-;56363:82;;;56427:7;;;56363:82;56529:16;56548:21;56560:8;56548:11;:21::i;:::-;56529:40;;56586:46;56612:8;56622:4;56628:3;56586:25;:46::i;:::-;56582:85;;;56649:7;;;;56582:85;56679:27;;;-1:-1:-1;;;;;56679:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;43734:368;39418:12;;-1:-1:-1;;;39418:12:0;;-1:-1:-1;;;;;39418:12:0;39410:66;;;;;-1:-1:-1;;;;;39410:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;43826:12;;-1:-1:-1;;;43826:12:0;;-1:-1:-1;;;;;43826:12:0;43812:10;:26;;:54;;-1:-1:-1;43856:10:0;;-1:-1:-1;;;;;43856:10:0;43842;:24;43812:54;43790:131;;;;-1:-1:-1;;;;;43790:131:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43934:12;:25;;-1:-1:-1;;;;;;;;43934:25:0;;;;;43975:24;;;43987:11;;;;43975:24;;;;;;;;;;;;44048:11;:16;;;;;;44063:1;44048:16;;-1:-1:-1;;44048:16:0;;;;;;:11;44075:15;:19;43734:368::o;15214:136::-;15302:40;15319:4;15325:2;15329:8;15302:40;;;;;;;;;;;;:16;:40::i;54555:152::-;54639:4;54663:36;54682:7;54691;54663:18;:36::i;:::-;54656:43;54555:152;-1:-1:-1;;;54555:152:0:o;41518:1749::-;32059:10;;41601:15;;-1:-1:-1;;;;;32059:10:0;32045;:24;32037:45;;;;;-1:-1:-1;;;;;32037:45:0;;;;;;;;;;;;-1:-1:-1;;;;;32037:45:0;;;;;;;;;;;;;;;41637:12;;-1:-1:-1;;;41637:12:0;;-1:-1:-1;;;;;41637:12:0;:26;41629:63;;;;;-1:-1:-1;;;;;41629:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41711:20:0;;41703:59;;;;;-1:-1:-1;;;;;41703:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;41779:11;;;;41775:1120;;42738:11;42753:4;42738:19;42730:66;;;;-1:-1:-1;;;;;42730:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41775:1120;;;-1:-1:-1;;;42837:11:0;:22;42829:54;;;;;-1:-1:-1;;;;;42829:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;43109:12;:21;;-1:-1:-1;;;;;;;;43109:21:0;-1:-1:-1;;;;;;;;43109:21:0;;;;;;;;-1:-1:-1;43159:15:0;;43109:12;43141:33;43192:36;;;43203:11;;;;43192:36;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43248:11:0;;;;41518:1749;;;;:::o;48034:894::-;40032:12;;48188:26;;-1:-1:-1;;;40032:12:0;;-1:-1:-1;;;;;40032:12:0;40018:10;:26;40010:62;;;;;-1:-1:-1;;;;;40010:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48240:34;;;48232:77;;;;;-1:-1:-1;;;;;48232:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48368:32;;;;;;;;;;;;;;;;48382:10;48368:32;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;48368:32:0;-1:-1:-1;48629:15:0;;48596:11;;48356:44;;-1:-1:-1;48596:11:0;;;;38119:3;48588:37;48587:57;48564:20;48657:208;48677:21;;;48657:208;;;48735:12;48720:9;48730:1;48720:12;;;;;;;;;;;;;:27;;;;;48762:14;;;;;;;48793:60;48807:9;48817:1;48807:12;;;;;;;;;;;;;;48821:5;48828:6;;48835:1;48828:9;;;;;;;;;;;;;-1:-1:-1;;;;;48828:9:0;48839:10;;48850:1;48839:13;;;;;;;;;;;;;;;48793;:60::i;:::-;48700:3;;48657:208;;;-1:-1:-1;;;;;;48895:25:0;48877:15;:43;48034:894;;-1:-1:-1;;;;;48034:894:0:o;9107:46::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;9107:46:0;;-1:-1:-1;;;9107:46:0;;;-1:-1:-1;;;;;9107:46:0;;;:::o;11343:234::-;11399:7;11435:21;;;:11;:21;;;;;:27;-1:-1:-1;;;11435:27:0;;-1:-1:-1;;;;;11435:27:0;;11473:73;;;;-1:-1:-1;;;;;11473:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10941:199;10996:7;-1:-1:-1;;;;;11024:19:0;;11016:74;;;;-1:-1:-1;;;;;11016:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;11108:24:0;;;;;:17;:24;;;;;;;10941:199::o;32599:121::-;31896:10;;-1:-1:-1;;;;;31896:10:0;31882;:24;31874:45;;;;;-1:-1:-1;;;;;31874:45:0;;;;;;;;;;;;-1:-1:-1;;;;;31874:45:0;;;;;;;;;;;;;;;32659:27;32679:6;32659:19;:27::i;:::-;32697:15;32705:6;32697:7;:15::i;:::-;32599:121;:::o;53786:549::-;40032:12;;-1:-1:-1;;;40032:12:0;;-1:-1:-1;;;;;40032:12:0;40018:10;:26;40010:62;;;;;-1:-1:-1;;;;;40010:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53920:11;;;;38119:3;53912:37;-1:-1:-1;;;;;;53884:22:0;;53883:67;53875:108;;;;;-1:-1:-1;;;;;53875:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53996:21;54020;;;:11;:21;;;;;54062:15;;:33;:15;:33;54054:78;;;;;-1:-1:-1;;;;;54054:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54174:29;;-1:-1:-1;;54174:29:0;;;;;;;;;54282:45;;;;;;;;;;;;;;;;;;;;;;;;;40083:1;53786:549;;:::o;33188:173::-;31896:10;;-1:-1:-1;;;;;31896:10:0;31882;:24;31874:45;;;;;-1:-1:-1;;;;;31874:45:0;;;;;;;;;;;;-1:-1:-1;;;;;31874:45:0;;;;;;;;;;;;;;;33246:27;33266:6;33246:19;:27::i;:::-;33304:10;;33289:34;;;-1:-1:-1;;;;;33304:10:0;;;33289:34;;;;;;;;;;;;;;;;;;;;;33334:10;:19;;-1:-1:-1;;;;;;33334:19:0;-1:-1:-1;;;;;33334:19:0;;;;;;;;;;33188:173::o;49682:1865::-;40032:12;;-1:-1:-1;;;40032:12:0;;-1:-1:-1;;;;;40032:12:0;40018:10;:26;40010:62;;;;;-1:-1:-1;;;;;40010:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;49917:37;;;:87;;;;-1:-1:-1;49971:33:0;;;49917:87;49895:144;;;;;-1:-1:-1;;;;;49895:144:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50057:9;50052:1488;50072:20;;;50052:1488;;;50114:17;50134:9;;50144:1;50134:12;;;;;;;50209:11;;50134:12;;;;;;;;;;;-1:-1:-1;;50209:11:0;;38119:3;50201:37;-1:-1:-1;;;;;;50172:23:0;;50171:68;50163:110;;;;;-1:-1:-1;;;;;50163:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50297:22:0;;50288:66;;;;;-1:-1:-1;;;;;50288:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51405:15;;-1:-1:-1;;;;;51379:22:0;;51378:42;51370:84;;;;;-1:-1:-1;;;;;51370:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51471:57;51485:9;51496:5;51503:6;;51510:1;51503:9;;;;;;;;;;;;;-1:-1:-1;;;;;51503:9:0;51514:10;;51525:1;51514:13;;;;;;51471:57;-1:-1:-1;50094:3:0;;50052:1488;;;;49682:1865;;;;;;;:::o;57588:318::-;57809:39;57825:9;57836:5;57843:4;;57809:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;57809:15:0;;-1:-1:-1;;;57809:39:0:i;:::-;57859;57875:9;57886:5;57893:4;;57859:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;57859:15:0;;-1:-1:-1;;;57859:39:0:i;13195:246::-;-1:-1:-1;;;;;13275:16:0;;13281:10;13275:16;;13267:54;;;;;-1:-1:-1;;;;;13267:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;13351:10;13332:30;;;;:18;:30;;;;;;;;-1:-1:-1;;;;;13332:34:0;;;;;;;;;;;;:45;;-1:-1:-1;;13332:45:0;;;;;;;;;;13393:40;;;;;;;13332:34;;13351:10;13393:40;;;;;;;;;;;13195:246;;:::o;30678:25::-;;;-1:-1:-1;;;;;30678:25:0;;:::o;16058:271::-;16166:32;16179:4;16185:2;16189:8;16166:12;:32::i;:::-;16217:49;16240:4;16246:2;16250:8;16260:5;16217:22;:49::i;:::-;16209:112;;;;-1:-1:-1;;;;;16209:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16058:271;;;;:::o;37723:103::-;37803:15;;37723:103;:::o;13760:147::-;-1:-1:-1;;;;;13864:25:0;;;13840:4;13864:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;13760:147::o;45703:371::-;45755:13;45770:18;45790:14;45806:16;45835:20;;:::i;:::-;-1:-1:-1;45858:15:0;;;;:11;:15;;;;;;;;;45835:38;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45835:38:0;;;;;;;;-1:-1:-1;;;45835:38:0;;;-1:-1:-1;;;;;45835:38:0;;;;;;;;;;;;;;;45884:60;;;;;-1:-1:-1;;;;;45884:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;45999:12;;;;46013:18;;;;46033:15;;46050;;;;;45999:12;;46013:18;;-1:-1:-1;46033:15:0;;-1:-1:-1;46050:15:0;-1:-1:-1;45703:371:0;-1:-1:-1;;45703:371:0:o;10489:231::-;10557:4;-1:-1:-1;;;;;;10594:46:0;;-1:-1:-1;;;;;10594:46:0;;:108;;-1:-1:-1;;;;;;;;10667:35:0;-1:-1:-1;;;;;10667:35:0;;10489:231::o;16518:163::-;16576:4;16609:21;;;:11;:21;;;;;:27;-1:-1:-1;;;16609:27:0;;-1:-1:-1;;;;;16609:27:0;16654:19;;;16518:163::o;17033:337::-;17119:4;17144:17;17152:8;17144:7;:17::i;:::-;17136:74;;;;-1:-1:-1;;;;;17136:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17221:13;17237:17;17245:8;17237:7;:17::i;:::-;17221:33;;17284:5;-1:-1:-1;;;;;17273:16:0;:7;-1:-1:-1;;;;;17273:16:0;;:52;;;;17318:7;-1:-1:-1;;;;;17293:32:0;:21;17305:8;17293:11;:21::i;:::-;-1:-1:-1;;;;;17293:32:0;;17273:52;:88;;;;17329:32;17346:5;17353:7;17329:16;:32::i;:::-;17265:97;17033:337;-1:-1:-1;;;;17033:337:0:o;20032:450::-;20148:4;-1:-1:-1;;;;;20127:25:0;:17;20135:8;20127:7;:17::i;:::-;-1:-1:-1;;;;;20127:25:0;;20119:79;;;;-1:-1:-1;;;;;20119:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20217:16:0;;20209:65;;;;-1:-1:-1;;;;;20209:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20287:24;20302:8;20287:14;:24::i;:::-;-1:-1:-1;;;;;20324:23:0;;;;;;;:17;:23;;;;;;;;:25;;-1:-1:-1;;20324:25:0;;;20360:21;;;;;;;;;:23;;-1:-1:-1;20360:23:0;;;20396:21;;;:11;:21;;;;;;:32;;;;-1:-1:-1;;;20396:32:0;;;;;20446:28;;20396:21;;20360;20324:23;20446:28;;;20032:450;;;:::o;32273:175::-;-1:-1:-1;;;;;32358:27:0;;;;;;:58;;-1:-1:-1;32406:10:0;;-1:-1:-1;;;;;32389:27:0;;;32406:10;;32389:27;;32358:58;32350:90;;;;;-1:-1:-1;;;;;32350:90:0;;;;;;;;;;;;;;;;;;;;;;;;;;;58282:1643;58410:4;-1:-1:-1;;;;;58436:28:0;;58432:1486;;-1:-1:-1;58577:5:0;58570:12;;58432:1486;58604:34;58623:14;58604:18;:34::i;:::-;58600:1318;;;58981:70;59012:14;-1:-1:-1;;;;;58981:30:0;:70::i;:::-;58977:395;;;59211:22;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;59211:22:0;;;;;;59201:33;;;;;;;;;-1:-1:-1;;;;;59180:66:0;;;;;;;;;;;;;;;;;;;;;;;59130:14;;59108:11;;-1:-1:-1;;;;;59180:20:0;;;;;59201:33;59236:9;;59180:66;;;;;;;;;;;;59108:11;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;59180:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59180:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59180:66:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59180:66:0;;-1:-1:-1;;;;;;;59269:32:0;;-1:-1:-1;;;;;59269:32:0;59265:92;;;59333:4;59326:11;;;;;;59265:92;58977:395;;;-1:-1:-1;59395:5:0;59388:12;;58600:1318;59558:9;59569;59580:7;59591:35;59616:9;59591:24;:35::i;:::-;59557:69;;;;;;59641:14;59658:89;59731:4;59678:58;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;59678:58:0;;;59668:69;;;;;;59739:1;59742;59745;59658:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;59658:89:0;;-1:-1:-1;;59658:89:0;;-1:-1:-1;;;;;59881:24:0;;;;;;;-1:-1:-1;;;;;;58282:1643:0;;;;;:::o;17925:773::-;-1:-1:-1;;;;;18045:19:0;;18037:64;;;;;-1:-1:-1;;;;;18037:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18121:17;18129:8;18121:7;:17::i;:::-;18120:18;18112:59;;;;;-1:-1:-1;;;;;18112:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;18201:1;18190:8;:12;18182:43;;;;;-1:-1:-1;;;;;18182:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;18258:1;18244:11;-1:-1:-1;;;;;18244:15:0;;18236:57;;;;;-1:-1:-1;;;;;18236:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;18361:144;;;;;;;;;;;;;;-1:-1:-1;;;;;18361:144:0;;;;;;;;;;-1:-1:-1;;;;;18361:144:0;;;;;;;;;-1:-1:-1;18361:144:0;;;;;;18337:21;;;:11;:21;;;;;:168;;;;;;;;-1:-1:-1;;18337:168:0;;;;;;;;;-1:-1:-1;;18337:168:0;;;;;;;;;;;;;;;;-1:-1:-1;;;18337:168:0;;;;;;;;;;;;;-1:-1:-1;18337:168:0;;;;18518:24;;;:17;:24;;;;;;:26;;;;;;;;18590:37;;18337:21;;18361:144;-1:-1:-1;18590:37:0;;-1:-1:-1;;18590:37:0;18643:47;;;;;;;;;;;;;-1:-1:-1;;;;;18643:47:0;;;;;;;;;;;;;;;;;17925:773;;;;:::o;32908:129::-;32980:10;;32965:34;;;-1:-1:-1;;;;;32980:10:0;;;32965:34;;;;;;;;;;;;;;;;;;;;;33010:10;:19;;-1:-1:-1;;;;;;33010:19:0;-1:-1:-1;;;;;33010:19:0;;;;;;;;;;32908:129::o;21008:357::-;21131:4;21158:14;21169:2;21158:10;:14::i;:::-;21153:59;;-1:-1:-1;21196:4:0;21189:11;;21153:59;21240:71;;-1:-1:-1;;;;;21240:71:0;;21277:10;21240:71;;;;;;-1:-1:-1;;;;;21240:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;21224:13;;21240:36;;;;;;21277:10;;21289:4;;21295:8;;21305:5;;21240:71;;;;;;;;;;;21224:13;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;21240:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21240:71:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;21240:71:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21240:71:0;-1:-1:-1;;;;;;21330:26:0;-1:-1:-1;;;;;21330:26:0;;-1:-1:-1;;21008:357:0;;;;;;:::o;21512:178::-;21614:1;21577:25;;;:15;:25;;;;;;-1:-1:-1;;;;;21577:25:0;:39;21573:110;;21669:1;21633:25;;;:15;:25;;;;;:38;;-1:-1:-1;;;;;;21633:38:0;;;21512:178::o;7013:678::-;7585:20;7675:8;;;7013:678::o;1377:729::-;1532:4;;;1627:44;1639:9;-1:-1:-1;;;;;1627:11:0;:44::i;:::-;1607:64;;-1:-1:-1;1607:64:0;-1:-1:-1;1687:12:0;;;1686:31;;-1:-1:-1;1705:11:0;;1686:31;1682:76;;;1741:5;1734:12;;;;;;1682:76;1790:45;1802:9;-1:-1:-1;;;;;;1790:11:0;:45::i;:::-;1770:65;;-1:-1:-1;1770:65:0;-1:-1:-1;1851:12:0;;;1850:31;;-1:-1:-1;1869:11:0;;;1850:31;1846:76;;;1905:5;1898:12;;;;;;1846:76;1954:36;1966:9;1977:12;1954:11;:36::i;:::-;1934:56;;-1:-1:-1;1934:56:0;-1:-1:-1;2017:1:0;2006:12;;2005:31;;;;;2024:6;2034:1;2024:11;2005:31;2001:75;;;2060:4;2053:11;;;;;;2001:75;-1:-1:-1;2093:5:0;;1377:729;-1:-1:-1;;;;1377:729:0:o;34009:901::-;34081:9;34092;34103:7;34166:9;:16;34186:2;34166:22;34158:59;;;;;-1:-1:-1;;;;;34158:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;34445:2:0;34430:18;;34424:25;34489:2;34474:18;;34468:25;34537:2;34522:18;;34516:25;34543:3;34512:35;34578:2;34574:6;;34570:141;;;34602:2;34597:7;34570:141;34009:901;;;;;:::o;2114:1110::-;2365:58;;;-1:-1:-1;;;;;;2365:58:0;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;2365:58:0;;;;;;;25:18:-1;;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;179:29;160:49;;2658:20:0;;2708:11;;2264:15;2795:19;;;2264:15;;;2365:58;2658:20;;2708:11;;2658:20;25:18:-1;2923:9:0;2870:5;2841:302;3169:13;;2830:313;;3169:13;;-1:-1:-1;2502:715:0;-1:-1:-1;;;;;;2502:715:0:o;35758:24172::-;;;;;;;;;-1:-1:-1;35758:24172:0;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

bzzr://f9051f4b625ef0f5d5e2f8daf3cf89c888bf0c1f607887cbf23dac69b8adb1c8
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.