Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19153698 | 200 days ago | 0.767 ETH | ||||
19153698 | 200 days ago | 0.767 ETH | ||||
19153698 | 200 days ago | 0.19175 ETH | ||||
19153698 | 200 days ago | 0.19175 ETH | ||||
19153698 | 200 days ago | 6.71125 ETH | ||||
19153698 | 200 days ago | 6.71125 ETH | ||||
19153684 | 200 days ago | 1 ETH | ||||
19153684 | 200 days ago | 1 ETH | ||||
19153684 | 200 days ago | 0.25 ETH | ||||
19153684 | 200 days ago | 0.25 ETH | ||||
19153684 | 200 days ago | 8.75 ETH | ||||
19153684 | 200 days ago | 8.75 ETH | ||||
19153573 | 200 days ago | 0.0005 ETH | ||||
19153573 | 200 days ago | 0.0005 ETH | ||||
19153573 | 200 days ago | 0.000125 ETH | ||||
19153573 | 200 days ago | 0.000125 ETH | ||||
19153573 | 200 days ago | 0.004375 ETH | ||||
19153573 | 200 days ago | 0.004375 ETH | ||||
19075707 | 211 days ago | 0.9995 ETH | ||||
19075707 | 211 days ago | 0.9995 ETH | ||||
19075707 | 211 days ago | 0.249875 ETH | ||||
19075707 | 211 days ago | 0.249875 ETH | ||||
19075707 | 211 days ago | 8.745625 ETH | ||||
19075707 | 211 days ago | 8.745625 ETH | ||||
19075641 | 211 days ago | 0.0005 ETH |
Loading...
Loading
Contract Name:
GhostNFTMarket
Compiler Version
v0.8.6+commit.11564f7e
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v2; import './interfaces/IERC721Ownable.sol'; import '../node_modules/@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol'; import '../node_modules/@openzeppelin/contracts/security/ReentrancyGuard.sol'; import '../node_modules/@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import './interfaces/ICollectionWhitelistChecker.sol'; import '../node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; import './libraries/AdminWhitelistable.sol'; import './libraries/PayReward.sol'; contract GhostNFTMarket is ERC721Holder, AdminWhitelistable, ReentrancyGuard, PayReward { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.UintSet; using SafeERC20 for IERC20; enum CollectionStatus { Pending, Open, Close } uint256 public constant TOTAL_MAX_FEE = 10000; // 100% of a sale address public treasury; uint256 public minAskPrice; // in wei uint256 public maxAskPrice; // in wei uint256 public _treasuryFee = 250; EnumerableSet.AddressSet private _collectionAddressSet; address[] private _supportedCollections; mapping(address => mapping(uint256 => Ask)) private _askDetails; // Ask details (price + seller address) for a given collection and a tokenId mapping(address => EnumerableSet.UintSet) private _askTokenIds; // Set of tokenIds for a collection mapping(address => Collection) private _collections; // Details about the collections mapping(address => mapping(address => EnumerableSet.UintSet)) private _tokenIdsOfSellerForCollection; mapping(address => mapping(uint256 => address)) private _tokenCreators; // Details about token creators struct Ask { address seller; // address of the seller uint256 price; // price of the token address msgSender; // address of the msgSender } struct Collection { CollectionStatus status; // status of the collection address creatorAddress; // address of the creator address whitelistChecker; // whitelist checker (if not set --> 0x00) uint256 creatorFee; // creator fee (100 = 1%, 500 = 5%, 5 = 0.05%) uint256 refererFee; // referer fee (100 = 1%, 500 = 5%, 5 = 0.05%) } event AskNew( address indexed collection, address indexed seller, uint256 indexed tokenId, uint256 askPrice, address msgSender ); event AskCancel(address indexed collection, address indexed seller, uint256 indexed tokenId); event AskUpdate( address indexed collection, address indexed seller, uint256 indexed tokenId, uint256 askPrice, address msgSender ); // Collection is closed for trading and new listings event CollectionClose(address indexed collection); // New collection is added event CollectionNew( address indexed collection, address indexed creator, address indexed whitelistChecker, uint256 creatorFee, uint256 refererFee ); // Existing collection is updated event CollectionUpdate( address indexed collection, address indexed creator, address indexed whitelistChecker, uint256 creatorFee, uint256 refererFee ); event UpdateTreasury(address indexed treasury); event UpdateMinAndMaxAskPrices(uint256 minimumAskPrice, uint256 maximumAskPrice); // Recover NFT tokens sent by accident event NonFungibleTokenRecovery(address indexed token, uint256 indexed tokenId); // Recover ERC20 tokens sent by accident event TokenRecovery(address indexed token, uint256 amount); // Ask order is matched by a trade event Trade( address indexed collection, uint256 indexed tokenId, address indexed seller, address buyer, uint256 askPrice, uint256 netPrice ); /** * @notice Constructor * @param _whitelist : address of the ghost admin whitelist * @param _treasury: address of the treasury * @param _weth: WETH address * @param _minAskPrice: minimum ask price * @param _maxAskPrice: maximum ask price */ constructor(address _whitelist, address _treasury, address _weth, uint256 _minAskPrice, uint256 _maxAskPrice) { _updateAdminWhitelist(_whitelist); _updateTreasury(_treasury); _updateWETH(_weth); _updateMinMaxAsk(_minAskPrice, _maxAskPrice); } /** * @notice Buy token with ETH by matching the price of an existing ask order * @param _collection: contract address of the NFT * @param _tokenId: tokenId of the NFT purchased * @param _referer: referer of buyer * @param _to: nft sending target */ function buyTokenUsingETH( address _collection, uint256 _tokenId, address _referer, address _to ) external payable nonReentrant { _WETHDeposit(); _buyToken(_collection, _tokenId, msg.value, _referer, _to); } /** * @notice Buy token with WETH by matching the price of an existing ask order * @param _collection: contract address of the NFT * @param _tokenId: tokenId of the NFT purchased * @param _price: price (must be equal to the askPrice set by the seller) * @param _referer: referer of buyer * @param _to: nft sending target */ function buyTokenUsingWETH( address _collection, uint256 _tokenId, uint256 _price, address _referer, address _to ) external nonReentrant { _WETHTransferFrom(msg.sender, address(this), _price); _buyToken(_collection, _tokenId, _price, _referer, _to); } function _checkTokenListed(address _collection, uint256 _tokenId, address _seller) internal view { require( _tokenIdsOfSellerForCollection[_seller][_collection].contains(_tokenId), 'GhostNFTMarket : Token not listed' ); } /** * @notice Cancel existing ask order * @param _collection: contract address of the NFT * @param _tokenId: tokenId of the NFT */ function cancelAskOrder(address _collection, uint256 _tokenId) external nonReentrant { // Verify the sender has listed it _checkTokenListed(_collection, _tokenId, msg.sender); // Adjust the information _tokenIdsOfSellerForCollection[msg.sender][_collection].remove(_tokenId); delete _askDetails[_collection][_tokenId]; _askTokenIds[_collection].remove(_tokenId); // Transfer the NFT back to the user IERC721Ownable(_collection).transferFrom(address(this), address(msg.sender), _tokenId); // Emit event emit AskCancel(_collection, msg.sender, _tokenId); } function _checkPriceRange(uint256 _ask) internal view { require(_ask >= minAskPrice && _ask <= maxAskPrice, 'GhostNFTMarket : Price not within range'); } function _checkCollectionOpen(address _collection) internal view { require(_collections[_collection].status == CollectionStatus.Open, 'GhostNFTMarket : Not for listing'); } /** * @notice Create ask order * @param _collection: contract address of the NFT * @param _tokenId: tokenId of the NFT * @param _askPrice: price for listing (in wei) * @param _seller: address of seller */ function createAskOrder( address _collection, uint256 _tokenId, uint256 _askPrice, address _seller ) external nonReentrant { _checkPriceRange(_askPrice); // Verify price is not too low/high _checkCollectionOpen(_collection); // Verify collection is accepted // Verify token has restriction require(_isClearCollectionWhitelist(_collection, _tokenId), 'GhostNFTMarket : tokenId not eligible'); // Transfer NFT to this contract IERC721Ownable(_collection).safeTransferFrom(address(msg.sender), address(this), _tokenId); // Adjust the information _tokenIdsOfSellerForCollection[_seller][_collection].add(_tokenId); _askDetails[_collection][_tokenId] = Ask({msgSender: msg.sender, price: _askPrice, seller: _seller}); // Add tokenId to the askTokenIds set _askTokenIds[_collection].add(_tokenId); // Emit event emit AskNew(_collection, _seller, _tokenId, _askPrice, msg.sender); } /** * @notice Modify existing ask order * @param _collection: contract address of the NFT * @param _tokenId: tokenId of the NFT * @param _newPrice: new price for listing (in wei) * @param _seller: address of seller */ function modifyAskOrder( address _collection, uint256 _tokenId, uint256 _newPrice, address _seller ) external nonReentrant { // Verify new price is not too low/high _checkPriceRange(_newPrice); // Verify collection is accepted _checkCollectionOpen(_collection); // Verify the sender has listed it _checkTokenListed(_collection, _tokenId, _seller); // Adjust the information _askDetails[_collection][_tokenId].price = _newPrice; // Emit event emit AskUpdate(_collection, _seller, _tokenId, _newPrice, msg.sender); } function _checkCreatorFee(uint256 _creatorFee, address _creator) internal pure { require( _creatorFee == 0 || (_creatorFee != 0 && _creator != address(0)), 'GhostNFTMarket: Creator parameters incorrect' ); } function _checkFee(uint256 _a, uint256 _b, uint256 _c) internal pure { require(_a + _b + _c <= TOTAL_MAX_FEE, 'GhostNFTMarket: Sum of fee must inferior to TOTAL_MAX_FEE'); } /** * @notice Add a new collection * @param _collection: collection address * @param _creator: creator address (must be 0x00 if none) * @param _whitelistChecker: whitelist checker (for additional restrictions, must be 0x00 if none) * @param _creatorFee: creator fee (100 = 1%, 500 = 5%, 5 = 0.05%, 0 if creator is 0x00) * @param _refererFee: referer fee (100 = 1%, 500 = 5%, 5 = 0.05%, 0 if creator is 0x00) * @dev Callable by admin */ function addCollection( address _collection, address _creator, address _whitelistChecker, uint256 _creatorFee, uint256 _refererFee ) external { _addCollection(_collection, _creator, _whitelistChecker, _creatorFee, _refererFee); } function _addCollection( address _collection, address _creator, address _whitelistChecker, uint256 _creatorFee, uint256 _refererFee ) internal { require(!_collectionAddressSet.contains(_collection), 'GhostNFTMarket: Collection already listed'); require(IERC721Ownable(_collection).supportsInterface(0x80ac58cd), 'GhostNFTMarket: Not ERC721'); require( IERC721Ownable(_collection).owner() == msg.sender || isInWhitelist(msg.sender), 'GhostNFTMarket: Not collection owner' ); _checkCreatorFee(_creatorFee, _creator); _checkFee(_treasuryFee, _creatorFee, _refererFee); _collectionAddressSet.add(_collection); _supportedCollections.push(_collection); _collections[_collection] = Collection({ status: CollectionStatus.Open, creatorAddress: _creator, whitelistChecker: _whitelistChecker, creatorFee: _creatorFee, refererFee: _refererFee }); emit CollectionNew(_collection, _creator, _whitelistChecker, _creatorFee, _refererFee); } /** * @notice Get all collections with supported this nft market */ function getCollections() external view returns (address[] memory) { return _supportedCollections; } /** * @notice Allows the admin to close collection for trading and new listing * @param _collection: collection address * @dev Callable by admin */ function closeCollectionForTradingAndListing(address _collection) external onlyAdminWhitelist { require(_collectionAddressSet.contains(_collection), 'GhostNFTMarket: Collection not listed'); _collections[_collection].status = CollectionStatus.Close; _collectionAddressSet.remove(_collection); emit CollectionClose(_collection); } /** * @notice Modify collection characteristics * @param _collection: collection address * @param _creator: creator address (must be 0x00 if none) * @param _whitelistChecker: whitelist checker (for additional restrictions, must be 0x00 if none) * @param _creatorFee: creator fee (100 = 1%, 500 = 5%, 5 = 0.05%, 0 if creator is 0x00) * @param _refererFee: referer fee (100 = 1%, 500 = 5%, 5 = 0.05%, 0 if creator is 0x00) * @dev Callable by admin */ function modifyCollection( address _collection, address _creator, address _whitelistChecker, uint256 _creatorFee, uint256 _refererFee ) external { require(_collectionAddressSet.contains(_collection), 'GhostNFTMarket : Collection not listed'); require( IERC721Ownable(_collection).owner() == msg.sender || isInWhitelist(msg.sender), 'GhostNFTMarket: Not collection owner' ); _checkCreatorFee(_creatorFee, _creator); _checkFee(_treasuryFee, _creatorFee, _refererFee); _collections[_collection] = Collection({ status: CollectionStatus.Open, creatorAddress: _creator, whitelistChecker: _whitelistChecker, creatorFee: _creatorFee, refererFee: _refererFee }); emit CollectionUpdate(_collection, _creator, _whitelistChecker, _creatorFee, _refererFee); } /** * @notice Allows the admin to update minimum and maximum prices for a token (in wei) * @param _min: minimum ask price * @param _max: maximum ask price * @dev Callable by admin */ function _updateMinMaxAsk(uint256 _min, uint256 _max) internal { require(_min > 0, 'GhostNFTMarket : _minAskPrice > 0'); require(_min < _max, 'GhostNFTMarket : _minAskPrice < _maxAskPrice'); minAskPrice = _min; maxAskPrice = _max; emit UpdateMinAndMaxAskPrices(_min, _max); } function updateMinMaxAsk(uint256 _min, uint256 _max) external onlyAdminWhitelist { return _updateMinMaxAsk(_min, _max); } /** * @notice Allows the owner to recover tokens sent to the contract by mistake * @param _token: token address * @dev Callable by owner */ function recoverFungibleTokens(address _token) external onlyOwner { require(_token != WETH, 'GhostNFTMarket : Cannot recover WETH'); uint256 amountToRecover = IERC20(_token).balanceOf(address(this)); require(amountToRecover != 0, 'GhostNFTMarket : No token to recover'); IERC20(_token).safeTransfer(address(msg.sender), amountToRecover); emit TokenRecovery(_token, amountToRecover); } /** * @notice Allows the owner to recover NFTs sent to the contract by mistake * @param _token: NFT token address * @param _tokenId: tokenId * @dev Callable by owner */ function recoverNonFungibleToken(address _token, uint256 _tokenId) external onlyOwner nonReentrant { require(!_askTokenIds[_token].contains(_tokenId), 'GhostNFTMarket : NFT not recoverable'); IERC721Ownable(_token).safeTransferFrom(address(this), address(msg.sender), _tokenId); emit NonFungibleTokenRecovery(_token, _tokenId); } /** * @notice Set treasury address * @param _newTreasury: address of the treasury */ function _updateTreasury(address _newTreasury) internal { require(_newTreasury != address(0), 'GhostNFTMarket: Treasury address cannot be zero'); treasury = _newTreasury; emit UpdateTreasury(_newTreasury); } function updateTreasury(address _newTreasury) external onlyAdminWhitelist { return _updateTreasury(_newTreasury); } /** * @notice Check asks for an array of tokenIds in a collection * @param collection: address of the collection * @param tokenIds: array of tokenId */ function viewAsksByCollectionAndTokenIds( address collection, uint256[] calldata tokenIds ) external view returns (bool[] memory statuses, Ask[] memory askInfo) { uint256 length = tokenIds.length; statuses = new bool[](length); askInfo = new Ask[](length); for (uint256 i = 0; i < length; i++) { if (_askTokenIds[collection].contains(tokenIds[i])) { statuses[i] = true; } else { statuses[i] = false; } askInfo[i] = _askDetails[collection][tokenIds[i]]; } return (statuses, askInfo); } /** * @notice View ask orders for a given collection across all sellers * @param collection: address of the collection * @param cursor: cursor * @param size: size of the response */ function viewAsksByCollection( address collection, uint256 cursor, uint256 size ) external view returns (uint256[] memory tokenIds, Ask[] memory askInfo, uint256) { uint256 length = size; if (length > _askTokenIds[collection].length() - cursor) { length = _askTokenIds[collection].length() - cursor; } tokenIds = new uint256[](length); askInfo = new Ask[](length); for (uint256 i = 0; i < length; i++) { tokenIds[i] = _askTokenIds[collection].at(cursor + i); askInfo[i] = _askDetails[collection][tokenIds[i]]; } return (tokenIds, askInfo, cursor + length); } /** * @notice View ask orders for a given collection and a seller * @param collection: address of the collection * @param seller: address of the seller * @param cursor: cursor * @param size: size of the response */ function viewAsksByCollectionAndSeller( address collection, address seller, uint256 cursor, uint256 size ) external view returns (uint256[] memory tokenIds, Ask[] memory askInfo, uint256) { uint256 length = size; if (length > _tokenIdsOfSellerForCollection[seller][collection].length() - cursor) { length = _tokenIdsOfSellerForCollection[seller][collection].length() - cursor; } tokenIds = new uint256[](length); askInfo = new Ask[](length); for (uint256 i = 0; i < length; i++) { tokenIds[i] = _tokenIdsOfSellerForCollection[seller][collection].at(cursor + i); askInfo[i] = _askDetails[collection][tokenIds[i]]; } return (tokenIds, askInfo, cursor + length); } /* * @notice View addresses and details for all the collections available for trading * @param cursor: cursor * @param size: size of the response */ function viewCollections( uint256 cursor, uint256 size ) external view returns (address[] memory collectionAddresses, Collection[] memory collectionDetails, uint256) { uint256 length = size; if (length > _collectionAddressSet.length() - cursor) { length = _collectionAddressSet.length() - cursor; } collectionAddresses = new address[](length); collectionDetails = new Collection[](length); for (uint256 i = 0; i < length; i++) { collectionAddresses[i] = _collectionAddressSet.at(cursor + i); collectionDetails[i] = _collections[collectionAddresses[i]]; } return (collectionAddresses, collectionDetails, cursor + length); } /** * @notice Calculate price and associated fees for a collection * @param collection: address of the collection * @param price: listed price */ function calculatePriceAndFeesForCollection( address collection, uint256 price ) external view returns (uint256 netPrice, uint256 treasureFee, uint256 creatorFee, uint256 refererFee) { if (_collections[collection].status != CollectionStatus.Open) { return (0, 0, 0, 0); } return (_calculatePriceAndFeesForCollection(collection, price)); } /** * @notice Checks if an array of tokenIds can be listed * @param _collection: address of the collection * @param _tokenIds: array of tokenIds * @dev if collection is not for trading, it returns array of bool with false */ function canTokensBeListed( address _collection, uint256[] calldata _tokenIds ) external view returns (bool[] memory listingStatuses) { listingStatuses = new bool[](_tokenIds.length); if (_collections[_collection].status != CollectionStatus.Open) { return listingStatuses; } for (uint256 i = 0; i < _tokenIds.length; i++) { listingStatuses[i] = _isClearCollectionWhitelist(_collection, _tokenIds[i]); } return listingStatuses; } /** * @notice Buy token by matching the price of an existing ask order * @param _collection: contract address of the NFT * @param _tokenId: tokenId of the NFT purchased * @param _price: price (must match the askPrice from the seller) */ function _buyToken( address _collection, uint256 _tokenId, uint256 _price, address _refererAddress, address _to ) internal { _checkCollectionOpen(_collection); require(_askTokenIds[_collection].contains(_tokenId), 'Buy: Not for sale'); Ask memory askOrder = _askDetails[_collection][_tokenId]; // Front-running protection require(_price == askOrder.price, 'Buy: Incorrect price'); require(msg.sender != askOrder.seller, 'Buy: Buyer cannot be seller'); // Calculate the net price (collected by seller), trading fee (collected by treasury), creator fee (collected by creator) ( uint256 netPrice, uint256 treasureFee, uint256 creatorFee, uint256 refererFee ) = _calculatePriceAndFeesForCollection(_collection, _price); // Update storage information _tokenIdsOfSellerForCollection[askOrder.seller][_collection].remove(_tokenId); delete _askDetails[_collection][_tokenId]; _askTokenIds[_collection].remove(_tokenId); _payReward(askOrder.seller, netPrice); _payReward(treasury, treasureFee); _payReward(_collections[_collection].creatorAddress, creatorFee); _payReward(_refererAddress, refererFee); // Transfer NFT to buyer IERC721Ownable(_collection).safeTransferFrom(address(this), _to, _tokenId); // Emit event emit Trade(_collection, _tokenId, askOrder.seller, _to, _price, netPrice); } /** * @notice Calculate price and associated fees for a collection * @param _collection: address of the collection * @param _askPrice: listed price */ function _calculatePriceAndFeesForCollection( address _collection, uint256 _askPrice ) internal view returns (uint256 netPrice, uint256 treasureFee, uint256 creatorFee, uint256 refererFee) { treasureFee = (_askPrice * _treasuryFee) / 10000; creatorFee = (_askPrice * _collections[_collection].creatorFee) / 10000; refererFee = (_askPrice * _collections[_collection].refererFee) / 10000; netPrice = _askPrice - treasureFee - creatorFee - refererFee; return (netPrice, treasureFee, creatorFee, refererFee); } /** * @notice Checks if a token can be listed * @param _collection: address of the collection * @param _tokenId: tokenId */ function _isClearCollectionWhitelist(address _collection, uint256 _tokenId) internal view returns (bool) { address whitelistCheckerAddress = _collections[_collection].whitelistChecker; return (whitelistCheckerAddress == address(0)) || ICollectionWhitelistChecker(whitelistCheckerAddress).canList(_tokenId); } function emitTradeFromPadFactory( address _collection, uint256[] calldata _tokenIds, uint256 _price, address _seller, address _referer, address _to ) external onlyAdminWhitelist { _checkPriceRange(_price); // Verify price is not too low/high _checkCollectionOpen(_collection); // Verify collection is accepted uint256 _length = _tokenIds.length; // Calculate the net price (collected by seller), trading fee (collected by treasury), creator fee (collected by creator) ( uint256 netPrice, uint256 treasureFee, uint256 creatorFee, uint256 refererFee ) = _calculatePriceAndFeesForCollection(_collection, _price); // Verify token has restriction for (uint256 index = 0; index < _length; index++) { require( _isClearCollectionWhitelist(_collection, _tokenIds[index]), 'GhostNFTMarket : tokenId not eligible' ); // event emit emit AskNew(_collection, _seller, _tokenIds[index], _price, msg.sender); emit Trade(_collection, _tokenIds[index], _seller, _to, _price, netPrice); } // Update storage information _payReward(_seller, netPrice * _length); _payReward(treasury, treasureFee * _length); _payReward(_collections[_collection].creatorAddress, creatorFee * _length); _payReward(_referer, refererFee * _length); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.0; import "../IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// 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) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated 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 v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); } function safeTransfer( address token, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); } function safeTransferFrom( address token, address from, address to, uint256 value ) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import './TransferHelper.sol'; import '../interfaces/IWETH.sol'; import '../../node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; abstract contract PayReward { using SafeERC20 for IERC20; address public WETH; event UpdateWETHAddress(address indexed _weth); receive() external payable { assert(msg.sender == WETH); } function _updateWETH(address _weth) internal { require(_weth != address(0), 'PayReward : WETH address cannot be zero'); WETH = _weth; emit UpdateWETHAddress(_weth); } function _WETHDeposit() internal { IWETH(WETH).deposit{value: msg.value}(); } function _WETHWithdraw(uint256 _value) internal { IWETH(WETH).withdraw(_value); } function _WETHTransfer(address _target, uint256 _value) internal { if (_value > 0) { IERC20(WETH).safeTransfer(_target, _value); } } function _WETHTransferFrom( address _from, address _to, uint256 _value ) internal { if (_value > 0) { IERC20(WETH).safeTransferFrom(_from, _to, _value); } } function _WETHTransferByETH(address _target, uint256 _value) internal { if (_value > 0) { _WETHWithdraw(_value); TransferHelper.safeTransferETH(_target, _value); } } function _WETHBalanceOf() internal view returns (uint256) { return IERC20(WETH).balanceOf(address(this)); } function _payReward(address _target, uint256 _value) internal { if (_value > 0) { if (payable(_target).send(0)) { _WETHTransferByETH(_target, _value); } else { _WETHTransfer(_target, _value); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../GhostAdminWhitelist.sol'; import '../../node_modules/@openzeppelin/contracts/access/Ownable.sol'; abstract contract AdminWhitelistable is Ownable { address private _adminWhitelist; event UpdateAdminWhitelist(address indexed _address); modifier onlyAdminWhitelist() { require(isInWhitelist(msg.sender), 'AdminWhitelistable : whitelist not contains msg.sender'); _; } /** * @param _newAdminWhitelist: new whitelist contract address */ function _updateAdminWhitelist(address _newAdminWhitelist) internal { require(_newAdminWhitelist != address(0), 'AdminWhitelistable: whitelist address cannot be zero'); _adminWhitelist = _newAdminWhitelist; emit UpdateAdminWhitelist(_newAdminWhitelist); } function updateAdminWhitelist(address _newAdminWhitelist) external onlyOwner { _updateAdminWhitelist(_newAdminWhitelist); } /** * @param _address: target address */ function isInWhitelist(address _address) public view returns (bool) { return GhostAdminWhitelist(_adminWhitelist).whitelists(_address); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol'; interface IERC721Ownable is IERC721 { function owner() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ICollectionWhitelistChecker { function canList(uint256 _tokenId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../node_modules/@openzeppelin/contracts/access/Ownable.sol'; // not migrate (create new whitelist) contract GhostAdminWhitelist is Ownable { mapping(address => bool) private _whitelists; event UpdateWhitelist(address indexed _address, bool _result); // change whitelist status constructor(address _admin) { _whitelists[_admin] = true; } /** * @param _address: target address * @param _result: in whitelist or not */ function updateWhitelist(address _address, bool _result) external onlyOwner { _whitelists[_address] = _result; emit UpdateWhitelist(_address, _result); } /** * @param _address: target address */ function whitelists(address _address) external view returns (bool) { return _whitelists[_address]; } }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 10000 }, "evmVersion": "berlin", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_whitelist","type":"address"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"uint256","name":"_minAskPrice","type":"uint256"},{"internalType":"uint256","name":"_maxAskPrice","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"AskCancel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"askPrice","type":"uint256"},{"indexed":false,"internalType":"address","name":"msgSender","type":"address"}],"name":"AskNew","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"askPrice","type":"uint256"},{"indexed":false,"internalType":"address","name":"msgSender","type":"address"}],"name":"AskUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"}],"name":"CollectionClose","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":true,"internalType":"address","name":"whitelistChecker","type":"address"},{"indexed":false,"internalType":"uint256","name":"creatorFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"refererFee","type":"uint256"}],"name":"CollectionNew","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":true,"internalType":"address","name":"whitelistChecker","type":"address"},{"indexed":false,"internalType":"uint256","name":"creatorFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"refererFee","type":"uint256"}],"name":"CollectionUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NonFungibleTokenRecovery","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenRecovery","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"askPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"netPrice","type":"uint256"}],"name":"Trade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"}],"name":"UpdateAdminWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minimumAskPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maximumAskPrice","type":"uint256"}],"name":"UpdateMinAndMaxAskPrices","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasury","type":"address"}],"name":"UpdateTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_weth","type":"address"}],"name":"UpdateWETHAddress","type":"event"},{"inputs":[],"name":"TOTAL_MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_treasuryFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"address","name":"_creator","type":"address"},{"internalType":"address","name":"_whitelistChecker","type":"address"},{"internalType":"uint256","name":"_creatorFee","type":"uint256"},{"internalType":"uint256","name":"_refererFee","type":"uint256"}],"name":"addCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_referer","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"buyTokenUsingETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_referer","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"buyTokenUsingWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"}],"name":"calculatePriceAndFeesForCollection","outputs":[{"internalType":"uint256","name":"netPrice","type":"uint256"},{"internalType":"uint256","name":"treasureFee","type":"uint256"},{"internalType":"uint256","name":"creatorFee","type":"uint256"},{"internalType":"uint256","name":"refererFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"canTokensBeListed","outputs":[{"internalType":"bool[]","name":"listingStatuses","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"cancelAskOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"}],"name":"closeCollectionForTradingAndListing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_askPrice","type":"uint256"},{"internalType":"address","name":"_seller","type":"address"}],"name":"createAskOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"address","name":"_seller","type":"address"},{"internalType":"address","name":"_referer","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"emitTradeFromPadFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCollections","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isInWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAskPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAskPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_newPrice","type":"uint256"},{"internalType":"address","name":"_seller","type":"address"}],"name":"modifyAskOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collection","type":"address"},{"internalType":"address","name":"_creator","type":"address"},{"internalType":"address","name":"_whitelistChecker","type":"address"},{"internalType":"uint256","name":"_creatorFee","type":"uint256"},{"internalType":"uint256","name":"_refererFee","type":"uint256"}],"name":"modifyCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"recoverFungibleTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"recoverNonFungibleToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAdminWhitelist","type":"address"}],"name":"updateAdminWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_min","type":"uint256"},{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"updateMinMaxAsk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTreasury","type":"address"}],"name":"updateTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"cursor","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"}],"name":"viewAsksByCollection","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"msgSender","type":"address"}],"internalType":"struct GhostNFTMarket.Ask[]","name":"askInfo","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"cursor","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"}],"name":"viewAsksByCollectionAndSeller","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"msgSender","type":"address"}],"internalType":"struct GhostNFTMarket.Ask[]","name":"askInfo","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"viewAsksByCollectionAndTokenIds","outputs":[{"internalType":"bool[]","name":"statuses","type":"bool[]"},{"components":[{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"address","name":"msgSender","type":"address"}],"internalType":"struct GhostNFTMarket.Ask[]","name":"askInfo","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"cursor","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"}],"name":"viewCollections","outputs":[{"internalType":"address[]","name":"collectionAddresses","type":"address[]"},{"components":[{"internalType":"enum GhostNFTMarket.CollectionStatus","name":"status","type":"uint8"},{"internalType":"address","name":"creatorAddress","type":"address"},{"internalType":"address","name":"whitelistChecker","type":"address"},{"internalType":"uint256","name":"creatorFee","type":"uint256"},{"internalType":"uint256","name":"refererFee","type":"uint256"}],"internalType":"struct GhostNFTMarket.Collection[]","name":"collectionDetails","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405260fa6007553480156200001657600080fd5b5060405162004a9038038062004a9083398101604081905262000039916200042f565b620000443362000081565b60016002556200005485620000d1565b6200005f846200019d565b6200006a8362000257565b62000076828262000309565b50505050506200048c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116620001535760405162461bcd60e51b815260206004820152603460248201527f41646d696e57686974656c69737461626c653a2077686974656c69737420616460448201527f64726573732063616e6e6f74206265207a65726f00000000000000000000000060648201526084015b60405180910390fd5b600180546001600160a01b0319166001600160a01b0383169081179091556040517f3e50444736bab5048f0beae25d9cf0982f7f44ad3d00b72e6088a98d5b04060b90600090a250565b6001600160a01b0381166200020d5760405162461bcd60e51b815260206004820152602f60248201527f47686f73744e46544d61726b65743a205472656173757279206164647265737360448201526e2063616e6e6f74206265207a65726f60881b60648201526084016200014a565b600480546001600160a01b0319166001600160a01b0383169081179091556040517f1f54d231bb9d500b1923e4a1cb25e600f366a8368873d9af7c1c623814df19fc90600090a250565b6001600160a01b038116620002bf5760405162461bcd60e51b815260206004820152602760248201527f506179526577617264203a205745544820616464726573732063616e6e6f74206044820152666265207a65726f60c81b60648201526084016200014a565b600380546001600160a01b0319166001600160a01b0383169081179091556040517fb982ba6bb867a56a1acc799103a069bc45d1c122b90acc6cb7d1175f479b615090600090a250565b60008211620003655760405162461bcd60e51b815260206004820152602160248201527f47686f73744e46544d61726b6574203a205f6d696e41736b5072696365203e206044820152600360fc1b60648201526084016200014a565b808210620003cb5760405162461bcd60e51b815260206004820152602c60248201527f47686f73744e46544d61726b6574203a205f6d696e41736b5072696365203c2060448201526b5f6d617841736b507269636560a01b60648201526084016200014a565b6005829055600681905560408051838152602081018390527fdb2a1e3f259454a99096a2a229d4af103f76dfa239ee204bcbb7159211c294ed910160405180910390a15050565b80516001600160a01b03811681146200042a57600080fd5b919050565b600080600080600060a086880312156200044857600080fd5b620004538662000412565b9450620004636020870162000412565b9350620004736040870162000412565b6060870151608090970151959894975095949392505050565b6145f4806200049c6000396000f3fe6080604052600436106101e75760003560e01c806384a4086411610102578063bf792dc111610095578063ddf9ba6f11610064578063ddf9ba6f14610636578063e17734a314610656578063f2fde38b14610676578063f59ee15c1461069657600080fd5b8063bf792dc1146105b3578063c5d4618e146105d3578063d286ef7414610600578063d9cc6c0c1461062057600080fd5b8063a5781792116100d1578063a578179214610533578063ad158e4214610553578063ad5c464814610573578063bb0fd1471461059357600080fd5b806384a40864146104865780638da5cb5b146104b557806395f42098146104d35780639e0140c8146104f357600080fd5b806351c383ea1161017a5780636df8cd13116101495780636df8cd131461041b578063715018a61461043157806372c25461146104465780637f51bb1f1461046657600080fd5b806351c383ea1461037457806357aa81af146103a357806361d027b3146103c35780636b248032146103fb57600080fd5b8063288c3d77116101b6578063288c3d771461030957806328f0b2571461031c5780633ffd17811461033257806346e635861461035257600080fd5b806309fd82121461020d578063150b7a0214610242578063209cbe7e146102b757806322f67b6d146102db57600080fd5b36610208576003546001600160a01b031633146102065761020661448f565b005b600080fd5b34801561021957600080fd5b5061022d610228366004613c93565b6106b6565b60405190151581526020015b60405180910390f35b34801561024e57600080fd5b5061028661025d366004613d28565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610239565b3480156102c357600080fd5b506102cd61271081565b604051908152602001610239565b3480156102e757600080fd5b506102fb6102f6366004613e6c565b610753565b6040516102399291906142e1565b610206610317366004613f86565b610963565b34801561032857600080fd5b506102cd60075481565b34801561033e57600080fd5b5061020661034d366004613c93565b6109de565b34801561035e57600080fd5b50610367610bcb565b60405161023991906141ed565b34801561038057600080fd5b5061039461038f3660046140e7565b610c2d565b60405161023993929190614200565b3480156103af57600080fd5b506102066103be36600461400e565b610e67565b3480156103cf57600080fd5b506004546103e3906001600160a01b031681565b6040516001600160a01b039091168152602001610239565b34801561040757600080fd5b50610206610416366004613ccd565b6110ed565b34801561042757600080fd5b506102cd60065481565b34801561043d57600080fd5b506102066113e9565b34801561045257600080fd5b50610206610461366004613ec1565b6113fd565b34801561047257600080fd5b50610206610481366004613c93565b6116c8565b34801561049257600080fd5b506104a66104a1366004613fd9565b61174f565b6040516102399392919061430f565b3480156104c157600080fd5b506000546001600160a01b03166103e3565b3480156104df57600080fd5b506102066104ee366004613f5a565b61198f565b3480156104ff57600080fd5b5061051361050e366004613f5a565b611b4f565b604080519485526020850193909352918301526060820152608001610239565b34801561053f57600080fd5b5061020661054e36600461404d565b611bb5565b34801561055f57600080fd5b5061020661056e366004613c93565b611c2f565b34801561057f57600080fd5b506003546103e3906001600160a01b031681565b34801561059f57600080fd5b506102066105ae366004613f5a565b611c40565b3480156105bf57600080fd5b506102066105ce3660046140e7565b611df5565b3480156105df57600080fd5b506105f36105ee366004613e6c565b611e7e565b60405161023991906142ce565b34801561060c57600080fd5b506104a661061b366004613e26565b611f5c565b34801561062c57600080fd5b506102cd60055481565b34801561064257600080fd5b50610206610651366004613c93565b6121c6565b34801561066257600080fd5b50610206610671366004613ccd565b612342565b34801561068257600080fd5b50610206610691366004613c93565b612356565b3480156106a257600080fd5b506102066106b136600461400e565b6123e3565b6001546040517f1e7be2100000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526000921690631e7be2109060240160206040518083038186803b15801561071557600080fd5b505afa158015610729573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074d91906140ac565b92915050565b606080828067ffffffffffffffff8111156107705761077061457a565b604051908082528060200260200182016040528015610799578160200160208202803683370190505b5092508067ffffffffffffffff8111156107b5576107b561457a565b60405190808252806020026020018201604052801561080057816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816107d35790505b50915060005b818110156109595761085d8686838181106108235761082361454b565b6001600160a01b038b166000908152600c602090815260409091209391020135905060009081526001919091016020526040902054151590565b1561088b5760018482815181106108765761087661454b565b911515602092830291909101909101526108b0565b600084828151811061089f5761089f61454b565b911515602092830291909101909101525b6001600160a01b0387166000908152600b60205260408120908787848181106108db576108db61454b565b60209081029290920135835250818101929092526040908101600020815160608101835281546001600160a01b03908116825260018301549482019490945260029091015490921690820152835184908390811061093b5761093b61454b565b6020026020010181905250808061095190614474565b915050610806565b5050935093915050565b6002805414156109ba5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600280556109c66124bc565b6109d38484348585612520565b505060016002555050565b6109e66128b4565b6003546001600160a01b0382811691161415610a695760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b6574203a2043616e6e6f74207265636f7665722060448201527f574554480000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b158015610ac457600080fd5b505afa158015610ad8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afc91906140ce565b905080610b705760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b6574203a204e6f20746f6b656e20746f2072656360448201527f6f7665720000000000000000000000000000000000000000000000000000000060648201526084016109b1565b610b846001600160a01b038316338361290e565b816001600160a01b03167f14f11966a996e0629572e51064726d2057a80fbd34efc066682c06a71dbb6e9882604051610bbf91815260200190565b60405180910390a25050565b6060600a805480602002602001604051908101604052809291908181526020018280548015610c2357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610c05575b5050505050905090565b60608060008385610c3e60086129da565b610c489190614431565b811115610c675785610c5a60086129da565b610c649190614431565b90505b8067ffffffffffffffff811115610c8057610c8061457a565b604051908082528060200260200182016040528015610ca9578160200160208202803683370190505b5093508067ffffffffffffffff811115610cc557610cc561457a565b604051908082528060200260200182016040528015610d1e57816020015b6040805160a081018252600080825260208083018290529282018190526060820181905260808201528252600019909201910181610ce35790505b50925060005b81811015610e4c57610d41610d3982896143bf565b6008906129e4565b858281518110610d5357610d5361454b565b60200260200101906001600160a01b031690816001600160a01b031681525050600d6000868381518110610d8957610d8961454b565b6020908102919091018101516001600160a01b031682528101919091526040908101600020815160a081019092528054829060ff166002811115610dcf57610dcf6144ed565b6002811115610de057610de06144ed565b815281546001600160a01b03610100909104811660208301526001830154166040820152600282015460608201526003909101546080909101528451859083908110610e2e57610e2e61454b565b60200260200101819052508080610e4490614474565b915050610d24565b508383610e5983896143bf565b935093509350509250925092565b600280541415610eb95760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b60028055610ec6826129f0565b610ecf84612a76565b610ed98484612af2565b610f4b5760405162461bcd60e51b815260206004820152602560248201527f47686f73744e46544d61726b6574203a20746f6b656e4964206e6f7420656c6960448201527f6769626c6500000000000000000000000000000000000000000000000000000060648201526084016109b1565b6040517f42842e0e000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018490526001600160a01b038516906342842e0e90606401600060405180830381600087803b158015610fb257600080fd5b505af1158015610fc6573d6000803e3d6000fd5b5050506001600160a01b038083166000908152600e60209081526040808320938916835292905220610ff9915084612bb3565b50604080516060810182526001600160a01b0380841682526020808301868152338486019081528984166000818152600b85528781208b82528552878120965187549087167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617885593516001880155915160029096018054969095169590921694909417909255908252600c9052206110969084612bb3565b506040805183815233602082015284916001600160a01b0380851692908816917f613a474dd5e07abe9f8b2812301e47553a146ee4ec93d03b8688173683c87e9a91015b60405180910390a4505060016002555050565b6110f8600886612bbf565b61116a5760405162461bcd60e51b815260206004820152602660248201527f47686f73744e46544d61726b6574203a20436f6c6c656374696f6e206e6f742060448201527f6c6973746564000000000000000000000000000000000000000000000000000060648201526084016109b1565b336001600160a01b0316856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111ad57600080fd5b505afa1580156111c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e59190613cb0565b6001600160a01b031614806111fe57506111fe336106b6565b61126f5760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b65743a204e6f7420636f6c6c656374696f6e206f60448201527f776e65720000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6112798285612be1565b6112866007548383612c72565b6040805160a0810190915280600181526001600160a01b038087166020808401919091528682166040808501919091526060840187905260809093018590529088166000908152600d909152208151815482907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600281111561130f5761130f6144ed565b021790555060208281015182547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b03928316021783556040808501516001850180547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905560608501516002850155608090940151600390930192909255825185815290810184905285821692878316928916917f655bd8b9d972737b566ec5473b537d81d079c6e251d4986005bf3f36000eacef91015b60405180910390a45050505050565b6113f16128b4565b6113fb6000612cfe565b565b611406336106b6565b6114785760405162461bcd60e51b815260206004820152603660248201527f41646d696e57686974656c69737461626c65203a2077686974656c697374206e60448201527f6f7420636f6e7461696e73206d73672e73656e6465720000000000000000000060648201526084016109b1565b611481846129f0565b61148a87612a76565b84600080808061149a8c8a612d66565b935093509350935060005b8581101561164f576114cf8d8d8d848181106114c3576114c361454b565b90506020020135612af2565b6115415760405162461bcd60e51b815260206004820152602560248201527f47686f73744e46544d61726b6574203a20746f6b656e4964206e6f7420656c6960448201527f6769626c6500000000000000000000000000000000000000000000000000000060648201526084016109b1565b8b8b828181106115535761155361454b565b90506020020135896001600160a01b03168e6001600160a01b03167f613a474dd5e07abe9f8b2812301e47553a146ee4ec93d03b8688173683c87e9a8d336040516115b19291909182526001600160a01b0316602082015260400190565b60405180910390a4886001600160a01b03168c8c838181106115d5576115d561454b565b905060200201358e6001600160a01b03167f1dd1aefafd84349621f251b5086ab453e2c3a575a76e96473bddc4acacdce8bd8a8e8a604051611635939291906001600160a01b039390931683526020830191909152604082015260600190565b60405180910390a48061164781614474565b9150506114a5565b506116638861165e8787614412565b612e22565b60045461167d906001600160a01b031661165e8786614412565b6001600160a01b03808d166000908152600d60205260409020546116ac916101009091041661165e8785614412565b6116ba8761165e8784614412565b505050505050505050505050565b6116d1336106b6565b6117435760405162461bcd60e51b815260206004820152603660248201527f41646d696e57686974656c69737461626c65203a2077686974656c697374206e60448201527f6f7420636f6e7461696e73206d73672e73656e6465720000000000000000000060648201526084016109b1565b61174c81612e63565b50565b6001600160a01b0383166000908152600c60205260408120606091829184908690611779906129da565b6117839190614431565b8111156117ba576001600160a01b0387166000908152600c6020526040902086906117ad906129da565b6117b79190614431565b90505b8067ffffffffffffffff8111156117d3576117d361457a565b6040519080825280602002602001820160405280156117fc578160200160208202803683370190505b5093508067ffffffffffffffff8111156118185761181861457a565b60405190808252806020026020018201604052801561186357816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816118365790505b50925060005b818110156119725761189c61187e82896143bf565b6001600160a01b038a166000908152600c60205260409020906129e4565b8582815181106118ae576118ae61454b565b602002602001018181525050600b6000896001600160a01b03166001600160a01b0316815260200190815260200160002060008683815181106118f3576118f361454b565b6020908102919091018101518252818101929092526040908101600020815160608101835281546001600160a01b0390811682526001830154948201949094526002909101549092169082015284518590839081106119545761195461454b565b6020026020010181905250808061196a90614474565b915050611869565b50838361197f83896143bf565b9350935093505093509350939050565b6002805414156119e15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b600280556119f0828233612f41565b336000908152600e602090815260408083206001600160a01b03861684529091529020611a1d9082612fe4565b506001600160a01b0382166000818152600b60209081526040808320858452825280832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825560018201859055600290910180549091169055928252600c905220611a8e9082612fe4565b506040517f23b872dd000000000000000000000000000000000000000000000000000000008152306004820152336024820152604481018290526001600160a01b038316906323b872dd90606401600060405180830381600087803b158015611af657600080fd5b505af1158015611b0a573d6000803e3d6000fd5b50506040518392503391506001600160a01b038516907fa5764ea233325154a6388255c54b9f302ec2ed8586af0a9a606cd64e88298eb790600090a450506001600255565b600080808060016001600160a01b0387166000908152600d602052604090205460ff166002811115611b8357611b836144ed565b14611b9957506000925082915081905080611bac565b611ba38686612d66565b93509350935093505b92959194509250565b600280541415611c075760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b60028055611c16333085612ff0565b611c238585858585612520565b50506001600255505050565b611c376128b4565b61174c8161300e565b611c486128b4565b600280541415611c9a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b600280556001600160a01b0382166000908152600c6020908152604080832084845260010190915290205415611d375760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b6574203a204e4654206e6f74207265636f76657260448201527f61626c650000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6040517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152336024820152604481018290526001600160a01b038316906342842e0e90606401600060405180830381600087803b158015611d9e57600080fd5b505af1158015611db2573d6000803e3d6000fd5b50506040518392506001600160a01b03851691507f861c3ea25dbda3af0bf5d258ba8582c0276c9446b1479e817be3f1b4a89acf9190600090a350506001600255565b611dfe336106b6565b611e705760405162461bcd60e51b815260206004820152603660248201527f41646d696e57686974656c69737461626c65203a2077686974656c697374206e60448201527f6f7420636f6e7461696e73206d73672e73656e6465720000000000000000000060648201526084016109b1565b611e7a82826130ec565b5050565b60608167ffffffffffffffff811115611e9957611e9961457a565b604051908082528060200260200182016040528015611ec2578160200160208202803683370190505b50905060016001600160a01b0385166000908152600d602052604090205460ff166002811115611ef457611ef46144ed565b14611efe57611f55565b60005b82811015611f5357611f1f858585848181106114c3576114c361454b565b828281518110611f3157611f3161454b565b9115156020928302919091019091015280611f4b81614474565b915050611f01565b505b9392505050565b6001600160a01b038084166000908152600e602090815260408083209388168352929052908120606091829184908690611f95906129da565b611f9f9190614431565b811115611fe3576001600160a01b038088166000908152600e60209081526040808320938c168352929052208690611fd6906129da565b611fe09190614431565b90505b8067ffffffffffffffff811115611ffc57611ffc61457a565b604051908082528060200260200182016040528015612025578160200160208202803683370190505b5093508067ffffffffffffffff8111156120415761204161457a565b60405190808252806020026020018201604052801561208c57816020015b604080516060810182526000808252602080830182905292820152825260001990920191018161205f5790505b50925060005b818110156121a8576120d26120a782896143bf565b6001600160a01b03808b166000908152600e60209081526040808320938f16835292905220906129e4565b8582815181106120e4576120e461454b565b602002602001018181525050600b60008a6001600160a01b03166001600160a01b0316815260200190815260200160002060008683815181106121295761212961454b565b6020908102919091018101518252818101929092526040908101600020815160608101835281546001600160a01b03908116825260018301549482019490945260029091015490921690820152845185908390811061218a5761218a61454b565b602002602001018190525080806121a090614474565b915050612092565b5083836121b583896143bf565b935093509350509450945094915050565b6121cf336106b6565b6122415760405162461bcd60e51b815260206004820152603660248201527f41646d696e57686974656c69737461626c65203a2077686974656c697374206e60448201527f6f7420636f6e7461696e73206d73672e73656e6465720000000000000000000060648201526084016109b1565b61224c600882612bbf565b6122be5760405162461bcd60e51b815260206004820152602560248201527f47686f73744e46544d61726b65743a20436f6c6c656374696f6e206e6f74206c60448201527f697374656400000000000000000000000000000000000000000000000000000060648201526084016109b1565b6001600160a01b0381166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600217905561230a60088261321e565b506040516001600160a01b038216907ff6df65a3d7d931af345d93f0420a22e8910de36c0d027c1d1ac93d5be509f5a990600090a250565b61234f8585858585613233565b5050505050565b61235e6128b4565b6001600160a01b0381166123da5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109b1565b61174c81612cfe565b6002805414156124355760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b60028055612442826129f0565b61244b84612a76565b612456848483612f41565b6001600160a01b038481166000818152600b60209081526040808320888452825291829020600101869055815186815233918101919091528693851692917f0bb9bfb2390e8a25f79f51b47fde7441b2a880dd87e24b4a6b0a4ab1a5f6d81291016110da565b600360009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561250c57600080fd5b505af115801561234f573d6000803e3d6000fd5b61252985612a76565b6001600160a01b0385166000908152600c6020908152604080832087845260010190915290205461259c5760405162461bcd60e51b815260206004820152601160248201527f4275793a204e6f7420666f722073616c6500000000000000000000000000000060448201526064016109b1565b6001600160a01b038086166000908152600b60209081526040808320888452825291829020825160608101845281548516815260018201549281018390526002909101549093169183019190915284146126385760405162461bcd60e51b815260206004820152601460248201527f4275793a20496e636f727265637420707269636500000000000000000000000060448201526064016109b1565b80516001600160a01b03163314156126925760405162461bcd60e51b815260206004820152601b60248201527f4275793a2042757965722063616e6e6f742062652073656c6c6572000000000060448201526064016109b1565b6000806000806126a28a89612d66565b935093509350935061270889600e600088600001516001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020612fe490919063ffffffff16565b506001600160a01b038a166000818152600b602090815260408083208d8452825280832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825560018201859055600290910180549091169055928252600c905220612779908a612fe4565b5084516127869085612e22565b60045461279c906001600160a01b031684612e22565b6001600160a01b03808b166000908152600d60205260409020546127c7916101009091041683612e22565b6127d18782612e22565b6040517f42842e0e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038781166024830152604482018b90528b16906342842e0e90606401600060405180830381600087803b15801561283a57600080fd5b505af115801561284e573d6000803e3d6000fd5b50508651604080516001600160a01b038b81168252602082018e905291810189905291811693508c92508d16907f1dd1aefafd84349621f251b5086ab453e2c3a575a76e96473bddc4acacdce8bd9060600160405180910390a450505050505050505050565b6000546001600160a01b031633146113fb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b1565b6040516001600160a01b0383166024820152604481018290526129d59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613682565b505050565b600061074d825490565b6000611f558383613767565b6005548110158015612a0457506006548111155b61174c5760405162461bcd60e51b815260206004820152602760248201527f47686f73744e46544d61726b6574203a205072696365206e6f7420776974686960448201527f6e2072616e67650000000000000000000000000000000000000000000000000060648201526084016109b1565b60016001600160a01b0382166000908152600d602052604090205460ff166002811115612aa557612aa56144ed565b1461174c5760405162461bcd60e51b815260206004820181905260248201527f47686f73744e46544d61726b6574203a204e6f7420666f72206c697374696e6760448201526064016109b1565b6001600160a01b038083166000908152600d6020526040812060010154909116801580612bab57506040517f5314a931000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b03821690635314a9319060240160206040518083038186803b158015612b7357600080fd5b505afa158015612b87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bab91906140ac565b949350505050565b6000611f558383613791565b6001600160a01b03811660009081526001830160205260408120541515611f55565b811580612c0057508115801590612c0057506001600160a01b03811615155b611e7a5760405162461bcd60e51b815260206004820152602c60248201527f47686f73744e46544d61726b65743a2043726561746f7220706172616d65746560448201527f727320696e636f7272656374000000000000000000000000000000000000000060648201526084016109b1565b61271081612c8084866143bf565b612c8a91906143bf565b11156129d55760405162461bcd60e51b815260206004820152603960248201527f47686f73744e46544d61726b65743a2053756d206f6620666565206d7573742060448201527f696e666572696f7220746f20544f54414c5f4d41585f4645450000000000000060648201526084016109b1565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060008061271060075486612d7d9190614412565b612d8791906143d7565b6001600160a01b0387166000908152600d602052604090206002015490935061271090612db49087614412565b612dbe91906143d7565b6001600160a01b0387166000908152600d602052604090206003015490925061271090612deb9087614412565b612df591906143d7565b90508082612e038588614431565b612e0d9190614431565b612e179190614431565b935092959194509250565b8015611e7a576040516001600160a01b038316906108fc9060009081818181818888f1935050505015612e5957611e7a82826137e0565b611e7a82826137f9565b6001600160a01b038116612edf5760405162461bcd60e51b815260206004820152602f60248201527f47686f73744e46544d61726b65743a205472656173757279206164647265737360448201527f2063616e6e6f74206265207a65726f000000000000000000000000000000000060648201526084016109b1565b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f1f54d231bb9d500b1923e4a1cb25e600f366a8368873d9af7c1c623814df19fc90600090a250565b6001600160a01b038181166000908152600e602090815260408083209387168352928152828220858352600101905220546129d55760405162461bcd60e51b815260206004820152602160248201527f47686f73744e46544d61726b6574203a20546f6b656e206e6f74206c6973746560448201527f640000000000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6000611f558383613816565b80156129d5576003546129d5906001600160a01b0316848484613909565b6001600160a01b03811661308a5760405162461bcd60e51b815260206004820152603460248201527f41646d696e57686974656c69737461626c653a2077686974656c69737420616460448201527f64726573732063616e6e6f74206265207a65726f00000000000000000000000060648201526084016109b1565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f3e50444736bab5048f0beae25d9cf0982f7f44ad3d00b72e6088a98d5b04060b90600090a250565b600082116131625760405162461bcd60e51b815260206004820152602160248201527f47686f73744e46544d61726b6574203a205f6d696e41736b5072696365203e2060448201527f300000000000000000000000000000000000000000000000000000000000000060648201526084016109b1565b8082106131d75760405162461bcd60e51b815260206004820152602c60248201527f47686f73744e46544d61726b6574203a205f6d696e41736b5072696365203c2060448201527f5f6d617841736b5072696365000000000000000000000000000000000000000060648201526084016109b1565b6005829055600681905560408051838152602081018390527fdb2a1e3f259454a99096a2a229d4af103f76dfa239ee204bcbb7159211c294ed910160405180910390a15050565b6000611f55836001600160a01b038416613816565b61323e600886612bbf565b156132b15760405162461bcd60e51b815260206004820152602960248201527f47686f73744e46544d61726b65743a20436f6c6c656374696f6e20616c72656160448201527f6479206c6973746564000000000000000000000000000000000000000000000060648201526084016109b1565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f80ac58cd0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038616906301ffc9a79060240160206040518083038186803b15801561332957600080fd5b505afa15801561333d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336191906140ac565b6133ad5760405162461bcd60e51b815260206004820152601a60248201527f47686f73744e46544d61726b65743a204e6f742045524337323100000000000060448201526064016109b1565b336001600160a01b0316856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133f057600080fd5b505afa158015613404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134289190613cb0565b6001600160a01b031614806134415750613441336106b6565b6134b25760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b65743a204e6f7420636f6c6c656374696f6e206f60448201527f776e65720000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6134bc8285612be1565b6134c96007548383612c72565b6134d4600886613960565b50600a805460018082019092557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038881169182179092556040805160a0810182528481528884166020808301919091529388168183015260608101879052608081018690526000928352600d90935290208151815492939192909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908360028111156135b3576135b36144ed565b021790555060208281015182547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b03928316021783556040808501516001850180547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905560608501516002850155608090940151600390930192909255825185815290810184905285821692878316928916917f4863c75720ebabd11e0cf1c60b58786b5572680a20fa1b568c203964ae56026a91016113da565b60006136d7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166139759092919063ffffffff16565b8051909150156129d557808060200190518101906136f591906140ac565b6129d55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016109b1565b600082600001828154811061377e5761377e61454b565b9060005260206000200154905092915050565b60008181526001830160205260408120546137d85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561074d565b50600061074d565b8015611e7a576137ef81613984565b611e7a82826139e3565b8015611e7a57600354611e7a906001600160a01b0316838361290e565b600081815260018301602052604081205480156138ff57600061383a600183614431565b855490915060009061384e90600190614431565b90508181146138b357600086600001828154811061386e5761386e61454b565b90600052602060002001549050808760000184815481106138915761389161454b565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806138c4576138c461451c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061074d565b600091505061074d565b6040516001600160a01b038085166024830152831660448201526064810182905261395a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612953565b50505050565b6000611f55836001600160a01b038416613791565b6060612bab8484600085613ac6565b6003546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b15801561250c57600080fd5b604080516000808252602082019092526001600160a01b038416908390604051613a0d91906141d1565b60006040518083038185875af1925050503d8060008114613a4a576040519150601f19603f3d011682016040523d82523d6000602084013e613a4f565b606091505b50509050806129d55760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201527f4c4544000000000000000000000000000000000000000000000000000000000060648201526084016109b1565b606082471015613b3e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016109b1565b6001600160a01b0385163b613b955760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109b1565b600080866001600160a01b03168587604051613bb191906141d1565b60006040518083038185875af1925050503d8060008114613bee576040519150601f19603f3d011682016040523d82523d6000602084013e613bf3565b606091505b5091509150613c03828286613c0e565b979650505050505050565b60608315613c1d575081611f55565b825115613c2d5782518084602001fd5b8160405162461bcd60e51b81526004016109b1919061436e565b60008083601f840112613c5957600080fd5b50813567ffffffffffffffff811115613c7157600080fd5b6020830191508360208260051b8501011115613c8c57600080fd5b9250929050565b600060208284031215613ca557600080fd5b8135611f55816145a9565b600060208284031215613cc257600080fd5b8151611f55816145a9565b600080600080600060a08688031215613ce557600080fd5b8535613cf0816145a9565b94506020860135613d00816145a9565b93506040860135613d10816145a9565b94979396509394606081013594506080013592915050565b60008060008060808587031215613d3e57600080fd5b8435613d49816145a9565b93506020850135613d59816145a9565b925060408501359150606085013567ffffffffffffffff80821115613d7d57600080fd5b818701915087601f830112613d9157600080fd5b813581811115613da357613da361457a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715613de957613de961457a565b816040528281528a6020848701011115613e0257600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060008060808587031215613e3c57600080fd5b8435613e47816145a9565b93506020850135613e57816145a9565b93969395505050506040820135916060013590565b600080600060408486031215613e8157600080fd5b8335613e8c816145a9565b9250602084013567ffffffffffffffff811115613ea857600080fd5b613eb486828701613c47565b9497909650939450505050565b600080600080600080600060c0888a031215613edc57600080fd5b8735613ee7816145a9565b9650602088013567ffffffffffffffff811115613f0357600080fd5b613f0f8a828b01613c47565b909750955050604088013593506060880135613f2a816145a9565b92506080880135613f3a816145a9565b915060a0880135613f4a816145a9565b8091505092959891949750929550565b60008060408385031215613f6d57600080fd5b8235613f78816145a9565b946020939093013593505050565b60008060008060808587031215613f9c57600080fd5b8435613fa7816145a9565b9350602085013592506040850135613fbe816145a9565b91506060850135613fce816145a9565b939692955090935050565b600080600060608486031215613fee57600080fd5b8335613ff9816145a9565b95602085013595506040909401359392505050565b6000806000806080858703121561402457600080fd5b843561402f816145a9565b935060208501359250604085013591506060850135613fce816145a9565b600080600080600060a0868803121561406557600080fd5b8535614070816145a9565b94506020860135935060408601359250606086013561408e816145a9565b9150608086013561409e816145a9565b809150509295509295909350565b6000602082840312156140be57600080fd5b81518015158114611f5557600080fd5b6000602082840312156140e057600080fd5b5051919050565b600080604083850312156140fa57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b838110156141425781516001600160a01b03168752958201959082019060010161411d565b509495945050505050565b600081518084526020808501945080840160005b83811015614142578151151587529582019590820190600101614161565b600081518084526020808501945080840160005b8381101561414257815180516001600160a01b03908116895284820151858a0152604091820151169088015260609096019590820190600101614193565b600082516141e3818460208701614448565b9190910192915050565b602081526000611f556020830184614109565b6000606080835261421381840187614109565b8381036020858101919091528651808352878201928201906000805b828110156142b6578551805160038110614270577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b8552808601516001600160a01b0390811687870152604080830151909116908601528781015188860152608090810151908501529484019460a09093019260010161422f565b50505080945050505050826040830152949350505050565b602081526000611f55602083018461414d565b6040815260006142f4604083018561414d565b8281036020840152614306818561417f565b95945050505050565b606080825284519082018190526000906020906080840190828801845b828110156143485781518452928401929084019060010161432c565b5050508381038285015261435c818761417f565b92505050826040830152949350505050565b602081526000825180602084015261438d816040850160208701614448565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600082198211156143d2576143d26144be565b500190565b60008261440d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600081600019048311821515161561442c5761442c6144be565b500290565b600082821015614443576144436144be565b500390565b60005b8381101561446357818101518382015260200161444b565b8381111561395a5750506000910152565b6000600019821415614488576144886144be565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6001600160a01b038116811461174c57600080fdfea26469706673582212204841b8bb4fa5df99e2fe0b09b768d733039d5e1556dd7067b1b39da6e22e788964736f6c634300080600330000000000000000000000004a6d8059ee4c154caf0005c9e83839721e2fb96f000000000000000000000000b51aa8db770c7b2de9c12c337d7ed8e203539ccc000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000021e19e0c9bab2400000
Deployed Bytecode
0x6080604052600436106101e75760003560e01c806384a4086411610102578063bf792dc111610095578063ddf9ba6f11610064578063ddf9ba6f14610636578063e17734a314610656578063f2fde38b14610676578063f59ee15c1461069657600080fd5b8063bf792dc1146105b3578063c5d4618e146105d3578063d286ef7414610600578063d9cc6c0c1461062057600080fd5b8063a5781792116100d1578063a578179214610533578063ad158e4214610553578063ad5c464814610573578063bb0fd1471461059357600080fd5b806384a40864146104865780638da5cb5b146104b557806395f42098146104d35780639e0140c8146104f357600080fd5b806351c383ea1161017a5780636df8cd13116101495780636df8cd131461041b578063715018a61461043157806372c25461146104465780637f51bb1f1461046657600080fd5b806351c383ea1461037457806357aa81af146103a357806361d027b3146103c35780636b248032146103fb57600080fd5b8063288c3d77116101b6578063288c3d771461030957806328f0b2571461031c5780633ffd17811461033257806346e635861461035257600080fd5b806309fd82121461020d578063150b7a0214610242578063209cbe7e146102b757806322f67b6d146102db57600080fd5b36610208576003546001600160a01b031633146102065761020661448f565b005b600080fd5b34801561021957600080fd5b5061022d610228366004613c93565b6106b6565b60405190151581526020015b60405180910390f35b34801561024e57600080fd5b5061028661025d366004613d28565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610239565b3480156102c357600080fd5b506102cd61271081565b604051908152602001610239565b3480156102e757600080fd5b506102fb6102f6366004613e6c565b610753565b6040516102399291906142e1565b610206610317366004613f86565b610963565b34801561032857600080fd5b506102cd60075481565b34801561033e57600080fd5b5061020661034d366004613c93565b6109de565b34801561035e57600080fd5b50610367610bcb565b60405161023991906141ed565b34801561038057600080fd5b5061039461038f3660046140e7565b610c2d565b60405161023993929190614200565b3480156103af57600080fd5b506102066103be36600461400e565b610e67565b3480156103cf57600080fd5b506004546103e3906001600160a01b031681565b6040516001600160a01b039091168152602001610239565b34801561040757600080fd5b50610206610416366004613ccd565b6110ed565b34801561042757600080fd5b506102cd60065481565b34801561043d57600080fd5b506102066113e9565b34801561045257600080fd5b50610206610461366004613ec1565b6113fd565b34801561047257600080fd5b50610206610481366004613c93565b6116c8565b34801561049257600080fd5b506104a66104a1366004613fd9565b61174f565b6040516102399392919061430f565b3480156104c157600080fd5b506000546001600160a01b03166103e3565b3480156104df57600080fd5b506102066104ee366004613f5a565b61198f565b3480156104ff57600080fd5b5061051361050e366004613f5a565b611b4f565b604080519485526020850193909352918301526060820152608001610239565b34801561053f57600080fd5b5061020661054e36600461404d565b611bb5565b34801561055f57600080fd5b5061020661056e366004613c93565b611c2f565b34801561057f57600080fd5b506003546103e3906001600160a01b031681565b34801561059f57600080fd5b506102066105ae366004613f5a565b611c40565b3480156105bf57600080fd5b506102066105ce3660046140e7565b611df5565b3480156105df57600080fd5b506105f36105ee366004613e6c565b611e7e565b60405161023991906142ce565b34801561060c57600080fd5b506104a661061b366004613e26565b611f5c565b34801561062c57600080fd5b506102cd60055481565b34801561064257600080fd5b50610206610651366004613c93565b6121c6565b34801561066257600080fd5b50610206610671366004613ccd565b612342565b34801561068257600080fd5b50610206610691366004613c93565b612356565b3480156106a257600080fd5b506102066106b136600461400e565b6123e3565b6001546040517f1e7be2100000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526000921690631e7be2109060240160206040518083038186803b15801561071557600080fd5b505afa158015610729573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074d91906140ac565b92915050565b606080828067ffffffffffffffff8111156107705761077061457a565b604051908082528060200260200182016040528015610799578160200160208202803683370190505b5092508067ffffffffffffffff8111156107b5576107b561457a565b60405190808252806020026020018201604052801561080057816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816107d35790505b50915060005b818110156109595761085d8686838181106108235761082361454b565b6001600160a01b038b166000908152600c602090815260409091209391020135905060009081526001919091016020526040902054151590565b1561088b5760018482815181106108765761087661454b565b911515602092830291909101909101526108b0565b600084828151811061089f5761089f61454b565b911515602092830291909101909101525b6001600160a01b0387166000908152600b60205260408120908787848181106108db576108db61454b565b60209081029290920135835250818101929092526040908101600020815160608101835281546001600160a01b03908116825260018301549482019490945260029091015490921690820152835184908390811061093b5761093b61454b565b6020026020010181905250808061095190614474565b915050610806565b5050935093915050565b6002805414156109ba5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600280556109c66124bc565b6109d38484348585612520565b505060016002555050565b6109e66128b4565b6003546001600160a01b0382811691161415610a695760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b6574203a2043616e6e6f74207265636f7665722060448201527f574554480000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a082319060240160206040518083038186803b158015610ac457600080fd5b505afa158015610ad8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afc91906140ce565b905080610b705760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b6574203a204e6f20746f6b656e20746f2072656360448201527f6f7665720000000000000000000000000000000000000000000000000000000060648201526084016109b1565b610b846001600160a01b038316338361290e565b816001600160a01b03167f14f11966a996e0629572e51064726d2057a80fbd34efc066682c06a71dbb6e9882604051610bbf91815260200190565b60405180910390a25050565b6060600a805480602002602001604051908101604052809291908181526020018280548015610c2357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610c05575b5050505050905090565b60608060008385610c3e60086129da565b610c489190614431565b811115610c675785610c5a60086129da565b610c649190614431565b90505b8067ffffffffffffffff811115610c8057610c8061457a565b604051908082528060200260200182016040528015610ca9578160200160208202803683370190505b5093508067ffffffffffffffff811115610cc557610cc561457a565b604051908082528060200260200182016040528015610d1e57816020015b6040805160a081018252600080825260208083018290529282018190526060820181905260808201528252600019909201910181610ce35790505b50925060005b81811015610e4c57610d41610d3982896143bf565b6008906129e4565b858281518110610d5357610d5361454b565b60200260200101906001600160a01b031690816001600160a01b031681525050600d6000868381518110610d8957610d8961454b565b6020908102919091018101516001600160a01b031682528101919091526040908101600020815160a081019092528054829060ff166002811115610dcf57610dcf6144ed565b6002811115610de057610de06144ed565b815281546001600160a01b03610100909104811660208301526001830154166040820152600282015460608201526003909101546080909101528451859083908110610e2e57610e2e61454b565b60200260200101819052508080610e4490614474565b915050610d24565b508383610e5983896143bf565b935093509350509250925092565b600280541415610eb95760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b60028055610ec6826129f0565b610ecf84612a76565b610ed98484612af2565b610f4b5760405162461bcd60e51b815260206004820152602560248201527f47686f73744e46544d61726b6574203a20746f6b656e4964206e6f7420656c6960448201527f6769626c6500000000000000000000000000000000000000000000000000000060648201526084016109b1565b6040517f42842e0e000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018490526001600160a01b038516906342842e0e90606401600060405180830381600087803b158015610fb257600080fd5b505af1158015610fc6573d6000803e3d6000fd5b5050506001600160a01b038083166000908152600e60209081526040808320938916835292905220610ff9915084612bb3565b50604080516060810182526001600160a01b0380841682526020808301868152338486019081528984166000818152600b85528781208b82528552878120965187549087167fffffffffffffffffffffffff000000000000000000000000000000000000000091821617885593516001880155915160029096018054969095169590921694909417909255908252600c9052206110969084612bb3565b506040805183815233602082015284916001600160a01b0380851692908816917f613a474dd5e07abe9f8b2812301e47553a146ee4ec93d03b8688173683c87e9a91015b60405180910390a4505060016002555050565b6110f8600886612bbf565b61116a5760405162461bcd60e51b815260206004820152602660248201527f47686f73744e46544d61726b6574203a20436f6c6c656374696f6e206e6f742060448201527f6c6973746564000000000000000000000000000000000000000000000000000060648201526084016109b1565b336001600160a01b0316856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156111ad57600080fd5b505afa1580156111c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e59190613cb0565b6001600160a01b031614806111fe57506111fe336106b6565b61126f5760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b65743a204e6f7420636f6c6c656374696f6e206f60448201527f776e65720000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6112798285612be1565b6112866007548383612c72565b6040805160a0810190915280600181526001600160a01b038087166020808401919091528682166040808501919091526060840187905260809093018590529088166000908152600d909152208151815482907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183600281111561130f5761130f6144ed565b021790555060208281015182547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b03928316021783556040808501516001850180547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905560608501516002850155608090940151600390930192909255825185815290810184905285821692878316928916917f655bd8b9d972737b566ec5473b537d81d079c6e251d4986005bf3f36000eacef91015b60405180910390a45050505050565b6113f16128b4565b6113fb6000612cfe565b565b611406336106b6565b6114785760405162461bcd60e51b815260206004820152603660248201527f41646d696e57686974656c69737461626c65203a2077686974656c697374206e60448201527f6f7420636f6e7461696e73206d73672e73656e6465720000000000000000000060648201526084016109b1565b611481846129f0565b61148a87612a76565b84600080808061149a8c8a612d66565b935093509350935060005b8581101561164f576114cf8d8d8d848181106114c3576114c361454b565b90506020020135612af2565b6115415760405162461bcd60e51b815260206004820152602560248201527f47686f73744e46544d61726b6574203a20746f6b656e4964206e6f7420656c6960448201527f6769626c6500000000000000000000000000000000000000000000000000000060648201526084016109b1565b8b8b828181106115535761155361454b565b90506020020135896001600160a01b03168e6001600160a01b03167f613a474dd5e07abe9f8b2812301e47553a146ee4ec93d03b8688173683c87e9a8d336040516115b19291909182526001600160a01b0316602082015260400190565b60405180910390a4886001600160a01b03168c8c838181106115d5576115d561454b565b905060200201358e6001600160a01b03167f1dd1aefafd84349621f251b5086ab453e2c3a575a76e96473bddc4acacdce8bd8a8e8a604051611635939291906001600160a01b039390931683526020830191909152604082015260600190565b60405180910390a48061164781614474565b9150506114a5565b506116638861165e8787614412565b612e22565b60045461167d906001600160a01b031661165e8786614412565b6001600160a01b03808d166000908152600d60205260409020546116ac916101009091041661165e8785614412565b6116ba8761165e8784614412565b505050505050505050505050565b6116d1336106b6565b6117435760405162461bcd60e51b815260206004820152603660248201527f41646d696e57686974656c69737461626c65203a2077686974656c697374206e60448201527f6f7420636f6e7461696e73206d73672e73656e6465720000000000000000000060648201526084016109b1565b61174c81612e63565b50565b6001600160a01b0383166000908152600c60205260408120606091829184908690611779906129da565b6117839190614431565b8111156117ba576001600160a01b0387166000908152600c6020526040902086906117ad906129da565b6117b79190614431565b90505b8067ffffffffffffffff8111156117d3576117d361457a565b6040519080825280602002602001820160405280156117fc578160200160208202803683370190505b5093508067ffffffffffffffff8111156118185761181861457a565b60405190808252806020026020018201604052801561186357816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816118365790505b50925060005b818110156119725761189c61187e82896143bf565b6001600160a01b038a166000908152600c60205260409020906129e4565b8582815181106118ae576118ae61454b565b602002602001018181525050600b6000896001600160a01b03166001600160a01b0316815260200190815260200160002060008683815181106118f3576118f361454b565b6020908102919091018101518252818101929092526040908101600020815160608101835281546001600160a01b0390811682526001830154948201949094526002909101549092169082015284518590839081106119545761195461454b565b6020026020010181905250808061196a90614474565b915050611869565b50838361197f83896143bf565b9350935093505093509350939050565b6002805414156119e15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b600280556119f0828233612f41565b336000908152600e602090815260408083206001600160a01b03861684529091529020611a1d9082612fe4565b506001600160a01b0382166000818152600b60209081526040808320858452825280832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825560018201859055600290910180549091169055928252600c905220611a8e9082612fe4565b506040517f23b872dd000000000000000000000000000000000000000000000000000000008152306004820152336024820152604481018290526001600160a01b038316906323b872dd90606401600060405180830381600087803b158015611af657600080fd5b505af1158015611b0a573d6000803e3d6000fd5b50506040518392503391506001600160a01b038516907fa5764ea233325154a6388255c54b9f302ec2ed8586af0a9a606cd64e88298eb790600090a450506001600255565b600080808060016001600160a01b0387166000908152600d602052604090205460ff166002811115611b8357611b836144ed565b14611b9957506000925082915081905080611bac565b611ba38686612d66565b93509350935093505b92959194509250565b600280541415611c075760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b60028055611c16333085612ff0565b611c238585858585612520565b50506001600255505050565b611c376128b4565b61174c8161300e565b611c486128b4565b600280541415611c9a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b600280556001600160a01b0382166000908152600c6020908152604080832084845260010190915290205415611d375760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b6574203a204e4654206e6f74207265636f76657260448201527f61626c650000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6040517f42842e0e000000000000000000000000000000000000000000000000000000008152306004820152336024820152604481018290526001600160a01b038316906342842e0e90606401600060405180830381600087803b158015611d9e57600080fd5b505af1158015611db2573d6000803e3d6000fd5b50506040518392506001600160a01b03851691507f861c3ea25dbda3af0bf5d258ba8582c0276c9446b1479e817be3f1b4a89acf9190600090a350506001600255565b611dfe336106b6565b611e705760405162461bcd60e51b815260206004820152603660248201527f41646d696e57686974656c69737461626c65203a2077686974656c697374206e60448201527f6f7420636f6e7461696e73206d73672e73656e6465720000000000000000000060648201526084016109b1565b611e7a82826130ec565b5050565b60608167ffffffffffffffff811115611e9957611e9961457a565b604051908082528060200260200182016040528015611ec2578160200160208202803683370190505b50905060016001600160a01b0385166000908152600d602052604090205460ff166002811115611ef457611ef46144ed565b14611efe57611f55565b60005b82811015611f5357611f1f858585848181106114c3576114c361454b565b828281518110611f3157611f3161454b565b9115156020928302919091019091015280611f4b81614474565b915050611f01565b505b9392505050565b6001600160a01b038084166000908152600e602090815260408083209388168352929052908120606091829184908690611f95906129da565b611f9f9190614431565b811115611fe3576001600160a01b038088166000908152600e60209081526040808320938c168352929052208690611fd6906129da565b611fe09190614431565b90505b8067ffffffffffffffff811115611ffc57611ffc61457a565b604051908082528060200260200182016040528015612025578160200160208202803683370190505b5093508067ffffffffffffffff8111156120415761204161457a565b60405190808252806020026020018201604052801561208c57816020015b604080516060810182526000808252602080830182905292820152825260001990920191018161205f5790505b50925060005b818110156121a8576120d26120a782896143bf565b6001600160a01b03808b166000908152600e60209081526040808320938f16835292905220906129e4565b8582815181106120e4576120e461454b565b602002602001018181525050600b60008a6001600160a01b03166001600160a01b0316815260200190815260200160002060008683815181106121295761212961454b565b6020908102919091018101518252818101929092526040908101600020815160608101835281546001600160a01b03908116825260018301549482019490945260029091015490921690820152845185908390811061218a5761218a61454b565b602002602001018190525080806121a090614474565b915050612092565b5083836121b583896143bf565b935093509350509450945094915050565b6121cf336106b6565b6122415760405162461bcd60e51b815260206004820152603660248201527f41646d696e57686974656c69737461626c65203a2077686974656c697374206e60448201527f6f7420636f6e7461696e73206d73672e73656e6465720000000000000000000060648201526084016109b1565b61224c600882612bbf565b6122be5760405162461bcd60e51b815260206004820152602560248201527f47686f73744e46544d61726b65743a20436f6c6c656374696f6e206e6f74206c60448201527f697374656400000000000000000000000000000000000000000000000000000060648201526084016109b1565b6001600160a01b0381166000908152600d6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600217905561230a60088261321e565b506040516001600160a01b038216907ff6df65a3d7d931af345d93f0420a22e8910de36c0d027c1d1ac93d5be509f5a990600090a250565b61234f8585858585613233565b5050505050565b61235e6128b4565b6001600160a01b0381166123da5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109b1565b61174c81612cfe565b6002805414156124355760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109b1565b60028055612442826129f0565b61244b84612a76565b612456848483612f41565b6001600160a01b038481166000818152600b60209081526040808320888452825291829020600101869055815186815233918101919091528693851692917f0bb9bfb2390e8a25f79f51b47fde7441b2a880dd87e24b4a6b0a4ab1a5f6d81291016110da565b600360009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561250c57600080fd5b505af115801561234f573d6000803e3d6000fd5b61252985612a76565b6001600160a01b0385166000908152600c6020908152604080832087845260010190915290205461259c5760405162461bcd60e51b815260206004820152601160248201527f4275793a204e6f7420666f722073616c6500000000000000000000000000000060448201526064016109b1565b6001600160a01b038086166000908152600b60209081526040808320888452825291829020825160608101845281548516815260018201549281018390526002909101549093169183019190915284146126385760405162461bcd60e51b815260206004820152601460248201527f4275793a20496e636f727265637420707269636500000000000000000000000060448201526064016109b1565b80516001600160a01b03163314156126925760405162461bcd60e51b815260206004820152601b60248201527f4275793a2042757965722063616e6e6f742062652073656c6c6572000000000060448201526064016109b1565b6000806000806126a28a89612d66565b935093509350935061270889600e600088600001516001600160a01b03166001600160a01b0316815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020612fe490919063ffffffff16565b506001600160a01b038a166000818152600b602090815260408083208d8452825280832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825560018201859055600290910180549091169055928252600c905220612779908a612fe4565b5084516127869085612e22565b60045461279c906001600160a01b031684612e22565b6001600160a01b03808b166000908152600d60205260409020546127c7916101009091041683612e22565b6127d18782612e22565b6040517f42842e0e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b038781166024830152604482018b90528b16906342842e0e90606401600060405180830381600087803b15801561283a57600080fd5b505af115801561284e573d6000803e3d6000fd5b50508651604080516001600160a01b038b81168252602082018e905291810189905291811693508c92508d16907f1dd1aefafd84349621f251b5086ab453e2c3a575a76e96473bddc4acacdce8bd9060600160405180910390a450505050505050505050565b6000546001600160a01b031633146113fb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109b1565b6040516001600160a01b0383166024820152604481018290526129d59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613682565b505050565b600061074d825490565b6000611f558383613767565b6005548110158015612a0457506006548111155b61174c5760405162461bcd60e51b815260206004820152602760248201527f47686f73744e46544d61726b6574203a205072696365206e6f7420776974686960448201527f6e2072616e67650000000000000000000000000000000000000000000000000060648201526084016109b1565b60016001600160a01b0382166000908152600d602052604090205460ff166002811115612aa557612aa56144ed565b1461174c5760405162461bcd60e51b815260206004820181905260248201527f47686f73744e46544d61726b6574203a204e6f7420666f72206c697374696e6760448201526064016109b1565b6001600160a01b038083166000908152600d6020526040812060010154909116801580612bab57506040517f5314a931000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b03821690635314a9319060240160206040518083038186803b158015612b7357600080fd5b505afa158015612b87573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bab91906140ac565b949350505050565b6000611f558383613791565b6001600160a01b03811660009081526001830160205260408120541515611f55565b811580612c0057508115801590612c0057506001600160a01b03811615155b611e7a5760405162461bcd60e51b815260206004820152602c60248201527f47686f73744e46544d61726b65743a2043726561746f7220706172616d65746560448201527f727320696e636f7272656374000000000000000000000000000000000000000060648201526084016109b1565b61271081612c8084866143bf565b612c8a91906143bf565b11156129d55760405162461bcd60e51b815260206004820152603960248201527f47686f73744e46544d61726b65743a2053756d206f6620666565206d7573742060448201527f696e666572696f7220746f20544f54414c5f4d41585f4645450000000000000060648201526084016109b1565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060008061271060075486612d7d9190614412565b612d8791906143d7565b6001600160a01b0387166000908152600d602052604090206002015490935061271090612db49087614412565b612dbe91906143d7565b6001600160a01b0387166000908152600d602052604090206003015490925061271090612deb9087614412565b612df591906143d7565b90508082612e038588614431565b612e0d9190614431565b612e179190614431565b935092959194509250565b8015611e7a576040516001600160a01b038316906108fc9060009081818181818888f1935050505015612e5957611e7a82826137e0565b611e7a82826137f9565b6001600160a01b038116612edf5760405162461bcd60e51b815260206004820152602f60248201527f47686f73744e46544d61726b65743a205472656173757279206164647265737360448201527f2063616e6e6f74206265207a65726f000000000000000000000000000000000060648201526084016109b1565b600480547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f1f54d231bb9d500b1923e4a1cb25e600f366a8368873d9af7c1c623814df19fc90600090a250565b6001600160a01b038181166000908152600e602090815260408083209387168352928152828220858352600101905220546129d55760405162461bcd60e51b815260206004820152602160248201527f47686f73744e46544d61726b6574203a20546f6b656e206e6f74206c6973746560448201527f640000000000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6000611f558383613816565b80156129d5576003546129d5906001600160a01b0316848484613909565b6001600160a01b03811661308a5760405162461bcd60e51b815260206004820152603460248201527f41646d696e57686974656c69737461626c653a2077686974656c69737420616460448201527f64726573732063616e6e6f74206265207a65726f00000000000000000000000060648201526084016109b1565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f3e50444736bab5048f0beae25d9cf0982f7f44ad3d00b72e6088a98d5b04060b90600090a250565b600082116131625760405162461bcd60e51b815260206004820152602160248201527f47686f73744e46544d61726b6574203a205f6d696e41736b5072696365203e2060448201527f300000000000000000000000000000000000000000000000000000000000000060648201526084016109b1565b8082106131d75760405162461bcd60e51b815260206004820152602c60248201527f47686f73744e46544d61726b6574203a205f6d696e41736b5072696365203c2060448201527f5f6d617841736b5072696365000000000000000000000000000000000000000060648201526084016109b1565b6005829055600681905560408051838152602081018390527fdb2a1e3f259454a99096a2a229d4af103f76dfa239ee204bcbb7159211c294ed910160405180910390a15050565b6000611f55836001600160a01b038416613816565b61323e600886612bbf565b156132b15760405162461bcd60e51b815260206004820152602960248201527f47686f73744e46544d61726b65743a20436f6c6c656374696f6e20616c72656160448201527f6479206c6973746564000000000000000000000000000000000000000000000060648201526084016109b1565b6040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527f80ac58cd0000000000000000000000000000000000000000000000000000000060048201526001600160a01b038616906301ffc9a79060240160206040518083038186803b15801561332957600080fd5b505afa15801561333d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336191906140ac565b6133ad5760405162461bcd60e51b815260206004820152601a60248201527f47686f73744e46544d61726b65743a204e6f742045524337323100000000000060448201526064016109b1565b336001600160a01b0316856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133f057600080fd5b505afa158015613404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134289190613cb0565b6001600160a01b031614806134415750613441336106b6565b6134b25760405162461bcd60e51b8152602060048201526024808201527f47686f73744e46544d61726b65743a204e6f7420636f6c6c656374696f6e206f60448201527f776e65720000000000000000000000000000000000000000000000000000000060648201526084016109b1565b6134bc8285612be1565b6134c96007548383612c72565b6134d4600886613960565b50600a805460018082019092557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038881169182179092556040805160a0810182528481528884166020808301919091529388168183015260608101879052608081018690526000928352600d90935290208151815492939192909183917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016908360028111156135b3576135b36144ed565b021790555060208281015182547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b03928316021783556040808501516001850180547fffffffffffffffffffffffff00000000000000000000000000000000000000001691841691909117905560608501516002850155608090940151600390930192909255825185815290810184905285821692878316928916917f4863c75720ebabd11e0cf1c60b58786b5572680a20fa1b568c203964ae56026a91016113da565b60006136d7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166139759092919063ffffffff16565b8051909150156129d557808060200190518101906136f591906140ac565b6129d55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016109b1565b600082600001828154811061377e5761377e61454b565b9060005260206000200154905092915050565b60008181526001830160205260408120546137d85750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561074d565b50600061074d565b8015611e7a576137ef81613984565b611e7a82826139e3565b8015611e7a57600354611e7a906001600160a01b0316838361290e565b600081815260018301602052604081205480156138ff57600061383a600183614431565b855490915060009061384e90600190614431565b90508181146138b357600086600001828154811061386e5761386e61454b565b90600052602060002001549050808760000184815481106138915761389161454b565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806138c4576138c461451c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061074d565b600091505061074d565b6040516001600160a01b038085166024830152831660448201526064810182905261395a9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612953565b50505050565b6000611f55836001600160a01b038416613791565b6060612bab8484600085613ac6565b6003546040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b15801561250c57600080fd5b604080516000808252602082019092526001600160a01b038416908390604051613a0d91906141d1565b60006040518083038185875af1925050503d8060008114613a4a576040519150601f19603f3d011682016040523d82523d6000602084013e613a4f565b606091505b50509050806129d55760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201527f4c4544000000000000000000000000000000000000000000000000000000000060648201526084016109b1565b606082471015613b3e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016109b1565b6001600160a01b0385163b613b955760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109b1565b600080866001600160a01b03168587604051613bb191906141d1565b60006040518083038185875af1925050503d8060008114613bee576040519150601f19603f3d011682016040523d82523d6000602084013e613bf3565b606091505b5091509150613c03828286613c0e565b979650505050505050565b60608315613c1d575081611f55565b825115613c2d5782518084602001fd5b8160405162461bcd60e51b81526004016109b1919061436e565b60008083601f840112613c5957600080fd5b50813567ffffffffffffffff811115613c7157600080fd5b6020830191508360208260051b8501011115613c8c57600080fd5b9250929050565b600060208284031215613ca557600080fd5b8135611f55816145a9565b600060208284031215613cc257600080fd5b8151611f55816145a9565b600080600080600060a08688031215613ce557600080fd5b8535613cf0816145a9565b94506020860135613d00816145a9565b93506040860135613d10816145a9565b94979396509394606081013594506080013592915050565b60008060008060808587031215613d3e57600080fd5b8435613d49816145a9565b93506020850135613d59816145a9565b925060408501359150606085013567ffffffffffffffff80821115613d7d57600080fd5b818701915087601f830112613d9157600080fd5b813581811115613da357613da361457a565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715613de957613de961457a565b816040528281528a6020848701011115613e0257600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060008060808587031215613e3c57600080fd5b8435613e47816145a9565b93506020850135613e57816145a9565b93969395505050506040820135916060013590565b600080600060408486031215613e8157600080fd5b8335613e8c816145a9565b9250602084013567ffffffffffffffff811115613ea857600080fd5b613eb486828701613c47565b9497909650939450505050565b600080600080600080600060c0888a031215613edc57600080fd5b8735613ee7816145a9565b9650602088013567ffffffffffffffff811115613f0357600080fd5b613f0f8a828b01613c47565b909750955050604088013593506060880135613f2a816145a9565b92506080880135613f3a816145a9565b915060a0880135613f4a816145a9565b8091505092959891949750929550565b60008060408385031215613f6d57600080fd5b8235613f78816145a9565b946020939093013593505050565b60008060008060808587031215613f9c57600080fd5b8435613fa7816145a9565b9350602085013592506040850135613fbe816145a9565b91506060850135613fce816145a9565b939692955090935050565b600080600060608486031215613fee57600080fd5b8335613ff9816145a9565b95602085013595506040909401359392505050565b6000806000806080858703121561402457600080fd5b843561402f816145a9565b935060208501359250604085013591506060850135613fce816145a9565b600080600080600060a0868803121561406557600080fd5b8535614070816145a9565b94506020860135935060408601359250606086013561408e816145a9565b9150608086013561409e816145a9565b809150509295509295909350565b6000602082840312156140be57600080fd5b81518015158114611f5557600080fd5b6000602082840312156140e057600080fd5b5051919050565b600080604083850312156140fa57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b838110156141425781516001600160a01b03168752958201959082019060010161411d565b509495945050505050565b600081518084526020808501945080840160005b83811015614142578151151587529582019590820190600101614161565b600081518084526020808501945080840160005b8381101561414257815180516001600160a01b03908116895284820151858a0152604091820151169088015260609096019590820190600101614193565b600082516141e3818460208701614448565b9190910192915050565b602081526000611f556020830184614109565b6000606080835261421381840187614109565b8381036020858101919091528651808352878201928201906000805b828110156142b6578551805160038110614270577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b8552808601516001600160a01b0390811687870152604080830151909116908601528781015188860152608090810151908501529484019460a09093019260010161422f565b50505080945050505050826040830152949350505050565b602081526000611f55602083018461414d565b6040815260006142f4604083018561414d565b8281036020840152614306818561417f565b95945050505050565b606080825284519082018190526000906020906080840190828801845b828110156143485781518452928401929084019060010161432c565b5050508381038285015261435c818761417f565b92505050826040830152949350505050565b602081526000825180602084015261438d816040850160208701614448565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600082198211156143d2576143d26144be565b500190565b60008261440d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600081600019048311821515161561442c5761442c6144be565b500290565b600082821015614443576144436144be565b500390565b60005b8381101561446357818101518382015260200161444b565b8381111561395a5750506000910152565b6000600019821415614488576144886144be565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6001600160a01b038116811461174c57600080fdfea26469706673582212204841b8bb4fa5df99e2fe0b09b768d733039d5e1556dd7067b1b39da6e22e788964736f6c63430008060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004a6d8059ee4c154caf0005c9e83839721e2fb96f000000000000000000000000b51aa8db770c7b2de9c12c337d7ed8e203539ccc000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000021e19e0c9bab2400000
-----Decoded View---------------
Arg [0] : _whitelist (address): 0x4A6D8059eE4c154caf0005C9e83839721e2Fb96f
Arg [1] : _treasury (address): 0xB51aa8dB770c7B2de9C12C337d7Ed8e203539CCc
Arg [2] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [3] : _minAskPrice (uint256): 5000000000000000
Arg [4] : _maxAskPrice (uint256): 10000000000000000000000
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000004a6d8059ee4c154caf0005c9e83839721e2fb96f
Arg [1] : 000000000000000000000000b51aa8db770c7b2de9c12c337d7ed8e203539ccc
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [3] : 0000000000000000000000000000000000000000000000000011c37937e08000
Arg [4] : 00000000000000000000000000000000000000000000021e19e0c9bab2400000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.