Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 38,935 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Purchase | 16932867 | 455 days ago | IN | 0 ETH | 0.00130429 | ||||
Purchase | 16932867 | 455 days ago | IN | 0 ETH | 0.00130429 | ||||
Purchase To | 16532817 | 511 days ago | IN | 0 ETH | 0.0010625 | ||||
Transfer | 16444225 | 523 days ago | IN | 0.2557 ETH | 0.00033644 | ||||
Purchase To | 16378058 | 533 days ago | IN | 0 ETH | 0.00463502 | ||||
Purchase To | 16378056 | 533 days ago | IN | 0 ETH | 0.0031903 | ||||
Purchase To | 16378056 | 533 days ago | IN | 0 ETH | 0.00340294 | ||||
Purchase To | 16378053 | 533 days ago | IN | 0 ETH | 0.00443426 | ||||
Purchase To | 16378053 | 533 days ago | IN | 0 ETH | 0.00357767 | ||||
Purchase To | 16378053 | 533 days ago | IN | 0 ETH | 0.00361948 | ||||
Purchase To | 16378052 | 533 days ago | IN | 0 ETH | 0.00476196 | ||||
Purchase To | 16378049 | 533 days ago | IN | 0 ETH | 0.00496889 | ||||
Purchase To | 16378047 | 533 days ago | IN | 0 ETH | 0.00532149 | ||||
Purchase To | 16378046 | 533 days ago | IN | 0 ETH | 0.00401338 | ||||
Purchase To | 16378043 | 533 days ago | IN | 0 ETH | 0.00378336 | ||||
Purchase To | 16378042 | 533 days ago | IN | 0 ETH | 0.0049649 | ||||
Purchase To | 16378041 | 533 days ago | IN | 0 ETH | 0.00469117 | ||||
Purchase To | 16378040 | 533 days ago | IN | 0 ETH | 0.00354453 | ||||
Purchase To | 16378039 | 533 days ago | IN | 0 ETH | 0.00472129 | ||||
Purchase To | 16378035 | 533 days ago | IN | 0 ETH | 0.00446738 | ||||
Purchase To | 16378033 | 533 days ago | IN | 0 ETH | 0.00486438 | ||||
Purchase To | 16378026 | 533 days ago | IN | 0 ETH | 0.00350656 | ||||
Purchase To | 16378026 | 533 days ago | IN | 0 ETH | 0.00349509 | ||||
Purchase To | 16378024 | 533 days ago | IN | 0 ETH | 0.00469048 | ||||
Purchase To | 16378024 | 533 days ago | IN | 0 ETH | 0.00468484 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
MinterMerkleV2
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 25 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: LGPL-3.0-only // Created By: Art Blocks Inc. import "../../../interfaces/0.8.x/IGenArt721CoreContractV3.sol"; import "../../../interfaces/0.8.x/IMinterFilterV0.sol"; import "../../../interfaces/0.8.x/IFilteredMinterMerkleV0.sol"; import "../../../interfaces/0.8.x/IDelegationRegistry.sol"; import "@openzeppelin-4.7/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin-4.7/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin-4.7/contracts/security/ReentrancyGuard.sol"; pragma solidity 0.8.17; /** * @title Filtered Minter contract that allows tokens to be minted with ETH * for addresses in a Merkle allowlist. * This is designed to be used with IGenArt721CoreContractV3 contracts. * @author Art Blocks Inc. * @notice Privileged Roles and Ownership: * This contract is designed to be managed, with limited powers. * Privileged roles and abilities are controlled by the project's artist, which * can be modified by the core contract's Admin ACL contract. Both of these * roles hold extensive power and can modify minter details. * Care must be taken to ensure that the admin ACL contract and artist * addresses are secure behind a multi-sig or other access control mechanism. * ---------------------------------------------------------------------------- * The following functions are restricted to a project's artist: * - updateMerkleRoot * - updatePricePerTokenInWei * - setProjectInvocationsPerAddress * ---------------------------------------------------------------------------- * Additional admin and artist privileged roles may be described on other * contracts that this minter integrates with. * ---------------------------------------------------------------------------- * This contract allows vaults to configure token-level or wallet-level * delegation of minting privileges. This allows a vault on an allowlist to * delegate minting privileges to a wallet that is not on the allowlist, * enabling the vault to remain air-gapped while still allowing minting. The * delegation registry contract is responsible for managing these delegations, * and is available at the address returned by the public constant * `DELEGATION_REGISTRY_ADDRESS`. At the time of writing, the delegation * registry enables easy delegation configuring at https://delegate.cash/. * Art Blocks does not guarentee the security of the delegation registry, and * users should take care to ensure that the delegation registry is secure. * Token-level delegations are configured by the vault owner, and contract- * level delegations must be configured for the core token contract as returned * by the public immutable variable `genArt721CoreAddress`. */ contract MinterMerkleV2 is ReentrancyGuard, IFilteredMinterMerkleV0 { using MerkleProof for bytes32[]; /// Delegation registry address address public constant DELEGATION_REGISTRY_ADDRESS = 0x00000000000076A84feF008CDAbe6409d2FE638B; /// Delegation registry address IDelegationRegistry private immutable delegationRegistryContract; /// Core contract address this minter interacts with address public immutable genArt721CoreAddress; /// This contract handles cores with interface IV3 IGenArt721CoreContractV3 private immutable genArtCoreContract; /// Minter filter address this minter interacts with address public immutable minterFilterAddress; /// Minter filter this minter may interact with. IMinterFilterV0 private immutable minterFilter; /// minterType for this minter string public constant minterType = "MinterMerkleV2"; /// project minter configuration keys used by this minter bytes32 private constant CONFIG_MERKLE_ROOT = "merkleRoot"; bytes32 private constant CONFIG_USE_MAX_INVOCATIONS_PER_ADDRESS_OVERRIDE = "useMaxMintsPerAddrOverride"; // shortened to fit in 32 bytes bytes32 private constant CONFIG_MAX_INVOCATIONS_OVERRIDE = "maxMintsPerAddrOverride"; // shortened to match format of previous key uint256 constant ONE_MILLION = 1_000_000; uint256 public constant DEFAULT_MAX_INVOCATIONS_PER_ADDRESS = 1; struct ProjectConfig { bool maxHasBeenInvoked; bool priceIsConfigured; // initial value is false, so by default, projects limit allowlisted // addresses to a mint qty of `DEFAULT_MAX_INVOCATIONS_PER_ADDRESS` bool useMaxInvocationsPerAddressOverride; // a value of 0 means no limit // (only used if `useMaxInvocationsPerAddressOverride` is true) uint24 maxInvocationsPerAddressOverride; uint24 maxInvocations; uint256 pricePerTokenInWei; } mapping(uint256 => ProjectConfig) public projectConfig; /// projectId => merkle root mapping(uint256 => bytes32) public projectMerkleRoot; /// projectId => purchaser address => qty of mints purchased for project mapping(uint256 => mapping(address => uint256)) public projectUserMintInvocations; modifier onlyArtist(uint256 _projectId) { require( msg.sender == genArtCoreContract.projectIdToArtistAddress(_projectId), "Only Artist" ); _; } /** * @notice Initializes contract to be a Filtered Minter for * `_minterFilter`, integrated with Art Blocks core contract * at address `_genArt721Address`. * @param _genArt721Address Art Blocks core contract address for * which this contract will be a minter. * @param _minterFilter Minter filter for which this will be a * filtered minter. */ constructor(address _genArt721Address, address _minterFilter) ReentrancyGuard() { genArt721CoreAddress = _genArt721Address; genArtCoreContract = IGenArt721CoreContractV3(_genArt721Address); delegationRegistryContract = IDelegationRegistry( DELEGATION_REGISTRY_ADDRESS ); minterFilterAddress = _minterFilter; minterFilter = IMinterFilterV0(_minterFilter); require( minterFilter.genArt721CoreAddress() == _genArt721Address, "Illegal contract pairing" ); // broadcast default max invocations per address for this minter emit DefaultMaxInvocationsPerAddress( DEFAULT_MAX_INVOCATIONS_PER_ADDRESS ); } /** * @notice Update the Merkle root for project `_projectId`. * @param _projectId Project ID to be updated. * @param _root root of Merkle tree defining addresses allowed to mint * on project `_projectId`. */ function updateMerkleRoot(uint256 _projectId, bytes32 _root) external onlyArtist(_projectId) { require(_root != bytes32(0), "Root must be provided"); projectMerkleRoot[_projectId] = _root; emit ConfigValueSet(_projectId, CONFIG_MERKLE_ROOT, _root); } /** * @notice Returns hashed address (to be used as merkle tree leaf). * Included as a public function to enable users to calculate their hashed * address in Solidity when generating proofs off-chain. * @param _address address to be hashed * @return bytes32 hashed address, via keccak256 (using encodePacked) */ function hashAddress(address _address) public pure returns (bytes32) { return keccak256(abi.encodePacked(_address)); } /** * @notice Verify if address is allowed to mint on project `_projectId`. * @param _projectId Project ID to be checked. * @param _proof Merkle proof for address. * @param _address Address to check. * @return inAllowlist true only if address is allowed to mint and valid * Merkle proof was provided */ function verifyAddress( uint256 _projectId, bytes32[] calldata _proof, address _address ) public view returns (bool) { return _proof.verifyCalldata( projectMerkleRoot[_projectId], hashAddress(_address) ); } /** * @notice Sets maximum allowed invocations per allowlisted address for * project `_project` to `limit`. If `limit` is set to 0, allowlisted * addresses will be able to mint as many times as desired, until the * project reaches its maximum invocations. * Default is a value of 1 if never configured by artist. * @param _projectId Project ID to toggle the mint limit. * @param _maxInvocationsPerAddress Maximum allowed invocations per * allowlisted address. * @dev default value stated above must be updated if the value of * CONFIG_USE_MAX_INVOCATIONS_PER_ADDRESS_OVERRIDE is changed. */ function setProjectInvocationsPerAddress( uint256 _projectId, uint24 _maxInvocationsPerAddress ) external onlyArtist(_projectId) { ProjectConfig storage _projectConfig = projectConfig[_projectId]; // use override value instead of the contract's default // @dev this never changes from true to false; default value is only // used if artist has never configured project invocations per address _projectConfig.useMaxInvocationsPerAddressOverride = true; // update the override value _projectConfig .maxInvocationsPerAddressOverride = _maxInvocationsPerAddress; // generic events emit ConfigValueSet( _projectId, CONFIG_USE_MAX_INVOCATIONS_PER_ADDRESS_OVERRIDE, true ); emit ConfigValueSet( _projectId, CONFIG_MAX_INVOCATIONS_OVERRIDE, uint256(_maxInvocationsPerAddress) ); } /** * @notice Syncs local maximum invocations of project `_projectId` based on * the value currently defined in the core contract. Only used for gas * optimization of mints after maxInvocations has been reached. * @param _projectId Project ID to set the maximum invocations for. * @dev this enables gas reduction after maxInvocations have been reached - * core contracts shall still enforce a maxInvocation check during mint. * @dev function is intentionally not gated to any specific access control; * it only syncs a local state variable to the core contract's state. */ function setProjectMaxInvocations(uint256 _projectId) external { uint256 maxInvocations; (, maxInvocations, , , , ) = genArtCoreContract.projectStateData( _projectId ); // update storage with results projectConfig[_projectId].maxInvocations = uint24(maxInvocations); } /** * @notice Warning: Disabling purchaseTo is not supported on this minter. * This method exists purely for interface-conformance purposes. */ function togglePurchaseToDisabled(uint256 _projectId) external view onlyArtist(_projectId) { revert("Action not supported"); } /** * @notice projectId => has project reached its maximum number of * invocations? Note that this returns a local cache of the core contract's * state, and may be out of sync with the core contract. This is * intentional, as it only enables gas optimization of mints after a * project's maximum invocations has been reached. A false negative will * only result in a gas cost increase, since the core contract will still * enforce a maxInvocation check during minting. A false positive is not * possible because the V3 core contract only allows maximum invocations * to be reduced, not increased. Based on this rationale, we intentionally * do not do input validation in this method as to whether or not the input * `_projectId` is an existing project ID. */ function projectMaxHasBeenInvoked(uint256 _projectId) external view returns (bool) { return projectConfig[_projectId].maxHasBeenInvoked; } /** * @notice projectId => project's maximum number of invocations. * Optionally synced with core contract value, for gas optimization. * Note that this returns a local cache of the core contract's * state, and may be out of sync with the core contract. This is * intentional, as it only enables gas optimization of mints after a * project's maximum invocations has been reached. * @dev A number greater than the core contract's project max invocations * will only result in a gas cost increase, since the core contract will * still enforce a maxInvocation check during minting. A number less than * the core contract's project max invocations is only possible when the * project's max invocations have not been synced on this minter, since the * V3 core contract only allows maximum invocations to be reduced, not * increased. When this happens, the minter will enable minting, allowing * the core contract to enforce the max invocations check. Based on this * rationale, we intentionally do not do input validation in this method as * to whether or not the input `_projectId` is an existing project ID. */ function projectMaxInvocations(uint256 _projectId) external view returns (uint256) { return uint256(projectConfig[_projectId].maxInvocations); } /** * @notice Updates this minter's price per token of project `_projectId` * to be '_pricePerTokenInWei`, in Wei. * This price supersedes any legacy core contract price per token value. * @dev Note that it is intentionally supported here that the configured * price may be explicitly set to `0`. */ function updatePricePerTokenInWei( uint256 _projectId, uint256 _pricePerTokenInWei ) external onlyArtist(_projectId) { projectConfig[_projectId].pricePerTokenInWei = _pricePerTokenInWei; projectConfig[_projectId].priceIsConfigured = true; emit PricePerTokenInWeiUpdated(_projectId, _pricePerTokenInWei); } /** * @notice Inactive function - requires Merkle proof to purchase. */ function purchase(uint256) external payable returns (uint256) { revert("Must provide Merkle proof"); } /** * @notice Inactive function - requires Merkle proof to purchase. */ function purchaseTo(address, uint256) public payable returns (uint256) { revert("Must provide Merkle proof"); } /** * @notice Purchases a token from project `_projectId`. * @param _projectId Project ID to mint a token on. * @param _proof Merkle proof. * @return tokenId Token ID of minted token */ function purchase(uint256 _projectId, bytes32[] calldata _proof) external payable returns (uint256 tokenId) { tokenId = purchaseTo_kem(msg.sender, _projectId, _proof, address(0)); return tokenId; } /** * @notice gas-optimized version of purchase(uint256,bytes32[]). */ function purchase_gD5(uint256 _projectId, bytes32[] calldata _proof) external payable returns (uint256 tokenId) { tokenId = purchaseTo_kem(msg.sender, _projectId, _proof, address(0)); return tokenId; } /** * @notice Purchases a token from project `_projectId` and sets * the token's owner to `_to`. * @param _to Address to be the new token's owner. * @param _projectId Project ID to mint a token on. * @param _proof Merkle proof. * @return tokenId Token ID of minted token */ function purchaseTo( address _to, uint256 _projectId, bytes32[] calldata _proof ) external payable returns (uint256 tokenId) { return purchaseTo_kem(_to, _projectId, _proof, address(0)); } /** * @notice Purchases a token from project `_projectId` and sets * the token's owner to `_to`, as a delegate, (the `msg.sender`) * on behalf of an explicitly defined vault. * @param _to Address to be the new token's owner. * @param _projectId Project ID to mint a token on. * @param _proof Merkle proof. * @param _vault Vault being purchased on behalf of. * @return tokenId Token ID of minted token */ function purchaseTo( address _to, uint256 _projectId, bytes32[] calldata _proof, address _vault ) external payable returns (uint256 tokenId) { return purchaseTo_kem(_to, _projectId, _proof, _vault); } /** * @notice gas-optimized version of * purchaseTo(address,uint256,bytes32[],address). * @param _to Address to be the new token's owner. * @param _projectId Project ID to mint a token on. * @param _proof Merkle proof. Must be a valid proof of either `msg.sender` * if `_vault` is `address(0)`, or `_vault` if `_vault` is not `address(0)`. * @param _vault Vault being purchased on behalf of. Acceptable to be * address(0) if no vault. */ function purchaseTo_kem( address _to, uint256 _projectId, bytes32[] calldata _proof, address _vault // acceptable to be `address(0)` if no vault ) public payable nonReentrant returns (uint256 tokenId) { // CHECKS ProjectConfig storage _projectConfig = projectConfig[_projectId]; // Note that `maxHasBeenInvoked` is only checked here to reduce gas // consumption after a project has been fully minted. // `_projectConfig.maxHasBeenInvoked` is locally cached to reduce // gas consumption, but if not in sync with the core contract's value, // the core contract also enforces its own max invocation check during // minting. require( !_projectConfig.maxHasBeenInvoked, "Maximum number of invocations reached" ); // load price of token into memory uint256 _pricePerTokenInWei = _projectConfig.pricePerTokenInWei; require( msg.value >= _pricePerTokenInWei, "Must send minimum value to mint!" ); // require artist to have configured price of token on this minter require(_projectConfig.priceIsConfigured, "Price not configured"); // no contract filter since Merkle tree controls allowed addresses // NOTE: delegate-vault handling **begins here**. // handle that the vault may be either the `msg.sender` in the case // that there is not a true vault, or may be `_vault` if one is // provided explicitly (and it is valid). address vault = msg.sender; if (_vault != address(0)) { // If a vault is provided, it must be valid, otherwise throw rather // than optimistically-minting with original `msg.sender`. // Note, we do not check `checkDelegateForAll` as well, as it is known // to be implicitly checked by calling `checkDelegateForContract`. bool isValidDelegee = delegationRegistryContract .checkDelegateForContract( msg.sender, // delegate _vault, // vault genArt721CoreAddress // contract ); require(isValidDelegee, "Invalid delegate-vault pairing"); vault = _vault; } // require valid Merkle proof require( verifyAddress(_projectId, _proof, vault), "Invalid Merkle proof" ); // limit mints per address by project uint256 _maxProjectInvocationsPerAddress = _projectConfig .useMaxInvocationsPerAddressOverride ? _projectConfig.maxInvocationsPerAddressOverride : DEFAULT_MAX_INVOCATIONS_PER_ADDRESS; // note that mint limits index off of the `vault` (when applicable) require( projectUserMintInvocations[_projectId][vault] < _maxProjectInvocationsPerAddress || _maxProjectInvocationsPerAddress == 0, "Maximum number of invocations per address reached" ); // EFFECTS // increment user's invocations for this project unchecked { // this will never overflow since user's invocations on a project // are limited by the project's max invocations projectUserMintInvocations[_projectId][vault]++; } // mint token tokenId = minterFilter.mint(_to, _projectId, vault); // NOTE: delegate-vault handling **ends here**. // okay if this underflows because if statement will always eval false. // this is only for gas optimization (core enforces maxInvocations). unchecked { if (tokenId % ONE_MILLION == _projectConfig.maxInvocations - 1) { _projectConfig.maxHasBeenInvoked = true; } } // INTERACTIONS _splitFundsETH(_projectId, _pricePerTokenInWei); return tokenId; } /** * @dev splits ETH funds between sender (if refund), foundation, * artist, and artist's additional payee for a token purchased on * project `_projectId`. * @dev possible DoS during splits is acknowledged, and mitigated by * business practices, including end-to-end testing on mainnet, and * admin-accepted artist payment addresses. */ function _splitFundsETH(uint256 _projectId, uint256 _pricePerTokenInWei) internal { if (msg.value > 0) { bool success_; // send refund to sender uint256 refund = msg.value - _pricePerTokenInWei; if (refund > 0) { (success_, ) = msg.sender.call{value: refund}(""); require(success_, "Refund failed"); } // split remaining funds between foundation, artist, and artist's // additional payee ( uint256 artblocksRevenue_, address payable artblocksAddress_, uint256 artistRevenue_, address payable artistAddress_, uint256 additionalPayeePrimaryRevenue_, address payable additionalPayeePrimaryAddress_ ) = genArtCoreContract.getPrimaryRevenueSplits( _projectId, _pricePerTokenInWei ); // Art Blocks payment if (artblocksRevenue_ > 0) { (success_, ) = artblocksAddress_.call{value: artblocksRevenue_}( "" ); require(success_, "Art Blocks payment failed"); } // artist payment if (artistRevenue_ > 0) { (success_, ) = artistAddress_.call{value: artistRevenue_}(""); require(success_, "Artist payment failed"); } // additional payee payment if (additionalPayeePrimaryRevenue_ > 0) { (success_, ) = additionalPayeePrimaryAddress_.call{ value: additionalPayeePrimaryRevenue_ }(""); require(success_, "Additional Payee payment failed"); } } } /** * @notice projectId => maximum invocations per allowlisted address. If a * a value of 0 is returned, there is no limit on the number of mints per * allowlisted address. * Default behavior is limit 1 mint per address. * This value can be changed at any time by the artist. * @dev default value stated above must be updated if the value of * CONFIG_USE_MAX_INVOCATIONS_PER_ADDRESS_OVERRIDE is changed. */ function projectMaxInvocationsPerAddress(uint256 _projectId) public view returns (uint256) { ProjectConfig storage _projectConfig = projectConfig[_projectId]; if (_projectConfig.useMaxInvocationsPerAddressOverride) { return uint256(_projectConfig.maxInvocationsPerAddressOverride); } else { return DEFAULT_MAX_INVOCATIONS_PER_ADDRESS; } } /** * @notice Returns remaining invocations for a given address. * If `projectLimitsMintInvocationsPerAddress` is false, individual * addresses are only limited by the project's maximum invocations, and a * dummy value of zero is returned for `mintInvocationsRemaining`. * If `projectLimitsMintInvocationsPerAddress` is true, the quantity of * remaining mint invocations for address `_address` is returned as * `mintInvocationsRemaining`. * Note that mint invocations per address can be changed at any time by the * artist of a project. * Also note that all mint invocations are limited by a project's maximum * invocations as defined on the core contract. This function may return * a value greater than the project's remaining invocations. */ function projectRemainingInvocationsForAddress( uint256 _projectId, address _address ) external view returns ( bool projectLimitsMintInvocationsPerAddress, uint256 mintInvocationsRemaining ) { uint256 maxInvocationsPerAddress = projectMaxInvocationsPerAddress( _projectId ); if (maxInvocationsPerAddress == 0) { // project does not limit mint invocations per address, so leave // `projectLimitsMintInvocationsPerAddress` at solidity initial // value of false. Also leave `mintInvocationsRemaining` at // solidity initial value of zero, as indicated in this function's // documentation. } else { projectLimitsMintInvocationsPerAddress = true; uint256 userMintInvocations = projectUserMintInvocations[ _projectId ][_address]; // if user has not reached max invocations per address, return // remaining invocations if (maxInvocationsPerAddress > userMintInvocations) { unchecked { // will never underflow due to the check above mintInvocationsRemaining = maxInvocationsPerAddress - userMintInvocations; } } // else user has reached their maximum invocations, so leave // `mintInvocationsRemaining` at solidity initial value of zero } } /** * @notice Process proof for an address. Returns Merkle root. Included to * enable users to easily verify a proof's validity. * @param _proof Merkle proof for address. * @param _address Address to process. * @return merkleRoot Merkle root for `_address` and `_proof` */ function processProofForAddress(bytes32[] calldata _proof, address _address) external pure returns (bytes32) { return _proof.processProofCalldata(hashAddress(_address)); } /** * @notice Gets if price of token is configured, price of minting a * token on project `_projectId`, and currency symbol and address to be * used as payment. Supersedes any core contract price information. * @param _projectId Project ID to get price information for. * @return isConfigured true only if token price has been configured on * this minter * @return tokenPriceInWei current price of token on this minter - invalid * if price has not yet been configured * @return currencySymbol currency symbol for purchases of project on this * minter. This minter always returns "ETH" * @return currencyAddress currency address for purchases of project on * this minter. This minter always returns null address, reserved for ether */ function getPriceInfo(uint256 _projectId) external view returns ( bool isConfigured, uint256 tokenPriceInWei, string memory currencySymbol, address currencyAddress ) { ProjectConfig storage _projectConfig = projectConfig[_projectId]; isConfigured = _projectConfig.priceIsConfigured; tokenPriceInWei = _projectConfig.pricePerTokenInWei; currencySymbol = "ETH"; currencyAddress = address(0); } }
// SPDX-License-Identifier: LGPL-3.0-only // Created By: Art Blocks Inc. pragma solidity ^0.8.0; import "./IAdminACLV0.sol"; /// use the Royalty Registry's IManifold interface for token royalties import "./IManifold.sol"; interface IGenArt721CoreContractV3 is IManifold { /** * @notice Token ID `_tokenId` minted to `_to`. */ event Mint(address indexed _to, uint256 indexed _tokenId); /** * @notice currentMinter updated to `_currentMinter`. * @dev Implemented starting with V3 core */ event MinterUpdated(address indexed _currentMinter); /** * @notice Platform updated on bytes32-encoded field `_field`. */ event PlatformUpdated(bytes32 indexed _field); /** * @notice Project ID `_projectId` updated on bytes32-encoded field * `_update`. */ event ProjectUpdated(uint256 indexed _projectId, bytes32 indexed _update); event ProposedArtistAddressesAndSplits( uint256 indexed _projectId, address _artistAddress, address _additionalPayeePrimarySales, uint256 _additionalPayeePrimarySalesPercentage, address _additionalPayeeSecondarySales, uint256 _additionalPayeeSecondarySalesPercentage ); event AcceptedArtistAddressesAndSplits(uint256 indexed _projectId); // version and type of the core contract // coreVersion is a string of the form "0.x.y" function coreVersion() external view returns (string memory); // coreType is a string of the form "GenArt721CoreV3" function coreType() external view returns (string memory); // owner (pre-V3 was named admin) of contract // this is expected to be an Admin ACL contract for V3 function owner() external view returns (address); // Admin ACL contract for V3, will be at the address owner() function adminACLContract() external returns (IAdminACLV0); // backwards-compatible (pre-V3) admin - equal to owner() function admin() external view returns (address); /** * Function determining if _sender is allowed to call function with * selector _selector on contract `_contract`. Intended to be used with * peripheral contracts such as minters, as well as internally by the * core contract itself. */ function adminACLAllowed( address _sender, address _contract, bytes4 _selector ) external returns (bool); // getter function of public variable function nextProjectId() external view returns (uint256); // getter function of public mapping function tokenIdToProjectId(uint256 tokenId) external view returns (uint256 projectId); // @dev this is not available in V0 function isMintWhitelisted(address minter) external view returns (bool); function projectIdToArtistAddress(uint256 _projectId) external view returns (address payable); function projectIdToAdditionalPayeePrimarySales(uint256 _projectId) external view returns (address payable); function projectIdToAdditionalPayeePrimarySalesPercentage( uint256 _projectId ) external view returns (uint256); // @dev new function in V3 function getPrimaryRevenueSplits(uint256 _projectId, uint256 _price) external view returns ( uint256 artblocksRevenue_, address payable artblocksAddress_, uint256 artistRevenue_, address payable artistAddress_, uint256 additionalPayeePrimaryRevenue_, address payable additionalPayeePrimaryAddress_ ); // @dev new function in V3 function projectStateData(uint256 _projectId) external view returns ( uint256 invocations, uint256 maxInvocations, bool active, bool paused, uint256 completedTimestamp, bool locked ); // @dev Art Blocks primary sales payment address function artblocksPrimarySalesAddress() external view returns (address payable); /** * @notice Backwards-compatible (pre-V3) function returning Art Blocks * primary sales payment address (now called artblocksPrimarySalesAddress). */ function artblocksAddress() external view returns (address payable); // @dev Percentage of primary sales allocated to Art Blocks function artblocksPrimarySalesPercentage() external view returns (uint256); /** * @notice Backwards-compatible (pre-V3) function returning Art Blocks * primary sales percentage (now called artblocksPrimarySalesPercentage). */ function artblocksPercentage() external view returns (uint256); // @dev Art Blocks secondary sales royalties payment address function artblocksSecondarySalesAddress() external view returns (address payable); // @dev Basis points of secondary sales allocated to Art Blocks function artblocksSecondarySalesBPS() external view returns (uint256); // function to set a token's hash (must be guarded) function setTokenHash_8PT(uint256 _tokenId, bytes32 _hash) external; // @dev gas-optimized signature in V3 for `mint` function mint_Ecf( address _to, uint256 _projectId, address _by ) external returns (uint256 tokenId); /** * @notice Backwards-compatible (pre-V3) function that gets artist + * artist's additional payee royalty data for token ID `_tokenId`. * WARNING: Does not include Art Blocks portion of royalties. */ function getRoyaltyData(uint256 _tokenId) external view returns ( address artistAddress, address additionalPayee, uint256 additionalPayeePercentage, uint256 royaltyFeeByID ); }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.17; /// @dev Source: https://github.com/0xfoobar/delegation-registry/blob/main/src/IDelegationRegistry.sol /** * @title An immutable registry contract to be deployed as a standalone primitive * @dev See EIP-5639, new project launches can read previous cold wallet -> hot wallet delegations * from here and integrate those permissions into their flow */ interface IDelegationRegistry { /// @notice Delegation type enum DelegationType { NONE, ALL, CONTRACT, TOKEN } /// @notice Info about a single delegation, used for onchain enumeration struct DelegationInfo { DelegationType type_; address vault; address delegate; address contract_; uint256 tokenId; } /// @notice Info about a single contract-level delegation struct ContractDelegation { address contract_; address delegate; } /// @notice Info about a single token-level delegation struct TokenDelegation { address contract_; uint256 tokenId; address delegate; } /// @notice Emitted when a user delegates their entire wallet event DelegateForAll(address vault, address delegate, bool value); /// @notice Emitted when a user delegates a specific contract event DelegateForContract( address vault, address delegate, address contract_, bool value ); /// @notice Emitted when a user delegates a specific token event DelegateForToken( address vault, address delegate, address contract_, uint256 tokenId, bool value ); /// @notice Emitted when a user revokes all delegations event RevokeAllDelegates(address vault); /// @notice Emitted when a user revoes all delegations for a given delegate event RevokeDelegate(address vault, address delegate); /** * ----------- WRITE ----------- */ /** * @notice Allow the delegate to act on your behalf for all contracts * @param delegate The hotwallet to act on your behalf * @param value Whether to enable or disable delegation for this address, true for setting and false for revoking */ function delegateForAll(address delegate, bool value) external; /** * @notice Allow the delegate to act on your behalf for a specific contract * @param delegate The hotwallet to act on your behalf * @param contract_ The address for the contract you're delegating * @param value Whether to enable or disable delegation for this address, true for setting and false for revoking */ function delegateForContract( address delegate, address contract_, bool value ) external; /** * @notice Allow the delegate to act on your behalf for a specific token * @param delegate The hotwallet to act on your behalf * @param contract_ The address for the contract you're delegating * @param tokenId The token id for the token you're delegating * @param value Whether to enable or disable delegation for this address, true for setting and false for revoking */ function delegateForToken( address delegate, address contract_, uint256 tokenId, bool value ) external; /** * @notice Revoke all delegates */ function revokeAllDelegates() external; /** * @notice Revoke a specific delegate for all their permissions * @param delegate The hotwallet to revoke */ function revokeDelegate(address delegate) external; /** * @notice Remove yourself as a delegate for a specific vault * @param vault The vault which delegated to the msg.sender, and should be removed */ function revokeSelf(address vault) external; /** * ----------- READ ----------- */ /** * @notice Returns all active delegations a given delegate is able to claim on behalf of * @param delegate The delegate that you would like to retrieve delegations for * @return info Array of DelegationInfo structs */ function getDelegationsByDelegate(address delegate) external view returns (DelegationInfo[] memory); /** * @notice Returns an array of wallet-level delegates for a given vault * @param vault The cold wallet who issued the delegation * @return addresses Array of wallet-level delegates for a given vault */ function getDelegatesForAll(address vault) external view returns (address[] memory); /** * @notice Returns an array of contract-level delegates for a given vault and contract * @param vault The cold wallet who issued the delegation * @param contract_ The address for the contract you're delegating * @return addresses Array of contract-level delegates for a given vault and contract */ function getDelegatesForContract(address vault, address contract_) external view returns (address[] memory); /** * @notice Returns an array of contract-level delegates for a given vault's token * @param vault The cold wallet who issued the delegation * @param contract_ The address for the contract holding the token * @param tokenId The token id for the token you're delegating * @return addresses Array of contract-level delegates for a given vault's token */ function getDelegatesForToken( address vault, address contract_, uint256 tokenId ) external view returns (address[] memory); /** * @notice Returns all contract-level delegations for a given vault * @param vault The cold wallet who issued the delegations * @return delegations Array of ContractDelegation structs */ function getContractLevelDelegations(address vault) external view returns (ContractDelegation[] memory delegations); /** * @notice Returns all token-level delegations for a given vault * @param vault The cold wallet who issued the delegations * @return delegations Array of TokenDelegation structs */ function getTokenLevelDelegations(address vault) external view returns (TokenDelegation[] memory delegations); /** * @notice Returns true if the address is delegated to act on the entire vault * @param delegate The hotwallet to act on your behalf * @param vault The cold wallet who issued the delegation */ function checkDelegateForAll(address delegate, address vault) external view returns (bool); /** * @notice Returns true if the address is delegated to act on your behalf for a token contract or an entire vault * @param delegate The hotwallet to act on your behalf * @param contract_ The address for the contract you're delegating * @param vault The cold wallet who issued the delegation */ function checkDelegateForContract( address delegate, address vault, address contract_ ) external view returns (bool); /** * @notice Returns true if the address is delegated to act on your behalf for a specific token, the token's contract or an entire vault * @param delegate The hotwallet to act on your behalf * @param contract_ The address for the contract you're delegating * @param tokenId The token id for the token you're delegating * @param vault The cold wallet who issued the delegation */ function checkDelegateForToken( address delegate, address vault, address contract_, uint256 tokenId ) external view returns (bool); }
// SPDX-License-Identifier: LGPL-3.0-only // Created By: Art Blocks Inc. import "./IFilteredMinterV1.sol"; pragma solidity ^0.8.0; /** * @title This interface extends the IFilteredMinterV1 interface in order to * add support for including Merkle proofs when purchasing. * @author Art Blocks Inc. */ interface IFilteredMinterMerkleV0 is IFilteredMinterV1 { /** * @notice Notifies of the contract's default maximum mints allowed per * user for a given project, on this minter. This value can be overridden * by the artist of any project at any time. */ event DefaultMaxInvocationsPerAddress( uint256 defaultMaxInvocationsPerAddress ); // Triggers a purchase of a token from the desired project, to the // TX-sending address. Requires Merkle proof. function purchase(uint256 _projectId, bytes32[] memory _proof) external payable returns (uint256 tokenId); // Triggers a purchase of a token from the desired project, to the specified // receiving address. Requires Merkle proof. function purchaseTo( address _to, uint256 _projectId, bytes32[] memory _proof ) external payable returns (uint256 tokenId); }
// SPDX-License-Identifier: LGPL-3.0-only // Created By: Art Blocks Inc. pragma solidity ^0.8.0; interface IMinterFilterV0 { /** * @notice Approved minter `_minterAddress`. */ event MinterApproved(address indexed _minterAddress, string _minterType); /** * @notice Revoked approval for minter `_minterAddress` */ event MinterRevoked(address indexed _minterAddress); /** * @notice Minter `_minterAddress` of type `_minterType` * registered for project `_projectId`. */ event ProjectMinterRegistered( uint256 indexed _projectId, address indexed _minterAddress, string _minterType ); /** * @notice Any active minter removed for project `_projectId`. */ event ProjectMinterRemoved(uint256 indexed _projectId); function genArt721CoreAddress() external returns (address); function setMinterForProject(uint256, address) external; function removeMinterForProject(uint256) external; function mint( address _to, uint256 _projectId, address sender ) external returns (uint256); function getMinterForProject(uint256) external view returns (address); function projectHasMinter(uint256) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`, * consuming from one or the other at each step according to the instructions given by * `proofFlags`. * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof} * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { return hashes[totalHashes - 1]; } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @dev Royalty Registry interface, used to support the Royalty Registry. /// @dev Source: https://github.com/manifoldxyz/royalty-registry-solidity/blob/main/contracts/specs/IManifold.sol /// @author: manifold.xyz /** * @dev Royalty interface for creator core classes */ interface IManifold { /** * @dev Get royalites of a token. Returns list of receivers and basisPoints * * bytes4(keccak256('getRoyalties(uint256)')) == 0xbb3bafd6 * * => 0xbb3bafd6 = 0xbb3bafd6 */ function getRoyalties(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory); }
// SPDX-License-Identifier: LGPL-3.0-only // Created By: Art Blocks Inc. pragma solidity ^0.8.0; interface IAdminACLV0 { /** * @notice Token ID `_tokenId` minted to `_to`. * @param previousSuperAdmin The previous superAdmin address. * @param newSuperAdmin The new superAdmin address. * @param genArt721CoreAddressesToUpdate Array of genArt721Core * addresses to update to the new superAdmin, for indexing purposes only. */ event SuperAdminTransferred( address indexed previousSuperAdmin, address indexed newSuperAdmin, address[] genArt721CoreAddressesToUpdate ); /// Type of the Admin ACL contract, e.g. "AdminACLV0" function AdminACLType() external view returns (string memory); /// super admin address function superAdmin() external view returns (address); /** * @notice Calls transferOwnership on other contract from this contract. * This is useful for updating to a new AdminACL contract. * @dev this function should be gated to only superAdmin-like addresses. */ function transferOwnershipOn(address _contract, address _newAdminACL) external; /** * @notice Calls renounceOwnership on other contract from this contract. * @dev this function should be gated to only superAdmin-like addresses. */ function renounceOwnershipOn(address _contract) external; /** * @notice Checks if sender `_sender` is allowed to call function with selector * `_selector` on contract `_contract`. */ function allowed( address _sender, address _contract, bytes4 _selector ) external returns (bool); }
// SPDX-License-Identifier: LGPL-3.0-only // Created By: Art Blocks Inc. import "./IFilteredMinterV0.sol"; pragma solidity ^0.8.0; /** * @title This interface extends the IFilteredMinterV0 interface in order to * add support for generic project minter configuration updates. * @dev keys represent strings of finite length encoded in bytes32 to minimize * gas. * @author Art Blocks Inc. */ interface IFilteredMinterV1 is IFilteredMinterV0 { /// ANY /** * @notice Generic project minter configuration event. Removes key `_key` * for project `_projectId`. */ event ConfigKeyRemoved(uint256 indexed _projectId, bytes32 _key); /// BOOL /** * @notice Generic project minter configuration event. Sets value of key * `_key` to `_value` for project `_projectId`. */ event ConfigValueSet(uint256 indexed _projectId, bytes32 _key, bool _value); /// UINT256 /** * @notice Generic project minter configuration event. Sets value of key * `_key` to `_value` for project `_projectId`. */ event ConfigValueSet( uint256 indexed _projectId, bytes32 _key, uint256 _value ); /** * @notice Generic project minter configuration event. Adds value `_value` * to the set of uint256 at key `_key` for project `_projectId`. */ event ConfigValueAddedToSet( uint256 indexed _projectId, bytes32 _key, uint256 _value ); /** * @notice Generic project minter configuration event. Removes value * `_value` to the set of uint256 at key `_key` for project `_projectId`. */ event ConfigValueRemovedFromSet( uint256 indexed _projectId, bytes32 _key, uint256 _value ); /// ADDRESS /** * @notice Generic project minter configuration event. Sets value of key * `_key` to `_value` for project `_projectId`. */ event ConfigValueSet( uint256 indexed _projectId, bytes32 _key, address _value ); /** * @notice Generic project minter configuration event. Adds value `_value` * to the set of addresses at key `_key` for project `_projectId`. */ event ConfigValueAddedToSet( uint256 indexed _projectId, bytes32 _key, address _value ); /** * @notice Generic project minter configuration event. Removes value * `_value` to the set of addresses at key `_key` for project `_projectId`. */ event ConfigValueRemovedFromSet( uint256 indexed _projectId, bytes32 _key, address _value ); /// BYTES32 /** * @notice Generic project minter configuration event. Sets value of key * `_key` to `_value` for project `_projectId`. */ event ConfigValueSet( uint256 indexed _projectId, bytes32 _key, bytes32 _value ); /** * @notice Generic project minter configuration event. Adds value `_value` * to the set of bytes32 at key `_key` for project `_projectId`. */ event ConfigValueAddedToSet( uint256 indexed _projectId, bytes32 _key, bytes32 _value ); /** * @notice Generic project minter configuration event. Removes value * `_value` to the set of bytes32 at key `_key` for project `_projectId`. */ event ConfigValueRemovedFromSet( uint256 indexed _projectId, bytes32 _key, bytes32 _value ); /** * @dev Strings not supported. Recommend conversion of (short) strings to * bytes32 to remain gas-efficient. */ }
// SPDX-License-Identifier: LGPL-3.0-only // Created By: Art Blocks Inc. pragma solidity ^0.8.0; interface IFilteredMinterV0 { /** * @notice Price per token in wei updated for project `_projectId` to * `_pricePerTokenInWei`. */ event PricePerTokenInWeiUpdated( uint256 indexed _projectId, uint256 indexed _pricePerTokenInWei ); /** * @notice Currency updated for project `_projectId` to symbol * `_currencySymbol` and address `_currencyAddress`. */ event ProjectCurrencyInfoUpdated( uint256 indexed _projectId, address indexed _currencyAddress, string _currencySymbol ); /// togglePurchaseToDisabled updated event PurchaseToDisabledUpdated( uint256 indexed _projectId, bool _purchaseToDisabled ); // getter function of public variable function minterType() external view returns (string memory); function genArt721CoreAddress() external returns (address); function minterFilterAddress() external returns (address); // Triggers a purchase of a token from the desired project, to the // TX-sending address. function purchase(uint256 _projectId) external payable returns (uint256 tokenId); // Triggers a purchase of a token from the desired project, to the specified // receiving address. function purchaseTo(address _to, uint256 _projectId) external payable returns (uint256 tokenId); // Toggles the ability for `purchaseTo` to be called directly with a // specified receiving address that differs from the TX-sending address. function togglePurchaseToDisabled(uint256 _projectId) external; // Called to make the minter contract aware of the max invocations for a // given project. function setProjectMaxInvocations(uint256 _projectId) external; // Gets if token price is configured, token price in wei, currency symbol, // and currency address, assuming this is project's minter. // Supersedes any defined core price. function getPriceInfo(uint256 _projectId) external view returns ( bool isConfigured, uint256 tokenPriceInWei, string memory currencySymbol, address currencyAddress ); }
{ "optimizer": { "enabled": true, "runs": 25 }, "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":"_genArt721Address","type":"address"},{"internalType":"address","name":"_minterFilter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"ConfigKeyRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"ConfigValueAddedToSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_value","type":"address"}],"name":"ConfigValueAddedToSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"ConfigValueAddedToSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"ConfigValueRemovedFromSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_value","type":"address"}],"name":"ConfigValueRemovedFromSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"ConfigValueRemovedFromSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"_value","type":"bool"}],"name":"ConfigValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"ConfigValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"address","name":"_value","type":"address"}],"name":"ConfigValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"_key","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"ConfigValueSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"defaultMaxInvocationsPerAddress","type":"uint256"}],"name":"DefaultMaxInvocationsPerAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_pricePerTokenInWei","type":"uint256"}],"name":"PricePerTokenInWeiUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_currencyAddress","type":"address"},{"indexed":false,"internalType":"string","name":"_currencySymbol","type":"string"}],"name":"ProjectCurrencyInfoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"_purchaseToDisabled","type":"bool"}],"name":"PurchaseToDisabledUpdated","type":"event"},{"inputs":[],"name":"DEFAULT_MAX_INVOCATIONS_PER_ADDRESS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DELEGATION_REGISTRY_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genArt721CoreAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"getPriceInfo","outputs":[{"internalType":"bool","name":"isConfigured","type":"bool"},{"internalType":"uint256","name":"tokenPriceInWei","type":"uint256"},{"internalType":"string","name":"currencySymbol","type":"string"},{"internalType":"address","name":"currencyAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"hashAddress","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"minterFilterAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minterType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_address","type":"address"}],"name":"processProofForAddress","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectConfig","outputs":[{"internalType":"bool","name":"maxHasBeenInvoked","type":"bool"},{"internalType":"bool","name":"priceIsConfigured","type":"bool"},{"internalType":"bool","name":"useMaxInvocationsPerAddressOverride","type":"bool"},{"internalType":"uint24","name":"maxInvocationsPerAddressOverride","type":"uint24"},{"internalType":"uint24","name":"maxInvocations","type":"uint24"},{"internalType":"uint256","name":"pricePerTokenInWei","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"projectMaxHasBeenInvoked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"projectMaxInvocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"projectMaxInvocationsPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"projectMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address","name":"_address","type":"address"}],"name":"projectRemainingInvocationsForAddress","outputs":[{"internalType":"bool","name":"projectLimitsMintInvocationsPerAddress","type":"bool"},{"internalType":"uint256","name":"mintInvocationsRemaining","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"projectUserMintInvocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"purchase","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"purchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"purchaseTo","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"purchaseTo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_vault","type":"address"}],"name":"purchaseTo","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_vault","type":"address"}],"name":"purchaseTo_kem","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"purchase_gD5","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint24","name":"_maxInvocationsPerAddress","type":"uint24"}],"name":"setProjectInvocationsPerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"setProjectMaxInvocations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"togglePurchaseToDisabled","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"updateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"uint256","name":"_pricePerTokenInWei","type":"uint256"}],"name":"updatePricePerTokenInWei","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_address","type":"address"}],"name":"verifyAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101206040523480156200001257600080fd5b5060405162001df138038062001df183398101604081905262000035916200018e565b600160009081556001600160a01b0380841660a081905260c08190526d76a84fef008cdabe6409d2fe638b60805290831660e0819052610100819052604080516392a10f8360e01b81529051929391926392a10f83926004808401936020939290839003909101908290875af1158015620000b4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000da9190620001c6565b6001600160a01b031614620001355760405162461bcd60e51b815260206004820152601860248201527f496c6c6567616c20636f6e74726163742070616972696e670000000000000000604482015260640160405180910390fd5b604051600181527fb004e34bc1718c504fde68324f2eba80b0329056f240eaaa6803c286c4b9e7ed9060200160405180910390a15050620001eb565b80516001600160a01b03811681146200018957600080fd5b919050565b60008060408385031215620001a257600080fd5b620001ad8362000171565b9150620001bd6020840162000171565b90509250929050565b600060208284031215620001d957600080fd5b620001e48262000171565b9392505050565b60805160a05160c05160e05161010051611b976200025a6000396000610a050152600061055f015260008181610b9101528181610ce001528181610e730152818161101f0152818161117f01526112d80152600081816103a501526107b9015260006107e40152611b976000f3fe6080604052600436106101535760003560e01c806392a10f83116100bc57806392a10f83146103935780639775f86f146103df578063aea7d3b9146103f4578063b2543d021461042c578063c15127c01461044e578063c71b1b7114610461578063cc3352bf14610500578063d684ec6714610520578063da7e7c501461017e578063dd85582f1461054d578063e9d1e8ac14610581578063efef39a1146105c8578063f1e33115146105d6578063f7bd4b88146105f657600080fd5b806157b6146101585780615aa11461017e57806315bed159146101915780631ec2e523146101b1578063202c5805146101d15780633aa5fe59146101e457806340d1397e14610204578063462add461461022657806356690aaf146102665780636b453e701461029f5780636cb9b7ff146102d65780636ede4ade146102f6578063774159c614610316578063891407c014610380575b600080fd5b61016b61016636600461166e565b610616565b6040519081526020015b60405180910390f35b61016b61018c3660046116e1565b610abd565b34801561019d57600080fd5b5061016b6101ac36600461172c565b610ad5565b3480156101bd57600080fd5b5061016b6101cc366004611745565b610b0f565b61016b6101df36600461179b565b610b26565b3480156101f057600080fd5b5061016b6101ff3660046117f6565b610b3f565b34801561021057600080fd5b5061022461021f36600461172c565b610b79565b005b34801561023257600080fd5b5061025661024136600461172c565b60009081526001602052604090205460ff1690565b6040519015158152602001610175565b34801561027257600080fd5b5061016b61028136600461172c565b600090815260016020526040902054600160301b900462ffffff1690565b3480156102ab57600080fd5b506102bf6102ba36600461181a565b610c73565b604080519215158352602083019190915201610175565b3480156102e257600080fd5b506102246102f136600461184a565b610cc8565b34801561030257600080fd5b5061025661031136600461186c565b610dd6565b34801561032257600080fd5b5061037061033136600461172c565b600090815260016020818152604080842080549301548151808301909252600382526208aa8960eb1b9282019290925261010090920460ff1693909290565b6040516101759493929190611910565b61016b61038e36600461194a565b610dfb565b34801561039f57600080fd5b506103c77f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610175565b3480156103eb57600080fd5b5061016b600181565b34801561040057600080fd5b5061016b61040f36600461181a565b600360209081526000928352604080842090915290825290205481565b34801561043857600080fd5b506103c76d76a84fef008cdabe6409d2fe638b81565b61016b61045c36600461166e565b610e42565b34801561046d57600080fd5b506104c461047c36600461172c565b6001602081905260009182526040909120805491015460ff8083169261010081048216926201000082049092169162ffffff63010000008304811692600160301b9004169086565b60408051961515875294151560208701529215159385019390935262ffffff9081166060850152909116608083015260a082015260c001610175565b34801561050c57600080fd5b5061022461051b366004611976565b610e5b565b34801561052c57600080fd5b5061016b61053b36600461172c565b60026020526000908152604090205481565b34801561055957600080fd5b506103c77f000000000000000000000000000000000000000000000000000000000000000081565b34801561058d57600080fd5b506105bb6040518060400160405280600e81526020016d26b4b73a32b926b2b935b632ab1960911b81525081565b60405161017591906119a3565b61016b61038e36600461172c565b3480156105e257600080fd5b506102246105f136600461184a565b611007565b34801561060257600080fd5b5061022461061136600461172c565b611166565b600060026000540361066f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000908155858152600160205260409020805460ff16156106e25760405162461bcd60e51b815260206004820152602560248201527f4d6178696d756d206e756d626572206f6620696e766f636174696f6e732072656044820152641858da195960da1b6064820152608401610666565b6001810154348111156107375760405162461bcd60e51b815260206004820181905260248201527f4d7573742073656e64206d696e696d756d2076616c756520746f206d696e74216044820152606401610666565b8154610100900460ff166107845760405162461bcd60e51b8152602060048201526014602482015273141c9a58d9481b9bdd0818dbdb999a59dd5c995960621b6044820152606401610666565b336001600160a01b038516156108a55760405163090c9a2d60e41b81523360048201526001600160a01b0386811660248301527f0000000000000000000000000000000000000000000000000000000000000000811660448301526000917f0000000000000000000000000000000000000000000000000000000000000000909116906390c9a2d090606401602060405180830381865afa15801561082d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085191906119cb565b9050806108a05760405162461bcd60e51b815260206004820152601e60248201527f496e76616c69642064656c65676174652d7661756c742070616972696e6700006044820152606401610666565b859150505b6108b188888884610dd6565b6108f45760405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21026b2b935b63290383937b7b360611b6044820152606401610666565b825460009062010000900460ff1661090d57600161091c565b83546301000000900462ffffff165b60008a81526003602090815260408083206001600160a01b038716845290915290205490915081118061094d575080155b6109b35760405162461bcd60e51b815260206004820152603160248201527f4d6178696d756d206e756d626572206f6620696e766f636174696f6e732070656044820152701c881859191c995cdcc81c995858da1959607a1b6064820152608401610666565b60008981526003602090815260408083206001600160a01b0386811680865291909352928190208054600101905551630d4d151360e01b81528c82166004820152602481018c905260448101929092527f00000000000000000000000000000000000000000000000000000000000000001690630d4d1513906064016020604051808303816000875af1158015610a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7291906119e6565b845490955060001962ffffff600160301b90920482160116620f4240860603610aa157835460ff191660011784555b610aab898461122a565b50505050600160005595945050505050565b6000610acd338585856000610616565b949350505050565b6000818152600160205260408120805462010000900460ff1615610b0657546301000000900462ffffff1692915050565b50600192915050565b6000610acd610b1d83610b3f565b85908590611573565b6000610b36858585856000610616565b95945050505050565b6040516001600160601b0319606083901b166020820152600090603401604051602081830303815290604052805190602001209050919050565b60405163a47d29cb60e01b81526004810182905281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a47d29cb90602401602060405180830381865afa158015610be0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0491906119ff565b6001600160a01b0316336001600160a01b031614610c345760405162461bcd60e51b815260040161066690611a1c565b60405162461bcd60e51b81526020600482015260146024820152731058dd1a5bdb881b9bdd081cdd5c1c1bdc9d195960621b6044820152606401610666565b6000806000610c8185610ad5565b90508015610cc05760008581526003602090815260408083206001600160a01b03881684529091529020546001935080821115610cbe5780820392505b505b509250929050565b60405163a47d29cb60e01b81526004810183905282907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a47d29cb90602401602060405180830381865afa158015610d2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5391906119ff565b6001600160a01b0316336001600160a01b031614610d835760405162461bcd60e51b815260040161066690611a1c565b6000838152600160208190526040808320918201859055815461ff0019166101001790915551839185917f26118a27aca826f829f3bfe21b140b4455c00b434849bd0da50d1e1a9720fb5c9190a3505050565b600084815260026020526040812054610b3690610df284610b3f565b869186916115bf565b60405162461bcd60e51b815260206004820152601960248201527826bab9ba10383937bb34b2329026b2b935b63290383937b7b360391b6044820152600090606401610666565b6000610e518686868686610616565b9695505050505050565b60405163a47d29cb60e01b81526004810183905282907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a47d29cb90602401602060405180830381865afa158015610ec2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee691906119ff565b6001600160a01b0316336001600160a01b031614610f165760405162461bcd60e51b815260040161066690611a1c565b600083815260016020819052604091829020805462ffffff861663010000000265ffffffff0000199091161762010000178155915185917fc594e23b9382359e253cdaba84b0aefe5ad09ccfd5706891673743b37229c2d291610fa091797573654d61784d696e7473506572416464724f7665727269646560301b82521515602082015260400190565b60405180910390a260408051766d61784d696e7473506572416464724f7665727269646560481b815262ffffff8516602082015285917f8a5820ca7148caeda3176e8d60a3bb413b4bcca45922ac2178b1ee191fe320eb910160405180910390a250505050565b60405163a47d29cb60e01b81526004810183905282907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a47d29cb90602401602060405180830381865afa15801561106e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109291906119ff565b6001600160a01b0316336001600160a01b0316146110c25760405162461bcd60e51b815260040161066690611a1c565b816111075760405162461bcd60e51b8152602060048201526015602482015274149bdbdd081b5d5cdd081899481c1c9bdd9a591959605a1b6044820152606401610666565b6000838152600260209081526040918290208490558151691b595c9adb19549bdbdd60b21b815290810184905284917f729c0261c7e3c976b9a392f2bb08064d7a03c82f9f1473ab0ee284c985df0815910160405180910390a2505050565b604051630ea5613f60e01b8152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630ea5613f9060240160c060405180830381865afa1580156111ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f29190611a41565b50505060009485525060016020526040909320805462ffffff909416600160301b0262ffffff60301b19909416939093179092555050565b341561156f5760008061123d8334611ab6565b905080156112cd5760405133908290600081818185875af1925050503d8060008114611285576040519150601f19603f3d011682016040523d82523d6000602084013e61128a565b606091505b505080925050816112cd5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606401610666565b6000806000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638639415b8b8b6040518363ffffffff1660e01b815260040161132d929190918252602082015260400190565b60c060405180830381865afa15801561134a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136e9190611ac9565b9550955095509550955095506000861115611420576040516001600160a01b038616908790600081818185875af1925050503d80600081146113cc576040519150601f19603f3d011682016040523d82523d6000602084013e6113d1565b606091505b505080985050876114205760405162461bcd60e51b8152602060048201526019602482015278105c9d08109b1bd8dadcc81c185e5b595b9d0819985a5b1959603a1b6044820152606401610666565b83156114bf576040516001600160a01b038416908590600081818185875af1925050503d806000811461146f576040519150601f19603f3d011682016040523d82523d6000602084013e611474565b606091505b505080985050876114bf5760405162461bcd60e51b8152602060048201526015602482015274105c9d1a5cdd081c185e5b595b9d0819985a5b1959605a1b6044820152606401610666565b8115611566576040516001600160a01b038216908390600081818185875af1925050503d806000811461150e576040519150601f19603f3d011682016040523d82523d6000602084013e611513565b606091505b505080985050876115665760405162461bcd60e51b815260206004820152601f60248201527f4164646974696f6e616c205061796565207061796d656e74206661696c6564006044820152606401610666565b50505050505050505b5050565b600081815b848110156115b6576115a28287878481811061159657611596611b32565b905060200201356115d7565b9150806115ae81611b48565b915050611578565b50949350505050565b6000826115cd868685611573565b1495945050505050565b60008183106115f3576000828152602084905260409020611602565b60008381526020839052604090205b90505b92915050565b6001600160a01b038116811461162057600080fd5b50565b60008083601f84011261163557600080fd5b5081356001600160401b0381111561164c57600080fd5b6020830191508360208260051b850101111561166757600080fd5b9250929050565b60008060008060006080868803121561168657600080fd5b85356116918161160b565b94506020860135935060408601356001600160401b038111156116b357600080fd5b6116bf88828901611623565b90945092505060608601356116d38161160b565b809150509295509295909350565b6000806000604084860312156116f657600080fd5b8335925060208401356001600160401b0381111561171357600080fd5b61171f86828701611623565b9497909650939450505050565b60006020828403121561173e57600080fd5b5035919050565b60008060006040848603121561175a57600080fd5b83356001600160401b0381111561177057600080fd5b61177c86828701611623565b90945092505060208401356117908161160b565b809150509250925092565b600080600080606085870312156117b157600080fd5b84356117bc8161160b565b93506020850135925060408501356001600160401b038111156117de57600080fd5b6117ea87828801611623565b95989497509550505050565b60006020828403121561180857600080fd5b81356118138161160b565b9392505050565b6000806040838503121561182d57600080fd5b82359150602083013561183f8161160b565b809150509250929050565b6000806040838503121561185d57600080fd5b50508035926020909101359150565b6000806000806060858703121561188257600080fd5b8435935060208501356001600160401b0381111561189f57600080fd5b6118ab87828801611623565b90945092505060408501356118bf8161160b565b939692955090935050565b6000815180845260005b818110156118f0576020818501810151868301820152016118d4565b506000602082860101526020601f19601f83011685010191505092915050565b841515815283602082015260806040820152600061193160808301856118ca565b905060018060a01b038316606083015295945050505050565b6000806040838503121561195d57600080fd5b82356119688161160b565b946020939093013593505050565b6000806040838503121561198957600080fd5b82359150602083013562ffffff8116811461183f57600080fd5b60208152600061160260208301846118ca565b805180151581146119c657600080fd5b919050565b6000602082840312156119dd57600080fd5b611602826119b6565b6000602082840312156119f857600080fd5b5051919050565b600060208284031215611a1157600080fd5b81516118138161160b565b6020808252600b908201526a13db9b1e48105c9d1a5cdd60aa1b604082015260600190565b60008060008060008060c08789031215611a5a57600080fd5b8651955060208701519450611a71604088016119b6565b9350611a7f606088016119b6565b925060808701519150611a9460a088016119b6565b90509295509295509295565b634e487b7160e01b600052601160045260246000fd5b8181038181111561160557611605611aa0565b60008060008060008060c08789031215611ae257600080fd5b865195506020870151611af48161160b565b604088015160608901519196509450611b0c8161160b565b608088015160a08901519194509250611b248161160b565b809150509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060018201611b5a57611b5a611aa0565b506001019056fea26469706673582212201a49e1efff7b0fc2d6e9c294eac51760b8f211bed47702c3d563dea63f83575d64736f6c63430008110033000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a0000000000000000000000003f4bbde879f9bb0e95aea08ff12f55e171495c8f
Deployed Bytecode
0x6080604052600436106101535760003560e01c806392a10f83116100bc57806392a10f83146103935780639775f86f146103df578063aea7d3b9146103f4578063b2543d021461042c578063c15127c01461044e578063c71b1b7114610461578063cc3352bf14610500578063d684ec6714610520578063da7e7c501461017e578063dd85582f1461054d578063e9d1e8ac14610581578063efef39a1146105c8578063f1e33115146105d6578063f7bd4b88146105f657600080fd5b806157b6146101585780615aa11461017e57806315bed159146101915780631ec2e523146101b1578063202c5805146101d15780633aa5fe59146101e457806340d1397e14610204578063462add461461022657806356690aaf146102665780636b453e701461029f5780636cb9b7ff146102d65780636ede4ade146102f6578063774159c614610316578063891407c014610380575b600080fd5b61016b61016636600461166e565b610616565b6040519081526020015b60405180910390f35b61016b61018c3660046116e1565b610abd565b34801561019d57600080fd5b5061016b6101ac36600461172c565b610ad5565b3480156101bd57600080fd5b5061016b6101cc366004611745565b610b0f565b61016b6101df36600461179b565b610b26565b3480156101f057600080fd5b5061016b6101ff3660046117f6565b610b3f565b34801561021057600080fd5b5061022461021f36600461172c565b610b79565b005b34801561023257600080fd5b5061025661024136600461172c565b60009081526001602052604090205460ff1690565b6040519015158152602001610175565b34801561027257600080fd5b5061016b61028136600461172c565b600090815260016020526040902054600160301b900462ffffff1690565b3480156102ab57600080fd5b506102bf6102ba36600461181a565b610c73565b604080519215158352602083019190915201610175565b3480156102e257600080fd5b506102246102f136600461184a565b610cc8565b34801561030257600080fd5b5061025661031136600461186c565b610dd6565b34801561032257600080fd5b5061037061033136600461172c565b600090815260016020818152604080842080549301548151808301909252600382526208aa8960eb1b9282019290925261010090920460ff1693909290565b6040516101759493929190611910565b61016b61038e36600461194a565b610dfb565b34801561039f57600080fd5b506103c77f000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a81565b6040516001600160a01b039091168152602001610175565b3480156103eb57600080fd5b5061016b600181565b34801561040057600080fd5b5061016b61040f36600461181a565b600360209081526000928352604080842090915290825290205481565b34801561043857600080fd5b506103c76d76a84fef008cdabe6409d2fe638b81565b61016b61045c36600461166e565b610e42565b34801561046d57600080fd5b506104c461047c36600461172c565b6001602081905260009182526040909120805491015460ff8083169261010081048216926201000082049092169162ffffff63010000008304811692600160301b9004169086565b60408051961515875294151560208701529215159385019390935262ffffff9081166060850152909116608083015260a082015260c001610175565b34801561050c57600080fd5b5061022461051b366004611976565b610e5b565b34801561052c57600080fd5b5061016b61053b36600461172c565b60026020526000908152604090205481565b34801561055957600080fd5b506103c77f0000000000000000000000003f4bbde879f9bb0e95aea08ff12f55e171495c8f81565b34801561058d57600080fd5b506105bb6040518060400160405280600e81526020016d26b4b73a32b926b2b935b632ab1960911b81525081565b60405161017591906119a3565b61016b61038e36600461172c565b3480156105e257600080fd5b506102246105f136600461184a565b611007565b34801561060257600080fd5b5061022461061136600461172c565b611166565b600060026000540361066f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b60026000908155858152600160205260409020805460ff16156106e25760405162461bcd60e51b815260206004820152602560248201527f4d6178696d756d206e756d626572206f6620696e766f636174696f6e732072656044820152641858da195960da1b6064820152608401610666565b6001810154348111156107375760405162461bcd60e51b815260206004820181905260248201527f4d7573742073656e64206d696e696d756d2076616c756520746f206d696e74216044820152606401610666565b8154610100900460ff166107845760405162461bcd60e51b8152602060048201526014602482015273141c9a58d9481b9bdd0818dbdb999a59dd5c995960621b6044820152606401610666565b336001600160a01b038516156108a55760405163090c9a2d60e41b81523360048201526001600160a01b0386811660248301527f000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a811660448301526000917f00000000000000000000000000000000000076a84fef008cdabe6409d2fe638b909116906390c9a2d090606401602060405180830381865afa15801561082d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085191906119cb565b9050806108a05760405162461bcd60e51b815260206004820152601e60248201527f496e76616c69642064656c65676174652d7661756c742070616972696e6700006044820152606401610666565b859150505b6108b188888884610dd6565b6108f45760405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21026b2b935b63290383937b7b360611b6044820152606401610666565b825460009062010000900460ff1661090d57600161091c565b83546301000000900462ffffff165b60008a81526003602090815260408083206001600160a01b038716845290915290205490915081118061094d575080155b6109b35760405162461bcd60e51b815260206004820152603160248201527f4d6178696d756d206e756d626572206f6620696e766f636174696f6e732070656044820152701c881859191c995cdcc81c995858da1959607a1b6064820152608401610666565b60008981526003602090815260408083206001600160a01b0386811680865291909352928190208054600101905551630d4d151360e01b81528c82166004820152602481018c905260448101929092527f0000000000000000000000003f4bbde879f9bb0e95aea08ff12f55e171495c8f1690630d4d1513906064016020604051808303816000875af1158015610a4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7291906119e6565b845490955060001962ffffff600160301b90920482160116620f4240860603610aa157835460ff191660011784555b610aab898461122a565b50505050600160005595945050505050565b6000610acd338585856000610616565b949350505050565b6000818152600160205260408120805462010000900460ff1615610b0657546301000000900462ffffff1692915050565b50600192915050565b6000610acd610b1d83610b3f565b85908590611573565b6000610b36858585856000610616565b95945050505050565b6040516001600160601b0319606083901b166020820152600090603401604051602081830303815290604052805190602001209050919050565b60405163a47d29cb60e01b81526004810182905281907f000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a6001600160a01b03169063a47d29cb90602401602060405180830381865afa158015610be0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0491906119ff565b6001600160a01b0316336001600160a01b031614610c345760405162461bcd60e51b815260040161066690611a1c565b60405162461bcd60e51b81526020600482015260146024820152731058dd1a5bdb881b9bdd081cdd5c1c1bdc9d195960621b6044820152606401610666565b6000806000610c8185610ad5565b90508015610cc05760008581526003602090815260408083206001600160a01b03881684529091529020546001935080821115610cbe5780820392505b505b509250929050565b60405163a47d29cb60e01b81526004810183905282907f000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a6001600160a01b03169063a47d29cb90602401602060405180830381865afa158015610d2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5391906119ff565b6001600160a01b0316336001600160a01b031614610d835760405162461bcd60e51b815260040161066690611a1c565b6000838152600160208190526040808320918201859055815461ff0019166101001790915551839185917f26118a27aca826f829f3bfe21b140b4455c00b434849bd0da50d1e1a9720fb5c9190a3505050565b600084815260026020526040812054610b3690610df284610b3f565b869186916115bf565b60405162461bcd60e51b815260206004820152601960248201527826bab9ba10383937bb34b2329026b2b935b63290383937b7b360391b6044820152600090606401610666565b6000610e518686868686610616565b9695505050505050565b60405163a47d29cb60e01b81526004810183905282907f000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a6001600160a01b03169063a47d29cb90602401602060405180830381865afa158015610ec2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee691906119ff565b6001600160a01b0316336001600160a01b031614610f165760405162461bcd60e51b815260040161066690611a1c565b600083815260016020819052604091829020805462ffffff861663010000000265ffffffff0000199091161762010000178155915185917fc594e23b9382359e253cdaba84b0aefe5ad09ccfd5706891673743b37229c2d291610fa091797573654d61784d696e7473506572416464724f7665727269646560301b82521515602082015260400190565b60405180910390a260408051766d61784d696e7473506572416464724f7665727269646560481b815262ffffff8516602082015285917f8a5820ca7148caeda3176e8d60a3bb413b4bcca45922ac2178b1ee191fe320eb910160405180910390a250505050565b60405163a47d29cb60e01b81526004810183905282907f000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a6001600160a01b03169063a47d29cb90602401602060405180830381865afa15801561106e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109291906119ff565b6001600160a01b0316336001600160a01b0316146110c25760405162461bcd60e51b815260040161066690611a1c565b816111075760405162461bcd60e51b8152602060048201526015602482015274149bdbdd081b5d5cdd081899481c1c9bdd9a591959605a1b6044820152606401610666565b6000838152600260209081526040918290208490558151691b595c9adb19549bdbdd60b21b815290810184905284917f729c0261c7e3c976b9a392f2bb08064d7a03c82f9f1473ab0ee284c985df0815910160405180910390a2505050565b604051630ea5613f60e01b8152600481018290526000907f000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a6001600160a01b031690630ea5613f9060240160c060405180830381865afa1580156111ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f29190611a41565b50505060009485525060016020526040909320805462ffffff909416600160301b0262ffffff60301b19909416939093179092555050565b341561156f5760008061123d8334611ab6565b905080156112cd5760405133908290600081818185875af1925050503d8060008114611285576040519150601f19603f3d011682016040523d82523d6000602084013e61128a565b606091505b505080925050816112cd5760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b6044820152606401610666565b6000806000806000807f000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a6001600160a01b0316638639415b8b8b6040518363ffffffff1660e01b815260040161132d929190918252602082015260400190565b60c060405180830381865afa15801561134a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136e9190611ac9565b9550955095509550955095506000861115611420576040516001600160a01b038616908790600081818185875af1925050503d80600081146113cc576040519150601f19603f3d011682016040523d82523d6000602084013e6113d1565b606091505b505080985050876114205760405162461bcd60e51b8152602060048201526019602482015278105c9d08109b1bd8dadcc81c185e5b595b9d0819985a5b1959603a1b6044820152606401610666565b83156114bf576040516001600160a01b038416908590600081818185875af1925050503d806000811461146f576040519150601f19603f3d011682016040523d82523d6000602084013e611474565b606091505b505080985050876114bf5760405162461bcd60e51b8152602060048201526015602482015274105c9d1a5cdd081c185e5b595b9d0819985a5b1959605a1b6044820152606401610666565b8115611566576040516001600160a01b038216908390600081818185875af1925050503d806000811461150e576040519150601f19603f3d011682016040523d82523d6000602084013e611513565b606091505b505080985050876115665760405162461bcd60e51b815260206004820152601f60248201527f4164646974696f6e616c205061796565207061796d656e74206661696c6564006044820152606401610666565b50505050505050505b5050565b600081815b848110156115b6576115a28287878481811061159657611596611b32565b905060200201356115d7565b9150806115ae81611b48565b915050611578565b50949350505050565b6000826115cd868685611573565b1495945050505050565b60008183106115f3576000828152602084905260409020611602565b60008381526020839052604090205b90505b92915050565b6001600160a01b038116811461162057600080fd5b50565b60008083601f84011261163557600080fd5b5081356001600160401b0381111561164c57600080fd5b6020830191508360208260051b850101111561166757600080fd5b9250929050565b60008060008060006080868803121561168657600080fd5b85356116918161160b565b94506020860135935060408601356001600160401b038111156116b357600080fd5b6116bf88828901611623565b90945092505060608601356116d38161160b565b809150509295509295909350565b6000806000604084860312156116f657600080fd5b8335925060208401356001600160401b0381111561171357600080fd5b61171f86828701611623565b9497909650939450505050565b60006020828403121561173e57600080fd5b5035919050565b60008060006040848603121561175a57600080fd5b83356001600160401b0381111561177057600080fd5b61177c86828701611623565b90945092505060208401356117908161160b565b809150509250925092565b600080600080606085870312156117b157600080fd5b84356117bc8161160b565b93506020850135925060408501356001600160401b038111156117de57600080fd5b6117ea87828801611623565b95989497509550505050565b60006020828403121561180857600080fd5b81356118138161160b565b9392505050565b6000806040838503121561182d57600080fd5b82359150602083013561183f8161160b565b809150509250929050565b6000806040838503121561185d57600080fd5b50508035926020909101359150565b6000806000806060858703121561188257600080fd5b8435935060208501356001600160401b0381111561189f57600080fd5b6118ab87828801611623565b90945092505060408501356118bf8161160b565b939692955090935050565b6000815180845260005b818110156118f0576020818501810151868301820152016118d4565b506000602082860101526020601f19601f83011685010191505092915050565b841515815283602082015260806040820152600061193160808301856118ca565b905060018060a01b038316606083015295945050505050565b6000806040838503121561195d57600080fd5b82356119688161160b565b946020939093013593505050565b6000806040838503121561198957600080fd5b82359150602083013562ffffff8116811461183f57600080fd5b60208152600061160260208301846118ca565b805180151581146119c657600080fd5b919050565b6000602082840312156119dd57600080fd5b611602826119b6565b6000602082840312156119f857600080fd5b5051919050565b600060208284031215611a1157600080fd5b81516118138161160b565b6020808252600b908201526a13db9b1e48105c9d1a5cdd60aa1b604082015260600190565b60008060008060008060c08789031215611a5a57600080fd5b8651955060208701519450611a71604088016119b6565b9350611a7f606088016119b6565b925060808701519150611a9460a088016119b6565b90509295509295509295565b634e487b7160e01b600052601160045260246000fd5b8181038181111561160557611605611aa0565b60008060008060008060c08789031215611ae257600080fd5b865195506020870151611af48161160b565b604088015160608901519196509450611b0c8161160b565b608088015160a08901519194509250611b248161160b565b809150509295509295509295565b634e487b7160e01b600052603260045260246000fd5b600060018201611b5a57611b5a611aa0565b506001019056fea26469706673582212201a49e1efff7b0fc2d6e9c294eac51760b8f211bed47702c3d563dea63f83575d64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a0000000000000000000000003f4bbde879f9bb0e95aea08ff12f55e171495c8f
-----Decoded View---------------
Arg [0] : _genArt721Address (address): 0x942BC2d3e7a589FE5bd4A5C6eF9727DFd82F5C8a
Arg [1] : _minterFilter (address): 0x3F4bbde879F9BB0E95AEa08fF12F55E171495C8f
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000942bc2d3e7a589fe5bd4a5c6ef9727dfd82f5c8a
Arg [1] : 0000000000000000000000003f4bbde879f9bb0e95aea08ff12f55e171495c8f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.