Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 3,389 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mint With Author... | 21287487 | 34 days ago | IN | 0 ETH | 0.00192279 | ||||
Mint With Author... | 21081993 | 62 days ago | IN | 0 ETH | 0.00163737 | ||||
Mint With Author... | 20470435 | 148 days ago | IN | 0 ETH | 0.00135079 | ||||
Mint With Author... | 20074420 | 203 days ago | IN | 0 ETH | 0.00144757 | ||||
Mint With Author... | 20074153 | 203 days ago | IN | 0 ETH | 0.00129841 | ||||
Mint With Author... | 19395341 | 298 days ago | IN | 0 ETH | 0.00680099 | ||||
Mint With Author... | 19180180 | 328 days ago | IN | 0 ETH | 0.0035935 | ||||
Mint With Author... | 18329688 | 447 days ago | IN | 0 ETH | 0.00124657 | ||||
Mint With Author... | 18279473 | 454 days ago | IN | 0 ETH | 0.00165526 | ||||
Mint With Author... | 18185834 | 468 days ago | IN | 0 ETH | 0.00118177 | ||||
Mint With Author... | 18180471 | 468 days ago | IN | 0 ETH | 0.00155543 | ||||
Mint With Author... | 18180429 | 468 days ago | IN | 0 ETH | 0.00139756 | ||||
Mint With Author... | 17960195 | 499 days ago | IN | 0 ETH | 0.00185244 | ||||
Mint With Author... | 17956141 | 500 days ago | IN | 0 ETH | 0.00210357 | ||||
Mint With Author... | 17812796 | 520 days ago | IN | 0 ETH | 0.00251481 | ||||
Mint With Author... | 17768220 | 526 days ago | IN | 0 ETH | 0.00237718 | ||||
Mint With Author... | 17749567 | 529 days ago | IN | 0 ETH | 0.00265911 | ||||
Mint With Author... | 17663863 | 541 days ago | IN | 0 ETH | 0.00424864 | ||||
Mint With Author... | 17663852 | 541 days ago | IN | 0 ETH | 0.00590039 | ||||
Mint With Author... | 17553682 | 556 days ago | IN | 0 ETH | 0.00247815 | ||||
Mint With Author... | 17547076 | 557 days ago | IN | 0 ETH | 0.00209844 | ||||
Mint With Author... | 17542863 | 558 days ago | IN | 0 ETH | 0.00344248 | ||||
Mint With Author... | 17514615 | 562 days ago | IN | 0 ETH | 0.00294966 | ||||
Mint With Author... | 17507698 | 563 days ago | IN | 0 ETH | 0.00201597 | ||||
Mint With Author... | 17498613 | 564 days ago | IN | 0 ETH | 0.00168388 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
ERC721Minter
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../interfaces/ERC721Spec.sol"; import "../interfaces/AletheaERC721Spec.sol"; import "../utils/AccessControl.sol"; import "../lib/ECDSA.sol"; /** * @title ERC721 Minter * * @notice ERC721Minter contract introduces a scalable mechanism to mint NFTs to an arbitrary * amount of addresses by leveraging the power of EIP712 signature. */ contract ERC721Minter is AccessControl { /** * @dev Mintable ERC721 contract address to mint tokens of */ address public immutable targetContract; /** * @dev Number of ERC721 token been mint by ERC721Minter */ uint256 public tokenMintCount; /** * @dev Max token can be minted by ERC721Minter */ uint256 public maxTokenMintLimit; /** * @notice Enables the airdrop, redeeming the tokens via EIP712 signature * * @dev Feature FEATURE_REDEEM_ACTIVE must be enabled in order for * `mintWithAuthorization` and `mintBatchWithAuthorization` functions to succeed */ uint32 public constant FEATURE_REDEEM_ACTIVE = 0x0000_0001; /** * @notice Authorization manager is responsible for supplying the EIP712 signature * which then can be used to mint tokens, meaning effectively, * that Authorization manager may act as a minter on the target NFT contract * * @dev Role ROLE_AUTHORIZATION_MANAGER allows minting tokens with authorization */ uint32 public constant ROLE_AUTHORIZATION_MANAGER = 0x0001_0000; /** * @notice mint limit manager is responsible for update ERC721 token mint limit * * @dev Role ROLE_MINT_LIMIT_MANAGER allows update token mint limit */ uint32 public constant ROLE_MINT_LIMIT_MANAGER = 0x0002_0000; /** * @notice EIP-712 contract's domain typeHash, * see https://eips.ethereum.org/EIPS/eip-712#rationale-for-typehash * * @dev Note: we do not include version into the domain typehash/separator, * it is implied version is concatenated to the name field, like "ERC721Minter" */ // keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)") bytes32 public constant DOMAIN_TYPEHASH = 0x8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866; /** * @notice EIP-712 contract's domain separator, * see https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator */ bytes32 public immutable DOMAIN_SEPARATOR; // keccak256("MintWithAuthorization(address from,address to,uint256 id,uint256 validAfter,uint256 validBefore,bytes32 nonce)") bytes32 public constant MINT_WITH_AUTHORIZATION_TYPEHASH = 0xaf4e98e5c9896ed6453d82e308a87caa8a02787c2c671d5a8cd308f9a99ed41f; // keccak256("MintBatchWithAuthorization(address from,address to,uint256 id,uint256 amount,uint256 validAfter,uint256 validBefore,bytes32 nonce)") bytes32 public constant MINTBATCH_WITH_AUTHORIZATION_TYPEHASH = 0x67c2bc25c87d2f7202a6c00ccb845fe254f34def701c1f45f93e7e9219b1ebb2; // keccak256("CancelAuthorization(address authorizer,bytes32 nonce)") bytes32 public constant CANCEL_AUTHORIZATION_TYPEHASH = 0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429; /** * @dev A record of used nonces for meta transactions * * @dev Maps authorizer address => nonce => true/false (used unused) */ mapping(address => mapping(bytes32 => bool)) private usedNonces; /** * @dev Fired whenever the nonce gets used (ex.: `mintWithAuthorization`, `mintBatchWithAuthorization`) * * @param authorizer an address which has used the nonce * @param nonce the nonce used */ event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce); /** * @dev Fired whenever the nonce gets cancelled (ex.: `cancelAuthorization`) * * @dev Both `AuthorizationUsed` and `AuthorizationCanceled` imply the nonce * cannot be longer used, the only difference is that `AuthorizationCanceled` * implies no smart contract state change made (except the nonce marked as cancelled) * * @param authorizer an address which has cancelled the nonce * @param nonce the nonce cancelled */ event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce); /** * @dev Fired whenever token mint Limit is updated (ex.: `updateTokenMintLimit`) * * @param authorizer an address which has updated token mint limit * @param oldLimit old token mint limit * @param newLimit new token mint limit */ event TokenMintLimitUpdated(address indexed authorizer, uint256 oldLimit, uint256 newLimit); /** * @dev Creates/deploys ERC721Minter and binds it to ERC721 smart contract on construction * * @param _target deployed Mintable ERC721 smart contract; contract will mint NFTs of that type */ constructor(address _target) { // verify the input is set require(_target != address(0), "target contract is not set"); // verify the input is valid smart contract of the expected interfaces require( ERC165(_target).supportsInterface(type(ERC721).interfaceId) && ERC165(_target).supportsInterface(type(MintableERC721).interfaceId), "unexpected target type" ); // assign the address targetContract = _target; // max ERC721Minter contract can mint 1000 token's maxTokenMintLimit = 1000; // build the EIP-712 contract domain separator, see https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes("ERC721Minter")), block.chainid, address(this))); } /** * @notice Checks if specified nonce was already used * * @dev Nonces are expected to be client-side randomly generated 32-byte values * unique to the authorizer's address * * @dev Alias for usedNonces(authorizer, nonce) * * @param _authorizer an address to check nonce for * @param _nonce a nonce to check * @return true if the nonce was used, false otherwise */ function authorizationState(address _authorizer, bytes32 _nonce) public view returns (bool) { // simply return the value from the mapping return usedNonces[_authorizer][_nonce]; } /** * @notice Receive a token with a signed authorization from the authorization manager * * @dev This has an additional check to ensure that the receiver's address * matches the caller of this function to prevent front-running attacks. * * @param _from token sender and transaction authorizer * @param _to token receiver * @param _id token ID to mint * @param _validAfter signature valid after time (unix timestamp) * @param _validBefore signature valid before time (unix timestamp) * @param _nonce unique random nonce * @param v the recovery byte of the signature * @param r half of the ECDSA signature pair * @param s half of the ECDSA signature pair */ function mintWithAuthorization( address _from, address _to, uint256 _id, uint256 _validAfter, uint256 _validBefore, bytes32 _nonce, uint8 v, bytes32 r, bytes32 s ) public { // verify redeems are enabled require(isFeatureEnabled(FEATURE_REDEEM_ACTIVE), "redeems are disabled"); require(tokenMintCount < maxTokenMintLimit, "minting Limit has been reached!!"); // derive signer of the EIP712 MintWithAuthorization message address signer = __deriveSigner(abi.encode(MINT_WITH_AUTHORIZATION_TYPEHASH, _from, _to, _id, _validAfter, _validBefore, _nonce), v, r, s); // perform message integrity and security validations require(signer == _from, "invalid signature"); require(isOperatorInRole(signer, ROLE_AUTHORIZATION_MANAGER), "invalid access"); require(block.timestamp > _validAfter, "signature not yet valid"); require(block.timestamp < _validBefore, "signature expired"); require(_to == msg.sender, "access denied"); // update token mint count tokenMintCount++; // use the nonce supplied (verify, mark as used, emit event) __useNonce(_from, _nonce, false); // mint token to the recipient MintableERC721(targetContract).mint(_to, _id); } /** * @notice Receive tokens with a signed authorization from the authorization manager * * @dev This has an additional check to ensure that the receiver's address * matches the caller of this function to prevent front-running attacks. * * @param _from token sender and transaction authorizer * @param _to token receiver * @param _id token ID to mint * @param _amount amount of tokens to create, two or more * @param _validAfter signature valid after time (unix timestamp) * @param _validBefore signature valid before time (unix timestamp) * @param _nonce unique random nonce * @param v the recovery byte of the signature * @param r half of the ECDSA signature pair * @param s half of the ECDSA signature pair */ function mintBatchWithAuthorization( address _from, address _to, uint256 _id, uint256 _amount, uint256 _validAfter, uint256 _validBefore, bytes32 _nonce, uint8 v, bytes32 r, bytes32 s ) public { // verify redeems are enabled require(isFeatureEnabled(FEATURE_REDEEM_ACTIVE), "redeems are disabled"); require(tokenMintCount + _amount <= maxTokenMintLimit, "minting Limit has been reached!!"); // derive signer of the EIP712 MintBatchWithAuthorization message address signer = __deriveSigner(abi.encode(MINTBATCH_WITH_AUTHORIZATION_TYPEHASH, _from, _to, _id, _amount, _validAfter, _validBefore, _nonce), v, r, s); // perform message integrity and security validations require(signer == _from, "invalid signature"); require(isOperatorInRole(signer, ROLE_AUTHORIZATION_MANAGER), "invalid access"); require(block.timestamp > _validAfter, "signature not yet valid"); require(block.timestamp < _validBefore, "signature expired"); require(_to == msg.sender, "access denied"); // update token mint count tokenMintCount = tokenMintCount + _amount; // use the nonce supplied (verify, mark as used, emit event) __useNonce(_from, _nonce, false); // mint token to the recipient MintableERC721(targetContract).mintBatch(_to, _id, _amount); } /** * @notice Attempt to cancel an authorization * * @param _authorizer transaction authorizer * @param _nonce unique random nonce to cancel (mark as used) * @param v the recovery byte of the signature * @param r half of the ECDSA signature pair * @param s half of the ECDSA signature pair */ function cancelAuthorization( address _authorizer, bytes32 _nonce, uint8 v, bytes32 r, bytes32 s ) public { // derive signer of the EIP712 ReceiveWithAuthorization message address signer = __deriveSigner(abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, _authorizer, _nonce), v, r, s); // perform message integrity and security validations require(signer == _authorizer, "invalid signature"); // cancel the nonce supplied (verify, mark as used, emit event) __useNonce(_authorizer, _nonce, true); } /** * @dev Auxiliary function to verify structured EIP712 message signature and derive its signer * * @param abiEncodedTypehash abi.encode of the message typehash together with all its parameters * @param v the recovery byte of the signature * @param r half of the ECDSA signature pair * @param s half of the ECDSA signature pair */ function __deriveSigner(bytes memory abiEncodedTypehash, uint8 v, bytes32 r, bytes32 s) private view returns(address) { // build the EIP-712 hashStruct of the message bytes32 hashStruct = keccak256(abiEncodedTypehash); // calculate the EIP-712 digest "\x19\x01" ‖ domainSeparator ‖ hashStruct(message) bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hashStruct)); // recover the address which signed the message with v, r, s address signer = ECDSA.recover(digest, v, r, s); // return the signer address derived from the signature return signer; } /** * @dev Auxiliary function to use/cancel the nonce supplied for a given authorizer: * 1. Verifies the nonce was not used before * 2. Marks the nonce as used * 3. Emits an event that the nonce was used/cancelled * * @dev Set `_cancellation` to false (default) to use nonce, * set `_cancellation` to true to cancel nonce * * @dev It is expected that the nonce supplied is a randomly * generated uint256 generated by the client * * @param _authorizer an address to use/cancel nonce for * @param _nonce random nonce to use * @param _cancellation true to emit `AuthorizationCancelled`, false to emit `AuthorizationUsed` event */ function __useNonce(address _authorizer, bytes32 _nonce, bool _cancellation) private { // verify nonce was not used before require(!usedNonces[_authorizer][_nonce], "invalid nonce"); // update the nonce state to "used" for that particular signer to avoid replay attack usedNonces[_authorizer][_nonce] = true; // depending on the usage type (use/cancel) if(_cancellation) { // emit an event regarding the nonce cancelled emit AuthorizationCanceled(_authorizer, _nonce); } else { // emit an event regarding the nonce used emit AuthorizationUsed(_authorizer, _nonce); } } /** * @notice Updates max ERC721 token mint Limit of * ERC721Minter contract. * * @dev Requires transaction sender to have `ROLE_ACCESS_MANAGER` permission * * @param _tokenMintLimit new ERC721 token mint limit */ function updateTokenMintLimit(uint256 _tokenMintLimit) public { // caller must have a permission to update token mint limit require(isSenderInRole(ROLE_MINT_LIMIT_MANAGER), "access denied"); // fire an event emit TokenMintLimitUpdated(msg.sender, maxTokenMintLimit, _tokenMintLimit); // update token mint limit maxTokenMintLimit = _tokenMintLimit; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./ERC165Spec.sol"; /** * @title ERC-721 Non-Fungible Token Standard * * @notice See https://eips.ethereum.org/EIPS/eip-721 * * @dev Solidity issue #3412: The ERC721 interfaces include explicit mutability guarantees for each function. * Mutability guarantees are, in order weak to strong: payable, implicit nonpayable, view, and pure. * Implementation MUST meet the mutability guarantee in this interface and MAY meet a stronger guarantee. * For example, a payable function in this interface may be implemented as nonpayable * (no state mutability specified) in implementing contract. * It is expected a later Solidity release will allow stricter contract to inherit from this interface, * but current workaround is that we edit this interface to add stricter mutability before inheriting: * we have removed all "payable" modifiers. * * @dev The ERC-165 identifier for this interface is 0x80ac58cd. * * @author William Entriken, Dieter Shirley, Jacob Evans, Nastassia Sachs */ interface ERC721 is ERC165 { /// @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. event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); /// @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. 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. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); /// @notice Count all NFTs assigned to an owner /// @dev NFTs assigned to the zero address are considered invalid, and this /// function throws for queries about the zero address. /// @param _owner An address for whom to query the balance /// @return The number of NFTs owned by `_owner`, possibly zero function balanceOf(address _owner) external view returns (uint256); /// @notice Find the owner of an NFT /// @dev NFTs assigned to zero address are considered invalid, and queries /// about them do throw. /// @param _tokenId The identifier for an NFT /// @return The address of the owner of the NFT function ownerOf(uint256 _tokenId) external view returns (address); /// @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)"))`. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param _data Additional data with no specified format, sent in call to `_to` function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata _data) external /*payable*/; /// @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 "". /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function safeTransferFrom(address _from, address _to, uint256 _tokenId) external /*payable*/; /// @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. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom(address _from, address _to, uint256 _tokenId) external /*payable*/; /// @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. /// @param _approved The new approved NFT controller /// @param _tokenId The NFT to approve function approve(address _approved, uint256 _tokenId) external /*payable*/; /// @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. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval function setApprovalForAll(address _operator, bool _approved) external; /// @notice Get the approved address for a single NFT /// @dev Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none function getApproved(uint256 _tokenId) external view returns (address); /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise function isApprovedForAll(address _owner, address _operator) external view returns (bool); } /// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. interface ERC721TokenReceiver { /// @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. /// @param _operator The address which called `safeTransferFrom` function /// @param _from The address which previously owned the token /// @param _tokenId The NFT identifier which is being transferred /// @param _data Additional data with no specified format /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` /// unless throwing function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external returns(bytes4); } /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * * @notice See https://eips.ethereum.org/EIPS/eip-721 * * @dev The ERC-165 identifier for this interface is 0x5b5e139f. * * @author William Entriken, Dieter Shirley, Jacob Evans, Nastassia Sachs */ interface ERC721Metadata is ERC721 { /// @notice A descriptive name for a collection of NFTs in this contract function name() external view returns (string memory _name); /// @notice An abbreviated name for NFTs in this contract function symbol() external view returns (string memory _symbol); /// @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); } /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * * @notice See https://eips.ethereum.org/EIPS/eip-721 * * @dev The ERC-165 identifier for this interface is 0x780e9d63. * * @author William Entriken, Dieter Shirley, Jacob Evans, Nastassia Sachs */ interface ERC721Enumerable is ERC721 { /// @notice Count NFTs tracked by this contract /// @return A count of valid NFTs tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address function totalSupply() external view returns (uint256); /// @notice Enumerate valid NFTs /// @dev Throws if `_index` >= `totalSupply()`. /// @param _index A counter less than `totalSupply()` /// @return The token identifier for the `_index`th NFT, /// (sort order not specified) 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. /// @param _owner An address where we are interested in NFTs owned by them /// @param _index A counter less than `balanceOf(_owner)` /// @return The token identifier for the `_index`th NFT assigned to `_owner`, /// (sort order not specified) function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @title Alethea Mintable ERC721 * * @notice Defines mint capabilities for Alethea ERC721 tokens. * This interface should be treated as a definition of what mintable means for ERC721 * * @author Basil Gorin */ interface MintableERC721 { /** * @notice Checks if specified token exists * * @dev Returns whether the specified token ID has an ownership * information associated with it * * @param _tokenId ID of the token to query existence for * @return whether the token exists (true - exists, false - doesn't exist) */ function exists(uint256 _tokenId) external view returns(bool); /** * @dev Creates new token with token ID specified * and assigns an ownership `_to` for this token * * @dev Unsafe: doesn't execute `onERC721Received` on the receiver. * Prefer the use of `saveMint` instead of `mint`. * * @dev Should have a restricted access handled by the implementation * * @param _to an address to mint token to * @param _tokenId ID of the token to mint */ function mint(address _to, uint256 _tokenId) external; /** * @dev Creates new tokens starting with token ID specified * and assigns an ownership `_to` for these tokens * * @dev Token IDs to be minted: [_tokenId, _tokenId + n) * * @dev n must be greater or equal 2: `n > 1` * * @dev Unsafe: doesn't execute `onERC721Received` on the receiver. * Prefer the use of `saveMintBatch` instead of `mintBatch`. * * @dev Should have a restricted access handled by the implementation * * @param _to an address to mint tokens to * @param _tokenId ID of the first token to mint * @param n how many tokens to mint, sequentially increasing the _tokenId */ function mintBatch(address _to, uint256 _tokenId, uint256 n) external; /** * @dev Creates new token with token ID specified * and assigns an ownership `_to` for this token * * @dev 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)"))`. * * @dev Should have a restricted access handled by the implementation * * @param _to an address to mint token to * @param _tokenId ID of the token to mint */ function safeMint(address _to, uint256 _tokenId) external; /** * @dev Creates new token with token ID specified * and assigns an ownership `_to` for this token * * @dev 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)"))`. * * @dev Should have a restricted access handled by the implementation * * @param _to an address to mint token to * @param _tokenId ID of the token to mint * @param _data additional data with no specified format, sent in call to `_to` */ function safeMint(address _to, uint256 _tokenId, bytes memory _data) external; /** * @dev Creates new tokens starting with token ID specified * and assigns an ownership `_to` for these tokens * * @dev Token IDs to be minted: [_tokenId, _tokenId + n) * * @dev n must be greater or equal 2: `n > 1` * * @dev 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)"))`. * * @dev Should have a restricted access handled by the implementation * * @param _to an address to mint token to * @param _tokenId ID of the token to mint * @param n how many tokens to mint, sequentially increasing the _tokenId */ function safeMintBatch(address _to, uint256 _tokenId, uint256 n) external; /** * @dev Creates new tokens starting with token ID specified * and assigns an ownership `_to` for these tokens * * @dev Token IDs to be minted: [_tokenId, _tokenId + n) * * @dev n must be greater or equal 2: `n > 1` * * @dev 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)"))`. * * @dev Should have a restricted access handled by the implementation * * @param _to an address to mint token to * @param _tokenId ID of the token to mint * @param n how many tokens to mint, sequentially increasing the _tokenId * @param _data additional data with no specified format, sent in call to `_to` */ function safeMintBatch(address _to, uint256 _tokenId, uint256 n, bytes memory _data) external; } /** * @title Alethea Burnable ERC721 * * @notice Defines burn capabilities for Alethea ERC721 tokens. * This interface should be treated as a definition of what burnable means for ERC721 * * @author Basil Gorin */ interface BurnableERC721 { /** * @notice Destroys the token with token ID specified * * @dev Should be accessible publicly by token owners. * May have a restricted access handled by the implementation * * @param _tokenId ID of the token to burn */ function burn(uint256 _tokenId) external; } /** * @title With Base URI * * @notice A marker interface for the contracts having the baseURI() function * or public string variable named baseURI * NFT implementations like TinyERC721, or ShortERC721 are example of such smart contracts * * @author Basil Gorin */ interface WithBaseURI { /** * @dev Usually used in NFT implementations to construct ERC721Metadata.tokenURI as * `base URI + token ID` if token URI is not set (not present in `_tokenURIs` mapping) * * @dev For example, if base URI is https://api.com/token/, then token #1 * will have an URI https://api.com/token/1 */ function baseURI() external view returns(string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @title Access Control List * * @notice Access control smart contract provides an API to check * if specific operation is permitted globally and/or * if particular user has a permission to execute it. * * @notice It deals with two main entities: features and roles. * * @notice Features are designed to be used to enable/disable specific * functions (public functions) of the smart contract for everyone. * @notice User roles are designed to restrict access to specific * functions (restricted functions) of the smart contract to some users. * * @notice Terms "role", "permissions" and "set of permissions" have equal meaning * in the documentation text and may be used interchangeably. * @notice Terms "permission", "single permission" implies only one permission bit set. * * @notice Access manager is a special role which allows to grant/revoke other roles. * Access managers can only grant/revoke permissions which they have themselves. * As an example, access manager with no other roles set can only grant/revoke its own * access manager permission and nothing else. * * @notice Access manager permission should be treated carefully, as a super admin permission: * Access manager with even no other permission can interfere with another account by * granting own access manager permission to it and effectively creating more powerful * permission set than its own. * * @dev Both current and OpenZeppelin AccessControl implementations feature a similar API * to check/know "who is allowed to do this thing". * @dev Zeppelin implementation is more flexible: * - it allows setting unlimited number of roles, while current is limited to 256 different roles * - it allows setting an admin for each role, while current allows having only one global admin * @dev Current implementation is more lightweight: * - it uses only 1 bit per role, while Zeppelin uses 256 bits * - it allows setting up to 256 roles at once, in a single transaction, while Zeppelin allows * setting only one role in a single transaction * * @dev This smart contract is designed to be inherited by other * smart contracts which require access control management capabilities. * * @dev Access manager permission has a bit 255 set. * This bit must not be used by inheriting contracts for any other permissions/features. * * @author Basil Gorin */ contract AccessControl { /** * @notice Access manager is responsible for assigning the roles to users, * enabling/disabling global features of the smart contract * @notice Access manager can add, remove and update user roles, * remove and update global features * * @dev Role ROLE_ACCESS_MANAGER allows modifying user roles and global features * @dev Role ROLE_ACCESS_MANAGER has single bit at position 255 enabled */ uint256 public constant ROLE_ACCESS_MANAGER = 0x8000000000000000000000000000000000000000000000000000000000000000; /** * @dev Bitmask representing all the possible permissions (super admin role) * @dev Has all the bits are enabled (2^256 - 1 value) */ uint256 private constant FULL_PRIVILEGES_MASK = type(uint256).max; // before 0.8.0: uint256(-1) overflows to 0xFFFF... /** * @notice Privileged addresses with defined roles/permissions * @notice In the context of ERC20/ERC721 tokens these can be permissions to * allow minting or burning tokens, transferring on behalf and so on * * @dev Maps user address to the permissions bitmask (role), where each bit * represents a permission * @dev Bitmask 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF * represents all possible permissions * @dev 'This' address mapping represents global features of the smart contract */ mapping(address => uint256) public userRoles; /** * @dev Fired in updateRole() and updateFeatures() * * @param _by operator which called the function * @param _to address which was granted/revoked permissions * @param _requested permissions requested * @param _actual permissions effectively set */ event RoleUpdated(address indexed _by, address indexed _to, uint256 _requested, uint256 _actual); /** * @notice Creates an access control instance, * setting contract creator to have full privileges */ constructor() { // contract creator has full privileges userRoles[msg.sender] = FULL_PRIVILEGES_MASK; } /** * @notice Retrieves globally set of features enabled * * @dev Effectively reads userRoles role for the contract itself * * @return 256-bit bitmask of the features enabled */ function features() public view returns(uint256) { // features are stored in 'this' address mapping of `userRoles` structure return userRoles[address(this)]; } /** * @notice Updates set of the globally enabled features (`features`), * taking into account sender's permissions * * @dev Requires transaction sender to have `ROLE_ACCESS_MANAGER` permission * @dev Function is left for backward compatibility with older versions * * @param _mask bitmask representing a set of features to enable/disable */ function updateFeatures(uint256 _mask) public { // delegate call to `updateRole` updateRole(address(this), _mask); } /** * @notice Updates set of permissions (role) for a given user, * taking into account sender's permissions. * * @dev Setting role to zero is equivalent to removing an all permissions * @dev Setting role to `FULL_PRIVILEGES_MASK` is equivalent to * copying senders' permissions (role) to the user * @dev Requires transaction sender to have `ROLE_ACCESS_MANAGER` permission * * @param operator address of a user to alter permissions for or zero * to alter global features of the smart contract * @param role bitmask representing a set of permissions to * enable/disable for a user specified */ function updateRole(address operator, uint256 role) public { // caller must have a permission to update user roles require(isSenderInRole(ROLE_ACCESS_MANAGER), "access denied"); // evaluate the role and reassign it userRoles[operator] = evaluateBy(msg.sender, userRoles[operator], role); // fire an event emit RoleUpdated(msg.sender, operator, role, userRoles[operator]); } /** * @notice Determines the permission bitmask an operator can set on the * target permission set * @notice Used to calculate the permission bitmask to be set when requested * in `updateRole` and `updateFeatures` functions * * @dev Calculated based on: * 1) operator's own permission set read from userRoles[operator] * 2) target permission set - what is already set on the target * 3) desired permission set - what do we want set target to * * @dev Corner cases: * 1) Operator is super admin and its permission set is `FULL_PRIVILEGES_MASK`: * `desired` bitset is returned regardless of the `target` permission set value * (what operator sets is what they get) * 2) Operator with no permissions (zero bitset): * `target` bitset is returned regardless of the `desired` value * (operator has no authority and cannot modify anything) * * @dev Example: * Consider an operator with the permissions bitmask 00001111 * is about to modify the target permission set 01010101 * Operator wants to set that permission set to 00110011 * Based on their role, an operator has the permissions * to update only lowest 4 bits on the target, meaning that * high 4 bits of the target set in this example is left * unchanged and low 4 bits get changed as desired: 01010011 * * @param operator address of the contract operator which is about to set the permissions * @param target input set of permissions to operator is going to modify * @param desired desired set of permissions operator would like to set * @return resulting set of permissions given operator will set */ function evaluateBy(address operator, uint256 target, uint256 desired) public view returns(uint256) { // read operator's permissions uint256 p = userRoles[operator]; // taking into account operator's permissions, // 1) enable the permissions desired on the `target` target |= p & desired; // 2) disable the permissions desired on the `target` target &= FULL_PRIVILEGES_MASK ^ (p & (FULL_PRIVILEGES_MASK ^ desired)); // return calculated result return target; } /** * @notice Checks if requested set of features is enabled globally on the contract * * @param required set of features to check against * @return true if all the features requested are enabled, false otherwise */ function isFeatureEnabled(uint256 required) public view returns(bool) { // delegate call to `__hasRole`, passing `features` property return __hasRole(features(), required); } /** * @notice Checks if transaction sender `msg.sender` has all the permissions required * * @param required set of permissions (role) to check against * @return true if all the permissions requested are enabled, false otherwise */ function isSenderInRole(uint256 required) public view returns(bool) { // delegate call to `isOperatorInRole`, passing transaction sender return isOperatorInRole(msg.sender, required); } /** * @notice Checks if operator has all the permissions (role) required * * @param operator address of the user to check role for * @param required set of permissions (role) to check * @return true if all the permissions requested are enabled, false otherwise */ function isOperatorInRole(address operator, uint256 required) public view returns(bool) { // delegate call to `__hasRole`, passing operator's permissions (role) return __hasRole(userRoles[operator], required); } /** * @dev Checks if role `actual` contains all the permissions required `required` * * @param actual existent role * @param required required role * @return true if actual has required role (all permissions), false otherwise */ function __hasRole(uint256 actual, uint256 required) internal pure returns(bool) { // check the bitmask for the role required and return the result return actual & required == required; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. * * @dev Copy of the Zeppelin's library: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/b0cf6fbb7a70f31527f36579ad644e1cf12fdf4e/contracts/utils/cryptography/ECDSA.sol */ library ECDSA { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } } else if (signature.length == 64) { // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { let vs := mload(add(signature, 0x40)) r := mload(add(signature, 0x20)) s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } } else { revert("invalid signature length"); } return recover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require( uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "invalid signature 's' value" ); require(v == 27 || v == 28, "invalid signature 'v' value"); // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); require(signer != address(0), "invalid signature"); return signer; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** * @title ERC-165 Standard Interface Detection * * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * @dev Implementers can declare support of contract interfaces, * which can then be queried by others. * * @author Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken */ interface ERC165 { /** * @notice Query if a contract implements an interface * * @dev Interface identification is specified in ERC-165. * This function uses less than 30,000 gas. * * @param interfaceID The interface identifier, as specified in ERC-165 * @return `true` if the contract implements `interfaceID` and * `interfaceID` is not 0xffffffff, `false` otherwise */ function supportsInterface(bytes4 interfaceID) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_target","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_by","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_requested","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_actual","type":"uint256"}],"name":"RoleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"TokenMintLimitUpdated","type":"event"},{"inputs":[],"name":"CANCEL_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEATURE_REDEEM_ACTIVE","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTBATCH_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_ACCESS_MANAGER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_AUTHORIZATION_MANAGER","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_MINT_LIMIT_MANAGER","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_authorizer","type":"address"},{"internalType":"bytes32","name":"_nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_authorizer","type":"address"},{"internalType":"bytes32","name":"_nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"target","type":"uint256"},{"internalType":"uint256","name":"desired","type":"uint256"}],"name":"evaluateBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"features","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"}],"name":"isFeatureEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"required","type":"uint256"}],"name":"isOperatorInRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"}],"name":"isSenderInRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokenMintLimit","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":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_validAfter","type":"uint256"},{"internalType":"uint256","name":"_validBefore","type":"uint256"},{"internalType":"bytes32","name":"_nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"mintBatchWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_validAfter","type":"uint256"},{"internalType":"uint256","name":"_validBefore","type":"uint256"},{"internalType":"bytes32","name":"_nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"mintWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"targetContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenMintCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mask","type":"uint256"}],"name":"updateFeatures","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"role","type":"uint256"}],"name":"updateRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenMintLimit","type":"uint256"}],"name":"updateTokenMintLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRoles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b5060405162001598380380620015988339810160408190526200003491620002cf565b33600090815260208190526040902060001990556001600160a01b038116620000a45760405162461bcd60e51b815260206004820152601a60248201527f74617267657420636f6e7472616374206973206e6f742073657400000000000060448201526064015b60405180910390fd5b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b038216906301ffc9a79060240160206040518083038186803b158015620000eb57600080fd5b505afa15801562000100573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000126919062000301565b8015620001b057506040516301ffc9a760e01b8152633197b5d160e21b60048201526001600160a01b038216906301ffc9a79060240160206040518083038186803b1580156200017557600080fd5b505afa1580156200018a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b0919062000301565b620001fe5760405162461bcd60e51b815260206004820152601660248201527f756e65787065637465642074617267657420747970650000000000000000000060448201526064016200009b565b6001600160601b0319606082901b166080526103e8600255604080518082018252600c81526b22a9219b9918a6b4b73a32b960a11b6020918201529051620002ad917f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866917fa72986cf2e84c8e2bcbe7c0e1ecaa1e88cd80d547ea7b949d5dcd2b92edeabe7914691309101938452602084019290925260408301526001600160a01b0316606082015260800190565b60408051601f19818403018152919052805160209091012060a0525062000325565b600060208284031215620002e257600080fd5b81516001600160a01b0381168114620002fa57600080fd5b9392505050565b6000602082840312156200031457600080fd5b81518015158114620002fa57600080fd5b60805160601c60a05161123562000363600039600081816101f40152610c7b0152600081816102f90152818161089c0152610bb201526112356000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1155f50116100de578063d1333c9811610097578063e94a010211610071578063e94a010214610393578063f822d5aa146103cc578063fcc2c078146103df578063ff2642cf146103f257600080fd5b8063d1333c9814610346578063d5bb7f6714610359578063d91694871461036c57600080fd5b8063a1155f50146102ba578063ae5b102e146102c3578063ae682e2e146102d6578063ba652d18146102e1578063bd90df70146102f4578063c688d6931461033357600080fd5b80635a049a70116101305780635a049a701461022b5780635c39eeb51461023e5780636fe41ee414610265578063725f36261461026d57806374d5e100146102905780638f6a046c146102b057600080fd5b806311a8278a1461017857806320606b701461019c57806325ada770146101d15780632b521416146101da5780633644e515146101ef57806352d8a87c14610216575b600080fd5b6101826201000081565b60405163ffffffff90911681526020015b60405180910390f35b6101c37f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b604051908152602001610193565b6101c360015481565b306000908152602081905260409020546101c3565b6101c37f000000000000000000000000000000000000000000000000000000000000000081565b61022961022436600461114b565b610419565b005b6102296102393660046110ca565b61048d565b6101c37f67c2bc25c87d2f7202a6c00ccb845fe254f34def701c1f45f93e7e9219b1ebb281565b610182600181565b61028061027b36600461114b565b610538565b6040519015158152602001610193565b6101c361029e366004610f7e565b60006020819052908152604090205481565b6101826202000081565b6101c360025481565b6102296102d13660046110a0565b610553565b6101c3600160ff1b81565b6102296102ef366004611017565b6105fd565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610193565b6102806103413660046110a0565b610905565b610229610354366004610f99565b61092a565b61022961036736600461114b565b610c1a565b6101c37f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b6102806103a13660046110a0565b6001600160a01b03919091166000908152600360209081526040808320938352929052205460ff1690565b6101c36103da366004611118565b610c27565b6102806103ed36600461114b565b610c52565b6101c37faf4e98e5c9896ed6453d82e308a87caa8a02787c2c671d5a8cd308f9a99ed41f81565b61042562020000610c52565b61044a5760405162461bcd60e51b81526004016104419061118f565b60405180910390fd5b600254604080519182526020820183905233917f6d74a65a0a51fed60628f3559d4289c2aade63a663302b58bebe3a281fbaed67910160405180910390a2600255565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b03871691810191909152606081018590526000906104f1906080015b604051602081830303815290604052858585610c5e565b9050856001600160a01b0316816001600160a01b0316146105245760405162461bcd60e51b815260040161044190611164565b61053086866001610ce0565b505050505050565b30600090815260208190526040812054821682145b92915050565b610560600160ff1b610c52565b61057c5760405162461bcd60e51b81526004016104419061118f565b6001600160a01b0382166000908152602081905260409020546105a190339083610c27565b6001600160a01b03831660008181526020818152604091829020849055815185815290810193909352909133917f5a10526456f5116c0b7b80582c217d666243fd51b6a2d92c8011e601c2462e5f910160405180910390a35050565b6106076001610538565b61064a5760405162461bcd60e51b81526020600482015260146024820152731c995919595b5cc8185c9948191a5cd8589b195960621b6044820152606401610441565b6002548760015461065b91906111b6565b11156106a95760405162461bcd60e51b815260206004820181905260248201527f6d696e74696e67204c696d697420686173206265656e207265616368656421216044820152606401610441565b604080517f67c2bc25c87d2f7202a6c00ccb845fe254f34def701c1f45f93e7e9219b1ebb260208201526001600160a01b03808d1692820192909252908a1660608201526080810189905260a0810188905260c0810187905260e08101869052610100810185905260009061072190610120016104da565b90508a6001600160a01b0316816001600160a01b0316146107545760405162461bcd60e51b815260040161044190611164565b6107618162010000610905565b61079e5760405162461bcd60e51b815260206004820152600e60248201526d696e76616c69642061636365737360901b6044820152606401610441565b8642116107e75760405162461bcd60e51b81526020600482015260176024820152761cda59db985d1d5c99481b9bdd081e595d081d985b1a59604a1b6044820152606401610441565b85421061082a5760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b6044820152606401610441565b6001600160a01b038a1633146108525760405162461bcd60e51b81526004016104419061118f565b8760015461086091906111b6565b60015561086f8b866000610ce0565b604051631740d57560e11b81526001600160a01b038b81166004830152602482018b9052604482018a90527f00000000000000000000000000000000000000000000000000000000000000001690632e81aaea90606401600060405180830381600087803b1580156108e057600080fd5b505af11580156108f4573d6000803e3d6000fd5b505050505050505050505050505050565b6001600160a01b038216600090815260208190526040812054821682145b9392505050565b6109346001610538565b6109775760405162461bcd60e51b81526020600482015260146024820152731c995919595b5cc8185c9948191a5cd8589b195960621b6044820152606401610441565b600254600154106109ca5760405162461bcd60e51b815260206004820181905260248201527f6d696e74696e67204c696d697420686173206265656e207265616368656421216044820152606401610441565b604080517faf4e98e5c9896ed6453d82e308a87caa8a02787c2c671d5a8cd308f9a99ed41f60208201526001600160a01b03808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e08101859052600090610a3a90610100016104da565b9050896001600160a01b0316816001600160a01b031614610a6d5760405162461bcd60e51b815260040161044190611164565b610a7a8162010000610905565b610ab75760405162461bcd60e51b815260206004820152600e60248201526d696e76616c69642061636365737360901b6044820152606401610441565b864211610b005760405162461bcd60e51b81526020600482015260176024820152761cda59db985d1d5c99481b9bdd081e595d081d985b1a59604a1b6044820152606401610441565b854210610b435760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b6044820152606401610441565b6001600160a01b0389163314610b6b5760405162461bcd60e51b81526004016104419061118f565b60018054906000610b7b836111ce565b9190505550610b8c8a866000610ce0565b6040516340c10f1960e01b81526001600160a01b038a81166004830152602482018a90527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b158015610bf657600080fd5b505af1158015610c0a573d6000803e3d6000fd5b5050505050505050505050505050565b610c243082610553565b50565b6001600160a01b03929092166000908152602081905260409020546000198084188216189216171690565b600061054d3383610905565b835160208086019190912060405161190160f01b928101929092527f000000000000000000000000000000000000000000000000000000000000000060228301526042820181905260009182906062016040516020818303038152906040528051906020012090506000610cd482888888610dee565b98975050505050505050565b6001600160a01b038316600090815260036020908152604080832085845290915290205460ff1615610d445760405162461bcd60e51b815260206004820152600d60248201526c696e76616c6964206e6f6e636560981b6044820152606401610441565b6001600160a01b03831660009081526003602090815260408083208584529091529020805460ff191660011790558015610db35760405182906001600160a01b038516907f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8190600090a3505050565b60405182906001600160a01b038516907f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a590600090a3505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115610e605760405162461bcd60e51b815260206004820152601b60248201527f696e76616c6964207369676e6174757265202773272076616c756500000000006044820152606401610441565b8360ff16601b1480610e7557508360ff16601c145b610ec15760405162461bcd60e51b815260206004820152601b60248201527f696e76616c6964207369676e6174757265202776272076616c756500000000006044820152606401610441565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015610f15573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610f485760405162461bcd60e51b815260040161044190611164565b95945050505050565b80356001600160a01b0381168114610f6857600080fd5b919050565b803560ff81168114610f6857600080fd5b600060208284031215610f9057600080fd5b61092382610f51565b60008060008060008060008060006101208a8c031215610fb857600080fd5b610fc18a610f51565b9850610fcf60208b01610f51565b975060408a0135965060608a0135955060808a0135945060a08a01359350610ff960c08b01610f6d565b925060e08a013591506101008a013590509295985092959850929598565b6000806000806000806000806000806101408b8d03121561103757600080fd5b6110408b610f51565b995061104e60208c01610f51565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135935061107f60e08c01610f6d565b92506101008b013591506101208b013590509295989b9194979a5092959850565b600080604083850312156110b357600080fd5b6110bc83610f51565b946020939093013593505050565b600080600080600060a086880312156110e257600080fd5b6110eb86610f51565b94506020860135935061110060408701610f6d565b94979396509394606081013594506080013592915050565b60008060006060848603121561112d57600080fd5b61113684610f51565b95602085013595506040909401359392505050565b60006020828403121561115d57600080fd5b5035919050565b602080825260119082015270696e76616c6964207369676e617475726560781b604082015260600190565b6020808252600d908201526c1858d8d95cdcc819195b9a5959609a1b604082015260600190565b600082198211156111c9576111c96111e9565b500190565b60006000198214156111e2576111e26111e9565b5060010190565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220a467b60ef6ab1fc854a58cc2d7612a65317cce8d623b62442969df680fe11e3e64736f6c63430008070033000000000000000000000000ce69a87c02baa8c5f17ed7eb8b1c2657afc2e1af
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101735760003560e01c8063a1155f50116100de578063d1333c9811610097578063e94a010211610071578063e94a010214610393578063f822d5aa146103cc578063fcc2c078146103df578063ff2642cf146103f257600080fd5b8063d1333c9814610346578063d5bb7f6714610359578063d91694871461036c57600080fd5b8063a1155f50146102ba578063ae5b102e146102c3578063ae682e2e146102d6578063ba652d18146102e1578063bd90df70146102f4578063c688d6931461033357600080fd5b80635a049a70116101305780635a049a701461022b5780635c39eeb51461023e5780636fe41ee414610265578063725f36261461026d57806374d5e100146102905780638f6a046c146102b057600080fd5b806311a8278a1461017857806320606b701461019c57806325ada770146101d15780632b521416146101da5780633644e515146101ef57806352d8a87c14610216575b600080fd5b6101826201000081565b60405163ffffffff90911681526020015b60405180910390f35b6101c37f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b604051908152602001610193565b6101c360015481565b306000908152602081905260409020546101c3565b6101c37fad86e9b1a125f22d1703e10e3aee42b417379544fd864ec5ac93be1e129a9f1d81565b61022961022436600461114b565b610419565b005b6102296102393660046110ca565b61048d565b6101c37f67c2bc25c87d2f7202a6c00ccb845fe254f34def701c1f45f93e7e9219b1ebb281565b610182600181565b61028061027b36600461114b565b610538565b6040519015158152602001610193565b6101c361029e366004610f7e565b60006020819052908152604090205481565b6101826202000081565b6101c360025481565b6102296102d13660046110a0565b610553565b6101c3600160ff1b81565b6102296102ef366004611017565b6105fd565b61031b7f000000000000000000000000ce69a87c02baa8c5f17ed7eb8b1c2657afc2e1af81565b6040516001600160a01b039091168152602001610193565b6102806103413660046110a0565b610905565b610229610354366004610f99565b61092a565b61022961036736600461114b565b610c1a565b6101c37f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b6102806103a13660046110a0565b6001600160a01b03919091166000908152600360209081526040808320938352929052205460ff1690565b6101c36103da366004611118565b610c27565b6102806103ed36600461114b565b610c52565b6101c37faf4e98e5c9896ed6453d82e308a87caa8a02787c2c671d5a8cd308f9a99ed41f81565b61042562020000610c52565b61044a5760405162461bcd60e51b81526004016104419061118f565b60405180910390fd5b600254604080519182526020820183905233917f6d74a65a0a51fed60628f3559d4289c2aade63a663302b58bebe3a281fbaed67910160405180910390a2600255565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b03871691810191909152606081018590526000906104f1906080015b604051602081830303815290604052858585610c5e565b9050856001600160a01b0316816001600160a01b0316146105245760405162461bcd60e51b815260040161044190611164565b61053086866001610ce0565b505050505050565b30600090815260208190526040812054821682145b92915050565b610560600160ff1b610c52565b61057c5760405162461bcd60e51b81526004016104419061118f565b6001600160a01b0382166000908152602081905260409020546105a190339083610c27565b6001600160a01b03831660008181526020818152604091829020849055815185815290810193909352909133917f5a10526456f5116c0b7b80582c217d666243fd51b6a2d92c8011e601c2462e5f910160405180910390a35050565b6106076001610538565b61064a5760405162461bcd60e51b81526020600482015260146024820152731c995919595b5cc8185c9948191a5cd8589b195960621b6044820152606401610441565b6002548760015461065b91906111b6565b11156106a95760405162461bcd60e51b815260206004820181905260248201527f6d696e74696e67204c696d697420686173206265656e207265616368656421216044820152606401610441565b604080517f67c2bc25c87d2f7202a6c00ccb845fe254f34def701c1f45f93e7e9219b1ebb260208201526001600160a01b03808d1692820192909252908a1660608201526080810189905260a0810188905260c0810187905260e08101869052610100810185905260009061072190610120016104da565b90508a6001600160a01b0316816001600160a01b0316146107545760405162461bcd60e51b815260040161044190611164565b6107618162010000610905565b61079e5760405162461bcd60e51b815260206004820152600e60248201526d696e76616c69642061636365737360901b6044820152606401610441565b8642116107e75760405162461bcd60e51b81526020600482015260176024820152761cda59db985d1d5c99481b9bdd081e595d081d985b1a59604a1b6044820152606401610441565b85421061082a5760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b6044820152606401610441565b6001600160a01b038a1633146108525760405162461bcd60e51b81526004016104419061118f565b8760015461086091906111b6565b60015561086f8b866000610ce0565b604051631740d57560e11b81526001600160a01b038b81166004830152602482018b9052604482018a90527f000000000000000000000000ce69a87c02baa8c5f17ed7eb8b1c2657afc2e1af1690632e81aaea90606401600060405180830381600087803b1580156108e057600080fd5b505af11580156108f4573d6000803e3d6000fd5b505050505050505050505050505050565b6001600160a01b038216600090815260208190526040812054821682145b9392505050565b6109346001610538565b6109775760405162461bcd60e51b81526020600482015260146024820152731c995919595b5cc8185c9948191a5cd8589b195960621b6044820152606401610441565b600254600154106109ca5760405162461bcd60e51b815260206004820181905260248201527f6d696e74696e67204c696d697420686173206265656e207265616368656421216044820152606401610441565b604080517faf4e98e5c9896ed6453d82e308a87caa8a02787c2c671d5a8cd308f9a99ed41f60208201526001600160a01b03808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e08101859052600090610a3a90610100016104da565b9050896001600160a01b0316816001600160a01b031614610a6d5760405162461bcd60e51b815260040161044190611164565b610a7a8162010000610905565b610ab75760405162461bcd60e51b815260206004820152600e60248201526d696e76616c69642061636365737360901b6044820152606401610441565b864211610b005760405162461bcd60e51b81526020600482015260176024820152761cda59db985d1d5c99481b9bdd081e595d081d985b1a59604a1b6044820152606401610441565b854210610b435760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b6044820152606401610441565b6001600160a01b0389163314610b6b5760405162461bcd60e51b81526004016104419061118f565b60018054906000610b7b836111ce565b9190505550610b8c8a866000610ce0565b6040516340c10f1960e01b81526001600160a01b038a81166004830152602482018a90527f000000000000000000000000ce69a87c02baa8c5f17ed7eb8b1c2657afc2e1af16906340c10f1990604401600060405180830381600087803b158015610bf657600080fd5b505af1158015610c0a573d6000803e3d6000fd5b5050505050505050505050505050565b610c243082610553565b50565b6001600160a01b03929092166000908152602081905260409020546000198084188216189216171690565b600061054d3383610905565b835160208086019190912060405161190160f01b928101929092527fad86e9b1a125f22d1703e10e3aee42b417379544fd864ec5ac93be1e129a9f1d60228301526042820181905260009182906062016040516020818303038152906040528051906020012090506000610cd482888888610dee565b98975050505050505050565b6001600160a01b038316600090815260036020908152604080832085845290915290205460ff1615610d445760405162461bcd60e51b815260206004820152600d60248201526c696e76616c6964206e6f6e636560981b6044820152606401610441565b6001600160a01b03831660009081526003602090815260408083208584529091529020805460ff191660011790558015610db35760405182906001600160a01b038516907f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8190600090a3505050565b60405182906001600160a01b038516907f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a590600090a3505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115610e605760405162461bcd60e51b815260206004820152601b60248201527f696e76616c6964207369676e6174757265202773272076616c756500000000006044820152606401610441565b8360ff16601b1480610e7557508360ff16601c145b610ec15760405162461bcd60e51b815260206004820152601b60248201527f696e76616c6964207369676e6174757265202776272076616c756500000000006044820152606401610441565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015610f15573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610f485760405162461bcd60e51b815260040161044190611164565b95945050505050565b80356001600160a01b0381168114610f6857600080fd5b919050565b803560ff81168114610f6857600080fd5b600060208284031215610f9057600080fd5b61092382610f51565b60008060008060008060008060006101208a8c031215610fb857600080fd5b610fc18a610f51565b9850610fcf60208b01610f51565b975060408a0135965060608a0135955060808a0135945060a08a01359350610ff960c08b01610f6d565b925060e08a013591506101008a013590509295985092959850929598565b6000806000806000806000806000806101408b8d03121561103757600080fd5b6110408b610f51565b995061104e60208c01610f51565b985060408b0135975060608b0135965060808b0135955060a08b0135945060c08b0135935061107f60e08c01610f6d565b92506101008b013591506101208b013590509295989b9194979a5092959850565b600080604083850312156110b357600080fd5b6110bc83610f51565b946020939093013593505050565b600080600080600060a086880312156110e257600080fd5b6110eb86610f51565b94506020860135935061110060408701610f6d565b94979396509394606081013594506080013592915050565b60008060006060848603121561112d57600080fd5b61113684610f51565b95602085013595506040909401359392505050565b60006020828403121561115d57600080fd5b5035919050565b602080825260119082015270696e76616c6964207369676e617475726560781b604082015260600190565b6020808252600d908201526c1858d8d95cdcc819195b9a5959609a1b604082015260600190565b600082198211156111c9576111c96111e9565b500190565b60006000198214156111e2576111e26111e9565b5060010190565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220a467b60ef6ab1fc854a58cc2d7612a65317cce8d623b62442969df680fe11e3e64736f6c63430008070033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ce69a87c02baa8c5f17ed7eb8b1c2657afc2e1af
-----Decoded View---------------
Arg [0] : _target (address): 0xcE69a87C02bAA8C5F17Ed7eB8B1C2657aFC2E1aF
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ce69a87c02baa8c5f17ed7eb8b1c2657afc2e1af
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.999796 | 6,567.0597 | $6,565.72 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.