Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer Ownersh... | 19985431 | 651 days ago | IN | 0 ETH | 0.00053756 |
Latest 3 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x3d602d80 | 20086118 | 636 days ago | Contract Creation | 0 ETH | |||
| 0x60c06040 | 20086118 | 636 days ago | Contract Creation | 0 ETH | |||
| 0x60e06040 | 19985297 | 651 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
EngineFactoryV0
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 10 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: LGPL-3.0-only
// Created By: Art Blocks Inc.
// @dev fixed to specific solidity version for clarity and for more clear
// source code verification purposes.
pragma solidity 0.8.22;
import {AdminACLV0} from "../../AdminACLV0.sol";
import {IGenArt721CoreContractV3_Engine, EngineConfiguration} from "../../interfaces/v0.8.x/IGenArt721CoreContractV3_Engine.sol";
import {ICoreRegistryV1} from "../../interfaces/v0.8.x/ICoreRegistryV1.sol";
import {IEngineFactoryV0} from "../../interfaces/v0.8.x/IEngineFactoryV0.sol";
import {IAdminACLV0_Extended} from "../../interfaces/v0.8.x/IAdminACLV0_Extended.sol";
import "@openzeppelin-5.0/contracts/access/Ownable.sol";
import {Clones} from "@openzeppelin-5.0/contracts/proxy/Clones.sol";
import {IERC20} from "@openzeppelin-5.0/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin-5.0/contracts/token/ERC20/utils/SafeERC20.sol";
import {Create2} from "@openzeppelin-5.0/contracts/utils/Create2.sol";
/**
* @title EngineFactoryV0
* @author Art Blocks Inc.
* @notice Factory contract for creating new Engine and Engine Flex Core contracts.
* @dev This contract is deployed once, and then used to create new Engine and Engine
* Flex Core contracts. The contract may be abandoned once it is no longer needed.
* Once abandoned, the contract can no longer be used to create new Engine and Engine
* Flex Core contracts.
* The contract is initialized with a required contract type.
* The contract is initialized with an Engine and Engine Flex implementation contract, which is cloned
* when creating new Engine and Engine Flex Core contracts.
*/
contract EngineFactoryV0 is Ownable, IEngineFactoryV0 {
// public type
bytes32 public constant type_ = "EngineFactoryV0";
// base URI host for all Engine contracts on this network/chainID
string public defaultBaseURIHost;
/**
* The implementation contract that is cloned when creating new Engine
* contracts.
*/
address public immutable engineImplementation;
/**
* The implementation contract that is cloned when creating new Engine
* Flex contracts.
*/
address public immutable engineFlexImplementation;
// Address of core registry contract.
address public immutable coreRegistry;
/// version and type of Engine implementation contract
string public engineCoreType;
string public engineCoreVersion;
/// version and type of Engine Flex implementation contract
string public flexCoreType;
string public flexCoreVersion;
/**
* Indicates whether the contract is abandoned.
* Once abandoned, the contract can no longer be used to create new Engine
* and Engine Flex contracts.
*/
bool public isAbandoned; // default false
// pseudorandom salt nonce to prevent collisions for multiple contract deployments in single block
uint256 private _pseudorandomSaltNonce;
/**
* Represents a generic call operation.
*/
struct Call {
address to;
bytes data;
}
/**
* @notice validates and assigns immutable configuration variables and
* sets state variables
* @param engineImplementation_ address of the Engine
* implementation contract
* @param engineFlexImplementation_ address of the Engine Flex
* implementation contract
* @param coreRegistry_ address of the core registry contract
* @param owner_ address of the initial owner
* @param defaultBaseURIHost_ default base URI prefix for all Engine contracts,
* e.g. "https://token.artblocks.io/" for mainnet, "https://token.arbitrum.artblocks.io/" for arbitrum, etc.
*/
constructor(
address engineImplementation_,
address engineFlexImplementation_,
address coreRegistry_,
address owner_,
string memory defaultBaseURIHost_
) Ownable(owner_) {
_onlyNonZeroAddress(engineImplementation_);
_onlyNonZeroAddress(engineFlexImplementation_);
_onlyNonZeroAddress(coreRegistry_);
_onlyNonZeroAddress(owner_);
defaultBaseURIHost = defaultBaseURIHost_;
engineImplementation = engineImplementation_;
engineFlexImplementation = engineFlexImplementation_;
coreRegistry = coreRegistry_;
engineCoreType = IGenArt721CoreContractV3_Engine(engineImplementation)
.coreType();
engineCoreVersion = IGenArt721CoreContractV3_Engine(
engineImplementation
).coreVersion();
flexCoreType = IGenArt721CoreContractV3_Engine(engineFlexImplementation)
.coreType();
flexCoreVersion = IGenArt721CoreContractV3_Engine(
engineFlexImplementation
).coreVersion();
// emit event
emit Deployed({
engineImplementation: engineImplementation_,
engineFlexImplementation: engineFlexImplementation_,
type_: type_
});
}
/**
* @notice Creates a new Engine or Engine Flex contract with the provided
* `engineConfiguration`, depending on the `engineCoreContractType`.
* Reverts if invalid configuration is provided, or if in an invalid deployment
* state (e.g. if the contract is abandoned or does not own the core registry).
* @param engineCoreContractType Type of Engine Core contract.
* @param engineConfiguration EngineConfiguration data to configure the
* contract with.
* @param adminACLContract Address of admin access control contract, to be
* set as contract owner. A new contract will be deployed if address is null.
* @param salt Salt used to deterministically deploy the clone. If null, a
* pseudorandom salt is generated.
* @return engineContract The address of the newly created Engine or Engine Flex
* contract. The address is also emitted in the `EngineContractCreated` event.
*/
function createEngineContract(
IEngineFactoryV0.EngineCoreType engineCoreContractType,
EngineConfiguration calldata engineConfiguration,
address adminACLContract,
bytes32 salt
) external onlyOwner returns (address engineContract) {
require(!isAbandoned, "factory is abandoned");
// validate engine contract configuration
_onlyNonZeroAddress(engineConfiguration.renderProviderAddress);
_onlyNonZeroAddress(engineConfiguration.randomizerContract);
// check if salt is empty and generate a pseudorandom one if so
if (salt == bytes32(0)) {
salt = _generatePseudorandomSalt();
}
if (adminACLContract == address(0)) {
_onlyNonZeroAddress(engineConfiguration.newSuperAdminAddress);
// deploy new AdminACLV0 contract and update super admin
adminACLContract = Create2.deploy({
amount: 0,
salt: _generatePseudorandomSalt(),
bytecode: type(AdminACLV0).creationCode
});
address[] memory tmpEmptyArray = new address[](0);
IAdminACLV0_Extended(adminACLContract).changeSuperAdmin(
engineConfiguration.newSuperAdminAddress,
tmpEmptyArray
);
} else {
// Use existing Admin ACL Contract, newSuperAdminAddress should not be populated
require(
engineConfiguration.newSuperAdminAddress == address(0),
"AdminACL already exists"
);
}
address implementation = engineCoreContractType ==
IEngineFactoryV0.EngineCoreType.Engine
? engineImplementation
: engineFlexImplementation;
engineContract = Clones.cloneDeterministic({
implementation: implementation,
salt: salt
});
IGenArt721CoreContractV3_Engine(engineContract).initialize({
engineConfiguration: engineConfiguration,
adminACLContract_: adminACLContract,
defaultBaseURIHost: defaultBaseURIHost
});
(
string memory coreContractType,
string memory coreContractVersion
) = engineCoreContractType == IEngineFactoryV0.EngineCoreType.Engine
? (engineCoreType, engineCoreVersion)
: (flexCoreType, flexCoreVersion);
// register the new Engine contract
ICoreRegistryV1(coreRegistry).registerContract(
engineContract,
_stringToBytes32(coreContractVersion),
_stringToBytes32(coreContractType)
);
// emit event
emit EngineContractCreated(engineContract);
}
/**
* @notice Calls transferOwnership on the core registry.
* Useful for updating the owner of the core registry contract.
* @param _owner address of the new owner
*/
function transferCoreRegistryOwnership(address _owner) external onlyOwner {
Ownable(coreRegistry).transferOwnership(_owner);
}
/**
* @notice Registers multiple contracts with the core registry.
* @param contractAddresses An array of contract addresses to register.
* @param coreVersions An array of versions corresponding to the contract addresses.
* @param coreTypes An array of types corresponding to the contract addresses.
*/
function registerMultipleContracts(
address[] calldata contractAddresses,
bytes32[] calldata coreVersions,
bytes32[] calldata coreTypes
) external onlyOwner {
// @dev pure forwarding - input validation is done in the core registry
ICoreRegistryV1(coreRegistry).registerContracts({
contractAddresses: contractAddresses,
coreVersions: coreVersions,
coreTypes: coreTypes
});
}
/**
* @notice Unregisters multiple contracts from the core registry.
* @param contractAddresses An array of contract addresses to unregister.
*/
function unregisterMultipleContracts(
address[] calldata contractAddresses
) external onlyOwner {
// @dev pure forwarding - input validation is done in the core registry
ICoreRegistryV1(coreRegistry).unregisterContracts(contractAddresses);
}
/**
* @notice Abandons the contract, preventing it from being used to create
* new Engine and Engine Flex contracts.
* Only callable by the owner, and only once; reverts otherwise.
*/
function abandon() external onlyOwner {
require(!isAbandoned, "factory is abandoned");
// set isAbandoned to true
isAbandoned = true;
// emit event
emit Abandoned();
}
/**
* @dev This contract is not intended to hold funds. This function,
* `drainETH`, and `drainERC20` are implemented to prevent the loss
* of funds that might be sent to this contract inadvertently.
*/
receive() external payable {}
/**
* @notice Drains the contract's balance to the `recipient`.
* @param recipient The address to send funds to.
* Only callable by the owner.
*/
function drainETH(address payable recipient) external onlyOwner {
uint256 balance = address(this).balance;
if (balance > 0) {
(bool success, ) = recipient.call{value: balance}("");
require(success, "Payment failed");
}
}
/**
* @notice Drains the contract's balance of an input ERC20 token to
* the `recipient`.
* @param ERC20TokenAddress The address of the ERC20 token to withdraw.
* @param recipient The address to send ERC20 tokens to.
* Only callable by the owner.
*/
function drainERC20(
address ERC20TokenAddress,
address recipient
) external onlyOwner {
IERC20 token = IERC20(ERC20TokenAddress);
uint256 balance = token.balanceOf(address(this));
if (balance > 0) {
SafeERC20.safeTransfer({
token: token,
to: recipient,
value: balance
});
}
}
/**
* @notice Execute a batch of calls.
* @dev The calls are executed in order, reverting if any of them fails. Can
* only be called by the owner. It is safe to check ownership only once here
* because the owner status is only used to gate access to the function, not
* to validate each individual call. Even if ownership is transferred during
* the sequence of calls, it does not affect the execution logic or security,
* as ownership is solely used to prevent unauthorized use of this batch
* execution capability. This is particularly useful to safely interact
* with contracts or addresses that might deem this contract eligible for
* airdrops, thereby avoiding loss of funds.
* @param _calls The calls to execute
*/
function execCalls(
Call[] calldata _calls
)
external
onlyOwner
returns (uint256 blockNumber, bytes[] memory returnData)
{
blockNumber = block.number;
uint256 length = _calls.length;
returnData = new bytes[](length);
for (uint256 i = 0; i < length; ++i) {
Call calldata calli = _calls[i];
// check for existence of code at the target address
if (calli.to.code.length == 0) {
// when the call is to an EOA, the calldata must be empty.
require(calli.data.length == 0, "Invalid call data");
}
(bool success, bytes memory data) = calli.to.call(calli.data);
require(success, string(data));
returnData[i] = data;
}
}
/**
* @dev Predict the deterministic address for a new core contract of type
* `engineCoreContractType` and salt `salt`, deployed using the function
* `createEngineContract`.
* Reverts if `salt` is null, because the factory generates a pseudorandom
* salt in that case.
* @param engineCoreContractType Type of Engine Core contract.
* @param salt Salt used to deterministically deploy the clone.
*/
function predictDeterministicAddress(
IEngineFactoryV0.EngineCoreType engineCoreContractType,
bytes32 salt
) external view returns (address predicted) {
// cannot predict if salt is null, because factory generates pseudorandom salt
if (salt == bytes32(0)) {
revert("null salt = pseudorandom addr");
}
return
Clones.predictDeterministicAddress({
implementation: engineCoreContractType ==
IEngineFactoryV0.EngineCoreType.Engine
? engineImplementation
: engineFlexImplementation,
salt: salt
});
}
/**
* @notice helper function to generate a pseudorandom salt
* @return result pseudorandom salt
*/
function _generatePseudorandomSalt() internal returns (bytes32 result) {
// get and increment nonce to prevent same-block collisions
uint256 nonce = _pseudorandomSaltNonce++;
return
keccak256(
abi.encodePacked(
nonce,
block.timestamp,
block.number,
address(this)
)
);
}
/**
* @notice helper function to convert a string to a bytes32.
* Caution: This function only works properly for short strings.
* @param source string to convert
* @return result bytes32 representation of the string
*/
function _stringToBytes32(
string memory source
) internal pure returns (bytes32 result) {
bytes memory tempString = bytes(source);
if (tempString.length == 0) {
return 0x0;
}
assembly {
result := mload(add(source, 32))
}
}
/**
* @notice helper function to validate that an address is non-zero.
* Reverts if the address is zero.
* @param address_ address to validate
*/
function _onlyNonZeroAddress(address address_) internal pure {
require(address_ != address(0), "Must input non-zero address");
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Clones.sol)
pragma solidity ^0.8.20;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*/
library Clones {
/**
* @dev A clone instance deployment failed.
*/
error ERC1167FailedCreateClone();
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(0, 0x09, 0x37)
}
if (instance == address(0)) {
revert ERC1167FailedCreateClone();
}
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(0, 0x09, 0x37, salt)
}
if (instance == address(0)) {
revert ERC1167FailedCreateClone();
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x38), deployer)
mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
mstore(add(ptr, 0x14), implementation)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
mstore(add(ptr, 0x58), salt)
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
predicted := keccak256(add(ptr, 0x43), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddress(implementation, salt, address(this));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Create2.sol)
pragma solidity ^0.8.20;
/**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
* `CREATE2` can be used to compute in advance the address where a smart
* contract will be deployed, which allows for interesting new mechanisms known
* as 'counterfactual interactions'.
*
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
* information.
*/
library Create2 {
/**
* @dev Not enough balance for performing a CREATE2 deploy.
*/
error Create2InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev There's no code to deploy.
*/
error Create2EmptyBytecode();
/**
* @dev The deployment failed.
*/
error Create2FailedDeployment();
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
if (address(this).balance < amount) {
revert Create2InsufficientBalance(address(this).balance, amount);
}
if (bytecode.length == 0) {
revert Create2EmptyBytecode();
}
/// @solidity memory-safe-assembly
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
if (addr == address(0)) {
revert Create2FailedDeployment();
}
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
* `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
* `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40) // Get free memory pointer
// | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... |
// |-------------------|---------------------------------------------------------------------------|
// | bytecodeHash | CCCCCCCCCCCCC...CC |
// | salt | BBBBBBBBBBBBB...BB |
// | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA |
// | 0xFF | FF |
// |-------------------|---------------------------------------------------------------------------|
// | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
// | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
mstore8(start, 0xff)
addr := keccak256(start, 85)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
import "./interfaces/v0.8.x/IAdminACLV0.sol";
import {IAdminACLV0_Extended} from "./interfaces/v0.8.x/IAdminACLV0_Extended.sol";
import "@openzeppelin-4.7/contracts/access/Ownable.sol";
import "@openzeppelin-4.7/contracts/utils/introspection/ERC165.sol";
/**
* @title Admin ACL contract, V0.
* @author Art Blocks Inc.
* @notice Privileged Roles and Ownership:
* This contract has a single superAdmin that passes all ACL checks. All checks
* for any other address will return false.
* The superAdmin can be changed by the current superAdmin.
* Care must be taken to ensure that the admin ACL contract is secure behind a
* multi-sig or other secure access control mechanism.
*/
contract AdminACLV0 is IAdminACLV0, IAdminACLV0_Extended, ERC165 {
string public AdminACLType = "AdminACLV0";
/// superAdmin is the only address that passes any and all ACL checks
address public superAdmin;
constructor() {
superAdmin = msg.sender;
}
/**
* @notice Allows superAdmin change the superAdmin address.
* @param _newSuperAdmin The new superAdmin address.
* @param _genArt721CoreAddressesToUpdate Array of genArt721Core
* addresses to update to the new superAdmin, for indexing purposes only.
* @dev this function is gated to only superAdmin address.
*/
function changeSuperAdmin(
address _newSuperAdmin,
address[] calldata _genArt721CoreAddressesToUpdate
) external {
require(msg.sender == superAdmin, "Only superAdmin");
address previousSuperAdmin = superAdmin;
superAdmin = _newSuperAdmin;
emit SuperAdminTransferred(
previousSuperAdmin,
_newSuperAdmin,
_genArt721CoreAddressesToUpdate
);
}
/**
* Calls transferOwnership on other contract from this contract.
* This is useful for updating to a new AdminACL contract.
* @dev this function is gated to only superAdmin address.
* @dev This implementation requires that the new AdminACL contract
* broadcasts support of IAdminACLV0 via ERC165 interface detection.
*/
function transferOwnershipOn(
address _contract,
address _newAdminACL
) external {
require(msg.sender == superAdmin, "Only superAdmin");
// ensure new AdminACL contract supports IAdminACLV0
require(
ERC165(_newAdminACL).supportsInterface(
type(IAdminACLV0).interfaceId
),
"AdminACLV0: new admin ACL does not support IAdminACLV0"
);
Ownable(_contract).transferOwnership(_newAdminACL);
}
/**
* @notice Calls renounceOwnership on other contract from this contract.
* @dev this function is gated to only superAdmin address.
*/
function renounceOwnershipOn(address _contract) external {
require(msg.sender == superAdmin, "Only superAdmin");
Ownable(_contract).renounceOwnership();
}
/**
* @notice Checks if sender `_sender` is allowed to call function with selector
* `_selector` on contract `_contract`. Returns true if sender is superAdmin.
*/
function allowed(
address _sender,
address /*_contract*/,
bytes4 /*_selector*/
) external view returns (bool) {
return superAdmin == _sender;
}
/**
* @inheritdoc ERC165
*/
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC165) returns (bool) {
return
interfaceId == type(IAdminACLV0).interfaceId ||
// @dev IAdminACLV0_Extended added after original deployments, so do not rely on it
// being present in all AdminACLV0 contracts.
interfaceId == type(IAdminACLV0_Extended).interfaceId ||
super.supportsInterface(interfaceId);
}
}// SPDX-License-Identifier: LGPL-3.0-only
// Created By: Art Blocks Inc.
pragma solidity ^0.8.0;
import "./IAdminACLV0.sol";
interface IAdminACLV0_Extended is IAdminACLV0 {
/**
* @notice Allows superAdmin change the superAdmin address.
* @param _newSuperAdmin The new superAdmin address.
* @param _genArt721CoreAddressesToUpdate Array of genArt721Core
* addresses to update to the new superAdmin, for indexing purposes only.
* @dev this function is gated to only superAdmin address.
*/
function changeSuperAdmin(
address _newSuperAdmin,
address[] calldata _genArt721CoreAddressesToUpdate
) external;
}// 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;
import "./IEngineRegistryV0.sol";
interface ICoreRegistryV1 is IEngineRegistryV0 {
function registerContracts(
address[] calldata contractAddresses,
bytes32[] calldata coreVersions,
bytes32[] calldata coreTypes
) external;
function unregisterContracts(address[] calldata contractAddresses) external;
function getNumRegisteredContracts() external view returns (uint256);
function getRegisteredContractAt(
uint256 index
) external view returns (address);
function isRegisteredContract(
address contractAddress
) external view returns (bool isRegistered);
}// SPDX-License-Identifier: LGPL-3.0-only
// Creatd By: Art Blocks Inc.
pragma solidity ^0.8.0;
import {EngineConfiguration} from "./IGenArt721CoreContractV3_Engine.sol";
interface IEngineFactoryV0 {
/// @notice Engine Core type
enum EngineCoreType {
Engine, // GenArt721CoreV3_Engine Contract
EngineFlex // GenArt721CoreV3_Engine_Flex Contract
}
/**
* @notice This contract was deployed.
* @param engineImplementation address with the implementation of the Engine contract
* @param engineFlexImplementation address with the implementation of the Engine Flex contract
* @param type_ type of this contract
*/
event Deployed(
address indexed engineImplementation,
address indexed engineFlexImplementation,
bytes32 indexed type_
);
/**
* @notice New Engine or Engine Flex contract was created.
* @param engineContract address of the newly created Engine contract
*/
event EngineContractCreated(address indexed engineContract);
/**
* @notice This contract was abandoned and no longer can be used to create
* new Engine or Engine Flex contracts.
*/
event Abandoned();
/**
* @notice Creates a new Engine or Engine Flex contract with the provided
* `engineConfiguration`, depending on the `engineCoreContractType`.
* @param engineCoreContractType Type of Engine Core contract.
* @param engineConfiguration EngineConfiguration data to configure the
* contract with.
* @param adminACLContract Address of admin access control contract, to be
* set as contract owner. A new contract will be deployed if address is null.
* @param salt Salt used to deterministically deploy the clone.
* @return engineContract The address of the newly created Engine or Engine Flex
* contract. The address is also emitted in both the `EngineCreated` and
* `EngineFlexCreated` events.
*/
function createEngineContract(
EngineCoreType engineCoreContractType,
EngineConfiguration calldata engineConfiguration,
address adminACLContract,
bytes32 salt
) external returns (address engineContract);
/**
* @notice Drains the contract's balance to the `recipient`.
* @param recipient The address to send funds to.
* Only callable by the owner.
*/
function drainETH(address payable recipient) external;
/**
* @notice Drains the contract's balance of an input ERC20 token to
* the `recipient`.
* @param ERC20TokenAddress The address of the ERC20 token to withdraw.
* @param recipient The address to send ERC20 tokens to.
* Only callable by the owner.
*/
function drainERC20(address ERC20TokenAddress, address recipient) external;
/**
* @notice Calls transferOwnership on the core registry.
* Useful for updating the owner of the core registry contract.
* @param _owner address of the new owner
*/
function transferCoreRegistryOwnership(address _owner) external;
/**
* @notice Registers multiple contracts with the core registry.
* @param contractAddresses An array of contract addresses to register.
* @param coreVersions An array of versions corresponding to the contract addresses.
* @param coreTypes An array of types corresponding to the contract addresses.
*/
function registerMultipleContracts(
address[] calldata contractAddresses,
bytes32[] calldata coreVersions,
bytes32[] calldata coreTypes
) external;
/**
* @notice Unregisters multiple contracts from the core registry.
* @param contractAddresses An array of contract addresses to unregister.
*/
function unregisterMultipleContracts(
address[] calldata contractAddresses
) external;
/**
* @notice The implementation contract that is cloned when creating new
* Engine Core contracts.
*/
function engineImplementation() external view returns (address);
/**
* @notice The implementation contract that is cloned when creating new
* Engine Flex Core contracts.
*/
function engineFlexImplementation() external view returns (address);
/**
* @notice Indicates whether the contract is abandoned.
* Once abandoned, the contract can no longer be used to create new Engine
* or Engine Flex contracts.
* @return bool True if the contract is abandoned, false otherwise.
*/
function isAbandoned() external view returns (bool);
/**
* @notice Indicates the type of the contract, e.g. `EngineFactoryV0`.
* @return type_ The type of the contract.
*/
function type_() external pure returns (bytes32);
}// SPDX-License-Identifier: LGPL-3.0-only
// Created By: Art Blocks Inc.
pragma solidity ^0.8.0;
interface IEngineRegistryV0 {
/// ADDRESS
/**
* @notice contract has been registered as a contract that is powered by the Art Blocks Engine.
*/
event ContractRegistered(
address indexed _contractAddress,
bytes32 _coreVersion,
bytes32 _coreType
);
/// ADDRESS
/**
* @notice contract has been unregistered as a contract that is powered by the Art Blocks Engine.
*/
event ContractUnregistered(address indexed _contractAddress);
/**
* @notice Emits a `ContractRegistered` event with the provided information.
* @dev this function should be gated to only deployer addresses.
*/
function registerContract(
address _contractAddress,
bytes32 _coreVersion,
bytes32 _coreType
) external;
/**
* @notice Emits a `ContractUnregistered` event with the provided information, validating that the provided
* address was indeed previously registered.
* @dev this function should be gated to only deployer addresses.
*/
function unregisterContract(address _contractAddress) external;
}// SPDX-License-Identifier: LGPL-3.0-only
// Created By: Art Blocks Inc.
pragma solidity ^0.8.0;
import "./IAdminACLV0.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 {
// This interface emits generic events that contain fields that indicate
// which parameter has been updated. This is sufficient for application
// state management, while also simplifying the contract and indexing code.
// This was done as an alternative to having custom events that emit what
// field-values have changed for each event, given that changed values can
// be introspected by indexers due to the design of this smart contract
// exposing these state changes via publicly viewable fields.
/**
* @notice Project's royalty splitter was updated to `_splitter`.
* @dev New event in v3.2
* @param projectId The project ID.
* @param royaltySplitter The new splitter address to receive royalties.
*/
event ProjectRoyaltySplitterUpdated(
uint256 indexed projectId,
address indexed royaltySplitter
);
// The following fields are used to indicate which contract-level parameter
// has been updated in the `PlatformUpdated` event:
// @dev only append to the end of this enum in the case of future updates
enum PlatformUpdatedFields {
FIELD_NEXT_PROJECT_ID, // 0
FIELD_NEW_PROJECTS_FORBIDDEN, // 1
FIELD_DEFAULT_BASE_URI, // 2
FIELD_RANDOMIZER_ADDRESS, // 3
FIELD_NEXT_CORE_CONTRACT, // 4
FIELD_ARTBLOCKS_DEPENDENCY_REGISTRY_ADDRESS, // 5
FIELD_ARTBLOCKS_ON_CHAIN_GENERATOR_ADDRESS, // 6
FIELD_PROVIDER_SALES_ADDRESSES, // 7
FIELD_PROVIDER_PRIMARY_SALES_PERCENTAGES, // 8
FIELD_PROVIDER_SECONDARY_SALES_BPS, // 9
FIELD_SPLIT_PROVIDER // 10
}
// The following fields are used to indicate which project-level parameter
// has been updated in the `ProjectUpdated` event:
// @dev only append to the end of this enum in the case of future updates
enum ProjectUpdatedFields {
FIELD_PROJECT_COMPLETED, // 0
FIELD_PROJECT_ACTIVE, // 1
FIELD_PROJECT_ARTIST_ADDRESS, // 2
FIELD_PROJECT_PAUSED, // 3
FIELD_PROJECT_CREATED, // 4
FIELD_PROJECT_NAME, // 5
FIELD_PROJECT_ARTIST_NAME, // 6
FIELD_PROJECT_SECONDARY_MARKET_ROYALTY_PERCENTAGE, // 7
FIELD_PROJECT_DESCRIPTION, // 8
FIELD_PROJECT_WEBSITE, // 9
FIELD_PROJECT_LICENSE, // 10
FIELD_PROJECT_MAX_INVOCATIONS, // 11
FIELD_PROJECT_SCRIPT, // 12
FIELD_PROJECT_SCRIPT_TYPE, // 13
FIELD_PROJECT_ASPECT_RATIO, // 14
FIELD_PROJECT_BASE_URI, // 15
FIELD_PROJECT_PROVIDER_SECONDARY_FINANCIALS // 16
}
/**
* @notice Error codes for the GenArt721 contract. Used by the GenArt721Error
* custom error.
* @dev only append to the end of this enum in the case of future updates
*/
enum ErrorCodes {
OnlyNonZeroAddress, // 0
OnlyNonEmptyString, // 1
OnlyNonEmptyBytes, // 2
TokenDoesNotExist, // 3
ProjectDoesNotExist, // 4
OnlyUnlockedProjects, // 5
OnlyAdminACL, // 6
OnlyArtist, // 7
OnlyArtistOrAdminACL, // 8
OnlyAdminACLOrRenouncedArtist, // 9
OnlyMinterContract, // 10
MaxInvocationsReached, // 11
ProjectMustExistAndBeActive, // 12
PurchasesPaused, // 13
OnlyRandomizer, // 14
TokenHashAlreadySet, // 15
NoZeroHashSeed, // 16
OverMaxSumOfPercentages, // 17
IndexOutOfBounds, // 18
OverMaxSumOfBPS, // 19
MaxOf100Percent, // 20
PrimaryPayeeIsZeroAddress, // 21
SecondaryPayeeIsZeroAddress, // 22
MustMatchArtistProposal, // 23
NewProjectsForbidden, // 24
NewProjectsAlreadyForbidden, // 25
OnlyArtistOrAdminIfLocked, // 26
OverMaxSecondaryRoyaltyPercentage, // 27
OnlyMaxInvocationsDecrease, // 28
OnlyGteInvocations, // 29
ScriptIdOutOfRange, // 30
NoScriptsToRemove, // 31
ScriptTypeAndVersionFormat, // 32
AspectRatioTooLong, // 33
AspectRatioNoNumbers, // 34
AspectRatioImproperFormat, // 35
OnlyNullPlatformProvider, // 36
ContractInitialized // 37
}
/**
* @notice Emits an error code `_errorCode` in the GenArt721Error event.
* @dev Emitting error codes instead of error strings saves significant
* contract bytecode size, allowing for more contract functionality within
* the 24KB contract size limit.
* @param _errorCode The error code to emit. See ErrorCodes enum.
*/
error GenArt721Error(ErrorCodes _errorCode);
/**
* @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 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";
import "./ISplitProviderV0.sol";
/**
* @notice Struct representing Engine contract configuration.
* @param tokenName Name of token.
* @param tokenSymbol Token symbol.
* @param renderProviderAddress address to send render provider revenue to
* @param randomizerContract Randomizer contract.
* @param splitProviderAddress Address to use as royalty splitter provider for the contract.
* @param minterFilterAddress Address of the Minter Filter to set as the Minter
* on the contract.
* @param startingProjectId The initial next project ID.
* @param autoApproveArtistSplitProposals Whether or not to always
* auto-approve proposed artist split updates.
* @param nullPlatformProvider Enforce always setting zero platform provider fees and addresses.
* @param allowArtistProjectActivation Allow artist to activate their own projects.
* @dev _startingProjectId should be set to a value much, much less than
* max(uint248), but an explicit input type of `uint248` is used as it is
* safer to cast up to `uint256` than it is to cast down for the purposes
* of setting `_nextProjectId`.
*/
struct EngineConfiguration {
string tokenName;
string tokenSymbol;
address renderProviderAddress;
address platformProviderAddress;
address newSuperAdminAddress;
address randomizerContract;
address splitProviderAddress;
address minterFilterAddress;
uint248 startingProjectId;
bool autoApproveArtistSplitProposals;
bool nullPlatformProvider;
bool allowArtistProjectActivation;
}
interface IGenArt721CoreContractV3_Engine is IGenArt721CoreContractV3_Base {
// @dev new function in V3.2
/**
* @notice Initializes the contract with the provided `engineConfiguration`.
* This function should be called atomically, immediately after deployment.
* Only callable once. Validation on `engineConfiguration` is performed by caller.
* @param engineConfiguration EngineConfiguration to configure the contract with.
* @param adminACLContract_ Address of admin access control contract, to be
* set as contract owner.
* @param defaultBaseURIHost Base URI prefix to initialize default base URI with.
*/
function initialize(
EngineConfiguration calldata engineConfiguration,
address adminACLContract_,
string memory defaultBaseURIHost
) external;
// @dev new function in V3
function getPrimaryRevenueSplits(
uint256 _projectId,
uint256 _price
)
external
view
returns (
uint256 renderProviderRevenue_,
address payable renderProviderAddress_,
uint256 platformProviderRevenue_,
address payable platformProviderAddress_,
uint256 artistRevenue_,
address payable artistAddress_,
uint256 additionalPayeePrimaryRevenue_,
address payable additionalPayeePrimaryAddress_
);
// @dev The render provider primary sales payment address
function renderProviderPrimarySalesAddress()
external
view
returns (address payable);
// @dev The platform provider primary sales payment address
function platformProviderPrimarySalesAddress()
external
view
returns (address payable);
// @dev Percentage of primary sales allocated to the render provider
function renderProviderPrimarySalesPercentage()
external
view
returns (uint256);
// @dev Percentage of primary sales allocated to the platform provider
function platformProviderPrimarySalesPercentage()
external
view
returns (uint256);
/** @notice The default render provider payment address for all secondary sales royalty
* revenues, for all new projects. Individual project payment info is defined
* in each project's ProjectFinance struct.
* @return The default render provider payment address for secondary sales royalties.
*/
function defaultRenderProviderSecondarySalesAddress()
external
view
returns (address payable);
/** @notice The default platform provider payment address for all secondary sales royalty
* revenues, for all new projects. Individual project payment info is defined
* in each project's ProjectFinance struct.
* @return The default platform provider payment address for secondary sales royalties.
*/
function defaultPlatformProviderSecondarySalesAddress()
external
view
returns (address payable);
/** @notice The default render provider payment basis points for all secondary sales royalty
* revenues, for all new projects. Individual project payment info is defined
* in each project's ProjectFinance struct.
* @return The default render provider payment basis points for secondary sales royalties.
*/
function defaultRenderProviderSecondarySalesBPS()
external
view
returns (uint256);
/** @notice The default platform provider payment basis points for all secondary sales royalty
* revenues, for all new projects. Individual project payment info is defined
* in each project's ProjectFinance struct.
* @return The default platform provider payment basis points for secondary sales royalties.
*/
function defaultPlatformProviderSecondarySalesBPS()
external
view
returns (uint256);
/**
* @notice The address of the current split provider being used by the contract.
* @return The address of the current split provider.
*/
function splitProvider() external view returns (ISplitProviderV0);
}// SPDX-License-Identifier: LGPL-3.0-only
// Created By: Art Blocks Inc. to support the 0xSplits V2 integration
// Sourced from:
// - https://github.com/0xSplits/splits-contracts-monorepo/blob/main/packages/splits-v2/src/libraries/SplitV2.sol
// - https://github.com/0xSplits/splits-contracts-monorepo/blob/main/packages/splits-v2/src/splitters/SplitFactoryV2.sol
pragma solidity ^0.8.0;
interface ISplitFactoryV2 {
/* -------------------------------------------------------------------------- */
/* STRUCTS */
/* -------------------------------------------------------------------------- */
/**
* @notice Split struct
* @dev This struct is used to store the split information.
* @dev There are no hard caps on the number of recipients/totalAllocation/allocation unit. Thus the chain and its
* gas limits will dictate these hard caps. Please double check if the split you are creating can be distributed on
* the chain.
* @param recipients The recipients of the split.
* @param allocations The allocations of the split.
* @param totalAllocation The total allocation of the split.
* @param distributionIncentive The incentive for distribution. Limits max incentive to 6.5%.
*/
struct Split {
address[] recipients;
uint256[] allocations;
uint256 totalAllocation;
uint16 distributionIncentive;
}
/* -------------------------------------------------------------------------- */
/* FUNCTIONS */
/* -------------------------------------------------------------------------- */
/**
* @notice Create a new split with params and owner.
* @param _splitParams Params to create split with.
* @param _owner Owner of created split.
* @param _creator Creator of created split.
* @param _salt Salt for create2.
* @return split Address of the created split.
*/
function createSplitDeterministic(
Split calldata _splitParams,
address _owner,
address _creator,
bytes32 _salt
) external returns (address split);
/**
* @notice Predict the address of a new split and check if it is deployed.
* @param _splitParams Params to create split with.
* @param _owner Owner of created split.
* @param _salt Salt for create2.
*/
function isDeployed(
Split calldata _splitParams,
address _owner,
bytes32 _salt
) external view returns (address split, bool exists);
}// SPDX-License-Identifier: LGPL-3.0-only
// Creatd By: Art Blocks Inc.
pragma solidity ^0.8.0;
import {ISplitFactoryV2} from "./integration-refs/splits-0x-v2/ISplitFactoryV2.sol";
interface ISplitProviderV0 {
/**
* @notice SplitInputs struct defines the inputs for requested splitters.
* It is defined in a way easily communicated from the Art Blocks GenArt721V3 contract,
* to allow for easy integration and minimal additional bytecode in the GenArt721V3 contract.
*/
struct SplitInputs {
address platformProviderSecondarySalesAddress;
uint16 platformProviderSecondarySalesBPS;
address renderProviderSecondarySalesAddress;
uint16 renderProviderSecondarySalesBPS;
uint8 artistTotalRoyaltyPercentage;
address artist;
address additionalPayee;
uint8 additionalPayeePercentage;
}
/**
* @notice Emitted when a new splitter contract is created.
* @param splitter address of the splitter contract
*/
event SplitterCreated(address indexed splitter);
/**
* @notice Gets or creates an immutable splitter contract at a deterministic address.
* Splits in the splitter contract are determined by the input split parameters,
* so we can safely create the splitter contract at a deterministic address (or use
* the existing splitter contract if it already exists at that address).
* @dev Uses the 0xSplits v2 implementation to create a splitter contract
* @param splitInputs The split input parameters.
* @return splitter The newly created splitter contract address.
*/
function getOrCreateSplitter(
SplitInputs calldata splitInputs
) external returns (address);
/**
* @notice Indicates the type of the contract, e.g. `SplitProviderV0`.
* @return type_ The type of the contract.
*/
function type_() external pure returns (bytes32);
}{
"optimizer": {
"enabled": true,
"runs": 10
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"engineImplementation_","type":"address"},{"internalType":"address","name":"engineFlexImplementation_","type":"address"},{"internalType":"address","name":"coreRegistry_","type":"address"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"string","name":"defaultBaseURIHost_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"Create2EmptyBytecode","type":"error"},{"inputs":[],"name":"Create2FailedDeployment","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"Create2InsufficientBalance","type":"error"},{"inputs":[],"name":"ERC1167FailedCreateClone","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[],"name":"Abandoned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"engineImplementation","type":"address"},{"indexed":true,"internalType":"address","name":"engineFlexImplementation","type":"address"},{"indexed":true,"internalType":"bytes32","name":"type_","type":"bytes32"}],"name":"Deployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"engineContract","type":"address"}],"name":"EngineContractCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"abandon","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"coreRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IEngineFactoryV0.EngineCoreType","name":"engineCoreContractType","type":"uint8"},{"components":[{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"address","name":"renderProviderAddress","type":"address"},{"internalType":"address","name":"platformProviderAddress","type":"address"},{"internalType":"address","name":"newSuperAdminAddress","type":"address"},{"internalType":"address","name":"randomizerContract","type":"address"},{"internalType":"address","name":"splitProviderAddress","type":"address"},{"internalType":"address","name":"minterFilterAddress","type":"address"},{"internalType":"uint248","name":"startingProjectId","type":"uint248"},{"internalType":"bool","name":"autoApproveArtistSplitProposals","type":"bool"},{"internalType":"bool","name":"nullPlatformProvider","type":"bool"},{"internalType":"bool","name":"allowArtistProjectActivation","type":"bool"}],"internalType":"struct EngineConfiguration","name":"engineConfiguration","type":"tuple"},{"internalType":"address","name":"adminACLContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"createEngineContract","outputs":[{"internalType":"address","name":"engineContract","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultBaseURIHost","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ERC20TokenAddress","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"drainERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"drainETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"engineCoreType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"engineCoreVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"engineFlexImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"engineImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct EngineFactoryV0.Call[]","name":"_calls","type":"tuple[]"}],"name":"execCalls","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes[]","name":"returnData","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flexCoreType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flexCoreVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isAbandoned","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IEngineFactoryV0.EngineCoreType","name":"engineCoreContractType","type":"uint8"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"predictDeterministicAddress","outputs":[{"internalType":"address","name":"predicted","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"contractAddresses","type":"address[]"},{"internalType":"bytes32[]","name":"coreVersions","type":"bytes32[]"},{"internalType":"bytes32[]","name":"coreTypes","type":"bytes32[]"}],"name":"registerMultipleContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"transferCoreRegistryOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"type_","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"contractAddresses","type":"address[]"}],"name":"unregisterMultipleContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60e06040523480156200001157600080fd5b5060405162002f5038038062002f5083398101604081905262000034916200049d565b816001600160a01b0381166200006557604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b62000070816200030d565b506200007c856200035d565b62000087846200035d565b62000092836200035d565b6200009d826200035d565b6001620000ab8282620005ba565b506001600160a01b03808616608081905285821660a05290841660c052604080516315c8b5b360e31b8152905163ae45ad98916004808201926000929091908290030181865afa15801562000104573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200012e919081019062000686565b6002906200013d9082620005ba565b506080516001600160a01b0316634e1d64af6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200017f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001a9919081019062000686565b600390620001b89082620005ba565b5060a0516001600160a01b031663ae45ad986040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001fa573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262000224919081019062000686565b600490620002339082620005ba565b5060a0516001600160a01b0316634e1d64af6040518163ffffffff1660e01b8152600401600060405180830381865afa15801562000275573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200029f919081019062000686565b600590620002ae9082620005ba565b506e0456e67696e65466163746f7279563608c1b846001600160a01b0316866001600160a01b03167f8a667a762c6b11836243ef58bb98850c7a4210d0226eb030bb2e03e3b7cc01e360405160405180910390a45050505050620006c6565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116620003b55760405162461bcd60e51b815260206004820152601b60248201527f4d75737420696e707574206e6f6e2d7a65726f2061646472657373000000000060448201526064016200005c565b50565b80516001600160a01b0381168114620003d057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620003fd57600080fd5b81516001600160401b03808211156200041a576200041a620003d5565b604051601f8301601f19908116603f01168101908282118183101715620004455762000445620003d5565b81604052838152602092508660208588010111156200046357600080fd5b600091505b8382101562000487578582018301518183018401529082019062000468565b6000602085830101528094505050505092915050565b600080600080600060a08688031215620004b657600080fd5b620004c186620003b8565b9450620004d160208701620003b8565b9350620004e160408701620003b8565b9250620004f160608701620003b8565b60808701519092506001600160401b038111156200050e57600080fd5b6200051c88828901620003eb565b9150509295509295909350565b600181811c908216806200053e57607f821691505b6020821081036200055f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620005b5576000816000526020600020601f850160051c81016020861015620005905750805b601f850160051c820191505b81811015620005b1578281556001016200059c565b5050505b505050565b81516001600160401b03811115620005d657620005d6620003d5565b620005ee81620005e7845462000529565b8462000565565b602080601f8311600181146200062657600084156200060d5750858301515b600019600386901b1c1916600185901b178555620005b1565b600085815260208120601f198616915b82811015620006575788860151825594840194600190910190840162000636565b5085821015620006765787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200069957600080fd5b81516001600160401b03811115620006b057600080fd5b620006be84828501620003eb565b949350505050565b60805160a05160c0516128226200072e6000396000818161024101528181610530015281816105d701528181610b670152610fa20152600081816103d00152818161094f0152610ee501526000818161019e015281816109760152610f0c01526128226000f3fe608060405260043610620001205760003560e01c806310a2e110146200012d57806324377e9f146200015d57806328d6edbf146200018a5780634e93d7e514620001cf57806366a2d9b014620001f65780636bf3d05a146200022d578063715018a614620002635780637390bb50146200027b5780637e56402f14620002a05780638831883414620002c55780638da5cb5b14620002dd5780638e6cee5214620002f55780639f1dc8f8146200031a5780639fc087391462000332578063af8181ff1462000367578063b8967f25146200037f578063e02878fd1462000397578063f21e018c14620003bc578063f2fde38b14620003f2578063f470c9911462000417578063f4ebf9e4146200043c578063fd24b937146200045457600080fd5b366200012857005b600080fd5b3480156200013a57600080fd5b506200014562000479565b604051620001549190620015c2565b60405180910390f35b3480156200016a57600080fd5b50600654620001799060ff1681565b604051901515815260200162000154565b3480156200019757600080fd5b50620001c07f000000000000000000000000000000000000000000000000000000000000000081565b604051620001549190620015e4565b348015620001dc57600080fd5b50620001f4620001ee36600462001620565b6200050f565b005b3480156200020357600080fd5b506200021e6e0456e67696e65466163746f7279563608c1b81565b60405190815260200162000154565b3480156200023a57600080fd5b50620001c07f000000000000000000000000000000000000000000000000000000000000000081565b3480156200027057600080fd5b50620001f46200059e565b3480156200028857600080fd5b50620001f46200029a3660046200168e565b620005b6565b348015620002ad57600080fd5b50620001f4620002bf366004620016d3565b62000648565b348015620002d257600080fd5b50620001f4620006e5565b348015620002ea57600080fd5b50620001c062000756565b3480156200030257600080fd5b50620001c06200031436600462001721565b62000765565b3480156200032757600080fd5b506200014562000c52565b3480156200033f57600080fd5b5062000357620003513660046200168e565b62000c61565b6040516200015492919062001795565b3480156200037457600080fd5b506200014562000e53565b3480156200038c57600080fd5b506200014562000e62565b348015620003a457600080fd5b50620001c0620003b636600462001805565b62000e71565b348015620003c957600080fd5b50620001c07f000000000000000000000000000000000000000000000000000000000000000081565b348015620003ff57600080fd5b50620001f46200041136600462001620565b62000f3c565b3480156200042457600080fd5b50620001f46200043636600462001832565b62000f81565b3480156200044957600080fd5b50620001456200101f565b3480156200046157600080fd5b50620001f46200047336600462001620565b6200102e565b600480546200048890620018d5565b80601f0160208091040260200160405190810160405280929190818152602001828054620004b690620018d5565b8015620005075780601f10620004db5761010080835404028352916020019162000507565b820191906000526020600020905b815481529060010190602001808311620004e957829003601f168201915b505050505081565b62000519620010de565b60405163f2fde38b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f2fde38b9062000567908490600401620015e4565b600060405180830381600087803b1580156200058257600080fd5b505af115801562000597573d6000803e3d6000fd5b5050505050565b620005a8620010de565b620005b4600062001115565b565b620005c0620010de565b604051631cdd23b160e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906373748ec4906200061090859085906004016200195e565b600060405180830381600087803b1580156200062b57600080fd5b505af115801562000640573d6000803e3d6000fd5b505050505050565b62000652620010de565b6040516370a0823160e01b815282906000906001600160a01b038316906370a082319062000685903090600401620015e4565b602060405180830381865afa158015620006a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006c991906200197c565b90508015620006df57620006df82848362001165565b50505050565b620006ef620010de565b60065460ff16156200071e5760405162461bcd60e51b8152600401620007159062001996565b60405180910390fd5b6006805460ff191660011790556040517ffb03bbbb81551103a80dda8d3bda55d93637ca4a96390de3719644774bdf1e9890600090a1565b6000546001600160a01b031690565b600062000771620010de565b60065460ff1615620007975760405162461bcd60e51b8152600401620007159062001996565b620007b3620007ad606086016040870162001620565b620011b9565b620007c9620007ad60c0860160a0870162001620565b81620007dc57620007d96200120f565b91505b6001600160a01b038316620008c95762000801620007ad60a086016080870162001620565b6200083b6000620008116200120f565b604051620008226020820162001560565b601f1982820381018352601f9091011660405262001274565b6040805160008152602081019091529093506001600160a01b03841663377a7d1a6200086e60a088016080890162001620565b836040518363ffffffff1660e01b81526004016200088e929190620019da565b600060405180830381600087803b158015620008a957600080fd5b505af1158015620008be573d6000803e3d6000fd5b50505050506200092f565b6000620008dd60a086016080870162001620565b6001600160a01b0316146200092f5760405162461bcd60e51b815260206004820152601760248201527641646d696e41434c20616c72656164792065786973747360481b604482015260640162000715565b60008086600181111562000947576200094762001a38565b1462000974577f000000000000000000000000000000000000000000000000000000000000000062000996565b7f00000000000000000000000000000000000000000000000000000000000000005b9050620009a48184620012ff565b604051630dcdda2360e21b81529092506001600160a01b03831690633737688c90620009da908890889060019060040162001b9f565b600060405180830381600087803b158015620009f557600080fd5b505af115801562000a0a573d6000803e3d6000fd5b506000925082915081905088600181111562000a2a5762000a2a62001a38565b1462000a3a576004600562000a3f565b600260035b805462000a4c90620018d5565b80601f016020809104026020016040519081016040528092919081815260200182805462000a7a90620018d5565b801562000acb5780601f1062000a9f5761010080835404028352916020019162000acb565b820191906000526020600020905b81548152906001019060200180831162000aad57829003601f168201915b50505050509150805462000adf90620018d5565b80601f016020809104026020016040519081016040528092919081815260200182805462000b0d90620018d5565b801562000b5e5780601f1062000b325761010080835404028352916020019162000b5e565b820191906000526020600020905b81548152906001019060200180831162000b4057829003601f168201915b505050505091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f889b3ed8562000ba0846200136e565b62000bab866200136e565b6040516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091526044820152606401600060405180830381600087803b15801562000bfa57600080fd5b505af115801562000c0f573d6000803e3d6000fd5b50506040516001600160a01b03871692507f72dba3aac69e7eadf1383243bbb649ff575d0d530bfecf3d33ef4a0cc0a77b8d9150600090a2505050949350505050565b600380546200048890620018d5565b6000606062000c6f620010de565b43915082806001600160401b0381111562000c8e5762000c8e620019c4565b60405190808252806020026020018201604052801562000cc357816020015b606081526020019060019003908162000cad5790505b50915060005b8181101562000e4a573686868381811062000ce85762000ce862001d5f565b905060200281019062000cfc919062001d75565b905062000d0d602082018262001620565b6001600160a01b03163b60000362000d735762000d2e602082018262001d96565b15905062000d735760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642063616c6c206461746160781b604482015260640162000715565b60008062000d85602084018462001620565b6001600160a01b031662000d9d602085018562001d96565b60405162000dad92919062001ddf565b6000604051808303816000865af19150503d806000811462000dec576040519150601f19603f3d011682016040523d82523d6000602084013e62000df1565b606091505b509150915081819062000e195760405162461bcd60e51b8152600401620007159190620015c2565b508086858151811062000e305762000e3062001d5f565b602002602001018190525050505080600101905062000cc9565b50509250929050565b600180546200048890620018d5565b600580546200048890620018d5565b60008162000ec25760405162461bcd60e51b815260206004820152601d60248201527f6e756c6c2073616c74203d2070736575646f72616e646f6d2061646472000000604482015260640162000715565b62000f33600084600181111562000edd5762000edd62001a38565b1462000f0a577f000000000000000000000000000000000000000000000000000000000000000062000f2c565b7f00000000000000000000000000000000000000000000000000000000000000005b836200138e565b90505b92915050565b62000f46620010de565b6001600160a01b03811662000f73576000604051631e4fbdf760e01b8152600401620007159190620015e4565b62000f7e8162001115565b50565b62000f8b620010de565b60405163b3cdf53760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b3cdf5379062000fe39089908990899089908990899060040162001e22565b600060405180830381600087803b15801562000ffe57600080fd5b505af115801562001013573d6000803e3d6000fd5b50505050505050505050565b600280546200048890620018d5565b62001038620010de565b478015620010da576000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146200108f576040519150601f19603f3d011682016040523d82523d6000602084013e62001094565b606091505b5050905080620010d85760405162461bcd60e51b815260206004820152600e60248201526d14185e5b595b9d0819985a5b195960921b604482015260640162000715565b505b5050565b33620010e962000756565b6001600160a01b031614620005b4573360405163118cdaa760e01b8152600401620007159190620015e4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052620010d8908490620013ef565b6001600160a01b03811662000f7e5760405162461bcd60e51b815260206004820152601b60248201527a4d75737420696e707574206e6f6e2d7a65726f206164647265737360281b604482015260640162000715565b6007805460009182919082620012258362001e71565b909155506040805160208082019390935242818301524360608083019190915230901b6001600160601b0319166080820152815180820360740181526094909101909152805191012092915050565b600083471015620012a25760405163392efb2b60e21b81524760048201526024810185905260440162000715565b8151600003620012c557604051631328927760e21b815260040160405180910390fd5b8282516020840186f590506001600160a01b038116620012f857604051633a0ba96160e11b815260040160405180910390fd5b9392505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008360601b60e81c176000526e5af43d82803e903d91602b57fd5bf38360781b1760205281603760096000f590506001600160a01b03811662000f36576040516330be1a3d60e21b815260040160405180910390fd5b805160009082908203620013855750600092915050565b50506020015190565b6040513060388201526f5af43d82803e903d91602b57fd5bf3ff602482015260148101839052733d602d80600a3d3981f3363d3d373d3d3d363d738152605881018290526037600c8201206078820152605560439091012060009062000f33565b6000620014066001600160a01b0384168362001451565b905080516000141580156200142e5750808060200190518101906200142c919062001e99565b155b15620010d85782604051635274afe760e01b8152600401620007159190620015e4565b606062000f338383600084600080856001600160a01b031684866040516200147a919062001eb9565b60006040518083038185875af1925050503d8060008114620014b9576040519150601f19603f3d011682016040523d82523d6000602084013e620014be565b606091505b5091509150620014d0868383620014da565b9695505050505050565b606082620014f357620014ed8262001536565b620012f8565b81511580156200150b57506001600160a01b0384163b155b156200152e5783604051639996b31560e01b8152600401620007159190620015e4565b5080620012f8565b805115620015475780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b61091f8062001ece83390190565b60005b838110156200158b57818101518382015260200162001571565b50506000910152565b60008151808452620015ae8160208601602086016200156e565b601f01601f19169290920160200192915050565b60208152600062000f33602083018462001594565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b6001600160a01b038116811462000f7e57600080fd5b80356200161b81620015f8565b919050565b6000602082840312156200163357600080fd5b8135620012f881620015f8565b60008083601f8401126200165357600080fd5b5081356001600160401b038111156200166b57600080fd5b6020830191508360208260051b85010111156200168757600080fd5b9250929050565b60008060208385031215620016a257600080fd5b82356001600160401b03811115620016b957600080fd5b620016c78582860162001640565b90969095509350505050565b60008060408385031215620016e757600080fd5b8235620016f481620015f8565b915060208301356200170681620015f8565b809150509250929050565b8035600281106200161b57600080fd5b600080600080608085870312156200173857600080fd5b620017438562001711565b935060208501356001600160401b038111156200175f57600080fd5b850161018081880312156200177357600080fd5b925060408501356200178581620015f8565b9396929550929360600135925050565b60006040820184835260206040602085015281855180845260608601915060608160051b87010193506020870160005b82811015620017f757605f19888703018452620017e486835162001594565b95509284019290840190600101620017c5565b509398975050505050505050565b600080604083850312156200181957600080fd5b620018248362001711565b946020939093013593505050565b600080600080600080606087890312156200184c57600080fd5b86356001600160401b03808211156200186457600080fd5b620018728a838b0162001640565b909850965060208901359150808211156200188c57600080fd5b6200189a8a838b0162001640565b90965094506040890135915080821115620018b457600080fd5b50620018c389828a0162001640565b979a9699509497509295939492505050565b600181811c90821680620018ea57607f821691505b6020821081036200190b57634e487b7160e01b600052602260045260246000fd5b50919050565b8183526000602080850194508260005b85811015620019535781356200193781620015f8565b6001600160a01b03168752958201959082019060010162001921565b509495945050505050565b6020815260006200197460208301848662001911565b949350505050565b6000602082840312156200198f57600080fd5b5051919050565b602080825260149082015273199858dd1bdc9e481a5cc81858985b991bdb995960621b604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038381168252604060208084018290528451918401829052600092858201929091906060860190855b8181101562001a2a57855185168352948301949183019160010162001a0a565b509098975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6000808335601e1984360301811262001a6657600080fd5b83016020810192503590506001600160401b0381111562001a8657600080fd5b8036038213156200168757600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b80356001600160f81b03811681146200161b57600080fd5b801515811462000f7e57600080fd5b80356200161b8162001ad7565b8054600090600181811c908083168062001b0e57607f831692505b6020808410820362001b3057634e487b7160e01b600052602260045260246000fd5b8388526020880182801562001b4e576001811462001b655762001b92565b60ff198716825285151560051b8201975062001b92565b60008981526020902060005b8781101562001b8c5781548482015290860190840162001b71565b83019850505b5050505050505092915050565b60608152600062001bb1858662001a4e565b61018080606086015262001bcb6101e08601838562001a96565b925062001bdc602089018962001a4e565b868503605f19016080880152925062001bf784848362001a96565b93505062001c08604089016200160e565b915062001c1960a0860183620015d7565b62001c27606089016200160e565b915062001c3860c0860183620015d7565b62001c46608089016200160e565b915062001c5760e0860183620015d7565b62001c6560a089016200160e565b915061010062001c7881870184620015d7565b62001c8660c08a016200160e565b925061012062001c9981880185620015d7565b62001ca760e08b016200160e565b935061014062001cba81890186620015d7565b62001cc7838c0162001abf565b9450610160925062001ce3838901866001600160f81b03169052565b62001cf0828c0162001ae6565b80151589860152945062001d06818c0162001ae6565b9450505062001d1a6101a087018415159052565b62001d27818a0162001ae6565b9250505062001d3b6101c085018215159052565b5062001d4b6020840186620015d7565b8281036040840152620014d0818562001af3565b634e487b7160e01b600052603260045260246000fd5b60008235603e1983360301811262001d8c57600080fd5b9190910192915050565b6000808335601e1984360301811262001dae57600080fd5b8301803591506001600160401b0382111562001dc957600080fd5b6020019150368190038213156200168757600080fd5b8183823760009101908152919050565b81835260006001600160fb1b0383111562001e0957600080fd5b8260051b80836020870137939093016020019392505050565b60608152600062001e3860608301888a62001911565b828103602084015262001e4d81878962001def565b9050828103604084015262001e6481858762001def565b9998505050505050505050565b60006001820162001e9257634e487b7160e01b600052601160045260246000fd5b5060010190565b60006020828403121562001eac57600080fd5b8151620012f88162001ad7565b6000825162001d8c8184602087016200156e56fe60c0604052600a608090815269041646d696e41434c56360b41b60a05260009061002990826100ef565b5034801561003657600080fd5b50600180546001600160a01b031916331790556101ae565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061007857607f821691505b60208210810361009857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156100ea576000816000526020600020601f850160051c810160208610156100c75750805b601f850160051c820191505b818110156100e6578281556001016100d3565b5050505b505050565b81516001600160401b038111156101085761010861004e565b61011c816101168454610064565b8461009e565b602080601f83116001811461015157600084156101395750858301515b600019600386901b1c1916600185901b1785556100e6565b600085815260208120601f198616915b8281101561018057888601518255948401946001909101908401610161565b508582101561019e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610762806101bd6000396000f3fe608060405234801561001057600080fd5b506004361061006d5760003560e01c806301ffc9a71461007257806305de62c01461009a57806329575f6a146100be578063377a7d1a146100de578063985d1968146100f3578063bcc91a1014610106578063c81a396e14610119575b600080fd5b6100856100803660046104a9565b61012e565b60405190151581526020015b60405180910390f35b6100856100a83660046104e2565b50506001546001600160a01b0391821691161490565b6001546100d1906001600160a01b031681565b6040516100919190610525565b6100f16100ec366004610539565b610180565b005b6100f16101013660046105be565b610218565b6100f16101143660046105d9565b610298565b6101216103fe565b604051610091919061060c565b60006001600160e01b03198216633001c1ef60e21b148061015f57506001600160e01b03198216631bbd3e8d60e11b145b8061017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546001600160a01b031633146101b35760405162461bcd60e51b81526004016101aa9061065b565b60405180910390fd5b600180546001600160a01b038581166001600160a01b0319831681179093556040519116919082907f3f6845104f9728af7979eed8814320daba008953c8db93b9fe32602d1f34b4759061020a9087908790610684565b60405180910390a350505050565b6001546001600160a01b031633146102425760405162461bcd60e51b81526004016101aa9061065b565b806001600160a01b031663715018a66040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561027d57600080fd5b505af1158015610291573d6000803e3d6000fd5b5050505050565b6001546001600160a01b031633146102c25760405162461bcd60e51b81526004016101aa9061065b565b6040516301ffc9a760e01b8152633001c1ef60e21b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa15801561030d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033191906106d0565b61039c5760405162461bcd60e51b815260206004820152603660248201527f41646d696e41434c56303a206e65772061646d696e2041434c20646f6573206e60448201527506f7420737570706f7274204941646d696e41434c56360541b60648201526084016101aa565b60405163f2fde38b60e01b81526001600160a01b0383169063f2fde38b906103c8908490600401610525565b600060405180830381600087803b1580156103e257600080fd5b505af11580156103f6573d6000803e3d6000fd5b505050505050565b6000805461040b906106f2565b80601f0160208091040260200160405190810160405280929190818152602001828054610437906106f2565b80156104845780601f1061045957610100808354040283529160200191610484565b820191906000526020600020905b81548152906001019060200180831161046757829003601f168201915b505050505081565b80356001600160e01b0319811681146104a457600080fd5b919050565b6000602082840312156104bb57600080fd5b6104c48261048c565b9392505050565b80356001600160a01b03811681146104a457600080fd5b6000806000606084860312156104f757600080fd5b610500846104cb565b925061050e602085016104cb565b915061051c6040850161048c565b90509250925092565b6001600160a01b0391909116815260200190565b60008060006040848603121561054e57600080fd5b610557846104cb565b925060208401356001600160401b038082111561057357600080fd5b818601915086601f83011261058757600080fd5b81358181111561059657600080fd5b8760208260051b85010111156105ab57600080fd5b6020830194508093505050509250925092565b6000602082840312156105d057600080fd5b6104c4826104cb565b600080604083850312156105ec57600080fd5b6105f5836104cb565b9150610603602084016104cb565b90509250929050565b60006020808352835180602085015260005b8181101561063a5785810183015185820160400152820161061e565b506000604082860101526040601f19601f8301168501019250505092915050565b6020808252600f908201526e27b7363c9039bab832b920b236b4b760891b604082015260600190565b60208082528181018390526000908460408401835b868110156106c5576001600160a01b036106b2846104cb565b1682529183019190830190600101610699565b509695505050505050565b6000602082840312156106e257600080fd5b815180151581146104c457600080fd5b600181811c9082168061070657607f821691505b60208210810361072657634e487b7160e01b600052602260045260246000fd5b5091905056fea2646970667358221220830f3c30ad4d14df1865965a76cbb302e6938979ee6e646e3a277a8abebb5fd164736f6c63430008160033a26469706673582212200750368963d281eadeb2667f0d1409504d011ab31a68b6699554729037b78c7e64736f6c63430008160033000000000000000000000000000000f74f006ce6480042f001c45c928d1ae6e70000000000000000000000000066009b13b8dfdabbe07800ee00004b008257d90000000000000000000000002ee7b9bb2e038be7323a119701a191c030a61ec600000000000000000000000000df4e8d293d57718aac0b18cbfbe128c5d484ef00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001b68747470733a2f2f746f6b656e2e617274626c6f636b732e696f2f0000000000
Deployed Bytecode
0x608060405260043610620001205760003560e01c806310a2e110146200012d57806324377e9f146200015d57806328d6edbf146200018a5780634e93d7e514620001cf57806366a2d9b014620001f65780636bf3d05a146200022d578063715018a614620002635780637390bb50146200027b5780637e56402f14620002a05780638831883414620002c55780638da5cb5b14620002dd5780638e6cee5214620002f55780639f1dc8f8146200031a5780639fc087391462000332578063af8181ff1462000367578063b8967f25146200037f578063e02878fd1462000397578063f21e018c14620003bc578063f2fde38b14620003f2578063f470c9911462000417578063f4ebf9e4146200043c578063fd24b937146200045457600080fd5b366200012857005b600080fd5b3480156200013a57600080fd5b506200014562000479565b604051620001549190620015c2565b60405180910390f35b3480156200016a57600080fd5b50600654620001799060ff1681565b604051901515815260200162000154565b3480156200019757600080fd5b50620001c07f000000000000000000000000000000f74f006ce6480042f001c45c928d1ae6e781565b604051620001549190620015e4565b348015620001dc57600080fd5b50620001f4620001ee36600462001620565b6200050f565b005b3480156200020357600080fd5b506200021e6e0456e67696e65466163746f7279563608c1b81565b60405190815260200162000154565b3480156200023a57600080fd5b50620001c07f0000000000000000000000002ee7b9bb2e038be7323a119701a191c030a61ec681565b3480156200027057600080fd5b50620001f46200059e565b3480156200028857600080fd5b50620001f46200029a3660046200168e565b620005b6565b348015620002ad57600080fd5b50620001f4620002bf366004620016d3565b62000648565b348015620002d257600080fd5b50620001f4620006e5565b348015620002ea57600080fd5b50620001c062000756565b3480156200030257600080fd5b50620001c06200031436600462001721565b62000765565b3480156200032757600080fd5b506200014562000c52565b3480156200033f57600080fd5b5062000357620003513660046200168e565b62000c61565b6040516200015492919062001795565b3480156200037457600080fd5b506200014562000e53565b3480156200038c57600080fd5b506200014562000e62565b348015620003a457600080fd5b50620001c0620003b636600462001805565b62000e71565b348015620003c957600080fd5b50620001c07f0000000000000000000000000066009b13b8dfdabbe07800ee00004b008257d981565b348015620003ff57600080fd5b50620001f46200041136600462001620565b62000f3c565b3480156200042457600080fd5b50620001f46200043636600462001832565b62000f81565b3480156200044957600080fd5b50620001456200101f565b3480156200046157600080fd5b50620001f46200047336600462001620565b6200102e565b600480546200048890620018d5565b80601f0160208091040260200160405190810160405280929190818152602001828054620004b690620018d5565b8015620005075780601f10620004db5761010080835404028352916020019162000507565b820191906000526020600020905b815481529060010190602001808311620004e957829003601f168201915b505050505081565b62000519620010de565b60405163f2fde38b60e01b81526001600160a01b037f0000000000000000000000002ee7b9bb2e038be7323a119701a191c030a61ec6169063f2fde38b9062000567908490600401620015e4565b600060405180830381600087803b1580156200058257600080fd5b505af115801562000597573d6000803e3d6000fd5b5050505050565b620005a8620010de565b620005b4600062001115565b565b620005c0620010de565b604051631cdd23b160e21b81526001600160a01b037f0000000000000000000000002ee7b9bb2e038be7323a119701a191c030a61ec616906373748ec4906200061090859085906004016200195e565b600060405180830381600087803b1580156200062b57600080fd5b505af115801562000640573d6000803e3d6000fd5b505050505050565b62000652620010de565b6040516370a0823160e01b815282906000906001600160a01b038316906370a082319062000685903090600401620015e4565b602060405180830381865afa158015620006a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620006c991906200197c565b90508015620006df57620006df82848362001165565b50505050565b620006ef620010de565b60065460ff16156200071e5760405162461bcd60e51b8152600401620007159062001996565b60405180910390fd5b6006805460ff191660011790556040517ffb03bbbb81551103a80dda8d3bda55d93637ca4a96390de3719644774bdf1e9890600090a1565b6000546001600160a01b031690565b600062000771620010de565b60065460ff1615620007975760405162461bcd60e51b8152600401620007159062001996565b620007b3620007ad606086016040870162001620565b620011b9565b620007c9620007ad60c0860160a0870162001620565b81620007dc57620007d96200120f565b91505b6001600160a01b038316620008c95762000801620007ad60a086016080870162001620565b6200083b6000620008116200120f565b604051620008226020820162001560565b601f1982820381018352601f9091011660405262001274565b6040805160008152602081019091529093506001600160a01b03841663377a7d1a6200086e60a088016080890162001620565b836040518363ffffffff1660e01b81526004016200088e929190620019da565b600060405180830381600087803b158015620008a957600080fd5b505af1158015620008be573d6000803e3d6000fd5b50505050506200092f565b6000620008dd60a086016080870162001620565b6001600160a01b0316146200092f5760405162461bcd60e51b815260206004820152601760248201527641646d696e41434c20616c72656164792065786973747360481b604482015260640162000715565b60008086600181111562000947576200094762001a38565b1462000974577f0000000000000000000000000066009b13b8dfdabbe07800ee00004b008257d962000996565b7f000000000000000000000000000000f74f006ce6480042f001c45c928d1ae6e75b9050620009a48184620012ff565b604051630dcdda2360e21b81529092506001600160a01b03831690633737688c90620009da908890889060019060040162001b9f565b600060405180830381600087803b158015620009f557600080fd5b505af115801562000a0a573d6000803e3d6000fd5b506000925082915081905088600181111562000a2a5762000a2a62001a38565b1462000a3a576004600562000a3f565b600260035b805462000a4c90620018d5565b80601f016020809104026020016040519081016040528092919081815260200182805462000a7a90620018d5565b801562000acb5780601f1062000a9f5761010080835404028352916020019162000acb565b820191906000526020600020905b81548152906001019060200180831162000aad57829003601f168201915b50505050509150805462000adf90620018d5565b80601f016020809104026020016040519081016040528092919081815260200182805462000b0d90620018d5565b801562000b5e5780601f1062000b325761010080835404028352916020019162000b5e565b820191906000526020600020905b81548152906001019060200180831162000b4057829003601f168201915b505050505091507f0000000000000000000000002ee7b9bb2e038be7323a119701a191c030a61ec66001600160a01b031663f889b3ed8562000ba0846200136e565b62000bab866200136e565b6040516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091526044820152606401600060405180830381600087803b15801562000bfa57600080fd5b505af115801562000c0f573d6000803e3d6000fd5b50506040516001600160a01b03871692507f72dba3aac69e7eadf1383243bbb649ff575d0d530bfecf3d33ef4a0cc0a77b8d9150600090a2505050949350505050565b600380546200048890620018d5565b6000606062000c6f620010de565b43915082806001600160401b0381111562000c8e5762000c8e620019c4565b60405190808252806020026020018201604052801562000cc357816020015b606081526020019060019003908162000cad5790505b50915060005b8181101562000e4a573686868381811062000ce85762000ce862001d5f565b905060200281019062000cfc919062001d75565b905062000d0d602082018262001620565b6001600160a01b03163b60000362000d735762000d2e602082018262001d96565b15905062000d735760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642063616c6c206461746160781b604482015260640162000715565b60008062000d85602084018462001620565b6001600160a01b031662000d9d602085018562001d96565b60405162000dad92919062001ddf565b6000604051808303816000865af19150503d806000811462000dec576040519150601f19603f3d011682016040523d82523d6000602084013e62000df1565b606091505b509150915081819062000e195760405162461bcd60e51b8152600401620007159190620015c2565b508086858151811062000e305762000e3062001d5f565b602002602001018190525050505080600101905062000cc9565b50509250929050565b600180546200048890620018d5565b600580546200048890620018d5565b60008162000ec25760405162461bcd60e51b815260206004820152601d60248201527f6e756c6c2073616c74203d2070736575646f72616e646f6d2061646472000000604482015260640162000715565b62000f33600084600181111562000edd5762000edd62001a38565b1462000f0a577f0000000000000000000000000066009b13b8dfdabbe07800ee00004b008257d962000f2c565b7f000000000000000000000000000000f74f006ce6480042f001c45c928d1ae6e75b836200138e565b90505b92915050565b62000f46620010de565b6001600160a01b03811662000f73576000604051631e4fbdf760e01b8152600401620007159190620015e4565b62000f7e8162001115565b50565b62000f8b620010de565b60405163b3cdf53760e01b81526001600160a01b037f0000000000000000000000002ee7b9bb2e038be7323a119701a191c030a61ec6169063b3cdf5379062000fe39089908990899089908990899060040162001e22565b600060405180830381600087803b15801562000ffe57600080fd5b505af115801562001013573d6000803e3d6000fd5b50505050505050505050565b600280546200048890620018d5565b62001038620010de565b478015620010da576000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146200108f576040519150601f19603f3d011682016040523d82523d6000602084013e62001094565b606091505b5050905080620010d85760405162461bcd60e51b815260206004820152600e60248201526d14185e5b595b9d0819985a5b195960921b604482015260640162000715565b505b5050565b33620010e962000756565b6001600160a01b031614620005b4573360405163118cdaa760e01b8152600401620007159190620015e4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052620010d8908490620013ef565b6001600160a01b03811662000f7e5760405162461bcd60e51b815260206004820152601b60248201527a4d75737420696e707574206e6f6e2d7a65726f206164647265737360281b604482015260640162000715565b6007805460009182919082620012258362001e71565b909155506040805160208082019390935242818301524360608083019190915230901b6001600160601b0319166080820152815180820360740181526094909101909152805191012092915050565b600083471015620012a25760405163392efb2b60e21b81524760048201526024810185905260440162000715565b8151600003620012c557604051631328927760e21b815260040160405180910390fd5b8282516020840186f590506001600160a01b038116620012f857604051633a0ba96160e11b815260040160405180910390fd5b9392505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008360601b60e81c176000526e5af43d82803e903d91602b57fd5bf38360781b1760205281603760096000f590506001600160a01b03811662000f36576040516330be1a3d60e21b815260040160405180910390fd5b805160009082908203620013855750600092915050565b50506020015190565b6040513060388201526f5af43d82803e903d91602b57fd5bf3ff602482015260148101839052733d602d80600a3d3981f3363d3d373d3d3d363d738152605881018290526037600c8201206078820152605560439091012060009062000f33565b6000620014066001600160a01b0384168362001451565b905080516000141580156200142e5750808060200190518101906200142c919062001e99565b155b15620010d85782604051635274afe760e01b8152600401620007159190620015e4565b606062000f338383600084600080856001600160a01b031684866040516200147a919062001eb9565b60006040518083038185875af1925050503d8060008114620014b9576040519150601f19603f3d011682016040523d82523d6000602084013e620014be565b606091505b5091509150620014d0868383620014da565b9695505050505050565b606082620014f357620014ed8262001536565b620012f8565b81511580156200150b57506001600160a01b0384163b155b156200152e5783604051639996b31560e01b8152600401620007159190620015e4565b5080620012f8565b805115620015475780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b61091f8062001ece83390190565b60005b838110156200158b57818101518382015260200162001571565b50506000910152565b60008151808452620015ae8160208601602086016200156e565b601f01601f19169290920160200192915050565b60208152600062000f33602083018462001594565b6001600160a01b03169052565b6001600160a01b0391909116815260200190565b6001600160a01b038116811462000f7e57600080fd5b80356200161b81620015f8565b919050565b6000602082840312156200163357600080fd5b8135620012f881620015f8565b60008083601f8401126200165357600080fd5b5081356001600160401b038111156200166b57600080fd5b6020830191508360208260051b85010111156200168757600080fd5b9250929050565b60008060208385031215620016a257600080fd5b82356001600160401b03811115620016b957600080fd5b620016c78582860162001640565b90969095509350505050565b60008060408385031215620016e757600080fd5b8235620016f481620015f8565b915060208301356200170681620015f8565b809150509250929050565b8035600281106200161b57600080fd5b600080600080608085870312156200173857600080fd5b620017438562001711565b935060208501356001600160401b038111156200175f57600080fd5b850161018081880312156200177357600080fd5b925060408501356200178581620015f8565b9396929550929360600135925050565b60006040820184835260206040602085015281855180845260608601915060608160051b87010193506020870160005b82811015620017f757605f19888703018452620017e486835162001594565b95509284019290840190600101620017c5565b509398975050505050505050565b600080604083850312156200181957600080fd5b620018248362001711565b946020939093013593505050565b600080600080600080606087890312156200184c57600080fd5b86356001600160401b03808211156200186457600080fd5b620018728a838b0162001640565b909850965060208901359150808211156200188c57600080fd5b6200189a8a838b0162001640565b90965094506040890135915080821115620018b457600080fd5b50620018c389828a0162001640565b979a9699509497509295939492505050565b600181811c90821680620018ea57607f821691505b6020821081036200190b57634e487b7160e01b600052602260045260246000fd5b50919050565b8183526000602080850194508260005b85811015620019535781356200193781620015f8565b6001600160a01b03168752958201959082019060010162001921565b509495945050505050565b6020815260006200197460208301848662001911565b949350505050565b6000602082840312156200198f57600080fd5b5051919050565b602080825260149082015273199858dd1bdc9e481a5cc81858985b991bdb995960621b604082015260600190565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038381168252604060208084018290528451918401829052600092858201929091906060860190855b8181101562001a2a57855185168352948301949183019160010162001a0a565b509098975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6000808335601e1984360301811262001a6657600080fd5b83016020810192503590506001600160401b0381111562001a8657600080fd5b8036038213156200168757600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b80356001600160f81b03811681146200161b57600080fd5b801515811462000f7e57600080fd5b80356200161b8162001ad7565b8054600090600181811c908083168062001b0e57607f831692505b6020808410820362001b3057634e487b7160e01b600052602260045260246000fd5b8388526020880182801562001b4e576001811462001b655762001b92565b60ff198716825285151560051b8201975062001b92565b60008981526020902060005b8781101562001b8c5781548482015290860190840162001b71565b83019850505b5050505050505092915050565b60608152600062001bb1858662001a4e565b61018080606086015262001bcb6101e08601838562001a96565b925062001bdc602089018962001a4e565b868503605f19016080880152925062001bf784848362001a96565b93505062001c08604089016200160e565b915062001c1960a0860183620015d7565b62001c27606089016200160e565b915062001c3860c0860183620015d7565b62001c46608089016200160e565b915062001c5760e0860183620015d7565b62001c6560a089016200160e565b915061010062001c7881870184620015d7565b62001c8660c08a016200160e565b925061012062001c9981880185620015d7565b62001ca760e08b016200160e565b935061014062001cba81890186620015d7565b62001cc7838c0162001abf565b9450610160925062001ce3838901866001600160f81b03169052565b62001cf0828c0162001ae6565b80151589860152945062001d06818c0162001ae6565b9450505062001d1a6101a087018415159052565b62001d27818a0162001ae6565b9250505062001d3b6101c085018215159052565b5062001d4b6020840186620015d7565b8281036040840152620014d0818562001af3565b634e487b7160e01b600052603260045260246000fd5b60008235603e1983360301811262001d8c57600080fd5b9190910192915050565b6000808335601e1984360301811262001dae57600080fd5b8301803591506001600160401b0382111562001dc957600080fd5b6020019150368190038213156200168757600080fd5b8183823760009101908152919050565b81835260006001600160fb1b0383111562001e0957600080fd5b8260051b80836020870137939093016020019392505050565b60608152600062001e3860608301888a62001911565b828103602084015262001e4d81878962001def565b9050828103604084015262001e6481858762001def565b9998505050505050505050565b60006001820162001e9257634e487b7160e01b600052601160045260246000fd5b5060010190565b60006020828403121562001eac57600080fd5b8151620012f88162001ad7565b6000825162001d8c8184602087016200156e56fe60c0604052600a608090815269041646d696e41434c56360b41b60a05260009061002990826100ef565b5034801561003657600080fd5b50600180546001600160a01b031916331790556101ae565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061007857607f821691505b60208210810361009857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156100ea576000816000526020600020601f850160051c810160208610156100c75750805b601f850160051c820191505b818110156100e6578281556001016100d3565b5050505b505050565b81516001600160401b038111156101085761010861004e565b61011c816101168454610064565b8461009e565b602080601f83116001811461015157600084156101395750858301515b600019600386901b1c1916600185901b1785556100e6565b600085815260208120601f198616915b8281101561018057888601518255948401946001909101908401610161565b508582101561019e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610762806101bd6000396000f3fe608060405234801561001057600080fd5b506004361061006d5760003560e01c806301ffc9a71461007257806305de62c01461009a57806329575f6a146100be578063377a7d1a146100de578063985d1968146100f3578063bcc91a1014610106578063c81a396e14610119575b600080fd5b6100856100803660046104a9565b61012e565b60405190151581526020015b60405180910390f35b6100856100a83660046104e2565b50506001546001600160a01b0391821691161490565b6001546100d1906001600160a01b031681565b6040516100919190610525565b6100f16100ec366004610539565b610180565b005b6100f16101013660046105be565b610218565b6100f16101143660046105d9565b610298565b6101216103fe565b604051610091919061060c565b60006001600160e01b03198216633001c1ef60e21b148061015f57506001600160e01b03198216631bbd3e8d60e11b145b8061017a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6001546001600160a01b031633146101b35760405162461bcd60e51b81526004016101aa9061065b565b60405180910390fd5b600180546001600160a01b038581166001600160a01b0319831681179093556040519116919082907f3f6845104f9728af7979eed8814320daba008953c8db93b9fe32602d1f34b4759061020a9087908790610684565b60405180910390a350505050565b6001546001600160a01b031633146102425760405162461bcd60e51b81526004016101aa9061065b565b806001600160a01b031663715018a66040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561027d57600080fd5b505af1158015610291573d6000803e3d6000fd5b5050505050565b6001546001600160a01b031633146102c25760405162461bcd60e51b81526004016101aa9061065b565b6040516301ffc9a760e01b8152633001c1ef60e21b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa15801561030d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033191906106d0565b61039c5760405162461bcd60e51b815260206004820152603660248201527f41646d696e41434c56303a206e65772061646d696e2041434c20646f6573206e60448201527506f7420737570706f7274204941646d696e41434c56360541b60648201526084016101aa565b60405163f2fde38b60e01b81526001600160a01b0383169063f2fde38b906103c8908490600401610525565b600060405180830381600087803b1580156103e257600080fd5b505af11580156103f6573d6000803e3d6000fd5b505050505050565b6000805461040b906106f2565b80601f0160208091040260200160405190810160405280929190818152602001828054610437906106f2565b80156104845780601f1061045957610100808354040283529160200191610484565b820191906000526020600020905b81548152906001019060200180831161046757829003601f168201915b505050505081565b80356001600160e01b0319811681146104a457600080fd5b919050565b6000602082840312156104bb57600080fd5b6104c48261048c565b9392505050565b80356001600160a01b03811681146104a457600080fd5b6000806000606084860312156104f757600080fd5b610500846104cb565b925061050e602085016104cb565b915061051c6040850161048c565b90509250925092565b6001600160a01b0391909116815260200190565b60008060006040848603121561054e57600080fd5b610557846104cb565b925060208401356001600160401b038082111561057357600080fd5b818601915086601f83011261058757600080fd5b81358181111561059657600080fd5b8760208260051b85010111156105ab57600080fd5b6020830194508093505050509250925092565b6000602082840312156105d057600080fd5b6104c4826104cb565b600080604083850312156105ec57600080fd5b6105f5836104cb565b9150610603602084016104cb565b90509250929050565b60006020808352835180602085015260005b8181101561063a5785810183015185820160400152820161061e565b506000604082860101526040601f19601f8301168501019250505092915050565b6020808252600f908201526e27b7363c9039bab832b920b236b4b760891b604082015260600190565b60208082528181018390526000908460408401835b868110156106c5576001600160a01b036106b2846104cb565b1682529183019190830190600101610699565b509695505050505050565b6000602082840312156106e257600080fd5b815180151581146104c457600080fd5b600181811c9082168061070657607f821691505b60208210810361072657634e487b7160e01b600052602260045260246000fd5b5091905056fea2646970667358221220830f3c30ad4d14df1865965a76cbb302e6938979ee6e646e3a277a8abebb5fd164736f6c63430008160033a26469706673582212200750368963d281eadeb2667f0d1409504d011ab31a68b6699554729037b78c7e64736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000f74f006ce6480042f001c45c928d1ae6e70000000000000000000000000066009b13b8dfdabbe07800ee00004b008257d90000000000000000000000002ee7b9bb2e038be7323a119701a191c030a61ec600000000000000000000000000df4e8d293d57718aac0b18cbfbe128c5d484ef00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001b68747470733a2f2f746f6b656e2e617274626c6f636b732e696f2f0000000000
-----Decoded View---------------
Arg [0] : engineImplementation_ (address): 0x000000F74f006CE6480042f001c45c928D1Ae6E7
Arg [1] : engineFlexImplementation_ (address): 0x0066009B13b8DfDabbE07800ee00004b008257D9
Arg [2] : coreRegistry_ (address): 0x2eE7B9bB2E038bE7323A119701A191c030A61ec6
Arg [3] : owner_ (address): 0x00df4E8d293d57718aac0B18cBfBE128c5d484Ef
Arg [4] : defaultBaseURIHost_ (string): https://token.artblocks.io/
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000f74f006ce6480042f001c45c928d1ae6e7
Arg [1] : 0000000000000000000000000066009b13b8dfdabbe07800ee00004b008257d9
Arg [2] : 0000000000000000000000002ee7b9bb2e038be7323a119701a191c030a61ec6
Arg [3] : 00000000000000000000000000df4e8d293d57718aac0b18cbfbe128c5d484ef
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [5] : 000000000000000000000000000000000000000000000000000000000000001b
Arg [6] : 68747470733a2f2f746f6b656e2e617274626c6f636b732e696f2f0000000000
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.