Contract 0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b 9

 
 
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0xe67fc47d23421012943e85ccc87fa08a8f69c79be37ddea7baf4d7fa9086c51cMint446343022023-07-03 13:03:3986 days 1 hr ago0xf456012af1e3172a70bc6157223ef1b866298c03 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.015356565628 191.44734181
0x5778008681f1173cd1c497228b1aeda8f33ec85576ab9bb09da82e1510c45ff5Mint444845942023-06-29 17:16:3789 days 20 hrs ago0x535380097eef1bff47551ee5121bdcdaaf0ba6cb IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.022547844058 171.580011555
0xb9c93cb1e4b0262f6e8c8b09f2dfb8b95a914cfe8cb5d4c450a57f190b7a9883Mint444232582023-06-28 3:48:3291 days 10 hrs ago0x7e060ea6f3e05f9b2f421aa73a5ce3f5d7afe591 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.012487447795 155.678603166
0x9816d117fb4a8f9c061968f45e4680e7ac7bca1ff9ae54a2280232cbc003bb7cMint443932082023-06-27 9:08:2392 days 5 hrs ago0x18e77064f0d18982b5064aaaf9fda15f15507376 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.016283964541 203.009045183
0x0da20accdd33c9b8494b1cc07d69fec8d640439df402267fd8dc42014bfb3c51Mint443930062023-06-27 9:00:1492 days 5 hrs ago0x55dbbed653c03898561e75c45d9de460c7c0f860 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.016478611584 205.435672326
0xc84c16eb6accf11abdeff09743120d417efb87cd4213d0e5e33faeb33fb78d94Mint442928452023-06-24 18:53:3094 days 19 hrs ago0x183fd4c5783850ec1b84e138cb26bbca8638d55f IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.004913830557 149.465584553
0xe6c907a6793407c1b9805327bad2c9725230cc0527ff9ca0e69d608fdd4faa4aMint440582642023-06-18 16:38:55100 days 21 hrs ago0x18e77064f0d18982b5064aaaf9fda15f15507376 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.014941982135 186.30668116
0xe21bc91d95b0bebecc1373b5982ab3106d7b14de3a81bb65125a5ba29db4d233Mint439379172023-06-15 11:58:50104 days 2 hrs ago0x0d0a59e0ed1fb7b26c4a16007899bca83a6a1616 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.040455555903 353.74689282
0xf0087287181a423190135940d6b0d1f5907f97669ec7bf5d41b26a38d98f7b7cMint439349512023-06-15 9:59:55104 days 4 hrs ago0x183fd4c5783850ec1b84e138cb26bbca8638d55f IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.021432686502 187.428938117
0x28e30660c20960830181ad1c60a24633c540c5cada8995af4b686952750b6a25Mint439333932023-06-15 8:59:55104 days 5 hrs ago0x56dd34a7ac65557028c5870d9a82817b46e66acc IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.053424540032 406.539231522
0xa4679614694546a36690c1cb06edd086021cd306459d80f18a306a33c83cb7f0Mint439300802023-06-15 6:50:29104 days 7 hrs ago0x68b202088f60a80e4a622c574d5713c3c6df12d2 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.018959136991 165.780339721
0x932dcf9972938e540ef7f491509ef6cb2614bddbf5cfff838eb2787e3442f79dMint439275782023-06-15 5:16:09104 days 8 hrs ago0xd65c1d7e9a5bbea4466efab6e9a53ea3422d0d19 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.013453034544 167.716386923
0xd83461329b2db5e9d4f7d4e8605b055c39d7557b1fbecf383d04965e859fdef3Mint439274662023-06-15 5:11:58104 days 8 hrs ago0x57d2e4902e3b6e17e8e58c75580a0e5cd18876d1 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.017534313452 153.321559004
0x075c1b9b8eb0fa8532d2052c4733faf7a495437d9e7cd50f281c2c3b087a7d75Mint439262562023-06-15 4:26:45104 days 9 hrs ago0x22581a3301753e1d1acf97a816de1280b3d21861 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.020766435801 181.58351741
0x932c0bfa4a925defb0050721d980bf600a204b6da8df525e29abb8c7cf14a60eMint439242492023-06-15 3:10:40104 days 10 hrs ago0xf07a12d20381bf2737eac4d668ed23e2c70ff297 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.036840627508 322.137645113
0x59246abdeb4ece405e5bd12483e42ae563889e065b991badd2770f934e3cac38Mint439240892023-06-15 3:04:27104 days 11 hrs ago0xc6124a69b8a0bd11f3870f999bc0b435ab42d8dc IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.027529004849 240.716008231
0x6a093cb3e56e7a820b2080d75b58dd003e94c268eb8242ba1906792c61aa90e5Mint439235422023-06-15 2:44:22104 days 11 hrs ago0x3e3a00e2c6c43616042ee313e1ea39b1ebe9dd01 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.019264918371 168.454118653
0xf7b75c346803faae280beb861df40e77032fec0f4fbfaaad5535c47c7c40105aMint439225842023-06-15 2:06:45104 days 12 hrs ago0x535380097eef1bff47551ee5121bdcdaaf0ba6cb IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.037985178654 289.051910044
0xc7398bcd6d24821ff664bd08372ec24f0b605b522f28600596200ca978d2204aMint439219132023-06-15 1:40:19104 days 12 hrs ago0x8cddbb0ec5cd251e390ba3e1ffe40ba347c13435 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.023009399358 201.196185465
0x371e9113ee881c33002cf8957b2aa89a2bee8dfb877e43ddb625ab9b043fe2d5Mint439216912023-06-15 1:31:52104 days 12 hrs ago0xf456012af1e3172a70bc6157223ef1b866298c03 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.025979029944 227.162893107
0x9e78e7539bec8a88876828fdb285d01c00425a6553573975abc346031a47b2a3Mint439214162023-06-15 1:20:50104 days 12 hrs ago0x7ec268c3750f41a7507feb98903fd216869b4f2b IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.023208557423 202.93764088
0x3ab792eaaa70067935f84fadc346791fa56d734b0c7fc426a433d821bd8ae5b1Mint439206712023-06-15 0:51:24104 days 13 hrs ago0x075b0fd46a1c12b5ee898e8f851eadbb32c069ac IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.013245669029 165.131201048
0x248afe19347ce6e3d9c7a65c52df47af3a30fe8505a1fe2253c0e0421222bbfeMint439201342023-06-15 0:29:43104 days 13 hrs ago0x2143c3cc6cc56ffae31e9223cd79d23ac781e259 IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.020257762975 177.135638064
0xa627f8c0c080b12ed3fe9c763d2078afcf15a7107d8970c9ce3f59667f8a15e3Mint439164112023-06-14 21:58:17104 days 16 hrs ago0x4b58fcf9690cffd8bdabc0d8d5daa5957d815baf IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.041918738727 366.541090449
0x8bc7eb2fca810d128c8e10bfca7150ae0e4b9f2705316ff40e6c00fe947e6fa8Mint439160812023-06-14 21:43:18104 days 16 hrs ago0x70a63f03632739933dcc231889a8d32c0bb7b76b IN  0xac70a3a292b7c9539fd1c7a8d1ca2ae43e24b80b0 MATIC0.028591114918 356.439915213
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NFTFactory

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 4 : ERC721SpecExt.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/**
 * @title Mintable ERC721
 *
 * @notice Defines mint capabilities for Alethea ERC721 tokens.
 *      This interface should be treated as a definition of what mintable means for ERC721
 */
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
 */
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
 */
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);
}

