Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 7 from a total of 7 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Set Minter For P... | 17380139 | 402 days ago | IN | 0 ETH | 0.00455594 | ||||
Set Minter For P... | 17374468 | 403 days ago | IN | 0 ETH | 0.00240047 | ||||
Set Minter For P... | 17374350 | 403 days ago | IN | 0 ETH | 0.00265411 | ||||
Set Minter For P... | 17373820 | 403 days ago | IN | 0 ETH | 0.00621243 | ||||
Add Approved Min... | 17345460 | 407 days ago | IN | 0 ETH | 0.00202979 | ||||
Add Approved Min... | 17345459 | 407 days ago | IN | 0 ETH | 0.00204573 | ||||
0x60c06040 | 17345451 | 407 days ago | IN | Create: MinterFilterV1 | 0 ETH | 0.03553336 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
MinterFilterV1
Compiler Version
v0.8.19+commit.7dd6d404
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/IMinterFilterV0.sol"; import "../../interfaces/0.8.x/IFilteredMinterV0.sol"; import "../../interfaces/0.8.x/IAdminACLV0.sol"; import "../../interfaces/0.8.x/IGenArt721CoreContractV3.sol"; import "../../libs/0.8.x/Bytes32Strings.sol"; import "@openzeppelin-4.5/contracts/utils/structs/EnumerableMap.sol"; pragma solidity 0.8.19; /** * @title Minter filter contract that allows filtered minters to be set * on a per-project basis. * 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 core contract's Admin * ACL contract and a project's artist. Both of these roles hold extensive * power and can modify a project's current minter. * 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 the core contract's Admin ACL * contract: * - addApprovedMinter * - removeApprovedMinter * - removeMintersForProjects * ---------------------------------------------------------------------------- * The following functions are restricted to the core contract's Admin ACL * contract or a project's artist: * - setMinterForProject * - removeMinterForProject * ---------------------------------------------------------------------------- * Additional admin and artist privileged roles may be described on minters */ contract MinterFilterV1 is IMinterFilterV0 { // add Enumerable Map methods using EnumerableMap for EnumerableMap.UintToAddressMap; // add Bytes32Strings methods using Bytes32Strings for bytes32; /// version & type of this core contract bytes32 constant MINTER_FILTER_VERSION = "v1.0.1"; function minterFilterVersion() external pure returns (string memory) { return MINTER_FILTER_VERSION.toString(); } bytes32 constant MINTER_FILTER_TYPE = "MinterFilterV1"; function minterFilterType() external pure returns (string memory) { return MINTER_FILTER_TYPE.toString(); } /// Core contract address this minter interacts with address public immutable genArt721CoreAddress; /// This contract integrates with the IV3 core contract IGenArt721CoreContractV3 private immutable genArtCoreContract; /// projectId => minter address EnumerableMap.UintToAddressMap private minterForProject; /// minter address => qty projects currently using minter mapping(address => uint256) public numProjectsUsingMinter; /// minter address => is an approved minter? mapping(address => bool) public isApprovedMinter; function _onlyNonZeroAddress(address _address) internal pure { require(_address != address(0), "Must input non-zero address"); } // function to restrict access to only AdminACL allowed calls // @dev defers which ACL contract is used to the core contract function _onlyCoreAdminACL(bytes4 _selector) internal { require(_coreAdminACLAllowed(_selector), "Only Core AdminACL allowed"); } // function to restrict access to only the artist of `_projectId`, or // AdminACL allowed calls // @dev defers which ACL contract is used to the core contract function _onlyCoreAdminACLOrArtist( uint256 _projectId, bytes4 _selector ) internal { require( msg.sender == genArtCoreContract.projectIdToArtistAddress(_projectId) || _coreAdminACLAllowed(_selector), "Only Core AdminACL or Artist" ); } function _onlyValidProjectId(uint256 _projectId) internal view { require( _projectId < genArtCoreContract.nextProjectId(), "Only existing projects" ); } function _usingApprovedMinter(address _minterAddress) internal view { require( isApprovedMinter[_minterAddress], "Only approved minters are allowed" ); } /** * @notice Initializes contract to be a Minter for `_genArt721Address`. * @param _genArt721Address Art Blocks core contract address * this contract will be a minter for. Can never be updated. */ constructor(address _genArt721Address) { _onlyNonZeroAddress(_genArt721Address); genArt721CoreAddress = _genArt721Address; genArtCoreContract = IGenArt721CoreContractV3(_genArt721Address); emit Deployed(); } /** * @notice Internal function that determines if msg.sender is allowed to * call a function on this contract. Defers to core contract's * adminACLAllowed function. */ function _coreAdminACLAllowed(bytes4 _selector) internal returns (bool) { return genArtCoreContract.adminACLAllowed( msg.sender, address(this), _selector ); } /** * @notice Approves minter `_minterAddress`. * @param _minterAddress Minter to be added as an approved minter. */ function addApprovedMinter(address _minterAddress) external { _onlyCoreAdminACL(this.addApprovedMinter.selector); _onlyNonZeroAddress(_minterAddress); isApprovedMinter[_minterAddress] = true; emit MinterApproved( _minterAddress, IFilteredMinterV0(_minterAddress).minterType() ); } /** * @notice Removes previously approved minter `_minterAddress`. * @param _minterAddress Minter to remove. */ function removeApprovedMinter(address _minterAddress) external { _onlyCoreAdminACL(this.removeApprovedMinter.selector); require(isApprovedMinter[_minterAddress], "Only approved minters"); require( numProjectsUsingMinter[_minterAddress] == 0, "Only unused minters" ); isApprovedMinter[_minterAddress] = false; emit MinterRevoked(_minterAddress); } /** * @notice Sets minter for project `_projectId` to minter * `_minterAddress`. * @param _projectId Project ID to set minter for. * @param _minterAddress Minter to be the project's minter. */ function setMinterForProject( uint256 _projectId, address _minterAddress ) external { _onlyCoreAdminACLOrArtist( _projectId, this.setMinterForProject.selector ); _usingApprovedMinter(_minterAddress); _onlyValidProjectId(_projectId); // decrement number of projects using a previous minter (bool hasPreviousMinter, address previousMinter) = minterForProject .tryGet(_projectId); if (hasPreviousMinter) { numProjectsUsingMinter[previousMinter]--; } // add new minter numProjectsUsingMinter[_minterAddress]++; minterForProject.set(_projectId, _minterAddress); emit ProjectMinterRegistered( _projectId, _minterAddress, IFilteredMinterV0(_minterAddress).minterType() ); } /** * @notice Updates project `_projectId` to have no configured minter. * @param _projectId Project ID to remove minter. * @dev requires project to have an assigned minter */ function removeMinterForProject(uint256 _projectId) external { _onlyCoreAdminACLOrArtist( _projectId, this.removeMinterForProject.selector ); _removeMinterForProject(_projectId); } /** * @notice Updates an array of project IDs to have no configured minter. * @param _projectIds Array of project IDs to remove minters for. * @dev requires all project IDs to have an assigned minter * @dev caution with respect to single tx gas limits */ function removeMintersForProjects(uint256[] calldata _projectIds) external { _onlyCoreAdminACL(this.removeMintersForProjects.selector); uint256 numProjects = _projectIds.length; for (uint256 i; i < numProjects; i++) { _removeMinterForProject(_projectIds[i]); } } /** * @notice Updates project `_projectId` to have no configured minter * (reverts tx if project does not have an assigned minter). * @param _projectId Project ID to remove minter. */ function _removeMinterForProject(uint256 _projectId) private { // remove minter for project and emit // `minterForProject.get()` reverts tx if no minter set for project numProjectsUsingMinter[minterForProject.get(_projectId)]--; minterForProject.remove(_projectId); emit ProjectMinterRemoved(_projectId); } /** * @notice Mint a token from project `_projectId` to `_to`, originally * purchased by `sender`. * @param _to The new token's owner. * @param _projectId Project ID to mint a new token on. * @param sender Address purchasing a new token. * @return _tokenId Token ID of minted token * @dev reverts w/nonexistent key error when project has no assigned minter */ function mint( address _to, uint256 _projectId, address sender ) external returns (uint256 _tokenId) { // CHECKS // minter is the project's minter require( msg.sender == minterForProject.get(_projectId), "Only assigned minter" ); // EFFECTS uint256 tokenId = genArtCoreContract.mint_Ecf(_to, _projectId, sender); return tokenId; } /** * @notice Gets the assigned minter for project `_projectId`. * @param _projectId Project ID to query. * @return address Minter address assigned to project `_projectId` * @dev requires project to have an assigned minter */ function getMinterForProject( uint256 _projectId ) external view returns (address) { _onlyValidProjectId(_projectId); (bool _hasMinter, address _currentMinter) = minterForProject.tryGet( _projectId ); require(_hasMinter, "No minter assigned"); return _currentMinter; } /** * @notice Queries if project `_projectId` has an assigned minter. * @param _projectId Project ID to query. * @return bool true if project has an assigned minter, else false */ function projectHasMinter(uint256 _projectId) external view returns (bool) { _onlyValidProjectId(_projectId); (bool _hasMinter, ) = minterForProject.tryGet(_projectId); return _hasMinter; } /** * @notice Gets quantity of projects that have assigned minters. * @return uint256 quantity of projects that have assigned minters */ function getNumProjectsWithMinters() external view returns (uint256) { return minterForProject.length(); } /** * @notice Get project ID and minter address at index `_index` of * enumerable map. * @param _index enumerable map index to query. * @return projectId project ID at index `_index` * @return minterAddress minter address for project at index `_index` * @return minterType minter type of minter at minterAddress * @dev index must be < quantity of projects that have assigned minters */ function getProjectAndMinterInfoAt( uint256 _index ) external view returns ( uint256 projectId, address minterAddress, string memory minterType ) { (projectId, minterAddress) = minterForProject.at(_index); minterType = IFilteredMinterV0(minterAddress).minterType(); return (projectId, minterAddress, minterType); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableMap.sol) pragma solidity ^0.8.0; import "./EnumerableSet.sol"; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { using EnumerableSet for EnumerableSet.Bytes32Set; // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct Map { // Storage of keys EnumerableSet.Bytes32Set _keys; mapping(bytes32 => bytes32) _values; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set( Map storage map, bytes32 key, bytes32 value ) private returns (bool) { map._values[key] = value; return map._keys.add(key); } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { delete map._values[key]; return map._keys.remove(key); } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._keys.contains(key); } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._keys.length(); } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { bytes32 key = map._keys.at(index); return (key, map._values[key]); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { bytes32 value = map._values[key]; if (value == bytes32(0)) { return (_contains(map, key), bytes32(0)); } else { return (true, value); } } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || _contains(map, key), "EnumerableMap: nonexistent key"); return value; } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {_tryGet}. */ function _get( Map storage map, bytes32 key, string memory errorMessage ) private view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || _contains(map, key), errorMessage); return value; } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( UintToAddressMap storage map, uint256 key, address value ) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( UintToAddressMap storage map, uint256 key, string memory errorMessage ) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } }
// 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. 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 ); }
// 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"; /** * @title This interface is intended to house interface items that are common * across all GenArt721CoreContractV3 flagship and derivative implementations. * This interface extends the IManifold royalty interface in order to * add support the Royalty Registry by default. * @author Art Blocks Inc. */ interface IGenArt721CoreContractV3_Base 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 startingProjectId() external view returns (uint256); // 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); function projectIdToSecondaryMarketRoyaltyPercentage( uint256 _projectId ) external view returns (uint256); function projectURIInfo( uint256 _projectId ) external view returns (string memory projectBaseURI); // @dev new function in V3 function projectStateData( uint256 _projectId ) external view returns ( uint256 invocations, uint256 maxInvocations, bool active, bool paused, uint256 completedTimestamp, bool locked ); function projectDetails( uint256 _projectId ) external view returns ( string memory projectName, string memory artist, string memory description, string memory website, string memory license ); function projectScriptDetails( uint256 _projectId ) external view returns ( string memory scriptTypeAndVersion, string memory aspectRatio, uint256 scriptCount ); function projectScriptByIndex( uint256 _projectId, uint256 _index ) external view returns (string memory); function tokenIdToHash(uint256 _tokenId) external view returns (bytes32); // 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); }
// SPDX-License-Identifier: LGPL-3.0-only // Created By: Art Blocks Inc. pragma solidity ^0.8.0; import "./IAdminACLV0.sol"; import "./IGenArt721CoreContractV3_Base.sol"; /** * @title This interface extends IGenArt721CoreContractV3_Base with functions * that are part of the Art Blocks Flagship core contract. * @author Art Blocks Inc. */ // This interface extends IGenArt721CoreContractV3_Base with functions that are // in part of the Art Blocks Flagship core contract. interface IGenArt721CoreContractV3 is IGenArt721CoreContractV3_Base { // @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 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); /** * @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: 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 IMinterFilterV0 { /** * @notice Emitted when contract is deployed to notify indexing services * of the new contract deployment. */ event Deployed(); /** * @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: LGPL-3.0-only // Created By: Art Blocks Inc. // Inspired by: https://ethereum.stackexchange.com/a/123950/103422 pragma solidity ^0.8.0; /** * @dev Operations on bytes32 data type, dealing with conversion to string. */ library Bytes32Strings { /** * @dev Intended to convert a `bytes32`-encoded string literal to `string`. * Trims zero padding to arrive at original string literal. */ function toString( bytes32 source ) internal pure returns (string memory result) { uint8 length = 0; while (source[length] != 0 && length < 32) { length++; } assembly { // free memory pointer result := mload(0x40) // update free memory pointer to new "memory end" // (offset is 64-bytes: 32 for length, 32 for data) mstore(0x40, add(result, 0x40)) // store length in first 32-byte memory slot mstore(result, length) // write actual data in second 32-byte memory slot mstore(add(result, 0x20), source) } } /** * @dev Intended to check if a `bytes32`-encoded string contains a given * character with UTF-8 character code `utf8CharCode exactly `targetQty` * times. Does not support searching for multi-byte characters, only * characters with UTF-8 character codes < 0x80. */ function containsExactCharacterQty( bytes32 source, uint8 utf8CharCode, uint8 targetQty ) internal pure returns (bool) { uint8 _occurrences = 0; uint8 i; for (i = 0; i < 32; ) { uint8 _charCode = uint8(source[i]); // if not a null byte, or a multi-byte UTF-8 character, check match if (_charCode != 0 && _charCode < 0x80) { if (_charCode == utf8CharCode) { unchecked { // no risk of overflow since max 32 iterations < max uin8=255 ++_occurrences; } } } unchecked { // no risk of overflow since max 32 iterations < max uin8=255 ++i; } } return _occurrences == targetQty; } }
{ "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"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"Deployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minterAddress","type":"address"},{"indexed":false,"internalType":"string","name":"_minterType","type":"string"}],"name":"MinterApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_minterAddress","type":"address"}],"name":"MinterRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_minterAddress","type":"address"},{"indexed":false,"internalType":"string","name":"_minterType","type":"string"}],"name":"ProjectMinterRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"ProjectMinterRemoved","type":"event"},{"inputs":[{"internalType":"address","name":"_minterAddress","type":"address"}],"name":"addApprovedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"genArt721CoreAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"getMinterForProject","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumProjectsWithMinters","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getProjectAndMinterInfoAt","outputs":[{"internalType":"uint256","name":"projectId","type":"uint256"},{"internalType":"address","name":"minterAddress","type":"address"},{"internalType":"string","name":"minterType","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isApprovedMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address","name":"sender","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minterFilterType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"minterFilterVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numProjectsUsingMinter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"projectHasMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minterAddress","type":"address"}],"name":"removeApprovedMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"}],"name":"removeMinterForProject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_projectIds","type":"uint256[]"}],"name":"removeMintersForProjects","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_projectId","type":"uint256"},{"internalType":"address","name":"_minterAddress","type":"address"}],"name":"setMinterForProject","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c060405234801561001057600080fd5b506040516114ef3803806114ef83398101604081905261002f916100d6565b61003881610079565b6001600160a01b038116608081905260a0526040517f3fad920548ed9f22deb8333b4cc1e4f9bc36666a1c2aa30ad59a0a3bb9dcbb9290600090a150610106565b6001600160a01b0381166100d35760405162461bcd60e51b815260206004820152601b60248201527f4d75737420696e707574206e6f6e2d7a65726f20616464726573730000000000604482015260640160405180910390fd5b50565b6000602082840312156100e857600080fd5b81516001600160a01b03811681146100ff57600080fd5b9392505050565b60805160a0516113af610140600039600081816102e7015281816109b701528181610a9e0152610d1f0152600061016d01526113af6000f3fe608060405234801561001057600080fd5b50600436106100c55760003560e01c80630d4d1513146100ca57806320f2ccb7146100f057806326df17b5146101055780633a3d146f146101255780637136b93e14610158578063718284221461016057806392a10f8314610168578063a409177e146101a7578063b34c5c84146101bc578063bcc0fdf1146101cf578063bee4d106146101e2578063c47d50f5146101f5578063e7300db914610208578063faf0d7451461022a578063ff2505f01461023d575b600080fd5b6100dd6100d8366004611012565b610250565b6040519081526020015b60405180910390f35b6100f861035d565b6040516100e791906110a4565b6100dd6101133660046110b7565b60036020526000908152604090205481565b6101486101333660046110b7565b60046020526000908152604090205460ff1681565b60405190151581526020016100e7565b6100f861037e565b6100dd610392565b61018f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100e7565b6101ba6101b53660046110d4565b61039e565b005b6101ba6101ca366004611148565b6103f3565b61018f6101dd366004611148565b610410565b6101ba6101f03660046110b7565b610475565b610148610203366004611148565b61054b565b61021b610216366004611148565b61056a565b6040516100e793929190611161565b6101ba61023836600461118b565b6105ef565b6101ba61024b3660046110b7565b610737565b600061025c818461084f565b6001600160a01b0316336001600160a01b0316146102b85760405162461bcd60e51b815260206004820152601460248201527327b7363c9030b9b9b4b3b732b21036b4b73a32b960611b60448201526064015b60405180910390fd5b604051615de560e01b81526001600160a01b0385811660048301526024820185905283811660448301526000917f000000000000000000000000000000000000000000000000000000000000000090911690615de5906064016020604051808303816000875af1158015610330573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035491906111bb565b95945050505050565b60606103796d4d696e74657246696c746572563160901b610864565b905090565b60606103796576312e302e3160d01b610864565b600061037960006108cf565b6103ae6352048bbf60e11b6108da565b8060005b818110156103ed576103db8484838181106103cf576103cf6111d4565b9050602002013561092c565b806103e581611200565b9150506103b2565b50505050565b61040481632cd3172160e21b6109a1565b61040d8161092c565b50565b600061041b82610a9c565b6000806104288185610b65565b915091508161046e5760405162461bcd60e51b8152602060048201526012602482015271139bc81b5a5b9d195c88185cdcda59db995960721b60448201526064016102af565b9392505050565b610485635f72688360e11b6108da565b61048e81610b83565b6001600160a01b0381166000818152600460208190526040808320805460ff191660011790558051633a747a2b60e21b815290517f1ac09d1079d96f19b763467642c3c3b4e36b56222414f4a4a50f26c7011147bb93859363e9d1e8ac938082019391908290030181865afa15801561050b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610533919081019061122f565b60405161054091906110a4565b60405180910390a250565b600061055682610a9c565b60006105628184610b65565b509392505050565b60008060606105798285610bd7565b8093508194505050816001600160a01b031663e9d1e8ac6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156105bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105e7919081019061122f565b929491935050565b6106008263faf0d74560e01b6109a1565b61060981610be6565b61061282610a9c565b60008061061f8185610b65565b915091508115610653576001600160a01b038116600090815260036020526040812080549161064d836112db565b91905055505b6001600160a01b038316600090815260036020526040812080549161067783611200565b90915550610689905060008585610c58565b50826001600160a01b0316847f21fd9bfc68d8bc4b740ebf996aa9c255d1e6bb474f81dc2ad577d5d3c5a5e1e0856001600160a01b031663e9d1e8ac6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156106f4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261071c919081019061122f565b60405161072991906110a4565b60405180910390a350505050565b61074a6001620dafa160e41b03196108da565b6001600160a01b03811660009081526004602052604090205460ff166107aa5760405162461bcd60e51b81526020600482015260156024820152744f6e6c7920617070726f766564206d696e7465727360581b60448201526064016102af565b6001600160a01b038116600090815260036020526040902054156108065760405162461bcd60e51b81526020600482015260136024820152724f6e6c7920756e75736564206d696e7465727360681b60448201526064016102af565b6001600160a01b038116600081815260046020526040808220805460ff19169055517f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe819190a250565b600061085b8383610c76565b90505b92915050565b606060005b828160ff166020811061087e5761087e6111d4565b1a60f81b6001600160f81b0319161580159061089d575060208160ff16105b156108b457806108ac816112f2565b915050610869565b60405191506040820160405280825282602083015250919050565b600061085e82610ce6565b6108e381610cf1565b61040d5760405162461bcd60e51b815260206004820152601a60248201527913db9b1e4810dbdc994810591b5a5b9050d308185b1b1bddd95960321b60448201526064016102af565b6003600061093a818461084f565b6001600160a01b0316815260208101919091526040016000908120805491610961836112db565b909155506109729050600082610d94565b5060405181907f15267d34078ead35bc0303f6cdd08f99b837bdfcd7fab97fca4c58f3d85d760590600090a250565b60405163a47d29cb60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a47d29cb90602401602060405180830381865afa158015610a06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2a9190611311565b6001600160a01b0316336001600160a01b03161480610a4d5750610a4d81610cf1565b610a985760405162461bcd60e51b815260206004820152601c60248201527b13db9b1e4810dbdc994810591b5a5b9050d3081bdc88105c9d1a5cdd60221b60448201526064016102af565b5050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e935b7b16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1e91906111bb565b811061040d5760405162461bcd60e51b81526020600482015260166024820152754f6e6c79206578697374696e672070726f6a6563747360501b60448201526064016102af565b6000808080610b748686610da0565b909450925050505b9250929050565b6001600160a01b03811661040d5760405162461bcd60e51b815260206004820152601b60248201527a4d75737420696e707574206e6f6e2d7a65726f206164647265737360281b60448201526064016102af565b6000808080610b748686610dda565b6001600160a01b03811660009081526004602052604090205460ff1661040d5760405162461bcd60e51b815260206004820152602160248201527f4f6e6c7920617070726f766564206d696e746572732061726520616c6c6f77656044820152601960fa1b60648201526084016102af565b6000610c6e84846001600160a01b038516610e05565b949350505050565b600081815260028301602052604081205480151580610c9a5750610c9a8484610e22565b61085b5760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b6579000060448201526064016102af565b600061085e82610e2e565b60405163230448b160e01b81523360048201523060248201526001600160e01b0319821660448201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063230448b1906064016020604051808303816000875af1158015610d70573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085e919061132e565b600061085b8383610e38565b6000818152600283016020526040812054819080610dcf57610dc28585610e22565b925060009150610b7c9050565b600192509050610b7c565b60008080610de88585610e55565b600081815260029690960160205260409095205494959350505050565b60008281526002840160205260408120829055610c6e8484610e61565b600061085b8383610e6d565b600061085e825490565b6000818152600283016020526040812081905561085b8383610e85565b600061085b8383610e91565b600061085b8383610ebb565b6000818152600183016020526040812054151561085b565b600061085b8383610f0a565b6000826000018281548110610ea857610ea86111d4565b9060005260206000200154905092915050565b6000818152600183016020526040812054610f025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561085e565b50600061085e565b60008181526001830160205260408120548015610ff3576000610f2e600183611350565b8554909150600090610f4290600190611350565b9050818114610fa7576000866000018281548110610f6257610f626111d4565b9060005260206000200154905080876000018481548110610f8557610f856111d4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610fb857610fb8611363565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061085e565b600091505061085e565b6001600160a01b038116811461040d57600080fd5b60008060006060848603121561102757600080fd5b833561103281610ffd565b925060208401359150604084013561104981610ffd565b809150509250925092565b60005b8381101561106f578181015183820152602001611057565b50506000910152565b60008151808452611090816020860160208601611054565b601f01601f19169290920160200192915050565b60208152600061085b6020830184611078565b6000602082840312156110c957600080fd5b813561085b81610ffd565b600080602083850312156110e757600080fd5b82356001600160401b03808211156110fe57600080fd5b818501915085601f83011261111257600080fd5b81358181111561112157600080fd5b8660208260051b850101111561113657600080fd5b60209290920196919550909350505050565b60006020828403121561115a57600080fd5b5035919050565b8381526001600160a01b038316602082015260606040820181905260009061035490830184611078565b6000806040838503121561119e57600080fd5b8235915060208301356111b081610ffd565b809150509250929050565b6000602082840312156111cd57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611212576112126111ea565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561124157600080fd5b81516001600160401b038082111561125857600080fd5b818401915084601f83011261126c57600080fd5b81518181111561127e5761127e611219565b604051601f8201601f19908116603f011681019083821181831017156112a6576112a6611219565b816040528281528760208487010111156112bf57600080fd5b6112d0836020830160208801611054565b979650505050505050565b6000816112ea576112ea6111ea565b506000190190565b600060ff821660ff8103611308576113086111ea565b60010192915050565b60006020828403121561132357600080fd5b815161085b81610ffd565b60006020828403121561134057600080fd5b8151801515811461085b57600080fd5b8181038181111561085e5761085e6111ea565b634e487b7160e01b600052603160045260246000fdfea26469706673582212207d47aa664d37862a23a5c623bcf2eda07adbcb9d651917d253cff93edf91a35b64736f6c634300081300330000000000000000000000009209070e1447018638e15b73dbee46bf085fcf5f
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100c55760003560e01c80630d4d1513146100ca57806320f2ccb7146100f057806326df17b5146101055780633a3d146f146101255780637136b93e14610158578063718284221461016057806392a10f8314610168578063a409177e146101a7578063b34c5c84146101bc578063bcc0fdf1146101cf578063bee4d106146101e2578063c47d50f5146101f5578063e7300db914610208578063faf0d7451461022a578063ff2505f01461023d575b600080fd5b6100dd6100d8366004611012565b610250565b6040519081526020015b60405180910390f35b6100f861035d565b6040516100e791906110a4565b6100dd6101133660046110b7565b60036020526000908152604090205481565b6101486101333660046110b7565b60046020526000908152604090205460ff1681565b60405190151581526020016100e7565b6100f861037e565b6100dd610392565b61018f7f0000000000000000000000009209070e1447018638e15b73dbee46bf085fcf5f81565b6040516001600160a01b0390911681526020016100e7565b6101ba6101b53660046110d4565b61039e565b005b6101ba6101ca366004611148565b6103f3565b61018f6101dd366004611148565b610410565b6101ba6101f03660046110b7565b610475565b610148610203366004611148565b61054b565b61021b610216366004611148565b61056a565b6040516100e793929190611161565b6101ba61023836600461118b565b6105ef565b6101ba61024b3660046110b7565b610737565b600061025c818461084f565b6001600160a01b0316336001600160a01b0316146102b85760405162461bcd60e51b815260206004820152601460248201527327b7363c9030b9b9b4b3b732b21036b4b73a32b960611b60448201526064015b60405180910390fd5b604051615de560e01b81526001600160a01b0385811660048301526024820185905283811660448301526000917f0000000000000000000000009209070e1447018638e15b73dbee46bf085fcf5f90911690615de5906064016020604051808303816000875af1158015610330573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035491906111bb565b95945050505050565b60606103796d4d696e74657246696c746572563160901b610864565b905090565b60606103796576312e302e3160d01b610864565b600061037960006108cf565b6103ae6352048bbf60e11b6108da565b8060005b818110156103ed576103db8484838181106103cf576103cf6111d4565b9050602002013561092c565b806103e581611200565b9150506103b2565b50505050565b61040481632cd3172160e21b6109a1565b61040d8161092c565b50565b600061041b82610a9c565b6000806104288185610b65565b915091508161046e5760405162461bcd60e51b8152602060048201526012602482015271139bc81b5a5b9d195c88185cdcda59db995960721b60448201526064016102af565b9392505050565b610485635f72688360e11b6108da565b61048e81610b83565b6001600160a01b0381166000818152600460208190526040808320805460ff191660011790558051633a747a2b60e21b815290517f1ac09d1079d96f19b763467642c3c3b4e36b56222414f4a4a50f26c7011147bb93859363e9d1e8ac938082019391908290030181865afa15801561050b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610533919081019061122f565b60405161054091906110a4565b60405180910390a250565b600061055682610a9c565b60006105628184610b65565b509392505050565b60008060606105798285610bd7565b8093508194505050816001600160a01b031663e9d1e8ac6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156105bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105e7919081019061122f565b929491935050565b6106008263faf0d74560e01b6109a1565b61060981610be6565b61061282610a9c565b60008061061f8185610b65565b915091508115610653576001600160a01b038116600090815260036020526040812080549161064d836112db565b91905055505b6001600160a01b038316600090815260036020526040812080549161067783611200565b90915550610689905060008585610c58565b50826001600160a01b0316847f21fd9bfc68d8bc4b740ebf996aa9c255d1e6bb474f81dc2ad577d5d3c5a5e1e0856001600160a01b031663e9d1e8ac6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156106f4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261071c919081019061122f565b60405161072991906110a4565b60405180910390a350505050565b61074a6001620dafa160e41b03196108da565b6001600160a01b03811660009081526004602052604090205460ff166107aa5760405162461bcd60e51b81526020600482015260156024820152744f6e6c7920617070726f766564206d696e7465727360581b60448201526064016102af565b6001600160a01b038116600090815260036020526040902054156108065760405162461bcd60e51b81526020600482015260136024820152724f6e6c7920756e75736564206d696e7465727360681b60448201526064016102af565b6001600160a01b038116600081815260046020526040808220805460ff19169055517f44f4322f8daa225d5f4877ad0f7d3dfba248a774396f3ca99405ed40a044fe819190a250565b600061085b8383610c76565b90505b92915050565b606060005b828160ff166020811061087e5761087e6111d4565b1a60f81b6001600160f81b0319161580159061089d575060208160ff16105b156108b457806108ac816112f2565b915050610869565b60405191506040820160405280825282602083015250919050565b600061085e82610ce6565b6108e381610cf1565b61040d5760405162461bcd60e51b815260206004820152601a60248201527913db9b1e4810dbdc994810591b5a5b9050d308185b1b1bddd95960321b60448201526064016102af565b6003600061093a818461084f565b6001600160a01b0316815260208101919091526040016000908120805491610961836112db565b909155506109729050600082610d94565b5060405181907f15267d34078ead35bc0303f6cdd08f99b837bdfcd7fab97fca4c58f3d85d760590600090a250565b60405163a47d29cb60e01b8152600481018390527f0000000000000000000000009209070e1447018638e15b73dbee46bf085fcf5f6001600160a01b03169063a47d29cb90602401602060405180830381865afa158015610a06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2a9190611311565b6001600160a01b0316336001600160a01b03161480610a4d5750610a4d81610cf1565b610a985760405162461bcd60e51b815260206004820152601c60248201527b13db9b1e4810dbdc994810591b5a5b9050d3081bdc88105c9d1a5cdd60221b60448201526064016102af565b5050565b7f0000000000000000000000009209070e1447018638e15b73dbee46bf085fcf5f6001600160a01b031663e935b7b16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610afa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1e91906111bb565b811061040d5760405162461bcd60e51b81526020600482015260166024820152754f6e6c79206578697374696e672070726f6a6563747360501b60448201526064016102af565b6000808080610b748686610da0565b909450925050505b9250929050565b6001600160a01b03811661040d5760405162461bcd60e51b815260206004820152601b60248201527a4d75737420696e707574206e6f6e2d7a65726f206164647265737360281b60448201526064016102af565b6000808080610b748686610dda565b6001600160a01b03811660009081526004602052604090205460ff1661040d5760405162461bcd60e51b815260206004820152602160248201527f4f6e6c7920617070726f766564206d696e746572732061726520616c6c6f77656044820152601960fa1b60648201526084016102af565b6000610c6e84846001600160a01b038516610e05565b949350505050565b600081815260028301602052604081205480151580610c9a5750610c9a8484610e22565b61085b5760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b6579000060448201526064016102af565b600061085e82610e2e565b60405163230448b160e01b81523360048201523060248201526001600160e01b0319821660448201526000907f0000000000000000000000009209070e1447018638e15b73dbee46bf085fcf5f6001600160a01b03169063230448b1906064016020604051808303816000875af1158015610d70573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085e919061132e565b600061085b8383610e38565b6000818152600283016020526040812054819080610dcf57610dc28585610e22565b925060009150610b7c9050565b600192509050610b7c565b60008080610de88585610e55565b600081815260029690960160205260409095205494959350505050565b60008281526002840160205260408120829055610c6e8484610e61565b600061085b8383610e6d565b600061085e825490565b6000818152600283016020526040812081905561085b8383610e85565b600061085b8383610e91565b600061085b8383610ebb565b6000818152600183016020526040812054151561085b565b600061085b8383610f0a565b6000826000018281548110610ea857610ea86111d4565b9060005260206000200154905092915050565b6000818152600183016020526040812054610f025750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561085e565b50600061085e565b60008181526001830160205260408120548015610ff3576000610f2e600183611350565b8554909150600090610f4290600190611350565b9050818114610fa7576000866000018281548110610f6257610f626111d4565b9060005260206000200154905080876000018481548110610f8557610f856111d4565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610fb857610fb8611363565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061085e565b600091505061085e565b6001600160a01b038116811461040d57600080fd5b60008060006060848603121561102757600080fd5b833561103281610ffd565b925060208401359150604084013561104981610ffd565b809150509250925092565b60005b8381101561106f578181015183820152602001611057565b50506000910152565b60008151808452611090816020860160208601611054565b601f01601f19169290920160200192915050565b60208152600061085b6020830184611078565b6000602082840312156110c957600080fd5b813561085b81610ffd565b600080602083850312156110e757600080fd5b82356001600160401b03808211156110fe57600080fd5b818501915085601f83011261111257600080fd5b81358181111561112157600080fd5b8660208260051b850101111561113657600080fd5b60209290920196919550909350505050565b60006020828403121561115a57600080fd5b5035919050565b8381526001600160a01b038316602082015260606040820181905260009061035490830184611078565b6000806040838503121561119e57600080fd5b8235915060208301356111b081610ffd565b809150509250929050565b6000602082840312156111cd57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611212576112126111ea565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561124157600080fd5b81516001600160401b038082111561125857600080fd5b818401915084601f83011261126c57600080fd5b81518181111561127e5761127e611219565b604051601f8201601f19908116603f011681019083821181831017156112a6576112a6611219565b816040528281528760208487010111156112bf57600080fd5b6112d0836020830160208801611054565b979650505050505050565b6000816112ea576112ea6111ea565b506000190190565b600060ff821660ff8103611308576113086111ea565b60010192915050565b60006020828403121561132357600080fd5b815161085b81610ffd565b60006020828403121561134057600080fd5b8151801515811461085b57600080fd5b8181038181111561085e5761085e6111ea565b634e487b7160e01b600052603160045260246000fdfea26469706673582212207d47aa664d37862a23a5c623bcf2eda07adbcb9d651917d253cff93edf91a35b64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009209070e1447018638e15b73dbee46bf085fcf5f
-----Decoded View---------------
Arg [0] : _genArt721Address (address): 0x9209070E1447018638e15b73Dbee46Bf085fcf5f
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000009209070e1447018638e15b73dbee46bf085fcf5f
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.