ERC-721
Overview
Max Total Supply
1,166 GQ3
Holders
712
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
4 GQ3Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
GQ3
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import {ERC721} from "openzeppelin-contracts/token/ERC721/ERC721.sol"; import {RevokableDefaultOperatorFilterer} from "./Base/RevokableDefaultOperatorFilterer.sol"; import {Ownable} from "openzeppelin-contracts/access/Ownable.sol"; import {Strings} from "openzeppelin-contracts/utils/Strings.sol"; import {ReentrancyGuard} from "openzeppelin-contracts/utils/ReentrancyGuard.sol"; import {MerkleProof} from "openzeppelin-contracts/cryptography/MerkleProof.sol"; import {AccessControl} from "openzeppelin-contracts/access/AccessControl.sol"; // GGGGGGGGGGGGG QQQQQQQQQ 333333333333333 // GGG::::::::::::G QQ:::::::::QQ 3:::::::::::::::33 // GG:::::::::::::::G QQ:::::::::::::QQ 3::::::33333::::::3 // G:::::GGGGGGGG::::GQ:::::::QQQ:::::::Q3333333 3:::::3 // G:::::G GGGGGGQ::::::O Q::::::Q 3:::::3 // G:::::G Q:::::O Q:::::Q 3:::::3 // G:::::G Q:::::O Q:::::Q 33333333:::::3 // G:::::G GGGGGGGGGGQ:::::O Q:::::Q 3:::::::::::3 // G:::::G G::::::::GQ:::::O Q:::::Q 33333333:::::3 // G:::::G GGGGG::::GQ:::::O Q:::::Q 3:::::3 // G:::::G G::::GQ:::::O QQQQ:::::Q 3:::::3 // G:::::G G::::GQ::::::O Q::::::::Q 3:::::3 // G:::::GGGGGGGG::::GQ:::::::QQ::::::::Q3333333 3:::::3 // GG:::::::::::::::G QQ::::::::::::::Q 3::::::33333::::::3 // GGG::::::GGG:::G QQ:::::::::::Q 3:::::::::::::::33 // GGGGGG GGGG QQQQQQQQ::::QQ 333333333333333 // Q:::::Q // QQQQQQ contract GQ3 is ERC721, RevokableDefaultOperatorFilterer, AccessControl, ReentrancyGuard { uint256 public price; uint256 public maxSupply; uint256 public maxAmountPerTx; uint8 public phase; bool private revealed; string private contractURL; string private notRevealedUri; string private baseUri; bytes32 public merkleRoot; address private ownerAddress; uint256 private currentTokenId; mapping(address => uint256) private _minted; bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); constructor( string memory _notRevealedUri, string memory _revealedUri ) ERC721("GQ3 Issue 001: Change is Good", "GQ3") { price = 0.1957 ether; currentTokenId = 1; maxSupply = 1661; maxAmountPerTx = 1; phase = 1; // 1, 2, or 3 revealed = false; notRevealedUri = _notRevealedUri; baseUri = _revealedUri; ownerAddress = _msgSender(); _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(MINTER_ROLE, 0xEF0B56692F78A44CF4034b07F80204757c31Bcc9); } modifier onlyOwner() { require( hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Caller is not a admin" ); _; } modifier onlyMinter() { require(hasRole(MINTER_ROLE, _msgSender()), "Caller is not a minter"); _; } function owner() public view virtual override returns (address) { return ownerAddress; } function grantMinterRole(address _account) public onlyOwner { grantRole(MINTER_ROLE, _account); } function isOnAllowlist( bytes32[] memory _proof, address _claimer, uint256 _amount ) public view returns (bool) { bytes32 leaf = keccak256(abi.encodePacked(_claimer, _amount)); return MerkleProof.verify(_proof, merkleRoot, leaf); } function setMerkleRoot(bytes32 _merkleRoot) public onlyOwner { merkleRoot = _merkleRoot; } function setPhase(uint8 _newPhase) public onlyOwner { require(_newPhase < 4 && _newPhase > 0, "Invalid phase: 1, 2, 3"); phase = _newPhase; } function setPrice(uint256 _newPrice) public onlyOwner { price = _newPrice; } function setMaxSupply(uint256 _maxSupply) public onlyOwner { require( _maxSupply > maxSupply, "New supply should be bigger than old one" ); maxSupply = _maxSupply; } function setRevealed(bool _revealed) public onlyOwner { revealed = _revealed; } function setNotRevealedURI( string memory _newNotRevealedURI ) public onlyOwner { notRevealedUri = _newNotRevealedURI; } function setBaseURI(string memory _newBaseURI) public onlyOwner { baseUri = _newBaseURI; } function setMaxAmountPerTx(uint256 _maxAmount) public onlyOwner { require(_maxAmount > 0, "Invalid param provided"); maxAmountPerTx = _maxAmount; } function withdraw() public onlyOwner nonReentrant { uint256 _balance = address(this).balance; require(_balance > 0, "No amount to withdraw"); (bool success, ) = _msgSender().call{value: _balance}(""); require(success, "Transfer failed."); } function contractURI() public view returns (string memory) { return contractURL; } function setContractURI(string memory _contractURL) public onlyOwner { contractURL = _contractURL; } function mintedBalanceOf(address _address) public view returns (uint256) { return _minted[_address]; } function airdrop(address _to, uint256 _amount) public onlyOwner { require( totalSupply() + _amount <= maxSupply, "Cannot mint that many tokens." ); for (uint256 index = 0; index < _amount; index++) { _mint(_to, currentTokenId); currentTokenId += 1; } _minted[_to] += _amount; } function checkClaimEligibility( address _to, uint256 _ogHoldQuantity, uint256 _mintQuantity, bytes32[] memory _proof ) external view returns (string memory) { return _checkClaimEligibility(_to, _ogHoldQuantity, _mintQuantity, _proof); } function _checkClaimEligibility( address _to, uint256 _ogHoldQuantity, uint256 _mintQuantity, bytes32[] memory _proof ) internal view returns (string memory) { if (phase < 3) { if (!isOnAllowlist(_proof, _to, _ogHoldQuantity)) { return "Wallet address is not Allowlisted"; } } if (phase > 1 && _mintQuantity > maxAmountPerTx) { return "Cannot mint that many tokens per tx"; } if (phase == 1) { if (_minted[_to] + _mintQuantity > _ogHoldQuantity) { return "Cannot mint that many tokens per wallet"; } } else if (phase == 2) { if ( _minted[_to] + _mintQuantity > (_ogHoldQuantity + maxAmountPerTx) ) { return "Cannot mint that many tokens per wallet"; } } if (totalSupply() + _mintQuantity > maxSupply) { return "NFT is sold out"; } return ""; } function claimTo( address _to, uint256 _ogHoldQuantity, // When phase 2, 3, ignore it as 0 for non og holders uint256 _mintQuantity, bytes32[] memory _proof ) external payable onlyMinter { string memory eligibility = _checkClaimEligibility( _to, _ogHoldQuantity, _mintQuantity, _proof ); require(bytes(eligibility).length == 0, eligibility); require( msg.value >= _mintQuantity * price, "Not enough to pay for that" ); for (uint256 index = 0; index < _mintQuantity; index++) { _safeMint(_msgSender(), currentTokenId); currentTokenId += 1; } _minted[_to] += _mintQuantity; } function webMint( uint256 _ogHoldQuantity, // When phase 2, 3, ignore it as 0 for non og holders uint256 _mintQuantity, bytes32[] memory _proof ) external payable { string memory eligibility = _checkClaimEligibility( _msgSender(), _ogHoldQuantity, _mintQuantity, _proof ); require(bytes(eligibility).length == 0, eligibility); require( msg.value >= _mintQuantity * price, "Not enough to pay for that" ); for (uint256 index = 0; index < _mintQuantity; index++) { _mint(_msgSender(), currentTokenId); currentTokenId += 1; } _minted[_msgSender()] += _mintQuantity; } function tokenURI( uint256 _tokenId ) public view virtual override returns (string memory) { require(_exists(_tokenId), "NFT does not exist"); if (!revealed) { return notRevealedUri; } return string( abi.encodePacked(baseUri, Strings.toString(_tokenId), ".json") ); } function setApprovalForAll( address operator, bool approved ) public override onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } function approve( address operator, uint256 tokenId ) public override onlyAllowedOperatorApproval(operator) { super.approve(operator, tokenId); } function transferFrom( address from, address to, uint256 tokenId ) public override onlyAllowedOperator(from) { super.transferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, tokenId, data); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external view returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function unregister(address addr) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {RevokableOperatorFilterer} from "./RevokableOperatorFilterer.sol"; /** * @title RevokableDefaultOperatorFilterer * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription. * Note that OpenSea will disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. */ abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() RevokableOperatorFilterer(0x000000000000AAeB6D7670E522A718067333cd4E, DEFAULT_SUBSCRIPTION, true) {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {UpdatableOperatorFilterer} from "./UpdatableOperatorFilterer.sol"; import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; /** * @title RevokableOperatorFilterer * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The * Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at * any point. As implemented, this abstract contract allows the contract owner to permanently skip the * OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry * address cannot be further updated. * Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. */ abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer { error RegistryHasBeenRevoked(); error InitialRegistryAddressCannotBeZeroAddress(); bool public isOperatorFilterRegistryRevoked; constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe) { // don't allow creating a contract with a permanently revoked registry if (_registry == address(0)) { revert InitialRegistryAddressCannotBeZeroAddress(); } } function _checkFilterOperator(address operator) internal view virtual override { if (address(operatorFilterRegistry) != address(0)) { super._checkFilterOperator(operator); } } /** * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero * address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner. */ function updateOperatorFilterRegistryAddress(address newRegistry) public override { if (msg.sender != owner()) { revert OnlyOwner(); } // if registry has been revoked, do not allow further updates if (isOperatorFilterRegistryRevoked) { revert RegistryHasBeenRevoked(); } operatorFilterRegistry = IOperatorFilterRegistry(newRegistry); } /** * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner. */ function revokeOperatorFilterRegistry() public { if (msg.sender != owner()) { revert OnlyOwner(); } // if registry has been revoked, do not allow further updates if (isOperatorFilterRegistryRevoked) { revert RegistryHasBeenRevoked(); } // set to zero address to bypass checks operatorFilterRegistry = IOperatorFilterRegistry(address(0)); isOperatorFilterRegistryRevoked = true; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; /** * @title UpdatableOperatorFilterer * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another * registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the * OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address, * which will bypass registry checks. * Note that OpenSea will still disable creator fee enforcement if filtered operators begin fulfilling orders * on-chain, eg, if the registry is revoked or bypassed. * @dev This smart contract is meant to be inherited by token contracts so they can use the following: * - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods. * - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods. */ abstract contract UpdatableOperatorFilterer { error OperatorNotAllowed(address operator); error OnlyOwner(); IOperatorFilterRegistry public operatorFilterRegistry; constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) { IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry); operatorFilterRegistry = registry; // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(registry).code.length > 0) { if (subscribe) { registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { registry.register(address(this)); } } } } modifier onlyAllowedOperator(address from) virtual { // Allow spending tokens from addresses with balance // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred // from an EOA. if (from != msg.sender) { _checkFilterOperator(msg.sender); } _; } modifier onlyAllowedOperatorApproval(address operator) virtual { _checkFilterOperator(operator); _; } /** * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero * address, checks will be bypassed. OnlyOwner. */ function updateOperatorFilterRegistryAddress(address newRegistry) public virtual { if (msg.sender != owner()) { revert OnlyOwner(); } operatorFilterRegistry = IOperatorFilterRegistry(newRegistry); } /** * @dev assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract */ function owner() public view virtual returns (address); function _checkFilterOperator(address operator) internal view virtual { IOperatorFilterRegistry registry = operatorFilterRegistry; // Check registry code length to facilitate testing in environments without a deployed registry. if (address(registry) != address(0) && address(registry).code.length > 0) { if (!registry.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/EnumerableSet.sol"; import "../utils/Address.sol"; import "../GSN/Context.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address; struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../GSN/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 () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view 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 { emit OwnershipTransferred(_owner, address(0)); _owner = 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"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle trees (hash trees), */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } else { // Hash(current element of the proof + current computed hash) computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } } // Check if the computed hash (root) is equal to the provided root return computedHash == root; } }
// SPDX-License-Identifier: MIT 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 GSN 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 memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public virtual view override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } }
// SPDX-License-Identifier: MIT 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 pragma solidity ^0.8.0; import "../../GSN/Context.sol"; import "./IERC721.sol"; import "./IERC721Metadata.sol"; import "./IERC721Enumerable.sol"; import "./IERC721Receiver.sol"; import "../../introspection/ERC165.sol"; import "../../utils/Address.sol"; import "../../utils/EnumerableSet.sol"; import "../../utils/EnumerableMap.sol"; import "../../utils/Strings.sol"; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using Address for address; using EnumerableSet for EnumerableSet.UintSet; using EnumerableMap for EnumerableMap.UintToAddressMap; using Strings for uint256; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from holder address to their (enumerable) set of owned tokens mapping (address => EnumerableSet.UintSet) private _holderTokens; // Enumerable mapping from token ids to their owners EnumerableMap.UintToAddressMap private _tokenOwners; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; // Token name string private _name; // Token symbol string private _symbol; // Optional mapping for token URIs mapping (uint256 => string) private _tokenURIs; // Base URI string private _baseURI; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor (string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); _registerInterface(_INTERFACE_ID_ERC721_METADATA); _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _holderTokens[owner].length(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); } /** * @dev See {IERC721Metadata-name}. */ function name() public view override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public virtual view override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory _tokenURI = _tokenURIs[tokenId]; // If there is no base URI, return the token URI. if (bytes(_baseURI).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(_baseURI, _tokenURI)); } // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI. return string(abi.encodePacked(_baseURI, tokenId.toString())); } /** * @dev Returns the base URI set via {_setBaseURI}. This will be * automatically added as a prefix in {tokenURI} to each token's URI, or * to the token ID if no specific URI is set for that token ID. */ function baseURI() public view returns (string memory) { return _baseURI; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) { return _holderTokens[owner].at(index); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view override returns (uint256) { // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds return _tokenOwners.length(); } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view override returns (uint256) { (uint256 tokenId, ) = _tokenOwners.at(index); return tokenId; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view returns (bool) { return _tokenOwners.contains(tokenId); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: d* * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); // Clear metadata (if any) if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } _holderTokens[owner].remove(tokenId); _tokenOwners.remove(tokenId); emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _holderTokens[from].remove(tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(from, to, tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev Internal function to set the base URI for all token IDs. It is * automatically added as a prefix to the value returned in {tokenURI}, * or to the token ID if {tokenURI} is empty. */ function _setBaseURI(string memory baseURI_) internal virtual { _baseURI = baseURI_; } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) { if (!to.isContract()) { return true; } bytes memory returndata = to.functionCall(abi.encodeWithSelector( IERC721Receiver(to).onERC721Received.selector, _msgSender(), from, tokenId, _data ), "ERC721: transfer to non ERC721Receiver implementer"); bytes4 retval = abi.decode(returndata, (bytes4)); return (retval == _ERC721_RECEIVED); } function _approve(address to, uint256 tokenId) private { _tokenApprovals[tokenId] = to; emit Approval(ownerOf(tokenId), to, tokenId); } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns 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 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; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.3._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.3._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct MapEntry { bytes32 _key; bytes32 _value; } struct Map { // Storage of map keys and values MapEntry[] _entries; // Position of the entry defined by a key in the `entries` array, plus 1 // because index 0 means a key is not in the map. mapping (bytes32 => uint256) _indexes; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) { // Equivalent to !contains(map, key) map._entries.push(MapEntry({ _key: key, _value: value })); // The entry is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value map._indexes[key] = map._entries.length; return true; } else { map._entries[keyIndex - 1]._value = value; return false; } } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex != 0) { // Equivalent to contains(map, key) // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one // in the array, and then remove the last entry (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = keyIndex - 1; uint256 lastIndex = map._entries.length - 1; // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. MapEntry storage lastEntry = map._entries[lastIndex]; // Move the last entry to the index where the entry to delete is map._entries[toDeleteIndex] = lastEntry; // Update the index for the moved entry map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved entry was stored map._entries.pop(); // Delete the index for the deleted slot delete map._indexes[key]; return true; } else { return false; } } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._indexes[key] != 0; } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._entries.length; } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { require(map._entries.length > index, "EnumerableMap: index out of bounds"); MapEntry storage entry = map._entries[index]; return (entry._key, entry._value); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { return _get(map, key, "EnumerableMap: nonexistent key"); } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. */ function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. */ function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { /** * @dev Converts a `uint256` to its ASCII `string` 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); uint256 index = digits; temp = value; while (temp != 0) { buffer[--index] = bytes1(uint8(48 + uint256(temp % 10))); temp /= 10; } return string(buffer); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"_notRevealedUri","type":"string"},{"internalType":"string","name":"_revealedUri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InitialRegistryAddressCannotBeZeroAddress","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"RegistryHasBeenRevoked","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_ogHoldQuantity","type":"uint256"},{"internalType":"uint256","name":"_mintQuantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"checkClaimEligibility","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_ogHoldQuantity","type":"uint256"},{"internalType":"uint256","name":"_mintQuantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"claimTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"grantMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_claimer","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"isOnAllowlist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOperatorFilterRegistryRevoked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAmountPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"mintedBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilterRegistry","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phase","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeOperatorFilterRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","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":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","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":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_contractURL","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxAmount","type":"uint256"}],"name":"setMaxAmountPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newNotRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_newPhase","type":"uint8"}],"name":"setPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_revealed","type":"bool"}],"name":"setRevealed","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRegistry","type":"address"}],"name":"updateOperatorFilterRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ogHoldQuantity","type":"uint256"},{"internalType":"uint256","name":"_mintQuantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"webMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003c5a38038062003c5a83398101604081905262000034916200063d565b6daaeb6d7670e522a718067333cd4e733cc6cdda760b79bafa08df41ecfa224f810dceb660018282826040518060400160405280601d81526020017f475133204973737565203030313a204368616e676520697320476f6f640000008152506040518060400160405280600381526020016247513360e81b815250620000c76301ffc9a760e01b6200035b60201b60201c565b8151620000dc906006906020850190620004ca565b508051620000f2906007906020840190620004ca565b50620001056380ac58cd60e01b6200035b565b62000117635b5e139f60e01b6200035b565b6200012963780e9d6360e01b6200035b565b5050600a80546001600160a01b0319166001600160a01b03851690811790915583903b1562000264578115620001c357604051633e9f1edf60e11b81523060048201526001600160a01b038481166024830152821690637d3e3dbe906044015b600060405180830381600087803b158015620001a457600080fd5b505af1158015620001b9573d6000803e3d6000fd5b5050505062000264565b6001600160a01b03831615620002085760405163a0af290360e01b81523060048201526001600160a01b03848116602483015282169063a0af29039060440162000189565b604051632210724360e11b81523060048201526001600160a01b03821690634420e48690602401600060405180830381600087803b1580156200024a57600080fd5b505af11580156200025f573d6000803e3d6000fd5b505050505b505050506001600160a01b038316620002905760405163c49d17ad60e01b815260040160405180910390fd5b50506001600c8190556702b7441cf68b4000600d55601681905561067d600e55600f8190556010805461ffff19169091179055508151620002d9906012906020850190620004ca565b508051620002ef906013906020840190620004ca565b50601580546001600160a01b031916339081179091556200031390600090620003df565b620003537f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a673ef0b56692f78a44cf4034b07f80204757c31bcc9620003df565b5050620006e4565b6001600160e01b03198082161415620003ba5760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b620003eb8282620003ef565b5050565b6000828152600b60209081526040909120620004169183906200197a62000458821b17901c565b15620003eb5760405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b60006200046f836001600160a01b03841662000478565b90505b92915050565b6000818152600183016020526040812054620004c15750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000472565b50600062000472565b828054620004d890620006a7565b90600052602060002090601f016020900481019282620004fc576000855562000547565b82601f106200051757805160ff191683800117855562000547565b8280016001018555821562000547579182015b82811115620005475782518255916020019190600101906200052a565b506200055592915062000559565b5090565b5b808211156200055557600081556001016200055a565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200059857600080fd5b81516001600160401b0380821115620005b557620005b562000570565b604051601f8301601f19908116603f01168101908282118183101715620005e057620005e062000570565b81604052838152602092508683858801011115620005fd57600080fd5b600091505b8382101562000621578582018301518183018401529082019062000602565b83821115620006335760008385830101525b9695505050505050565b600080604083850312156200065157600080fd5b82516001600160401b03808211156200066957600080fd5b620006778683870162000586565b935060208501519150808211156200068e57600080fd5b506200069d8582860162000586565b9150509250929050565b600181811c90821680620006bc57607f821691505b60208210811415620006de57634e487b7160e01b600052602260045260246000fd5b50919050565b61356680620006f46000396000f3fe6080604052600436106103355760003560e01c80638ba4cc3c116101ab578063b8d1e532116100f7578063da312df711610095578063e985e9c51161006f578063e985e9c514610988578063ecba222a146109d1578063f26a9816146109f2578063f2c4ce1e14610a1257600080fd5b8063da312df714610933578063e0a8085314610953578063e8a3d4851461097357600080fd5b8063ca15c873116100d1578063ca15c873146108a9578063d5391393146108c9578063d547741f146108fd578063d5abeb011461091d57600080fd5b8063b8d1e53214610849578063c03afb5914610869578063c87b56dd1461088957600080fd5b806395d89b4111610164578063a22cb4651161013e578063a22cb465146107bd578063b0ccc31e146107dd578063b1c9fe6e146107fd578063b88d4fde1461082957600080fd5b806395d89b411461077d578063a035b1fe14610792578063a217fddf146107a857600080fd5b80638ba4cc3c146106bf5780638da5cb5b146106df5780639010d07c146106fd57806391b7f5ed1461071d57806391d148541461073d578063938e3d7b1461075d57600080fd5b80633ccfd60b116102855780635ef9432a116102235780636f8b44b0116101fd5780636f8b44b01461064957806370a08231146106695780637cb647591461068957806385b27c85146106a957600080fd5b80635ef9432a146105ff5780636352211e146106145780636c0360eb1461063457600080fd5b80634455c41c1161025f5780634455c41c146105765780634d74817f146105895780634f6ccce7146105bf57806355f804b3146105df57600080fd5b80633ccfd60b146105215780633dd1eb611461053657806342842e0e1461055657600080fd5b806323b872dd116102f25780632eb4a7ab116102cc5780632eb4a7ab146104ab5780632f2ff15d146104c15780632f745c59146104e157806336568abe1461050157600080fd5b806323b872dd14610448578063248a9ca31461046857806325b84d0d1461049857600080fd5b806301ffc9a71461033a57806306fdde0314610389578063081812fc146103ab578063095ea7b3146103e357806318160ddd146104055780631fb9133514610428575b600080fd5b34801561034657600080fd5b50610374610355366004612bfc565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561039557600080fd5b5061039e610a32565b6040516103809190612c71565b3480156103b757600080fd5b506103cb6103c6366004612c84565b610ac4565b6040516001600160a01b039091168152602001610380565b3480156103ef57600080fd5b506104036103fe366004612cb9565b610b51565b005b34801561041157600080fd5b5061041a610b6a565b604051908152602001610380565b34801561043457600080fd5b5061039e610443366004612d9f565b610b7b565b34801561045457600080fd5b50610403610463366004612e00565b610b94565b34801561047457600080fd5b5061041a610483366004612c84565b6000908152600b602052604090206002015490565b6104036104a6366004612d9f565b610bbf565b3480156104b757600080fd5b5061041a60145481565b3480156104cd57600080fd5b506104036104dc366004612e3c565b610d36565b3480156104ed57600080fd5b5061041a6104fc366004612cb9565b610dc4565b34801561050d57600080fd5b5061040361051c366004612e3c565b610def565b34801561052d57600080fd5b50610403610e69565b34801561054257600080fd5b50610403610551366004612e68565b610fc2565b34801561056257600080fd5b50610403610571366004612e00565b611016565b610403610584366004612e83565b61103b565b34801561059557600080fd5b5061041a6105a4366004612e68565b6001600160a01b031660009081526017602052604090205490565b3480156105cb57600080fd5b5061041a6105da366004612c84565b611139565b3480156105eb57600080fd5b506104036105fa366004612f2b565b61114f565b34801561060b57600080fd5b50610403611189565b34801561062057600080fd5b506103cb61062f366004612c84565b6111f7565b34801561064057600080fd5b5061039e61121f565b34801561065557600080fd5b50610403610664366004612c84565b61122e565b34801561067557600080fd5b5061041a610684366004612e68565b6112bc565b34801561069557600080fd5b506104036106a4366004612c84565b611348565b3480156106b557600080fd5b5061041a600f5481565b3480156106cb57600080fd5b506104036106da366004612cb9565b611374565b3480156106eb57600080fd5b506015546001600160a01b03166103cb565b34801561070957600080fd5b506103cb610718366004612f74565b611473565b34801561072957600080fd5b50610403610738366004612c84565b61148b565b34801561074957600080fd5b50610374610758366004612e3c565b6114b7565b34801561076957600080fd5b50610403610778366004612f2b565b6114cf565b34801561078957600080fd5b5061039e611509565b34801561079e57600080fd5b5061041a600d5481565b3480156107b457600080fd5b5061041a600081565b3480156107c957600080fd5b506104036107d8366004612fa4565b611518565b3480156107e957600080fd5b50600a546103cb906001600160a01b031681565b34801561080957600080fd5b506010546108179060ff1681565b60405160ff9091168152602001610380565b34801561083557600080fd5b50610403610844366004612fdb565b61152c565b34801561085557600080fd5b50610403610864366004612e68565b611559565b34801561087557600080fd5b5061040361088436600461304b565b6115d1565b34801561089557600080fd5b5061039e6108a4366004612c84565b611669565b3480156108b557600080fd5b5061041a6108c4366004612c84565b611788565b3480156108d557600080fd5b5061041a7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b34801561090957600080fd5b50610403610918366004612e3c565b61179f565b34801561092957600080fd5b5061041a600e5481565b34801561093f57600080fd5b5061037461094e36600461306e565b611820565b34801561095f57600080fd5b5061040361096e3660046130b5565b61187b565b34801561097f57600080fd5b5061039e6118bc565b34801561099457600080fd5b506103746109a33660046130d2565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156109dd57600080fd5b50600a5461037490600160a01b900460ff1681565b3480156109fe57600080fd5b50610403610a0d366004612c84565b6118cb565b348015610a1e57600080fd5b50610403610a2d366004612f2b565b611940565b606060068054610a41906130fc565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6d906130fc565b8015610aba5780601f10610a8f57610100808354040283529160200191610aba565b820191906000526020600020905b815481529060010190602001808311610a9d57829003601f168201915b5050505050905090565b6000610acf8261198f565b610b355760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b81610b5b8161199c565b610b6583836119b6565b505050565b6000610b766002611ac7565b905090565b6060610b8985858585611ad1565b90505b949350505050565b826001600160a01b0381163314610bae57610bae3361199c565b610bb9848484611c74565b50505050565b610be97f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336114b7565b610c2e5760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba10309036b4b73a32b960511b6044820152606401610b2c565b6000610c3c85858585611ad1565b905080516000148190610c625760405162461bcd60e51b8152600401610b2c9190612c71565b50600d54610c70908461314d565b341015610cbf5760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820746f2070617920666f7220746861740000000000006044820152606401610b2c565b60005b83811015610d0157610cd633601654611ca5565b600160166000828254610ce9919061316c565b90915550819050610cf981613184565b915050610cc2565b506001600160a01b03851660009081526017602052604081208054859290610d2a90849061316c565b90915550505050505050565b6000828152600b6020526040902060020154610d5290336114b7565b610db65760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526e0818591b5a5b881d1bc819dc985b9d608a1b6064820152608401610b2c565b610dc08282611cbf565b5050565b6001600160a01b0382166000908152600160205260408120610de69083611d18565b90505b92915050565b6001600160a01b0381163314610e5f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610b2c565b610dc08282611d24565b610e746000336114b7565b610e905760405162461bcd60e51b8152600401610b2c9061319f565b6002600c541415610ee35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b2c565b6002600c554780610f2e5760405162461bcd60e51b81526020600482015260156024820152744e6f20616d6f756e7420746f20776974686472617760581b6044820152606401610b2c565b604051600090339083908381818185875af1925050503d8060008114610f70576040519150601f19603f3d011682016040523d82523d6000602084013e610f75565b606091505b5050905080610fb95760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610b2c565b50506001600c55565b610fcd6000336114b7565b610fe95760405162461bcd60e51b8152600401610b2c9061319f565b6110137f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a682610d36565b50565b826001600160a01b0381163314611030576110303361199c565b610bb9848484611d7d565b600061104933858585611ad1565b90508051600014819061106f5760405162461bcd60e51b8152600401610b2c9190612c71565b50600d5461107d908461314d565b3410156110cc5760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820746f2070617920666f7220746861740000000000006044820152606401610b2c565b60005b8381101561110e576110e333601654611d98565b6001601660008282546110f6919061316c565b9091555081905061110681613184565b9150506110cf565b50336000908152601760205260408120805485929061112e90849061316c565b909155505050505050565b600080611147600284611eb0565b509392505050565b61115a6000336114b7565b6111765760405162461bcd60e51b8152600401610b2c9061319f565b8051610dc0906013906020840190612b4d565b6015546001600160a01b031633146111b457604051635fc483c560e01b815260040160405180910390fd5b600a54600160a01b900460ff16156111df57604051631551a48f60e11b815260040160405180910390fd5b600a80546001600160a81b031916600160a01b179055565b6000610de9826040518060600160405280602981526020016134e16029913960029190611ecc565b606060098054610a41906130fc565b6112396000336114b7565b6112555760405162461bcd60e51b8152600401610b2c9061319f565b600e5481116112b75760405162461bcd60e51b815260206004820152602860248201527f4e657720737570706c792073686f756c6420626520626967676572207468616e604482015267206f6c64206f6e6560c01b6064820152608401610b2c565b600e55565b60006001600160a01b0382166113275760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610b2c565b6001600160a01b0382166000908152600160205260409020610de990611ac7565b6113536000336114b7565b61136f5760405162461bcd60e51b8152600401610b2c9061319f565b601455565b61137f6000336114b7565b61139b5760405162461bcd60e51b8152600401610b2c9061319f565b600e54816113a7610b6a565b6113b1919061316c565b11156113ff5760405162461bcd60e51b815260206004820152601d60248201527f43616e6e6f74206d696e742074686174206d616e7920746f6b656e732e0000006044820152606401610b2c565b60005b818110156114415761141683601654611d98565b600160166000828254611429919061316c565b9091555081905061143981613184565b915050611402565b506001600160a01b0382166000908152601760205260408120805483929061146a90849061316c565b90915550505050565b6000828152600b60205260408120610de69083611d18565b6114966000336114b7565b6114b25760405162461bcd60e51b8152600401610b2c9061319f565b600d55565b6000828152600b60205260408120610de69083611ed9565b6114da6000336114b7565b6114f65760405162461bcd60e51b8152600401610b2c9061319f565b8051610dc0906011906020840190612b4d565b606060078054610a41906130fc565b816115228161199c565b610b658383611efb565b836001600160a01b0381163314611546576115463361199c565b61155285858585611fc0565b5050505050565b6015546001600160a01b0316331461158457604051635fc483c560e01b815260040160405180910390fd5b600a54600160a01b900460ff16156115af57604051631551a48f60e11b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6115dc6000336114b7565b6115f85760405162461bcd60e51b8152600401610b2c9061319f565b60048160ff1610801561160e575060008160ff16115b6116535760405162461bcd60e51b8152602060048201526016602482015275496e76616c69642070686173653a20312c20322c203360501b6044820152606401610b2c565b6010805460ff191660ff92909216919091179055565b60606116748261198f565b6116b55760405162461bcd60e51b815260206004820152601260248201527113919508191bd95cc81b9bdd08195e1a5cdd60721b6044820152606401610b2c565b601054610100900460ff1661175657601280546116d1906130fc565b80601f01602080910402602001604051908101604052809291908181526020018280546116fd906130fc565b801561174a5780601f1061171f5761010080835404028352916020019161174a565b820191906000526020600020905b81548152906001019060200180831161172d57829003601f168201915b50505050509050919050565b601361176183611ff2565b6040516020016117729291906131ea565b6040516020818303038152906040529050919050565b6000818152600b60205260408120610de990611ac7565b6000828152600b60205260409020600201546117bb90336114b7565b610e5f5760405162461bcd60e51b815260206004820152603060248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526f2061646d696e20746f207265766f6b6560801b6064820152608401610b2c565b6040516bffffffffffffffffffffffff19606084901b16602082015260348101829052600090819060540160405160208183030381529060405280519060200120905061187085601454836120fb565b9150505b9392505050565b6118866000336114b7565b6118a25760405162461bcd60e51b8152600401610b2c9061319f565b601080549115156101000261ff0019909216919091179055565b606060118054610a41906130fc565b6118d66000336114b7565b6118f25760405162461bcd60e51b8152600401610b2c9061319f565b6000811161193b5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c185c985b481c1c9bdd9a59195960521b6044820152606401610b2c565b600f55565b61194b6000336114b7565b6119675760405162461bcd60e51b8152600401610b2c9061319f565b8051610dc0906012906020840190612b4d565b6000610de6836001600160a01b0384166121aa565b6000610de96002836121f9565b600a546001600160a01b0316156110135761101381612211565b60006119c1826111f7565b9050806001600160a01b0316836001600160a01b03161415611a2f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610b2c565b336001600160a01b0382161480611a4b5750611a4b81336109a3565b611abd5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b2c565b610b6583836122d3565b6000610de9825490565b601054606090600360ff9091161015611b1357611aef828686611820565b611b135760405180606001604052806021815260200161349d602191399050610b8c565b601054600160ff909116118015611b2b5750600f5483115b15611b50576040518060600160405280602381526020016134be602391399050610b8c565b60105460ff1660011415611baf576001600160a01b0385166000908152601760205260409020548490611b8490859061316c565b1115611baa5760405180606001604052806027815260200161350a602791399050610b8c565b611c14565b60105460ff1660021415611c1457600f54611bca908561316c565b6001600160a01b038616600090815260176020526040902054611bee90859061316c565b1115611c145760405180606001604052806027815260200161350a602791399050610b8c565b600e5483611c20610b6a565b611c2a919061316c565b1115611c5c575060408051808201909152600f81526e139195081a5cc81cdbdb19081bdd5d608a1b6020820152610b8c565b50604080516020810190915260008152949350505050565b611c7e3382612341565b611c9a5760405162461bcd60e51b8152600401610b2c9061329c565b610b65838383612427565b610dc08282604051806020016040528060008152506125a8565b6000828152600b60205260409020611cd7908261197a565b15610dc05760405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b6000610de683836125db565b6000828152600b60205260409020611d3c9082612661565b15610dc05760405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b610b658383836040518060200160405280600081525061152c565b6001600160a01b038216611dee5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b2c565b611df78161198f565b15611e445760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b2c565b6001600160a01b0382166000908152600160205260409020611e669082612676565b50611e7360028284612682565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000808080611ebf8686612698565b9097909650945050505050565b6000610b8c848484612735565b6001600160a01b03811660009081526001830160205260408120541515610de6565b6001600160a01b038216331415611f545760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b2c565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611fca3383612341565b611fe65760405162461bcd60e51b8152600401610b2c9061329c565b610bb98484848461279e565b6060816120165750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612040578061202a81613184565b91506120399050600a83613303565b915061201a565b60008167ffffffffffffffff81111561205b5761205b612ce3565b6040519080825280601f01601f191660200182016040528015612085576020820181803683370190505b508593509050815b83156120f25761209e600a85613317565b6120a990603061316c565b60f81b826120b68361332b565b925082815181106120c9576120c9613342565b60200101906001600160f81b031916908160001a9053506120eb600a85613303565b935061208d565b50949350505050565b600081815b855181101561219f57600086828151811061211d5761211d613342565b6020026020010151905080831161215f57604080516020810185905290810182905260600160405160208183030381529060405280519060200120925061218c565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061219781613184565b915050612100565b509092149392505050565b60008181526001830160205260408120546121f157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610de9565b506000610de9565b60008181526001830160205260408120541515610de6565b600a546001600160a01b0316801580159061223657506000816001600160a01b03163b115b15610dc057604051633185c44d60e21b81523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa158015612287573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ab9190613358565b610dc057604051633b79c77360e21b81526001600160a01b0383166004820152602401610b2c565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612308826111f7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061234c8261198f565b6123ad5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b2c565b60006123b8836111f7565b9050806001600160a01b0316846001600160a01b031614806123f35750836001600160a01b03166123e884610ac4565b6001600160a01b0316145b80610b8c57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff16610b8c565b826001600160a01b031661243a826111f7565b6001600160a01b0316146124a25760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610b2c565b6001600160a01b0382166125045760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610b2c565b61250f6000826122d3565b6001600160a01b038316600090815260016020526040902061253190826127d1565b506001600160a01b03821660009081526001602052604090206125549082612676565b5061256160028284612682565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6125b28383611d98565b6125bf60008484846127dd565b610b655760405162461bcd60e51b8152600401610b2c90613375565b815460009082106126395760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610b2c565b82600001828154811061264e5761264e613342565b9060005260206000200154905092915050565b6000610de6836001600160a01b0384166128ae565b6000610de683836121aa565b6000610b8c84846001600160a01b0385166129a1565b8154600090819083106126f85760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610b2c565b600084600001848154811061270f5761270f613342565b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816127655760405162461bcd60e51b8152600401610b2c9190612c71565b50846127726001836133c7565b8154811061278257612782613342565b9060005260206000209060020201600101549150509392505050565b6127a9848484612427565b6127b5848484846127dd565b610bb95760405162461bcd60e51b8152600401610b2c90613375565b6000610de683836128ae565b60006001600160a01b0384163b6127f657506001610b8c565b6000612877630a85bd0160e11b3388878760405160240161281a94939291906133de565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505060405180606001604052806032815260200161346b603291396001600160a01b0388169190612a42565b905060008180602001905181019061288f919061341b565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b600081815260018301602052604081205480156129975760006128d26001836133c7565b85549091506000906128e6906001906133c7565b905060008660000182815481106128ff576128ff613342565b906000526020600020015490508087600001848154811061292257612922613342565b60009182526020909120015561293983600161316c565b6000828152600189016020526040902055865487908061295b5761295b613438565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610de9565b6000915050610de9565b600082815260018401602052604081205480612a06575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611874565b8285612a136001846133c7565b81548110612a2357612a23613342565b9060005260206000209060020201600101819055506000915050611874565b6060610b8c848460008585843b612a9b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b2c565b600080866001600160a01b03168587604051612ab7919061344e565b60006040518083038185875af1925050503d8060008114612af4576040519150601f19603f3d011682016040523d82523d6000602084013e612af9565b606091505b5091509150612b09828286612b14565b979650505050505050565b60608315612b23575081611874565b825115612b335782518084602001fd5b8160405162461bcd60e51b8152600401610b2c9190612c71565b828054612b59906130fc565b90600052602060002090601f016020900481019282612b7b5760008555612bc1565b82601f10612b9457805160ff1916838001178555612bc1565b82800160010185558215612bc1579182015b82811115612bc1578251825591602001919060010190612ba6565b50612bcd929150612bd1565b5090565b5b80821115612bcd5760008155600101612bd2565b6001600160e01b03198116811461101357600080fd5b600060208284031215612c0e57600080fd5b813561187481612be6565b60005b83811015612c34578181015183820152602001612c1c565b83811115610bb95750506000910152565b60008151808452612c5d816020860160208601612c19565b601f01601f19169290920160200192915050565b602081526000610de66020830184612c45565b600060208284031215612c9657600080fd5b5035919050565b80356001600160a01b0381168114612cb457600080fd5b919050565b60008060408385031215612ccc57600080fd5b612cd583612c9d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612d2257612d22612ce3565b604052919050565b600082601f830112612d3b57600080fd5b8135602067ffffffffffffffff821115612d5757612d57612ce3565b8160051b612d66828201612cf9565b9283528481018201928281019087851115612d8057600080fd5b83870192505b84831015612b0957823582529183019190830190612d86565b60008060008060808587031215612db557600080fd5b612dbe85612c9d565b93506020850135925060408501359150606085013567ffffffffffffffff811115612de857600080fd5b612df487828801612d2a565b91505092959194509250565b600080600060608486031215612e1557600080fd5b612e1e84612c9d565b9250612e2c60208501612c9d565b9150604084013590509250925092565b60008060408385031215612e4f57600080fd5b82359150612e5f60208401612c9d565b90509250929050565b600060208284031215612e7a57600080fd5b610de682612c9d565b600080600060608486031215612e9857600080fd5b8335925060208401359150604084013567ffffffffffffffff811115612ebd57600080fd5b612ec986828701612d2a565b9150509250925092565b600067ffffffffffffffff831115612eed57612eed612ce3565b612f00601f8401601f1916602001612cf9565b9050828152838383011115612f1457600080fd5b828260208301376000602084830101529392505050565b600060208284031215612f3d57600080fd5b813567ffffffffffffffff811115612f5457600080fd5b8201601f81018413612f6557600080fd5b610b8c84823560208401612ed3565b60008060408385031215612f8757600080fd5b50508035926020909101359150565b801515811461101357600080fd5b60008060408385031215612fb757600080fd5b612fc083612c9d565b91506020830135612fd081612f96565b809150509250929050565b60008060008060808587031215612ff157600080fd5b612ffa85612c9d565b935061300860208601612c9d565b925060408501359150606085013567ffffffffffffffff81111561302b57600080fd5b8501601f8101871361303c57600080fd5b612df487823560208401612ed3565b60006020828403121561305d57600080fd5b813560ff8116811461187457600080fd5b60008060006060848603121561308357600080fd5b833567ffffffffffffffff81111561309a57600080fd5b6130a686828701612d2a565b935050612e2c60208501612c9d565b6000602082840312156130c757600080fd5b813561187481612f96565b600080604083850312156130e557600080fd5b6130ee83612c9d565b9150612e5f60208401612c9d565b600181811c9082168061311057607f821691505b6020821081141561313157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561316757613167613137565b500290565b6000821982111561317f5761317f613137565b500190565b600060001982141561319857613198613137565b5060010190565b60208082526015908201527421b0b63632b91034b9903737ba10309030b236b4b760591b604082015260600190565b600081516131e0818560208601612c19565b9290920192915050565b600080845481600182811c91508083168061320657607f831692505b602080841082141561322657634e487b7160e01b86526022600452602486fd5b81801561323a576001811461324b57613278565b60ff19861689528489019650613278565b60008b81526020902060005b868110156132705781548b820152908501908301613257565b505084890196505b50505050505061187061328b82866131ce565b64173539b7b760d91b815260050190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b600082613312576133126132ed565b500490565b600082613326576133266132ed565b500690565b60008161333a5761333a613137565b506000190190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561336a57600080fd5b815161187481612f96565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000828210156133d9576133d9613137565b500390565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061341190830184612c45565b9695505050505050565b60006020828403121561342d57600080fd5b815161187481612be6565b634e487b7160e01b600052603160045260246000fd5b60008251613460818460208701612c19565b919091019291505056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e74657257616c6c65742061646472657373206973206e6f7420416c6c6f776c697374656443616e6e6f74206d696e742074686174206d616e7920746f6b656e73207065722074784552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e43616e6e6f74206d696e742074686174206d616e7920746f6b656e73207065722077616c6c6574a26469706673582212205faffd841f625bae69371d25a15d16975c16899cfea9561ea2c9661056e813c164736f6c634300080a0033000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000005f68747470733a2f2f677265656e2d67656e746c652d666f776c2d34312e6d7970696e6174612e636c6f75642f697066732f516d65335a674578653364565a694b4861506d76787470734b5347547933374348766954394a426f417735567a74000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106103355760003560e01c80638ba4cc3c116101ab578063b8d1e532116100f7578063da312df711610095578063e985e9c51161006f578063e985e9c514610988578063ecba222a146109d1578063f26a9816146109f2578063f2c4ce1e14610a1257600080fd5b8063da312df714610933578063e0a8085314610953578063e8a3d4851461097357600080fd5b8063ca15c873116100d1578063ca15c873146108a9578063d5391393146108c9578063d547741f146108fd578063d5abeb011461091d57600080fd5b8063b8d1e53214610849578063c03afb5914610869578063c87b56dd1461088957600080fd5b806395d89b4111610164578063a22cb4651161013e578063a22cb465146107bd578063b0ccc31e146107dd578063b1c9fe6e146107fd578063b88d4fde1461082957600080fd5b806395d89b411461077d578063a035b1fe14610792578063a217fddf146107a857600080fd5b80638ba4cc3c146106bf5780638da5cb5b146106df5780639010d07c146106fd57806391b7f5ed1461071d57806391d148541461073d578063938e3d7b1461075d57600080fd5b80633ccfd60b116102855780635ef9432a116102235780636f8b44b0116101fd5780636f8b44b01461064957806370a08231146106695780637cb647591461068957806385b27c85146106a957600080fd5b80635ef9432a146105ff5780636352211e146106145780636c0360eb1461063457600080fd5b80634455c41c1161025f5780634455c41c146105765780634d74817f146105895780634f6ccce7146105bf57806355f804b3146105df57600080fd5b80633ccfd60b146105215780633dd1eb611461053657806342842e0e1461055657600080fd5b806323b872dd116102f25780632eb4a7ab116102cc5780632eb4a7ab146104ab5780632f2ff15d146104c15780632f745c59146104e157806336568abe1461050157600080fd5b806323b872dd14610448578063248a9ca31461046857806325b84d0d1461049857600080fd5b806301ffc9a71461033a57806306fdde0314610389578063081812fc146103ab578063095ea7b3146103e357806318160ddd146104055780631fb9133514610428575b600080fd5b34801561034657600080fd5b50610374610355366004612bfc565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561039557600080fd5b5061039e610a32565b6040516103809190612c71565b3480156103b757600080fd5b506103cb6103c6366004612c84565b610ac4565b6040516001600160a01b039091168152602001610380565b3480156103ef57600080fd5b506104036103fe366004612cb9565b610b51565b005b34801561041157600080fd5b5061041a610b6a565b604051908152602001610380565b34801561043457600080fd5b5061039e610443366004612d9f565b610b7b565b34801561045457600080fd5b50610403610463366004612e00565b610b94565b34801561047457600080fd5b5061041a610483366004612c84565b6000908152600b602052604090206002015490565b6104036104a6366004612d9f565b610bbf565b3480156104b757600080fd5b5061041a60145481565b3480156104cd57600080fd5b506104036104dc366004612e3c565b610d36565b3480156104ed57600080fd5b5061041a6104fc366004612cb9565b610dc4565b34801561050d57600080fd5b5061040361051c366004612e3c565b610def565b34801561052d57600080fd5b50610403610e69565b34801561054257600080fd5b50610403610551366004612e68565b610fc2565b34801561056257600080fd5b50610403610571366004612e00565b611016565b610403610584366004612e83565b61103b565b34801561059557600080fd5b5061041a6105a4366004612e68565b6001600160a01b031660009081526017602052604090205490565b3480156105cb57600080fd5b5061041a6105da366004612c84565b611139565b3480156105eb57600080fd5b506104036105fa366004612f2b565b61114f565b34801561060b57600080fd5b50610403611189565b34801561062057600080fd5b506103cb61062f366004612c84565b6111f7565b34801561064057600080fd5b5061039e61121f565b34801561065557600080fd5b50610403610664366004612c84565b61122e565b34801561067557600080fd5b5061041a610684366004612e68565b6112bc565b34801561069557600080fd5b506104036106a4366004612c84565b611348565b3480156106b557600080fd5b5061041a600f5481565b3480156106cb57600080fd5b506104036106da366004612cb9565b611374565b3480156106eb57600080fd5b506015546001600160a01b03166103cb565b34801561070957600080fd5b506103cb610718366004612f74565b611473565b34801561072957600080fd5b50610403610738366004612c84565b61148b565b34801561074957600080fd5b50610374610758366004612e3c565b6114b7565b34801561076957600080fd5b50610403610778366004612f2b565b6114cf565b34801561078957600080fd5b5061039e611509565b34801561079e57600080fd5b5061041a600d5481565b3480156107b457600080fd5b5061041a600081565b3480156107c957600080fd5b506104036107d8366004612fa4565b611518565b3480156107e957600080fd5b50600a546103cb906001600160a01b031681565b34801561080957600080fd5b506010546108179060ff1681565b60405160ff9091168152602001610380565b34801561083557600080fd5b50610403610844366004612fdb565b61152c565b34801561085557600080fd5b50610403610864366004612e68565b611559565b34801561087557600080fd5b5061040361088436600461304b565b6115d1565b34801561089557600080fd5b5061039e6108a4366004612c84565b611669565b3480156108b557600080fd5b5061041a6108c4366004612c84565b611788565b3480156108d557600080fd5b5061041a7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b34801561090957600080fd5b50610403610918366004612e3c565b61179f565b34801561092957600080fd5b5061041a600e5481565b34801561093f57600080fd5b5061037461094e36600461306e565b611820565b34801561095f57600080fd5b5061040361096e3660046130b5565b61187b565b34801561097f57600080fd5b5061039e6118bc565b34801561099457600080fd5b506103746109a33660046130d2565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156109dd57600080fd5b50600a5461037490600160a01b900460ff1681565b3480156109fe57600080fd5b50610403610a0d366004612c84565b6118cb565b348015610a1e57600080fd5b50610403610a2d366004612f2b565b611940565b606060068054610a41906130fc565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6d906130fc565b8015610aba5780601f10610a8f57610100808354040283529160200191610aba565b820191906000526020600020905b815481529060010190602001808311610a9d57829003601f168201915b5050505050905090565b6000610acf8261198f565b610b355760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b81610b5b8161199c565b610b6583836119b6565b505050565b6000610b766002611ac7565b905090565b6060610b8985858585611ad1565b90505b949350505050565b826001600160a01b0381163314610bae57610bae3361199c565b610bb9848484611c74565b50505050565b610be97f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6336114b7565b610c2e5760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba10309036b4b73a32b960511b6044820152606401610b2c565b6000610c3c85858585611ad1565b905080516000148190610c625760405162461bcd60e51b8152600401610b2c9190612c71565b50600d54610c70908461314d565b341015610cbf5760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820746f2070617920666f7220746861740000000000006044820152606401610b2c565b60005b83811015610d0157610cd633601654611ca5565b600160166000828254610ce9919061316c565b90915550819050610cf981613184565b915050610cc2565b506001600160a01b03851660009081526017602052604081208054859290610d2a90849061316c565b90915550505050505050565b6000828152600b6020526040902060020154610d5290336114b7565b610db65760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526e0818591b5a5b881d1bc819dc985b9d608a1b6064820152608401610b2c565b610dc08282611cbf565b5050565b6001600160a01b0382166000908152600160205260408120610de69083611d18565b90505b92915050565b6001600160a01b0381163314610e5f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610b2c565b610dc08282611d24565b610e746000336114b7565b610e905760405162461bcd60e51b8152600401610b2c9061319f565b6002600c541415610ee35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b2c565b6002600c554780610f2e5760405162461bcd60e51b81526020600482015260156024820152744e6f20616d6f756e7420746f20776974686472617760581b6044820152606401610b2c565b604051600090339083908381818185875af1925050503d8060008114610f70576040519150601f19603f3d011682016040523d82523d6000602084013e610f75565b606091505b5050905080610fb95760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610b2c565b50506001600c55565b610fcd6000336114b7565b610fe95760405162461bcd60e51b8152600401610b2c9061319f565b6110137f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a682610d36565b50565b826001600160a01b0381163314611030576110303361199c565b610bb9848484611d7d565b600061104933858585611ad1565b90508051600014819061106f5760405162461bcd60e51b8152600401610b2c9190612c71565b50600d5461107d908461314d565b3410156110cc5760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820746f2070617920666f7220746861740000000000006044820152606401610b2c565b60005b8381101561110e576110e333601654611d98565b6001601660008282546110f6919061316c565b9091555081905061110681613184565b9150506110cf565b50336000908152601760205260408120805485929061112e90849061316c565b909155505050505050565b600080611147600284611eb0565b509392505050565b61115a6000336114b7565b6111765760405162461bcd60e51b8152600401610b2c9061319f565b8051610dc0906013906020840190612b4d565b6015546001600160a01b031633146111b457604051635fc483c560e01b815260040160405180910390fd5b600a54600160a01b900460ff16156111df57604051631551a48f60e11b815260040160405180910390fd5b600a80546001600160a81b031916600160a01b179055565b6000610de9826040518060600160405280602981526020016134e16029913960029190611ecc565b606060098054610a41906130fc565b6112396000336114b7565b6112555760405162461bcd60e51b8152600401610b2c9061319f565b600e5481116112b75760405162461bcd60e51b815260206004820152602860248201527f4e657720737570706c792073686f756c6420626520626967676572207468616e604482015267206f6c64206f6e6560c01b6064820152608401610b2c565b600e55565b60006001600160a01b0382166113275760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610b2c565b6001600160a01b0382166000908152600160205260409020610de990611ac7565b6113536000336114b7565b61136f5760405162461bcd60e51b8152600401610b2c9061319f565b601455565b61137f6000336114b7565b61139b5760405162461bcd60e51b8152600401610b2c9061319f565b600e54816113a7610b6a565b6113b1919061316c565b11156113ff5760405162461bcd60e51b815260206004820152601d60248201527f43616e6e6f74206d696e742074686174206d616e7920746f6b656e732e0000006044820152606401610b2c565b60005b818110156114415761141683601654611d98565b600160166000828254611429919061316c565b9091555081905061143981613184565b915050611402565b506001600160a01b0382166000908152601760205260408120805483929061146a90849061316c565b90915550505050565b6000828152600b60205260408120610de69083611d18565b6114966000336114b7565b6114b25760405162461bcd60e51b8152600401610b2c9061319f565b600d55565b6000828152600b60205260408120610de69083611ed9565b6114da6000336114b7565b6114f65760405162461bcd60e51b8152600401610b2c9061319f565b8051610dc0906011906020840190612b4d565b606060078054610a41906130fc565b816115228161199c565b610b658383611efb565b836001600160a01b0381163314611546576115463361199c565b61155285858585611fc0565b5050505050565b6015546001600160a01b0316331461158457604051635fc483c560e01b815260040160405180910390fd5b600a54600160a01b900460ff16156115af57604051631551a48f60e11b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6115dc6000336114b7565b6115f85760405162461bcd60e51b8152600401610b2c9061319f565b60048160ff1610801561160e575060008160ff16115b6116535760405162461bcd60e51b8152602060048201526016602482015275496e76616c69642070686173653a20312c20322c203360501b6044820152606401610b2c565b6010805460ff191660ff92909216919091179055565b60606116748261198f565b6116b55760405162461bcd60e51b815260206004820152601260248201527113919508191bd95cc81b9bdd08195e1a5cdd60721b6044820152606401610b2c565b601054610100900460ff1661175657601280546116d1906130fc565b80601f01602080910402602001604051908101604052809291908181526020018280546116fd906130fc565b801561174a5780601f1061171f5761010080835404028352916020019161174a565b820191906000526020600020905b81548152906001019060200180831161172d57829003601f168201915b50505050509050919050565b601361176183611ff2565b6040516020016117729291906131ea565b6040516020818303038152906040529050919050565b6000818152600b60205260408120610de990611ac7565b6000828152600b60205260409020600201546117bb90336114b7565b610e5f5760405162461bcd60e51b815260206004820152603060248201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60448201526f2061646d696e20746f207265766f6b6560801b6064820152608401610b2c565b6040516bffffffffffffffffffffffff19606084901b16602082015260348101829052600090819060540160405160208183030381529060405280519060200120905061187085601454836120fb565b9150505b9392505050565b6118866000336114b7565b6118a25760405162461bcd60e51b8152600401610b2c9061319f565b601080549115156101000261ff0019909216919091179055565b606060118054610a41906130fc565b6118d66000336114b7565b6118f25760405162461bcd60e51b8152600401610b2c9061319f565b6000811161193b5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c185c985b481c1c9bdd9a59195960521b6044820152606401610b2c565b600f55565b61194b6000336114b7565b6119675760405162461bcd60e51b8152600401610b2c9061319f565b8051610dc0906012906020840190612b4d565b6000610de6836001600160a01b0384166121aa565b6000610de96002836121f9565b600a546001600160a01b0316156110135761101381612211565b60006119c1826111f7565b9050806001600160a01b0316836001600160a01b03161415611a2f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610b2c565b336001600160a01b0382161480611a4b5750611a4b81336109a3565b611abd5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b2c565b610b6583836122d3565b6000610de9825490565b601054606090600360ff9091161015611b1357611aef828686611820565b611b135760405180606001604052806021815260200161349d602191399050610b8c565b601054600160ff909116118015611b2b5750600f5483115b15611b50576040518060600160405280602381526020016134be602391399050610b8c565b60105460ff1660011415611baf576001600160a01b0385166000908152601760205260409020548490611b8490859061316c565b1115611baa5760405180606001604052806027815260200161350a602791399050610b8c565b611c14565b60105460ff1660021415611c1457600f54611bca908561316c565b6001600160a01b038616600090815260176020526040902054611bee90859061316c565b1115611c145760405180606001604052806027815260200161350a602791399050610b8c565b600e5483611c20610b6a565b611c2a919061316c565b1115611c5c575060408051808201909152600f81526e139195081a5cc81cdbdb19081bdd5d608a1b6020820152610b8c565b50604080516020810190915260008152949350505050565b611c7e3382612341565b611c9a5760405162461bcd60e51b8152600401610b2c9061329c565b610b65838383612427565b610dc08282604051806020016040528060008152506125a8565b6000828152600b60205260409020611cd7908261197a565b15610dc05760405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b6000610de683836125db565b6000828152600b60205260409020611d3c9082612661565b15610dc05760405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b610b658383836040518060200160405280600081525061152c565b6001600160a01b038216611dee5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b2c565b611df78161198f565b15611e445760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b2c565b6001600160a01b0382166000908152600160205260409020611e669082612676565b50611e7360028284612682565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000808080611ebf8686612698565b9097909650945050505050565b6000610b8c848484612735565b6001600160a01b03811660009081526001830160205260408120541515610de6565b6001600160a01b038216331415611f545760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b2c565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611fca3383612341565b611fe65760405162461bcd60e51b8152600401610b2c9061329c565b610bb98484848461279e565b6060816120165750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612040578061202a81613184565b91506120399050600a83613303565b915061201a565b60008167ffffffffffffffff81111561205b5761205b612ce3565b6040519080825280601f01601f191660200182016040528015612085576020820181803683370190505b508593509050815b83156120f25761209e600a85613317565b6120a990603061316c565b60f81b826120b68361332b565b925082815181106120c9576120c9613342565b60200101906001600160f81b031916908160001a9053506120eb600a85613303565b935061208d565b50949350505050565b600081815b855181101561219f57600086828151811061211d5761211d613342565b6020026020010151905080831161215f57604080516020810185905290810182905260600160405160208183030381529060405280519060200120925061218c565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061219781613184565b915050612100565b509092149392505050565b60008181526001830160205260408120546121f157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610de9565b506000610de9565b60008181526001830160205260408120541515610de6565b600a546001600160a01b0316801580159061223657506000816001600160a01b03163b115b15610dc057604051633185c44d60e21b81523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa158015612287573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122ab9190613358565b610dc057604051633b79c77360e21b81526001600160a01b0383166004820152602401610b2c565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612308826111f7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061234c8261198f565b6123ad5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610b2c565b60006123b8836111f7565b9050806001600160a01b0316846001600160a01b031614806123f35750836001600160a01b03166123e884610ac4565b6001600160a01b0316145b80610b8c57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff16610b8c565b826001600160a01b031661243a826111f7565b6001600160a01b0316146124a25760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610b2c565b6001600160a01b0382166125045760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610b2c565b61250f6000826122d3565b6001600160a01b038316600090815260016020526040902061253190826127d1565b506001600160a01b03821660009081526001602052604090206125549082612676565b5061256160028284612682565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6125b28383611d98565b6125bf60008484846127dd565b610b655760405162461bcd60e51b8152600401610b2c90613375565b815460009082106126395760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610b2c565b82600001828154811061264e5761264e613342565b9060005260206000200154905092915050565b6000610de6836001600160a01b0384166128ae565b6000610de683836121aa565b6000610b8c84846001600160a01b0385166129a1565b8154600090819083106126f85760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610b2c565b600084600001848154811061270f5761270f613342565b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816127655760405162461bcd60e51b8152600401610b2c9190612c71565b50846127726001836133c7565b8154811061278257612782613342565b9060005260206000209060020201600101549150509392505050565b6127a9848484612427565b6127b5848484846127dd565b610bb95760405162461bcd60e51b8152600401610b2c90613375565b6000610de683836128ae565b60006001600160a01b0384163b6127f657506001610b8c565b6000612877630a85bd0160e11b3388878760405160240161281a94939291906133de565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505060405180606001604052806032815260200161346b603291396001600160a01b0388169190612a42565b905060008180602001905181019061288f919061341b565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b600081815260018301602052604081205480156129975760006128d26001836133c7565b85549091506000906128e6906001906133c7565b905060008660000182815481106128ff576128ff613342565b906000526020600020015490508087600001848154811061292257612922613342565b60009182526020909120015561293983600161316c565b6000828152600189016020526040902055865487908061295b5761295b613438565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610de9565b6000915050610de9565b600082815260018401602052604081205480612a06575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611874565b8285612a136001846133c7565b81548110612a2357612a23613342565b9060005260206000209060020201600101819055506000915050611874565b6060610b8c848460008585843b612a9b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b2c565b600080866001600160a01b03168587604051612ab7919061344e565b60006040518083038185875af1925050503d8060008114612af4576040519150601f19603f3d011682016040523d82523d6000602084013e612af9565b606091505b5091509150612b09828286612b14565b979650505050505050565b60608315612b23575081611874565b825115612b335782518084602001fd5b8160405162461bcd60e51b8152600401610b2c9190612c71565b828054612b59906130fc565b90600052602060002090601f016020900481019282612b7b5760008555612bc1565b82601f10612b9457805160ff1916838001178555612bc1565b82800160010185558215612bc1579182015b82811115612bc1578251825591602001919060010190612ba6565b50612bcd929150612bd1565b5090565b5b80821115612bcd5760008155600101612bd2565b6001600160e01b03198116811461101357600080fd5b600060208284031215612c0e57600080fd5b813561187481612be6565b60005b83811015612c34578181015183820152602001612c1c565b83811115610bb95750506000910152565b60008151808452612c5d816020860160208601612c19565b601f01601f19169290920160200192915050565b602081526000610de66020830184612c45565b600060208284031215612c9657600080fd5b5035919050565b80356001600160a01b0381168114612cb457600080fd5b919050565b60008060408385031215612ccc57600080fd5b612cd583612c9d565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612d2257612d22612ce3565b604052919050565b600082601f830112612d3b57600080fd5b8135602067ffffffffffffffff821115612d5757612d57612ce3565b8160051b612d66828201612cf9565b9283528481018201928281019087851115612d8057600080fd5b83870192505b84831015612b0957823582529183019190830190612d86565b60008060008060808587031215612db557600080fd5b612dbe85612c9d565b93506020850135925060408501359150606085013567ffffffffffffffff811115612de857600080fd5b612df487828801612d2a565b91505092959194509250565b600080600060608486031215612e1557600080fd5b612e1e84612c9d565b9250612e2c60208501612c9d565b9150604084013590509250925092565b60008060408385031215612e4f57600080fd5b82359150612e5f60208401612c9d565b90509250929050565b600060208284031215612e7a57600080fd5b610de682612c9d565b600080600060608486031215612e9857600080fd5b8335925060208401359150604084013567ffffffffffffffff811115612ebd57600080fd5b612ec986828701612d2a565b9150509250925092565b600067ffffffffffffffff831115612eed57612eed612ce3565b612f00601f8401601f1916602001612cf9565b9050828152838383011115612f1457600080fd5b828260208301376000602084830101529392505050565b600060208284031215612f3d57600080fd5b813567ffffffffffffffff811115612f5457600080fd5b8201601f81018413612f6557600080fd5b610b8c84823560208401612ed3565b60008060408385031215612f8757600080fd5b50508035926020909101359150565b801515811461101357600080fd5b60008060408385031215612fb757600080fd5b612fc083612c9d565b91506020830135612fd081612f96565b809150509250929050565b60008060008060808587031215612ff157600080fd5b612ffa85612c9d565b935061300860208601612c9d565b925060408501359150606085013567ffffffffffffffff81111561302b57600080fd5b8501601f8101871361303c57600080fd5b612df487823560208401612ed3565b60006020828403121561305d57600080fd5b813560ff8116811461187457600080fd5b60008060006060848603121561308357600080fd5b833567ffffffffffffffff81111561309a57600080fd5b6130a686828701612d2a565b935050612e2c60208501612c9d565b6000602082840312156130c757600080fd5b813561187481612f96565b600080604083850312156130e557600080fd5b6130ee83612c9d565b9150612e5f60208401612c9d565b600181811c9082168061311057607f821691505b6020821081141561313157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561316757613167613137565b500290565b6000821982111561317f5761317f613137565b500190565b600060001982141561319857613198613137565b5060010190565b60208082526015908201527421b0b63632b91034b9903737ba10309030b236b4b760591b604082015260600190565b600081516131e0818560208601612c19565b9290920192915050565b600080845481600182811c91508083168061320657607f831692505b602080841082141561322657634e487b7160e01b86526022600452602486fd5b81801561323a576001811461324b57613278565b60ff19861689528489019650613278565b60008b81526020902060005b868110156132705781548b820152908501908301613257565b505084890196505b50505050505061187061328b82866131ce565b64173539b7b760d91b815260050190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b600082613312576133126132ed565b500490565b600082613326576133266132ed565b500690565b60008161333a5761333a613137565b506000190190565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561336a57600080fd5b815161187481612f96565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000828210156133d9576133d9613137565b500390565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061341190830184612c45565b9695505050505050565b60006020828403121561342d57600080fd5b815161187481612be6565b634e487b7160e01b600052603160045260246000fd5b60008251613460818460208701612c19565b919091019291505056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e74657257616c6c65742061646472657373206973206e6f7420416c6c6f776c697374656443616e6e6f74206d696e742074686174206d616e7920746f6b656e73207065722074784552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e43616e6e6f74206d696e742074686174206d616e7920746f6b656e73207065722077616c6c6574a26469706673582212205faffd841f625bae69371d25a15d16975c16899cfea9561ea2c9661056e813c164736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000005f68747470733a2f2f677265656e2d67656e746c652d666f776c2d34312e6d7970696e6174612e636c6f75642f697066732f516d65335a674578653364565a694b4861506d76787470734b5347547933374348766954394a426f417735567a74000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _notRevealedUri (string): https://green-gentle-fowl-41.mypinata.cloud/ipfs/Qme3ZgExe3dVZiKHaPmvxtpsKSGTy37CHviT9JBoAw5Vzt
Arg [1] : _revealedUri (string):
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 000000000000000000000000000000000000000000000000000000000000005f
Arg [3] : 68747470733a2f2f677265656e2d67656e746c652d666f776c2d34312e6d7970
Arg [4] : 696e6174612e636c6f75642f697066732f516d65335a674578653364565a694b
Arg [5] : 4861506d76787470734b5347547933374348766954394a426f417735567a7400
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
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.