Feature Tip: Add private address tag to any address under My Name Tag !
ERC-1155
Overview
Max Total Supply
102 DRIVERS
Holders
83
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
DriversOpenEditions
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.17; /** ########## ########## ##### ##### ##### ############ ########## ########## ############ ############ ##### ##### ##### ############ ############ ############ ##### ##### ##### ###### ##### ##### ##### ############ ##### ###### ###### ###### ##### ##### ##### ##### ##### ##### ##### ##### ##### ##### ###### ###### ##### ##### ##### ##### ##### #### #### ##### ##### ##### ####### ##### ##### ##### ##### ##### #### #### ########## ##### ##### ########## ##### ##### ########### ##### #### #### ########## ########### ########### ##### ##### ############ ##### #### #### ##### ############ ####### ##### ##### ##### ##### ##### #### #### ##### ##### ##### ###### ###### ##### ##### ##### ##### ##### ########## ############ ##### ##### ###### ###### ############ ##### ##### ##### ######## ############ ##### ##### ############ ########## ##### ##### ##### #### ############ ##### ##### ########## By Everfresh */ import "./ERC1155Base.sol"; /** * @author Fount Gallery * @title Drivers Open Editions by Everfresh * @notice Drivers is celebrated motion artist Everfresh's first Fount Gallery release. Driven by * the rhythm of skate culture and dance, the Drivers collection delivers an immersive world of * form and flow. * * Features: * - Open edition NFTs * - ERC-1155 lazy minting * - Flexible minting conditions with EIP-712 signatures or on-chain Fount Card checks * - Swappable metadata contract * - On-chain royalties standard (EIP-2981) * - Support for OpenSea's Operator Filterer to allow royalties */ contract DriversOpenEditions is ERC1155Base { /* ------------------------------------------------------------------------ S T O R A G E ------------------------------------------------------------------------ */ /// @dev Stores information about a given token struct TokenData { uint128 price; uint32 startTime; uint32 endTime; uint32 collected; uint16 perAddressAllowance; bool fountExclusive; bool requiresSig; } /// @dev Mapping of token id to token data mapping(uint256 => TokenData) internal _idToTokenData; /* ------------------------------------------------------------------------ E R R O R S ------------------------------------------------------------------------ */ /** TOKEN DATA ---------------------------------------------------------- */ error TokenDataDoesNotExist(); error TokenDataAlreadyExists(); error CannotSetStartTimeToZero(); error CannotSetEndTimeToThePast(); /** SALE CONDITIONS ---------------------------------------------------- */ error RequiresFountCard(); error RequiresSignature(); error InvalidSignature(); /** PURCHASING --------------------------------------------------------- */ error NotForSale(); error IncorrectPaymentAmount(); error AmountExceedsMaxWalletMint(); error AmountExceedsWalletAllowance(); /** EDITIONS ----------------------------------------------------------- */ error OpenEditionEnded(); error OpenEditionNotStartedYet(); /* ------------------------------------------------------------------------ E V E N T S ------------------------------------------------------------------------ */ event TokenDataAdded(uint256 indexed id, TokenData tokenData); event TokenDataSaleTimesUpdated(uint256 indexed id, TokenData tokenData); event TokenDataSalePriceUpdated(uint256 indexed id, TokenData tokenData); event TokenDataSaleConditionsUpdated(uint256 indexed id, TokenData tokenData); event CollectedOpenEdition(uint256 indexed id); /* ------------------------------------------------------------------------ I N I T ------------------------------------------------------------------------ */ /** * @param owner_ The owner of the contract * @param admin_ The admin of the contract * @param payments_ The address where payments should be sent * @param royaltiesAmount_ The royalty percentage with two decimals (10,000 = 100%) * @param metadata_ The initial metadata contract address * @param fountCard_ The address of the Fount Gallery Patron Card */ constructor( address owner_, address admin_, address payments_, uint256 royaltiesAmount_, address metadata_, address fountCard_ ) ERC1155Base(owner_, admin_, payments_, royaltiesAmount_, metadata_, fountCard_) {} /* ------------------------------------------------------------------------ O P E N E D I T I O N S ------------------------------------------------------------------------ */ /** * @notice Mints a number of editions from an open edition NFT * @dev Calls internal `_collectEdition` for logic. * * Reverts if: * - the edition requires an off-chain signature * - see `_collectEdition` for other conditions * * @param id The id of the edition * @param amount The amount to mint * @param to The address to mint the token to */ function collectEdition( uint256 id, uint256 amount, address to ) external payable { TokenData memory tokenData = _idToTokenData[id]; if (tokenData.requiresSig) revert RequiresSignature(); _collectEdition(id, amount, to, tokenData); } /** * @notice Mints a number of editions from an open edition NFT with an off-chain signature * @dev Calls internal `_collectEdition` for logic. * * Reverts if: * - the edition requires an off-chain signature and the signature is invalid * - see `_collectEdition` for other conditions * * @param id The id of the edition * @param amount The amount to mint * @param to The address to mint the token to * @param signature The off-chain signature which permits a mint */ function collectEdition( uint256 id, uint256 amount, address to, bytes calldata signature ) external payable { TokenData memory tokenData = _idToTokenData[id]; if (tokenData.requiresSig && !_verifyMintSignature(id, amount, to, signature)) { revert InvalidSignature(); } _collectEdition(id, amount, to, tokenData); } /** * @notice Internal function to mint some editions with some conditions * @dev Allows minting to a different address from msg.sender. * * Reverts if: * - the edition has not started * - the edition has ended * - msg.value does not equal the required amount * - the edition requires a Fount Card, but `to` does not hold one * * @param id The token id of the edition * @param amount The amount of editions to mint * @param to The address to mint the token to * @param tokenData Information about the token */ function _collectEdition( uint256 id, uint256 amount, address to, TokenData memory tokenData ) internal { uint256 mintAmount = amount; // Check to see if the edition is mintable and the price is correct if (tokenData.startTime > block.timestamp) revert OpenEditionNotStartedYet(); if (tokenData.endTime > 0 && block.timestamp > tokenData.endTime) revert OpenEditionEnded(); if (tokenData.price > 0 && tokenData.price * amount != msg.value) { revert IncorrectPaymentAmount(); } // Check if it's a Fount Gallery exclusive if (tokenData.fountExclusive && !_isFountCardHolder(to)) revert RequiresFountCard(); // Check if there's a cap on mints per wallet if (tokenData.perAddressAllowance > 0) { // Check the amount doesn't exceed the per wallet allowance to mint if (amount > tokenData.perAddressAllowance) revert AmountExceedsMaxWalletMint(); // Get the accounts remaining balance for this edition uint256 currentBalance = balanceOf[to][id]; uint256 remainingAllowance = currentBalance >= tokenData.perAddressAllowance ? 0 : tokenData.perAddressAllowance - currentBalance; // Set the mint amount based on the remaining allowance of `to` if (amount > remainingAllowance) { mintAmount = remainingAllowance; } // If there's no allowed tokens to mint, then revert if (mintAmount == 0) revert AmountExceedsWalletAllowance(); // If the request amount was over the actual mint amount, refund any ETH to the msg.sender if (tokenData.price > 0 && amount > mintAmount) { _transferETHWithFallback(msg.sender, (amount - mintAmount) * tokenData.price); } } // Add the new mint to the token data unchecked { tokenData.collected += uint32(mintAmount); } _idToTokenData[id] = tokenData; // Mint the NFT to the `to` address _mintToArtistFirst(to, id, mintAmount); emit CollectedOpenEdition(id); } /* ------------------------------------------------------------------------ A D M I N ------------------------------------------------------------------------ */ /** ADD TOKEN DATA ----------------------------------------------------- */ /** * @notice Admin function to make a token available for sale * @dev As soon as the token data is registered, the NFT will be available to collect. * * Reverts if: * - `startTime` is zero (used to check if a token can be sold or not) * - `endTime` is in the past * - the token data already exists (to update token data, use the other admin * functions to set price and sale conditions) * * @param id The token id * @param price The sale price, if any * @param startTime The start time of the sale * @param endTime The end time of the sale, if any * @param mintPerAddress The max amount that can be minted for a wallet, if any * @param fountExclusive If the sale requires a Fount Gallery Patron card * @param requiresSig If the sale requires an off-chain signature */ function addTokenForSale( uint256 id, uint128 price, uint32 startTime, uint32 endTime, uint16 mintPerAddress, bool fountExclusive, bool requiresSig ) external onlyOwnerOrAdmin { // Check that start time is valid. This value is used to check if the token data // exists. Setting to zero will effectively "delete" the token data for other functions. if (startTime == 0) revert CannotSetStartTimeToZero(); // Check the end time is not in the past if (endTime > 0 && block.timestamp > endTime) revert CannotSetEndTimeToThePast(); TokenData memory tokenData = _idToTokenData[id]; // Check the token data is empty before adding if (tokenData.startTime != 0) revert TokenDataAlreadyExists(); // Set the new token data tokenData.price = price; tokenData.startTime = startTime; tokenData.endTime = endTime; tokenData.perAddressAllowance = mintPerAddress; tokenData.fountExclusive = fountExclusive; tokenData.requiresSig = requiresSig; _idToTokenData[id] = tokenData; emit TokenDataAdded(id, tokenData); } /** SET SALE PRICE ----------------------------------------------------- */ /** * @notice Admin function to update the sale price for a token * @dev Sets the start and end time values for a token. Setting `endTime` to zero * effectively keeps the edition open forever. * * Reverts if: * - `startTime` is zero (used to check if a token can be sold or not) * - `endTime` is in the past * - the token data does not exist, must be added with `addTokenForSale` first * * @param id The token id * @param startTime The new start time of the sale * @param endTime The new end time of the sale */ function setTokenSaleTimes( uint256 id, uint32 startTime, uint32 endTime ) external onlyOwnerOrAdmin { // Check that start time is not zero. This value is used to check if the token data // exists. Setting to zero will effectively "delete" the token data for other functions. if (startTime == 0) revert CannotSetStartTimeToZero(); // Check the end time is not in the past if (endTime > 0 && block.timestamp > endTime) revert CannotSetEndTimeToThePast(); TokenData memory tokenData = _idToTokenData[id]; // Check the token data already exists. // If not, it should be created with `addTokenForSale` first. if (tokenData.startTime == 0) revert TokenDataDoesNotExist(); // Set the new sale price tokenData.startTime = startTime; tokenData.endTime = endTime; _idToTokenData[id] = tokenData; emit TokenDataSaleTimesUpdated(id, tokenData); } /** SET SALE TIMES ----------------------------------------------------- */ /** * @notice Admin function to update the sale price for a token * @dev Reverts if the token data does not exist. Must be added with `addTokenForSale` first. * @param id The token id * @param price The new sale price */ function setTokenSalePrice(uint256 id, uint128 price) external onlyOwnerOrAdmin { TokenData memory tokenData = _idToTokenData[id]; // Check the token data already exists. // If not, it should be created with `addTokenForSale` first. if (tokenData.startTime == 0) revert TokenDataDoesNotExist(); // Set the new sale price tokenData.price = price; _idToTokenData[id] = tokenData; emit TokenDataSalePriceUpdated(id, tokenData); } /** SET SALE CONDITIONS ------------------------------------------------ */ /** * @notice Admin function to update the sale conditions for a token * @dev Reverts if the token data does not exist. Must be added with `addTokenForSale` first. * @param id The token id * @param mintPerAddress The max amount that can be minted for a wallet, if any * @param fountExclusive If the sale requires a Fount Gallery Patron card * @param requiresSig If the sale requires an off-chain signature */ function setTokenSaleConditions( uint256 id, uint16 mintPerAddress, bool fountExclusive, bool requiresSig ) external onlyOwnerOrAdmin { TokenData memory tokenData = _idToTokenData[id]; // Check the token data already exists. // If not, it should be created with `addTokenForSale` first. if (tokenData.startTime == 0) revert TokenDataDoesNotExist(); tokenData.perAddressAllowance = mintPerAddress; tokenData.fountExclusive = fountExclusive; tokenData.requiresSig = requiresSig; _idToTokenData[id] = tokenData; emit TokenDataSaleConditionsUpdated(id, tokenData); } /* ------------------------------------------------------------------------ G E T T E R S ------------------------------------------------------------------------ */ function tokenPrice(uint256 id) external view returns (uint256) { return _idToTokenData[id].price; } function tokenStartTime(uint256 id) external view returns (uint256) { return _idToTokenData[id].startTime; } function tokenEndTime(uint256 id) external view returns (uint256) { return _idToTokenData[id].endTime; } function tokenCollectedCount(uint256 id) external view returns (uint256) { return _idToTokenData[id].collected; } function tokenAllowancePerAddress(uint256 id) external view returns (uint256) { return _idToTokenData[id].perAddressAllowance; } function tokenRemainingAllowanceForAddress(uint256 id, address account) external view returns (uint256) { TokenData memory tokenData = _idToTokenData[id]; uint256 currentBalance = balanceOf[account][id]; uint256 remainingAllowance = currentBalance > tokenData.perAddressAllowance ? 0 : tokenData.perAddressAllowance - currentBalance; return remainingAllowance; } function tokenIsFountExclusive(uint256 id) external view returns (bool) { return _idToTokenData[id].fountExclusive; } function tokenRequiresOffChainSignatureToMint(uint256 id) external view returns (bool) { return _idToTokenData[id].requiresSig; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Optimized and flexible operator filterer to abide to OpenSea's /// mandatory on-chain royalty enforcement in order for new collections to /// receive royalties. /// For more information, see: /// See: https://github.com/ProjectOpenSea/operator-filter-registry abstract contract OperatorFilterer { /// @dev The default OpenSea operator blocklist subscription. address internal constant _DEFAULT_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6; /// @dev The OpenSea operator filter registry. address internal constant _OPERATOR_FILTER_REGISTRY = 0x000000000000AAeB6D7670E522A718067333cd4E; /// @dev Registers the current contract to OpenSea's operator filter, /// and subscribe to the default OpenSea operator blocklist. /// Note: Will not revert nor update existing settings for repeated registration. function _registerForOperatorFiltering() internal virtual { _registerForOperatorFiltering(_DEFAULT_SUBSCRIPTION, true); } /// @dev Registers the current contract to OpenSea's operator filter. /// Note: Will not revert nor update existing settings for repeated registration. function _registerForOperatorFiltering(address subscriptionOrRegistrantToCopy, bool subscribe) internal virtual { /// @solidity memory-safe-assembly assembly { let functionSelector := 0x7d3e3dbe // `registerAndSubscribe(address,address)`. // Clean the upper 96 bits of `subscriptionOrRegistrantToCopy` in case they are dirty. subscriptionOrRegistrantToCopy := shr(96, shl(96, subscriptionOrRegistrantToCopy)) for {} iszero(subscribe) {} { if iszero(subscriptionOrRegistrantToCopy) { functionSelector := 0x4420e486 // `register(address)`. break } functionSelector := 0xa0af2903 // `registerAndCopyEntries(address,address)`. break } // Store the function selector. mstore(0x00, shl(224, functionSelector)) // Store the `address(this)`. mstore(0x04, address()) // Store the `subscriptionOrRegistrantToCopy`. mstore(0x24, subscriptionOrRegistrantToCopy) // Register into the registry. if iszero(call(gas(), _OPERATOR_FILTER_REGISTRY, 0, 0x00, 0x44, 0x00, 0x04)) { // If the function selector has not been overwritten, // it is an out-of-gas error. if eq(shr(224, mload(0x00)), functionSelector) { // To prevent gas under-estimation. revert(0, 0) } } // Restore the part of the free memory pointer that was overwritten, // which is guaranteed to be zero, because of Solidity's memory size limits. mstore(0x24, 0) } } /// @dev Modifier to guard a function and revert if the caller is a blocked operator. modifier onlyAllowedOperator(address from) virtual { if (from != msg.sender) { if (!_isPriorityOperator(msg.sender)) { if (_operatorFilteringEnabled()) _revertIfBlocked(msg.sender); } } _; } /// @dev Modifier to guard a function from approving a blocked operator.. modifier onlyAllowedOperatorApproval(address operator) virtual { if (!_isPriorityOperator(operator)) { if (_operatorFilteringEnabled()) _revertIfBlocked(operator); } _; } /// @dev Helper function that reverts if the `operator` is blocked by the registry. function _revertIfBlocked(address operator) private view { /// @solidity memory-safe-assembly assembly { // Store the function selector of `isOperatorAllowed(address,address)`, // shifted left by 6 bytes, which is enough for 8tb of memory. // We waste 6-3 = 3 bytes to save on 6 runtime gas (PUSH1 0x224 SHL). mstore(0x00, 0xc6171134001122334455) // Store the `address(this)`. mstore(0x1a, address()) // Store the `operator`. mstore(0x3a, operator) // `isOperatorAllowed` always returns true if it does not revert. if iszero(staticcall(gas(), _OPERATOR_FILTER_REGISTRY, 0x16, 0x44, 0x00, 0x00)) { // Bubble up the revert if the staticcall reverts. returndatacopy(0x00, 0x00, returndatasize()) revert(0x00, returndatasize()) } // We'll skip checking if `from` is inside the blacklist. // Even though that can block transferring out of wrapper contracts, // we don't want tokens to be stuck. // Restore the part of the free memory pointer that was overwritten, // which is guaranteed to be zero, if less than 8tb of memory is used. mstore(0x3a, 0) } } /// @dev For deriving contracts to override, so that operator filtering /// can be turned on / off. /// Returns true by default. function _operatorFilteringEnabled() internal view virtual returns (bool) { return true; } /// @dev For deriving contracts to override, so that preferred marketplaces can /// skip operator filtering, helping users save gas. /// Returns false for all inputs by default. function _isPriorityOperator(address) internal view virtual returns (bool) { return false; } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.15; /** * @author Sam King (samkingstudio.eth) for Fount Gallery * @title Simple owner and admin authentication * @notice Allows the management of a contract by using simple ownership and admin modifiers. */ abstract contract Auth { /* ------------------------------------------------------------------------ S T O R A G E ------------------------------------------------------------------------ */ /// @notice Current owner of the contract address public owner; /// @notice Current admins of the contract mapping(address => bool) public admins; /* ------------------------------------------------------------------------ E V E N T S ------------------------------------------------------------------------ */ /** * @notice When the contract owner is updated * @param user The account that updated the new owner * @param newOwner The new owner of the contract */ event OwnerUpdated(address indexed user, address indexed newOwner); /** * @notice When an admin is added to the contract * @param user The account that added the new admin * @param newAdmin The admin that was added */ event AdminAdded(address indexed user, address indexed newAdmin); /** * @notice When an admin is removed from the contract * @param user The account that removed an admin * @param prevAdmin The admin that got removed */ event AdminRemoved(address indexed user, address indexed prevAdmin); /* ------------------------------------------------------------------------ M O D I F I E R S ------------------------------------------------------------------------ */ /** * @dev Only the owner can call */ modifier onlyOwner() { require(msg.sender == owner, "UNAUTHORIZED"); _; } /** * @dev Only an admin can call */ modifier onlyAdmin() { require(admins[msg.sender], "UNAUTHORIZED"); _; } /** * @dev Only the owner or an admin can call */ modifier onlyOwnerOrAdmin() { require((msg.sender == owner || admins[msg.sender]), "UNAUTHORIZED"); _; } /* ------------------------------------------------------------------------ I N I T ------------------------------------------------------------------------ */ /** * @dev Sets the initial owner and a first admin upon creation. * @param owner_ The initial owner of the contract * @param admin_ An initial admin of the contract */ constructor(address owner_, address admin_) { owner = owner_; emit OwnerUpdated(address(0), owner_); admins[admin_] = true; emit AdminAdded(address(0), admin_); } /* ------------------------------------------------------------------------ A D M I N ------------------------------------------------------------------------ */ /** * @notice Transfers ownership of the contract to `newOwner` * @dev Can only be called by the current owner or an admin * @param newOwner The new owner of the contract */ function setOwner(address newOwner) public virtual onlyOwnerOrAdmin { owner = newOwner; emit OwnerUpdated(msg.sender, newOwner); } /** * @notice Adds `newAdmin` as an amdin of the contract * @dev Can only be called by the current owner or an admin * @param newAdmin A new admin of the contract */ function addAdmin(address newAdmin) public virtual onlyOwnerOrAdmin { admins[newAdmin] = true; emit AdminAdded(address(0), newAdmin); } /** * @notice Removes `prevAdmin` as an amdin of the contract * @dev Can only be called by the current owner or an admin * @param prevAdmin The admin to remove */ function removeAdmin(address prevAdmin) public virtual onlyOwnerOrAdmin { admins[prevAdmin] = false; emit AdminRemoved(address(0), prevAdmin); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.15; import "openzeppelin/token/ERC1155/IERC1155.sol"; /** * @author Sam King (samkingstudio.eth) for Fount Gallery * @title Fount Gallery Card Check * @notice Utility functions to check ownership of a Fount Gallery Patron Card NFT */ contract FountCardCheck { /// @dev Address of the Fount Gallery Patron Card contract IERC1155 internal _fountCard; /// @dev Does not own a Fount Gallery Patron Card error NotFountCardHolder(); /** * @dev Does not own enough Fount Gallery Patron Cards * @param required The minimum amount of cards that need to be owned * @param owned The actualy amount of cards owned */ error DoesNotHoldEnoughFountCards(uint256 required, uint256 owned); /** * @dev Init with the Fount Gallery Patron Card contract address * @param fountCard The Fount Gallery Patron Card contract address */ constructor(address fountCard) { _fountCard = IERC1155(fountCard); } /** * @dev Modifier that only allows the caller to do something if they hold * a Fount Gallery Patron Card */ modifier onlyWhenFountCardHolder() { if (_getFountCardBalance(msg.sender) < 1) revert NotFountCardHolder(); _; } /** * @dev Modifier that only allows the caller to do something if they hold * at least a specific amount Fount Gallery Patron Cards * @param minAmount The minimum amount of cards that need to be owned */ modifier onlyWhenHoldingMinFountCards(uint256 minAmount) { uint256 balance = _getFountCardBalance(msg.sender); if (minAmount > balance) revert DoesNotHoldEnoughFountCards(minAmount, balance); _; } /** * @dev Get the number of Fount Gallery Patron Cards an address owns * @param owner The owner address to query * @return balance The balance of the owner */ function _getFountCardBalance(address owner) internal view returns (uint256 balance) { balance = _fountCard.balanceOf(owner, 1); } /** * @dev Check if an address holds at least one Fount Gallery Patron Card * @param owner The owner address to query * @return isHolder If the owner holds at least one card */ function _isFountCardHolder(address owner) internal view returns (bool isHolder) { isHolder = _getFountCardBalance(owner) > 0; } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.15; /** * @author Sam King (samkingstudio.eth) for Fount Gallery * @title Swappable metadata module * @notice Allows the use of a separate and swappable metadata contract */ abstract contract SwappableMetadata { /* ------------------------------------------------------------------------ S T O R A G E ------------------------------------------------------------------------ */ /// @notice Address of metadata contract address public metadata; /// @notice Flag for whether the metadata address can be updated or not bool public isMetadataLocked; /* ------------------------------------------------------------------------ E R R O R S ------------------------------------------------------------------------ */ error MetadataLocked(); /* ------------------------------------------------------------------------ E V E N T S ------------------------------------------------------------------------ */ /** * @dev When the metadata contract has been set * @param metadataContract The new metadata contract address */ event MetadataContractSet(address indexed metadataContract); /** * @dev When the metadata contract has been locked and is no longer swappable * @param metadataContract The final locked metadata contract address */ event MetadataContractLocked(address indexed metadataContract); /* ------------------------------------------------------------------------ I N I T ------------------------------------------------------------------------ */ /** * @param metadata_ The address of the initial metadata contract */ constructor(address metadata_) { metadata = metadata_; emit MetadataContractSet(metadata_); } /* ------------------------------------------------------------------------ A D M I N ------------------------------------------------------------------------ */ /** * @notice Sets the metadata address * @param metadata_ The new address of the metadata contract */ function _setMetadataAddress(address metadata_) internal { if (isMetadataLocked) revert MetadataLocked(); metadata = metadata_; emit MetadataContractSet(metadata_); } /** * @notice Sets the metadata address * @param metadata The new address of the metadata contract */ function setMetadataAddress(address metadata) public virtual; /** * @dev Locks the metadata address preventing further updates */ function _lockMetadata() internal { isMetadataLocked = true; emit MetadataContractLocked(metadata); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.15; import "openzeppelin/interfaces/IERC2981.sol"; /** * @author Sam King (samkingstudio.eth) for Fount Gallery * @title Royalty payments * @notice Support for the royalty standard (ERC-2981) */ abstract contract Royalties is IERC2981 { /* ------------------------------------------------------------------------ S T O R A G E ------------------------------------------------------------------------ */ /// @dev Store information about token royalties struct RoyaltyInfo { address receiver; uint96 amount; } /// @dev The current royalty information RoyaltyInfo internal _royaltyInfo; /// @dev Interface id for the royalty information standard /// bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a bytes4 internal constant ROYALTY_INTERFACE_ID = 0x2a55205a; /* ------------------------------------------------------------------------ E R R O R S ------------------------------------------------------------------------ */ error MoreThanOneHundredPercentRoyalty(); /* ------------------------------------------------------------------------ E V E N T S ------------------------------------------------------------------------ */ event RoyaltyInfoSet(address indexed receiver, uint256 indexed amount); event RoyaltyInfoUpdated(address indexed receiver, uint256 indexed amount); /* ------------------------------------------------------------------------ I N I T ------------------------------------------------------------------------ */ /** * @param royaltiesReceiver The receiver of royalty payments * @param royaltiesAmount The royalty percentage with two decimals (10,000 = 100%) */ constructor(address royaltiesReceiver, uint256 royaltiesAmount) { _royaltyInfo = RoyaltyInfo(royaltiesReceiver, uint96(royaltiesAmount)); emit RoyaltyInfoSet(royaltiesReceiver, royaltiesAmount); } /* ------------------------------------------------------------------------ E R C 2 9 8 1 ------------------------------------------------------------------------ */ /// @notice EIP-2981 royalty standard for on-chain royalties function royaltyInfo(uint256, uint256 salePrice) public view virtual returns (address receiver, uint256 royaltyAmount) { receiver = _royaltyInfo.receiver; royaltyAmount = (salePrice * _royaltyInfo.amount) / 100_00; } /* ------------------------------------------------------------------------ A D M I N ------------------------------------------------------------------------ */ /** * @dev Internal function to set the royalty information * @param receiver The receiver of royalty payments * @param amount The royalty percentage with two decimals (10,000 = 100%) */ function _setRoyaltyInfo(address receiver, uint256 amount) internal { if (amount > 100_00) revert MoreThanOneHundredPercentRoyalty(); _royaltyInfo = RoyaltyInfo(receiver, uint24(amount)); emit RoyaltyInfoUpdated(receiver, amount); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.15; import "openzeppelin/token/ERC20/IERC20.sol"; import "openzeppelin/token/ERC721/IERC721.sol"; import "openzeppelin/token/ERC1155/IERC1155.sol"; /** * @author Sam King (samkingstudio.eth) for Fount Gallery * @title Withdraw ETH and tokens module * @notice Allows the withdrawal of ETH, ERC20, ERC721, an ERC1155 tokens */ abstract contract Withdraw { /* ------------------------------------------------------------------------ E R R O R S ------------------------------------------------------------------------ */ error CannotWithdrawToZeroAddress(); error WithdrawFailed(); error BalanceTooLow(); error ZeroBalance(); /* ------------------------------------------------------------------------ W I T H D R A W ------------------------------------------------------------------------ */ function _withdrawETH(address to) internal { // Prevent withdrawing to the zero address if (to == address(0)) revert CannotWithdrawToZeroAddress(); // Check there is eth to withdraw uint256 balance = address(this).balance; if (balance == 0) revert ZeroBalance(); // Transfer funds (bool success, ) = payable(to).call{value: balance}(""); if (!success) revert WithdrawFailed(); } function _withdrawToken(address tokenAddress, address to) internal { // Prevent withdrawing to the zero address if (to == address(0)) revert CannotWithdrawToZeroAddress(); // Check there are tokens to withdraw uint256 balance = IERC20(tokenAddress).balanceOf(address(this)); if (balance == 0) revert ZeroBalance(); // Transfer tokens bool success = IERC20(tokenAddress).transfer(to, balance); if (!success) revert WithdrawFailed(); } function _withdrawERC721Token( address tokenAddress, uint256 id, address to ) internal { // Prevent withdrawing to the zero address if (to == address(0)) revert CannotWithdrawToZeroAddress(); // Check the NFT is in this contract address owner = IERC721(tokenAddress).ownerOf(id); if (owner != address(this)) revert ZeroBalance(); // Transfer NFT IERC721(tokenAddress).transferFrom(address(this), to, id); } function _withdrawERC1155Token( address tokenAddress, uint256 id, uint256 amount, address to ) internal { // Prevent withdrawing to the zero address if (to == address(0)) revert CannotWithdrawToZeroAddress(); // Check the tokens are owned by this contract, and there's at least `amount` uint256 balance = IERC1155(tokenAddress).balanceOf(address(this), id); if (balance == 0) revert ZeroBalance(); if (amount > balance) revert BalanceTooLow(); // Transfer tokens IERC1155(tokenAddress).safeTransferFrom(address(this), to, id, amount, ""); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ECDSA.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712 { /* solhint-disable var-name-mixedcase */ // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; address private immutable _CACHED_THIS; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _CACHED_THIS = address(this); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } }
// 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: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC1155 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event URI(string value, uint256 indexed id); /*////////////////////////////////////////////////////////////// ERC1155 STORAGE //////////////////////////////////////////////////////////////*/ mapping(address => mapping(uint256 => uint256)) public balanceOf; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// METADATA LOGIC //////////////////////////////////////////////////////////////*/ function uri(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC1155 LOGIC //////////////////////////////////////////////////////////////*/ function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public virtual { require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); balanceOf[from][id] -= amount; balanceOf[to][id] += amount; emit TransferSingle(msg.sender, from, to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public virtual { require(ids.length == amounts.length, "LENGTH_MISMATCH"); require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); // Storing these outside the loop saves ~15 gas per iteration. uint256 id; uint256 amount; for (uint256 i = 0; i < ids.length; ) { id = ids[i]; amount = amounts[i]; balanceOf[from][id] -= amount; balanceOf[to][id] += amount; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) public view virtual returns (uint256[] memory balances) { require(owners.length == ids.length, "LENGTH_MISMATCH"); balances = new uint256[](owners.length); // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < owners.length; ++i) { balances[i] = balanceOf[owners[i]][ids[i]]; } } } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { balanceOf[to][id] += amount; emit TransferSingle(msg.sender, address(0), to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[to][ids[i]] += amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, address(0), to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function _batchBurn( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[from][ids[i]] -= amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, address(0), ids, amounts); } function _burn( address from, uint256 id, uint256 amount ) internal virtual { balanceOf[from][id] -= amount; emit TransferSingle(msg.sender, from, address(0), id, amount); } } /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155TokenReceiver { function onERC1155Received( address, address, uint256, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] calldata, uint256[] calldata, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.17; import "solmate/tokens/ERC1155.sol"; import "fount-contracts/auth/Auth.sol"; import "fount-contracts/community/FountCardCheck.sol"; import "fount-contracts/extensions/SwappableMetadata.sol"; import "fount-contracts/utils/Royalties.sol"; import "fount-contracts/utils/Withdraw.sol"; import "closedsea/OperatorFilterer.sol"; import "openzeppelin/utils/cryptography/ECDSA.sol"; import "openzeppelin/utils/cryptography/EIP712.sol"; import "openzeppelin/token/ERC20/IERC20.sol"; import "./interfaces/IMetadata.sol"; import "./interfaces/IDriversPayments.sol"; import "./interfaces/IWETH.sol"; /** * @author Fount Gallery * @title ERC1155Base * @notice Base contract for Drivers Open Editions to inherit from * * Features: * - EIP-712 signature minting and verification * - On-chain checking of Fount Gallery Patron cards for minting * - Swappable metadata contract * - On-chain royalties standard (EIP-2981) * - Support for OpenSea's Operator Filterer to allow royalties */ abstract contract ERC1155Base is ERC1155, Auth, FountCardCheck, SwappableMetadata, Royalties, Withdraw, EIP712, OperatorFilterer { /* ------------------------------------------------------------------------ S T O R A G E ------------------------------------------------------------------------ */ /// @notice everfresh.eth address public everfresh = 0xBb3444a06E9928dDA9a739CdAb3E0c5cf6890099; /// @notice Contract information string public contractURI; /// @notice Contract name string public name = "Drivers Open Editions by Everfresh"; /// @notice Contract symbol string public symbol = "DRIVERS"; /// @notice EIP-712 signing domain string public constant SIGNING_DOMAIN = "DriversOpenEditions"; /// @notice EIP-712 signature version string public constant SIGNATURE_VERSION = "1"; /// @notice EIP-712 signed data type hash for minting with an off-chain signature bytes32 public constant MINT_SIGNATURE_TYPEHASH = keccak256("MintSignatureData(uint256 id,uint256 amount,address to,uint256 nonce)"); /// @dev EIP-712 signed data struct for minting with an off-chain signature struct MintSignatureData { uint256 id; uint256 amount; address to; uint256 nonce; bytes signature; } /// @notice Approved signer public addresses mapping(address => bool) public approvedSigners; /// @notice Nonce management to avoid signature replay attacks mapping(address => uint256) public nonces; /// @notice If operator filtering is applied bool public operatorFilteringEnabled; /// @notice Wrapped ETH contract address for safe ETH transfer fallbacks address public weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; /// @notice Address where proceeds should be sent address public payments; /* ------------------------------------------------------------------------ E R R O R S ------------------------------------------------------------------------ */ error CannotSetPaymentAddressToZero(); /* ------------------------------------------------------------------------ E V E N T S ------------------------------------------------------------------------ */ event Init(); /* ------------------------------------------------------------------------ I N I T ------------------------------------------------------------------------ */ /** * @param owner_ The owner of the contract * @param admin_ The admin of the contract * @param payments_ The admin of the contract * @param royaltiesAmount_ The royalty percentage with two decimals (10,000 = 100%) * @param metadata_ The initial metadata contract address * @param fountCard_ The address of the Fount Gallery Patron Card */ constructor( address owner_, address admin_, address payments_, uint256 royaltiesAmount_, address metadata_, address fountCard_ ) ERC1155() Auth(owner_, admin_) FountCardCheck(fountCard_) SwappableMetadata(metadata_) Royalties(payments_, royaltiesAmount_) EIP712(SIGNING_DOMAIN, SIGNATURE_VERSION) { payments = payments_; _registerForOperatorFiltering(); operatorFilteringEnabled = true; emit Init(); } /* ------------------------------------------------------------------------ A R T I S T M I N T I N G ------------------------------------------------------------------------ */ function _mintToArtistFirst( address to, uint256 id, uint256 amount ) internal { balanceOf[to][id] += amount; emit TransferSingle(msg.sender, address(0), everfresh, id, amount); emit TransferSingle(msg.sender, everfresh, to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received( msg.sender, everfresh, id, amount, "" ) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } /* ------------------------------------------------------------------------ S I G N A T U R E V E R I F I C A T I O N ------------------------------------------------------------------------ */ /** * @notice Internal function to verify an EIP-712 minting signature * @param id The token id * @param to The account that has approval to mint * @param signature The EIP-712 signature * @return bool If the signature is verified or not */ function _verifyMintSignature( uint256 id, uint256 amount, address to, bytes calldata signature ) internal returns (bool) { MintSignatureData memory data = MintSignatureData({ id: id, amount: amount, to: to, nonce: nonces[to], signature: signature }); // Hash the data for verification bytes32 digest = _hashTypedDataV4( keccak256( abi.encode( MINT_SIGNATURE_TYPEHASH, data.id, data.amount, data.to, nonces[data.to]++ ) ) ); // Verifiy signature is ok address addr = ECDSA.recover(digest, data.signature); return approvedSigners[addr] && addr != address(0); } /* ------------------------------------------------------------------------ A D M I N ------------------------------------------------------------------------ */ /** SIGNERS ------------------------------------------------------------ */ /** * @notice Admin function to set an EIP-712 signer address * @param signer The address of the new signer * @param approved If the signer is approved */ function setSigner(address signer, bool approved) external onlyOwnerOrAdmin { approvedSigners[signer] = approved; } /** METADATA ----------------------------------------------------------- */ /** * @notice Admin function to set the metadata contract address * @param metadata The new metadata contract address */ function setMetadataAddress(address metadata) public override onlyOwnerOrAdmin { _setMetadataAddress(metadata); } /** * @notice Admin function to set the contract URI for marketplaces * @param contractURI_ The new contract URI */ function setContractURI(string memory contractURI_) external onlyOwnerOrAdmin { contractURI = contractURI_; } /** ROYALTIES ---------------------------------------------------------- */ /** * @notice Admin function to set the royalty information * @param receiver The receiver of royalty payments * @param amount The royalty percentage with two decimals (10,000 = 100%) */ function setRoyaltyInfo(address receiver, uint256 amount) external onlyOwnerOrAdmin { _setRoyaltyInfo(receiver, amount); } /** * @notice Admin function to set whether OpenSea's Operator Filtering should be enabled * @param enabled If the operator filtering should be enabled */ function setOperatorFilteringEnabled(bool enabled) external onlyOwnerOrAdmin { operatorFilteringEnabled = enabled; } function registerForOperatorFiltering(address subscriptionOrRegistrantToCopy, bool subscribe) external onlyOwnerOrAdmin { _registerForOperatorFiltering(subscriptionOrRegistrantToCopy, subscribe); } /** PAYMENTS ----------------------------------------------------------- */ /** * @notice Admin function to set the payment address for withdrawing funds * @param paymentAddress The new address where payments should be sent upon withdrawal */ function setPaymentAddress(address paymentAddress) external onlyOwnerOrAdmin { if (paymentAddress == address(0)) revert CannotSetPaymentAddressToZero(); payments = paymentAddress; } /* ------------------------------------------------------------------------ R O T A L T I E S ------------------------------------------------------------------------ */ /** * @notice Add interface for on-chain royalty standard */ function supportsInterface(bytes4 interfaceId) public view override(ERC1155, IERC165) returns (bool) { return interfaceId == ROYALTY_INTERFACE_ID || super.supportsInterface(interfaceId); } /** * @notice Repeats the OpenSea Operator Filtering registration */ function repeatRegistration() public { _registerForOperatorFiltering(); } /** * @notice Override ERC-1155 `setApprovalForAll` to support OpenSea Operator Filtering */ function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) { super.setApprovalForAll(operator, approved); } /** * @notice Override ERC-1155 `safeTransferFrom` to support OpenSea Operator Filtering */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public override onlyAllowedOperator(from) { super.safeTransferFrom(from, to, id, amount, data); } /** * @notice Override ERC-1155 `safeTransferFrom` to support OpenSea Operator Filtering */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public virtual override onlyAllowedOperator(from) { super.safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Overrde `OperatorFilterer._operatorFilteringEnabled` to return whether * the operator filtering is enabled in this contract. */ function _operatorFilteringEnabled() internal view virtual override returns (bool) { return operatorFilteringEnabled; } /* ------------------------------------------------------------------------ S A F E T R A N S F E R S ------------------------------------------------------------------------ */ /** * @notice Safely transfer ETH by wrapping as WETH if the ETH transfer fails * @param to The address to transfer ETH/WETH to * @param amount The amount of ETH/WETH to transfer */ function _transferETHWithFallback(address to, uint256 amount) internal { if (!_transferETH(to, amount)) { IWETH(weth).deposit{value: amount}(); IERC20(weth).transfer(to, amount); } } /** * @notice Transfer ETH and return the success status. * @param to The address to transfer ETH to * @param amount The amount of ETH to transfer */ function _transferETH(address to, uint256 amount) internal returns (bool) { (bool success, ) = payable(to).call{value: amount}(new bytes(0)); return success; } /* ------------------------------------------------------------------------ E R C 1 1 5 5 ------------------------------------------------------------------------ */ /** * @notice Returns the token metadata * @return id The token id to get metadata for */ function uri(uint256 id) public view override returns (string memory) { return IMetadata(metadata).tokenURI(id); } /** * @notice Burn a token. You can only burn tokens you own. * @param id The token id to burn * @param amount The amount to burn */ function burn(uint256 id, uint256 amount) external { require(balanceOf[msg.sender][id] >= amount, "CANNOT_BURN"); _burn(msg.sender, id, amount); } /* ------------------------------------------------------------------------ W I T H D R A W ------------------------------------------------------------------------ */ /** * @notice Admin function to withdraw ETH from this contract * @dev Withdraws to the `payments` address. * * Reverts if: * - there are active auctions * - the payments address is set to zero * */ function withdrawETH() public onlyOwnerOrAdmin { // Send the eth to the payments address _withdrawETH(payments); } /** * @notice Admin function to withdraw ETH from this contract and release from payments contract * @dev Withdraws to the `payments` address, then calls `releaseAllETH` as a splitter. * * Reverts if: * - there are active auctions * - the payments address is set to zero * */ function withdrawAndReleaseAllETH() public onlyOwnerOrAdmin { // Send the eth to the payments address _withdrawETH(payments); // And then release all the ETH to the payees IDriversPayments(payments).releaseAllETH(); } /** * @notice Admin function to withdraw ERC-20 tokens from this contract * @dev Withdraws to the `payments` address. * * Reverts if: * - the payments address is set to zero * */ function withdrawTokens(address tokenAddress) public onlyOwnerOrAdmin { // Send the tokens to the payments address _withdrawToken(tokenAddress, payments); } /** * @notice Admin function to withdraw ERC-20 tokens from this contract * @param to The address to send the ERC-20 tokens to */ function withdrawTokens(address tokenAddress, address to) public onlyOwnerOrAdmin { _withdrawToken(tokenAddress, to); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.17; interface IDriversPayments { function releaseAllETH() external; function releaseAllToken(address tokenAddress) external; }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.17; interface IMetadata { function tokenURI(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.17; interface IWETH { function deposit() external payable; function withdraw(uint256 wad) external; function transfer(address to, uint256 value) external returns (bool); }
{ "remappings": [ "closedsea/=packages/contracts/lib/closedsea/src/", "ds-test/=packages/contracts/lib/ds-test/src/", "erc4626-tests/=packages/contracts/lib/closedsea/lib/openzeppelin-contracts/lib/erc4626-tests/", "erc721a-upgradeable/=packages/contracts/lib/closedsea/lib/erc721a-upgradeable/contracts/", "erc721a/=packages/contracts/lib/closedsea/lib/erc721a/contracts/", "ethier/=packages/contracts/lib/fount-contracts/lib/ethier/", "forge-std/=packages/contracts/lib/forge-std/src/", "fount-contracts/=packages/contracts/lib/fount-contracts/src/", "fount-drivers/=packages/contracts/src/", "openzeppelin-contracts-upgradeable/=packages/contracts/lib/closedsea/lib/openzeppelin-contracts-upgradeable/contracts/", "openzeppelin-contracts/=packages/contracts/lib/openzeppelin-contracts/", "openzeppelin/=packages/contracts/lib/openzeppelin-contracts/contracts/", "operator-filter-registry/=packages/contracts/lib/closedsea/lib/operator-filter-registry/src/", "solmate/=packages/contracts/lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"admin_","type":"address"},{"internalType":"address","name":"payments_","type":"address"},{"internalType":"uint256","name":"royaltiesAmount_","type":"uint256"},{"internalType":"address","name":"metadata_","type":"address"},{"internalType":"address","name":"fountCard_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AmountExceedsMaxWalletMint","type":"error"},{"inputs":[],"name":"AmountExceedsWalletAllowance","type":"error"},{"inputs":[],"name":"BalanceTooLow","type":"error"},{"inputs":[],"name":"CannotSetEndTimeToThePast","type":"error"},{"inputs":[],"name":"CannotSetPaymentAddressToZero","type":"error"},{"inputs":[],"name":"CannotSetStartTimeToZero","type":"error"},{"inputs":[],"name":"CannotWithdrawToZeroAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"},{"internalType":"uint256","name":"owned","type":"uint256"}],"name":"DoesNotHoldEnoughFountCards","type":"error"},{"inputs":[],"name":"IncorrectPaymentAmount","type":"error"},{"inputs":[],"name":"InvalidSignature","type":"error"},{"inputs":[],"name":"MetadataLocked","type":"error"},{"inputs":[],"name":"MoreThanOneHundredPercentRoyalty","type":"error"},{"inputs":[],"name":"NotForSale","type":"error"},{"inputs":[],"name":"NotFountCardHolder","type":"error"},{"inputs":[],"name":"OpenEditionEnded","type":"error"},{"inputs":[],"name":"OpenEditionNotStartedYet","type":"error"},{"inputs":[],"name":"RequiresFountCard","type":"error"},{"inputs":[],"name":"RequiresSignature","type":"error"},{"inputs":[],"name":"TokenDataAlreadyExists","type":"error"},{"inputs":[],"name":"TokenDataDoesNotExist","type":"error"},{"inputs":[],"name":"WithdrawFailed","type":"error"},{"inputs":[],"name":"ZeroBalance","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"prevAdmin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"CollectedOpenEdition","type":"event"},{"anonymous":false,"inputs":[],"name":"Init","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"metadataContract","type":"address"}],"name":"MetadataContractLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"metadataContract","type":"address"}],"name":"MetadataContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RoyaltyInfoSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RoyaltyInfoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint128","name":"price","type":"uint128"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"collected","type":"uint32"},{"internalType":"uint16","name":"perAddressAllowance","type":"uint16"},{"internalType":"bool","name":"fountExclusive","type":"bool"},{"internalType":"bool","name":"requiresSig","type":"bool"}],"indexed":false,"internalType":"struct DriversOpenEditions.TokenData","name":"tokenData","type":"tuple"}],"name":"TokenDataAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint128","name":"price","type":"uint128"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"collected","type":"uint32"},{"internalType":"uint16","name":"perAddressAllowance","type":"uint16"},{"internalType":"bool","name":"fountExclusive","type":"bool"},{"internalType":"bool","name":"requiresSig","type":"bool"}],"indexed":false,"internalType":"struct DriversOpenEditions.TokenData","name":"tokenData","type":"tuple"}],"name":"TokenDataSaleConditionsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint128","name":"price","type":"uint128"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"collected","type":"uint32"},{"internalType":"uint16","name":"perAddressAllowance","type":"uint16"},{"internalType":"bool","name":"fountExclusive","type":"bool"},{"internalType":"bool","name":"requiresSig","type":"bool"}],"indexed":false,"internalType":"struct DriversOpenEditions.TokenData","name":"tokenData","type":"tuple"}],"name":"TokenDataSalePriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"uint128","name":"price","type":"uint128"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint32","name":"collected","type":"uint32"},{"internalType":"uint16","name":"perAddressAllowance","type":"uint16"},{"internalType":"bool","name":"fountExclusive","type":"bool"},{"internalType":"bool","name":"requiresSig","type":"bool"}],"indexed":false,"internalType":"struct DriversOpenEditions.TokenData","name":"tokenData","type":"tuple"}],"name":"TokenDataSaleTimesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"MINT_SIGNATURE_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNATURE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNING_DOMAIN","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint128","name":"price","type":"uint128"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"},{"internalType":"uint16","name":"mintPerAddress","type":"uint16"},{"internalType":"bool","name":"fountExclusive","type":"bool"},{"internalType":"bool","name":"requiresSig","type":"bool"}],"name":"addTokenForSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvedSigners","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"collectEdition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"collectEdition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"everfresh","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMetadataLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadata","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilteringEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payments","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"subscriptionOrRegistrantToCopy","type":"address"},{"internalType":"bool","name":"subscribe","type":"bool"}],"name":"registerForOperatorFiltering","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"prevAdmin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"repeatRegistration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"contractURI_","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"metadata","type":"address"}],"name":"setMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setOperatorFilteringEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"paymentAddress","type":"address"}],"name":"setPaymentAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint16","name":"mintPerAddress","type":"uint16"},{"internalType":"bool","name":"fountExclusive","type":"bool"},{"internalType":"bool","name":"requiresSig","type":"bool"}],"name":"setTokenSaleConditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint128","name":"price","type":"uint128"}],"name":"setTokenSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"setTokenSaleTimes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenAllowancePerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenCollectedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenIsFountExclusive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"tokenRemainingAllowanceForAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenRequiresOffChainSignatureToMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAndReleaseAllETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
600780546001600160a01b03191673bb3444a06e9928dda9a739cdab3e0c5cf68900991790556101a0604052602261014081815290620049ff610160396009906200004b9082620004dd565b506040805180820190915260078152664452495645525360c81b6020820152600a90620000799082620004dd565b50600d8054610100600160a81b03191674c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200179055348015620000af57600080fd5b5060405162004a2138038062004a21833981016040819052620000d291620005c6565b8585858585856040518060400160405280601381526020017f447269766572734f70656e45646974696f6e7300000000000000000000000000815250604051806040016040528060018152602001603160f81b815250858585858b8b81600260006101000a8154816001600160a01b0302191690836001600160a01b03160217905550816001600160a01b031660006001600160a01b03167f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7660405160405180910390a36001600160a01b038116600081815260036020526040808220805460ff19166001179055517fbf3f493c772c8c283fd124432c2d0f539ab343faa04258fe88e52912d36b102b908290a35050600480546001600160a01b039283166001600160a01b0319918216179091556005805492841692909116821790556040517f0713c9f4b0c5db294e61505e6819f6ad0cccf782df1a544939dc55d13fe7fc1c90600090a2506040805180820182526001600160a01b0384168082526001600160601b0384166020909201829052600160a01b909102811760065590518291907f984cbbb47b413608120ad6b444ea0004fe19b6f88a5c0992e612b97fd3cb631e90600090a35050815160208084019190912082518383012060e08290526101008190524660a0818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81880181905281830187905260608201869052608082019490945230818401528151808203909301835260c00190528051940193909320919290916080523060c052610120525050600e80546001600160a01b0319166001600160a01b038816179055506200035390506200039b565b600d805460ff191660011790556040517f57a86f7d14ccde89e22870afe839e3011216827daa9b24e18629f0a1e9d6cc1490600090a15050505050505050505050506200063e565b620003bc733cc6cdda760b79bafa08df41ecfa224f810dceb66001620003be565b565b6001600160a01b0390911690637d3e3dbe81620003ee5782620003e75750634420e486620003ee565b5063a0af29035b8060e01b60005230600452826024526004600060446000806daaeb6d7670e522a718067333cd4e5af16200042e578060005160e01c036200042e57600080fd5b5060006024525050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200046357607f821691505b6020821081036200048457634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004d857600081815260208120601f850160051c81016020861015620004b35750805b601f850160051c820191505b81811015620004d457828155600101620004bf565b5050505b505050565b81516001600160401b03811115620004f957620004f962000438565b62000511816200050a84546200044e565b846200048a565b602080601f831160018114620005495760008415620005305750858301515b600019600386901b1c1916600185901b178555620004d4565b600085815260208120601f198616915b828110156200057a5788860151825594840194600190910190840162000559565b5085821015620005995787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80516001600160a01b0381168114620005c157600080fd5b919050565b60008060008060008060c08789031215620005e057600080fd5b620005eb87620005a9565b9550620005fb60208801620005a9565b94506200060b60408801620005a9565b9350606087015192506200062260808801620005a9565b91506200063260a08801620005a9565b90509295509295509295565b60805160a05160c05160e05161010051610120516143716200068e6000396000613354015260006133a30152600061337e015260006132d7015260006133010152600061332b01526143716000f3fe60806040526004361061034e5760003560e01c80638a875512116101c6578063d7e45cd7116100f7578063e8a3d48511610095578063ef6ea27a1161006f578063ef6ea27a14610ae6578063f242432a14610b20578063fb796e6c14610b40578063fd6724fc14610b5a57600080fd5b8063e8a3d48514610a76578063e985e9c514610a8b578063ecd8dbf714610ac657600080fd5b8063e086e5ec116100d1578063e086e5ec146109e2578063e17b25af146109f7578063e2e784d514610a17578063e3faad9414610a3757600080fd5b8063d7e45cd714610981578063de7ff469146109a2578063e07b1afb146109c257600080fd5b8063a6d23e1011610164578063b7c0b8e81161013e578063b7c0b8e814610903578063b8e94ab314610923578063c0fd735b14610936578063d4ddce8a1461094b57600080fd5b8063a6d23e101461088f578063af4fddfa146108af578063b390c0ab146108e357600080fd5b806395d89b41116101a057806395d89b411461080d578063a22cb46514610822578063a415729614610842578063a522ad251461086f57600080fd5b80638a8755121461079d5780638da5cb5b146107cd578063938e3d7b146107ed57600080fd5b8063429b62e5116102a05780635e1e10041161023e5780637c1a8343116102185780637c1a8343146106f65780637ecebe0014610716578063881ced951461074357806389d020dc1461077d57600080fd5b80635e1e10041461067f5780636b2a9d251461069f57806370480275146106d657600080fd5b806347a9341e1161027a57806347a9341e1461060a57806349df728c1461061d5780634e1273f41461063d5780635e1c07461461066a57600080fd5b8063429b62e51461058257806345372241146105b257806346d8efad146105ea57600080fd5b80631785f53c1161030d5780632eb2c2d6116102e75780632eb2c2d6146104e557806331cb610514610505578063392f37e9146105255780633fc8cef31461055d57600080fd5b80631785f53c1461044f57806326645a2c1461046f5780632a55205a146104a657600080fd5b8062029eb814610353578062fdd58e1461037557806301ffc9a7146103bd57806306fdde03146103ed5780630e89341c1461040f57806313af40351461042f575b600080fd5b34801561035f57600080fd5b5061037361036e366004613784565b610b94565b005b34801561038157600080fd5b506103aa610390366004613820565b600060208181529281526040808220909352908152205481565b6040519081526020015b60405180910390f35b3480156103c957600080fd5b506103dd6103d8366004613860565b610ece565b60405190151581526020016103b4565b3480156103f957600080fd5b50610402610ef9565b6040516103b491906138a8565b34801561041b57600080fd5b5061040261042a3660046138db565b610f87565b34801561043b57600080fd5b5061037361044a3660046138f4565b610ff9565b34801561045b57600080fd5b5061037361046a3660046138f4565b611089565b34801561047b57600080fd5b506103dd61048a3660046138db565b6000908152600f6020526040902054600160f01b900460ff1690565b3480156104b257600080fd5b506104c66104c136600461390f565b611117565b604080516001600160a01b0390931683526020830191909152016103b4565b3480156104f157600080fd5b506103736105003660046139b8565b61115e565b34801561051157600080fd5b50610373610520366004613a73565b61119e565b34801561053157600080fd5b50600554610545906001600160a01b031681565b6040516001600160a01b0390911681526020016103b4565b34801561056957600080fd5b50600d546105459061010090046001600160a01b031681565b34801561058e57600080fd5b506103dd61059d3660046138f4565b60036020526000908152604090205460ff1681565b3480156105be57600080fd5b506103aa6105cd3660046138db565b6000908152600f6020526040902054600160e01b900461ffff1690565b3480156105f657600080fd5b50610373610605366004613a73565b61120d565b610373610618366004613aaa565b61125f565b34801561062957600080fd5b506103736106383660046138f4565b611339565b34801561064957600080fd5b5061065d610658366004613b12565b611397565b6040516103b49190613b7e565b34801561067657600080fd5b506103736114cc565b34801561068b57600080fd5b5061037361069a3660046138f4565b6114d6565b3480156106ab57600080fd5b506103dd6106ba3660046138db565b6000908152600f6020526040902054600160f81b900460ff1690565b3480156106e257600080fd5b506103736106f13660046138f4565b611563565b34801561070257600080fd5b50610373610711366004613bc2565b6115f4565b34801561072257600080fd5b506103aa6107313660046138f4565b600c6020526000908152604090205481565b34801561074f57600080fd5b506103aa61075e3660046138db565b6000908152600f6020526040902054600160801b900463ffffffff1690565b34801561078957600080fd5b50610373610798366004613be5565b611806565b3480156107a957600080fd5b506103dd6107b83660046138f4565b600b6020526000908152604090205460ff1681565b3480156107d957600080fd5b50600254610545906001600160a01b031681565b3480156107f957600080fd5b50610373610808366004613ca5565b611a25565b34801561081957600080fd5b50610402611a75565b34801561082e57600080fd5b5061037361083d366004613a73565b611a82565b34801561084e57600080fd5b50610402604051806040016040528060018152602001603160f81b81525081565b34801561087b57600080fd5b5061037361088a366004613d25565b611aa6565b34801561089b57600080fd5b50600e54610545906001600160a01b031681565b3480156108bb57600080fd5b506103aa7fe37c1ccae98d27199c22415b5eeafcff88faf573ce46a133cfc68db0c918d56581565b3480156108ef57600080fd5b506103736108fe36600461390f565b611af4565b34801561090f57600080fd5b5061037361091e366004613d4f565b611b55565b610373610931366004613d6c565b611bac565b34801561094257600080fd5b50610373611c6c565b34801561095757600080fd5b506103aa6109663660046138db565b6000908152600f60205260409020546001600160801b031690565b34801561098d57600080fd5b506005546103dd90600160a01b900460ff1681565b3480156109ae57600080fd5b506103aa6109bd366004613da1565b611d29565b3480156109ce57600080fd5b50600754610545906001600160a01b031681565b3480156109ee57600080fd5b50610373611e02565b348015610a0357600080fd5b50610373610a123660046138f4565b611e5b565b348015610a2357600080fd5b50610373610a32366004613820565b611ea8565b348015610a4357600080fd5b5061040260405180604001604052806013815260200172447269766572734f70656e45646974696f6e7360681b81525081565b348015610a8257600080fd5b50610402611ef6565b348015610a9757600080fd5b506103dd610aa6366004613d25565b600160209081526000928352604080842090915290825290205460ff1681565b348015610ad257600080fd5b50610373610ae1366004613dc4565b611f03565b348015610af257600080fd5b506103aa610b013660046138db565b6000908152600f6020526040902054600160c01b900463ffffffff1690565b348015610b2c57600080fd5b50610373610b3b366004613df7565b61217d565b348015610b4c57600080fd5b50600d546103dd9060ff1681565b348015610b6657600080fd5b506103aa610b753660046138db565b6000908152600f6020526040902054600160a01b900463ffffffff1690565b6002546001600160a01b0316331480610bbc57503360009081526003602052604090205460ff165b610be15760405162461bcd60e51b8152600401610bd890613e6f565b60405180910390fd5b8463ffffffff16600003610c08576040516361bc7fb160e11b815260040160405180910390fd5b60008463ffffffff16118015610c2357508363ffffffff1642115b15610c415760405163312728dd60e11b815260040160405180910390fd5b6000878152600f6020908152604091829020825160e08101845290546001600160801b038116825263ffffffff600160801b82048116938301849052600160a01b8204811694830194909452600160c01b8104909316606082015261ffff600160e01b840416608082015260ff600160f01b84048116151560a0830152600160f81b909304909216151560c083015215610cee576040516320705a1b60e11b815260040160405180910390fd5b8681600001906001600160801b031690816001600160801b03168152505085816020019063ffffffff16908163ffffffff168152505084816040019063ffffffff16908163ffffffff168152505083816080019061ffff16908161ffff1681525050828160a0019015159081151581525050818160c001901515908115158152505080600f60008a815260200190815260200160002060008201518160000160006101000a8154816001600160801b0302191690836001600160801b0316021790555060208201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001601c6101000a81548161ffff021916908361ffff16021790555060a082015181600001601e6101000a81548160ff02191690831515021790555060c082015181600001601f6101000a81548160ff021916908315150217905550905050877fcbbe66244ef9bdffe7f2771b55a9ef388ac4d13d901ba070b3b61b96ed7c1aa882604051610ebc9190613e95565b60405180910390a25050505050505050565b60006001600160e01b0319821663152a902d60e11b1480610ef35750610ef3826121b9565b92915050565b60098054610f0690613f02565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3290613f02565b8015610f7f5780601f10610f5457610100808354040283529160200191610f7f565b820191906000526020600020905b815481529060010190602001808311610f6257829003601f168201915b505050505081565b60055460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd90602401600060405180830381865afa158015610fd1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ef39190810190613f3c565b6002546001600160a01b031633148061102157503360009081526003602052604090205460ff165b61103d5760405162461bcd60e51b8152600401610bd890613e6f565b600280546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b6002546001600160a01b03163314806110b157503360009081526003602052604090205460ff165b6110cd5760405162461bcd60e51b8152600401610bd890613e6f565b6001600160a01b038116600081815260036020526040808220805460ff19169055517fdb9d5d31320daf5bc7181d565b6da4d12e30f0f4d5aa324a992426c14a1d19ce908290a350565b6006546001600160a01b038116906000906127109061114b90600160a01b90046bffffffffffffffffffffffff1685613fc9565b6111559190613fe0565b90509250929050565b876001600160a01b038116331461118357600d5460ff16156111835761118333612207565b611193898989898989898961224b565b505050505050505050565b6002546001600160a01b03163314806111c657503360009081526003602052604090205460ff165b6111e25760405162461bcd60e51b8152600401610bd890613e6f565b6001600160a01b03919091166000908152600b60205260409020805460ff1916911515919091179055565b6002546001600160a01b031633148061123557503360009081526003602052604090205460ff165b6112515760405162461bcd60e51b8152600401610bd890613e6f565b61125b82826124ee565b5050565b6000858152600f6020908152604091829020825160e08101845290546001600160801b038116825263ffffffff600160801b8204811693830193909352600160a01b8104831693820193909352600160c01b8304909116606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b90920490911615801560c083018190529061130757506113058686868686612563565b155b1561132557604051638baa579f60e01b815260040160405180910390fd5b611331868686846126d2565b505050505050565b6002546001600160a01b031633148061136157503360009081526003602052604090205460ff165b61137d5760405162461bcd60e51b8152600401610bd890613e6f565b600e546113949082906001600160a01b03166129ea565b50565b60608382146113da5760405162461bcd60e51b815260206004820152600f60248201526e0988a9c8ea890be9a92a69a82a8869608b1b6044820152606401610bd8565b8367ffffffffffffffff8111156113f3576113f3613c36565b60405190808252806020026020018201604052801561141c578160200160208202803683370190505b50905060005b848110156114c35760008087878481811061143f5761143f614002565b905060200201602081019061145491906138f4565b6001600160a01b03166001600160a01b03168152602001908152602001600020600085858481811061148857611488614002565b905060200201358152602001908152602001600020548282815181106114b0576114b0614002565b6020908102919091010152600101611422565b50949350505050565b6114d4612b36565b565b6002546001600160a01b03163314806114fe57503360009081526003602052604090205460ff165b61151a5760405162461bcd60e51b8152600401610bd890613e6f565b6001600160a01b03811661154157604051631f4c499760e01b815260040160405180910390fd5b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031633148061158b57503360009081526003602052604090205460ff165b6115a75760405162461bcd60e51b8152600401610bd890613e6f565b6001600160a01b038116600081815260036020526040808220805460ff19166001179055517fbf3f493c772c8c283fd124432c2d0f539ab343faa04258fe88e52912d36b102b908290a350565b6002546001600160a01b031633148061161c57503360009081526003602052604090205460ff165b6116385760405162461bcd60e51b8152600401610bd890613e6f565b6000828152600f60209081526040808320815160e08101835290546001600160801b038116825263ffffffff600160801b82048116948301859052600160a01b8204811693830193909352600160c01b8104909216606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b909204909116151560c082015291036116e5576040516347c0cce560e01b815260040160405180910390fd5b6001600160801b0382811682526000848152600f60209081526040918290208451815492860151848701516060880151608089015160a08a015160c08b0151959099166001600160a01b031990971696909617600160801b63ffffffff948516021767ffffffffffffffff60a01b1916600160a01b9284169290920263ffffffff60c01b191691909117600160c01b92909116919091021762ffffff60e01b1916600160e01b61ffff9094169390930260ff60f01b191692909217600160f01b94151594909402939093176001600160f81b0316600160f81b91151591909102179091555183907f44e4819dc1ed2a187bca4e8978c8bbf1a42c34bb4697c9f02db89d87d007614b906117f9908490613e95565b60405180910390a2505050565b6002546001600160a01b031633148061182e57503360009081526003602052604090205460ff165b61184a5760405162461bcd60e51b8152600401610bd890613e6f565b6000848152600f60209081526040808320815160e08101835290546001600160801b038116825263ffffffff600160801b82048116948301859052600160a01b8204811693830193909352600160c01b8104909216606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b909204909116151560c082015291036118f7576040516347c0cce560e01b815260040160405180910390fd5b61ffff8085166080830190815284151560a0840190815284151560c085019081526000898152600f60209081526040918290208751815492890151848a015160608b01519851975196511515600160f81b026001600160f81b03971515600160f01b0260ff60f01b1999909b16600160e01b029890981662ffffff60e01b1963ffffffff9a8b16600160c01b0263ffffffff60c01b19938c16600160a01b029390931667ffffffffffffffff60a01b199b909416600160801b026001600160a01b03199097166001600160801b039095169490941795909517989098161796909617959095161794909417161790555185907f63ad5f4d7f7728e5b8f9a8e757982827e6df61fa74911e98cb44748a0f9b057890611a16908490613e95565b60405180910390a25050505050565b6002546001600160a01b0316331480611a4d57503360009081526003602052604090205460ff165b611a695760405162461bcd60e51b8152600401610bd890613e6f565b600861125b828261405e565b600a8054610f0690613f02565b81600d5460ff1615611a9757611a9781612207565b611aa18383612b55565b505050565b6002546001600160a01b0316331480611ace57503360009081526003602052604090205460ff165b611aea5760405162461bcd60e51b8152600401610bd890613e6f565b61125b82826129ea565b33600090815260208181526040808320858452909152902054811115611b4a5760405162461bcd60e51b815260206004820152600b60248201526a21a0a72727aa2fa12aa92760a91b6044820152606401610bd8565b61125b338383612bc1565b6002546001600160a01b0316331480611b7d57503360009081526003602052604090205460ff165b611b995760405162461bcd60e51b8152600401610bd890613e6f565b600d805460ff1916911515919091179055565b6000838152600f6020908152604091829020825160e08101845290546001600160801b038116825263ffffffff600160801b8204811693830193909352600160a01b8104831693820193909352600160c01b8304909116606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b90920490911615801560c0830152611c5a57604051630426ff7760e01b815260040160405180910390fd5b611c66848484846126d2565b50505050565b6002546001600160a01b0316331480611c9457503360009081526003602052604090205460ff165b611cb05760405162461bcd60e51b8152600401610bd890613e6f565b600e54611cc5906001600160a01b0316612c33565b600e60009054906101000a90046001600160a01b03166001600160a01b031663465105f06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611d1557600080fd5b505af1158015611c66573d6000803e3d6000fd5b6000828152600f60209081526040808320815160e08101835290546001600160801b038116825263ffffffff600160801b8204811683860152600160a01b8204811683850152600160c01b820416606083015261ffff600160e01b820481166080840190815260ff600160f01b84048116151560a0860152600160f81b909304909216151560c08401526001600160a01b038716865285855283862088875290945291842054915190928491168211611df55781836080015161ffff16611df0919061411e565b611df8565b60005b9695505050505050565b6002546001600160a01b0316331480611e2a57503360009081526003602052604090205460ff165b611e465760405162461bcd60e51b8152600401610bd890613e6f565b600e546114d4906001600160a01b0316612c33565b6002546001600160a01b0316331480611e8357503360009081526003602052604090205460ff165b611e9f5760405162461bcd60e51b8152600401610bd890613e6f565b61139481612cf1565b6002546001600160a01b0316331480611ed057503360009081526003602052604090205460ff165b611eec5760405162461bcd60e51b8152600401610bd890613e6f565b61125b8282612d66565b60088054610f0690613f02565b6002546001600160a01b0316331480611f2b57503360009081526003602052604090205460ff165b611f475760405162461bcd60e51b8152600401610bd890613e6f565b8163ffffffff16600003611f6e576040516361bc7fb160e11b815260040160405180910390fd5b60008163ffffffff16118015611f8957508063ffffffff1642115b15611fa75760405163312728dd60e11b815260040160405180910390fd5b6000838152600f60209081526040808320815160e08101835290546001600160801b038116825263ffffffff600160801b82048116948301859052600160a01b8204811693830193909352600160c01b8104909216606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b909204909116151560c08201529103612054576040516347c0cce560e01b815260040160405180910390fd5b63ffffffff808416602080840191825284831660408086019182526000898152600f9093529182902085518154945192516060880151608089015160a08a015160c08b01511515600160f81b026001600160f81b03911515600160f01b0260ff60f01b1961ffff909416600160e01b029390931662ffffff60e01b19948c16600160c01b0263ffffffff60c01b19968d16600160a01b029690961667ffffffffffffffff60a01b1999909c16600160801b026001600160a01b0319909b166001600160801b03909716969096179990991796909616989098179190911716179490941716919091179091555184907fe7decc699896feefecbb9be5418a0bc1c84d880973ee5ecf2f92deb0f0f7f75e9061216f908490613e95565b60405180910390a250505050565b856001600160a01b03811633146121a257600d5460ff16156121a2576121a233612207565b6121b0878787878787612de9565b50505050505050565b60006301ffc9a760e01b6001600160e01b0319831614806121ea5750636cdb3d1360e11b6001600160e01b03198316145b80610ef35750506001600160e01b0319166303a24d0760e21b1490565b69c617113400112233445560005230601a5280603a52600080604460166daaeb6d7670e522a718067333cd4e5afa612243573d6000803e3d6000fd5b6000603a5250565b84831461228c5760405162461bcd60e51b815260206004820152600f60248201526e0988a9c8ea890be9a92a69a82a8869608b1b6044820152606401610bd8565b336001600160a01b03891614806122c657506001600160a01b038816600090815260016020908152604080832033845290915290205460ff165b6123035760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610bd8565b60008060005b878110156123be5788888281811061232357612323614002565b90506020020135925086868281811061233e5761233e614002565b6001600160a01b038e166000908152602081815260408083208984528252822080549390910294909401359550859392509061237b90849061411e565b90915550506001600160a01b038a16600090815260208181526040808320868452909152812080548492906123b1908490614131565b9091555050600101612309565b50886001600160a01b03168a6001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b6040516124129493929190614176565b60405180910390a46001600160a01b0389163b156124b95760405163bc197c8160e01b808252906001600160a01b038b169063bc197c81906124669033908f908e908e908e908e908e908e906004016141d1565b6020604051808303816000875af1158015612485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a99190614235565b6001600160e01b031916146124c6565b6001600160a01b03891615155b6124e25760405162461bcd60e51b8152600401610bd890614252565b50505050505050505050565b6001600160a01b0390911690637d3e3dbe8161251b57826125145750634420e48661251b565b5063a0af29035b8060e01b60005230600452826024526004600060446000806daaeb6d7670e522a718067333cd4e5af1612559578060005160e01c0361255957600080fd5b5060006024525050565b6040805160a08101825286815260208082018790526001600160a01b0386168284018190526000908152600c82528381205460608401528351601f8601839004830281018301909452848452928392916080830191908790879081908401838280828437600092018290525093909452505082516020808501516040808701516001600160a01b0381168652600c90935284208054969750939561268095507fe37c1ccae98d27199c22415b5eeafcff88faf573ce46a133cfc68db0c918d56594919291876126318361427c565b9091555060408051602081019690965285019390935260608401919091526001600160a01b0316608083015260a082015260c00160405160208183030381529060405280519060200120612fc9565b90506000612692828460800151613017565b6001600160a01b0381166000908152600b602052604090205490915060ff1680156126c557506001600160a01b03811615155b9998505050505050505050565b600083905042826020015163ffffffff161115612701576040516254d81f60e41b815260040160405180910390fd5b6000826040015163ffffffff161180156127245750816040015163ffffffff1642115b15612742576040516330aee1db60e21b815260040160405180910390fd5b81516001600160801b03161580159061277157508151349061276e9086906001600160801b0316613fc9565b14155b1561278f57604051636992e1ff60e01b815260040160405180910390fd5b8160a0015180156127a657506127a48361303b565b155b156127c457604051633664886760e11b815260040160405180910390fd5b608082015161ffff16156128c457816080015161ffff168411156127fb57604051632d00877b60e11b815260040160405180910390fd5b6001600160a01b038316600090815260208181526040808320888452909152812054608084015190919061ffff168210156128495781846080015161ffff16612844919061411e565b61284c565b60005b90508086111561285a578092505b8260000361287a5760405162726eb760e11b815260040160405180910390fd5b83516001600160801b03161580159061289257508286115b156128c15783516128c19033906001600160801b03166128b2868a61411e565b6128bc9190613fc9565b61304e565b50505b60608201805163ffffffff908301811682526000878152600f60209081526040918290208651815492880151938801519551608089015160a08a015160c08b01511515600160f81b026001600160f81b03911515600160f01b0260ff60f01b1961ffff909416600160e01b029390931662ffffff60e01b19948a16600160c01b0263ffffffff60c01b199b8b16600160a01b029b909b1667ffffffffffffffff60a01b1999909a16600160801b026001600160a01b03199098166001600160801b039096169590951796909617969096169690961796909617959095169490941792909217161790556129b8838683613143565b60405185907f97740a2d1e4e75b5dea30b31b96c67193bed444129f7f62010953c83c9b03dcd90600090a25050505050565b6001600160a01b038116612a115760405163172fe2d160e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015612a58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7c9190614295565b905080600003612a9f5760405163334ab3f560e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390526000919085169063a9059cbb906044016020604051808303816000875af1158015612af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b1691906142ae565b905080611c6657604051631d42c86760e21b815260040160405180910390fd5b6114d4733cc6cdda760b79bafa08df41ecfa224f810dceb660016124ee565b3360008181526001602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6001600160a01b03831660009081526020818152604080832085845290915281208054839290612bf290849061411e565b909155505060408051838152602081018390526000916001600160a01b038616913391600080516020614345833981519152910160405180910390a4505050565b6001600160a01b038116612c5a5760405163172fe2d160e01b815260040160405180910390fd5b476000819003612c7d5760405163334ab3f560e11b815260040160405180910390fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612cca576040519150601f19603f3d011682016040523d82523d6000602084013e612ccf565b606091505b5050905080611aa157604051631d42c86760e21b815260040160405180910390fd5b600554600160a01b900460ff1615612d1c576040516313ef243160e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040517f0713c9f4b0c5db294e61505e6819f6ad0cccf782df1a544939dc55d13fe7fc1c90600090a250565b612710811115612d89576040516303c799a760e61b815260040160405180910390fd5b6040805180820182526001600160a01b03841680825262ffffff84166020909201829052600160a01b909102811760065590518291907ff21fccf4d64d86d532c4e4eb86c007b6ad57a460c27d724188625e755ec6cf6d90600090a35050565b336001600160a01b0387161480612e2357506001600160a01b038616600090815260016020908152604080832033845290915290205460ff165b612e605760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610bd8565b6001600160a01b03861660009081526020818152604080832087845290915281208054859290612e9190849061411e565b90915550506001600160a01b03851660009081526020818152604080832087845290915281208054859290612ec7908490614131565b909155505060408051858152602081018590526001600160a01b0380881692908916913391600080516020614345833981519152910160405180910390a46001600160a01b0385163b15612fa05760405163f23a6e6160e01b808252906001600160a01b0387169063f23a6e6190612f4d9033908b908a908a908a908a906004016142cb565b6020604051808303816000875af1158015612f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f909190614235565b6001600160e01b03191614612fad565b6001600160a01b03851615155b6113315760405162461bcd60e51b8152600401610bd890614252565b6000610ef3612fd66132ca565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061302685856133f1565b9150915061303381613436565b509392505050565b60008061304783613580565b1192915050565b61305882826135f9565b61125b57600d60019054906101000a90046001600160a01b03166001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130ac57600080fd5b505af11580156130c0573d6000803e3d6000fd5b5050600d5460405163a9059cbb60e01b81526001600160a01b03878116600483015260248201879052610100909204909116935063a9059cbb925060440190506020604051808303816000875af115801561311f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa191906142ae565b6001600160a01b03831660009081526020818152604080832085845290915281208054839290613174908490614131565b909155505060075460408051848152602081018490526001600160a01b03909216916000913391600080516020614345833981519152910160405180910390a460075460408051848152602081018490526001600160a01b038681169316913391600080516020614345833981519152910160405180910390a46001600160a01b0383163b156132a15760075460405163f23a6e6160e01b8082523360048301526001600160a01b039283166024830152604482018590526064820184905260a06084830152600060a48301529185169063f23a6e619060c4016020604051808303816000875af115801561326d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132919190614235565b6001600160e01b031916146132ae565b6001600160a01b03831615155b611aa15760405162461bcd60e51b8152600401610bd890614252565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561332357507f000000000000000000000000000000000000000000000000000000000000000046145b1561334d57507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60008082516041036134275760208301516040840151606085015160001a61341b87828585613670565b9450945050505061342f565b506000905060025b9250929050565b600081600481111561344a5761344a614312565b036134525750565b600181600481111561346657613466614312565b036134b35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610bd8565b60028160048111156134c7576134c7614312565b036135145760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610bd8565b600381600481111561352857613528614312565b036113945760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610bd8565b60048054604051627eeac760e11b81526001600160a01b0384811693820193909352600160248201526000929091169062fdd58e90604401602060405180830381865afa1580156135d5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef39190614295565b60408051600080825260208201928390529182916001600160a01b03861691859161362391614328565b60006040518083038185875af1925050503d8060008114613660576040519150601f19603f3d011682016040523d82523d6000602084013e613665565b606091505b509095945050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156136a7575060009050600361372b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136fb573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166137245760006001925092505061372b565b9150600090505b94509492505050565b80356001600160801b038116811461374b57600080fd5b919050565b803563ffffffff8116811461374b57600080fd5b803561ffff8116811461374b57600080fd5b801515811461139457600080fd5b600080600080600080600060e0888a03121561379f57600080fd5b873596506137af60208901613734565b95506137bd60408901613750565b94506137cb60608901613750565b93506137d960808901613764565b925060a08801356137e981613776565b915060c08801356137f981613776565b8091505092959891949750929550565b80356001600160a01b038116811461374b57600080fd5b6000806040838503121561383357600080fd5b61383c83613809565b946020939093013593505050565b6001600160e01b03198116811461139457600080fd5b60006020828403121561387257600080fd5b813561387d8161384a565b9392505050565b60005b8381101561389f578181015183820152602001613887565b50506000910152565b60208152600082518060208401526138c7816040850160208701613884565b601f01601f19169190910160400192915050565b6000602082840312156138ed57600080fd5b5035919050565b60006020828403121561390657600080fd5b61387d82613809565b6000806040838503121561392257600080fd5b50508035926020909101359150565b60008083601f84011261394357600080fd5b50813567ffffffffffffffff81111561395b57600080fd5b6020830191508360208260051b850101111561342f57600080fd5b60008083601f84011261398857600080fd5b50813567ffffffffffffffff8111156139a057600080fd5b60208301915083602082850101111561342f57600080fd5b60008060008060008060008060a0898b0312156139d457600080fd5b6139dd89613809565b97506139eb60208a01613809565b9650604089013567ffffffffffffffff80821115613a0857600080fd5b613a148c838d01613931565b909850965060608b0135915080821115613a2d57600080fd5b613a398c838d01613931565b909650945060808b0135915080821115613a5257600080fd5b50613a5f8b828c01613976565b999c989b5096995094979396929594505050565b60008060408385031215613a8657600080fd5b613a8f83613809565b91506020830135613a9f81613776565b809150509250929050565b600080600080600060808688031215613ac257600080fd5b8535945060208601359350613ad960408701613809565b9250606086013567ffffffffffffffff811115613af557600080fd5b613b0188828901613976565b969995985093965092949392505050565b60008060008060408587031215613b2857600080fd5b843567ffffffffffffffff80821115613b4057600080fd5b613b4c88838901613931565b90965094506020870135915080821115613b6557600080fd5b50613b7287828801613931565b95989497509550505050565b6020808252825182820181905260009190848201906040850190845b81811015613bb657835183529284019291840191600101613b9a565b50909695505050505050565b60008060408385031215613bd557600080fd5b8235915061115560208401613734565b60008060008060808587031215613bfb57600080fd5b84359350613c0b60208601613764565b92506040850135613c1b81613776565b91506060850135613c2b81613776565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c7557613c75613c36565b604052919050565b600067ffffffffffffffff821115613c9757613c97613c36565b50601f01601f191660200190565b600060208284031215613cb757600080fd5b813567ffffffffffffffff811115613cce57600080fd5b8201601f81018413613cdf57600080fd5b8035613cf2613ced82613c7d565b613c4c565b818152856020838501011115613d0757600080fd5b81602084016020830137600091810160200191909152949350505050565b60008060408385031215613d3857600080fd5b613d4183613809565b915061115560208401613809565b600060208284031215613d6157600080fd5b813561387d81613776565b600080600060608486031215613d8157600080fd5b8335925060208401359150613d9860408501613809565b90509250925092565b60008060408385031215613db457600080fd5b8235915061115560208401613809565b600080600060608486031215613dd957600080fd5b83359250613de960208501613750565b9150613d9860408501613750565b60008060008060008060a08789031215613e1057600080fd5b613e1987613809565b9550613e2760208801613809565b94506040870135935060608701359250608087013567ffffffffffffffff811115613e5157600080fd5b613e5d89828a01613976565b979a9699509497509295939492505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b600060e0820190506001600160801b038351168252602083015163ffffffff8082166020850152806040860151166040850152806060860151166060850152505061ffff608084015116608083015260a0830151151560a083015260c0830151151560c083015292915050565b600181811c90821680613f1657607f821691505b602082108103613f3657634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215613f4e57600080fd5b815167ffffffffffffffff811115613f6557600080fd5b8201601f81018413613f7657600080fd5b8051613f84613ced82613c7d565b818152856020838501011115613f9957600080fd5b613faa826020830160208601613884565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610ef357610ef3613fb3565b600082613ffd57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b601f821115611aa157600081815260208120601f850160051c8101602086101561403f5750805b601f850160051c820191505b818110156113315782815560010161404b565b815167ffffffffffffffff81111561407857614078613c36565b61408c816140868454613f02565b84614018565b602080601f8311600181146140c157600084156140a95750858301515b600019600386901b1c1916600185901b178555611331565b600085815260208120601f198616915b828110156140f0578886015182559484019460019091019084016140d1565b508582101561410e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81810381811115610ef357610ef3613fb3565b80820180821115610ef357610ef3613fb3565b81835260006001600160fb1b0383111561415d57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061418a604083018688614144565b828103602084015261419d818587614144565b979650505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0389811682528816602082015260a0604082018190526000906141fe908301888a614144565b8281036060840152614211818789614144565b905082810360808401526142268185876141a8565b9b9a5050505050505050505050565b60006020828403121561424757600080fd5b815161387d8161384a565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b60006001820161428e5761428e613fb3565b5060010190565b6000602082840312156142a757600080fd5b5051919050565b6000602082840312156142c057600080fd5b815161387d81613776565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905260009061430690830184866141a8565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6000825161433a818460208701613884565b919091019291505056fec3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62a164736f6c6343000811000a44726976657273204f70656e2045646974696f6e73206279204576657266726573680000000000000000000000003b1bd4c99c059ed58155240fd01d6fc86a430d4d0000000000000000000000006306d0cdfadd6095a313e8484275b6cc7036166c00000000000000000000000085991f5f68b0f3678baae5848dea092c582df0cf00000000000000000000000000000000000000000000000000000000000002ee0000000000000000000000008d12974b9003112ecb9f58d60095cc03bef8f0e300000000000000000000000016f444f2d9e696834c1c9b536dc3896e1b545213
Deployed Bytecode
0x60806040526004361061034e5760003560e01c80638a875512116101c6578063d7e45cd7116100f7578063e8a3d48511610095578063ef6ea27a1161006f578063ef6ea27a14610ae6578063f242432a14610b20578063fb796e6c14610b40578063fd6724fc14610b5a57600080fd5b8063e8a3d48514610a76578063e985e9c514610a8b578063ecd8dbf714610ac657600080fd5b8063e086e5ec116100d1578063e086e5ec146109e2578063e17b25af146109f7578063e2e784d514610a17578063e3faad9414610a3757600080fd5b8063d7e45cd714610981578063de7ff469146109a2578063e07b1afb146109c257600080fd5b8063a6d23e1011610164578063b7c0b8e81161013e578063b7c0b8e814610903578063b8e94ab314610923578063c0fd735b14610936578063d4ddce8a1461094b57600080fd5b8063a6d23e101461088f578063af4fddfa146108af578063b390c0ab146108e357600080fd5b806395d89b41116101a057806395d89b411461080d578063a22cb46514610822578063a415729614610842578063a522ad251461086f57600080fd5b80638a8755121461079d5780638da5cb5b146107cd578063938e3d7b146107ed57600080fd5b8063429b62e5116102a05780635e1e10041161023e5780637c1a8343116102185780637c1a8343146106f65780637ecebe0014610716578063881ced951461074357806389d020dc1461077d57600080fd5b80635e1e10041461067f5780636b2a9d251461069f57806370480275146106d657600080fd5b806347a9341e1161027a57806347a9341e1461060a57806349df728c1461061d5780634e1273f41461063d5780635e1c07461461066a57600080fd5b8063429b62e51461058257806345372241146105b257806346d8efad146105ea57600080fd5b80631785f53c1161030d5780632eb2c2d6116102e75780632eb2c2d6146104e557806331cb610514610505578063392f37e9146105255780633fc8cef31461055d57600080fd5b80631785f53c1461044f57806326645a2c1461046f5780632a55205a146104a657600080fd5b8062029eb814610353578062fdd58e1461037557806301ffc9a7146103bd57806306fdde03146103ed5780630e89341c1461040f57806313af40351461042f575b600080fd5b34801561035f57600080fd5b5061037361036e366004613784565b610b94565b005b34801561038157600080fd5b506103aa610390366004613820565b600060208181529281526040808220909352908152205481565b6040519081526020015b60405180910390f35b3480156103c957600080fd5b506103dd6103d8366004613860565b610ece565b60405190151581526020016103b4565b3480156103f957600080fd5b50610402610ef9565b6040516103b491906138a8565b34801561041b57600080fd5b5061040261042a3660046138db565b610f87565b34801561043b57600080fd5b5061037361044a3660046138f4565b610ff9565b34801561045b57600080fd5b5061037361046a3660046138f4565b611089565b34801561047b57600080fd5b506103dd61048a3660046138db565b6000908152600f6020526040902054600160f01b900460ff1690565b3480156104b257600080fd5b506104c66104c136600461390f565b611117565b604080516001600160a01b0390931683526020830191909152016103b4565b3480156104f157600080fd5b506103736105003660046139b8565b61115e565b34801561051157600080fd5b50610373610520366004613a73565b61119e565b34801561053157600080fd5b50600554610545906001600160a01b031681565b6040516001600160a01b0390911681526020016103b4565b34801561056957600080fd5b50600d546105459061010090046001600160a01b031681565b34801561058e57600080fd5b506103dd61059d3660046138f4565b60036020526000908152604090205460ff1681565b3480156105be57600080fd5b506103aa6105cd3660046138db565b6000908152600f6020526040902054600160e01b900461ffff1690565b3480156105f657600080fd5b50610373610605366004613a73565b61120d565b610373610618366004613aaa565b61125f565b34801561062957600080fd5b506103736106383660046138f4565b611339565b34801561064957600080fd5b5061065d610658366004613b12565b611397565b6040516103b49190613b7e565b34801561067657600080fd5b506103736114cc565b34801561068b57600080fd5b5061037361069a3660046138f4565b6114d6565b3480156106ab57600080fd5b506103dd6106ba3660046138db565b6000908152600f6020526040902054600160f81b900460ff1690565b3480156106e257600080fd5b506103736106f13660046138f4565b611563565b34801561070257600080fd5b50610373610711366004613bc2565b6115f4565b34801561072257600080fd5b506103aa6107313660046138f4565b600c6020526000908152604090205481565b34801561074f57600080fd5b506103aa61075e3660046138db565b6000908152600f6020526040902054600160801b900463ffffffff1690565b34801561078957600080fd5b50610373610798366004613be5565b611806565b3480156107a957600080fd5b506103dd6107b83660046138f4565b600b6020526000908152604090205460ff1681565b3480156107d957600080fd5b50600254610545906001600160a01b031681565b3480156107f957600080fd5b50610373610808366004613ca5565b611a25565b34801561081957600080fd5b50610402611a75565b34801561082e57600080fd5b5061037361083d366004613a73565b611a82565b34801561084e57600080fd5b50610402604051806040016040528060018152602001603160f81b81525081565b34801561087b57600080fd5b5061037361088a366004613d25565b611aa6565b34801561089b57600080fd5b50600e54610545906001600160a01b031681565b3480156108bb57600080fd5b506103aa7fe37c1ccae98d27199c22415b5eeafcff88faf573ce46a133cfc68db0c918d56581565b3480156108ef57600080fd5b506103736108fe36600461390f565b611af4565b34801561090f57600080fd5b5061037361091e366004613d4f565b611b55565b610373610931366004613d6c565b611bac565b34801561094257600080fd5b50610373611c6c565b34801561095757600080fd5b506103aa6109663660046138db565b6000908152600f60205260409020546001600160801b031690565b34801561098d57600080fd5b506005546103dd90600160a01b900460ff1681565b3480156109ae57600080fd5b506103aa6109bd366004613da1565b611d29565b3480156109ce57600080fd5b50600754610545906001600160a01b031681565b3480156109ee57600080fd5b50610373611e02565b348015610a0357600080fd5b50610373610a123660046138f4565b611e5b565b348015610a2357600080fd5b50610373610a32366004613820565b611ea8565b348015610a4357600080fd5b5061040260405180604001604052806013815260200172447269766572734f70656e45646974696f6e7360681b81525081565b348015610a8257600080fd5b50610402611ef6565b348015610a9757600080fd5b506103dd610aa6366004613d25565b600160209081526000928352604080842090915290825290205460ff1681565b348015610ad257600080fd5b50610373610ae1366004613dc4565b611f03565b348015610af257600080fd5b506103aa610b013660046138db565b6000908152600f6020526040902054600160c01b900463ffffffff1690565b348015610b2c57600080fd5b50610373610b3b366004613df7565b61217d565b348015610b4c57600080fd5b50600d546103dd9060ff1681565b348015610b6657600080fd5b506103aa610b753660046138db565b6000908152600f6020526040902054600160a01b900463ffffffff1690565b6002546001600160a01b0316331480610bbc57503360009081526003602052604090205460ff165b610be15760405162461bcd60e51b8152600401610bd890613e6f565b60405180910390fd5b8463ffffffff16600003610c08576040516361bc7fb160e11b815260040160405180910390fd5b60008463ffffffff16118015610c2357508363ffffffff1642115b15610c415760405163312728dd60e11b815260040160405180910390fd5b6000878152600f6020908152604091829020825160e08101845290546001600160801b038116825263ffffffff600160801b82048116938301849052600160a01b8204811694830194909452600160c01b8104909316606082015261ffff600160e01b840416608082015260ff600160f01b84048116151560a0830152600160f81b909304909216151560c083015215610cee576040516320705a1b60e11b815260040160405180910390fd5b8681600001906001600160801b031690816001600160801b03168152505085816020019063ffffffff16908163ffffffff168152505084816040019063ffffffff16908163ffffffff168152505083816080019061ffff16908161ffff1681525050828160a0019015159081151581525050818160c001901515908115158152505080600f60008a815260200190815260200160002060008201518160000160006101000a8154816001600160801b0302191690836001600160801b0316021790555060208201518160000160106101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160186101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001601c6101000a81548161ffff021916908361ffff16021790555060a082015181600001601e6101000a81548160ff02191690831515021790555060c082015181600001601f6101000a81548160ff021916908315150217905550905050877fcbbe66244ef9bdffe7f2771b55a9ef388ac4d13d901ba070b3b61b96ed7c1aa882604051610ebc9190613e95565b60405180910390a25050505050505050565b60006001600160e01b0319821663152a902d60e11b1480610ef35750610ef3826121b9565b92915050565b60098054610f0690613f02565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3290613f02565b8015610f7f5780601f10610f5457610100808354040283529160200191610f7f565b820191906000526020600020905b815481529060010190602001808311610f6257829003601f168201915b505050505081565b60055460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd90602401600060405180830381865afa158015610fd1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ef39190810190613f3c565b6002546001600160a01b031633148061102157503360009081526003602052604090205460ff165b61103d5760405162461bcd60e51b8152600401610bd890613e6f565b600280546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b6002546001600160a01b03163314806110b157503360009081526003602052604090205460ff165b6110cd5760405162461bcd60e51b8152600401610bd890613e6f565b6001600160a01b038116600081815260036020526040808220805460ff19169055517fdb9d5d31320daf5bc7181d565b6da4d12e30f0f4d5aa324a992426c14a1d19ce908290a350565b6006546001600160a01b038116906000906127109061114b90600160a01b90046bffffffffffffffffffffffff1685613fc9565b6111559190613fe0565b90509250929050565b876001600160a01b038116331461118357600d5460ff16156111835761118333612207565b611193898989898989898961224b565b505050505050505050565b6002546001600160a01b03163314806111c657503360009081526003602052604090205460ff165b6111e25760405162461bcd60e51b8152600401610bd890613e6f565b6001600160a01b03919091166000908152600b60205260409020805460ff1916911515919091179055565b6002546001600160a01b031633148061123557503360009081526003602052604090205460ff165b6112515760405162461bcd60e51b8152600401610bd890613e6f565b61125b82826124ee565b5050565b6000858152600f6020908152604091829020825160e08101845290546001600160801b038116825263ffffffff600160801b8204811693830193909352600160a01b8104831693820193909352600160c01b8304909116606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b90920490911615801560c083018190529061130757506113058686868686612563565b155b1561132557604051638baa579f60e01b815260040160405180910390fd5b611331868686846126d2565b505050505050565b6002546001600160a01b031633148061136157503360009081526003602052604090205460ff165b61137d5760405162461bcd60e51b8152600401610bd890613e6f565b600e546113949082906001600160a01b03166129ea565b50565b60608382146113da5760405162461bcd60e51b815260206004820152600f60248201526e0988a9c8ea890be9a92a69a82a8869608b1b6044820152606401610bd8565b8367ffffffffffffffff8111156113f3576113f3613c36565b60405190808252806020026020018201604052801561141c578160200160208202803683370190505b50905060005b848110156114c35760008087878481811061143f5761143f614002565b905060200201602081019061145491906138f4565b6001600160a01b03166001600160a01b03168152602001908152602001600020600085858481811061148857611488614002565b905060200201358152602001908152602001600020548282815181106114b0576114b0614002565b6020908102919091010152600101611422565b50949350505050565b6114d4612b36565b565b6002546001600160a01b03163314806114fe57503360009081526003602052604090205460ff165b61151a5760405162461bcd60e51b8152600401610bd890613e6f565b6001600160a01b03811661154157604051631f4c499760e01b815260040160405180910390fd5b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031633148061158b57503360009081526003602052604090205460ff165b6115a75760405162461bcd60e51b8152600401610bd890613e6f565b6001600160a01b038116600081815260036020526040808220805460ff19166001179055517fbf3f493c772c8c283fd124432c2d0f539ab343faa04258fe88e52912d36b102b908290a350565b6002546001600160a01b031633148061161c57503360009081526003602052604090205460ff165b6116385760405162461bcd60e51b8152600401610bd890613e6f565b6000828152600f60209081526040808320815160e08101835290546001600160801b038116825263ffffffff600160801b82048116948301859052600160a01b8204811693830193909352600160c01b8104909216606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b909204909116151560c082015291036116e5576040516347c0cce560e01b815260040160405180910390fd5b6001600160801b0382811682526000848152600f60209081526040918290208451815492860151848701516060880151608089015160a08a015160c08b0151959099166001600160a01b031990971696909617600160801b63ffffffff948516021767ffffffffffffffff60a01b1916600160a01b9284169290920263ffffffff60c01b191691909117600160c01b92909116919091021762ffffff60e01b1916600160e01b61ffff9094169390930260ff60f01b191692909217600160f01b94151594909402939093176001600160f81b0316600160f81b91151591909102179091555183907f44e4819dc1ed2a187bca4e8978c8bbf1a42c34bb4697c9f02db89d87d007614b906117f9908490613e95565b60405180910390a2505050565b6002546001600160a01b031633148061182e57503360009081526003602052604090205460ff165b61184a5760405162461bcd60e51b8152600401610bd890613e6f565b6000848152600f60209081526040808320815160e08101835290546001600160801b038116825263ffffffff600160801b82048116948301859052600160a01b8204811693830193909352600160c01b8104909216606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b909204909116151560c082015291036118f7576040516347c0cce560e01b815260040160405180910390fd5b61ffff8085166080830190815284151560a0840190815284151560c085019081526000898152600f60209081526040918290208751815492890151848a015160608b01519851975196511515600160f81b026001600160f81b03971515600160f01b0260ff60f01b1999909b16600160e01b029890981662ffffff60e01b1963ffffffff9a8b16600160c01b0263ffffffff60c01b19938c16600160a01b029390931667ffffffffffffffff60a01b199b909416600160801b026001600160a01b03199097166001600160801b039095169490941795909517989098161796909617959095161794909417161790555185907f63ad5f4d7f7728e5b8f9a8e757982827e6df61fa74911e98cb44748a0f9b057890611a16908490613e95565b60405180910390a25050505050565b6002546001600160a01b0316331480611a4d57503360009081526003602052604090205460ff165b611a695760405162461bcd60e51b8152600401610bd890613e6f565b600861125b828261405e565b600a8054610f0690613f02565b81600d5460ff1615611a9757611a9781612207565b611aa18383612b55565b505050565b6002546001600160a01b0316331480611ace57503360009081526003602052604090205460ff165b611aea5760405162461bcd60e51b8152600401610bd890613e6f565b61125b82826129ea565b33600090815260208181526040808320858452909152902054811115611b4a5760405162461bcd60e51b815260206004820152600b60248201526a21a0a72727aa2fa12aa92760a91b6044820152606401610bd8565b61125b338383612bc1565b6002546001600160a01b0316331480611b7d57503360009081526003602052604090205460ff165b611b995760405162461bcd60e51b8152600401610bd890613e6f565b600d805460ff1916911515919091179055565b6000838152600f6020908152604091829020825160e08101845290546001600160801b038116825263ffffffff600160801b8204811693830193909352600160a01b8104831693820193909352600160c01b8304909116606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b90920490911615801560c0830152611c5a57604051630426ff7760e01b815260040160405180910390fd5b611c66848484846126d2565b50505050565b6002546001600160a01b0316331480611c9457503360009081526003602052604090205460ff165b611cb05760405162461bcd60e51b8152600401610bd890613e6f565b600e54611cc5906001600160a01b0316612c33565b600e60009054906101000a90046001600160a01b03166001600160a01b031663465105f06040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611d1557600080fd5b505af1158015611c66573d6000803e3d6000fd5b6000828152600f60209081526040808320815160e08101835290546001600160801b038116825263ffffffff600160801b8204811683860152600160a01b8204811683850152600160c01b820416606083015261ffff600160e01b820481166080840190815260ff600160f01b84048116151560a0860152600160f81b909304909216151560c08401526001600160a01b038716865285855283862088875290945291842054915190928491168211611df55781836080015161ffff16611df0919061411e565b611df8565b60005b9695505050505050565b6002546001600160a01b0316331480611e2a57503360009081526003602052604090205460ff165b611e465760405162461bcd60e51b8152600401610bd890613e6f565b600e546114d4906001600160a01b0316612c33565b6002546001600160a01b0316331480611e8357503360009081526003602052604090205460ff165b611e9f5760405162461bcd60e51b8152600401610bd890613e6f565b61139481612cf1565b6002546001600160a01b0316331480611ed057503360009081526003602052604090205460ff165b611eec5760405162461bcd60e51b8152600401610bd890613e6f565b61125b8282612d66565b60088054610f0690613f02565b6002546001600160a01b0316331480611f2b57503360009081526003602052604090205460ff165b611f475760405162461bcd60e51b8152600401610bd890613e6f565b8163ffffffff16600003611f6e576040516361bc7fb160e11b815260040160405180910390fd5b60008163ffffffff16118015611f8957508063ffffffff1642115b15611fa75760405163312728dd60e11b815260040160405180910390fd5b6000838152600f60209081526040808320815160e08101835290546001600160801b038116825263ffffffff600160801b82048116948301859052600160a01b8204811693830193909352600160c01b8104909216606082015261ffff600160e01b830416608082015260ff600160f01b83048116151560a0830152600160f81b909204909116151560c08201529103612054576040516347c0cce560e01b815260040160405180910390fd5b63ffffffff808416602080840191825284831660408086019182526000898152600f9093529182902085518154945192516060880151608089015160a08a015160c08b01511515600160f81b026001600160f81b03911515600160f01b0260ff60f01b1961ffff909416600160e01b029390931662ffffff60e01b19948c16600160c01b0263ffffffff60c01b19968d16600160a01b029690961667ffffffffffffffff60a01b1999909c16600160801b026001600160a01b0319909b166001600160801b03909716969096179990991796909616989098179190911716179490941716919091179091555184907fe7decc699896feefecbb9be5418a0bc1c84d880973ee5ecf2f92deb0f0f7f75e9061216f908490613e95565b60405180910390a250505050565b856001600160a01b03811633146121a257600d5460ff16156121a2576121a233612207565b6121b0878787878787612de9565b50505050505050565b60006301ffc9a760e01b6001600160e01b0319831614806121ea5750636cdb3d1360e11b6001600160e01b03198316145b80610ef35750506001600160e01b0319166303a24d0760e21b1490565b69c617113400112233445560005230601a5280603a52600080604460166daaeb6d7670e522a718067333cd4e5afa612243573d6000803e3d6000fd5b6000603a5250565b84831461228c5760405162461bcd60e51b815260206004820152600f60248201526e0988a9c8ea890be9a92a69a82a8869608b1b6044820152606401610bd8565b336001600160a01b03891614806122c657506001600160a01b038816600090815260016020908152604080832033845290915290205460ff165b6123035760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610bd8565b60008060005b878110156123be5788888281811061232357612323614002565b90506020020135925086868281811061233e5761233e614002565b6001600160a01b038e166000908152602081815260408083208984528252822080549390910294909401359550859392509061237b90849061411e565b90915550506001600160a01b038a16600090815260208181526040808320868452909152812080548492906123b1908490614131565b9091555050600101612309565b50886001600160a01b03168a6001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b6040516124129493929190614176565b60405180910390a46001600160a01b0389163b156124b95760405163bc197c8160e01b808252906001600160a01b038b169063bc197c81906124669033908f908e908e908e908e908e908e906004016141d1565b6020604051808303816000875af1158015612485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a99190614235565b6001600160e01b031916146124c6565b6001600160a01b03891615155b6124e25760405162461bcd60e51b8152600401610bd890614252565b50505050505050505050565b6001600160a01b0390911690637d3e3dbe8161251b57826125145750634420e48661251b565b5063a0af29035b8060e01b60005230600452826024526004600060446000806daaeb6d7670e522a718067333cd4e5af1612559578060005160e01c0361255957600080fd5b5060006024525050565b6040805160a08101825286815260208082018790526001600160a01b0386168284018190526000908152600c82528381205460608401528351601f8601839004830281018301909452848452928392916080830191908790879081908401838280828437600092018290525093909452505082516020808501516040808701516001600160a01b0381168652600c90935284208054969750939561268095507fe37c1ccae98d27199c22415b5eeafcff88faf573ce46a133cfc68db0c918d56594919291876126318361427c565b9091555060408051602081019690965285019390935260608401919091526001600160a01b0316608083015260a082015260c00160405160208183030381529060405280519060200120612fc9565b90506000612692828460800151613017565b6001600160a01b0381166000908152600b602052604090205490915060ff1680156126c557506001600160a01b03811615155b9998505050505050505050565b600083905042826020015163ffffffff161115612701576040516254d81f60e41b815260040160405180910390fd5b6000826040015163ffffffff161180156127245750816040015163ffffffff1642115b15612742576040516330aee1db60e21b815260040160405180910390fd5b81516001600160801b03161580159061277157508151349061276e9086906001600160801b0316613fc9565b14155b1561278f57604051636992e1ff60e01b815260040160405180910390fd5b8160a0015180156127a657506127a48361303b565b155b156127c457604051633664886760e11b815260040160405180910390fd5b608082015161ffff16156128c457816080015161ffff168411156127fb57604051632d00877b60e11b815260040160405180910390fd5b6001600160a01b038316600090815260208181526040808320888452909152812054608084015190919061ffff168210156128495781846080015161ffff16612844919061411e565b61284c565b60005b90508086111561285a578092505b8260000361287a5760405162726eb760e11b815260040160405180910390fd5b83516001600160801b03161580159061289257508286115b156128c15783516128c19033906001600160801b03166128b2868a61411e565b6128bc9190613fc9565b61304e565b50505b60608201805163ffffffff908301811682526000878152600f60209081526040918290208651815492880151938801519551608089015160a08a015160c08b01511515600160f81b026001600160f81b03911515600160f01b0260ff60f01b1961ffff909416600160e01b029390931662ffffff60e01b19948a16600160c01b0263ffffffff60c01b199b8b16600160a01b029b909b1667ffffffffffffffff60a01b1999909a16600160801b026001600160a01b03199098166001600160801b039096169590951796909617969096169690961796909617959095169490941792909217161790556129b8838683613143565b60405185907f97740a2d1e4e75b5dea30b31b96c67193bed444129f7f62010953c83c9b03dcd90600090a25050505050565b6001600160a01b038116612a115760405163172fe2d160e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000906001600160a01b038416906370a0823190602401602060405180830381865afa158015612a58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7c9190614295565b905080600003612a9f5760405163334ab3f560e11b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b038381166004830152602482018390526000919085169063a9059cbb906044016020604051808303816000875af1158015612af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b1691906142ae565b905080611c6657604051631d42c86760e21b815260040160405180910390fd5b6114d4733cc6cdda760b79bafa08df41ecfa224f810dceb660016124ee565b3360008181526001602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6001600160a01b03831660009081526020818152604080832085845290915281208054839290612bf290849061411e565b909155505060408051838152602081018390526000916001600160a01b038616913391600080516020614345833981519152910160405180910390a4505050565b6001600160a01b038116612c5a5760405163172fe2d160e01b815260040160405180910390fd5b476000819003612c7d5760405163334ab3f560e11b815260040160405180910390fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612cca576040519150601f19603f3d011682016040523d82523d6000602084013e612ccf565b606091505b5050905080611aa157604051631d42c86760e21b815260040160405180910390fd5b600554600160a01b900460ff1615612d1c576040516313ef243160e11b815260040160405180910390fd5b600580546001600160a01b0319166001600160a01b0383169081179091556040517f0713c9f4b0c5db294e61505e6819f6ad0cccf782df1a544939dc55d13fe7fc1c90600090a250565b612710811115612d89576040516303c799a760e61b815260040160405180910390fd5b6040805180820182526001600160a01b03841680825262ffffff84166020909201829052600160a01b909102811760065590518291907ff21fccf4d64d86d532c4e4eb86c007b6ad57a460c27d724188625e755ec6cf6d90600090a35050565b336001600160a01b0387161480612e2357506001600160a01b038616600090815260016020908152604080832033845290915290205460ff165b612e605760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610bd8565b6001600160a01b03861660009081526020818152604080832087845290915281208054859290612e9190849061411e565b90915550506001600160a01b03851660009081526020818152604080832087845290915281208054859290612ec7908490614131565b909155505060408051858152602081018590526001600160a01b0380881692908916913391600080516020614345833981519152910160405180910390a46001600160a01b0385163b15612fa05760405163f23a6e6160e01b808252906001600160a01b0387169063f23a6e6190612f4d9033908b908a908a908a908a906004016142cb565b6020604051808303816000875af1158015612f6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f909190614235565b6001600160e01b03191614612fad565b6001600160a01b03851615155b6113315760405162461bcd60e51b8152600401610bd890614252565b6000610ef3612fd66132ca565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061302685856133f1565b9150915061303381613436565b509392505050565b60008061304783613580565b1192915050565b61305882826135f9565b61125b57600d60019054906101000a90046001600160a01b03166001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130ac57600080fd5b505af11580156130c0573d6000803e3d6000fd5b5050600d5460405163a9059cbb60e01b81526001600160a01b03878116600483015260248201879052610100909204909116935063a9059cbb925060440190506020604051808303816000875af115801561311f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa191906142ae565b6001600160a01b03831660009081526020818152604080832085845290915281208054839290613174908490614131565b909155505060075460408051848152602081018490526001600160a01b03909216916000913391600080516020614345833981519152910160405180910390a460075460408051848152602081018490526001600160a01b038681169316913391600080516020614345833981519152910160405180910390a46001600160a01b0383163b156132a15760075460405163f23a6e6160e01b8082523360048301526001600160a01b039283166024830152604482018590526064820184905260a06084830152600060a48301529185169063f23a6e619060c4016020604051808303816000875af115801561326d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132919190614235565b6001600160e01b031916146132ae565b6001600160a01b03831615155b611aa15760405162461bcd60e51b8152600401610bd890614252565b6000306001600160a01b037f0000000000000000000000002f4c0c83ef2c39d269c3f4fa12c5bd04bf16bddd1614801561332357507f000000000000000000000000000000000000000000000000000000000000000146145b1561334d57507f92bfdd905040fb90672083edca76000e631b640026e4cc1cc5bc15a8bc9c69a990565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f7edc74ecdd8a6af46cbe45aa86005f8ad014ffa05c89cc8963f530c9d96ba5f5828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60008082516041036134275760208301516040840151606085015160001a61341b87828585613670565b9450945050505061342f565b506000905060025b9250929050565b600081600481111561344a5761344a614312565b036134525750565b600181600481111561346657613466614312565b036134b35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610bd8565b60028160048111156134c7576134c7614312565b036135145760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610bd8565b600381600481111561352857613528614312565b036113945760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610bd8565b60048054604051627eeac760e11b81526001600160a01b0384811693820193909352600160248201526000929091169062fdd58e90604401602060405180830381865afa1580156135d5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef39190614295565b60408051600080825260208201928390529182916001600160a01b03861691859161362391614328565b60006040518083038185875af1925050503d8060008114613660576040519150601f19603f3d011682016040523d82523d6000602084013e613665565b606091505b509095945050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156136a7575060009050600361372b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136fb573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166137245760006001925092505061372b565b9150600090505b94509492505050565b80356001600160801b038116811461374b57600080fd5b919050565b803563ffffffff8116811461374b57600080fd5b803561ffff8116811461374b57600080fd5b801515811461139457600080fd5b600080600080600080600060e0888a03121561379f57600080fd5b873596506137af60208901613734565b95506137bd60408901613750565b94506137cb60608901613750565b93506137d960808901613764565b925060a08801356137e981613776565b915060c08801356137f981613776565b8091505092959891949750929550565b80356001600160a01b038116811461374b57600080fd5b6000806040838503121561383357600080fd5b61383c83613809565b946020939093013593505050565b6001600160e01b03198116811461139457600080fd5b60006020828403121561387257600080fd5b813561387d8161384a565b9392505050565b60005b8381101561389f578181015183820152602001613887565b50506000910152565b60208152600082518060208401526138c7816040850160208701613884565b601f01601f19169190910160400192915050565b6000602082840312156138ed57600080fd5b5035919050565b60006020828403121561390657600080fd5b61387d82613809565b6000806040838503121561392257600080fd5b50508035926020909101359150565b60008083601f84011261394357600080fd5b50813567ffffffffffffffff81111561395b57600080fd5b6020830191508360208260051b850101111561342f57600080fd5b60008083601f84011261398857600080fd5b50813567ffffffffffffffff8111156139a057600080fd5b60208301915083602082850101111561342f57600080fd5b60008060008060008060008060a0898b0312156139d457600080fd5b6139dd89613809565b97506139eb60208a01613809565b9650604089013567ffffffffffffffff80821115613a0857600080fd5b613a148c838d01613931565b909850965060608b0135915080821115613a2d57600080fd5b613a398c838d01613931565b909650945060808b0135915080821115613a5257600080fd5b50613a5f8b828c01613976565b999c989b5096995094979396929594505050565b60008060408385031215613a8657600080fd5b613a8f83613809565b91506020830135613a9f81613776565b809150509250929050565b600080600080600060808688031215613ac257600080fd5b8535945060208601359350613ad960408701613809565b9250606086013567ffffffffffffffff811115613af557600080fd5b613b0188828901613976565b969995985093965092949392505050565b60008060008060408587031215613b2857600080fd5b843567ffffffffffffffff80821115613b4057600080fd5b613b4c88838901613931565b90965094506020870135915080821115613b6557600080fd5b50613b7287828801613931565b95989497509550505050565b6020808252825182820181905260009190848201906040850190845b81811015613bb657835183529284019291840191600101613b9a565b50909695505050505050565b60008060408385031215613bd557600080fd5b8235915061115560208401613734565b60008060008060808587031215613bfb57600080fd5b84359350613c0b60208601613764565b92506040850135613c1b81613776565b91506060850135613c2b81613776565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c7557613c75613c36565b604052919050565b600067ffffffffffffffff821115613c9757613c97613c36565b50601f01601f191660200190565b600060208284031215613cb757600080fd5b813567ffffffffffffffff811115613cce57600080fd5b8201601f81018413613cdf57600080fd5b8035613cf2613ced82613c7d565b613c4c565b818152856020838501011115613d0757600080fd5b81602084016020830137600091810160200191909152949350505050565b60008060408385031215613d3857600080fd5b613d4183613809565b915061115560208401613809565b600060208284031215613d6157600080fd5b813561387d81613776565b600080600060608486031215613d8157600080fd5b8335925060208401359150613d9860408501613809565b90509250925092565b60008060408385031215613db457600080fd5b8235915061115560208401613809565b600080600060608486031215613dd957600080fd5b83359250613de960208501613750565b9150613d9860408501613750565b60008060008060008060a08789031215613e1057600080fd5b613e1987613809565b9550613e2760208801613809565b94506040870135935060608701359250608087013567ffffffffffffffff811115613e5157600080fd5b613e5d89828a01613976565b979a9699509497509295939492505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b600060e0820190506001600160801b038351168252602083015163ffffffff8082166020850152806040860151166040850152806060860151166060850152505061ffff608084015116608083015260a0830151151560a083015260c0830151151560c083015292915050565b600181811c90821680613f1657607f821691505b602082108103613f3657634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215613f4e57600080fd5b815167ffffffffffffffff811115613f6557600080fd5b8201601f81018413613f7657600080fd5b8051613f84613ced82613c7d565b818152856020838501011115613f9957600080fd5b613faa826020830160208601613884565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610ef357610ef3613fb3565b600082613ffd57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b601f821115611aa157600081815260208120601f850160051c8101602086101561403f5750805b601f850160051c820191505b818110156113315782815560010161404b565b815167ffffffffffffffff81111561407857614078613c36565b61408c816140868454613f02565b84614018565b602080601f8311600181146140c157600084156140a95750858301515b600019600386901b1c1916600185901b178555611331565b600085815260208120601f198616915b828110156140f0578886015182559484019460019091019084016140d1565b508582101561410e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b81810381811115610ef357610ef3613fb3565b80820180821115610ef357610ef3613fb3565b81835260006001600160fb1b0383111561415d57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061418a604083018688614144565b828103602084015261419d818587614144565b979650505050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0389811682528816602082015260a0604082018190526000906141fe908301888a614144565b8281036060840152614211818789614144565b905082810360808401526142268185876141a8565b9b9a5050505050505050505050565b60006020828403121561424757600080fd5b815161387d8161384a565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b60006001820161428e5761428e613fb3565b5060010190565b6000602082840312156142a757600080fd5b5051919050565b6000602082840312156142c057600080fd5b815161387d81613776565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905260009061430690830184866141a8565b98975050505050505050565b634e487b7160e01b600052602160045260246000fd5b6000825161433a818460208701613884565b919091019291505056fec3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62a164736f6c6343000811000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003b1bd4c99c059ed58155240fd01d6fc86a430d4d0000000000000000000000006306d0cdfadd6095a313e8484275b6cc7036166c00000000000000000000000085991f5f68b0f3678baae5848dea092c582df0cf00000000000000000000000000000000000000000000000000000000000002ee0000000000000000000000008d12974b9003112ecb9f58d60095cc03bef8f0e300000000000000000000000016f444f2d9e696834c1c9b536dc3896e1b545213
-----Decoded View---------------
Arg [0] : owner_ (address): 0x3B1Bd4C99c059ED58155240FD01D6fC86A430D4D
Arg [1] : admin_ (address): 0x6306D0cDFADD6095A313e8484275b6cC7036166C
Arg [2] : payments_ (address): 0x85991F5F68b0F3678bAAE5848DEa092c582Df0Cf
Arg [3] : royaltiesAmount_ (uint256): 750
Arg [4] : metadata_ (address): 0x8d12974B9003112ecB9F58D60095Cc03BeF8f0e3
Arg [5] : fountCard_ (address): 0x16F444F2d9E696834C1c9b536Dc3896E1B545213
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000003b1bd4c99c059ed58155240fd01d6fc86a430d4d
Arg [1] : 0000000000000000000000006306d0cdfadd6095a313e8484275b6cc7036166c
Arg [2] : 00000000000000000000000085991f5f68b0f3678baae5848dea092c582df0cf
Arg [3] : 00000000000000000000000000000000000000000000000000000000000002ee
Arg [4] : 0000000000000000000000008d12974b9003112ecb9f58d60095cc03bef8f0e3
Arg [5] : 00000000000000000000000016f444f2d9e696834c1c9b536dc3896e1b545213
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.