File 2 of 4 : ECDSA.sol
// 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));
	}
}

File 3 of 4 : NFTFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "../interfaces/ERC721SpecExt.sol";
import "../utils/AccessControl.sol";
import "../lib/ECDSA.sol";

/**
 * @title Alethea NFT Factory
 *
 * @notice NFT Factory is a helper smart contract responsible for minting arbitrary NFTs
 *
 * @notice It supports two mechanisms:
 *      - minting delegation: authorized address executes mint function on the helper,
 *        and helper executes minting function on the target ERC721 contract as an internal transaction
 *      - meta transaction minting or minting with an authorization: authorized address signs
 *        the minting authorization message and any address executes mint function on the helper
 *
 * @notice Second mechanism allows to shift the gas costs for the transaction to any address
 *      (usually this is the NFT beneficiary - an address which receives an NFT)
 *
 * @dev The signature is constructed via EIP-712 similar to EIP-2612, or EIP-3009
 *
 * @dev Target ERC721 contract(s) must allow helper to mint the tokens, this should be configured
 *      as part of the deployment or setup processes
 */
contract NFTFactory is AccessControl {
	/**
	 * @dev A record of used nonces for EIP-712 transactions
	 *
	 * @dev A record of used nonces for signing/validating signatures
	 *      in `mintWithAuthorization` for every mint
	 *
	 * @dev Maps authorizer address => nonce => true/false (used unused)
	 */
	mapping(address => mapping(bytes32 => bool)) private usedNonces;

	/**
	 * @notice EIP-712 contract's domain separator,
	 *      see https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator
	 */
	bytes32 public immutable DOMAIN_SEPARATOR;

	/**
	 * @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 "NFTFactoryV2"
	 */
	// keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)")
	bytes32 public constant DOMAIN_TYPEHASH = 0x8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866;

	/**
	 * @notice EIP-712 MintWithAuthorization struct typeHash,
	 *      see https://eips.ethereum.org/EIPS/eip-712#rationale-for-typehash
	 */
	// keccak256("MintWithAuthorization(address contract,address to,uint256 tokenId,uint256 validAfter,uint256 validBefore,bytes32 nonce)")
	bytes32 public constant MINT_WITH_AUTHORIZATION_TYPEHASH = 0x495835d970a03ff092657fca9abde67d34a0bb73a0bba258a5fa90c4ce4340f6;

	/**
	 * @notice EIP-712 CancelAuthorization struct typeHash,
	 *      see https://eips.ethereum.org/EIPS/eip-712#rationale-for-typehash
	 */
	// keccak256("CancelAuthorization(address authorizer,bytes32 nonce)")
	bytes32 public constant CANCEL_AUTHORIZATION_TYPEHASH = 0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;

	/**
	 * @notice Enables meta transaction minting (minting with an authorization
	 *      via an EIP712 signature)
	 * @dev Feature FEATURE_MINTING_WITH_AUTH must be enabled in order for
	 *      `mintWithAuthorization()` function to succeed
	 */
	uint32 public constant FEATURE_MINTING_WITH_AUTH = 0x0000_0001;

	/**
	 * @notice Factory minter is responsible for creating (minting)
	 *      tokens to an arbitrary address
	 * @dev Role ROLE_FACTORY_MINTER allows minting tokens
	 *      (executing `mint` function)
	 */
	uint32 public constant ROLE_FACTORY_MINTER = 0x0001_0000;

	/**
	 * @dev Fired in mint() and mintWithAuthorization() after an NFT is minted
	 *
	 * @param erc721Address ERC721 contract address which was minted
	 * @param to an address NFT was minted to
	 * @param tokenId NFT ID which was minted
	 */
	event Minted(address indexed erc721Address, address indexed to, uint256 indexed tokenId);

	/**
	 * @dev Fired whenever the nonce gets used (ex.: `transferWithAuthorization`, `receiveWithAuthorization`)
	 *
	 * @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);

	/**
	 * Deploys the helper contract and initializes DOMAIN_SEPARATOR using the created smart contract address
	 */
	constructor() {
		// build the EIP-712 contract domain separator, see https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator
		// note: we specify contract version in its name
		DOMAIN_SEPARATOR = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes("NFTFactoryV1")), block.chainid, address(this)));
	}

	/**
	 * @notice Restricted access function to mint an NFT
	 *
	 * @dev Doesn't allow minting the token with ID zero
	 * @dev Requires an executor to have ROLE_MINTER permission
	 * @dev Requires target ERC721 contract to be mintable (`MintableERC721`)
	 * @dev Requires target ERC721 contract instance to allow minting via helper
	 *
	 * @param _mintableErc721 target ERC721 contract instance to mint token on,
	 *      compatible with `MintableERC721`
	 * @param _to an address to mint token to
	 * @param _tokenId target ERC721 token ID to mint
	 */
	function mint(address _mintableErc721, address _to, uint256 _tokenId) public {
		// delegate to _mint()
		__mint(msg.sender, _mintableErc721, _to, _tokenId);
	}

	/**
	 * @dev Auxiliary internally used function to mint an NFT
	 *
	 * @dev Unsafe: doesn't verify real tx executor (msg.sender) permissions, but the permissions of
	 *      the address specified as an executor, must be kept private at all times
	 *
	 * @dev Doesn't allow minting the token with ID zero
	 * @dev Requires an executor to have ROLE_MINTER permission
	 * @dev Requires target ERC721 contract to be mintable (`MintableERC721`)
	 * @dev Requires target ERC721 contract instance to allow minting via helper
	 *
	 * @param _executor an address on which behalf the operation is executed,
	 *      this is usually `msg.sender` but this can be different address for
	 *      the EIP-712 like transactions (mint with authorization)
	 * @param _mintableErc721 target ERC721 contract instance to mint token on,
	 *      compatible with `MintableERC721`
	 * @param _to an address to mint token to
	 * @param _tokenId target ERC721 token ID to mint
	 */
	function __mint(address _executor, address _mintableErc721, address _to, uint256 _tokenId) private {
		// verify the access permission
		require(isOperatorInRole(_executor, ROLE_FACTORY_MINTER), "access denied");

		// verify the inputs
		require(_mintableErc721 != address(0), "ERC721 instance addr is not set");
		require(_to != address(0), "NFT receiver addr is not set");
		require(_tokenId != 0, "token ID is not set");

		// delegate to the target ERC721 contract
		MintableERC721(_mintableErc721).safeMint(_to, _tokenId);

		// emit an event
		emit Minted(_mintableErc721, _to, _tokenId);
	}

	/**
	 * @notice Executes a mint function with a signed authorization
	 *
	 * @param _mintableErc721 target ERC721 contract instance to mint token on,
	 *      compatible with `MintableERC721`
	 * @param _to an address to mint token to
	 * @param _tokenId target ERC721 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 _mintableErc721,
		address _to,
		uint256 _tokenId,
		uint256 _validAfter,
		uint256 _validBefore,
		bytes32 _nonce,
		uint8 v,
		bytes32 r,
		bytes32 s
	) public {
		// ensure EIP-712 minting with authorization is enabled
		require(isFeatureEnabled(FEATURE_MINTING_WITH_AUTH), "minting with auth is disabled");

		// derive signer of the EIP712 MintWithAuthorization message
		address signer = __deriveSigner(
			abi.encode(MINT_WITH_AUTHORIZATION_TYPEHASH, _mintableErc721, _to, _tokenId, _validAfter, _validBefore, _nonce),
			v,
			r,
			s
		);

		// perform message integrity and security validations
		require(block.timestamp > _validAfter, "signature not yet valid");
		require(block.timestamp < _validBefore, "signature expired");

		// use the nonce supplied (verify, mark as used, emit event)
		__useNonce(signer, _nonce, false);

		// delegate call to `_mint` - execute the logic required
		__mint(signer, _mintableErc721, _to, _tokenId);
	}

	/**
	 * @notice Returns the state of an authorization, more specifically
	 *      if the specified nonce was already used by the address specified
	 *
	 * @dev Nonces are expected to be client-side randomly generated 32-byte data
	 *      unique to the authorizer's address
	 *
	 * @param _authorizer Authorizer's address
	 * @param _nonce Nonce of the authorization
	 * @return true if the nonce is used
	 */
	function authorizationState(
		address _authorizer,
		bytes32 _nonce
	) external view returns (bool) {
		// simply return the value from the mapping
		return usedNonces[_authorizer][_nonce];
	}

	/**
	 * @notice Cancels the authorization (using EIP-712 signature)
	 *
	 * @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);
	}

	/**
	 * @notice Cancels the authorization
	 *
	 * @param _nonce unique random nonce to cancel (mark as used)
	 */
	function cancelAuthorization(bytes32 _nonce) public {
		// cancel the nonce supplied (verify, mark as used, emit event)
		__useNonce(msg.sender, _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);
		}
	}
}

