Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
NFT
Overview
Max Total Supply
0 GHOST
Holders
303
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 GHOSTLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
HippyGhosts
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; /** * _ _ _____ _____ _______ __ _____ _ _ ____ _____ _______ _____ * | | | |_ _| __ \| __ \ \ / / / ____| | | |/ __ \ / ____|__ __/ ____| * | |__| | | | | |__) | |__) \ \_/ / | | __| |__| | | | | (___ | | | (___ * | __ | | | | ___/| ___/ \ / | | |_ | __ | | | |\___ \ | | \___ \ * | | | |_| |_| | | | | | | |__| | | | | |__| |____) | | | ____) | * |_| |_|_____|_| |_| |_| \_____|_| |_|\____/|_____/ |_| |_____/ * */ import "./ERC721.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/interfaces/IERC2981.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract HippyGhosts is ERC721, IERC2981, Ownable { /**************************************** * Variables ****************************************/ /** * @dev mint logic */ address public mintController; /** * @dev renderer for {IERC721Metadata-tokenURI} */ address public renderer; /**************************************** * Functions ****************************************/ constructor() ERC721("Hippy Ghosts", "GHOST") {} receive() external payable {} /* config functions */ function setAddresses(address renderer_, address mintController_) external onlyOwner { if (renderer_ != address(0)) { renderer = renderer_; } if (mintController_ != address(0)) { mintController = mintController_; } } /* mint logic */ function mint(address to, uint256 tokenId) external { require(msg.sender == mintController, "caller is not mint controller"); require(tokenId >= 1 && tokenId <= 9999, "Incorrect tokenId to mint"); _safeMint(to, tokenId, ""); } /* overrides */ /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view override returns (string memory) { require(_ownerOf[tokenId] != address(0), "ERC721Metadata: URI query for nonexistent token"); return IRenderer(renderer).tokenURI(tokenId); } /** * @dev See {IERC2981-royaltyInfo}. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) public view override returns (address receiver, uint256 royaltyAmount) { require(_ownerOf[tokenId] != address(0), "royaltyInfo for nonexistent token"); return (address(this), salePrice * 5 / 100); } function supportsInterface( bytes4 interfaceId ) public view override(ERC721, IERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /* withdraw from contract */ function withdraw() external onlyOwner { uint256 balance = address(this).balance; payable(msg.sender).transfer(balance); } function withdrawTokens(IERC20 token) external onlyOwner { uint256 balance = token.balanceOf(address(this)); token.transfer(msg.sender, balance); } } interface IRenderer { function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 indexed id); event Approval(address indexed owner, address indexed spender, uint256 indexed id); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /*////////////////////////////////////////////////////////////// METADATA STORAGE/LOGIC //////////////////////////////////////////////////////////////*/ string public name; string public symbol; function tokenURI(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) internal _ownerOf; mapping(address => uint256) internal _balanceOf; function ownerOf(uint256 id) public view virtual returns (address owner) { require((owner = _ownerOf[id]) != address(0), "NOT_MINTED"); } function balanceOf(address owner) public view virtual returns (uint256) { require(owner != address(0), "ZERO_ADDRESS"); return _balanceOf[owner]; } /*////////////////////////////////////////////////////////////// ERC721 APPROVAL STORAGE //////////////////////////////////////////////////////////////*/ mapping(uint256 => address) public getApproved; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(string memory _name, string memory _symbol) { name = _name; symbol = _symbol; } /*////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 id) public virtual { address owner = _ownerOf[id]; require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function transferFrom( address from, address to, uint256 id ) public virtual { require(from == _ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { _balanceOf[from]--; _balanceOf[to]++; } _ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom( address from, address to, uint256 id ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function safeTransferFrom( address from, address to, uint256 id, bytes calldata data ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); require(_ownerOf[id] == address(0), "ALREADY_MINTED"); // Counter overflow is incredibly unrealistic. unchecked { _balanceOf[to]++; } _ownerOf[id] = to; emit Transfer(address(0), to, id); } function _burn(uint256 id) internal virtual { address owner = _ownerOf[id]; require(owner != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { _balanceOf[owner]--; } delete _ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); } /*////////////////////////////////////////////////////////////// INTERNAL SAFE MINT LOGIC //////////////////////////////////////////////////////////////*/ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function _safeMint( address to, uint256 id, bytes memory data ) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) abstract contract ERC721TokenReceiver { function onERC721Received( address, address, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC721TokenReceiver.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract HippyGhostsRenderer is Ownable { using Strings for uint256; bytes32 constant public MERKLE_ROOT = 0x58d247a687ef48f010e2e6107a04d575787163cfb0d70543c421a5001e9f5aab; address public immutable hippyGhosts; string public baseURI; constructor( address hippyGhosts_, string memory baseURI_ ) { hippyGhosts = hippyGhosts_; baseURI = baseURI_; } function setBaseURI(string memory baseURI_) external onlyOwner { baseURI = baseURI_; } function tokenURI(uint256 tokenId) external view returns (string memory) { return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; library SignatureVerification { using ECDSA for bytes32; // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol // https://docs.soliditylang.org/en/v0.8.4/solidity-by-example.html?highlight=ecrecover#the-full-contract /** * @dev Performs address recovery on data and signature. Compares recovred address to varification address. * @param data Packed data used for signature generation * @param signature Signature for the provided data * @param verificationAddress Address to compare to recovered address */ function requireValidSignature( bytes memory data, bytes memory signature, address verificationAddress ) internal pure { require( verificationAddress != address(0), "verification address not initialized" ); require( keccak256(data).toEthSignedMessageHash().recover(signature) == verificationAddress, "signature invalid" ); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.11; /** * _ _ _____ _____ _______ __ _____ _ _ ____ _____ _______ _____ * | | | |_ _| __ \| __ \ \ / / / ____| | | |/ __ \ / ____|__ __/ ____| * | |__| | | | | |__) | |__) \ \_/ / | | __| |__| | | | | (___ | | | (___ * | __ | | | | ___/| ___/ \ / | | |_ | __ | | | |\___ \ | | \___ \ * | | | |_| |_| | | | | | | |__| | | | | |__| |____) | | | ____) | * |_| |_|_____|_| |_| |_| \_____|_| |_|\____/|_____/ |_| |_____/ * * Total 9999 Hippy Ghosts * ---------------------------------------------------------------------------- * 1 | 180 | [ 1, 180] | kept for team * 2 | 1320 | [ 181,1500] | private mint, 320 for team, 1000 for community * 3 | 8499 | [1501,9999] | public mint, release 300 ghosts every 40000 blocks * ---------------------------------------------------------------------------- */ import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./libraries/SignatureVerification.sol"; contract HippyGhostsMinter is Ownable { /**************************************** * Variables ****************************************/ address public immutable hippyGhosts; /** * @dev Ether value for each token in public mint */ uint256 public constant publicMintPriceUpper = 0.24 ether; uint256 public constant publicMintPriceLower = 0.08 ether; uint256 public constant publicMintPriceDecay = 0.04 ether; /** * @dev Starting block and inverval for public mint */ uint256 public publicMintStartBlock = 0; uint256 public constant EPOCH_BLOCKS = 40000; uint256 public constant GHOSTS_PER_EPOCH = 300; /** * @dev Index and upper bound for mint */ // general uint256 public constant MAX_GHOSTS_PER_MINT = 10; // team uint256 public ownerMintCount = 0; uint256 public constant MAX_OWNER_MINT_COUNT = 300; // private uint128 public privateMintCount = 0; uint128 public privateMintIndex = 180; uint256 public constant MAX_PRIVATE_MINT_INDEX = 1500; // public uint256 public publicMintIndex = 1500; uint256 public constant MAX_PUBLIC_MINT_INDEX = 9999; /** * @dev Public address used to sign function calls parameters */ address public verificationAddress; /** * @dev Key(address) mapping to a claimed key. * Used to prevent address from rebroadcasting mint transactions */ mapping(address => bool) private _claimedMintKeys; /**************************************** * Events ****************************************/ /** * @dev provide feedback on mint key used for signed mints */ event MintKeyClaimed( address indexed claimer, address indexed mintKey, uint256 numberOfTokens ); /**************************************** * Functions ****************************************/ constructor( address hippyGhosts_, address verificationAddress_ ) { hippyGhosts = hippyGhosts_; verificationAddress = verificationAddress_; } receive() external payable {} /* config functions */ function setPublicMintStartBlock(uint256 publicMintStartBlock_) external onlyOwner { require(publicMintStartBlock == 0, "publicMintStartBlock has already been set"); publicMintStartBlock = publicMintStartBlock_; } function setVerificationAddress(address verificationAddress_) external onlyOwner { verificationAddress = verificationAddress_; } function isMintKeyClaimed(address mintKey) external view returns (bool) { return _claimedMintKeys[mintKey]; } /* private mint functions */ function ownerMint( address[] calldata addresses, uint256[] calldata tokenIds ) external onlyOwner { ownerMintCount = ownerMintCount + tokenIds.length; require(ownerMintCount <= MAX_OWNER_MINT_COUNT, "Not enough ghosts remaining to mint"); for (uint256 i = 0; i < tokenIds.length; i++) { require(tokenIds[i] <= MAX_PRIVATE_MINT_INDEX, "Incorrect tokenId to mint"); IHippyGhosts(hippyGhosts).mint(addresses[i], tokenIds[i]); } } function mintWithSignature( uint256 numberOfTokens, uint256 valueInWei, address mintKey, bytes memory signature ) external payable { require(valueInWei == msg.value, "Incorrect ether value"); require(_claimedMintKeys[mintKey] == false, "Mint key already claimed"); SignatureVerification.requireValidSignature( abi.encodePacked(msg.sender, numberOfTokens, valueInWei, mintKey, this), signature, verificationAddress ); _claimedMintKeys[mintKey] = true; emit MintKeyClaimed(msg.sender, mintKey, numberOfTokens); uint256 currentMintIndex = uint256(privateMintIndex); for (uint256 i = 0; i < numberOfTokens; i++) { bool success = false; bytes memory result; while (!success) { // count to next index before minting currentMintIndex = currentMintIndex + 1; require(currentMintIndex <= MAX_PRIVATE_MINT_INDEX, "Incorrect tokenId to mint"); (success, result) = hippyGhosts.call( abi.encodeWithSignature("mint(address,uint256)", msg.sender, currentMintIndex) ); // mint will fail ONLY when tokenId is taken } } privateMintCount = privateMintCount + uint128(numberOfTokens); privateMintIndex = uint128(currentMintIndex); } /* public mint functions */ /** * @dev Epoch number start from 1, will increase every [EPOCH_BLOCKS] blocks */ function currentEpoch() public view returns (uint256) { if (publicMintStartBlock == 0 || block.number < publicMintStartBlock) { return 0; } uint256 epoches = (block.number - publicMintStartBlock) / EPOCH_BLOCKS; return epoches + 1; } function epochOfToken(uint256 tokenId) public pure returns (uint256) { require(tokenId > MAX_PRIVATE_MINT_INDEX, "Invalid tokenId"); uint256 epoches = (tokenId - MAX_PRIVATE_MINT_INDEX - 1) / GHOSTS_PER_EPOCH; return epoches + 1; } function availableForPublicMint() public view returns (uint256) { uint256 released = GHOSTS_PER_EPOCH * currentEpoch(); if (released > MAX_PUBLIC_MINT_INDEX - MAX_PRIVATE_MINT_INDEX) { released = MAX_PUBLIC_MINT_INDEX - MAX_PRIVATE_MINT_INDEX; } uint256 ghostsMintedInPublic = publicMintIndex - MAX_PRIVATE_MINT_INDEX; return released - ghostsMintedInPublic; } function priceForTokenId(uint256 tokenId) public view returns (uint256) { return priceForTokenId(currentEpoch(), epochOfToken(tokenId)); } function priceForTokenId(uint256 _currentEpoch, uint256 _tokenEpoch) public pure returns (uint256) { require(_currentEpoch >= _tokenEpoch, "Target epoch is not open"); uint256 price = publicMintPriceUpper - (_currentEpoch - _tokenEpoch) * publicMintPriceDecay; if (price < publicMintPriceLower) { price = publicMintPriceLower; } return price; } function mint(uint256 numberOfTokens) external payable { uint256 _currentEpoch = currentEpoch(); require(_currentEpoch > 0, "Public sale is not open"); require(numberOfTokens <= MAX_GHOSTS_PER_MINT, "Max ghosts to mint is ten"); require(publicMintIndex + numberOfTokens <= MAX_PUBLIC_MINT_INDEX, "Not enough ghosts remaining to mint"); uint256 _etherValue = msg.value; for (uint256 i = 0; i < numberOfTokens; i++) { publicMintIndex = publicMintIndex + 1; uint256 _tokenEpoch = epochOfToken(publicMintIndex); uint256 price = priceForTokenId(_currentEpoch, _tokenEpoch); _etherValue = _etherValue - price; IHippyGhosts(hippyGhosts).mint(msg.sender, publicMintIndex); } if (_etherValue > 0) { payable(msg.sender).transfer(_etherValue); } } /* withdraw from contract */ function withdraw() external onlyOwner { uint256 balance = address(this).balance; payable(msg.sender).transfer(balance); } function withdrawTokens(IERC20 token) external onlyOwner { uint256 balance = token.balanceOf(address(this)); token.transfer(msg.sender, balance); } function selfDestruct() external onlyOwner { selfdestruct(payable(msg.sender)); } } interface IHippyGhosts { function mint(address to, uint256 tokenId) external; }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renderer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"renderer_","type":"address"},{"internalType":"address","name":"mintController_","type":"address"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604080518082018252600c81526b48697070792047686f73747360a01b60208083019182528351808501909452600584526411d213d4d560da1b9084015281519192916200006391600091620000f2565b50805162000079906001906020840190620000f2565b50505062000096620000906200009c60201b60201c565b620000a0565b620001d5565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001009062000198565b90600052602060002090601f0160209004810192826200012457600085556200016f565b82601f106200013f57805160ff19168380011785556200016f565b828001600101855582156200016f579182015b828111156200016f57825182559160200191906001019062000152565b506200017d92915062000181565b5090565b5b808211156200017d576000815560010162000182565b600181811c90821680620001ad57607f821691505b60208210811415620001cf57634e487b7160e01b600052602260045260246000fd5b50919050565b61175880620001e56000396000f3fe6080604052600436106101445760003560e01c806370a08231116100b657806395d89b411161006f57806395d89b41146103cc578063a22cb465146103e1578063b88d4fde14610401578063c87b56dd14610421578063e985e9c514610441578063f2fde38b1461047c57600080fd5b806370a082311461030b57806370ac1fa514610339578063715018a6146103595780638ada6b0f1461036e5780638da5cb5b1461038e57806390107afe146103ac57600080fd5b80632a55205a116101085780632a55205a146102375780633ccfd60b1461027657806340c10f191461028b57806342842e0e146102ab57806349df728c146102cb5780636352211e146102eb57600080fd5b806301ffc9a71461015057806306fdde0314610185578063081812fc146101a7578063095ea7b3146101f557806323b872dd1461021757600080fd5b3661014b57005b600080fd5b34801561015c57600080fd5b5061017061016b36600461123b565b61049c565b60405190151581526020015b60405180910390f35b34801561019157600080fd5b5061019a6104c7565b60405161017c91906112bb565b3480156101b357600080fd5b506101dd6101c23660046112ce565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161017c565b34801561020157600080fd5b506102156102103660046112fc565b610555565b005b34801561022357600080fd5b50610215610232366004611328565b61063c565b34801561024357600080fd5b50610257610252366004611369565b610803565b604080516001600160a01b03909316835260208301919091520161017c565b34801561028257600080fd5b50610215610896565b34801561029757600080fd5b506102156102a63660046112fc565b6108f3565b3480156102b757600080fd5b506102156102c6366004611328565b6109c6565b3480156102d757600080fd5b506102156102e636600461138b565b610abf565b3480156102f757600080fd5b506101dd6103063660046112ce565b610bc8565b34801561031757600080fd5b5061032b61032636600461138b565b610c1f565b60405190815260200161017c565b34801561034557600080fd5b506007546101dd906001600160a01b031681565b34801561036557600080fd5b50610215610c82565b34801561037a57600080fd5b506008546101dd906001600160a01b031681565b34801561039a57600080fd5b506006546001600160a01b03166101dd565b3480156103b857600080fd5b506102156103c73660046113a8565b610cb8565b3480156103d857600080fd5b5061019a610d3d565b3480156103ed57600080fd5b506102156103fc3660046113ef565b610d4a565b34801561040d57600080fd5b5061021561041c36600461141d565b610db6565b34801561042d57600080fd5b5061019a61043c3660046112ce565b610e9e565b34801561044d57600080fd5b5061017061045c3660046113a8565b600560209081526000928352604080842090915290825290205460ff1681565b34801561048857600080fd5b5061021561049736600461138b565b610f8e565b60006001600160e01b0319821663152a902d60e11b14806104c157506104c182611029565b92915050565b600080546104d4906114bc565b80601f0160208091040260200160405190810160405280929190818152602001828054610500906114bc565b801561054d5780601f106105225761010080835404028352916020019161054d565b820191906000526020600020905b81548152906001019060200180831161053057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b03163381148061059e57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6105e05760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000818152600260205260409020546001600160a01b038481169116146106925760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b60448201526064016105d7565b6001600160a01b0382166106dc5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016105d7565b336001600160a01b038416148061071657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061073757506000818152600460205260409020546001600160a01b031633145b6107745760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016105d7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60008281526002602052604081205481906001600160a01b03166108735760405162461bcd60e51b815260206004820152602160248201527f726f79616c7479496e666f20666f72206e6f6e6578697374656e7420746f6b656044820152603760f91b60648201526084016105d7565b3060646108818560056114f7565b61088b9190611524565b915091509250929050565b6006546001600160a01b031633146108c05760405162461bcd60e51b81526004016105d790611546565b6040514790339082156108fc029083906000818181858888f193505050501580156108ef573d6000803e3d6000fd5b5050565b6007546001600160a01b0316331461094d5760405162461bcd60e51b815260206004820152601d60248201527f63616c6c6572206973206e6f74206d696e7420636f6e74726f6c6c657200000060448201526064016105d7565b60018110158015610960575061270f8111155b6109ac5760405162461bcd60e51b815260206004820152601960248201527f496e636f727265637420746f6b656e496420746f206d696e740000000000000060448201526064016105d7565b6108ef828260405180602001604052806000815250611077565b6109d183838361063c565b6001600160a01b0382163b1580610a7b5750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4015b6020604051808303816000875af1158015610a4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6f919061157b565b6001600160e01b031916145b610aba5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064016105d7565b505050565b6006546001600160a01b03163314610ae95760405162461bcd60e51b81526004016105d790611546565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610b30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b549190611598565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015610ba4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aba91906115b1565b6000818152600260205260409020546001600160a01b031680610c1a5760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b60448201526064016105d7565b919050565b60006001600160a01b038216610c665760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b60448201526064016105d7565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b03163314610cac5760405162461bcd60e51b81526004016105d790611546565b610cb660006110c8565b565b6006546001600160a01b03163314610ce25760405162461bcd60e51b81526004016105d790611546565b6001600160a01b03821615610d0d57600880546001600160a01b0319166001600160a01b0384161790555b6001600160a01b038116156108ef57600780546001600160a01b0383166001600160a01b03199091161790555050565b600180546104d4906114bc565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610dc185858561063c565b6001600160a01b0384163b1580610e585750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290610e099033908a908990899089906004016115ce565b6020604051808303816000875af1158015610e28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4c919061157b565b6001600160e01b031916145b610e975760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064016105d7565b5050505050565b6000818152600260205260409020546060906001600160a01b0316610f1d5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016105d7565b60085460405163c87b56dd60e01b8152600481018490526001600160a01b039091169063c87b56dd90602401600060405180830381865afa158015610f66573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104c19190810190611638565b6006546001600160a01b03163314610fb85760405162461bcd60e51b81526004016105d790611546565b6001600160a01b03811661101d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105d7565b611026816110c8565b50565b60006301ffc9a760e01b6001600160e01b03198316148061105a57506380ac58cd60e01b6001600160e01b03198316145b806104c15750506001600160e01b031916635b5e139f60e01b1490565b611081838361111a565b6001600160a01b0383163b1580610a7b5750604051630a85bd0160e11b808252906001600160a01b0385169063150b7a0290610a2c903390600090889088906004016116e5565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166111645760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016105d7565b6000818152600260205260409020546001600160a01b0316156111ba5760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b60448201526064016105d7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b03198116811461102657600080fd5b60006020828403121561124d57600080fd5b813561125881611225565b9392505050565b60005b8381101561127a578181015183820152602001611262565b83811115611289576000848401525b50505050565b600081518084526112a781602086016020860161125f565b601f01601f19169290920160200192915050565b602081526000611258602083018461128f565b6000602082840312156112e057600080fd5b5035919050565b6001600160a01b038116811461102657600080fd5b6000806040838503121561130f57600080fd5b823561131a816112e7565b946020939093013593505050565b60008060006060848603121561133d57600080fd5b8335611348816112e7565b92506020840135611358816112e7565b929592945050506040919091013590565b6000806040838503121561137c57600080fd5b50508035926020909101359150565b60006020828403121561139d57600080fd5b8135611258816112e7565b600080604083850312156113bb57600080fd5b82356113c6816112e7565b915060208301356113d6816112e7565b809150509250929050565b801515811461102657600080fd5b6000806040838503121561140257600080fd5b823561140d816112e7565b915060208301356113d6816113e1565b60008060008060006080868803121561143557600080fd5b8535611440816112e7565b94506020860135611450816112e7565b935060408601359250606086013567ffffffffffffffff8082111561147457600080fd5b818801915088601f83011261148857600080fd5b81358181111561149757600080fd5b8960208285010111156114a957600080fd5b9699959850939650602001949392505050565b600181811c908216806114d057607f821691505b602082108114156114f157634e487b7160e01b600052602260045260246000fd5b50919050565b600081600019048311821515161561151f57634e487b7160e01b600052601160045260246000fd5b500290565b60008261154157634e487b7160e01b600052601260045260246000fd5b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561158d57600080fd5b815161125881611225565b6000602082840312156115aa57600080fd5b5051919050565b6000602082840312156115c357600080fd5b8151611258816113e1565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561164a57600080fd5b815167ffffffffffffffff8082111561166257600080fd5b818401915084601f83011261167657600080fd5b81518181111561168857611688611622565b604051601f8201601f19908116603f011681019083821181831017156116b0576116b0611622565b816040528281528760208487010111156116c957600080fd5b6116da83602083016020880161125f565b979650505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906117189083018461128f565b969550505050505056fea2646970667358221220fb9bbda9a881306992036e3fd1f8899878089498cd6334f657ce7325acd36c8264736f6c634300080b0033
Deployed Bytecode
0x6080604052600436106101445760003560e01c806370a08231116100b657806395d89b411161006f57806395d89b41146103cc578063a22cb465146103e1578063b88d4fde14610401578063c87b56dd14610421578063e985e9c514610441578063f2fde38b1461047c57600080fd5b806370a082311461030b57806370ac1fa514610339578063715018a6146103595780638ada6b0f1461036e5780638da5cb5b1461038e57806390107afe146103ac57600080fd5b80632a55205a116101085780632a55205a146102375780633ccfd60b1461027657806340c10f191461028b57806342842e0e146102ab57806349df728c146102cb5780636352211e146102eb57600080fd5b806301ffc9a71461015057806306fdde0314610185578063081812fc146101a7578063095ea7b3146101f557806323b872dd1461021757600080fd5b3661014b57005b600080fd5b34801561015c57600080fd5b5061017061016b36600461123b565b61049c565b60405190151581526020015b60405180910390f35b34801561019157600080fd5b5061019a6104c7565b60405161017c91906112bb565b3480156101b357600080fd5b506101dd6101c23660046112ce565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200161017c565b34801561020157600080fd5b506102156102103660046112fc565b610555565b005b34801561022357600080fd5b50610215610232366004611328565b61063c565b34801561024357600080fd5b50610257610252366004611369565b610803565b604080516001600160a01b03909316835260208301919091520161017c565b34801561028257600080fd5b50610215610896565b34801561029757600080fd5b506102156102a63660046112fc565b6108f3565b3480156102b757600080fd5b506102156102c6366004611328565b6109c6565b3480156102d757600080fd5b506102156102e636600461138b565b610abf565b3480156102f757600080fd5b506101dd6103063660046112ce565b610bc8565b34801561031757600080fd5b5061032b61032636600461138b565b610c1f565b60405190815260200161017c565b34801561034557600080fd5b506007546101dd906001600160a01b031681565b34801561036557600080fd5b50610215610c82565b34801561037a57600080fd5b506008546101dd906001600160a01b031681565b34801561039a57600080fd5b506006546001600160a01b03166101dd565b3480156103b857600080fd5b506102156103c73660046113a8565b610cb8565b3480156103d857600080fd5b5061019a610d3d565b3480156103ed57600080fd5b506102156103fc3660046113ef565b610d4a565b34801561040d57600080fd5b5061021561041c36600461141d565b610db6565b34801561042d57600080fd5b5061019a61043c3660046112ce565b610e9e565b34801561044d57600080fd5b5061017061045c3660046113a8565b600560209081526000928352604080842090915290825290205460ff1681565b34801561048857600080fd5b5061021561049736600461138b565b610f8e565b60006001600160e01b0319821663152a902d60e11b14806104c157506104c182611029565b92915050565b600080546104d4906114bc565b80601f0160208091040260200160405190810160405280929190818152602001828054610500906114bc565b801561054d5780601f106105225761010080835404028352916020019161054d565b820191906000526020600020905b81548152906001019060200180831161053057829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b03163381148061059e57506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b6105e05760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000818152600260205260409020546001600160a01b038481169116146106925760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b60448201526064016105d7565b6001600160a01b0382166106dc5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016105d7565b336001600160a01b038416148061071657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061073757506000818152600460205260409020546001600160a01b031633145b6107745760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016105d7565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60008281526002602052604081205481906001600160a01b03166108735760405162461bcd60e51b815260206004820152602160248201527f726f79616c7479496e666f20666f72206e6f6e6578697374656e7420746f6b656044820152603760f91b60648201526084016105d7565b3060646108818560056114f7565b61088b9190611524565b915091509250929050565b6006546001600160a01b031633146108c05760405162461bcd60e51b81526004016105d790611546565b6040514790339082156108fc029083906000818181858888f193505050501580156108ef573d6000803e3d6000fd5b5050565b6007546001600160a01b0316331461094d5760405162461bcd60e51b815260206004820152601d60248201527f63616c6c6572206973206e6f74206d696e7420636f6e74726f6c6c657200000060448201526064016105d7565b60018110158015610960575061270f8111155b6109ac5760405162461bcd60e51b815260206004820152601960248201527f496e636f727265637420746f6b656e496420746f206d696e740000000000000060448201526064016105d7565b6108ef828260405180602001604052806000815250611077565b6109d183838361063c565b6001600160a01b0382163b1580610a7b5750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4015b6020604051808303816000875af1158015610a4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6f919061157b565b6001600160e01b031916145b610aba5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064016105d7565b505050565b6006546001600160a01b03163314610ae95760405162461bcd60e51b81526004016105d790611546565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610b30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b549190611598565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015610ba4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aba91906115b1565b6000818152600260205260409020546001600160a01b031680610c1a5760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b60448201526064016105d7565b919050565b60006001600160a01b038216610c665760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b60448201526064016105d7565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b03163314610cac5760405162461bcd60e51b81526004016105d790611546565b610cb660006110c8565b565b6006546001600160a01b03163314610ce25760405162461bcd60e51b81526004016105d790611546565b6001600160a01b03821615610d0d57600880546001600160a01b0319166001600160a01b0384161790555b6001600160a01b038116156108ef57600780546001600160a01b0383166001600160a01b03199091161790555050565b600180546104d4906114bc565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610dc185858561063c565b6001600160a01b0384163b1580610e585750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290610e099033908a908990899089906004016115ce565b6020604051808303816000875af1158015610e28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4c919061157b565b6001600160e01b031916145b610e975760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b60448201526064016105d7565b5050505050565b6000818152600260205260409020546060906001600160a01b0316610f1d5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016105d7565b60085460405163c87b56dd60e01b8152600481018490526001600160a01b039091169063c87b56dd90602401600060405180830381865afa158015610f66573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104c19190810190611638565b6006546001600160a01b03163314610fb85760405162461bcd60e51b81526004016105d790611546565b6001600160a01b03811661101d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105d7565b611026816110c8565b50565b60006301ffc9a760e01b6001600160e01b03198316148061105a57506380ac58cd60e01b6001600160e01b03198316145b806104c15750506001600160e01b031916635b5e139f60e01b1490565b611081838361111a565b6001600160a01b0383163b1580610a7b5750604051630a85bd0160e11b808252906001600160a01b0385169063150b7a0290610a2c903390600090889088906004016116e5565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166111645760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b60448201526064016105d7565b6000818152600260205260409020546001600160a01b0316156111ba5760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b60448201526064016105d7565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160e01b03198116811461102657600080fd5b60006020828403121561124d57600080fd5b813561125881611225565b9392505050565b60005b8381101561127a578181015183820152602001611262565b83811115611289576000848401525b50505050565b600081518084526112a781602086016020860161125f565b601f01601f19169290920160200192915050565b602081526000611258602083018461128f565b6000602082840312156112e057600080fd5b5035919050565b6001600160a01b038116811461102657600080fd5b6000806040838503121561130f57600080fd5b823561131a816112e7565b946020939093013593505050565b60008060006060848603121561133d57600080fd5b8335611348816112e7565b92506020840135611358816112e7565b929592945050506040919091013590565b6000806040838503121561137c57600080fd5b50508035926020909101359150565b60006020828403121561139d57600080fd5b8135611258816112e7565b600080604083850312156113bb57600080fd5b82356113c6816112e7565b915060208301356113d6816112e7565b809150509250929050565b801515811461102657600080fd5b6000806040838503121561140257600080fd5b823561140d816112e7565b915060208301356113d6816113e1565b60008060008060006080868803121561143557600080fd5b8535611440816112e7565b94506020860135611450816112e7565b935060408601359250606086013567ffffffffffffffff8082111561147457600080fd5b818801915088601f83011261148857600080fd5b81358181111561149757600080fd5b8960208285010111156114a957600080fd5b9699959850939650602001949392505050565b600181811c908216806114d057607f821691505b602082108114156114f157634e487b7160e01b600052602260045260246000fd5b50919050565b600081600019048311821515161561151f57634e487b7160e01b600052601160045260246000fd5b500290565b60008261154157634e487b7160e01b600052601260045260246000fd5b500490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561158d57600080fd5b815161125881611225565b6000602082840312156115aa57600080fd5b5051919050565b6000602082840312156115c357600080fd5b8151611258816113e1565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561164a57600080fd5b815167ffffffffffffffff8082111561166257600080fd5b818401915084601f83011261167657600080fd5b81518181111561168857611688611622565b604051601f8201601f19908116603f011681019083821181831017156116b0576116b0611622565b816040528281528760208487010111156116c957600080fd5b6116da83602083016020880161125f565b979650505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906117189083018461128f565b969550505050505056fea2646970667358221220fb9bbda9a881306992036e3fd1f8899878089498cd6334f657ce7325acd36c8264736f6c634300080b0033
Deployed Bytecode Sourcemap
760:2393:9:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2576:219;;;;;;;;;;-1:-1:-1;2576:219:9;;;;;:::i;:::-;;:::i;:::-;;;565:14:13;;558:22;540:41;;528:2;513:18;2576:219:9;;;;;;;;896:18:8;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;1841:46::-;;;;;;;;;;-1:-1:-1;1841:46:8;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;1841:46:8;;;;;;-1:-1:-1;;;;;1692:32:13;;;1674:51;;1662:2;1647:18;1841:46:8;1528:203:13;2450:282:8;;;;;;;;;;-1:-1:-1;2450:282:8;;;;;:::i;:::-;;:::i;:::-;;2947:741;;;;;;;;;;-1:-1:-1;2947:741:8;;;;;:::i;:::-;;:::i;2281:289:9:-;;;;;;;;;;-1:-1:-1;2281:289:9;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3098:32:13;;;3080:51;;3162:2;3147:18;;3140:34;;;;3053:18;2281:289:9;2906:274:13;2835:142:9;;;;;;;;;;;;;:::i;1636:254::-;;;;;;;;;;-1:-1:-1;1636:254:9;;;;;:::i;:::-;;:::i;3694:396:8:-;;;;;;;;;;-1:-1:-1;3694:396:8;;;;;:::i;:::-;;:::i;2983:167:9:-;;;;;;;;;;-1:-1:-1;2983:167:9;;;;;:::i;:::-;;:::i;1324:149:8:-;;;;;;;;;;-1:-1:-1;1324:149:8;;;;;:::i;:::-;;:::i;1479:168::-;;;;;;;;;;-1:-1:-1;1479:168:8;;;;;:::i;:::-;;:::i;:::-;;;3849:25:13;;;3837:2;3822:18;1479:168:8;3703:177:13;968:29:9;;;;;;;;;;-1:-1:-1;968:29:9;;;;-1:-1:-1;;;;;968:29:9;;;1668:101:0;;;;;;;;;;;;;:::i;1073:23:9:-;;;;;;;;;;-1:-1:-1;1073:23:9;;;;-1:-1:-1;;;;;1073:23:9;;;1036:85:0;;;;;;;;;;-1:-1:-1;1108:6:0;;-1:-1:-1;;;;;1108:6:0;1036:85;;1332:276:9;;;;;;;;;;-1:-1:-1;1332:276:9;;;;;:::i;:::-;;:::i;921:20:8:-;;;;;;;;;;;;;:::i;2738:203::-;;;;;;;;;;-1:-1:-1;2738:203:8;;;;;:::i;:::-;;:::i;4096:427::-;;;;;;;;;;-1:-1:-1;4096:427:8;;;;;:::i;:::-;;:::i;1977:242:9:-;;;;;;;;;;-1:-1:-1;1977:242:9;;;;;:::i;:::-;;:::i;1894:68:8:-;;;;;;;;;;-1:-1:-1;1894:68:8;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;1918:198:0;;;;;;;;;;-1:-1:-1;1918:198:0;;;;;:::i;:::-;;:::i;2576:219:9:-;2684:4;-1:-1:-1;;;;;;2707:41:9;;-1:-1:-1;;;2707:41:9;;:81;;;2752:36;2776:11;2752:23;:36::i;:::-;2700:88;2576:219;-1:-1:-1;;2576:219:9:o;896:18:8:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2450:282::-;2521:13;2537:12;;;:8;:12;;;;;;-1:-1:-1;;;;;2537:12:8;2568:10;:19;;;:58;;-1:-1:-1;;;;;;2591:23:8;;;;;;:16;:23;;;;;;;;2615:10;2591:35;;;;;;;;;;2568:58;2560:85;;;;-1:-1:-1;;;2560:85:8;;6316:2:13;2560:85:8;;;6298:21:13;6355:2;6335:18;;;6328:30;-1:-1:-1;;;6374:18:13;;;6367:44;6428:18;;2560:85:8;;;;;;;;;2656:15;;;;:11;:15;;;;;;:25;;-1:-1:-1;;;;;;2656:25:8;-1:-1:-1;;;;;2656:25:8;;;;;;;;;2697:28;;2656:15;;2697:28;;;;;;;2511:221;2450:282;;:::o;2947:741::-;3078:12;;;;:8;:12;;;;;;-1:-1:-1;;;;;3070:20:8;;;3078:12;;3070:20;3062:43;;;;-1:-1:-1;;;3062:43:8;;6659:2:13;3062:43:8;;;6641:21:13;6698:2;6678:18;;;6671:30;-1:-1:-1;;;6717:18:13;;;6710:40;6767:18;;3062:43:8;6457:334:13;3062:43:8;-1:-1:-1;;;;;3124:16:8;;3116:46;;;;-1:-1:-1;;;3116:46:8;;6998:2:13;3116:46:8;;;6980:21:13;7037:2;7017:18;;;7010:30;-1:-1:-1;;;7056:18:13;;;7049:47;7113:18;;3116:46:8;6796:341:13;3116:46:8;3194:10;-1:-1:-1;;;;;3194:18:8;;;;:56;;-1:-1:-1;;;;;;3216:22:8;;;;;;:16;:22;;;;;;;;3239:10;3216:34;;;;;;;;;;3194:56;:89;;;-1:-1:-1;3268:15:8;;;;:11;:15;;;;;;-1:-1:-1;;;;;3268:15:8;3254:10;:29;3194:89;3173:150;;;;-1:-1:-1;;;3173:150:8;;6316:2:13;3173:150:8;;;6298:21:13;6355:2;6335:18;;;6328:30;-1:-1:-1;;;6374:18:13;;;6367:44;6428:18;;3173:150:8;6114:338:13;3173:150:8;-1:-1:-1;;;;;3523:16:8;;;;;;;:10;:16;;;;;;;;:18;;-1:-1:-1;;3523:18:8;;;3556:14;;;;;;;;;:16;;3523:18;3556:16;;;3593:12;;;:8;:12;;;;;:17;;-1:-1:-1;;;;;;3593:17:8;;;;;;;;3628:11;:15;;;;;;3621:22;;;;;;;;3659;;3602:2;;3556:14;3523:16;3659:22;;;2947:741;;;:::o;2281:289:9:-;2382:16;2441:17;;;:8;:17;;;;;;2382:16;;-1:-1:-1;;;;;2441:17:9;2433:77;;;;-1:-1:-1;;;2433:77:9;;7344:2:13;2433:77:9;;;7326:21:13;7383:2;7363:18;;;7356:30;7422:34;7402:18;;;7395:62;-1:-1:-1;;;7473:18:13;;;7466:31;7514:19;;2433:77:9;7142:397:13;2433:77:9;2536:4;2559:3;2543:13;:9;2555:1;2543:13;:::i;:::-;:19;;;;:::i;:::-;2520:43;;;;2281:289;;;;;:::o;2835:142::-;1108:6:0;;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;2933:37:9::1;::::0;2902:21:::1;::::0;2941:10:::1;::::0;2933:37;::::1;;;::::0;2902:21;;2884:15:::1;2933:37:::0;2884:15;2933:37;2902:21;2941:10;2933:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;2874:103;2835:142::o:0;1636:254::-;1720:14;;-1:-1:-1;;;;;1720:14:9;1706:10;:28;1698:70;;;;-1:-1:-1;;;1698:70:9;;8599:2:13;1698:70:9;;;8581:21:13;8638:2;8618:18;;;8611:30;8677:31;8657:18;;;8650:59;8726:18;;1698:70:9;8397:353:13;1698:70:9;1797:1;1786:7;:12;;:31;;;;;1813:4;1802:7;:15;;1786:31;1778:69;;;;-1:-1:-1;;;1778:69:9;;8957:2:13;1778:69:9;;;8939:21:13;8996:2;8976:18;;;8969:30;9035:27;9015:18;;;9008:55;9080:18;;1778:69:9;8755:349:13;1778:69:9;1857:26;1867:2;1871:7;1857:26;;;;;;;;;;;;:9;:26::i;3694:396:8:-;3813:26;3826:4;3832:2;3836;3813:12;:26::i;:::-;-1:-1:-1;;;;;3871:14:8;;;:19;;:170;;-1:-1:-1;3910:66:8;;-1:-1:-1;;;3910:66:8;;;3951:10;3910:66;;;9414:34:13;-1:-1:-1;;;;;9484:15:13;;;9464:18;;;9457:43;9516:18;;;9509:34;;;9579:3;9559:18;;;9552:31;-1:-1:-1;9599:19:13;;;9592:30;3996:45:8;;3910:40;;;;3996:45;;9639:19:13;;3910:66:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;3910:131:8;;3871:170;3850:233;;;;-1:-1:-1;;;3850:233:8;;10125:2:13;3850:233:8;;;10107:21:13;10164:2;10144:18;;;10137:30;-1:-1:-1;;;10183:18:13;;;10176:46;10239:18;;3850:233:8;9923:340:13;3850:233:8;3694:396;;;:::o;2983:167:9:-;1108:6:0;;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;3068:30:9::1;::::0;-1:-1:-1;;;3068:30:9;;3092:4:::1;3068:30;::::0;::::1;1674:51:13::0;3050:15:9::1;::::0;-1:-1:-1;;;;;3068:15:9;::::1;::::0;::::1;::::0;1647:18:13;;3068:30:9::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3108:35;::::0;-1:-1:-1;;;3108:35:9;;3123:10:::1;3108:35;::::0;::::1;3080:51:13::0;3147:18;;;3140:34;;;3050:48:9;;-1:-1:-1;;;;;;3108:14:9;::::1;::::0;::::1;::::0;3053:18:13;;3108:35:9::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;1324:149:8:-:0;1382:13;1424:12;;;:8;:12;;;;;;-1:-1:-1;;;;;1424:12:8;1415:36;1407:59;;;;-1:-1:-1;;;1407:59:8;;10909:2:13;1407:59:8;;;10891:21:13;10948:2;10928:18;;;10921:30;-1:-1:-1;;;10967:18:13;;;10960:40;11017:18;;1407:59:8;10707:334:13;1407:59:8;1324:149;;;:::o;1479:168::-;1542:7;-1:-1:-1;;;;;1569:19:8;;1561:44;;;;-1:-1:-1;;;1561:44:8;;11248:2:13;1561:44:8;;;11230:21:13;11287:2;11267:18;;;11260:30;-1:-1:-1;;;11306:18:13;;;11299:42;11358:18;;1561:44:8;11046:336:13;1561:44:8;-1:-1:-1;;;;;;1623:17:8;;;;;:10;:17;;;;;;;1479:168::o;1668:101:0:-;1108:6;;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;1732:30:::1;1759:1;1732:18;:30::i;:::-;1668:101::o:0;1332:276:9:-;1108:6:0;;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;1431:23:9;::::1;::::0;1427:74:::1;;1470:8;:20:::0;;-1:-1:-1;;;;;;1470:20:9::1;-1:-1:-1::0;;;;;1470:20:9;::::1;;::::0;;1427:74:::1;-1:-1:-1::0;;;;;1514:29:9;::::1;::::0;1510:92:::1;;1559:14;:32:::0;;-1:-1:-1;;;;;1559:32:9;::::1;-1:-1:-1::0;;;;;;1559:32:9;;::::1;;::::0;;1332:276;;:::o;921:20:8:-;;;;;;;:::i;2738:203::-;2840:10;2823:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;2823:38:8;;;;;;;;;;;;:49;;-1:-1:-1;;2823:49:8;;;;;;;;;;2888:46;;540:41:13;;;2823:38:8;;2840:10;2888:46;;513:18:13;2888:46:8;;;;;;;2738:203;;:::o;4096:427::-;4244:26;4257:4;4263:2;4267;4244:12;:26::i;:::-;-1:-1:-1;;;;;4302:14:8;;;:19;;:172;;-1:-1:-1;4341:68:8;;-1:-1:-1;;;4341:68:8;;;4429:45;-1:-1:-1;;;;;4341:40:8;;;4429:45;;4341:68;;4382:10;;4394:4;;4400:2;;4404:4;;;;4341:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;4341:133:8;;4302:172;4281:235;;;;-1:-1:-1;;;4281:235:8;;10125:2:13;4281:235:8;;;10107:21:13;10164:2;10144:18;;;10137:30;-1:-1:-1;;;10183:18:13;;;10176:46;10239:18;;4281:235:8;9923:340:13;4281:235:8;4096:427;;;;;:::o;1977:242:9:-;2104:1;2075:17;;;:8;:17;;;;;;2042:13;;-1:-1:-1;;;;;2075:17:9;2067:91;;;;-1:-1:-1;;;2067:91:9;;12256:2:13;2067:91:9;;;12238:21:13;12295:2;12275:18;;;12268:30;12334:34;12314:18;;;12307:62;-1:-1:-1;;;12385:18:13;;;12378:45;12440:19;;2067:91:9;12054:411:13;2067:91:9;2185:8;;2175:37;;-1:-1:-1;;;2175:37:9;;;;;3849:25:13;;;-1:-1:-1;;;;;2185:8:9;;;;2175:28;;3822:18:13;;2175:37:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2175:37:9;;;;;;;;;;;;:::i;1918:198:0:-;1108:6;;-1:-1:-1;;;;;1108:6:0;719:10:4;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2006:22:0;::::1;1998:73;;;::::0;-1:-1:-1;;;1998:73:0;;13693:2:13;1998:73:0::1;::::0;::::1;13675:21:13::0;13732:2;13712:18;;;13705:30;13771:34;13751:18;;;13744:62;-1:-1:-1;;;13822:18:13;;;13815:36;13868:19;;1998:73:0::1;13491:402:13::0;1998:73:0::1;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;4711:335:8:-;4787:4;-1:-1:-1;;;;;;;;;4822:25:8;;;;:100;;-1:-1:-1;;;;;;;;;;4897:25:8;;;4822:100;:175;;;-1:-1:-1;;;;;;;;4972:25:8;-1:-1:-1;;;4972:25:8;;4711:335::o;6528:391::-;6647:13;6653:2;6657;6647:5;:13::i;:::-;-1:-1:-1;;;;;6692:14:8;;;:19;;:178;;-1:-1:-1;6731:74:8;;-1:-1:-1;;;6731:74:8;;;6825:45;-1:-1:-1;;;;;6731:40:8;;;6825:45;;6731:74;;6772:10;;6792:1;;6796:2;;6800:4;;6731:74;;;:::i;2270:187:0:-;2362:6;;;-1:-1:-1;;;;;2378:17:0;;;-1:-1:-1;;;;;;2378:17:0;;;;;;;2410:40;;2362:6;;;2378:17;2362:6;;2410:40;;2343:16;;2410:40;2333:124;2270:187;:::o;5240:371:8:-;-1:-1:-1;;;;;5314:16:8;;5306:46;;;;-1:-1:-1;;;5306:46:8;;6998:2:13;5306:46:8;;;6980:21:13;7037:2;7017:18;;;7010:30;-1:-1:-1;;;7056:18:13;;;7049:47;7113:18;;5306:46:8;6796:341:13;5306:46:8;5395:1;5371:12;;;:8;:12;;;;;;-1:-1:-1;;;;;5371:12:8;:26;5363:53;;;;-1:-1:-1;;;5363:53:8;;14594:2:13;5363:53:8;;;14576:21:13;14633:2;14613:18;;;14606:30;-1:-1:-1;;;14652:18:13;;;14645:44;14706:18;;5363:53:8;14392:338:13;5363:53:8;-1:-1:-1;;;;;5506:14:8;;;;;;:10;:14;;;;;;;;:16;;;;;;5543:12;;;:8;:12;;;;;;:17;;-1:-1:-1;;;;;;5543:17:8;;;;;5576:28;5552:2;;5506:14;;5576:28;;5506:14;;5576:28;5240:371;;:::o;14:131:13:-;-1:-1:-1;;;;;;88:32:13;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;:::-;384:5;150:245;-1:-1:-1;;;150:245:13:o;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;840:1;831:6;826:3;822:16;815:27;796:48;;592:258;;;:::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:13;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:13:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:13;;1343:180;-1:-1:-1;1343:180:13:o;1736:131::-;-1:-1:-1;;;;;1811:31:13;;1801:42;;1791:70;;1857:1;1854;1847:12;1872:315;1940:6;1948;2001:2;1989:9;1980:7;1976:23;1972:32;1969:52;;;2017:1;2014;2007:12;1969:52;2056:9;2043:23;2075:31;2100:5;2075:31;:::i;:::-;2125:5;2177:2;2162:18;;;;2149:32;;-1:-1:-1;;;1872:315:13:o;2192:456::-;2269:6;2277;2285;2338:2;2326:9;2317:7;2313:23;2309:32;2306:52;;;2354:1;2351;2344:12;2306:52;2393:9;2380:23;2412:31;2437:5;2412:31;:::i;:::-;2462:5;-1:-1:-1;2519:2:13;2504:18;;2491:32;2532:33;2491:32;2532:33;:::i;:::-;2192:456;;2584:7;;-1:-1:-1;;;2638:2:13;2623:18;;;;2610:32;;2192:456::o;2653:248::-;2721:6;2729;2782:2;2770:9;2761:7;2757:23;2753:32;2750:52;;;2798:1;2795;2788:12;2750:52;-1:-1:-1;;2821:23:13;;;2891:2;2876:18;;;2863:32;;-1:-1:-1;2653:248:13:o;3185:261::-;3258:6;3311:2;3299:9;3290:7;3286:23;3282:32;3279:52;;;3327:1;3324;3317:12;3279:52;3366:9;3353:23;3385:31;3410:5;3385:31;:::i;3885:388::-;3953:6;3961;4014:2;4002:9;3993:7;3989:23;3985:32;3982:52;;;4030:1;4027;4020:12;3982:52;4069:9;4056:23;4088:31;4113:5;4088:31;:::i;:::-;4138:5;-1:-1:-1;4195:2:13;4180:18;;4167:32;4208:33;4167:32;4208:33;:::i;:::-;4260:7;4250:17;;;3885:388;;;;;:::o;4278:118::-;4364:5;4357:13;4350:21;4343:5;4340:32;4330:60;;4386:1;4383;4376:12;4401:382;4466:6;4474;4527:2;4515:9;4506:7;4502:23;4498:32;4495:52;;;4543:1;4540;4533:12;4495:52;4582:9;4569:23;4601:31;4626:5;4601:31;:::i;:::-;4651:5;-1:-1:-1;4708:2:13;4693:18;;4680:32;4721:30;4680:32;4721:30;:::i;4788:936::-;4885:6;4893;4901;4909;4917;4970:3;4958:9;4949:7;4945:23;4941:33;4938:53;;;4987:1;4984;4977:12;4938:53;5026:9;5013:23;5045:31;5070:5;5045:31;:::i;:::-;5095:5;-1:-1:-1;5152:2:13;5137:18;;5124:32;5165:33;5124:32;5165:33;:::i;:::-;5217:7;-1:-1:-1;5271:2:13;5256:18;;5243:32;;-1:-1:-1;5326:2:13;5311:18;;5298:32;5349:18;5379:14;;;5376:34;;;5406:1;5403;5396:12;5376:34;5444:6;5433:9;5429:22;5419:32;;5489:7;5482:4;5478:2;5474:13;5470:27;5460:55;;5511:1;5508;5501:12;5460:55;5551:2;5538:16;5577:2;5569:6;5566:14;5563:34;;;5593:1;5590;5583:12;5563:34;5638:7;5633:2;5624:6;5620:2;5616:15;5612:24;5609:37;5606:57;;;5659:1;5656;5649:12;5606:57;4788:936;;;;-1:-1:-1;4788:936:13;;-1:-1:-1;5690:2:13;5682:11;;5712:6;4788:936;-1:-1:-1;;;4788:936:13:o;5729:380::-;5808:1;5804:12;;;;5851;;;5872:61;;5926:4;5918:6;5914:17;5904:27;;5872:61;5979:2;5971:6;5968:14;5948:18;5945:38;5942:161;;;6025:10;6020:3;6016:20;6013:1;6006:31;6060:4;6057:1;6050:15;6088:4;6085:1;6078:15;5942:161;;5729:380;;;:::o;7544:265::-;7584:7;7650:1;7646;7642:6;7638:14;7635:1;7632:21;7627:1;7620:9;7613:17;7609:45;7606:168;;;7696:10;7691:3;7687:20;7684:1;7677:31;7731:4;7728:1;7721:15;7759:4;7756:1;7749:15;7606:168;-1:-1:-1;7794:9:13;;7544:265::o;7814:217::-;7854:1;7880;7870:132;;7924:10;7919:3;7915:20;7912:1;7905:31;7959:4;7956:1;7949:15;7987:4;7984:1;7977:15;7870:132;-1:-1:-1;8016:9:13;;7814:217::o;8036:356::-;8238:2;8220:21;;;8257:18;;;8250:30;8316:34;8311:2;8296:18;;8289:62;8383:2;8368:18;;8036:356::o;9669:249::-;9738:6;9791:2;9779:9;9770:7;9766:23;9762:32;9759:52;;;9807:1;9804;9797:12;9759:52;9839:9;9833:16;9858:30;9882:5;9858:30;:::i;10268:184::-;10338:6;10391:2;10379:9;10370:7;10366:23;10362:32;10359:52;;;10407:1;10404;10397:12;10359:52;-1:-1:-1;10430:16:13;;10268:184;-1:-1:-1;10268:184:13:o;10457:245::-;10524:6;10577:2;10565:9;10556:7;10552:23;10548:32;10545:52;;;10593:1;10590;10583:12;10545:52;10625:9;10619:16;10644:28;10666:5;10644:28;:::i;11387:662::-;-1:-1:-1;;;;;11666:15:13;;;11648:34;;11718:15;;11713:2;11698:18;;11691:43;11765:2;11750:18;;11743:34;;;11813:3;11808:2;11793:18;;11786:31;;;11833:19;;11826:35;;;11591:4;11854:6;11904;11628:3;11883:19;;11870:49;11969:1;11963:3;11954:6;11943:9;11939:22;11935:32;11928:43;12039:3;12032:2;12028:7;12023:2;12015:6;12011:15;12007:29;11996:9;11992:45;11988:55;11980:63;;11387:662;;;;;;;;:::o;12470:127::-;12531:10;12526:3;12522:20;12519:1;12512:31;12562:4;12559:1;12552:15;12586:4;12583:1;12576:15;12602:884;12682:6;12735:2;12723:9;12714:7;12710:23;12706:32;12703:52;;;12751:1;12748;12741:12;12703:52;12784:9;12778:16;12813:18;12854:2;12846:6;12843:14;12840:34;;;12870:1;12867;12860:12;12840:34;12908:6;12897:9;12893:22;12883:32;;12953:7;12946:4;12942:2;12938:13;12934:27;12924:55;;12975:1;12972;12965:12;12924:55;13004:2;12998:9;13026:2;13022;13019:10;13016:36;;;13032:18;;:::i;:::-;13107:2;13101:9;13075:2;13161:13;;-1:-1:-1;;13157:22:13;;;13181:2;13153:31;13149:40;13137:53;;;13205:18;;;13225:22;;;13202:46;13199:72;;;13251:18;;:::i;:::-;13291:10;13287:2;13280:22;13326:2;13318:6;13311:18;13366:7;13361:2;13356;13352;13348:11;13344:20;13341:33;13338:53;;;13387:1;13384;13377:12;13338:53;13400:55;13452:2;13447;13439:6;13435:15;13430:2;13426;13422:11;13400:55;:::i;:::-;13474:6;12602:884;-1:-1:-1;;;;;;;12602:884:13:o;13898:489::-;-1:-1:-1;;;;;14167:15:13;;;14149:34;;14219:15;;14214:2;14199:18;;14192:43;14266:2;14251:18;;14244:34;;;14314:3;14309:2;14294:18;;14287:31;;;14092:4;;14335:46;;14361:19;;14353:6;14335:46;:::i;:::-;14327:54;13898:489;-1:-1:-1;;;;;;13898:489:13:o
Swarm Source
ipfs://fb9bbda9a881306992036e3fd1f8899878089498cd6334f657ce7325acd36c82
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.