false
false

Contract Address Details

0xcd59c690ddcd7bfe2eab55d01d2a9517df07fcdf

Contract Name
GemsImplementation
Creator
0x4cbbe9–5bb1f1 at 0x591c13–d9072d
Implementation
0x0000000000000000000000000000000000000000
Balance
0 Xai ( )
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
44910382
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
GemsImplementation




Optimization enabled
true
Compiler version
v0.8.19+commit.7dd6d404




Optimization runs
200
EVM Version
paris




Verified at
2024-06-11T23:33:40.651998Z

src/implementations/GemsImplementation.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {CutERC721Diamond} from '../../lib/@lagunagames/cu-common-tokens/src/implementation/CutERC721Diamond.sol';
import {IGem} from '../interfaces/IGem.sol';

/// @title Dummy "implementation" contract for LG Diamond interface for ERC-1967 compatibility
/// @dev adapted from https://github.com/zdenham/diamond-etherscan?tab=readme-ov-file
/// @dev This interface is used internally to call endpoints on a deployed diamond cluster.
contract GemsImplementation is CutERC721Diamond {
    event GemCreated(
        uint256 indexed requestId,
        uint256 indexed tokenId,
        address owner,
        string name,
        address indexed signer,
        uint256[] parameters
    );

    function adminTerminusInfo() external view returns (address, uint256) {}

    function changeAdminTerminusInfo(address adminTerminusAddress, uint256 adminTerminusPoolID) external {}

    function getAllGemsByOwner(
        address _owner,
        uint32 _pageNumber
    ) external view returns (uint256[] memory tokenIds, bool moreEntriesExist) {}

    function mintMessageHash(
        address to,
        uint256 tokenId,
        string calldata name,
        uint256[] calldata bonusesArray,
        uint256 requestId,
        uint256 blockDeadline
    ) public view virtual returns (bytes32) {}

    function mintWithSignature(
        // requestId is not used as part of any idempotence logic - users will not be able to mint a gem that
        // was already minted anyway - the tokenId enforce all constraints.
        // requestId is simply used so that the gamer server can track the completion of signed workflows.
        // It *is* an indexed field of the GemCreated event.
        address to,
        uint256 tokenId,
        string calldata name,
        uint256[] calldata bonusesArray,
        address signer,
        uint256 requestId,
        uint256 blockDeadline,
        bytes calldata signature
    ) public {}

    function transferToUnicornContract(uint256[] calldata tokenIds) external {}

    /// @notice Returns true if the gem with the given tokenId has been minted.
    /// @param tokenId The ID of the gem to check.
    function gemMinted(uint256 tokenId) external view returns (bool) {}

    /// @notice Returns the name of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function gemName(uint256 tokenId) external view returns (string memory) {}

    /// @notice Returns the rarity of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function gemRarity(uint256 tokenId) external view returns (uint256) {}

    /// @notice Returns the number of bonuses of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function gemNumBonuses(uint256 tokenId) external view returns (uint256) {}

    /// @notice Returns the type of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function gemType(uint256 tokenId) external view returns (string memory) {}

    /// @notice Returns the bonuses of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function bonuses(uint256 tokenId) external view returns (IGem.GemBonuses memory) {}

    /// @notice Returns the metadata of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function metadataJSON(uint256 tokenId) external view returns (string memory) {}
}
        

lib/@lagunagames/cu-common-tokens/lib/@lagunagames/lg-diamond-template/src/diamond/CutDiamond.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IDiamondCut} from '../interfaces/IDiamondCut.sol';
import {IDiamondLoupe} from '../interfaces/IDiamondLoupe.sol';
import {IERC165} from '../interfaces/IERC165.sol';
import {LibSupportsInterface} from '../libraries/LibSupportsInterface.sol';

/// @title Dummy "implementation" contract for LG Diamond interface for ERC-1967 compatibility
/// @dev adapted from https://github.com/zdenham/diamond-etherscan?tab=readme-ov-file
/// @dev This interface is used internally to call endpoints on a deployed diamond cluster.
contract CutDiamond is 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.
    /// @return `true` if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
        return (interfaceID == type(IERC165).interfaceId);
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(
        IDiamondCut.FacetCut[] calldata _diamondCut,
        address _init,
        bytes calldata _calldata
    ) external {}

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @dev This is a convenience implementation of the above
    /// @param _diamondCut Contains the facet addresses and function selectors
    function diamondCut(IDiamondCut.FacetCut[] calldata _diamondCut) external {}

    /// @notice Removes one selector from the Diamond, using DiamondCut
    /// @param selector - The byte4 signature for a method selector to remove
    /// @custom:emits FacetCutAction
    function cutSelector(bytes4 selector) external {}

    /// @notice Removes one selector from the Diamond, using removeFunction()
    /// @param selector - The byte4 signature for a method selector to remove
    function deleteSelector(bytes4 selector) external {}

    /// @notice Removes many selectors from the Diamond, using DiamondCut
    /// @param selectors - Array of byte4 signatures for method selectors to remove
    /// @custom:emits FacetCutAction
    function cutSelectors(bytes4[] memory selectors) external {}

    /// @notice Removes many selectors from the Diamond, using removeFunctions()
    /// @param selectors - Array of byte4 signatures for method selectors to remove
    function deleteSelectors(bytes4[] memory selectors) external {}

    /// @notice Removes any selectors from the Diamond that come from a target
    /// @notice contract address, using DiamondCut.
    /// @param facet - The address of the Facet smart contract to remove
    /// @custom:emits FacetCutAction
    function cutFacet(address facet) external {}

    /// @notice Gets all facets and their selectors.
    /// @return facets_ Facet
    function facets() external view returns (IDiamondLoupe.Facet[] memory facets_) {}

    /// @notice Gets all the function selectors provided by a facet.
    /// @param _facet The facet address.
    /// @return facetFunctionSelectors_
    function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_) {}

    /// @notice Get all the facet addresses used by a diamond.
    /// @return facetAddresses_
    function facetAddresses() external view returns (address[] memory facetAddresses_) {}

    /// @notice Gets the facet that supports the given selector.
    /// @dev If facet is not found return address(0).
    /// @param _functionSelector The function selector.
    /// @return facetAddress_ The facet address.
    function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_) {}

    /// @notice Get the address of the owner
    /// @return The address of the owner.
    function owner() external view returns (address) {}

    /// @notice Set the address of the new owner of the contract
    /// @dev Set _newOwner to address(0) to renounce any ownership.
    /// @param _newOwner The address of the new owner of the contract
    function transferOwnership(address _newOwner) external {}

    /// @notice Set the dummy "implementation" contract address
    /// @custom:emits Upgraded
    function setImplementation(address _implementation) external {}

    /// @notice Get the dummy "implementation" contract address
    /// @return The dummy "implementation" contract address
    function implementation() external view returns (address) {}

    /// @notice Set whether an interface is implemented
    /// @dev Only the contract owner can call this function
    /// @param interfaceID The interface identifier, as specified in ERC-165
    /// @param implemented `true` if the contract implements `interfaceID`
    function setSupportsInterface(bytes4 interfaceID, bool implemented) external {}

    /// @notice Set a list of interfaces as implemented or not
    /// @dev Only the contract owner can call this function
    /// @param interfaceIDs The interface identifiers, as specified in ERC-165
    /// @param allImplemented `true` if the contract implements all interfaces
    function setSupportsInterfaces(bytes4[] calldata interfaceIDs, bool allImplemented) external {}

    /// @notice Returns a list of interfaces that have (ever) been supported
    /// @return The list of interfaces
    function interfaces() external view returns (LibSupportsInterface.KnownInterface[] memory) {}
}
          

