ETH Price: $3,454.00 (+1.63%)

Token

Pasteurized Cheeze Wizard ()
 

Overview

Max Total Supply

0 Pasteurized Cheeze Wizard

Holders

1,378

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
blockbird.eth
Balance
1 Pasteurized Cheeze Wizard
0x6B67623ff56c10d9dcFc2152425f90285fC74DDD
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.