File 4 of 4 : AccessControl.sol
// 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.
 */
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;
	}
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"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":"erc721Address","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Minted","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"},{"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_MINTING_WITH_AUTH","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"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_FACTORY_MINTER","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":"bytes32","name":"_nonce","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":[{"internalType":"address","name":"_mintableErc721","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mintableErc721","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","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":[{"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":"address","name":"","type":"address"}],"name":"userRoles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60a060405234801561001057600080fd5b503360009081526020818152604091829020600019905581518083018352600c81526b4e4654466163746f7279563160a01b9082015281517f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866918101919091527f06df569e81a0cee0d4bf93bcbb32cd170bf15a994570fea8a3c8e631cc4b61719181019190915246606082015230608082015260a00160408051601f198184030181529190528051602090910120608052608051610e056100e460003960008181610185015261072a0152610e056000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c8063c688d693116100ad578063d916948711610071578063d9169487146102a3578063e94a0102146102ca578063f822d5aa14610303578063fcc2c07814610316578063ff2642cf1461032957600080fd5b8063c688d6931461024d578063c6c3bbe614610260578063ce8b3a5814610273578063d1333c981461027d578063d5bb7f671461029057600080fd5b806374d5e100116100f457806374d5e100146101df578063845ab94f146101ff578063ae5b102e14610212578063ae682e2e14610225578063c4d029c61461023057600080fd5b806320606b70146101315780632b5214161461016b5780633644e515146101805780635a049a70146101a7578063725f3626146101bc575b600080fd5b6101587f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b6040519081526020015b60405180910390f35b30600090815260208190526040902054610158565b6101587f000000000000000000000000000000000000000000000000000000000000000081565b6101ba6101b5366004610c36565b610350565b005b6101cf6101ca366004610c84565b610424565b6040519015158152602001610162565b6101586101ed366004610c9d565b60006020819052908152604090205481565b6101ba61020d366004610c84565b61043f565b6101ba610220366004610cb8565b61044e565b610158600160ff1b81565b610238600181565b60405163ffffffff9091168152602001610162565b6101cf61025b366004610cb8565b610518565b6101ba61026e366004610ce2565b61053d565b6102386201000081565b6101ba61028b366004610d1e565b61054e565b6101ba61029e366004610c84565b6106cc565b6101587f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b6101cf6102d8366004610cb8565b6001600160a01b03919091166000908152600160209081526040808320938352929052205460ff1690565b610158610311366004610d9c565b6106d6565b6101cf610324366004610c84565b610701565b6101587f495835d970a03ff092657fca9abde67d34a0bb73a0bba258a5fa90c4ce4340f681565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960208201526001600160a01b03871691810191909152606081018590526000906103b4906080015b60405160208183030381529060405285858561070d565b9050856001600160a01b0316816001600160a01b0316146104105760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064015b60405180910390fd5b61041c8686600161078f565b505050505050565b30600090815260208190526040812054821682145b92915050565b61044b3382600161078f565b50565b61045b600160ff1b610701565b6104975760405162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b6044820152606401610407565b6001600160a01b0382166000908152602081905260409020546104bc903390836106d6565b6001600160a01b03831660008181526020818152604091829020849055815185815290810193909352909133917f5a10526456f5116c0b7b80582c217d666243fd51b6a2d92c8011e601c2462e5f910160405180910390a35050565b6001600160a01b038216600090815260208190526040812054821682145b9392505050565b6105493384848461089e565b505050565b6105586001610424565b6105a45760405162461bcd60e51b815260206004820152601d60248201527f6d696e74696e67207769746820617574682069732064697361626c65640000006044820152606401610407565b604080517f495835d970a03ff092657fca9abde67d34a0bb73a0bba258a5fa90c4ce4340f660208201526001600160a01b03808c169282019290925290891660608201526080810188905260a0810187905260c0810186905260e08101859052600090610614906101000161039d565b90508642116106655760405162461bcd60e51b815260206004820152601760248201527f7369676e6174757265206e6f74207965742076616c69640000000000000000006044820152606401610407565b8542106106a85760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b6044820152606401610407565b6106b48186600061078f565b6106c0818b8b8b61089e565b50505050505050505050565b61044b308261044e565b6001600160a01b03929092166000908152602081905260409020546000198084188216189216171690565b60006104393383610518565b835160208086019190912060405161190160f01b928101929092527f00000000000000000000000000000000000000000000000000000000000000006022830152604282018190526000918290606201604051602081830303815290604052805190602001209050600061078382888888610a82565b98975050505050505050565b6001600160a01b038316600090815260016020908152604080832085845290915290205460ff16156107f35760405162461bcd60e51b815260206004820152600d60248201526c696e76616c6964206e6f6e636560981b6044820152606401610407565b6001600160a01b0383166000908152600160208181526040808420868552909152909120805460ff1916909117905580156108635760405182906001600160a01b038516907f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8190600090a3505050565b60405182906001600160a01b038516907f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a590600090a3505050565b6108ab8462010000610518565b6108e75760405162461bcd60e51b815260206004820152600d60248201526c1858d8d95cdcc819195b9a5959609a1b6044820152606401610407565b6001600160a01b03831661093d5760405162461bcd60e51b815260206004820152601f60248201527f45524337323120696e7374616e63652061646472206973206e6f7420736574006044820152606401610407565b6001600160a01b0382166109935760405162461bcd60e51b815260206004820152601c60248201527f4e46542072656365697665722061646472206973206e6f7420736574000000006044820152606401610407565b806000036109d95760405162461bcd60e51b81526020600482015260136024820152721d1bdad95b881251081a5cc81b9bdd081cd95d606a1b6044820152606401610407565b604051632851206560e21b81526001600160a01b0383811660048301526024820183905284169063a144819490604401600060405180830381600087803b158015610a2357600080fd5b505af1158015610a37573d6000803e3d6000fd5b5050505080826001600160a01b0316846001600160a01b03167f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f060405160405180910390a450505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115610af45760405162461bcd60e51b815260206004820152601b60248201527f696e76616c6964207369676e6174757265202773272076616c756500000000006044820152606401610407565b8360ff16601b1480610b0957508360ff16601c145b610b555760405162461bcd60e51b815260206004820152601b60248201527f696e76616c6964207369676e6174757265202776272076616c756500000000006044820152606401610407565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015610ba9573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610c005760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b6044820152606401610407565b95945050505050565b80356001600160a01b0381168114610c2057600080fd5b919050565b803560ff81168114610c2057600080fd5b600080600080600060a08688031215610c4e57600080fd5b610c5786610c09565b945060208601359350610c6c60408701610c25565b94979396509394606081013594506080013592915050565b600060208284031215610c9657600080fd5b5035919050565b600060208284031215610caf57600080fd5b61053682610c09565b60008060408385031215610ccb57600080fd5b610cd483610c09565b946020939093013593505050565b600080600060608486031215610cf757600080fd5b610d0084610c09565b9250610d0e60208501610c09565b9150604084013590509250925092565b60008060008060008060008060006101208a8c031215610d3d57600080fd5b610d468a610c09565b9850610d5460208b01610c09565b975060408a0135965060608a0135955060808a0135945060a08a01359350610d7e60c08b01610c25565b925060e08a013591506101008a013590509295985092959850929598565b600080600060608486031215610db157600080fd5b610dba84610c09565b9560208501359550604090940135939250505056fea26469706673582212205da09b76b316b383871649cf1f936304792d07632f756f85f38663aee6f3e6aa64736f6c634300080f0033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.