lib/@solidstate/contracts/interfaces/IERC165.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC165Internal } from './IERC165Internal.sol';

/**
 * @title ERC165 interface registration interface
 * @dev see https://eips.ethereum.org/EIPS/eip-165
 */
interface IERC165 is IERC165Internal {
    /**
     * @notice query whether contract has registered support for given interface
     * @param interfaceId interface id
     * @return bool whether interface is supported
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
          

lib/@solidstate/contracts/interfaces/IERC165Internal.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title ERC165 interface registration interface
 */
interface IERC165Internal {

}
          

lib/@solidstate/contracts/interfaces/IERC721Internal.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Partial ERC721 interface needed by internal functions
 */
interface IERC721Internal {
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );

    event Approval(
        address indexed owner,
        address indexed operator,
        uint256 indexed tokenId
    );

    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );
}
          

lib/@solidstate/contracts/token/ERC721/ISolidStateERC721.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC721Base } from './base/IERC721Base.sol';
import { IERC721Enumerable } from './enumerable/IERC721Enumerable.sol';
import { IERC721Metadata } from './metadata/IERC721Metadata.sol';

interface ISolidStateERC721 is IERC721Base, IERC721Enumerable, IERC721Metadata {
    error SolidStateERC721__PayableApproveNotSupported();
    error SolidStateERC721__PayableTransferNotSupported();
}
          

lib/@solidstate/contracts/token/ERC721/base/IERC721Base.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC721 } from '../../../interfaces/IERC721.sol';
import { IERC721BaseInternal } from './IERC721BaseInternal.sol';

/**
 * @title ERC721 base interface
 */
interface IERC721Base is IERC721BaseInternal, IERC721 {

}
          

lib/@solidstate/contracts/interfaces/IERC721.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC165 } from './IERC165.sol';
import { IERC721Internal } from './IERC721Internal.sol';

/**
 * @title ERC721 interface
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721 is IERC721Internal, IERC165 {
    /**
     * @notice query the balance of given address
     * @return balance quantity of tokens held
     */
    function balanceOf(address account) external view returns (uint256 balance);

    /**
     * @notice query the owner of given token
     * @param tokenId token to query
     * @return owner token owner
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     * @param data data payload
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external payable;

    /**
     * @notice transfer token between given addresses, without checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @notice grant approval to given account to spend token
     * @param operator address to be approved
     * @param tokenId token to approve
     */
    function approve(address operator, uint256 tokenId) external payable;

    /**
     * @notice get approval status for given token
     * @param tokenId token to query
     * @return operator address approved to spend token
     */
    function getApproved(
        uint256 tokenId
    ) external view returns (address operator);

    /**
     * @notice grant approval to or revoke approval from given account to spend all tokens held by sender
     * @param operator address to be approved
     * @param status approval status
     */
    function setApprovalForAll(address operator, bool status) external;

    /**
     * @notice query approval status of given operator with respect to given address
     * @param account address to query for approval granted
     * @param operator address to query for approval received
     * @return status whether operator is approved to spend tokens held by account
     */
    function isApprovedForAll(
        address account,
        address operator
    ) external view returns (bool status);
}
          

lib/@lagunagames/cu-common-tokens/lib/@lagunagames/lg-diamond-template/src/interfaces/IDiamondCut.sol

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/

interface IDiamondCut {
    enum FacetCutAction {
        Add,
        Replace,
        Remove
    }
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external;

    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}
          

lib/@lagunagames/cu-common-tokens/lib/@lagunagames/lg-diamond-template/src/interfaces/IDiamondLoupe.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

// Adapted from the Diamond 3 reference implementation by Nick Mudge:
// https://github.com/mudgen/diamond-3-hardhat

// A loupe is a small magnifying glass used to look at diamonds.
// These functions look at diamonds
interface IDiamondLoupe {
    /// These functions are expected to be called frequently
    /// by tools.

    struct Facet {
        address facetAddress;
        bytes4[] functionSelectors;
    }

    /// @notice Gets all facet addresses and their four byte function selectors.
    /// @return facets_ Facet
    function facets() external view returns (Facet[] memory facets_);

    /// @notice Gets all the function selectors supported by a specific facet.
    /// @param _facet The facet address.
    /// @return facetFunctionSelectors_
    function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);

    /// @notice Get all the facet addresses used by a diamond.
    /// @return facetAddresses_
    function facetAddresses() external view returns (address[] memory facetAddresses_);

    /// @notice Gets the facet that supports the given selector.
    /// @dev If facet is not found return address(0).
    /// @param _functionSelector The function selector.
    /// @return facetAddress_ The facet address.
    function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
}
          

lib/@lagunagames/cu-common-tokens/lib/@lagunagames/lg-diamond-template/src/interfaces/IERC165.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/// @title ERC-165 Standard Interface Detection
/// @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.
    /// @return `true` if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
          

