ERC-721
Overview
Max Total Supply
184 CBLOCKS
Holders
147
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 CBLOCKSLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
CuratedBlocks
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC165.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IArrayErrors.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IEtherErrors.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/INFTSupplyErrors.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721Errors.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721Receiver.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721Enumerable.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721Metadata.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/utils/ERC173.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/utils/ERC2981.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/utils/ContractState.sol"; import "@lambdalf-dev/ethereum-contracts/contracts/utils/Whitelist_ECDSA.sol"; import "operator-filter-registry/src/UpdatableOperatorFilterer.sol"; contract CuratedBlocks is IArrayErrors, IEtherErrors, INFTSupplyErrors, IERC721Errors, IERC721, IERC721Enumerable, IERC721Metadata, IERC165, ERC173, ERC2981, ContractState, Whitelist_ECDSA, UpdatableOperatorFilterer { // ************************************** // ***** BYTECODE VARIABLES ***** // ************************************** address public constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); address public constant DEFAULT_OPERATOR_FILTER_REGISTRY = address(0x000000000000AAeB6D7670E522A718067333cd4E); uint256 public constant MAX_BATCH = 10; uint8 public constant MAGMA_SALE = 1; uint8 public constant PRIVATE_SALE = 2; uint8 public constant WAITLIST_SALE = 3; string public constant name = "CuratedBlocks Genesis"; string public constant symbol = "CBLOCKS"; // ************************************** // ************************************** // ***** STORAGE VARIABLES ***** // ************************************** uint256 public maxSupply; address public treasury; string private _baseUri; uint256 private _nextId = 3; // Mapping from token ID to approved address mapping(uint256 => address) private _approvals; // List of owner addresses mapping(uint256 => address) private _owners; // Token owners mapped to balance mapping(address => uint256) private _balances; // Token owner mapped to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Phase mapped to sale price mapping(uint8 => uint256) private _salePrice; // ************************************** constructor(address airdropAddress_, address royaltyRecipient_, address treasury_, address signerWallet_, uint256 maxSupply_) UpdatableOperatorFilterer(DEFAULT_OPERATOR_FILTER_REGISTRY, DEFAULT_SUBSCRIPTION, true) { maxSupply = maxSupply_; _salePrice[MAGMA_SALE] = 0.044 ether; _salePrice[PRIVATE_SALE] = 0.055 ether; _salePrice[WAITLIST_SALE] = 0.055 ether; treasury = treasury_; _setOwner(msg.sender); _setRoyaltyInfo(royaltyRecipient_, 250); _setWhitelist(signerWallet_); _owners[1] = airdropAddress_; _owners[2] = airdropAddress_; } // ************************************** // ***** MODIFIER ***** // ************************************** /** * @dev Ensures the token exist. * A token exists if it has been minted and is not owned by the null address. * * @param tokenId_ identifier of the NFT being referenced */ modifier exists(uint256 tokenId_) { if (! _exists(tokenId_)) { revert IERC721_NONEXISTANT_TOKEN(tokenId_); } _; } // ************************************** // ************************************** // ***** INTERNAL ***** // ************************************** /** * @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 owning the token being transferred * @param to_ address the token is being transferred to * @param tokenId_ identifier of the NFT being referenced * @param data_ optional data to send along with the call * * @return whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from_, address to_, uint256 tokenId_, bytes memory data_) internal 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. // // IMPORTANT // It is unsafe to assume that an address not flagged by this method // is an externally-owned account (EOA) and not a contract. // // Among others, the following types of addresses will not be flagged: // // - 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 uint256 _size_; assembly { _size_ := extcodesize(to_) } // If address is a contract, check that it is aware of how to handle ERC721 tokens if (_size_ > 0) { try IERC721Receiver(to_).onERC721Received(msg.sender, from_, tokenId_, data_) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert IERC721_NON_ERC721_RECEIVER(to_); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Internal function to process whitelist status. * * @param account_ address minting a token * @param currentState_ the current contract state * @param whitelistType_ identifies the whitelist used * @param alloted_ the maximum alloted for that user * @param qty_ the amount of tokens to be minted * @param proof_ the signature to verify whitelist allocation */ function _processWhitelist(address account_, uint8 currentState_, uint8 whitelistType_, uint256 alloted_, uint256 qty_, Proof memory proof_) internal { uint256 _allowed_; if (currentState_ == MAGMA_SALE) { _allowed_ = checkWhitelistAllowance(account_, MAGMA_SALE, alloted_, proof_); if (_allowed_ < qty_) { revert Whitelist_FORBIDDEN(account_); } _consumeWhitelist(account_, MAGMA_SALE, qty_); } else if (currentState_ == PRIVATE_SALE) { if (whitelistType_ == MAGMA_SALE) { _allowed_ = checkWhitelistAllowance(account_, MAGMA_SALE, alloted_, proof_); if (_allowed_ < qty_) { revert Whitelist_FORBIDDEN(account_); } _consumeWhitelist(account_, MAGMA_SALE, qty_); } else { _allowed_ = checkWhitelistAllowance(account_, PRIVATE_SALE, alloted_, proof_); if (_allowed_ < qty_) { revert Whitelist_FORBIDDEN(account_); } _consumeWhitelist(account_, PRIVATE_SALE, qty_); } } else { checkWhitelistAllowance(account_, WAITLIST_SALE, 1, proof_); } } /** * @dev Internal function returning whether a token exists. * A token exists if it has been minted and is not owned by the null address. * * Note: this function must be overriden if tokens are burnable. * * @param tokenId_ identifier of the NFT being referenced * * @return whether the token exists */ function _exists(uint256 tokenId_) internal view returns (bool) { if (tokenId_ == 0) { return false; } return _owners[tokenId_] != address(0); } /** * @dev Internal function returning whether `operator_` is allowed to handle `tokenId_` * * Note: To avoid multiple checks for the same data, it is assumed * that existence of `tokenId_` has been verified prior via {_exists} * If it hasn't been verified, this function might panic * * @param operator_ address that tries to handle the token * @param tokenId_ identifier of the NFT being referenced * * @return whether `operator_` is allowed to manage the token */ function _isApprovedOrOwner(address tokenOwner_, address operator_, uint256 tokenId_) internal view returns (bool) { return operator_ == tokenOwner_ || operator_ == getApproved(tokenId_) || isApprovedForAll(tokenOwner_, operator_); } /** * @dev Mints a token and transfer it to `to_`. * * This internal function can be used to perform token minting. * If the Vested Pass contract is set, it will also burn a vested pass from the token receiver * * @param to_ address receiving the tokens * * Emits a {Transfer} event. */ function _mint(address to_, uint256 tokenId_) internal { _owners[tokenId_] = to_; emit Transfer(address(0), to_, tokenId_); } /** * @dev Internal function returning the owner of the `tokenId_` token. * * @param tokenId_ identifier of the NFT being referenced * * @return address of the token owner */ function _ownerOf(uint256 tokenId_) internal view returns (address) { return _owners[tokenId_]; } /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function _toString(uint256 value_) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value_ } 1 {} { // solhint-disable-line str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } /** * @dev Internal functions that counts the NFTs tracked by this contract. * * @return the number of NFTs in existence */ function _totalSupply() internal view virtual returns (uint256) { return supplyMinted(); } /** * @dev Transfers `tokenId_` from `from_` to `to_`. * * This internal function can be used to implement alternative mechanisms to perform * token transfer, such as signature-based, or token burning. * * @param from_ the current owner of the NFT * @param to_ the new owner * @param tokenId_ identifier of the NFT being referenced * * Emits a {Transfer} event. */ function _transfer(address from_, address to_, uint256 tokenId_) internal { unchecked { ++_balances[to_]; --_balances[from_]; } _owners[tokenId_] = to_; _approvals[tokenId_] = address(0); emit Transfer(from_, to_, tokenId_); } // ************************************** // ************************************** // ***** PUBLIC ***** // ************************************** /** * @notice Mints `qty_` tokens and transfers them to the caller. * * @param qty_ : the amount of tokens to be minted * @param alloted_ : the maximum alloted for that user * @param whitelistType_ : identifies the whitelist used * @param proof_ : the signature to verify whitelist allocation * * Requirements: * * - Sale state must not be {PAUSED}. * - Caller must send enough ether to pay for `qty_` tokens at current sale state price. * - Caller must be allowed to mint `qty_` tokens during `whitelistType_` sale state. */ function mint(uint256 qty_, uint256 alloted_, uint8 whitelistType_, Proof calldata proof_) public payable isNotState(PAUSED) { uint8 _currentState_ = getContractState(); if (qty_ > MAX_BATCH) { revert NFT_MAX_BATCH(qty_, MAX_BATCH); } uint256 _remainingSupply_ = maxSupply - supplyMinted(); if (qty_ > _remainingSupply_) { revert NFT_MAX_SUPPLY(qty_, _remainingSupply_); } uint256 _expected_ = qty_ * _salePrice[whitelistType_]; if (_expected_ != msg.value) { revert ETHER_INCORRECT_PRICE(msg.value, _expected_); } _processWhitelist(msg.sender, _currentState_, whitelistType_, alloted_, qty_, proof_); uint256 _firstToken_ = _nextId; uint256 _nextStart_ = _firstToken_ + qty_; unchecked { _balances[msg.sender] += qty_; _nextId += qty_; } while (_firstToken_ < _nextStart_) { _mint(msg.sender, _firstToken_); unchecked { _firstToken_ ++; } } } // *********** // * IERC721 * // *********** /** * @notice Gives permission to `to_` to transfer the token number `tokenId_` on behalf of its owner. * 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. * * @param to_ The new approved NFT controller * @param tokenId_ The NFT to approve * * Requirements: * * - The token number `tokenId_` must exist. * - The caller must own the token or be an approved operator. * - Must emit an {Approval} event. */ function approve(address to_, uint256 tokenId_) public override exists(tokenId_) onlyAllowedOperatorApproval(msg.sender) { address _tokenOwner_ = _ownerOf(tokenId_); if (to_ == _tokenOwner_) { revert IERC721_INVALID_APPROVAL(to_); } bool _isApproved_ = _isApprovedOrOwner(_tokenOwner_, msg.sender, tokenId_); if (! _isApproved_) { revert IERC721_CALLER_NOT_APPROVED(_tokenOwner_, msg.sender, tokenId_); } _approvals[tokenId_] = to_; emit Approval(_tokenOwner_, to_, tokenId_); } /** * @notice Transfers the token number `tokenId_` from `from_` to `to_`. * * @param from_ The current owner of the NFT * @param to_ The new owner * @param tokenId_ identifier of the NFT being referenced * * Requirements: * * - The token number `tokenId_` must exist. * - `from_` must be the token owner. * - The caller must own the token or be an approved operator. * - `to_` must not be the zero address. * - If `to_` is a contract, it must implement {IERC721Receiver-onERC721Received} with a return value of `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, * - Must emit a {Transfer} event. */ function safeTransferFrom(address from_, address to_, uint256 tokenId_) public override { safeTransferFrom(from_, to_, tokenId_, ""); } /** * @notice Transfers the token number `tokenId_` from `from_` to `to_`. * * @param from_ The current owner of the NFT * @param to_ The new owner * @param tokenId_ identifier of the NFT being referenced * @param data_ Additional data with no specified format, sent in call to `to_` * * Requirements: * * - The token number `tokenId_` must exist. * - `from_` must be the token owner. * - The caller must own the token or be an approved operator. * - `to_` must not be the zero address. * - If `to_` is a contract, it must implement {IERC721Receiver-onERC721Received} with a return value of `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, * - Must emit a {Transfer} event. */ function safeTransferFrom(address from_, address to_, uint256 tokenId_, bytes memory data_) public override { transferFrom(from_, to_, tokenId_); if (! _checkOnERC721Received(from_, to_, tokenId_, data_)) { revert IERC721_NON_ERC721_RECEIVER(to_); } } /** * @notice Allows or disallows `operator_` to manage the caller's tokens on their behalf. * * @param operator_ Address to add to the set of authorized operators * @param approved_ True if the operator is approved, false to revoke approval * * Requirements: * * - Must emit an {ApprovalForAll} event. */ function setApprovalForAll(address operator_, bool approved_) public override onlyAllowedOperatorApproval(msg.sender) { address _account_ = msg.sender; if (operator_ == _account_) { revert IERC721_INVALID_APPROVAL(operator_); } _operatorApprovals[_account_][operator_] = approved_; emit ApprovalForAll(_account_, operator_, approved_); } /** * @notice Transfers the token number `tokenId_` from `from_` to `to_`. * * @param from_ the current owner of the NFT * @param to_ the new owner * @param tokenId_ identifier of the NFT being referenced * * Requirements: * * - The token number `tokenId_` must exist. * - `from_` must be the token owner. * - The caller must own the token or be an approved operator. * - `to_` must not be the zero address. * - Must emit a {Transfer} event. */ function transferFrom(address from_, address to_, uint256 tokenId_) public override onlyAllowedOperator(msg.sender) { if (to_ == address(0)) { revert IERC721_INVALID_TRANSFER(); } address _tokenOwner_ = ownerOf(tokenId_); if (from_ != _tokenOwner_) { revert IERC721_INVALID_TRANSFER_FROM(_tokenOwner_, from_, tokenId_); } if (! _isApprovedOrOwner(_tokenOwner_, msg.sender, tokenId_)) { revert IERC721_CALLER_NOT_APPROVED(_tokenOwner_, msg.sender, tokenId_); } _transfer(_tokenOwner_, to_, tokenId_); } // *********** // ************************************** // ************************************** // ***** CONTRACT_OWNER ***** // ************************************** /** * @notice Reduces the max supply. * * @param newMaxSupply_ : the new max supply * * Requirements: * * - Caller must be the contract owner. * - `newMaxSupply_` must be lower than `maxSupply`. * - `newMaxSupply_` must be higher than `_nextId`. */ function reduceSupply(uint256 newMaxSupply_) public onlyOwner { if (newMaxSupply_ > maxSupply || newMaxSupply_ < supplyMinted()) { revert NFT_INVALID_SUPPLY(); } maxSupply = newMaxSupply_; } /** * @notice Updates the baseUri for the tokens. * * @param newBaseUri_ : the new baseUri for the tokens * * Requirements: * * - Caller must be the contract owner. */ function setBaseUri(string memory newBaseUri_) public onlyOwner { _baseUri = newBaseUri_; } /** * @notice Updates the contract state. * * @param newState_ : the new sale state * * Requirements: * * - Caller must be the contract owner. * - `newState_` must be a valid state. */ function setContractState(uint8 newState_) external onlyOwner { if (newState_ > WAITLIST_SALE) { revert ContractState_INVALID_STATE(newState_); } _setContractState(newState_); } /** * @notice Updates the royalty recipient and rate. * * @param newRoyaltyRecipient_ : the new recipient of the royalties * @param newRoyaltyRate_ : the new royalty rate * * Requirements: * * - Caller must be the contract owner. * - `newRoyaltyRate_` cannot be higher than 10,000. */ function setRoyaltyInfo(address newRoyaltyRecipient_, uint256 newRoyaltyRate_) external onlyOwner { _setRoyaltyInfo(newRoyaltyRecipient_, newRoyaltyRate_); } /** * @notice Updates the royalty recipient and rate. * * @param newMagmaPrice_ : the new magma price * @param newPrivatePrice_ : the new private price * @param newPublicPrice_ : the new public price * * Requirements: * * - Caller must be the contract owner. */ function setPrices(uint256 newMagmaPrice_, uint256 newPrivatePrice_, uint256 newPublicPrice_) external onlyOwner { _salePrice[MAGMA_SALE] = newMagmaPrice_; _salePrice[PRIVATE_SALE] = newPrivatePrice_; _salePrice[WAITLIST_SALE] = newPublicPrice_; } /** * @notice Updates the contract treasury. * * @param newTreasury_ : the new trasury * * Requirements: * * - Caller must be the contract owner. */ function setTreasury(address newTreasury_) external onlyOwner { treasury = newTreasury_; } /** * @notice Updates the whitelist signer. * * @param newAdminSigner_ : the new whitelist signer * * Requirements: * * - Caller must be the contract owner. */ function setWhitelist(address newAdminSigner_) external onlyOwner { _setWhitelist(newAdminSigner_); } /** * @notice Withdraws all the money stored in the contract and sends it to the treasury. * * Requirements: * * - Caller must be the contract owner. * - `treasury` must be able to receive the funds. * - Contract must have a positive balance. */ function withdraw() public onlyOwner { uint256 _balance_ = address(this).balance; if (_balance_ == 0) { revert ETHER_NO_BALANCE(); } address _recipient_ = payable(treasury); // solhint-disable-next-line (bool _success_,) = _recipient_.call{ value: _balance_ }(""); if (! _success_) { revert ETHER_TRANSFER_FAIL(_recipient_, _balance_); } } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @notice Returns the sale price during the specified state. * * @param contractState_ : the state of the contract to check the price at * * @return price : uint256 => the sale price at the specified state */ function salePrice(uint8 contractState_) public virtual view returns (uint256 price) { return _salePrice[ contractState_ ]; } /** * @notice Returns the total number of tokens minted * * @return uint256 the number of tokens that have been minted so far */ function supplyMinted() public view virtual returns (uint256) { return _nextId - 1; } // *********** // * IERC721 * // *********** /** * @notice Returns the number of tokens in `tokenOwner_`'s account. * * @param tokenOwner_ address that owns tokens * * @return the nomber of tokens owned by `tokenOwner_` */ function balanceOf(address tokenOwner_) public view override returns (uint256) { if (tokenOwner_ == address(0)) { return 0; } return _balances[tokenOwner_]; } /** * @notice Returns the address that has been specifically allowed to manage `tokenId_` on behalf of its owner. * * @param tokenId_ the NFT that has been approved * * @return the address allowed to manage `tokenId_` * * Requirements: * * - `tokenId_` must exist. * * Note: See {Approve} */ function getApproved(uint256 tokenId_) public view override exists(tokenId_) returns (address) { return _approvals[tokenId_]; } /** * @notice Returns whether `operator_` is allowed to manage tokens on behalf of `tokenOwner_`. * * @param tokenOwner_ address that owns tokens * @param operator_ address that tries to manage tokens * * @return whether `operator_` is allowed to handle `tokenOwner`'s tokens * * Note: See {setApprovalForAll} */ function isApprovedForAll(address tokenOwner_, address operator_) public view override returns (bool) { return _operatorApprovals[tokenOwner_][operator_]; } /** * @notice Returns the owner of the token number `tokenId_`. * * @param tokenId_ the NFT to verify ownership of * * @return the owner of token number `tokenId_` * * Requirements: * * - `tokenId_` must exist. */ function ownerOf(uint256 tokenId_) public view override exists(tokenId_) returns (address) { return _ownerOf(tokenId_); } // *********** // ******************* // * IERC721Metadata * // ******************* /** * @notice A distinct Uniform Resource Identifier (URI) for a given asset. * * @param tokenId_ the NFT that has been approved * * @return the URI of the token * * Requirements: * * - `tokenId_` must exist. */ function tokenURI(uint256 tokenId_) public view override exists(tokenId_) returns (string memory) { return bytes(_baseUri).length > 0 ? string(abi.encodePacked(_baseUri, _toString(tokenId_))) : _toString(tokenId_); } // ******************* // ********************* // * IERC721Enumerable * // ********************* /** * @notice Enumerate valid NFTs * @dev Throws if `index_` >= {totalSupply()}. * * @param index_ the index requested * * @return the identifier of the token at the specified index */ function tokenByIndex(uint256 index_) public view virtual override returns (uint256) { if (index_ >= supplyMinted()) { revert IERC721Enumerable_INDEX_OUT_OF_BOUNDS(index_); } return index_ + 1; } /** * @notice Enumerate NFTs assigned to an owner * @dev Throws if `index_` >= {balanceOf(owner_)} or if `owner_` is the zero address, representing invalid NFTs. * * @param tokenOwner_ the address requested * @param index_ the index requested * * @return the identifier of the token at the specified index */ function tokenOfOwnerByIndex(address tokenOwner_, uint256 index_) public view virtual override returns (uint256) { if (index_ >= balanceOf(tokenOwner_)) { revert IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS(tokenOwner_, index_); } uint256 _count_ = 0; uint256 _nextId_ = supplyMinted(); for (uint256 i = 1; i < _nextId_; i++) { if (_exists(i) && tokenOwner_ == _ownerOf(i)) { if (index_ == _count_) { return i; } _count_++; } } } /** * @notice Count NFTs tracked by this contract * * @return the number of NFTs in existence */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply(); } // ********************* // *********** // * IERC173 * // *********** /** * @dev Returns the address of the current contract owner. * * @return address : the current contract owner */ function owner() public view override(ERC173, UpdatableOperatorFilterer) returns (address) { return ERC173.owner(); } // *********** // *********** // * IERC165 * // *********** /** * @notice Query if a contract implements an interface. * @dev see https://eips.ethereum.org/EIPS/eip-165 * * @param interfaceId_ : the interface identifier, as specified in ERC-165 * * @return bool : true if the contract implements the specified interface, false otherwise * * Requirements: * * - This function must use less than 30,000 gas. */ function supportsInterface(bytes4 interfaceId_) public pure override returns (bool) { return interfaceId_ == type(IERC721).interfaceId || interfaceId_ == type(IERC721Enumerable).interfaceId || interfaceId_ == type(IERC721Metadata).interfaceId || interfaceId_ == type(IERC173).interfaceId || interfaceId_ == type(IERC165).interfaceId || interfaceId_ == type(IERC2981).interfaceId; } // *********** // ************************************** }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IArrayErrors { /** * @dev Thrown when two related arrays have different lengths */ error ARRAY_LENGTH_MISMATCH(); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IContractState { /** * @dev Thrown when a function is called with the wrong contract state. * * @param currentState the current state of the contract */ error ContractState_INCORRECT_STATE(uint8 currentState); /** * @dev Thrown when trying to set the contract state to an invalid value. * * @param invalidState the invalid contract state */ error ContractState_INVALID_STATE(uint8 invalidState); /** * @dev Emitted when the sale state changes * * @param previousState the previous state of the contract * @param newState the new state of the contract */ event ContractStateChanged(uint8 indexed previousState, uint8 indexed newState); /** * @dev Returns the current contract state. */ function getContractState() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; interface IERC165 { /** * @notice Returns if a contract implements an interface. * @dev Interface identification is specified in ERC-165. This function uses less than 30,000 gas. */ function supportsInterface(bytes4 interfaceId_) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // import "./IERC165.sol"; /** * @dev Required interface of an ERC173 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-173[EIP]. */ interface IERC173 /* is IERC165 */ { /** * @dev This emits when ownership of a contract changes. * * @param previousOwner the previous contract owner * @param newOwner the new contract owner */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @notice Set the address of the new owner of the contract. * @dev Set newOwner_ to address(0) to renounce any ownership. */ function transferOwnership(address newOwner_) external; /** * @notice Returns the address of the owner. */ function owner() external view returns(address); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IERC173Errors { /** * @dev Thrown when `operator` is not the contract owner. * * @param operator address trying to use a function reserved to contract owner without authorization */ error IERC173_NOT_OWNER(address operator); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // import "./IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard */ interface IERC2981 /* is IERC165 */ { /** * ERC165 bytes to add to interface array - set in parent contract implementing this standard * * bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a * bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; * _registerInterface(_INTERFACE_ID_ERC2981); * * @notice Called with the sale price to determine how much royalty is owed and to whom. */ function royaltyInfo( uint256 tokenId_, uint256 salePrice_ ) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IERC2981Errors { /** * @dev Thrown when the desired royalty rate is higher than 10,000 * * @param royaltyRate the desired royalty rate * @param royaltyBase the maximum royalty rate */ error IERC2981_INVALID_ROYALTIES(uint256 royaltyRate, uint256 royaltyBase); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // import "./IERC165.sol"; /** * @title ERC-721 Non-Fungible Token Standard * @dev See https://eips.ethereum.org/EIPS/eip-721 * Note: the ERC-165 identifier for this interface is 0x80ac58cd. */ interface IERC721 /* is IERC165 */ { /** * @dev This emits when the approved address for an NFT is changed or reaffirmed. * The zero address indicates there is no approved address. * When a Transfer event emits, this also indicates that the approved address for that NFT (if any) is reset to none. * * @param owner address that owns the token * @param approved address that is allowed to manage the token * @param tokenId identifier of the token being approved */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev This emits when an operator is enabled or disabled for an owner. The operator can manage all NFTs of the owner. * * @param owner address that owns the tokens * @param operator address that is allowed or not to manage the tokens * @param approved whether the operator is allowed or not */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev This emits when ownership of any NFT changes by any mechanism. * This event emits when NFTs are created (`from` == 0) and destroyed (`to` == 0). * Exception: during contract creation, any number of NFTs may be created and assigned without emitting Transfer. * At the time of any transfer, the approved address for that NFT (if any) is reset to none. * * @param from address the token is being transferred from * @param to address the token is being transferred to * @param tokenId identifier of the token being transferred */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @notice Change or reaffirm the approved address for an NFT * @dev The zero address indicates there is no approved address. * Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner. */ function approve(address approved_, uint256 tokenId_) external; /** * @notice Transfers the ownership of an NFT from one address to another address * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT. * Throws if `from_` is not the current owner. * Throws if `to_` is the zero address. * Throws if `tokenId_` is not a valid NFT. * When transfer is complete, this function checks if `to_` is a smart contract (code size > 0). * If so, it calls {onERC721Received} on `to_` and throws if the return value is not * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. */ function safeTransferFrom(address from_, address to_, uint256 tokenId_, bytes calldata data_) external; /** * @notice Transfers the ownership of an NFT from one address to another address * @dev This works identically to the other function with an extra data parameter, * except this function just sets data to "". */ function safeTransferFrom(address from_, address to_, uint256 tokenId_) external; /** * @notice Enable or disable approval for a third party ("operator") to manage all of `msg.sender`'s assets. * @dev Emits the ApprovalForAll event. The contract MUST allow multiple operators per owner. */ function setApprovalForAll(address operator_, bool approved_) external; /** * @notice Transfer ownership of an NFT. * The caller is responsible to confirm that `to_` is capable of receiving nfts or * else they may be permanently lost * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT. * Throws if `from_` is not the current owner. * Throws if `to_` is the zero address. * Throws if `tokenId_` is not a valid NFT. */ function transferFrom(address from_, address to_, uint256 tokenId_) external; /** * @notice Count all NFTs assigned to an owner * @dev NFTs assigned to the zero address are considered invalid. Throws for queries about the zero address. */ function balanceOf(address owner_) external view returns (uint256); /** * @notice Get the approved address for a single NFT * @dev Throws if `tokenId_` is not a valid NFT. */ function getApproved(uint256 tokenId_) external view returns (address); /** * @notice Query if an address is an authorized operator for another address */ function isApprovedForAll(address owner_, address operator_) external view returns (bool); /** * @notice Find the owner of an NFT * @dev NFTs assigned to zero address are considered invalid, and queries * about them do throw. */ function ownerOf(uint256 tokenId_) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 * Note: the ERC-165 identifier for this interface is 0x780e9d63. */ interface IERC721Enumerable /* is IERC721 */ { /** * @notice Enumerate valid NFTs * @dev Throws if `index_` >= {totalSupply()}. */ function tokenByIndex(uint256 index_) external view returns (uint256); /** * @notice Enumerate NFTs assigned to an owner * @dev Throws if `index_` >= {balanceOf(owner_)} or if `owner_` is the zero address, representing invalid NFTs. */ function tokenOfOwnerByIndex(address owner_, uint256 index_) external view returns (uint256); /** * @notice Count NFTs tracked by this contract */ function totalSupply() external view returns (uint256); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IERC721Errors { /** * @dev Thrown when `operator` has not been approved to manage `tokenId` on behalf of `tokenOwner`. * * @param tokenOwner address owning the token * @param operator address trying to manage the token * @param tokenId identifier of the NFT being referenced */ error IERC721_CALLER_NOT_APPROVED(address tokenOwner, address operator, uint256 tokenId); /** * @dev Thrown when `operator` tries to approve themselves for managing a token they own. * * @param operator address that is trying to approve themselves */ error IERC721_INVALID_APPROVAL(address operator); /** * @dev Thrown when a token is being transferred to the zero address. */ error IERC721_INVALID_TRANSFER(); /** * @dev Thrown when a token is being transferred from an address that doesn"t own it. * * @param tokenOwner address owning the token * @param from address that the NFT is being transferred from * @param tokenId identifier of the NFT being referenced */ error IERC721_INVALID_TRANSFER_FROM(address tokenOwner, address from, uint256 tokenId); /** * @dev Thrown when the requested token doesn"t exist. * * @param tokenId identifier of the NFT being referenced */ error IERC721_NONEXISTANT_TOKEN(uint256 tokenId); /** * @dev Thrown when a token is being safely transferred to a contract unable to handle it. * * @param receiver address unable to receive the token */ error IERC721_NON_ERC721_RECEIVER(address receiver); /** * @dev Thrown when trying to get the token at an index that doesn"t exist. * * @param index the inexistant index */ error IERC721Enumerable_INDEX_OUT_OF_BOUNDS(uint256 index); /** * @dev Thrown when trying to get the token owned by `tokenOwner` at an index that doesn"t exist. * * @param tokenOwner address owning the token * @param index the inexistant index */ error IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS(address tokenOwner, uint256 index); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 * Note: the ERC-165 identifier for this interface is 0x5b5e139f. */ interface IERC721Metadata /* is IERC721 */ { /** * @notice A descriptive name for a collection of NFTs in this contract */ function name() external view returns (string memory); /** * @notice An abbreviated name for NFTs in this contract */ function symbol() external view returns (string memory); /** * @notice A distinct Uniform Resource Identifier (URI) for a given asset. * @dev Throws if `tokenId_` is not a valid NFT. URIs are defined in RFC 3986. * The URI may point to a JSON file that conforms to the "ERC721 Metadata JSON Schema". */ function tokenURI(uint256 tokenId_) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; /** * @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. */ interface IERC721Receiver { /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a `transfer`. This function MAY throw to revert and reject the * transfer. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the contract address is always the message sender. */ function onERC721Received( address operator_, address from_, uint256 tokenId_, bytes calldata data_ ) external returns(bytes4); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface IEtherErrors { /** * @dev Thrown when an incorrect amount of eth is being sent for a payable operation. * * @param amountReceived the amount the contract received * @param amountExpected the actual amount the contract expected to receive */ error ETHER_INCORRECT_PRICE(uint256 amountReceived, uint256 amountExpected); /** * @dev Thrown when trying to withdraw from the contract with no balance. */ error ETHER_NO_BALANCE(); /** * @dev Thrown when contract fails to send ether to recipient. * * @param to the recipient of the ether * @param amount the amount of ether being sent */ error ETHER_TRANSFER_FAIL(address to, uint256 amount); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; interface INFTSupplyErrors { /** * @dev Thrown when trying to mint 0 token. */ error NFT_INVALID_QTY(); /** * @dev Thrown when trying to set max supply to an invalid amount. */ error NFT_INVALID_SUPPLY(); /** * @dev Thrown when trying to mint more tokens than the max allowed per transaction. * * @param qtyRequested the amount of tokens requested * @param maxBatch the maximum amount that can be minted per transaction */ error NFT_MAX_BATCH(uint256 qtyRequested, uint256 maxBatch); /** * @dev Thrown when trying to mint more tokens from the reserve than the amount left. * * @param qtyRequested the amount of tokens requested * @param reserveLeft the amount of tokens left in the reserve */ error NFT_MAX_RESERVE(uint256 qtyRequested, uint256 reserveLeft); /** * @dev Thrown when trying to mint more tokens than the amount left to be minted (except reserve). * * @param qtyRequested the amount of tokens requested * @param remainingSupply the amount of tokens left in the reserve */ error NFT_MAX_SUPPLY(uint256 qtyRequested, uint256 remainingSupply); }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; import "../interfaces/IContractState.sol"; abstract contract ContractState is IContractState { // Enum to represent the sale state, defaults to ``PAUSED``. uint8 public constant PAUSED = 0; // The current state of the contract uint8 private _contractState; // ************************************** // ***** MODIFIER ***** // ************************************** /** * @dev Ensures that contract state is `expectedState_`. * * @param expectedState_ : the desirable contract state */ modifier isState(uint8 expectedState_) { if (_contractState != expectedState_) { revert ContractState_INCORRECT_STATE(_contractState); } _; } /** * @dev Ensures that contract state is not `unexpectedState_`. * * @param unexpectedState_ : the undesirable contract state */ modifier isNotState(uint8 unexpectedState_) { if (_contractState == unexpectedState_) { revert ContractState_INCORRECT_STATE(_contractState); } _; } // ************************************** // ************************************** // ***** INTERNAL ***** // ************************************** /** * @dev Internal function setting the contract state to `newState_`. * * Note: Contract state defaults to ``PAUSED``. * To maintain extendability, this value kept as uint8 instead of enum. * As a result, it is possible to set the state to an incorrect value. * To avoid issues, `newState_` should be validated before calling this function */ function _setContractState(uint8 newState_) internal virtual { uint8 _previousState_ = _contractState; _contractState = newState_; emit ContractStateChanged(_previousState_, newState_); } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @dev Returns the current contract state. * * @return uint8 : the current contract state */ function getContractState() public virtual view override returns (uint8) { return _contractState; } // ************************************** }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; import "../interfaces/IERC173.sol"; import "../interfaces/IERC173Errors.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 ERC173 is IERC173, IERC173Errors { // The owner of the contract address private _owner; // ************************************** // ***** MODIFIER ***** // ************************************** /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { if (owner() != msg.sender) { revert IERC173_NOT_OWNER(msg.sender); } _; } // ************************************** // ************************************** // ***** INTERNAL ***** // ************************************** /** * @dev Sets the contract owner. * * Note: This function needs to be called in the contract constructor to initialize the contract owner, * if it is not, then parts of the contract might be non functional * * @param owner_ : address that owns the contract */ function _setOwner(address owner_) internal { _owner = owner_; } // ************************************** // ************************************** // ***** CONTRACT OWNER ***** // ************************************** /** * @dev Transfers ownership of the contract to `newOwner_`. * * @param newOwner_ : address of the new contract owner * * Requirements: * * - Caller must be the contract owner. */ function transferOwnership(address newOwner_) public virtual onlyOwner { address _oldOwner_ = _owner; _owner = newOwner_; emit OwnershipTransferred(_oldOwner_, newOwner_); } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @dev Returns the address of the current contract owner. * * @return address : the current contract owner */ function owner() public view virtual returns (address) { return _owner; } // ************************************** }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; import "../interfaces/IERC2981.sol"; import "../interfaces/IERC2981Errors.sol"; abstract contract ERC2981 is IERC2981, IERC2981Errors { // Royalty rate is stored out of 10,000 instead of a percentage to allow for // up to two digits below the unit such as 2.5% or 1.25%. uint public constant ROYALTY_BASE = 10000; // Represents the percentage of royalties on each sale on secondary markets. // Set to 0 to have no royalties. uint256 private _royaltyRate; // Address of the recipient of the royalties. address private _royaltyRecipient; // ************************************** // ***** INTERNAL ***** // ************************************** /** * @dev Sets the royalty rate to `royaltyRate_` and the royalty recipient to `royaltyRecipient_`. * * @param royaltyRecipient_ the address that will receive royalty payments * @param royaltyRate_ the percentage of the sale price that will be taken off as royalties, * expressed in Basis Points (100 BP = 1%) * * Requirements: * * - `royaltyRate_` cannot be higher than `10,000`; */ function _setRoyaltyInfo(address royaltyRecipient_, uint256 royaltyRate_) internal virtual { if (royaltyRate_ > ROYALTY_BASE) { revert IERC2981_INVALID_ROYALTIES(royaltyRate_, ROYALTY_BASE); } _royaltyRate = royaltyRate_; _royaltyRecipient = royaltyRecipient_; } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @notice Called with the sale price to determine how much royalty is owed and to whom. * * Note: This function should be overriden to revert on a query for non existent token. * * @param tokenId_ identifier of the NFT being referenced * @param salePrice_ the sale price of the token sold * * @return address the address receiving the royalties * @return uint256 the royalty payment amount */ /* solhint-disable no-unused-vars */ function royaltyInfo(uint256 tokenId_, uint256 salePrice_) public view virtual override returns (address, uint256) { if (salePrice_ == 0 || _royaltyRate == 0) { return (_royaltyRecipient, 0); } uint256 _royaltyAmount_ = _royaltyRate * salePrice_ / ROYALTY_BASE; return (_royaltyRecipient, _royaltyAmount_); } /* solhint-enable no-unused-vars */ // ************************************** }
// SPDX-License-Identifier: MIT /** * Author: Lambdalf the White */ pragma solidity 0.8.17; abstract contract Whitelist_ECDSA { // Errors /** * @dev Thrown when trying to query the whitelist while it"s not set */ error Whitelist_NOT_SET(); /** * @dev Thrown when `account` has consumed their alloted access and tries to query more * * @param account address trying to access the whitelist */ error Whitelist_CONSUMED(address account); /** * @dev Thrown when `account` does not have enough alloted access to fulfil their query * * @param account address trying to access the whitelist */ error Whitelist_FORBIDDEN(address account); /** * @dev A structure representing a signature proof to be decoded by the contract */ struct Proof { bytes32 r; bytes32 s; uint8 v; } address private _adminSigner; mapping(uint8 => mapping(address => uint256)) private _consumed; // ************************************** // ***** MODIFIER ***** // ************************************** /** * @dev Ensures that `account_` has `qty_` alloted access on the `whitelistId_` whitelist. * * @param account_ the address to validate access * @param whitelistId_ the identifier of the whitelist being queried * @param alloted_ the max amount of whitelist spots allocated * @param proof_ the signature proof to validate whitelist allocation * @param qty_ the amount of whitelist access requested */ modifier isWhitelisted(address account_, uint8 whitelistId_, uint256 alloted_, Proof memory proof_, uint256 qty_) { uint256 _allowed_ = checkWhitelistAllowance(account_, whitelistId_, alloted_, proof_); if (_allowed_ < qty_) { revert Whitelist_FORBIDDEN(account_); } _; } // ************************************** // ************************************** // ***** INTERNAL ***** // ************************************** /** * @dev Consumes `amount_` whitelist access passes from `account_`. * * @param account_ the address to consume access from * @param whitelistId_ the identifier of the whitelist being queried * @param qty_ the amount of whitelist access consumed * * Note: Before calling this function, eligibility should be checked through {Whitelistable-checkWhitelistAllowance}. */ function _consumeWhitelist(address account_, uint8 whitelistId_, uint256 qty_) internal { unchecked { _consumed[ whitelistId_ ][ account_ ] += qty_; } } /** * @dev Sets the pass to protect the whitelist. * * @param adminSigner_ : the address validating the whitelist signatures */ function _setWhitelist(address adminSigner_) internal virtual { _adminSigner = adminSigner_; } /** * @dev Internal function to decode a signature and compare it with the `_adminSigner`. * * @param account_ the address to validate access * @param whitelistId_ the identifier of the whitelist being queried * @param alloted_ the max amount of whitelist spots allocated * @param proof_ the signature proof to validate whitelist allocation * * @return bool whether the signature is valid or not */ function _validateProof( address account_, uint8 whitelistId_, uint256 alloted_, Proof memory proof_ ) private view returns (bool) { bytes32 _digest_ = keccak256(abi.encode(whitelistId_, alloted_, account_)); address _signer_ = ecrecover(_digest_, proof_.v, proof_.r, proof_.s); return _signer_ == _adminSigner; } // ************************************** // ************************************** // ***** VIEW ***** // ************************************** /** * @dev Returns the amount that `account_` is allowed to access from the whitelist. * * @param account_ the address to validate access * @param whitelistId_ the identifier of the whitelist being queried * @param alloted_ the max amount of whitelist spots allocated * @param proof_ the signature proof to validate whitelist allocation * * @return uint256 : the total amount of whitelist allocation remaining for `account_` * * Requirements: * * - `_adminSigner` must be set. */ function checkWhitelistAllowance( address account_, uint8 whitelistId_, uint256 alloted_, Proof memory proof_ ) public view returns (uint256) { if (_adminSigner == address(0)) { revert Whitelist_NOT_SET(); } if (_consumed[ whitelistId_ ][ account_ ] >= alloted_) { revert Whitelist_CONSUMED(account_); } if (! _validateProof(account_, whitelistId_, alloted_, proof_)) { revert Whitelist_FORBIDDEN(account_); } return alloted_ - _consumed[ whitelistId_ ][ account_ ]; } // ************************************** }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IOperatorFilterRegistry { /** * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns * true if supplied registrant address is not registered. */ function isOperatorAllowed(address registrant, address operator) external view returns (bool); /** * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. */ function register(address registrant) external; /** * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. */ function registerAndSubscribe(address registrant, address subscription) external; /** * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another * address without subscribing. */ function registerAndCopyEntries(address registrant, address registrantToCopy) external; /** * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. * Note that this does not remove any filtered addresses or codeHashes. * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. */ function unregister(address addr) external; /** * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. */ function updateOperator(address registrant, address operator, bool filtered) external; /** * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. */ function updateOperators(address registrant, address[] calldata operators, bool filtered) external; /** * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. */ function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; /** * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. */ function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; /** * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous * subscription if present. * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be * used. */ function subscribe(address registrant, address registrantToSubscribe) external; /** * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. */ function unsubscribe(address registrant, bool copyExistingEntries) external; /** * @notice Get the subscription address of a given registrant, if any. */ function subscriptionOf(address addr) external returns (address registrant); /** * @notice Get the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscribers(address registrant) external returns (address[] memory); /** * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscriberAt(address registrant, uint256 index) external returns (address); /** * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. */ function copyEntriesOf(address registrant, address registrantToCopy) external; /** * @notice Returns true if operator is filtered by a given address or its subscription. */ function isOperatorFiltered(address registrant, address operator) external returns (bool); /** * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. */ function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); /** * @notice Returns true if a codeHash is filtered by a given address or its subscription. */ function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); /** * @notice Returns a list of filtered operators for a given address or its subscription. */ function filteredOperators(address addr) external returns (address[] memory); /** * @notice Returns the set of filtered codeHashes for a given address or its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashes(address addr) external returns (bytes32[] memory); /** * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredOperatorAt(address registrant, uint256 index) external returns (address); /** * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); /** * @notice Returns true if an address has registered */ function isRegistered(address addr) external returns (bool); /** * @dev Convenience method to compute the code hash of an arbitrary contract */ function codeHashOf(address addr) external returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; 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 earnings 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 { /// @dev Emitted when an operator is not allowed. error OperatorNotAllowed(address operator); /// @dev Emitted when someone other than the owner is trying to call an only owner function. error OnlyOwner(); event OperatorFilterRegistryAddressUpdated(address newRegistry); IOperatorFilterRegistry public operatorFilterRegistry; /// @dev The constructor that is called when the contract is being deployed. 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)); } } } } /** * @dev A helper function to check if the operator is allowed. */ 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); } _; } /** * @dev A helper function to check if the operator approval is allowed. */ 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); emit OperatorFilterRegistryAddressUpdated(newRegistry); } /** * @dev Assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract. */ function owner() public view virtual returns (address); /** * @dev A helper function to check if the operator is allowed. */ 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) { // under normal circumstances, this function will revert rather than return false, but inheriting contracts // may specify their own OperatorFilterRegistry implementations, which may behave differently if (!registry.isOperatorAllowed(address(this), operator)) { revert OperatorNotAllowed(operator); } } } }
{ "viaIR": false, "optimizer": { "enabled": true, "runs": 10000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"airdropAddress_","type":"address"},{"internalType":"address","name":"royaltyRecipient_","type":"address"},{"internalType":"address","name":"treasury_","type":"address"},{"internalType":"address","name":"signerWallet_","type":"address"},{"internalType":"uint256","name":"maxSupply_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ARRAY_LENGTH_MISMATCH","type":"error"},{"inputs":[{"internalType":"uint8","name":"currentState","type":"uint8"}],"name":"ContractState_INCORRECT_STATE","type":"error"},{"inputs":[{"internalType":"uint8","name":"invalidState","type":"uint8"}],"name":"ContractState_INVALID_STATE","type":"error"},{"inputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"},{"internalType":"uint256","name":"amountExpected","type":"uint256"}],"name":"ETHER_INCORRECT_PRICE","type":"error"},{"inputs":[],"name":"ETHER_NO_BALANCE","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ETHER_TRANSFER_FAIL","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"IERC173_NOT_OWNER","type":"error"},{"inputs":[{"internalType":"uint256","name":"royaltyRate","type":"uint256"},{"internalType":"uint256","name":"royaltyBase","type":"uint256"}],"name":"IERC2981_INVALID_ROYALTIES","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"IERC721Enumerable_INDEX_OUT_OF_BOUNDS","type":"error"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS","type":"error"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"IERC721_CALLER_NOT_APPROVED","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"IERC721_INVALID_APPROVAL","type":"error"},{"inputs":[],"name":"IERC721_INVALID_TRANSFER","type":"error"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"IERC721_INVALID_TRANSFER_FROM","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"IERC721_NONEXISTANT_TOKEN","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"IERC721_NON_ERC721_RECEIVER","type":"error"},{"inputs":[],"name":"NFT_INVALID_QTY","type":"error"},{"inputs":[],"name":"NFT_INVALID_SUPPLY","type":"error"},{"inputs":[{"internalType":"uint256","name":"qtyRequested","type":"uint256"},{"internalType":"uint256","name":"maxBatch","type":"uint256"}],"name":"NFT_MAX_BATCH","type":"error"},{"inputs":[{"internalType":"uint256","name":"qtyRequested","type":"uint256"},{"internalType":"uint256","name":"reserveLeft","type":"uint256"}],"name":"NFT_MAX_RESERVE","type":"error"},{"inputs":[{"internalType":"uint256","name":"qtyRequested","type":"uint256"},{"internalType":"uint256","name":"remainingSupply","type":"uint256"}],"name":"NFT_MAX_SUPPLY","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"Whitelist_CONSUMED","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"Whitelist_FORBIDDEN","type":"error"},{"inputs":[],"name":"Whitelist_NOT_SET","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":"uint8","name":"previousState","type":"uint8"},{"indexed":true,"internalType":"uint8","name":"newState","type":"uint8"}],"name":"ContractStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newRegistry","type":"address"}],"name":"OperatorFilterRegistryAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_SUBSCRIPTION","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAGMA_SALE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BATCH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSED","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRIVATE_SALE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROYALTY_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WAITLIST_SALE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"uint8","name":"whitelistId_","type":"uint8"},{"internalType":"uint256","name":"alloted_","type":"uint256"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"}],"internalType":"struct Whitelist_ECDSA.Proof","name":"proof_","type":"tuple"}],"name":"checkWhitelistAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractState","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner_","type":"address"},{"internalType":"address","name":"operator_","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"qty_","type":"uint256"},{"internalType":"uint256","name":"alloted_","type":"uint256"},{"internalType":"uint8","name":"whitelistType_","type":"uint8"},{"components":[{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"}],"internalType":"struct Whitelist_ECDSA.Proof","name":"proof_","type":"tuple"}],"name":"mint","outputs":[],"stateMutability":"payable","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":[{"internalType":"uint256","name":"newMaxSupply_","type":"uint256"}],"name":"reduceSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"},{"internalType":"uint256","name":"salePrice_","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"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":"uint8","name":"contractState_","type":"uint8"}],"name":"salePrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","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":"uint8","name":"newState_","type":"uint8"}],"name":"setContractState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMagmaPrice_","type":"uint256"},{"internalType":"uint256","name":"newPrivatePrice_","type":"uint256"},{"internalType":"uint256","name":"newPublicPrice_","type":"uint256"}],"name":"setPrices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRoyaltyRecipient_","type":"address"},{"internalType":"uint256","name":"newRoyaltyRate_","type":"uint256"}],"name":"setRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasury_","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdminSigner_","type":"address"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId_","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","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":"tokenOwner_","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":"newOwner_","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newRegistry","type":"address"}],"name":"updateOperatorFilterRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260036009553480156200001657600080fd5b50604051620030053803806200300583398101604081905262000039916200035c565b600580546001600160a01b0319166daaeb6d7670e522a718067333cd4e908117909155733cc6cdda760b79bafa08df41ecfa224f810dceb6600182803b156200018e578115620000ed57604051633e9f1edf60e11b81523060048201526001600160a01b038481166024830152821690637d3e3dbe906044015b600060405180830381600087803b158015620000ce57600080fd5b505af1158015620000e3573d6000803e3d6000fd5b505050506200018e565b6001600160a01b03831615620001325760405163a0af290360e01b81523060048201526001600160a01b03848116602483015282169063a0af290390604401620000b3565b604051632210724360e11b81523060048201526001600160a01b03821690634420e48690602401600060405180830381600087803b1580156200017457600080fd5b505af115801562000189573d6000803e3d6000fd5b505050505b505050600682905550600e602052669c51c4521e00007fa7c5ba7114a813b50159add3a36832908dc83db71d0b9a24c2ad0f83be9582075566c3663566a580007f9adb202b1492743bc00c81d33cdc6423fa8c79109027eb6a845391e8fc1f0481819055600360009081527fe0283e559c29e31ee7f56467acc9dd307779c843a883aeeb3bf5c6128c90814491909155600780546001600160a01b0386166001600160a01b03199182161790915581541633179055620002508460fa620002e7565b600380546001600160a01b0319166001600160a01b0384161790555050600b60205250507f72c6bfb7988af3a1efa6568f02a999bc52252641c659d85961ca3d372b57d5cf80546001600160a01b039092166001600160a01b0319928316811790915560026000527fa50eece07c7db1631545c0069bd8f5f54d5935e215d59097edf258a44ba916348054909216179055620003c3565b6127108111156200031a57604051632761fe9d60e11b815260048101829052612710602482015260440160405180910390fd5b600155600280546001600160a01b0319166001600160a01b0392909216919091179055565b80516001600160a01b03811681146200035757600080fd5b919050565b600080600080600060a086880312156200037557600080fd5b62000380866200033f565b945062000390602087016200033f565b9350620003a0604087016200033f565b9250620003b0606087016200033f565b9150608086015190509295509295909350565b612c3280620003d36000396000f3fe6080604052600436106102e75760003560e01c80638da5cb5b11610184578063b8d1e532116100d6578063e2e784d51161008a578063f2fde38b11610064578063f2fde38b146108a5578063f7b4c187146108c5578063f9c0611c146108e557600080fd5b8063e2e784d51461081c578063e985e9c51461083c578063f0f442601461088557600080fd5b8063c87b56dd116100bb578063c87b56dd146107d1578063d5abeb01146107f1578063dc62bd891461080757600080fd5b8063b8d1e5321461079c578063c50ef4d8146107bc57600080fd5b8063a22cb46511610138578063a9aad58c11610112578063a9aad58c14610747578063b0ccc31e1461075c578063b88d4fde1461077c57600080fd5b8063a22cb465146106e5578063a49225f814610705578063a88fe42d1461072757600080fd5b806395d89b411161016957806395d89b411461066757806398c83a16146106b0578063a0bcfc7f146106c557600080fd5b80638da5cb5b14610634578063950bff9f1461065257600080fd5b80633ccfd60b1161023d5780636352211e116101f15780637f4e4849116101cb5780637f4e4849146105b657806380623444146105f4578063854cff2f1461061457600080fd5b80636352211e1461056157806370a08231146105815780637e9845f5146105a157600080fd5b80634f6ccce7116102225780634f6ccce71461050b5780635f97036f1461052b57806361d027b31461054157600080fd5b80633ccfd60b146104d657806342842e0e146104eb57600080fd5b806318160ddd1161029f5780632a55205a116102795780632a55205a146104475780632f745c591461048657806338af39e8146104a657600080fd5b806318160ddd146103e45780631a3f839d1461040757806323b872dd1461042757600080fd5b8063081812fc116102d0578063081812fc14610377578063095ea7b3146103af5780630b520220146103d157600080fd5b806301ffc9a7146102ec57806306fdde0314610321575b600080fd5b3480156102f857600080fd5b5061030c6103073660046123f8565b61090d565b60405190151581526020015b60405180910390f35b34801561032d57600080fd5b5061036a6040518060400160405280601581526020017f43757261746564426c6f636b732047656e65736973000000000000000000000081525081565b6040516103189190612465565b34801561038357600080fd5b50610397610392366004612478565b610ad6565b6040516001600160a01b039091168152602001610318565b3480156103bb57600080fd5b506103cf6103ca3660046124ad565b610b41565b005b6103cf6103df3660046124e8565b610cc4565b3480156103f057600080fd5b506103f9610ed0565b604051908152602001610318565b34801561041357600080fd5b506103f96104223660046125e8565b610edf565b34801561043357600080fd5b506103cf610442366004612636565b611017565b34801561045357600080fd5b50610467610462366004612672565b611135565b604080516001600160a01b039093168352602083019190915201610318565b34801561049257600080fd5b506103f96104a13660046124ad565b611195565b3480156104b257600080fd5b506103f96104c1366004612694565b60ff166000908152600e602052604090205490565b3480156104e257600080fd5b506103cf61126f565b3480156104f757600080fd5b506103cf610506366004612636565b6113a8565b34801561051757600080fd5b506103f9610526366004612478565b6113c3565b34801561053757600080fd5b506103f961271081565b34801561054d57600080fd5b50600754610397906001600160a01b031681565b34801561056d57600080fd5b5061039761057c366004612478565b611413565b34801561058d57600080fd5b506103f961059c3660046126af565b611478565b3480156105ad57600080fd5b506103f96114ac565b3480156105c257600080fd5b5060025474010000000000000000000000000000000000000000900460ff165b60405160ff9091168152602001610318565b34801561060057600080fd5b506103cf61060f366004612478565b6114bd565b34801561062057600080fd5b506103cf61062f3660046126af565b611564565b34801561064057600080fd5b506000546001600160a01b0316610397565b34801561065e57600080fd5b506103f9600a81565b34801561067357600080fd5b5061036a6040518060400160405280600781526020017f43424c4f434b530000000000000000000000000000000000000000000000000081525081565b3480156106bc57600080fd5b506105e2600281565b3480156106d157600080fd5b506103cf6106e0366004612740565b6115f2565b3480156106f157600080fd5b506103cf610700366004612797565b611657565b34801561071157600080fd5b506103976daaeb6d7670e522a718067333cd4e81565b34801561073357600080fd5b506103cf6107423660046127ce565b61173c565b34801561075357600080fd5b506105e2600081565b34801561076857600080fd5b50600554610397906001600160a01b031681565b34801561078857600080fd5b506103cf6107973660046127fa565b611806565b3480156107a857600080fd5b506103cf6107b73660046126af565b611864565b3480156107c857600080fd5b506105e2600381565b3480156107dd57600080fd5b5061036a6107ec366004612478565b611914565b3480156107fd57600080fd5b506103f960065481565b34801561081357600080fd5b506105e2600181565b34801561082857600080fd5b506103cf6108373660046124ad565b6119b0565b34801561084857600080fd5b5061030c610857366004612876565b6001600160a01b039182166000908152600d6020908152604080832093909416825291909152205460ff1690565b34801561089157600080fd5b506103cf6108a03660046126af565b611a0f565b3480156108b157600080fd5b506103cf6108c03660046126af565b611a9e565b3480156108d157600080fd5b506103cf6108e0366004612694565b611b5b565b3480156108f157600080fd5b50610397733cc6cdda760b79bafa08df41ecfa224f810dceb681565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806109a057507fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d6300000000000000000000000000000000000000000000000000000000145b806109ec57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a3857507fffffffff0000000000000000000000000000000000000000000000000000000082167f7f5828d000000000000000000000000000000000000000000000000000000000145b80610a8457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b80610ad057507fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a00000000000000000000000000000000000000000000000000000000145b92915050565b600081610ae281611bfc565b610b20576040517f1cf4d9a4000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6000838152600a60205260409020546001600160a01b031691505b50919050565b80610b4b81611bfc565b610b84576040517f1cf4d9a400000000000000000000000000000000000000000000000000000000815260048101829052602401610b17565b33610b8e81611c2c565b6000838152600b60205260409020546001600160a01b03908116908516819003610bef576040517ff2b21e1c0000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152602401610b17565b6000610bfc823387611d20565b905080610c4d576040517f19f48dff0000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015233602482015260448101869052606401610b17565b6000858152600a602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038a811691821790925591518893918616917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050505050565b60025460009074010000000000000000000000000000000000000000900460ff16610d3b576002546040517f5d80b9ec0000000000000000000000000000000000000000000000000000000081527401000000000000000000000000000000000000000090910460ff166004820152602401610b17565b60025474010000000000000000000000000000000000000000900460ff16600a861115610d9e576040517f5aaca4e400000000000000000000000000000000000000000000000000000000815260048101879052600a6024820152604401610b17565b6000610da86114ac565b600654610db591906128d8565b905080871115610dfb576040517f9abbab070000000000000000000000000000000000000000000000000000000081526004810188905260248101829052604401610b17565b60ff85166000908152600e6020526040812054610e1890896128eb565b9050348114610e5c576040517f9310692e00000000000000000000000000000000000000000000000000000000815234600482015260248101829052604401610b17565b610e783384888a8c610e73368c90038c018c612902565b611d8f565b6009546000610e878a8361291e565b336000908152600c6020526040902080548c019055600980548c01905590505b80821015610ec457610eb93383611f25565b600190910190610ea7565b50505050505050505050565b6000610eda611f96565b905090565b6003546000906001600160a01b0316610f24576040517f93dff14200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff841660009081526004602090815260408083206001600160a01b03891684529091529020548311610f8e576040517f6acdb0950000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152602401610b17565b610f9a85858585611fa0565b610fdb576040517f186a628d0000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152602401610b17565b60ff841660009081526004602090815260408083206001600160a01b038916845290915290205461100c90846128d8565b90505b949350505050565b336001600160a01b038316611058576040517f14242cb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061106383611413565b9050806001600160a01b0316856001600160a01b0316146110ca576040517fe02b28e70000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301528616602482015260448101849052606401610b17565b6110d5813385611d20565b611123576040517f19f48dff0000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015233602482015260448101849052606401610b17565b61112e818585612075565b5050505050565b6000808215806111455750600154155b1561115f5750506002546001600160a01b0316600061118e565b60006127108460015461117291906128eb565b61117c9190612931565b6002546001600160a01b031693509150505b9250929050565b60006111a083611478565b82106111ea576040517f374f8b4f0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101839052604401610b17565b6000806111f56114ac565b905060015b818110156112665761120b81611bfc565b801561123057506000818152600b60205260409020546001600160a01b038781169116145b1561125457828503611246579250610ad0915050565b826112508161296c565b9350505b8061125e8161296c565b9150506111fa565b50505092915050565b336112826000546001600160a01b031690565b6001600160a01b0316146112c4576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b476000819003611300576040517f6cc4466b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040516001600160a01b0390911690600090829084908381818185875af1925050503d8060008114611351576040519150601f19603f3d011682016040523d82523d6000602084013e611356565b606091505b50509050806113a3576040517f84020a7b0000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260248101849052604401610b17565b505050565b6113a383838360405180602001604052806000815250611806565b60006113cd6114ac565b8210611408576040517f125c19b000000000000000000000000000000000000000000000000000000000815260048101839052602401610b17565b610ad082600161291e565b60008161141f81611bfc565b611458576040517f1cf4d9a400000000000000000000000000000000000000000000000000000000815260048101829052602401610b17565b6000838152600b60205260409020546001600160a01b03165b9392505050565b60006001600160a01b03821661149057506000919050565b506001600160a01b03166000908152600c602052604090205490565b60006001600954610eda91906128d8565b336114d06000546001600160a01b031690565b6001600160a01b031614611512576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b60065481118061152857506115256114ac565b81105b1561155f576040517fbcc7b4fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600655565b336115776000546001600160a01b031690565b6001600160a01b0316146115b9576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03831617905550565b50565b336116056000546001600160a01b031690565b6001600160a01b031614611647576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b60086116538282612a21565b5050565b3361166181611c2c565b336001600160a01b0384168190036116b0576040517ff2b21e1c0000000000000000000000000000000000000000000000000000000081526001600160a01b0385166004820152602401610b17565b6001600160a01b038181166000818152600d602090815260408083209489168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001688151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b3361174f6000546001600160a01b031690565b6001600160a01b031614611791576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600e6020527fa7c5ba7114a813b50159add3a36832908dc83db71d0b9a24c2ad0f83be958207929092557f9adb202b1492743bc00c81d33cdc6423fa8c79109027eb6a845391e8fc1f04815560036000527fe0283e559c29e31ee7f56467acc9dd307779c843a883aeeb3bf5c6128c90814455565b611811848484611017565b61181d8484848461211b565b61185e576040517f015be56a0000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152602401610b17565b50505050565b6000546001600160a01b031633146118a8576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f9f513fe86dc42fdbac355fa4d9b1d5be7b5e6cd2df67e30db8003766568de4769060200160405180910390a150565b60608161192081611bfc565b611959576040517f1cf4d9a400000000000000000000000000000000000000000000000000000000815260048101829052602401610b17565b60006008805461196890612986565b90501161197d5761197883612284565b611471565b600861198884612284565b604051602001611999929190612ae1565b604051602081830303815290604052915050919050565b336119c36000546001600160a01b031690565b6001600160a01b031614611a05576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b61165382826122c8565b33611a226000546001600160a01b031690565b6001600160a01b031614611a64576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b33611ab16000546001600160a01b031690565b6001600160a01b031614611af3576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b33611b6e6000546001600160a01b031690565b6001600160a01b031614611bb0576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600360ff82161115611bf3576040517fb81f899300000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610b17565b6115ef8161234c565b600081600003611c0e57506000919050565b506000908152600b60205260409020546001600160a01b0316151590565b6005546001600160a01b03168015801590611c5157506000816001600160a01b03163b115b15611653576040517fc61711340000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa158015611cbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cdf9190612b86565b611653576040517fede71dcc0000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b17565b6000836001600160a01b0316836001600160a01b03161480611d5b5750611d4682610ad6565b6001600160a01b0316836001600160a01b0316145b8061100f57506001600160a01b038085166000908152600d602090815260408083209387168352929052205460ff1661100f565b600060001960ff871601611e3357611daa8760018685610edf565b905082811015611df1576040517f186a628d0000000000000000000000000000000000000000000000000000000081526001600160a01b0388166004820152602401610b17565b6001600160a01b03871660009081527fabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe0560205260409020805484019055611f1c565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60ff871601611f0c5760001960ff861601611e7657611daa8760018685610edf565b611e838760028685610edf565b905082811015611eca576040517f186a628d0000000000000000000000000000000000000000000000000000000081526001600160a01b0388166004820152602401610b17565b6001600160a01b03871660009081527f91da3fd0782e51c6b3986e9e672fd566868e71f3dbc2d6c2cd6fbb3e361af2a760205260409020805484019055611f1c565b611f1a876003600185610edf565b505b50505050505050565b6000818152600b602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610eda6114ac565b6040805160ff851660208201529081018390526001600160a01b0385166060820152600090819060800160405160208183030381529060405280519060200120905060006001828560400151866000015187602001516040516000815260200160405260405161202c949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561204e573d6000803e3d6000fd5b5050604051601f1901516003546001600160a01b0390811691161498975050505050505050565b6001600160a01b038083166000818152600c60209081526040808320805460010190559387168083528483208054600019019055858352600b825284832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168617909155600a909252848320805490921690915592518493917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000833b801561227a576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0386169063150b7a02906121709033908a9089908990600401612ba3565b6020604051808303816000875af19250505080156121ab575060408051601f3d908101601f191682019092526121a891810190612bdf565b60015b61222d573d8080156121d9576040519150601f19603f3d011682016040523d82523d6000602084013e6121de565b606091505b508051600003612225576040517f015be56a0000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152602401610b17565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a020000000000000000000000000000000000000000000000000000000014915061100f9050565b600191505061100f565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061229e5750819003601f19909101908152919050565b61271081111561230f576040517f4ec3fd3a000000000000000000000000000000000000000000000000000000008152600481018290526127106024820152604401610b17565b600155600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6002805460ff838116740100000000000000000000000000000000000000008181027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff85161790945560405193909204169182907f7285522ec93a20dcefa1a1d057094a227073a5463b91c0c19a23c6ef5c9c1fe490600090a35050565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146115ef57600080fd5b60006020828403121561240a57600080fd5b8135611471816123ca565b60005b83811015612430578181015183820152602001612418565b50506000910152565b60008151808452612451816020860160208601612415565b601f01601f19169290920160200192915050565b6020815260006114716020830184612439565b60006020828403121561248a57600080fd5b5035919050565b80356001600160a01b03811681146124a857600080fd5b919050565b600080604083850312156124c057600080fd5b6124c983612491565b946020939093013593505050565b803560ff811681146124a857600080fd5b60008060008084860360c08112156124ff57600080fd5b8535945060208601359350612516604087016124d7565b925060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08201121561254857600080fd5b509295919450926060019150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006060828403121561259757600080fd5b6040516060810181811067ffffffffffffffff821117156125ba576125ba612556565b806040525080915082358152602083013560208201526125dc604084016124d7565b60408201525092915050565b60008060008060c085870312156125fe57600080fd5b61260785612491565b9350612615602086016124d7565b92506040850135915061262b8660608701612585565b905092959194509250565b60008060006060848603121561264b57600080fd5b61265484612491565b925061266260208501612491565b9150604084013590509250925092565b6000806040838503121561268557600080fd5b50508035926020909101359150565b6000602082840312156126a657600080fd5b611471826124d7565b6000602082840312156126c157600080fd5b61147182612491565b600067ffffffffffffffff808411156126e5576126e5612556565b604051601f8501601f19908116603f0116810190828211818310171561270d5761270d612556565b8160405280935085815286868601111561272657600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561275257600080fd5b813567ffffffffffffffff81111561276957600080fd5b8201601f8101841361277a57600080fd5b61100f848235602084016126ca565b80151581146115ef57600080fd5b600080604083850312156127aa57600080fd5b6127b383612491565b915060208301356127c381612789565b809150509250929050565b6000806000606084860312156127e357600080fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561281057600080fd5b61281985612491565b935061282760208601612491565b925060408501359150606085013567ffffffffffffffff81111561284a57600080fd5b8501601f8101871361285b57600080fd5b61286a878235602084016126ca565b91505092959194509250565b6000806040838503121561288957600080fd5b61289283612491565b91506128a060208401612491565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ad057610ad06128a9565b8082028115828204841417610ad057610ad06128a9565b60006060828403121561291457600080fd5b6114718383612585565b80820180821115610ad057610ad06128a9565b600082612967577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000600019820361297f5761297f6128a9565b5060010190565b600181811c9082168061299a57607f821691505b602082108103610b3b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f8211156113a357600081815260208120601f850160051c810160208610156129fa5750805b601f850160051c820191505b81811015612a1957828155600101612a06565b505050505050565b815167ffffffffffffffff811115612a3b57612a3b612556565b612a4f81612a498454612986565b846129d3565b602080601f831160018114612a845760008415612a6c5750858301515b600019600386901b1c1916600185901b178555612a19565b600085815260208120601f198616915b82811015612ab357888601518255948401946001909101908401612a94565b5085821015612ad15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808454612aef81612986565b60018281168015612b075760018114612b3a57612b69565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450612b69565b8860005260208060002060005b85811015612b605781548a820152908401908201612b47565b50505082870194505b505050508351612b7d818360208801612415565b01949350505050565b600060208284031215612b9857600080fd5b815161147181612789565b60006001600160a01b03808716835280861660208401525083604083015260806060830152612bd56080830184612439565b9695505050505050565b600060208284031215612bf157600080fd5b8151611471816123ca56fea26469706673582212207ec51d89adbd2c8dfe3f5609d26e92752853ab47949daadeacc13c7c2ed7068f64736f6c63430008110033000000000000000000000000d841d89ff8775966750eae25547757751460e1eb0000000000000000000000000138897081e32b6fb3c2280ae541a14aa42f4de10000000000000000000000000138897081e32b6fb3c2280ae541a14aa42f4de100000000000000000000000007037e9767a832ecc63f8dbccfc843fd3d7af4f300000000000000000000000000000000000000000000000000000000000001bc
Deployed Bytecode
0x6080604052600436106102e75760003560e01c80638da5cb5b11610184578063b8d1e532116100d6578063e2e784d51161008a578063f2fde38b11610064578063f2fde38b146108a5578063f7b4c187146108c5578063f9c0611c146108e557600080fd5b8063e2e784d51461081c578063e985e9c51461083c578063f0f442601461088557600080fd5b8063c87b56dd116100bb578063c87b56dd146107d1578063d5abeb01146107f1578063dc62bd891461080757600080fd5b8063b8d1e5321461079c578063c50ef4d8146107bc57600080fd5b8063a22cb46511610138578063a9aad58c11610112578063a9aad58c14610747578063b0ccc31e1461075c578063b88d4fde1461077c57600080fd5b8063a22cb465146106e5578063a49225f814610705578063a88fe42d1461072757600080fd5b806395d89b411161016957806395d89b411461066757806398c83a16146106b0578063a0bcfc7f146106c557600080fd5b80638da5cb5b14610634578063950bff9f1461065257600080fd5b80633ccfd60b1161023d5780636352211e116101f15780637f4e4849116101cb5780637f4e4849146105b657806380623444146105f4578063854cff2f1461061457600080fd5b80636352211e1461056157806370a08231146105815780637e9845f5146105a157600080fd5b80634f6ccce7116102225780634f6ccce71461050b5780635f97036f1461052b57806361d027b31461054157600080fd5b80633ccfd60b146104d657806342842e0e146104eb57600080fd5b806318160ddd1161029f5780632a55205a116102795780632a55205a146104475780632f745c591461048657806338af39e8146104a657600080fd5b806318160ddd146103e45780631a3f839d1461040757806323b872dd1461042757600080fd5b8063081812fc116102d0578063081812fc14610377578063095ea7b3146103af5780630b520220146103d157600080fd5b806301ffc9a7146102ec57806306fdde0314610321575b600080fd5b3480156102f857600080fd5b5061030c6103073660046123f8565b61090d565b60405190151581526020015b60405180910390f35b34801561032d57600080fd5b5061036a6040518060400160405280601581526020017f43757261746564426c6f636b732047656e65736973000000000000000000000081525081565b6040516103189190612465565b34801561038357600080fd5b50610397610392366004612478565b610ad6565b6040516001600160a01b039091168152602001610318565b3480156103bb57600080fd5b506103cf6103ca3660046124ad565b610b41565b005b6103cf6103df3660046124e8565b610cc4565b3480156103f057600080fd5b506103f9610ed0565b604051908152602001610318565b34801561041357600080fd5b506103f96104223660046125e8565b610edf565b34801561043357600080fd5b506103cf610442366004612636565b611017565b34801561045357600080fd5b50610467610462366004612672565b611135565b604080516001600160a01b039093168352602083019190915201610318565b34801561049257600080fd5b506103f96104a13660046124ad565b611195565b3480156104b257600080fd5b506103f96104c1366004612694565b60ff166000908152600e602052604090205490565b3480156104e257600080fd5b506103cf61126f565b3480156104f757600080fd5b506103cf610506366004612636565b6113a8565b34801561051757600080fd5b506103f9610526366004612478565b6113c3565b34801561053757600080fd5b506103f961271081565b34801561054d57600080fd5b50600754610397906001600160a01b031681565b34801561056d57600080fd5b5061039761057c366004612478565b611413565b34801561058d57600080fd5b506103f961059c3660046126af565b611478565b3480156105ad57600080fd5b506103f96114ac565b3480156105c257600080fd5b5060025474010000000000000000000000000000000000000000900460ff165b60405160ff9091168152602001610318565b34801561060057600080fd5b506103cf61060f366004612478565b6114bd565b34801561062057600080fd5b506103cf61062f3660046126af565b611564565b34801561064057600080fd5b506000546001600160a01b0316610397565b34801561065e57600080fd5b506103f9600a81565b34801561067357600080fd5b5061036a6040518060400160405280600781526020017f43424c4f434b530000000000000000000000000000000000000000000000000081525081565b3480156106bc57600080fd5b506105e2600281565b3480156106d157600080fd5b506103cf6106e0366004612740565b6115f2565b3480156106f157600080fd5b506103cf610700366004612797565b611657565b34801561071157600080fd5b506103976daaeb6d7670e522a718067333cd4e81565b34801561073357600080fd5b506103cf6107423660046127ce565b61173c565b34801561075357600080fd5b506105e2600081565b34801561076857600080fd5b50600554610397906001600160a01b031681565b34801561078857600080fd5b506103cf6107973660046127fa565b611806565b3480156107a857600080fd5b506103cf6107b73660046126af565b611864565b3480156107c857600080fd5b506105e2600381565b3480156107dd57600080fd5b5061036a6107ec366004612478565b611914565b3480156107fd57600080fd5b506103f960065481565b34801561081357600080fd5b506105e2600181565b34801561082857600080fd5b506103cf6108373660046124ad565b6119b0565b34801561084857600080fd5b5061030c610857366004612876565b6001600160a01b039182166000908152600d6020908152604080832093909416825291909152205460ff1690565b34801561089157600080fd5b506103cf6108a03660046126af565b611a0f565b3480156108b157600080fd5b506103cf6108c03660046126af565b611a9e565b3480156108d157600080fd5b506103cf6108e0366004612694565b611b5b565b3480156108f157600080fd5b50610397733cc6cdda760b79bafa08df41ecfa224f810dceb681565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806109a057507fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d6300000000000000000000000000000000000000000000000000000000145b806109ec57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610a3857507fffffffff0000000000000000000000000000000000000000000000000000000082167f7f5828d000000000000000000000000000000000000000000000000000000000145b80610a8457507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b80610ad057507fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a00000000000000000000000000000000000000000000000000000000145b92915050565b600081610ae281611bfc565b610b20576040517f1cf4d9a4000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b6000838152600a60205260409020546001600160a01b031691505b50919050565b80610b4b81611bfc565b610b84576040517f1cf4d9a400000000000000000000000000000000000000000000000000000000815260048101829052602401610b17565b33610b8e81611c2c565b6000838152600b60205260409020546001600160a01b03908116908516819003610bef576040517ff2b21e1c0000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152602401610b17565b6000610bfc823387611d20565b905080610c4d576040517f19f48dff0000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015233602482015260448101869052606401610b17565b6000858152600a602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038a811691821790925591518893918616917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050505050565b60025460009074010000000000000000000000000000000000000000900460ff16610d3b576002546040517f5d80b9ec0000000000000000000000000000000000000000000000000000000081527401000000000000000000000000000000000000000090910460ff166004820152602401610b17565b60025474010000000000000000000000000000000000000000900460ff16600a861115610d9e576040517f5aaca4e400000000000000000000000000000000000000000000000000000000815260048101879052600a6024820152604401610b17565b6000610da86114ac565b600654610db591906128d8565b905080871115610dfb576040517f9abbab070000000000000000000000000000000000000000000000000000000081526004810188905260248101829052604401610b17565b60ff85166000908152600e6020526040812054610e1890896128eb565b9050348114610e5c576040517f9310692e00000000000000000000000000000000000000000000000000000000815234600482015260248101829052604401610b17565b610e783384888a8c610e73368c90038c018c612902565b611d8f565b6009546000610e878a8361291e565b336000908152600c6020526040902080548c019055600980548c01905590505b80821015610ec457610eb93383611f25565b600190910190610ea7565b50505050505050505050565b6000610eda611f96565b905090565b6003546000906001600160a01b0316610f24576040517f93dff14200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ff841660009081526004602090815260408083206001600160a01b03891684529091529020548311610f8e576040517f6acdb0950000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152602401610b17565b610f9a85858585611fa0565b610fdb576040517f186a628d0000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152602401610b17565b60ff841660009081526004602090815260408083206001600160a01b038916845290915290205461100c90846128d8565b90505b949350505050565b336001600160a01b038316611058576040517f14242cb600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061106383611413565b9050806001600160a01b0316856001600160a01b0316146110ca576040517fe02b28e70000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301528616602482015260448101849052606401610b17565b6110d5813385611d20565b611123576040517f19f48dff0000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015233602482015260448101849052606401610b17565b61112e818585612075565b5050505050565b6000808215806111455750600154155b1561115f5750506002546001600160a01b0316600061118e565b60006127108460015461117291906128eb565b61117c9190612931565b6002546001600160a01b031693509150505b9250929050565b60006111a083611478565b82106111ea576040517f374f8b4f0000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101839052604401610b17565b6000806111f56114ac565b905060015b818110156112665761120b81611bfc565b801561123057506000818152600b60205260409020546001600160a01b038781169116145b1561125457828503611246579250610ad0915050565b826112508161296c565b9350505b8061125e8161296c565b9150506111fa565b50505092915050565b336112826000546001600160a01b031690565b6001600160a01b0316146112c4576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b476000819003611300576040517f6cc4466b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546040516001600160a01b0390911690600090829084908381818185875af1925050503d8060008114611351576040519150601f19603f3d011682016040523d82523d6000602084013e611356565b606091505b50509050806113a3576040517f84020a7b0000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260248101849052604401610b17565b505050565b6113a383838360405180602001604052806000815250611806565b60006113cd6114ac565b8210611408576040517f125c19b000000000000000000000000000000000000000000000000000000000815260048101839052602401610b17565b610ad082600161291e565b60008161141f81611bfc565b611458576040517f1cf4d9a400000000000000000000000000000000000000000000000000000000815260048101829052602401610b17565b6000838152600b60205260409020546001600160a01b03165b9392505050565b60006001600160a01b03821661149057506000919050565b506001600160a01b03166000908152600c602052604090205490565b60006001600954610eda91906128d8565b336114d06000546001600160a01b031690565b6001600160a01b031614611512576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b60065481118061152857506115256114ac565b81105b1561155f576040517fbcc7b4fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600655565b336115776000546001600160a01b031690565b6001600160a01b0316146115b9576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03831617905550565b50565b336116056000546001600160a01b031690565b6001600160a01b031614611647576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b60086116538282612a21565b5050565b3361166181611c2c565b336001600160a01b0384168190036116b0576040517ff2b21e1c0000000000000000000000000000000000000000000000000000000081526001600160a01b0385166004820152602401610b17565b6001600160a01b038181166000818152600d602090815260408083209489168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001688151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b3361174f6000546001600160a01b031690565b6001600160a01b031614611791576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600e6020527fa7c5ba7114a813b50159add3a36832908dc83db71d0b9a24c2ad0f83be958207929092557f9adb202b1492743bc00c81d33cdc6423fa8c79109027eb6a845391e8fc1f04815560036000527fe0283e559c29e31ee7f56467acc9dd307779c843a883aeeb3bf5c6128c90814455565b611811848484611017565b61181d8484848461211b565b61185e576040517f015be56a0000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152602401610b17565b50505050565b6000546001600160a01b031633146118a8576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f9f513fe86dc42fdbac355fa4d9b1d5be7b5e6cd2df67e30db8003766568de4769060200160405180910390a150565b60608161192081611bfc565b611959576040517f1cf4d9a400000000000000000000000000000000000000000000000000000000815260048101829052602401610b17565b60006008805461196890612986565b90501161197d5761197883612284565b611471565b600861198884612284565b604051602001611999929190612ae1565b604051602081830303815290604052915050919050565b336119c36000546001600160a01b031690565b6001600160a01b031614611a05576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b61165382826122c8565b33611a226000546001600160a01b031690565b6001600160a01b031614611a64576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b33611ab16000546001600160a01b031690565b6001600160a01b031614611af3576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b33611b6e6000546001600160a01b031690565b6001600160a01b031614611bb0576040517f55932a1b000000000000000000000000000000000000000000000000000000008152336004820152602401610b17565b600360ff82161115611bf3576040517fb81f899300000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610b17565b6115ef8161234c565b600081600003611c0e57506000919050565b506000908152600b60205260409020546001600160a01b0316151590565b6005546001600160a01b03168015801590611c5157506000816001600160a01b03163b115b15611653576040517fc61711340000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa158015611cbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cdf9190612b86565b611653576040517fede71dcc0000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b17565b6000836001600160a01b0316836001600160a01b03161480611d5b5750611d4682610ad6565b6001600160a01b0316836001600160a01b0316145b8061100f57506001600160a01b038085166000908152600d602090815260408083209387168352929052205460ff1661100f565b600060001960ff871601611e3357611daa8760018685610edf565b905082811015611df1576040517f186a628d0000000000000000000000000000000000000000000000000000000081526001600160a01b0388166004820152602401610b17565b6001600160a01b03871660009081527fabd6e7cb50984ff9c2f3e18a2660c3353dadf4e3291deeb275dae2cd1e44fe0560205260409020805484019055611f1c565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60ff871601611f0c5760001960ff861601611e7657611daa8760018685610edf565b611e838760028685610edf565b905082811015611eca576040517f186a628d0000000000000000000000000000000000000000000000000000000081526001600160a01b0388166004820152602401610b17565b6001600160a01b03871660009081527f91da3fd0782e51c6b3986e9e672fd566868e71f3dbc2d6c2cd6fbb3e361af2a760205260409020805484019055611f1c565b611f1a876003600185610edf565b505b50505050505050565b6000818152600b602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000610eda6114ac565b6040805160ff851660208201529081018390526001600160a01b0385166060820152600090819060800160405160208183030381529060405280519060200120905060006001828560400151866000015187602001516040516000815260200160405260405161202c949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa15801561204e573d6000803e3d6000fd5b5050604051601f1901516003546001600160a01b0390811691161498975050505050505050565b6001600160a01b038083166000818152600c60209081526040808320805460010190559387168083528483208054600019019055858352600b825284832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168617909155600a909252848320805490921690915592518493917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000833b801561227a576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0386169063150b7a02906121709033908a9089908990600401612ba3565b6020604051808303816000875af19250505080156121ab575060408051601f3d908101601f191682019092526121a891810190612bdf565b60015b61222d573d8080156121d9576040519150601f19603f3d011682016040523d82523d6000602084013e6121de565b606091505b508051600003612225576040517f015be56a0000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152602401610b17565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a020000000000000000000000000000000000000000000000000000000014915061100f9050565b600191505061100f565b606060a06040510180604052602081039150506000815280825b600183039250600a81066030018353600a90048061229e5750819003601f19909101908152919050565b61271081111561230f576040517f4ec3fd3a000000000000000000000000000000000000000000000000000000008152600481018290526127106024820152604401610b17565b600155600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6002805460ff838116740100000000000000000000000000000000000000008181027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff85161790945560405193909204169182907f7285522ec93a20dcefa1a1d057094a227073a5463b91c0c19a23c6ef5c9c1fe490600090a35050565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146115ef57600080fd5b60006020828403121561240a57600080fd5b8135611471816123ca565b60005b83811015612430578181015183820152602001612418565b50506000910152565b60008151808452612451816020860160208601612415565b601f01601f19169290920160200192915050565b6020815260006114716020830184612439565b60006020828403121561248a57600080fd5b5035919050565b80356001600160a01b03811681146124a857600080fd5b919050565b600080604083850312156124c057600080fd5b6124c983612491565b946020939093013593505050565b803560ff811681146124a857600080fd5b60008060008084860360c08112156124ff57600080fd5b8535945060208601359350612516604087016124d7565b925060607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08201121561254857600080fd5b509295919450926060019150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006060828403121561259757600080fd5b6040516060810181811067ffffffffffffffff821117156125ba576125ba612556565b806040525080915082358152602083013560208201526125dc604084016124d7565b60408201525092915050565b60008060008060c085870312156125fe57600080fd5b61260785612491565b9350612615602086016124d7565b92506040850135915061262b8660608701612585565b905092959194509250565b60008060006060848603121561264b57600080fd5b61265484612491565b925061266260208501612491565b9150604084013590509250925092565b6000806040838503121561268557600080fd5b50508035926020909101359150565b6000602082840312156126a657600080fd5b611471826124d7565b6000602082840312156126c157600080fd5b61147182612491565b600067ffffffffffffffff808411156126e5576126e5612556565b604051601f8501601f19908116603f0116810190828211818310171561270d5761270d612556565b8160405280935085815286868601111561272657600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561275257600080fd5b813567ffffffffffffffff81111561276957600080fd5b8201601f8101841361277a57600080fd5b61100f848235602084016126ca565b80151581146115ef57600080fd5b600080604083850312156127aa57600080fd5b6127b383612491565b915060208301356127c381612789565b809150509250929050565b6000806000606084860312156127e357600080fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561281057600080fd5b61281985612491565b935061282760208601612491565b925060408501359150606085013567ffffffffffffffff81111561284a57600080fd5b8501601f8101871361285b57600080fd5b61286a878235602084016126ca565b91505092959194509250565b6000806040838503121561288957600080fd5b61289283612491565b91506128a060208401612491565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610ad057610ad06128a9565b8082028115828204841417610ad057610ad06128a9565b60006060828403121561291457600080fd5b6114718383612585565b80820180821115610ad057610ad06128a9565b600082612967577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000600019820361297f5761297f6128a9565b5060010190565b600181811c9082168061299a57607f821691505b602082108103610b3b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b601f8211156113a357600081815260208120601f850160051c810160208610156129fa5750805b601f850160051c820191505b81811015612a1957828155600101612a06565b505050505050565b815167ffffffffffffffff811115612a3b57612a3b612556565b612a4f81612a498454612986565b846129d3565b602080601f831160018114612a845760008415612a6c5750858301515b600019600386901b1c1916600185901b178555612a19565b600085815260208120601f198616915b82811015612ab357888601518255948401946001909101908401612a94565b5085821015612ad15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808454612aef81612986565b60018281168015612b075760018114612b3a57612b69565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084168752821515830287019450612b69565b8860005260208060002060005b85811015612b605781548a820152908401908201612b47565b50505082870194505b505050508351612b7d818360208801612415565b01949350505050565b600060208284031215612b9857600080fd5b815161147181612789565b60006001600160a01b03808716835280861660208401525083604083015260806060830152612bd56080830184612439565b9695505050505050565b600060208284031215612bf157600080fd5b8151611471816123ca56fea26469706673582212207ec51d89adbd2c8dfe3f5609d26e92752853ab47949daadeacc13c7c2ed7068f64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d841d89ff8775966750eae25547757751460e1eb0000000000000000000000000138897081e32b6fb3c2280ae541a14aa42f4de10000000000000000000000000138897081e32b6fb3c2280ae541a14aa42f4de100000000000000000000000007037e9767a832ecc63f8dbccfc843fd3d7af4f300000000000000000000000000000000000000000000000000000000000001bc
-----Decoded View---------------
Arg [0] : airdropAddress_ (address): 0xd841d89Ff8775966750eAe25547757751460E1eB
Arg [1] : royaltyRecipient_ (address): 0x0138897081e32B6fB3c2280ae541A14aA42F4DE1
Arg [2] : treasury_ (address): 0x0138897081e32B6fB3c2280ae541A14aA42F4DE1
Arg [3] : signerWallet_ (address): 0x07037e9767A832EcC63F8DbccFC843fd3D7aF4F3
Arg [4] : maxSupply_ (uint256): 444
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000d841d89ff8775966750eae25547757751460e1eb
Arg [1] : 0000000000000000000000000138897081e32b6fb3c2280ae541a14aa42f4de1
Arg [2] : 0000000000000000000000000138897081e32b6fb3c2280ae541a14aa42f4de1
Arg [3] : 00000000000000000000000007037e9767a832ecc63f8dbccfc843fd3d7af4f3
Arg [4] : 00000000000000000000000000000000000000000000000000000000000001bc
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.