lib/@lagunagames/cu-common-tokens/lib/@lagunagames/lg-diamond-template/src/libraries/LibContractOwner.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/// @title Library for the common LG implementation of ERC-173 Contract Ownership Standard
/// @author [email protected]
/// @custom:storage-location erc1967:eip1967.proxy.admin
library LibContractOwner {
    error CallerIsNotContractOwner();

    /// @notice This emits when ownership of a contract changes.
    /// @dev ERC-173
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /// @notice Emitted when the admin account has changed.
    /// @dev ERC-1967
    event AdminChanged(address previousAdmin, address newAdmin);

    //  @dev Standard storage slot for the ERC-1967 admin address
    //  @dev bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
    bytes32 private constant ADMIN_SLOT_POSITION = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    struct LibOwnerStorage {
        address contractOwner;
    }

    /// @notice Storage slot for Contract Owner state data
    function ownerStorage() internal pure returns (LibOwnerStorage storage storageSlot) {
        bytes32 position = ADMIN_SLOT_POSITION;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            storageSlot.slot := position
        }
    }

    /// @notice Sets the contract owner
    /// @param newOwner The new owner
    /// @custom:emits OwnershipTransferred
    function setContractOwner(address newOwner) internal {
        LibOwnerStorage storage ls = ownerStorage();
        address previousOwner = ls.contractOwner;
        ls.contractOwner = newOwner;
        emit OwnershipTransferred(previousOwner, newOwner);
        emit AdminChanged(previousOwner, newOwner);
    }

    /// @notice Gets the contract owner wallet
    /// @return owner The contract owner
    function contractOwner() internal view returns (address owner) {
        owner = ownerStorage().contractOwner;
    }

    /// @notice Ensures that the caller is the contract owner, or throws an error.
    /// @custom:throws LibAccess: Must be contract owner
    function enforceIsContractOwner() internal view {
        if (msg.sender != ownerStorage().contractOwner) revert CallerIsNotContractOwner();
    }
}
          

lib/@lagunagames/cu-common-tokens/lib/@lagunagames/lg-diamond-template/src/libraries/LibSupportsInterface.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

import {LibContractOwner} from '../libraries/LibContractOwner.sol';

/// @title Library for the common LG implementation of ERC-165
/// @author [email protected]
/// @custom:storage-location erc7201:games.laguna.LibSupportsInterface
library LibSupportsInterface {
    bytes32 public constant SUPPORTS_INTERFACE_STORAGE_POSITION =
        keccak256(abi.encode(uint256(keccak256('games.laguna.LibSupportsInterface')) - 1)) & ~bytes32(uint256(0xff));

    struct KnownInterface {
        bytes4 selector;
        bool supported;
    }

    struct SupportsInterfaceStorage {
        mapping(bytes4 selector => bool supported) supportedInterfaces;
        bytes4[] interfaces;
    }

    /// @notice Storage slot for SupportsInterface state data
    function supportsInterfaceStorage() internal pure returns (SupportsInterfaceStorage storage storageSlot) {
        bytes32 position = SUPPORTS_INTERFACE_STORAGE_POSITION;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            storageSlot.slot := position
        }
    }

    /// @notice Checks if a contract implements an interface
    /// @param _interfaceId Interface ID to check
    /// @return true if the contract implements the interface
    function supportsInterface(bytes4 _interfaceId) internal view returns (bool) {
        return supportsInterfaceStorage().supportedInterfaces[_interfaceId];
    }

    /// @notice Sets whether a contract implements an interface
    /// @param _interfaceId Interface ID to set
    /// @param _implemented true if the contract implements the interface
    function setSupportsInterface(bytes4 _interfaceId, bool _implemented) internal {
        SupportsInterfaceStorage storage s = supportsInterfaceStorage();

        if (_implemented && !s.supportedInterfaces[_interfaceId]) {
            s.interfaces.push(_interfaceId);
        }

        s.supportedInterfaces[_interfaceId] = _implemented;
    }

    /// @notice Returns the list of interfaces this contract has supported, and whether they are supported currently.
    /// @return The list of interfaces
    function getKnownInterfaces() internal view returns (KnownInterface[] memory) {
        SupportsInterfaceStorage storage s = supportsInterfaceStorage();
        KnownInterface[] memory interfaces = new KnownInterface[](s.interfaces.length);
        for (uint i = 0; i < s.interfaces.length; ++i) {
            interfaces[i] = KnownInterface({
                selector: s.interfaces[i],
                supported: s.supportedInterfaces[s.interfaces[i]]
            });
        }
        return interfaces;
    }

    /// @notice Calculate the interface ID for a list of function selectors
    /// @dev Per ERC-165: "We define the interface identifier as the XOR of all function selectors in the interface"
    /// @param functionSelectors The list of function selectors in the interface
    /// @return interfaceId The ERC-165 interface ID
    function calculateInterfaceId(bytes4[] memory functionSelectors) internal pure returns (bytes4 interfaceId) {
        for (uint256 i = 0; i < functionSelectors.length; ++i) {
            interfaceId ^= functionSelectors[i];
        }
    }
}
          

lib/@lagunagames/cu-common-tokens/src/implementation/CutERC721Diamond.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {CutDiamond} from '../../lib/@lagunagames/lg-diamond-template/src/diamond/CutDiamond.sol';
import {ERC721Fragment} from './ERC721Fragment.sol';

/// @title Dummy "implementation" contract for LG Diamond interface for ERC-1967 compatibility
/// @dev adapted from https://github.com/zdenham/diamond-etherscan?tab=readme-ov-file
/// @dev This interface is used internally to call endpoints on a deployed diamond cluster.
contract CutERC721Diamond is CutDiamond, ERC721Fragment {

}
          

lib/@lagunagames/cu-common-tokens/src/implementation/ERC721Fragment.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/// @title Dummy "implementation" contract for LG Diamond interface for ERC-1967 compatibility
/// @dev adapted from https://github.com/zdenham/diamond-etherscan?tab=readme-ov-file
/// @dev This interface is used internally to call endpoints on a deployed diamond cluster.
contract ERC721Fragment {
    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance) {}

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external {}

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

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

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

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

    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory) {}

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

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

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256) {}

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

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

    /**
     * @dev Returns the URI for the contract level collection.
     * @dev See https://docs.opensea.io/docs/contract-level-metadata
     */
    function contractURI() external view returns (string memory) {}

    /**
     * @dev Reference URI for the NFT license file hosted on Arweave permaweb.
     */
    function license() external view returns (string memory) {}
}
          

lib/@solidstate/contracts/token/ERC721/base/IERC721BaseInternal.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC721Internal } from '../../../interfaces/IERC721Internal.sol';

/**
 * @title ERC721 base interface
 */
interface IERC721BaseInternal is IERC721Internal {
    error ERC721Base__NotOwnerOrApproved();
    error ERC721Base__SelfApproval();
    error ERC721Base__BalanceQueryZeroAddress();
    error ERC721Base__ERC721ReceiverNotImplemented();
    error ERC721Base__InvalidOwner();
    error ERC721Base__MintToZeroAddress();
    error ERC721Base__NonExistentToken();
    error ERC721Base__NotTokenOwner();
    error ERC721Base__TokenAlreadyMinted();
    error ERC721Base__TransferToZeroAddress();
}
          

lib/@solidstate/contracts/token/ERC721/enumerable/IERC721Enumerable.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

interface IERC721Enumerable {
    /**
     * @notice get total token supply
     * @return total supply
     */
    function totalSupply() external view returns (uint256);

    /**
     * @notice get token of given owner at given internal storage index
     * @param owner token holder to query
     * @param index position in owner's token list to query
     * @return tokenId id of retrieved token
     */
    function tokenOfOwnerByIndex(
        address owner,
        uint256 index
    ) external view returns (uint256 tokenId);

    /**
     * @notice get token at given internal storage index
     * @param index position in global token list to query
     * @return tokenId id of retrieved token
     */
    function tokenByIndex(
        uint256 index
    ) external view returns (uint256 tokenId);
}
          

lib/@solidstate/contracts/token/ERC721/metadata/IERC721Metadata.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC721MetadataInternal } from './IERC721MetadataInternal.sol';

/**
 * @title ERC721Metadata interface
 */
interface IERC721Metadata is IERC721MetadataInternal {
    /**
     * @notice get token name
     * @return token name
     */
    function name() external view returns (string memory);

    /**
     * @notice get token symbol
     * @return token symbol
     */
    function symbol() external view returns (string memory);

    /**
     * @notice get generated URI for given token
     * @return token URI
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}
          

lib/@solidstate/contracts/token/ERC721/metadata/IERC721MetadataInternal.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC721BaseInternal } from '../base/IERC721BaseInternal.sol';

/**
 * @title ERC721Metadata internal interface
 */
interface IERC721MetadataInternal is IERC721BaseInternal {
    error ERC721Metadata__NonExistentToken();
}
          

src/interfaces/IGem.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

import {ISolidStateERC721} from '../../lib/@solidstate/contracts/token/ERC721/ISolidStateERC721.sol';

interface IGem is ISolidStateERC721 {
    // ### Note on multiplicative bonuses
    // Gems can have 1 - 3 affixes which provide multiplicative bonuses. All of these could apply
    // to the same stat.
    // The Gems contract only allows for the registration of a single multiplicative bonus.
    //
    // Suppose that a gem has three affixes, the first of which improves attack by x_1%, the second
    // of which improves attack by x_2%, and the third of which improves attack by x_3%.
    //
    // Then the attackMultiplicativeBonusPercent for that gem can is:
    // 100 * [(1 + x_1/100)*(1 + x_2/100)*(1 + x_3/100) - 1]
    //
    //  Multiplicative bonuses max out at 255%
    //  Additive bonuses max out at 65,535
    struct GemBonuses {
        uint16 attackAdditive;
        uint8 attackMultiplicativePercent;
        uint16 defenseAdditive;
        uint8 defenseMultiplicativePercent;
        uint16 vitalityAdditive;
        uint8 vitalityMultiplicativePercent;
        uint16 accuracyAdditive;
        uint8 accuracyMultiplicativePercent;
        uint16 magicAdditive;
        uint8 magicMultiplicativePercent;
        uint16 resistanceAdditive;
        uint8 resistanceMultiplicativePercent;
        uint16 attackSpeedAdditive;
        uint8 attackSpeedMultiplicativePercent;
        uint16 moveSpeedAdditive;
        uint8 moveSpeedMultiplicativePercent;
        uint8 numBonuses;
    }

    /// @notice Returns true if the gem with the given tokenId has been minted.
    /// @param tokenId The ID of the gem to check.
    function gemMinted(uint256 tokenId) external view returns (bool);

    /// @notice Returns the name of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function gemName(uint256 tokenId) external view returns (string memory);

    /// @notice Returns the rarity of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function gemRarity(uint256 tokenId) external view returns (uint256);

    /// @notice Returns the number of bonuses of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function gemNumBonuses(uint256 tokenId) external view returns (uint256);

    /// @notice Returns the type of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function gemType(uint256 tokenId) external view returns (string memory);

    /// @notice Returns the bonuses of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function bonuses(uint256 tokenId) external view returns (GemBonuses memory bonuses);

    /// @notice Returns the metadata of the gem with the given tokenId.
    /// @param tokenId The ID of the gem to check.
    function metadataJSON(uint256 tokenId) external view returns (string memory);
}
          

Compiler Settings

{"viaIR":false,"remappings":["ds-test/=lib/forge-std/lib/ds-test/src/","forge-std/=lib/forge-std/src/","@openzeppelin-contracts/=lib/openzeppelin-contracts/"],"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":200,"enabled":true,"details":{"yulDetails":{"stackAllocation":true,"optimizerSteps":"dhfoDgvulfnTUtnIf"},"yul":true,"peephole":true,"inliner":true,"deduplicate":true,"cse":true}},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"paris"}
              

Contract ABI

[{"type":"event","name":"GemCreated","inputs":[{"type":"uint256","name":"requestId","internalType":"uint256","indexed":true},{"type":"uint256","name":"tokenId","internalType":"uint256","indexed":true},{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"string","name":"name","internalType":"string","indexed":false},{"type":"address","name":"signer","internalType":"address","indexed":true},{"type":"uint256[]","name":"parameters","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"adminTerminusInfo","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"approve","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"balance","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct IGem.GemBonuses","components":[{"type":"uint16","name":"attackAdditive","internalType":"uint16"},{"type":"uint8","name":"attackMultiplicativePercent","internalType":"uint8"},{"type":"uint16","name":"defenseAdditive","internalType":"uint16"},{"type":"uint8","name":"defenseMultiplicativePercent","internalType":"uint8"},{"type":"uint16","name":"vitalityAdditive","internalType":"uint16"},{"type":"uint8","name":"vitalityMultiplicativePercent","internalType":"uint8"},{"type":"uint16","name":"accuracyAdditive","internalType":"uint16"},{"type":"uint8","name":"accuracyMultiplicativePercent","internalType":"uint8"},{"type":"uint16","name":"magicAdditive","internalType":"uint16"},{"type":"uint8","name":"magicMultiplicativePercent","internalType":"uint8"},{"type":"uint16","name":"resistanceAdditive","internalType":"uint16"},{"type":"uint8","name":"resistanceMultiplicativePercent","internalType":"uint8"},{"type":"uint16","name":"attackSpeedAdditive","internalType":"uint16"},{"type":"uint8","name":"attackSpeedMultiplicativePercent","internalType":"uint8"},{"type":"uint16","name":"moveSpeedAdditive","internalType":"uint16"},{"type":"uint8","name":"moveSpeedMultiplicativePercent","internalType":"uint8"},{"type":"uint8","name":"numBonuses","internalType":"uint8"}]}],"name":"bonuses","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeAdminTerminusInfo","inputs":[{"type":"address","name":"adminTerminusAddress","internalType":"address"},{"type":"uint256","name":"adminTerminusPoolID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"contractURI","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutFacet","inputs":[{"type":"address","name":"facet","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutSelector","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutSelectors","inputs":[{"type":"bytes4[]","name":"selectors","internalType":"bytes4[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deleteSelector","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deleteSelectors","inputs":[{"type":"bytes4[]","name":"selectors","internalType":"bytes4[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"diamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamondCut.FacetCut[]","components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]},{"type":"address","name":"_init","internalType":"address"},{"type":"bytes","name":"_calldata","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"diamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamondCut.FacetCut[]","components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"facetAddress_","internalType":"address"}],"name":"facetAddress","inputs":[{"type":"bytes4","name":"_functionSelector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"facetAddresses_","internalType":"address[]"}],"name":"facetAddresses","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes4[]","name":"facetFunctionSelectors_","internalType":"bytes4[]"}],"name":"facetFunctionSelectors","inputs":[{"type":"address","name":"_facet","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"facets_","internalType":"struct IDiamondLoupe.Facet[]","components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]}],"name":"facets","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"gemMinted","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"gemName","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"gemNumBonuses","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"gemRarity","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"gemType","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"tokenIds","internalType":"uint256[]"},{"type":"bool","name":"moreEntriesExist","internalType":"bool"}],"name":"getAllGemsByOwner","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"uint32","name":"_pageNumber","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"operator","internalType":"address"}],"name":"getApproved","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"implementation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct LibSupportsInterface.KnownInterface[]","components":[{"type":"bytes4","name":"selector","internalType":"bytes4"},{"type":"bool","name":"supported","internalType":"bool"}]}],"name":"interfaces","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isApprovedForAll","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"operator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"license","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"metadataJSON","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"mintMessageHash","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"tokenId","internalType":"uint256"},{"type":"string","name":"name","internalType":"string"},{"type":"uint256[]","name":"bonusesArray","internalType":"uint256[]"},{"type":"uint256","name":"requestId","internalType":"uint256"},{"type":"uint256","name":"blockDeadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintWithSignature","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"tokenId","internalType":"uint256"},{"type":"string","name":"name","internalType":"string"},{"type":"uint256[]","name":"bonusesArray","internalType":"uint256[]"},{"type":"address","name":"signer","internalType":"address"},{"type":"uint256","name":"requestId","internalType":"uint256"},{"type":"uint256","name":"blockDeadline","internalType":"uint256"},{"type":"bytes","name":"signature","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"owner","internalType":"address"}],"name":"ownerOf","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"tokenId","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setApprovalForAll","inputs":[{"type":"address","name":"operator","internalType":"address"},{"type":"bool","name":"approved","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setImplementation","inputs":[{"type":"address","name":"_implementation","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSupportsInterface","inputs":[{"type":"bytes4","name":"interfaceID","internalType":"bytes4"},{"type":"bool","name":"implemented","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSupportsInterfaces","inputs":[{"type":"bytes4[]","name":"interfaceIDs","internalType":"bytes4[]"},{"type":"bool","name":"allImplemented","internalType":"bool"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceID","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tokenByIndex","inputs":[{"type":"uint256","name":"index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tokenOfOwnerByIndex","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"uint256","name":"index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"tokenURI","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"_newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferToUnicornContract","inputs":[{"type":"uint256[]","name":"tokenIds","internalType":"uint256[]"}]}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b50611250806100206000396000f3fe608060405234801561001057600080fd5b50600436106102bb5760003560e01c80638da5cb5b11610182578063cf43a6d0116100e9578063e57e69c6116100a2578063f2709f211161007c578063f2709f21146105b0578063f2fde38b14610447578063f60476f21461034f578063ff6f3e0b146103ef57600080fd5b8063e57e69c614610545578063e8a3d485146102fa578063e985e9c5146105a257600080fd5b8063cf43a6d014610545578063d1b9b6a814610553578063d784d42614610447578063db01c9ec14610579578063debb385614610594578063e0435c0b1461059457600080fd5b8063ab3756411161013b578063ab37564114610466578063adfca15e1461050e578063b72b1b63146103bd578063b88d4fde14610529578063c87b56dd1461034f578063cdffacc61461053757600080fd5b80638da5cb5b146103e8578063925b75cd1461042b57806395d89b41146102fa578063a22cb46514610439578063a6638c0e14610447578063a69d73371461045557600080fd5b806347cc3bdd116102265780636352211e116101df5780636352211e1461030a5780636463e3a0146103ef57806366e5722b146104005780636b87d24c146102fa57806370a082311461040e5780637a0ed6271461041c57600080fd5b806347cc3bdd146103bd5780634f6ccce7146103bd57806352ef6b2c146103cb57806354e7796f146103da5780635c60da1b146103e85780635f49fb971461032b57600080fd5b80631f931c1c116102785780631f931c1c1461036357806323b872dd14610378578063260fb8901461038b5780632f745c59146103a757806338c3faa61461034f57806342842e0e1461037857600080fd5b806301ffc9a7146102c057806306fdde03146102fa578063081812fc1461030a578063095ea7b31461032b57806318160ddd1461033f5780631b6ea4d31461034f575b600080fd5b6102e46102ce3660046105ec565b6001600160e01b0319166301ffc9a760e01b1490565b6040516102f1919061061f565b60405180910390f35b60605b6040516102f19190610683565b61031e6103183660046106ac565b50600090565b6040516102f191906106e7565b61033d610339366004610709565b5050565b005b60005b6040516102f1919061074c565b6102fd61035d3660046106ac565b50606090565b61033d6103713660046107f5565b5050505050565b61033d610386366004610882565b505050565b6103426103993660046108d2565b600098975050505050505050565b6103426103b5366004610709565b600092915050565b6103426103183660046106ac565b60606040516102f191906109f2565b61033d610339366004610a16565b600061031e565b61033d6103fd366004610b47565b50565b61033d610386366004610b81565b610342610318366004610bd1565b60606040516102f19190610cee565b6102e46103183660046106ac565b61033d610339366004610cff565b61033d6103fd366004610bd1565b6000806040516102f1929190610d21565b6105016104743660046106ac565b506040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810182905261020081019190915290565b6040516102f19190610e9d565b61051c61035d366004610bd1565b6040516102f19190610ee9565b61033d610371366004610efa565b61031e6103183660046105ec565b61033d610339366004610f62565b61056b610561366004610fc0565b5060609160009150565b6040516102f192919061103a565b61033d61058736600461105a565b5050505050505050505050565b61033d6103fd3660046105ec565b6102e46103b5366004611169565b60606040516102f19190611209565b919050565b6001600160e01b031981165b81146103fd57600080fd5b80356105e6816105c4565b92915050565b60006020828403121561060157610601600080fd5b600061060d84846105db565b949350505050565b8015155b82525050565b602081016105e68284610615565b60005b83811015610648578181015183820152602001610630565b50506000910152565b600061065b825190565b80845260208401935061067281856020860161062d565b601f01601f19169290920192915050565b602080825281016106948184610651565b9392505050565b806105d0565b80356105e68161069b565b6000602082840312156106c1576106c1600080fd5b600061060d84846106a1565b60006001600160a01b0382166105e6565b610619816106cd565b602081016105e682846106de565b6105d0816106cd565b80356105e6816106f5565b6000806040838503121561071f5761071f600080fd5b600061072b85856106fe565b925050602061073c858286016106a1565b9150509250929050565b80610619565b602081016105e68284610746565b60008083601f84011261076f5761076f600080fd5b5081356001600160401b0381111561078957610789600080fd5b6020830191508360208202830111156107a4576107a4600080fd5b9250929050565b60008083601f8401126107c0576107c0600080fd5b5081356001600160401b038111156107da576107da600080fd5b6020830191508360018202830111156107a4576107a4600080fd5b60008060008060006060868803121561081057610810600080fd5b85356001600160401b0381111561082957610829600080fd5b6108358882890161075a565b95509550506020610848888289016106fe565b93505060408601356001600160401b0381111561086757610867600080fd5b610873888289016107ab565b92509250509295509295909350565b60008060006060848603121561089a5761089a600080fd5b60006108a686866106fe565b93505060206108b7868287016106fe565b92505060406108c8868287016106a1565b9150509250925092565b60008060008060008060008060c0898b0312156108f1576108f1600080fd5b60006108fd8b8b6106fe565b985050602061090e8b828c016106a1565b97505060408901356001600160401b0381111561092d5761092d600080fd5b6109398b828c016107ab565b965096505060608901356001600160401b0381111561095a5761095a600080fd5b6109668b828c0161075a565b945094505060806109798b828c016106a1565b92505060a061098a8b828c016106a1565b9150509295985092959890939650565b6109a482826106de565b5060200190565b60006109b5825190565b808452602093840193830160005b828110156109e85781516109d7878261099a565b9650506020820191506001016109c3565b5093949350505050565b6020808252810161069481846109ab565b8015156105d0565b80356105e681610a03565b60008060408385031215610a2c57610a2c600080fd5b6000610a3885856105db565b925050602061073c85828601610a0b565b634e487b7160e01b600052604160045260246000fd5b601f19601f83011681018181106001600160401b0382111715610a8457610a84610a49565b6040525050565b6000610a9660405190565b90506105bf8282610a5f565b60006001600160401b03821115610abb57610abb610a49565b5060209081020190565b6000610ad8610ad384610aa2565b610a8b565b83815290506020808201908402830185811115610af757610af7600080fd5b835b81811015610b1957610b0b87826105db565b835260209283019201610af9565b5050509392505050565b600082601f830112610b3757610b37600080fd5b813561060d848260208601610ac5565b600060208284031215610b5c57610b5c600080fd5b81356001600160401b03811115610b7557610b75600080fd5b61060d84828501610b23565b600080600060408486031215610b9957610b99600080fd5b83356001600160401b03811115610bb257610bb2600080fd5b610bbe8682870161075a565b935093505060206108c886828701610a0b565b600060208284031215610be657610be6600080fd5b600061060d84846106fe565b6001600160e01b03198116610619565b6109a48282610bf2565b6000610c16825190565b808452602093840193830160005b828110156109e8578151610c388782610c02565b965050602082019150600101610c24565b80516000906040840190610c5d85826106de565b5060208301518482036020860152610c758282610c0c565b95945050505050565b60006106948383610c49565b6000610c94825190565b80845260208401935083602082028501610cae8560200190565b60005b84811015610ce25783830388528151610cca8482610c7e565b93505060208201602098909801979150600101610cb1565b50909695505050505050565b602080825281016106948184610c8a565b60008060408385031215610d1557610d15600080fd5b6000610a3885856106fe565b60408101610d2f82856106de565b6106946020830184610746565b61ffff8116610619565b60ff8116610619565b8051610d5b8382610d3c565b506020810151610d6e6020840182610d46565b506040810151610d816040840182610d3c565b506060810151610d946060840182610d46565b506080810151610da76080840182610d3c565b5060a0810151610dba60a0840182610d46565b5060c0810151610dcd60c0840182610d3c565b5060e0810151610de060e0840182610d46565b50610100810151610df5610100840182610d3c565b50610120810151610e0a610120840182610d46565b50610140810151610e1f610140840182610d3c565b50610160810151610e34610160840182610d46565b50610180810151610e49610180840182610d3c565b506101a0810151610e5e6101a0840182610d46565b506101c0810151610e736101c0840182610d3c565b506101e0810151610e886101e0840182610d46565b50610200810151610386610200840182610d46565b61022081016105e68284610d4f565b6000610eb6825190565b808452602093840193830160005b828110156109e8578151610ed88782610c02565b965050602082019150600101610ec4565b602080825281016106948184610eac565b600080600080600060808688031215610f1557610f15600080fd5b6000610f2188886106fe565b9550506020610f32888289016106fe565b9450506040610f43888289016106a1565b93505060608601356001600160401b0381111561086757610867600080fd5b60008060208385031215610f7857610f78600080fd5b82356001600160401b03811115610f9157610f91600080fd5b610f9d8582860161075a565b92509250509250929050565b63ffffffff81166105d0565b80356105e681610fa9565b60008060408385031215610fd657610fd6600080fd5b6000610fe285856106fe565b925050602061073c85828601610fb5565b6109a48282610746565b6000611007825190565b808452602093840193830160005b828110156109e85781516110298782610ff3565b965050602082019150600101611015565b6040808252810161104b8185610ffd565b90506106946020830184610615565b60008060008060008060008060008060006101008c8e03121561107f5761107f600080fd5b600061108b8e8e6106fe565b9b5050602061109c8e828f016106a1565b9a505060408c01356001600160401b038111156110bb576110bb600080fd5b6110c78e828f016107ab565b995099505060608c01356001600160401b038111156110e8576110e8600080fd5b6110f48e828f0161075a565b975097505060806111078e828f016106fe565b95505060a06111188e828f016106a1565b94505060c06111298e828f016106a1565b93505060e08c01356001600160401b0381111561114857611148600080fd5b6111548e828f016107ab565b92509250509295989b509295989b9093969950565b6000806040838503121561117f5761117f600080fd5b600061118b85856106fe565b925050602061073c858286016106fe565b80516111a88382610bf2565b5060208101516103866020840182610615565b6111c5828261119c565b5060400190565b60006111d6825190565b808452602093840193830160005b828110156109e85781516111f887826111bb565b9650506020820191506001016111e4565b6020808252810161069481846111cc56fea26469706673582212209399a1ccfb95d9c936db12a02fb47b9e2b7990795c95e8cbaed44c5fefa744e364736f6c63430008130033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106102bb5760003560e01c80638da5cb5b11610182578063cf43a6d0116100e9578063e57e69c6116100a2578063f2709f211161007c578063f2709f21146105b0578063f2fde38b14610447578063f60476f21461034f578063ff6f3e0b146103ef57600080fd5b8063e57e69c614610545578063e8a3d485146102fa578063e985e9c5146105a257600080fd5b8063cf43a6d014610545578063d1b9b6a814610553578063d784d42614610447578063db01c9ec14610579578063debb385614610594578063e0435c0b1461059457600080fd5b8063ab3756411161013b578063ab37564114610466578063adfca15e1461050e578063b72b1b63146103bd578063b88d4fde14610529578063c87b56dd1461034f578063cdffacc61461053757600080fd5b80638da5cb5b146103e8578063925b75cd1461042b57806395d89b41146102fa578063a22cb46514610439578063a6638c0e14610447578063a69d73371461045557600080fd5b806347cc3bdd116102265780636352211e116101df5780636352211e1461030a5780636463e3a0146103ef57806366e5722b146104005780636b87d24c146102fa57806370a082311461040e5780637a0ed6271461041c57600080fd5b806347cc3bdd146103bd5780634f6ccce7146103bd57806352ef6b2c146103cb57806354e7796f146103da5780635c60da1b146103e85780635f49fb971461032b57600080fd5b80631f931c1c116102785780631f931c1c1461036357806323b872dd14610378578063260fb8901461038b5780632f745c59146103a757806338c3faa61461034f57806342842e0e1461037857600080fd5b806301ffc9a7146102c057806306fdde03146102fa578063081812fc1461030a578063095ea7b31461032b57806318160ddd1461033f5780631b6ea4d31461034f575b600080fd5b6102e46102ce3660046105ec565b6001600160e01b0319166301ffc9a760e01b1490565b6040516102f1919061061f565b60405180910390f35b60605b6040516102f19190610683565b61031e6103183660046106ac565b50600090565b6040516102f191906106e7565b61033d610339366004610709565b5050565b005b60005b6040516102f1919061074c565b6102fd61035d3660046106ac565b50606090565b61033d6103713660046107f5565b5050505050565b61033d610386366004610882565b505050565b6103426103993660046108d2565b600098975050505050505050565b6103426103b5366004610709565b600092915050565b6103426103183660046106ac565b60606040516102f191906109f2565b61033d610339366004610a16565b600061031e565b61033d6103fd366004610b47565b50565b61033d610386366004610b81565b610342610318366004610bd1565b60606040516102f19190610cee565b6102e46103183660046106ac565b61033d610339366004610cff565b61033d6103fd366004610bd1565b6000806040516102f1929190610d21565b6105016104743660046106ac565b506040805161022081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810182905261020081019190915290565b6040516102f19190610e9d565b61051c61035d366004610bd1565b6040516102f19190610ee9565b61033d610371366004610efa565b61031e6103183660046105ec565b61033d610339366004610f62565b61056b610561366004610fc0565b5060609160009150565b6040516102f192919061103a565b61033d61058736600461105a565b5050505050505050505050565b61033d6103fd3660046105ec565b6102e46103b5366004611169565b60606040516102f19190611209565b919050565b6001600160e01b031981165b81146103fd57600080fd5b80356105e6816105c4565b92915050565b60006020828403121561060157610601600080fd5b600061060d84846105db565b949350505050565b8015155b82525050565b602081016105e68284610615565b60005b83811015610648578181015183820152602001610630565b50506000910152565b600061065b825190565b80845260208401935061067281856020860161062d565b601f01601f19169290920192915050565b602080825281016106948184610651565b9392505050565b806105d0565b80356105e68161069b565b6000602082840312156106c1576106c1600080fd5b600061060d84846106a1565b60006001600160a01b0382166105e6565b610619816106cd565b602081016105e682846106de565b6105d0816106cd565b80356105e6816106f5565b6000806040838503121561071f5761071f600080fd5b600061072b85856106fe565b925050602061073c858286016106a1565b9150509250929050565b80610619565b602081016105e68284610746565b60008083601f84011261076f5761076f600080fd5b5081356001600160401b0381111561078957610789600080fd5b6020830191508360208202830111156107a4576107a4600080fd5b9250929050565b60008083601f8401126107c0576107c0600080fd5b5081356001600160401b038111156107da576107da600080fd5b6020830191508360018202830111156107a4576107a4600080fd5b60008060008060006060868803121561081057610810600080fd5b85356001600160401b0381111561082957610829600080fd5b6108358882890161075a565b95509550506020610848888289016106fe565b93505060408601356001600160401b0381111561086757610867600080fd5b610873888289016107ab565b92509250509295509295909350565b60008060006060848603121561089a5761089a600080fd5b60006108a686866106fe565b93505060206108b7868287016106fe565b92505060406108c8868287016106a1565b9150509250925092565b60008060008060008060008060c0898b0312156108f1576108f1600080fd5b60006108fd8b8b6106fe565b985050602061090e8b828c016106a1565b97505060408901356001600160401b0381111561092d5761092d600080fd5b6109398b828c016107ab565b965096505060608901356001600160401b0381111561095a5761095a600080fd5b6109668b828c0161075a565b945094505060806109798b828c016106a1565b92505060a061098a8b828c016106a1565b9150509295985092959890939650565b6109a482826106de565b5060200190565b60006109b5825190565b808452602093840193830160005b828110156109e85781516109d7878261099a565b9650506020820191506001016109c3565b5093949350505050565b6020808252810161069481846109ab565b8015156105d0565b80356105e681610a03565b60008060408385031215610a2c57610a2c600080fd5b6000610a3885856105db565b925050602061073c85828601610a0b565b634e487b7160e01b600052604160045260246000fd5b601f19601f83011681018181106001600160401b0382111715610a8457610a84610a49565b6040525050565b6000610a9660405190565b90506105bf8282610a5f565b60006001600160401b03821115610abb57610abb610a49565b5060209081020190565b6000610ad8610ad384610aa2565b610a8b565b83815290506020808201908402830185811115610af757610af7600080fd5b835b81811015610b1957610b0b87826105db565b835260209283019201610af9565b5050509392505050565b600082601f830112610b3757610b37600080fd5b813561060d848260208601610ac5565b600060208284031215610b5c57610b5c600080fd5b81356001600160401b03811115610b7557610b75600080fd5b61060d84828501610b23565b600080600060408486031215610b9957610b99600080fd5b83356001600160401b03811115610bb257610bb2600080fd5b610bbe8682870161075a565b935093505060206108c886828701610a0b565b600060208284031215610be657610be6600080fd5b600061060d84846106fe565b6001600160e01b03198116610619565b6109a48282610bf2565b6000610c16825190565b808452602093840193830160005b828110156109e8578151610c388782610c02565b965050602082019150600101610c24565b80516000906040840190610c5d85826106de565b5060208301518482036020860152610c758282610c0c565b95945050505050565b60006106948383610c49565b6000610c94825190565b80845260208401935083602082028501610cae8560200190565b60005b84811015610ce25783830388528151610cca8482610c7e565b93505060208201602098909801979150600101610cb1565b50909695505050505050565b602080825281016106948184610c8a565b60008060408385031215610d1557610d15600080fd5b6000610a3885856106fe565b60408101610d2f82856106de565b6106946020830184610746565b61ffff8116610619565b60ff8116610619565b8051610d5b8382610d3c565b506020810151610d6e6020840182610d46565b506040810151610d816040840182610d3c565b506060810151610d946060840182610d46565b506080810151610da76080840182610d3c565b5060a0810151610dba60a0840182610d46565b5060c0810151610dcd60c0840182610d3c565b5060e0810151610de060e0840182610d46565b50610100810151610df5610100840182610d3c565b50610120810151610e0a610120840182610d46565b50610140810151610e1f610140840182610d3c565b50610160810151610e34610160840182610d46565b50610180810151610e49610180840182610d3c565b506101a0810151610e5e6101a0840182610d46565b506101c0810151610e736101c0840182610d3c565b506101e0810151610e886101e0840182610d46565b50610200810151610386610200840182610d46565b61022081016105e68284610d4f565b6000610eb6825190565b808452602093840193830160005b828110156109e8578151610ed88782610c02565b965050602082019150600101610ec4565b602080825281016106948184610eac565b600080600080600060808688031215610f1557610f15600080fd5b6000610f2188886106fe565b9550506020610f32888289016106fe565b9450506040610f43888289016106a1565b93505060608601356001600160401b0381111561086757610867600080fd5b60008060208385031215610f7857610f78600080fd5b82356001600160401b03811115610f9157610f91600080fd5b610f9d8582860161075a565b92509250509250929050565b63ffffffff81166105d0565b80356105e681610fa9565b60008060408385031215610fd657610fd6600080fd5b6000610fe285856106fe565b925050602061073c85828601610fb5565b6109a48282610746565b6000611007825190565b808452602093840193830160005b828110156109e85781516110298782610ff3565b965050602082019150600101611015565b6040808252810161104b8185610ffd565b90506106946020830184610615565b60008060008060008060008060008060006101008c8e03121561107f5761107f600080fd5b600061108b8e8e6106fe565b9b5050602061109c8e828f016106a1565b9a505060408c01356001600160401b038111156110bb576110bb600080fd5b6110c78e828f016107ab565b995099505060608c01356001600160401b038111156110e8576110e8600080fd5b6110f48e828f0161075a565b975097505060806111078e828f016106fe565b95505060a06111188e828f016106a1565b94505060c06111298e828f016106a1565b93505060e08c01356001600160401b0381111561114857611148600080fd5b6111548e828f016107ab565b92509250509295989b509295989b9093969950565b6000806040838503121561117f5761117f600080fd5b600061118b85856106fe565b925050602061073c858286016106fe565b80516111a88382610bf2565b5060208101516103866020840182610615565b6111c5828261119c565b5060400190565b60006111d6825190565b808452602093840193830160005b828110156109e85781516111f887826111bb565b9650506020820191506001016111e4565b6020808252810161069481846111cc56fea26469706673582212209399a1ccfb95d9c936db12a02fb47b9e2b7990795c95e8cbaed44c5fefa744e364736f6c63430008130033