Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
Latest 25 from a total of 167 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Buy | 19969419 | 211 days ago | IN | 0.056 ETH | 0.00080459 | ||||
Buy | 19969410 | 211 days ago | IN | 0 ETH | 0.00591303 | ||||
Buy | 19969352 | 211 days ago | IN | 0.08 ETH | 0.00388759 | ||||
Buy | 19969301 | 211 days ago | IN | 0.056 ETH | 0.00606554 | ||||
Buy | 19969262 | 211 days ago | IN | 0 ETH | 0.00575488 | ||||
Buy | 19969161 | 211 days ago | IN | 0.08 ETH | 0.00408562 | ||||
Buy | 19967621 | 211 days ago | IN | 0 ETH | 0.00335321 | ||||
Buy | 19964857 | 211 days ago | IN | 0 ETH | 0.00263042 | ||||
Buy | 19962693 | 212 days ago | IN | 0.08 ETH | 0.00509524 | ||||
Buy | 19961986 | 212 days ago | IN | 0.056 ETH | 0.00685726 | ||||
Buy | 19961941 | 212 days ago | IN | 0.08 ETH | 0.0040248 | ||||
Buy | 19958038 | 212 days ago | IN | 0 ETH | 0.00160693 | ||||
Buy | 19956999 | 212 days ago | IN | 0.056 ETH | 0.00138327 | ||||
Buy | 19955294 | 213 days ago | IN | 0.056 ETH | 0.00275109 | ||||
Buy | 19952546 | 213 days ago | IN | 0.056 ETH | 0.00133438 | ||||
Buy | 19951781 | 213 days ago | IN | 0 ETH | 0.00121647 | ||||
Buy | 19950109 | 213 days ago | IN | 0 ETH | 0.00151728 | ||||
Buy | 19948878 | 214 days ago | IN | 0 ETH | 0.00176541 | ||||
Buy | 19948483 | 214 days ago | IN | 0.056 ETH | 0.00146448 | ||||
Buy | 19947747 | 214 days ago | IN | 0.056 ETH | 0.00200454 | ||||
Buy | 19947390 | 214 days ago | IN | 0.056 ETH | 0.0015804 | ||||
Buy | 19947383 | 214 days ago | IN | 0.056 ETH | 0.00159468 | ||||
Buy | 19947310 | 214 days ago | IN | 0 ETH | 0.00165252 | ||||
Buy | 19946453 | 214 days ago | IN | 0 ETH | 0.00158066 | ||||
Buy | 19942292 | 214 days ago | IN | 0.08 ETH | 0.00176887 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
20699145 | 109 days ago | 0.05544 ETH | ||||
20699145 | 109 days ago | 0.00056 ETH | ||||
20699145 | 109 days ago | 0.056 ETH | ||||
20185201 | 181 days ago | 0.05544 ETH | ||||
20185201 | 181 days ago | 0.00056 ETH | ||||
20185201 | 181 days ago | 0.056 ETH | ||||
20131877 | 188 days ago | 0.05544 ETH | ||||
20131877 | 188 days ago | 0.00056 ETH | ||||
20131877 | 188 days ago | 0.056 ETH | ||||
20119291 | 190 days ago | 0.05544 ETH | ||||
20119291 | 190 days ago | 0.00056 ETH | ||||
20119291 | 190 days ago | 0.056 ETH | ||||
19969352 | 211 days ago | 0.0792 ETH | ||||
19969352 | 211 days ago | 0.0008 ETH | ||||
19969301 | 211 days ago | 0.05544 ETH | ||||
19969301 | 211 days ago | 0.00056 ETH | ||||
19969161 | 211 days ago | 0.0792 ETH | ||||
19969161 | 211 days ago | 0.0008 ETH | ||||
19962693 | 212 days ago | 0.0792 ETH | ||||
19962693 | 212 days ago | 0.0008 ETH | ||||
19961986 | 212 days ago | 0.05544 ETH | ||||
19961986 | 212 days ago | 0.00056 ETH | ||||
19961941 | 212 days ago | 0.0792 ETH | ||||
19961941 | 212 days ago | 0.0008 ETH | ||||
19956999 | 212 days ago | 0.05544 ETH |
Loading...
Loading
Contract Name:
MercedesOnchainBuy
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 125 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import {IERC721, IERC165} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {AdminControlUpgradeable} from "../../manifold/libraries-solidity/access/AdminControlUpgradeable.sol"; import {IERC721CreatorCore} from "../../manifold/creator-core/core/IERC721CreatorCore.sol"; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; import "@openzeppelin/contracts/utils/Address.sol"; /** * @title Mercedes BuyNow Contract handles the token gating and fixed price purchase. Intended for use by Mercedes Sales only. Built and powered by Mojito Inc. */ contract MercedesOnchainBuy is Initializable, ReentrancyGuard, AdminControlUpgradeable { using SafeERC20 for IERC20; using ECDSA for bytes32; /// @notice The metadata for a Tokens to purchase /// @param maxCap Total supply for minting /// @param nftContractAddress NFT contract address for minting /// @param startDate Start Date for the Sale /// @param enDate End Date for the Sale /// @param walletLimit wallet limit for the sale /// @param minimumCryptoPrice the cryptoprice for the sale /// @param discountedNFT List of gated collection address /// @param discountedPrice List of gated collection prices /// @param paymentSettlement Settlement address and payment percentage provided in basis points /// @param isSaleActive Sale is active or not currently /// @param coinflowAddress CoinFlow Address for Purchase functionality struct PriceList { uint16 maxCap; address nftContractAddress; uint64 startDate; uint64 endDate; uint8 walletLimit; uint256 minimumCryptoPrice; address[] discountedNFT; uint256[] discountedPrice; settlementList paymentSettlement; bool isSaleActive; address coinflowAddress; } /// @notice The metadata for a given Order /// @param paymentSettlementAddress the settlement address for the listed tokens /// @param commissionAddress the commission address for settlement of commission fee /// @param platformSettlementAddress the platform address for settlement of platform fee /// @param commissionFeePercentage the commission fee given in basis points /// @param platformFeePercentage the platform fee given in basis points struct settlementList { address payable paymentSettlementAddress; address payable commissionAddress; address payable platformSettlementAddress; uint16 commissionFeePercentage; // in basis points uint16 platformFeePercentage; // in basis points } /// @notice The details to be provided to buy the token /// @param buyer the person who buys the nft /// @param paymentAmount the amount to be paid in the payment currency /// @param discountedNFT the gated nft collection need to be verified /// @param discountedTokenId the tokenId which was gated /// @param expiryTime the expiration time for the signature /// @param signature the signature data given by signer struct BuyList { address buyer; uint256 paymentAmount; address discountedNFT; uint16 discountedTokenId; uint64 expiryTime; bytes signature; } // listing the sale details PriceList public listings; // tokens used to be compared with maxCap uint16 public tokenUsed; // Validating Signature mapping(bytes => bool) private isSignatureUsed; // validating walletLimit mapping(address => mapping(address => uint256)) public walletAddressLimit; // validating Collection History mapping(address => mapping(uint256 => address)) public collectionHistory; //validating Collection Token IDs mapping(address => uint256[]) public collectionTokenId; // Interface ID constants bytes4 private constant ERC721_INTERFACE_ID = 0x80ac58cd; /// @notice Emitted when sale is created /// @param saleList contains the details of sale created /// @param CreatedOrUpdated the details provide whether sale is created or updated event saleCreated(PriceList saleList, string CreatedOrUpdated); /// @notice Emitted when sale is closed /// @param nftContractAddress sale for the collection address event saleClosed(address nftContractAddress); /// @notice Emitted when an Buy Event is completed /// @param tokenContract The NFT Contract address /// @param buyingDetails consist of buyer details /// @param paymentAmount total amount paid by buyer /// @param mintedNfts the token ids minted event BuyExecuted( address indexed tokenContract, BuyList buyingDetails, uint256 paymentAmount, uint256 mintedNfts ); /** * Initializer * /// @param list Sale related details */ function initialize(PriceList calldata list) public initializer { uint16 totalFeeBasisPoints = 0; totalFeeBasisPoints += (list.paymentSettlement.platformFeePercentage + list.paymentSettlement.commissionFeePercentage); // checks whether the total basis points shouldn't exceed the value 10000 require( totalFeeBasisPoints < 10000, "The total fee basis point should be less than 10000" ); // checks for the maxcap and walletLimit require(list.maxCap != 0, "should provide maxCap for minting"); require( list.walletLimit != 0, "should provide walletLimit for minting" ); // checks to provide only supported interface for nftContractAddress require( IERC165(list.nftContractAddress).supportsInterface( ERC721_INTERFACE_ID ), "should provide only supported contract interfaces ERC 721" ); require( list.endDate == 0 || list.startDate < list.endDate, "Cannot have startDate greater than or equal to endDate" ); // checks for paymentSettlementAddress require( list.paymentSettlement.paymentSettlementAddress != address(0), "should provide valid wallet address for settlement" ); listings = list; __Ownable_init(); emit saleCreated(list, "Created"); } /** * @notice Purchasing a Token with the listing details * @param list gives the listing details to buy the nfts */ function buy(BuyList memory list) external payable nonReentrant { // checks whether the sale is Active or not require(listings.isSaleActive, "Sale is not Active"); require( listings.startDate <= block.timestamp, "Sale has not yet started" ); require( listings.endDate == 0 || listings.endDate >= block.timestamp, "Sale has been Closed" ); // checks whether the admin or the buyer is calling the function require( isAdmin(msg.sender) || list.buyer == msg.sender || listings.coinflowAddress == msg.sender, "Only the buyer or admin or owner of this contract can call this function" ); require( !isSignatureUsed[list.signature], "Listing has already been purchased with this siganture" ); // get the address that signed the voucher address signer = getListingSigner(list); require(isAdmin(signer), "Signature invalid or signer is not an admin"); isSignatureUsed[list.signature] = true; if (list.discountedNFT != address(0)) { require( IERC721(list.discountedNFT).ownerOf(list.discountedTokenId) == list.buyer, "Invalid NFT Owner Address. Please check and try again" ); require( collectionHistory[list.discountedNFT][list.discountedTokenId] == address(0), "Token Claimed already" ); } // checks whether the wallet limit has been reached for the buyer require( walletAddressLimit[listings.nftContractAddress][list.buyer] < listings.walletLimit, "Wallet Limit Exceeded" ); uint256 minimumPrice; minimumPrice = getListingPrice(list.discountedNFT); // checks whether the buyer sends the exact amount of the price for the token to be bought require( msg.value == list.paymentAmount && list.paymentAmount >= minimumPrice, "Insufficient funds or invalid amount" ); // Transferring the NFT tokens to the buyer uint256 nftTokenId; (nftTokenId) = _tokenTransaction( listings.nftContractAddress, list.buyer, list.discountedNFT, list.discountedTokenId, minimumPrice ); // Transferring the payments as per the settlement details if (list.paymentAmount != 0) { paymentTransaction(list.paymentAmount); } walletAddressLimit[listings.nftContractAddress][list.buyer] = walletAddressLimit[listings.nftContractAddress][list.buyer] + 1; if (list.discountedNFT != address(0)) { collectionHistory[list.discountedNFT][list.discountedTokenId] = list .buyer; collectionTokenId[list.discountedNFT].push(list.discountedTokenId); } emit BuyExecuted( listings.nftContractAddress, list, minimumPrice, nftTokenId ); } /** * @notice payment settlement happens to all settlement address. * @param _totalAmount the totalAmount to be paid by the seller */ function paymentTransaction(uint256 _totalAmount) private { settlementList memory settlement = listings.paymentSettlement; uint256 totalCommission = 0; // transferring the platformFee amount to the platformSettlementAddress if ( settlement.platformSettlementAddress != address(0) && settlement.platformFeePercentage > 0 ) { _handlePayment( settlement.platformSettlementAddress, totalCommission += ((_totalAmount * settlement.platformFeePercentage) / 10000) ); } // transferring the commissionfee amount to the commissionAddress if ( settlement.commissionAddress != address(0) && settlement.commissionFeePercentage > 0 ) { totalCommission += ((_totalAmount * settlement.commissionFeePercentage) / 10000); _handlePayment( settlement.commissionAddress, ((_totalAmount * settlement.commissionFeePercentage) / 10000) ); } _totalAmount = _totalAmount - totalCommission; // Transfer the balance to the paymentSettlementAddress _handlePayment(settlement.paymentSettlementAddress, _totalAmount); } /// @notice The details to be provided to buy the token /// @param _tokenContract the address of the nft contract /// @param _buyer the address of the buyer /// @param _discountedNFT the gated nft collection address /// @param _discountedTokenId the gated nft token id /// @param _minimumPrice the price of the token to purchase function _tokenTransaction( address _tokenContract, address _buyer, address _discountedNFT, uint256 _discountedTokenId, uint256 _minimumPrice ) private returns (uint256 nftTokenId) { if (_minimumPrice == 0) { require( IERC721(_discountedNFT).ownerOf(_discountedTokenId) == _buyer, "Invalid NFT Owner Address. Please check and try again" ); // Burning the ERC721 TokenID IERC721(_discountedNFT).safeTransferFrom( _buyer, address(0xdEaD), _discountedTokenId ); } require(tokenUsed + 1 <= listings.maxCap, "max cap reached"); // Minting the ERC721 in a batch nftTokenId = IERC721CreatorCore(_tokenContract).mintExtension(_buyer); tokenUsed = tokenUsed + 1; return nftTokenId; } /// @notice Settle the Payment based on the given parameters /// @param _to Address to whom need to settle the payment /// @param _amount Amount to be transferred function _handlePayment(address payable _to, uint256 _amount) private { bool success; (success, ) = _to.call{value: _amount}(new bytes(0)); require(success, "unable to debit native balance please try again"); } /// @notice get the listings currency and price /// @param collectionAddress to get the details of sale function getListingPrice( address collectionAddress ) public view returns (uint256 minimumCryptoPrice) { if (collectionAddress == address(0)) { minimumCryptoPrice = listings.minimumCryptoPrice; } else { for (uint256 i; i < listings.discountedNFT.length; i++) { if (collectionAddress == listings.discountedNFT[i]) { minimumCryptoPrice = listings.discountedPrice[i]; break; } } } } /** * @notice Verifies the signature for a given buy listings, returning the address of the signer. * @param list A signed buy listing containing minting info */ function getListingSigner( BuyList memory list ) internal view returns (address) { require(list.expiryTime >= block.timestamp, "signature expired"); bytes32 digest = keccak256( abi.encodePacked( list.buyer, list.paymentAmount, list.discountedNFT, list.discountedTokenId, list.expiryTime, "PRICING TIER" ) ); return digest.toEthSignedMessageHash().recover(list.signature); } /// @notice get the walletLimit /// @param buyer addess of the buyer function getWalletLimit( address buyer ) external view returns (uint256 tokensRemaining, uint256 tokensBought) { tokensBought = walletAddressLimit[listings.nftContractAddress][buyer]; tokensRemaining = listings.walletLimit - walletAddressLimit[listings.nftContractAddress][buyer]; } /// @notice get the sold TokenId List /// @param collectionAddress addess of the collection function getSoldTokenId( address collectionAddress ) external view returns (uint256[] memory tokenIds) { tokenIds = collectionTokenId[collectionAddress]; } /// @notice get the listings of tokens /// @param buyer addess of the buyer function getTokenlist( address buyer ) external view returns ( address[] memory collectionAddresses, uint256[] memory tokenshold, uint256[] memory price ) { collectionAddresses = listings.discountedNFT; tokenshold = new uint256[](collectionAddresses.length); price = new uint256[](collectionAddresses.length); for (uint256 i; i < collectionAddresses.length; i++) { tokenshold[i] = IERC721(collectionAddresses[i]).balanceOf(buyer); price[i] = listings.discountedPrice[i]; } } /// @notice Withdraw the funds to owner function withdraw(address paymentCurrency) external onlyOwner { bool success; address payable to = payable(msg.sender); if (paymentCurrency == address(0)) { (success, ) = to.call{value: address(this).balance}(new bytes(0)); require(success, "withdraw to withdraw funds. Please try again"); } else if (paymentCurrency != address(0)) { // transferring ERC20 currency uint256 amount = IERC20(paymentCurrency).balanceOf(address(this)); IERC20(paymentCurrency).safeTransfer(to, amount); } } /// @notice cancel the sale of a listed token function cancelSale() external adminRequired { listings.isSaleActive = false; emit saleClosed(listings.nftContractAddress); } /// @notice update contract listings details /// @param list Sale related details function updateContractListings( PriceList calldata list ) external adminRequired { uint16 totalFeeBasisPoints = 0; totalFeeBasisPoints += (list.paymentSettlement.platformFeePercentage + list.paymentSettlement.commissionFeePercentage); require( totalFeeBasisPoints < 10000, "The total fee basis point should be less than 10000" ); require(list.maxCap != 0, "should provide maxCap for minting"); require( list.walletLimit != 0, "should provide walletLimit for minting" ); // checks to provide only supported interface for nftContractAddress require( IERC165(list.nftContractAddress).supportsInterface( ERC721_INTERFACE_ID ), "should provide only supported contract interfaces ERC 721" ); require( list.endDate == 0 || list.startDate < list.endDate, "Cannot have startDate greater than or equal to endDate" ); // checks for paymentSettlementAddress require( list.paymentSettlement.paymentSettlementAddress != address(0), "should provide valid wallet address for settlement" ); listings = list; emit saleCreated(list, "Updated"); } receive() external payable {} fallback() external payable {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @author: manifold.xyz import "./ICreatorCore.sol"; /** * @dev Core ERC721 creator interface */ interface IERC721CreatorCore is ICreatorCore { /** * @dev mint a token with no extension. Can only be called by an admin. * Returns tokenId minted */ function mintBase(address to) external returns (uint256); /** * @dev mint a token with no extension. Can only be called by an admin. * Returns tokenId minted */ function mintBase( address to, string calldata uri ) external returns (uint256); /** * @dev batch mint a token with no extension. Can only be called by an admin. * Returns tokenId minted */ function mintBaseBatch( address to, uint16 count ) external returns (uint256[] memory); /** * @dev batch mint a token with no extension. Can only be called by an admin. * Returns tokenId minted */ function mintBaseBatch( address to, string[] calldata uris ) external returns (uint256[] memory); /** * @dev mint a token. Can only be called by a registered extension. * Returns tokenId minted */ function mintExtension(address to) external returns (uint256); /** * @dev mint a token. Can only be called by a registered extension. * Returns tokenId minted */ function mintExtension( address to, string calldata uri ) external returns (uint256); /** * @dev mint a token. Can only be called by a registered extension. * Returns tokenId minted */ function mintExtension(address to, uint80 data) external returns (uint256); /** * @dev batch mint a token. Can only be called by a registered extension. * Returns tokenIds minted */ function mintExtensionBatch( address to, uint16 count ) external returns (uint256[] memory); /** * @dev batch mint a token. Can only be called by a registered extension. * Returns tokenId minted */ function mintExtensionBatch( address to, string[] calldata uris ) external returns (uint256[] memory); /** * @dev batch mint a token. Can only be called by a registered extension. * Returns tokenId minted */ function mintExtensionBatch( address to, uint80[] calldata data ) external returns (uint256[] memory); /** * @dev burn a token. Can only be called by token owner or approved address. * On burn, calls back to the registered extension's onBurn method */ function burn(uint256 tokenId) external; /** * @dev get token data */ function tokenData(uint256 tokenId) external view returns (uint80); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @author: manifold.xyz import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "./IAdminControl.sol"; abstract contract AdminControlUpgradeable is OwnableUpgradeable, IAdminControl, ERC165 { using EnumerableSet for EnumerableSet.AddressSet; // Track registered admins EnumerableSet.AddressSet private _admins; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IAdminControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Only allows approved admins to call the specified function */ modifier adminRequired() { require( owner() == msg.sender || _admins.contains(msg.sender), "AdminControl: Must be owner or admin" ); _; } /** * @dev See {IAdminControl-getAdmins}. */ function getAdmins() external view override returns (address[] memory admins) { admins = new address[](_admins.length()); for (uint256 i = 0; i < _admins.length(); i++) { admins[i] = _admins.at(i); } return admins; } /** * @dev See {IAdminControl-approveAdmin}. */ function approveAdmin(address admin) external override onlyOwner { if (!_admins.contains(admin)) { emit AdminApproved(admin, msg.sender); _admins.add(admin); } } /** * @dev See {IAdminControl-revokeAdmin}. */ function revokeAdmin(address admin) external override onlyOwner { if (_admins.contains(admin)) { emit AdminRevoked(admin, msg.sender); _admins.remove(admin); } } /** * @dev See {IAdminControl-isAdmin}. */ function isAdmin(address admin) public view override returns (bool) { return (owner() == admin || _admins.contains(admin)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/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; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.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)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ 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"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ 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"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation 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). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (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() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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 pragma solidity ^0.8.0; /// @author: manifold.xyz import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * @dev Interface for admin control */ interface IAdminControl is IERC165 { event AdminApproved(address indexed account, address indexed sender); event AdminRevoked(address indexed account, address indexed sender); /** * @dev gets address of all admins */ function getAdmins() external view returns (address[] memory); /** * @dev add an admin. Can only be called by contract owner. */ function approveAdmin(address admin) external; /** * @dev remove an admin. Can only be called by contract owner. */ function revokeAdmin(address admin) external; /** * @dev checks whether or not given address is an admin * Returns True if they are */ function isAdmin(address admin) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _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. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { 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); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. 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. * * ```solidity * 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) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // 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 in 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 pragma solidity ^0.8.0; /// @author: manifold.xyz import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; /** * @dev Core creator interface */ interface ICreatorCore is IERC165 { event ExtensionRegistered( address indexed extension, address indexed sender ); event ExtensionUnregistered( address indexed extension, address indexed sender ); event ExtensionBlacklisted( address indexed extension, address indexed sender ); event MintPermissionsUpdated( address indexed extension, address indexed permissions, address indexed sender ); event RoyaltiesUpdated( uint256 indexed tokenId, address payable[] receivers, uint256[] basisPoints ); event DefaultRoyaltiesUpdated( address payable[] receivers, uint256[] basisPoints ); event ApproveTransferUpdated(address extension); event ExtensionRoyaltiesUpdated( address indexed extension, address payable[] receivers, uint256[] basisPoints ); event ExtensionApproveTransferUpdated( address indexed extension, bool enabled ); event MetadataUpdate(uint256 _tokenId); event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); /** * @dev gets address of all extensions */ function getExtensions() external view returns (address[] memory); /** * @dev add an extension. Can only be called by contract owner or admin. * extension address must point to a contract implementing ICreatorExtension. * Returns True if newly added, False if already added. */ function registerExtension( address extension, string calldata baseURI ) external; /** * @dev add an extension. Can only be called by contract owner or admin. * extension address must point to a contract implementing ICreatorExtension. * Returns True if newly added, False if already added. */ function registerExtension( address extension, string calldata baseURI, bool baseURIIdentical ) external; /** * @dev add an extension. Can only be called by contract owner or admin. * Returns True if removed, False if already removed. */ function unregisterExtension(address extension) external; /** * @dev blacklist an extension. Can only be called by contract owner or admin. * This function will destroy all ability to reference the metadata of any tokens created * by the specified extension. It will also unregister the extension if needed. * Returns True if removed, False if already removed. */ // function blacklistExtension(address extension) external; /** * @dev set the baseTokenURI of an extension. Can only be called by extension. */ function setBaseTokenURIExtension(string calldata uri) external; /** * @dev set the baseTokenURI of an extension. Can only be called by extension. * For tokens with no uri configured, tokenURI will return "uri+tokenId" */ function setBaseTokenURIExtension( string calldata uri, bool identical ) external; /** * @dev set the common prefix of an extension. Can only be called by extension. * If configured, and a token has a uri set, tokenURI will return "prefixURI+tokenURI" * Useful if you want to use ipfs/arweave */ function setTokenURIPrefixExtension(string calldata prefix) external; /** * @dev set the tokenURI of a token extension. Can only be called by extension that minted token. */ function setTokenURIExtension( uint256 tokenId, string calldata uri ) external; /** * @dev set the tokenURI of a token extension for multiple tokens. Can only be called by extension that minted token. */ function setTokenURIExtension( uint256[] memory tokenId, string[] calldata uri ) external; /** * @dev set the baseTokenURI for tokens with no extension. Can only be called by owner/admin. * For tokens with no uri configured, tokenURI will return "uri+tokenId" */ function setBaseTokenURI(string calldata uri) external; /** * @dev set the common prefix for tokens with no extension. Can only be called by owner/admin. * If configured, and a token has a uri set, tokenURI will return "prefixURI+tokenURI" * Useful if you want to use ipfs/arweave */ function setTokenURIPrefix(string calldata prefix) external; /** * @dev set the tokenURI of a token with no extension. Can only be called by owner/admin. */ function setTokenURI(uint256 tokenId, string calldata uri) external; /** * @dev set the tokenURI of multiple tokens with no extension. Can only be called by owner/admin. */ function setTokenURI( uint256[] memory tokenIds, string[] calldata uris ) external; /** * @dev set a permissions contract for an extension. Used to control minting. */ // function setMintPermissions( // address extension, // address permissions // ) external; /** * @dev Configure so transfers of tokens created by the caller (must be extension) gets approval * from the extension before transferring */ function setApproveTransferExtension(bool enabled) external; /** * @dev get the extension of a given token */ function tokenExtension(uint256 tokenId) external view returns (address); /** * @dev Set default royalties */ function setRoyalties( address payable[] calldata receivers, uint256[] calldata basisPoints ) external; /** * @dev Set royalties of a token */ function setRoyalties( uint256 tokenId, address payable[] calldata receivers, uint256[] calldata basisPoints ) external; /** * @dev Set royalties of an extension */ // function setRoyaltiesExtension( // address extension, // address payable[] calldata receivers, // uint256[] calldata basisPoints // ) external; /** * @dev Get royalites of a token. Returns list of receivers and basisPoints */ function getRoyalties( uint256 tokenId ) external view returns (address payable[] memory, uint256[] memory); // Royalty support for various other standards function getFeeRecipients( uint256 tokenId ) external view returns (address payable[] memory); function getFeeBps(uint256 tokenId) external view returns (uint[] memory); function getFees( uint256 tokenId ) external view returns (address payable[] memory, uint256[] memory); function royaltyInfo( uint256 tokenId, uint256 value ) external view returns (address, uint256); /** * @dev Set the default approve transfer contract location. */ function setApproveTransfer(address extension) external; /** * @dev Get the default approve transfer contract location. */ function getApproveTransfer() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/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.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
{ "optimizer": { "enabled": true, "runs": 125 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenContract","type":"address"},{"components":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"internalType":"address","name":"discountedNFT","type":"address"},{"internalType":"uint16","name":"discountedTokenId","type":"uint16"},{"internalType":"uint64","name":"expiryTime","type":"uint64"},{"internalType":"bytes","name":"signature","type":"bytes"}],"indexed":false,"internalType":"struct MercedesOnchainBuy.BuyList","name":"buyingDetails","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintedNfts","type":"uint256"}],"name":"BuyExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","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":false,"internalType":"address","name":"nftContractAddress","type":"address"}],"name":"saleClosed","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"maxCap","type":"uint16"},{"internalType":"address","name":"nftContractAddress","type":"address"},{"internalType":"uint64","name":"startDate","type":"uint64"},{"internalType":"uint64","name":"endDate","type":"uint64"},{"internalType":"uint8","name":"walletLimit","type":"uint8"},{"internalType":"uint256","name":"minimumCryptoPrice","type":"uint256"},{"internalType":"address[]","name":"discountedNFT","type":"address[]"},{"internalType":"uint256[]","name":"discountedPrice","type":"uint256[]"},{"components":[{"internalType":"address payable","name":"paymentSettlementAddress","type":"address"},{"internalType":"address payable","name":"commissionAddress","type":"address"},{"internalType":"address payable","name":"platformSettlementAddress","type":"address"},{"internalType":"uint16","name":"commissionFeePercentage","type":"uint16"},{"internalType":"uint16","name":"platformFeePercentage","type":"uint16"}],"internalType":"struct MercedesOnchainBuy.settlementList","name":"paymentSettlement","type":"tuple"},{"internalType":"bool","name":"isSaleActive","type":"bool"},{"internalType":"address","name":"coinflowAddress","type":"address"}],"indexed":false,"internalType":"struct MercedesOnchainBuy.PriceList","name":"saleList","type":"tuple"},{"indexed":false,"internalType":"string","name":"CreatedOrUpdated","type":"string"}],"name":"saleCreated","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"approveAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"paymentAmount","type":"uint256"},{"internalType":"address","name":"discountedNFT","type":"address"},{"internalType":"uint16","name":"discountedTokenId","type":"uint16"},{"internalType":"uint64","name":"expiryTime","type":"uint64"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct MercedesOnchainBuy.BuyList","name":"list","type":"tuple"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"cancelSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"collectionHistory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"collectionTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAdmins","outputs":[{"internalType":"address[]","name":"admins","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"getListingPrice","outputs":[{"internalType":"uint256","name":"minimumCryptoPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collectionAddress","type":"address"}],"name":"getSoldTokenId","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"buyer","type":"address"}],"name":"getTokenlist","outputs":[{"internalType":"address[]","name":"collectionAddresses","type":"address[]"},{"internalType":"uint256[]","name":"tokenshold","type":"uint256[]"},{"internalType":"uint256[]","name":"price","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"buyer","type":"address"}],"name":"getWalletLimit","outputs":[{"internalType":"uint256","name":"tokensRemaining","type":"uint256"},{"internalType":"uint256","name":"tokensBought","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"maxCap","type":"uint16"},{"internalType":"address","name":"nftContractAddress","type":"address"},{"internalType":"uint64","name":"startDate","type":"uint64"},{"internalType":"uint64","name":"endDate","type":"uint64"},{"internalType":"uint8","name":"walletLimit","type":"uint8"},{"internalType":"uint256","name":"minimumCryptoPrice","type":"uint256"},{"internalType":"address[]","name":"discountedNFT","type":"address[]"},{"internalType":"uint256[]","name":"discountedPrice","type":"uint256[]"},{"components":[{"internalType":"address payable","name":"paymentSettlementAddress","type":"address"},{"internalType":"address payable","name":"commissionAddress","type":"address"},{"internalType":"address payable","name":"platformSettlementAddress","type":"address"},{"internalType":"uint16","name":"commissionFeePercentage","type":"uint16"},{"internalType":"uint16","name":"platformFeePercentage","type":"uint16"}],"internalType":"struct MercedesOnchainBuy.settlementList","name":"paymentSettlement","type":"tuple"},{"internalType":"bool","name":"isSaleActive","type":"bool"},{"internalType":"address","name":"coinflowAddress","type":"address"}],"internalType":"struct MercedesOnchainBuy.PriceList","name":"list","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"listings","outputs":[{"internalType":"uint16","name":"maxCap","type":"uint16"},{"internalType":"address","name":"nftContractAddress","type":"address"},{"internalType":"uint64","name":"startDate","type":"uint64"},{"internalType":"uint64","name":"endDate","type":"uint64"},{"internalType":"uint8","name":"walletLimit","type":"uint8"},{"internalType":"uint256","name":"minimumCryptoPrice","type":"uint256"},{"components":[{"internalType":"address payable","name":"paymentSettlementAddress","type":"address"},{"internalType":"address payable","name":"commissionAddress","type":"address"},{"internalType":"address payable","name":"platformSettlementAddress","type":"address"},{"internalType":"uint16","name":"commissionFeePercentage","type":"uint16"},{"internalType":"uint16","name":"platformFeePercentage","type":"uint16"}],"internalType":"struct MercedesOnchainBuy.settlementList","name":"paymentSettlement","type":"tuple"},{"internalType":"bool","name":"isSaleActive","type":"bool"},{"internalType":"address","name":"coinflowAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"revokeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenUsed","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"maxCap","type":"uint16"},{"internalType":"address","name":"nftContractAddress","type":"address"},{"internalType":"uint64","name":"startDate","type":"uint64"},{"internalType":"uint64","name":"endDate","type":"uint64"},{"internalType":"uint8","name":"walletLimit","type":"uint8"},{"internalType":"uint256","name":"minimumCryptoPrice","type":"uint256"},{"internalType":"address[]","name":"discountedNFT","type":"address[]"},{"internalType":"uint256[]","name":"discountedPrice","type":"uint256[]"},{"components":[{"internalType":"address payable","name":"paymentSettlementAddress","type":"address"},{"internalType":"address payable","name":"commissionAddress","type":"address"},{"internalType":"address payable","name":"platformSettlementAddress","type":"address"},{"internalType":"uint16","name":"commissionFeePercentage","type":"uint16"},{"internalType":"uint16","name":"platformFeePercentage","type":"uint16"}],"internalType":"struct MercedesOnchainBuy.settlementList","name":"paymentSettlement","type":"tuple"},{"internalType":"bool","name":"isSaleActive","type":"bool"},{"internalType":"address","name":"coinflowAddress","type":"address"}],"internalType":"struct MercedesOnchainBuy.PriceList","name":"list","type":"tuple"}],"name":"updateContractListings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"walletAddressLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"paymentCurrency","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b506001805561388d806100246000396000f3fe60806040526004361061012d5760003560e01c80636d73e669116100a5578063d47736801161006c578063d477368014610385578063e1f5b28b146103b4578063e7e10490146103f5578063e8a545f51461040a578063f2fde38b14610437578063f6c94deb1461045757005b80636d73e669146102e9578063715018a6146103095780638da5cb5b1461031e578063aad4763414610345578063be60c2031461036557005b806331ae450b116100f457806331ae450b146101de57806344acd6d014610200578063455856861461024657806351cff8d91461026657806352aeaba91461028657806360a78a81146102b457005b806301ffc9a7146101365780630704b0461461016b57806318c016131461018b57806324d7806c1461019e5780632d345670146101be57005b3661013457005b005b34801561014257600080fd5b506101566101513660046127a7565b610517565b60405190151581526020015b60405180910390f35b34801561017757600080fd5b506101346101863660046127d1565b61054e565b610134610199366004612931565b6107f6565b3480156101aa57600080fd5b506101566101b93660046129f1565b610ed3565b3480156101ca57600080fd5b506101346101d93660046129f1565b610f0c565b3480156101ea57600080fd5b506101f3610f69565b6040516101629190612a52565b34801561020c57600080fd5b5061023861021b366004612a65565b607360209081526000928352604080842090915290825290205481565b604051908152602001610162565b34801561025257600080fd5b506102386102613660046129f1565b611017565b34801561027257600080fd5b506101346102813660046129f1565b6110ae565b34801561029257600080fd5b506071546102a19061ffff1681565b60405161ffff9091168152602001610162565b3480156102c057600080fd5b506102d46102cf3660046129f1565b611237565b60408051928352602083019190915201610162565b3480156102f557600080fd5b506101346103043660046129f1565b611287565b34801561031557600080fd5b506101346112df565b34801561032a57600080fd5b506034546001600160a01b03165b6040516101629190612a9e565b34801561035157600080fd5b50610238610360366004612ab2565b6112f3565b34801561037157600080fd5b506101346103803660046127d1565b611324565b34801561039157600080fd5b506103a56103a03660046129f1565b611680565b60405161016293929190612b0e565b3480156103c057600080fd5b506103386103cf366004612ab2565b60746020908152600092835260408084209091529082529020546001600160a01b031681565b34801561040157600080fd5b5061013461186d565b34801561041657600080fd5b5061042a6104253660046129f1565b61190d565b6040516101629190612b51565b34801561044357600080fd5b506101346104523660046129f1565b611979565b34801561046357600080fd5b50606854606954606a546040805160a081018252606d546001600160a01b039081168252606e5481166020830152606f5480821693830193909352600160a01b830461ffff9081166060840152600160b01b938490048116608084015260705461050297918216966201000083048416966001600160401b039690930486169581169460ff600160401b90920482169490929182169161010090041689565b60405161016299989796959493929190612b64565b60006001600160e01b03198216632a9f3abf60e11b148061054857506301ffc9a760e01b6001600160e01b03198316145b92915050565b336105616034546001600160a01b031690565b6001600160a01b0316148061057c575061057c6066336119ef565b6105a15760405162461bcd60e51b815260040161059890612c17565b60405180910390fd5b60006105b561018083016101608401612c5b565b6105c76101a084016101808501612c5b565b6105d19190612c8e565b6105db9082612c8e565b90506127108161ffff16106106025760405162461bcd60e51b815260040161059890612ca9565b61060f6020830183612c5b565b61ffff166000036106325760405162461bcd60e51b815260040161059890612cfc565b61064260a0830160808401612d57565b60ff166000036106645760405162461bcd60e51b815260040161059890612d74565b61067460408301602084016129f1565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b0391909116906301ffc9a790602401602060405180830381865afa1580156106c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e59190612dc8565b6107015760405162461bcd60e51b815260040161059890612de5565b6107116080830160608401612e3e565b6001600160401b0316158061075557506107316080830160608401612e3e565b6001600160401b031661074a6060840160408501612e3e565b6001600160401b0316105b6107715760405162461bcd60e51b815260040161059890612e5b565b6000610785610120840161010085016129f1565b6001600160a01b0316036107ab5760405162461bcd60e51b815260040161059890612eb1565b8160686107b88282613173565b9050507f58fd1674a6da72519d238f5c1e48f31f9751c93939f1cc3bb1febf2a57c539da826040516107ea919061356b565b60405180910390a15050565b6107fe611a14565b60705460ff166108455760405162461bcd60e51b815260206004820152601260248201527153616c65206973206e6f742041637469766560701b6044820152606401610598565b60685442600160b01b9091046001600160401b031611156108a35760405162461bcd60e51b815260206004820152601860248201527714d85b19481a185cc81b9bdd081e595d081cdd185c9d195960421b6044820152606401610598565b6069546001600160401b031615806108c85750606954426001600160401b0390911610155b61090b5760405162461bcd60e51b815260206004820152601460248201527314d85b19481a185cc81899595b8810db1bdcd95960621b6044820152606401610598565b61091433610ed3565b80610928575080516001600160a01b031633145b80610942575060705461010090046001600160a01b031633145b6109c55760405162461bcd60e51b815260206004820152604860248201527f4f6e6c7920746865206275796572206f722061646d696e206f72206f776e657260448201527f206f66207468697320636f6e74726163742063616e2063616c6c207468697320606482015267333ab731ba34b7b760c11b608482015260a401610598565b60728160a001516040516109d991906135cb565b9081526040519081900360200190205460ff1615610a585760405162461bcd60e51b815260206004820152603660248201527f4c697374696e672068617320616c7265616479206265656e207075726368617360448201527565642077697468207468697320736967616e7475726560501b6064820152608401610598565b6000610a6382611a6d565b9050610a6e81610ed3565b610ace5760405162461bcd60e51b815260206004820152602b60248201527f5369676e617475726520696e76616c6964206f72207369676e6572206973206e60448201526a37ba1030b71030b236b4b760a91b6064820152608401610598565b600160728360a00151604051610ae491906135cb565b9081526040805191829003602001909120805492151560ff19909316929092179091558201516001600160a01b031615610c32578151604080840151606085015191516331a9108f60e11b815261ffff90921660048301526001600160a01b03928316921690636352211e90602401602060405180830381865afa158015610b70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9491906135e7565b6001600160a01b031614610bba5760405162461bcd60e51b815260040161059890613604565b6040808301516001600160a01b03908116600090815260746020908152838220606087015161ffff168352905291909120541615610c325760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20436c61696d656420616c726561647960581b6044820152606401610598565b6069546068546201000090046001600160a01b039081166000908152607360209081526040808320875190941683529290522054600160401b90910460ff1611610cb65760405162461bcd60e51b815260206004820152601560248201527415d85b1b195d08131a5b5a5d08115e18d959591959605a1b6044820152606401610598565b6000610cc58360400151611017565b9050826020015134148015610cde575080836020015110155b610d365760405162461bcd60e51b8152602060048201526024808201527f496e73756666696369656e742066756e6473206f7220696e76616c696420616d6044820152631bdd5b9d60e21b6064820152608401610598565b6000610d6d606860000160029054906101000a90046001600160a01b031685600001518660400151876060015161ffff1686611ba3565b90508360200151600014610d8857610d888460200151611dac565b6068546001600160a01b036201000090910481166000908152607360209081526040808320885190941683529290522054610dc4906001613659565b6068546001600160a01b0362010000909104811660009081526073602090815260408083208951851684529091529081902092909255908501511615610e74578351604080860180516001600160a01b0390811660009081526074602090815284822060608b01805161ffff908116855291835286842080546001600160a01b03191698861698909817909755935190921681526075825292832093518454600181018655948452922091169101555b606854604051620100009091046001600160a01b0316907fd80ab56539c3907247b558dc815d9e828561b44346c924fce82ea10a9ef9ca2a90610ebc90879086908690613698565b60405180910390a2505050610ed060018055565b50565b6000816001600160a01b0316610ef16034546001600160a01b031690565b6001600160a01b0316148061054857506105486066836119ef565b610f14611ef3565b610f1f6066826119ef565b15610ed05760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a3610f65606682611f4d565b5050565b6060610f756066611f62565b6001600160401b03811115610f8c57610f8c61280c565b604051908082528060200260200182016040528015610fb5578160200160208202803683370190505b50905060005b610fc56066611f62565b81101561101357610fd7606682611f6c565b828281518110610fe957610fe9613714565b6001600160a01b03909216602092830291909101909101528061100b8161372a565b915050610fbb565b5090565b60006001600160a01b03821661102f575050606a5490565b60005b606b548110156110a757606b80548290811061105057611050613714565b6000918252602090912001546001600160a01b039081169084160361109557606c80548290811061108357611083613714565b906000526020600020015491506110a7565b8061109f8161372a565b915050611032565b505b919050565b6110b6611ef3565b6000336001600160a01b03831661119c57604080516000815260208101918290526001600160a01b0383169147916110ed916135cb565b60006040518083038185875af1925050503d806000811461112a576040519150601f19603f3d011682016040523d82523d6000602084013e61112f565b606091505b505080925050816111975760405162461bcd60e51b815260206004820152602c60248201527f776974686472617720746f2077697468647261772066756e64732e20506c656160448201526b39b2903a393c9030b3b0b4b760a11b6064820152608401610598565b505050565b6001600160a01b03831615611197576040516370a0823160e01b81526000906001600160a01b038516906370a08231906111da903090600401612a9e565b602060405180830381865afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b9190613743565b90506112316001600160a01b0385168383611f78565b50505050565b6068546201000090046001600160a01b039081166000908152607360209081526040808320938516835292905290812054606954611280908290600160401b900460ff1661375c565b9150915091565b61128f611ef3565b61129a6066826119ef565b610ed05760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a3610f65606682611fca565b6112e7611ef3565b6112f16000611fdf565b565b6075602052816000526040600020818154811061130f57600080fd5b90600052602060002001600091509150505481565b600054610100900460ff16158080156113445750600054600160ff909116105b8061135e5750303b15801561135e575060005460ff166001145b6113c15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610598565b6000805460ff1916600117905580156113e4576000805461ff0019166101001790555b60006113f861018084016101608501612c5b565b61140a6101a085016101808601612c5b565b6114149190612c8e565b61141e9082612c8e565b90506127108161ffff16106114455760405162461bcd60e51b815260040161059890612ca9565b6114526020840184612c5b565b61ffff166000036114755760405162461bcd60e51b815260040161059890612cfc565b61148560a0840160808501612d57565b60ff166000036114a75760405162461bcd60e51b815260040161059890612d74565b6114b760408401602085016129f1565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b0391909116906301ffc9a790602401602060405180830381865afa158015611504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115289190612dc8565b6115445760405162461bcd60e51b815260040161059890612de5565b6115546080840160608501612e3e565b6001600160401b0316158061159857506115746080840160608501612e3e565b6001600160401b031661158d6060850160408601612e3e565b6001600160401b0316105b6115b45760405162461bcd60e51b815260040161059890612e5b565b60006115c8610120850161010086016129f1565b6001600160a01b0316036115ee5760405162461bcd60e51b815260040161059890612eb1565b8260686115fb8282613173565b905050611606612031565b7f58fd1674a6da72519d238f5c1e48f31f9751c93939f1cc3bb1febf2a57c539da83604051611635919061376f565b60405180910390a1508015610f65576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020016107ea565b606b805460408051602080840282018101909252828152606093849384938301828280156116d757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116116b9575b5050505050925082516001600160401b038111156116f7576116f761280c565b604051908082528060200260200182016040528015611720578160200160208202803683370190505b50915082516001600160401b0381111561173c5761173c61280c565b604051908082528060200260200182016040528015611765578160200160208202803683370190505b50905060005b83518110156118655783818151811061178657611786613714565b60200260200101516001600160a01b03166370a08231866040518263ffffffff1660e01b81526004016117b99190612a9e565b602060405180830381865afa1580156117d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117fa9190613743565b83828151811061180c5761180c613714565b6020908102919091010152606c80548290811061182b5761182b613714565b906000526020600020015482828151811061184857611848613714565b60209081029190910101528061185d8161372a565b91505061176b565b509193909250565b336118806034546001600160a01b031690565b6001600160a01b0316148061189b575061189b6066336119ef565b6118b75760405162461bcd60e51b815260040161059890612c17565b6070805460ff191690556068546040517fdbd5e84acb116bc193aaea2ba63b0c2999373e07b0c50a75c9c235e3b1a5251f9161190391620100009091046001600160a01b031690612a9e565b60405180910390a1565b6001600160a01b03811660009081526075602090815260409182902080548351818402810184019094528084526060939283018282801561196d57602002820191906000526020600020905b815481526020019060010190808311611959575b50505050509050919050565b611981611ef3565b6001600160a01b0381166119e65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610598565b610ed081611fdf565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b600260015403611a665760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610598565b6002600155565b60004282608001516001600160401b03161015611ac05760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b6044820152606401610598565b81516020808401516040808601516060808801516080890151935196821b6bffffffffffffffffffffffff199081169688019690965260348701949094521b909216605484015260f01b6001600160f01b031916606883015260c01b6001600160c01b031916606a8201526b282924a1a4a723902a24a2a960a11b6072820152600090607e01604051602081830303815290604052805190602001209050611a0d8360a00151611b9d837f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b90612060565b600081600003611cac576040516331a9108f60e11b8152600481018490526001600160a01b038087169190861690636352211e90602401602060405180830381865afa158015611bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1b91906135e7565b6001600160a01b031614611c415760405162461bcd60e51b815260040161059890613604565b604051632142170760e11b81526001600160a01b03868116600483015261dead6024830152604482018590528516906342842e0e90606401600060405180830381600087803b158015611c9357600080fd5b505af1158015611ca7573d6000803e3d6000fd5b505050505b60685460715461ffff91821691611cc591166001612c8e565b61ffff161115611d095760405162461bcd60e51b815260206004820152600f60248201526e1b585e0818d85c081c995858da1959608a1b6044820152606401610598565b604051630525194b60e31b81526001600160a01b03871690632928ca5890611d35908890600401612a9e565b6020604051808303816000875af1158015611d54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d789190613743565b607154909150611d8d9061ffff166001612c8e565b6071805461ffff191661ffff9290921691909117905595945050505050565b6040805160a081018252606d546001600160a01b039081168252606e5481166020830152606f5490811692820183905261ffff600160a01b820481166060840152600160b01b9091041660808201529060009015801590611e1557506000826080015161ffff16115b15611e5557611e558260400151612710846080015161ffff1686611e399190612f80565b611e4391906137ab565b611e4d9084613659565b925082612084565b60208201516001600160a01b031615801590611e7957506000826060015161ffff16115b15611ed957612710826060015161ffff1684611e959190612f80565b611e9f91906137ab565b611ea99082613659565b9050611ed98260200151612710846060015161ffff1686611eca9190612f80565b611ed491906137ab565b612084565b611ee3818461375c565b9250611197826000015184612084565b6034546001600160a01b031633146112f15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610598565b6000611a0d836001600160a01b03841661215b565b6000610548825490565b6000611a0d8383612255565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261119790849061227f565b6000611a0d836001600160a01b038416612354565b603480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166120585760405162461bcd60e51b8152600401610598906137cd565b6112f16123a3565b600080600061206f85856123d3565b9150915061207c81612418565b509392505050565b604080516000808252602082019092526001600160a01b0384169083906040516120ae91906135cb565b60006040518083038185875af1925050503d80600081146120eb576040519150601f19603f3d011682016040523d82523d6000602084013e6120f0565b606091505b505080915050806111975760405162461bcd60e51b815260206004820152602f60248201527f756e61626c6520746f206465626974206e61746976652062616c616e6365207060448201526e3632b0b9b2903a393c9030b3b0b4b760891b6064820152608401610598565b6000818152600183016020526040812054801561224457600061217f60018361375c565b85549091506000906121939060019061375c565b90508181146121f85760008660000182815481106121b3576121b3613714565b90600052602060002001549050808760000184815481106121d6576121d6613714565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061220957612209613818565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610548565b6000915050610548565b5092915050565b600082600001828154811061226c5761226c613714565b9060005260206000200154905092915050565b60006122d4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661255d9092919063ffffffff16565b90508051600014806122f55750808060200190518101906122f59190612dc8565b6111975760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610598565b600081815260018301602052604081205461239b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610548565b506000610548565b600054610100900460ff166123ca5760405162461bcd60e51b8152600401610598906137cd565b6112f133611fdf565b60008082516041036124095760208301516040840151606085015160001a6123fd87828585612574565b94509450505050612411565b506000905060025b9250929050565b600081600481111561242c5761242c61382e565b036124345750565b60018160048111156124485761244861382e565b036124905760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b6044820152606401610598565b60028160048111156124a4576124a461382e565b036124f15760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610598565b60038160048111156125055761250561382e565b03610ed05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610598565b606061256c848460008561262e565b949350505050565b6000806fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311156125a15750600090506003612625565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156125f5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661261e57600060019250925050612625565b9150600090505b94509492505050565b60608247101561268f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610598565b600080866001600160a01b031685876040516126ab91906135cb565b60006040518083038185875af1925050503d80600081146126e8576040519150601f19603f3d011682016040523d82523d6000602084013e6126ed565b606091505b50915091506126fe87838387612709565b979650505050505050565b60608315612778578251600003612771576001600160a01b0385163b6127715760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610598565b508161256c565b61256c838381511561278d5781518083602001fd5b8060405162461bcd60e51b81526004016105989190613844565b6000602082840312156127b957600080fd5b81356001600160e01b031981168114611a0d57600080fd5b6000602082840312156127e357600080fd5b81356001600160401b038111156127f957600080fd5b82016101e08185031215611a0d57600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156128445761284461280c565b60405290565b6001600160a01b0381168114610ed057600080fd5b80356110a98161284a565b61ffff81168114610ed057600080fd5b80356110a98161286a565b6001600160401b0381168114610ed057600080fd5b80356110a981612885565b600082601f8301126128b657600080fd5b81356001600160401b03808211156128d0576128d061280c565b604051601f8301601f19908116603f011681019082821181831017156128f8576128f861280c565b8160405283815286602085880101111561291157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561294357600080fd5b81356001600160401b038082111561295a57600080fd5b9083019060c0828603121561296e57600080fd5b612976612822565b82356129818161284a565b815260208381013590820152604083013561299b8161284a565b604082015260608301356129ae8161286a565b60608201526129bf6080840161289a565b608082015260a0830135828111156129d657600080fd5b6129e2878286016128a5565b60a08301525095945050505050565b600060208284031215612a0357600080fd5b8135611a0d8161284a565b600081518084526020808501945080840160005b83811015612a475781516001600160a01b031687529582019590820190600101612a22565b509495945050505050565b602081526000611a0d6020830184612a0e565b60008060408385031215612a7857600080fd5b8235612a838161284a565b91506020830135612a938161284a565b809150509250929050565b6001600160a01b0391909116815260200190565b60008060408385031215612ac557600080fd5b8235612ad08161284a565b946020939093013593505050565b600081518084526020808501945080840160005b83811015612a4757815187529582019590820190600101612af2565b606081526000612b216060830186612a0e565b8281036020840152612b338186612ade565b90508281036040840152612b478185612ade565b9695505050505050565b602081526000611a0d6020830184612ade565b60006101a08201905061ffff808c16835260018060a01b03808c1660208501526001600160401b03808c166040860152808b1660608601525060ff891660808501528760a08501528087511660c08501528060208801511660e08501528060408801511661010085015250806060870151166101208401528060808701511661014084015250612bf961016083018515159052565b6001600160a01b0383166101808301529a9950505050505050505050565b60208082526024908201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616040820152633236b4b760e11b606082015260800190565b600060208284031215612c6d57600080fd5b8135611a0d8161286a565b634e487b7160e01b600052601160045260246000fd5b61ffff81811683821601908082111561224e5761224e612c78565b60208082526033908201527f54686520746f74616c2066656520626173697320706f696e742073686f756c646040820152720206265206c657373207468616e20313030303606c1b606082015260800190565b60208082526021908201527f73686f756c642070726f76696465206d617843617020666f72206d696e74696e6040820152606760f81b606082015260800190565b60ff81168114610ed057600080fd5b80356110a981612d3d565b600060208284031215612d6957600080fd5b8135611a0d81612d3d565b60208082526026908201527f73686f756c642070726f766964652077616c6c65744c696d697420666f72206d604082015265696e74696e6760d01b606082015260800190565b8015158114610ed057600080fd5b600060208284031215612dda57600080fd5b8151611a0d81612dba565b60208082526039908201527f73686f756c642070726f76696465206f6e6c7920737570706f7274656420636f6040820152786e747261637420696e7465726661636573204552432037323160381b606082015260800190565b600060208284031215612e5057600080fd5b8135611a0d81612885565b60208082526036908201527f43616e6e6f742068617665207374617274446174652067726561746572207468604082015275616e206f7220657175616c20746f20656e644461746560501b606082015260800190565b60208082526032908201527f73686f756c642070726f766964652076616c69642077616c6c65742061646472604082015271195cdcc8199bdc881cd95d1d1b195b595b9d60721b606082015260800190565b600081356105488161286a565b600081356105488161284a565b6000813561054881612885565b6000813561054881612d3d565b6000808335601e19843603018112612f4e57600080fd5b8301803591506001600160401b03821115612f6857600080fd5b6020019150600581901b360382131561241157600080fd5b808202811582820484141761054857610548612c78565b81831015611197576000818152602081208481019084015b80821015612fc557828255600182019150612faf565b505050505050565b6001600160401b03831115612fe457612fe461280c565b600160401b831115612ff857612ff861280c565b8054838255613008848284612f97565b50818160005260208060002060005b8681101561303a57833561302a8161284a565b8282015592820192600101613017565b50505050505050565b6001600160401b0383111561305a5761305a61280c565b600160401b83111561306e5761306e61280c565b805483825561307e848284612f97565b50818160005260208060002060005b8681101561303a578335828201559282019260010161308d565b80546001600160a01b0319166001600160a01b0392909216919091179055565b81356130d28161284a565b6130dc81836130a7565b5060208201356130eb8161284a565b6130f881600184016130a7565b5060028101604083013561310b8161284a565b61311581836130a7565b5060608301356131248161286a565b815460808501356131348161286a565b63ffffffff60a01b199190911660a09290921b61ffff60a01b169190911760b09190911b61ffff60b01b161790555050565b6000813561054881612dba565b61319261317f83612f03565b825461ffff191661ffff91909116178255565b6131c96131a160208401612f10565b82805462010000600160b01b03191660109290921b62010000600160b01b0316919091179055565b6132046131d860408401612f1d565b82805467ffffffffffffffff60b01b191660b09290921b67ffffffffffffffff60b01b16919091179055565b6001810161323561321760608501612f1d565b825467ffffffffffffffff19166001600160401b0391909116178255565b61326261324460808501612f2a565b82805460ff60401b191660409290921b60ff60401b16919091179055565b5060a0820135600282015561327a60c0830183612f37565b613288818360038601612fcd565b505061329760e0830183612f37565b6132a5818360048601613043565b50506132b86101008301600583016130c7565b600881016132e06132cc6101a08501613166565b825490151560ff1660ff1991909116178255565b6111976132f06101c08501612f10565b828054610100600160a81b03191660089290921b610100600160a81b0316919091179055565b6000808335601e1984360301811261332d57600080fd5b83016020810192503590506001600160401b0381111561334c57600080fd5b8060051b360382131561241157600080fd5b8183526000602080850194508260005b85811015612a475781356133818161284a565b6001600160a01b03168752958201959082019060010161336e565b81835260006001600160fb1b038311156133b557600080fd5b8260051b80836020870137939093016020019392505050565b80356133d98161284a565b6001600160a01b0390811683526020820135906133f58261284a565b908116602084015260408201359061340c8261284a565b16604083015260608101356134208161286a565b61ffff908116606084015260808201359061343a8261286a565b808216608085015250505050565b80356110a981612dba565b60006101e061346d846134658561287a565b61ffff169052565b6134796020840161285f565b6001600160a01b031660208501526134936040840161289a565b6001600160401b031660408501526134ad6060840161289a565b6001600160401b031660608501526134c760808401612d4c565b60ff16608085015260a083810135908501526134e660c0840184613316565b8260c08701526134f9838701828461335e565b9250505061350a60e0840184613316565b85830360e087015261351d83828461339c565b925050506101006135328186018286016133ce565b506101a0613541818501613448565b1515908501526101c061355584820161285f565b6001600160a01b03169401939093525090919050565b60408152600061357e6040830184613453565b82810360208401526007815266155c19185d195960ca1b60208201526040810191505092915050565b60005b838110156135c25781810151838201526020016135aa565b50506000910152565b600082516135dd8184602087016135a7565b9190910192915050565b6000602082840312156135f957600080fd5b8151611a0d8161284a565b60208082526035908201527f496e76616c6964204e4654204f776e657220416464726573732e20506c656173604082015274329031b432b1b59030b732103a393c9030b3b0b4b760591b606082015260800190565b8082018082111561054857610548612c78565b600081518084526136848160208601602086016135a7565b601f01601f19169290920160200192915050565b60608152600060018060a01b03808651166060840152602086015160808401528060408701511660a08401525061ffff60608601511660c08301526001600160401b0360808601511660e083015260a085015160c061010084015261370161012084018261366c565b6020840195909552505060400152919050565b634e487b7160e01b600052603260045260246000fd5b60006001820161373c5761373c612c78565b5060010190565b60006020828403121561375557600080fd5b5051919050565b8181038181111561054857610548612c78565b6040815260006137826040830184613453565b8281036020840152600781526610dc99585d195960ca1b60208201526040810191505092915050565b6000826137c857634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b602081526000611a0d602083018461366c56fea2646970667358221220abd3b0853797cc1c8412c1b835fbe6d9544cd108ed13c435cf800d47ea4e440e64736f6c63430008110033
Deployed Bytecode
0x60806040526004361061012d5760003560e01c80636d73e669116100a5578063d47736801161006c578063d477368014610385578063e1f5b28b146103b4578063e7e10490146103f5578063e8a545f51461040a578063f2fde38b14610437578063f6c94deb1461045757005b80636d73e669146102e9578063715018a6146103095780638da5cb5b1461031e578063aad4763414610345578063be60c2031461036557005b806331ae450b116100f457806331ae450b146101de57806344acd6d014610200578063455856861461024657806351cff8d91461026657806352aeaba91461028657806360a78a81146102b457005b806301ffc9a7146101365780630704b0461461016b57806318c016131461018b57806324d7806c1461019e5780632d345670146101be57005b3661013457005b005b34801561014257600080fd5b506101566101513660046127a7565b610517565b60405190151581526020015b60405180910390f35b34801561017757600080fd5b506101346101863660046127d1565b61054e565b610134610199366004612931565b6107f6565b3480156101aa57600080fd5b506101566101b93660046129f1565b610ed3565b3480156101ca57600080fd5b506101346101d93660046129f1565b610f0c565b3480156101ea57600080fd5b506101f3610f69565b6040516101629190612a52565b34801561020c57600080fd5b5061023861021b366004612a65565b607360209081526000928352604080842090915290825290205481565b604051908152602001610162565b34801561025257600080fd5b506102386102613660046129f1565b611017565b34801561027257600080fd5b506101346102813660046129f1565b6110ae565b34801561029257600080fd5b506071546102a19061ffff1681565b60405161ffff9091168152602001610162565b3480156102c057600080fd5b506102d46102cf3660046129f1565b611237565b60408051928352602083019190915201610162565b3480156102f557600080fd5b506101346103043660046129f1565b611287565b34801561031557600080fd5b506101346112df565b34801561032a57600080fd5b506034546001600160a01b03165b6040516101629190612a9e565b34801561035157600080fd5b50610238610360366004612ab2565b6112f3565b34801561037157600080fd5b506101346103803660046127d1565b611324565b34801561039157600080fd5b506103a56103a03660046129f1565b611680565b60405161016293929190612b0e565b3480156103c057600080fd5b506103386103cf366004612ab2565b60746020908152600092835260408084209091529082529020546001600160a01b031681565b34801561040157600080fd5b5061013461186d565b34801561041657600080fd5b5061042a6104253660046129f1565b61190d565b6040516101629190612b51565b34801561044357600080fd5b506101346104523660046129f1565b611979565b34801561046357600080fd5b50606854606954606a546040805160a081018252606d546001600160a01b039081168252606e5481166020830152606f5480821693830193909352600160a01b830461ffff9081166060840152600160b01b938490048116608084015260705461050297918216966201000083048416966001600160401b039690930486169581169460ff600160401b90920482169490929182169161010090041689565b60405161016299989796959493929190612b64565b60006001600160e01b03198216632a9f3abf60e11b148061054857506301ffc9a760e01b6001600160e01b03198316145b92915050565b336105616034546001600160a01b031690565b6001600160a01b0316148061057c575061057c6066336119ef565b6105a15760405162461bcd60e51b815260040161059890612c17565b60405180910390fd5b60006105b561018083016101608401612c5b565b6105c76101a084016101808501612c5b565b6105d19190612c8e565b6105db9082612c8e565b90506127108161ffff16106106025760405162461bcd60e51b815260040161059890612ca9565b61060f6020830183612c5b565b61ffff166000036106325760405162461bcd60e51b815260040161059890612cfc565b61064260a0830160808401612d57565b60ff166000036106645760405162461bcd60e51b815260040161059890612d74565b61067460408301602084016129f1565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b0391909116906301ffc9a790602401602060405180830381865afa1580156106c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e59190612dc8565b6107015760405162461bcd60e51b815260040161059890612de5565b6107116080830160608401612e3e565b6001600160401b0316158061075557506107316080830160608401612e3e565b6001600160401b031661074a6060840160408501612e3e565b6001600160401b0316105b6107715760405162461bcd60e51b815260040161059890612e5b565b6000610785610120840161010085016129f1565b6001600160a01b0316036107ab5760405162461bcd60e51b815260040161059890612eb1565b8160686107b88282613173565b9050507f58fd1674a6da72519d238f5c1e48f31f9751c93939f1cc3bb1febf2a57c539da826040516107ea919061356b565b60405180910390a15050565b6107fe611a14565b60705460ff166108455760405162461bcd60e51b815260206004820152601260248201527153616c65206973206e6f742041637469766560701b6044820152606401610598565b60685442600160b01b9091046001600160401b031611156108a35760405162461bcd60e51b815260206004820152601860248201527714d85b19481a185cc81b9bdd081e595d081cdd185c9d195960421b6044820152606401610598565b6069546001600160401b031615806108c85750606954426001600160401b0390911610155b61090b5760405162461bcd60e51b815260206004820152601460248201527314d85b19481a185cc81899595b8810db1bdcd95960621b6044820152606401610598565b61091433610ed3565b80610928575080516001600160a01b031633145b80610942575060705461010090046001600160a01b031633145b6109c55760405162461bcd60e51b815260206004820152604860248201527f4f6e6c7920746865206275796572206f722061646d696e206f72206f776e657260448201527f206f66207468697320636f6e74726163742063616e2063616c6c207468697320606482015267333ab731ba34b7b760c11b608482015260a401610598565b60728160a001516040516109d991906135cb565b9081526040519081900360200190205460ff1615610a585760405162461bcd60e51b815260206004820152603660248201527f4c697374696e672068617320616c7265616479206265656e207075726368617360448201527565642077697468207468697320736967616e7475726560501b6064820152608401610598565b6000610a6382611a6d565b9050610a6e81610ed3565b610ace5760405162461bcd60e51b815260206004820152602b60248201527f5369676e617475726520696e76616c6964206f72207369676e6572206973206e60448201526a37ba1030b71030b236b4b760a91b6064820152608401610598565b600160728360a00151604051610ae491906135cb565b9081526040805191829003602001909120805492151560ff19909316929092179091558201516001600160a01b031615610c32578151604080840151606085015191516331a9108f60e11b815261ffff90921660048301526001600160a01b03928316921690636352211e90602401602060405180830381865afa158015610b70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9491906135e7565b6001600160a01b031614610bba5760405162461bcd60e51b815260040161059890613604565b6040808301516001600160a01b03908116600090815260746020908152838220606087015161ffff168352905291909120541615610c325760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20436c61696d656420616c726561647960581b6044820152606401610598565b6069546068546201000090046001600160a01b039081166000908152607360209081526040808320875190941683529290522054600160401b90910460ff1611610cb65760405162461bcd60e51b815260206004820152601560248201527415d85b1b195d08131a5b5a5d08115e18d959591959605a1b6044820152606401610598565b6000610cc58360400151611017565b9050826020015134148015610cde575080836020015110155b610d365760405162461bcd60e51b8152602060048201526024808201527f496e73756666696369656e742066756e6473206f7220696e76616c696420616d6044820152631bdd5b9d60e21b6064820152608401610598565b6000610d6d606860000160029054906101000a90046001600160a01b031685600001518660400151876060015161ffff1686611ba3565b90508360200151600014610d8857610d888460200151611dac565b6068546001600160a01b036201000090910481166000908152607360209081526040808320885190941683529290522054610dc4906001613659565b6068546001600160a01b0362010000909104811660009081526073602090815260408083208951851684529091529081902092909255908501511615610e74578351604080860180516001600160a01b0390811660009081526074602090815284822060608b01805161ffff908116855291835286842080546001600160a01b03191698861698909817909755935190921681526075825292832093518454600181018655948452922091169101555b606854604051620100009091046001600160a01b0316907fd80ab56539c3907247b558dc815d9e828561b44346c924fce82ea10a9ef9ca2a90610ebc90879086908690613698565b60405180910390a2505050610ed060018055565b50565b6000816001600160a01b0316610ef16034546001600160a01b031690565b6001600160a01b0316148061054857506105486066836119ef565b610f14611ef3565b610f1f6066826119ef565b15610ed05760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a3610f65606682611f4d565b5050565b6060610f756066611f62565b6001600160401b03811115610f8c57610f8c61280c565b604051908082528060200260200182016040528015610fb5578160200160208202803683370190505b50905060005b610fc56066611f62565b81101561101357610fd7606682611f6c565b828281518110610fe957610fe9613714565b6001600160a01b03909216602092830291909101909101528061100b8161372a565b915050610fbb565b5090565b60006001600160a01b03821661102f575050606a5490565b60005b606b548110156110a757606b80548290811061105057611050613714565b6000918252602090912001546001600160a01b039081169084160361109557606c80548290811061108357611083613714565b906000526020600020015491506110a7565b8061109f8161372a565b915050611032565b505b919050565b6110b6611ef3565b6000336001600160a01b03831661119c57604080516000815260208101918290526001600160a01b0383169147916110ed916135cb565b60006040518083038185875af1925050503d806000811461112a576040519150601f19603f3d011682016040523d82523d6000602084013e61112f565b606091505b505080925050816111975760405162461bcd60e51b815260206004820152602c60248201527f776974686472617720746f2077697468647261772066756e64732e20506c656160448201526b39b2903a393c9030b3b0b4b760a11b6064820152608401610598565b505050565b6001600160a01b03831615611197576040516370a0823160e01b81526000906001600160a01b038516906370a08231906111da903090600401612a9e565b602060405180830381865afa1580156111f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121b9190613743565b90506112316001600160a01b0385168383611f78565b50505050565b6068546201000090046001600160a01b039081166000908152607360209081526040808320938516835292905290812054606954611280908290600160401b900460ff1661375c565b9150915091565b61128f611ef3565b61129a6066826119ef565b610ed05760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a3610f65606682611fca565b6112e7611ef3565b6112f16000611fdf565b565b6075602052816000526040600020818154811061130f57600080fd5b90600052602060002001600091509150505481565b600054610100900460ff16158080156113445750600054600160ff909116105b8061135e5750303b15801561135e575060005460ff166001145b6113c15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610598565b6000805460ff1916600117905580156113e4576000805461ff0019166101001790555b60006113f861018084016101608501612c5b565b61140a6101a085016101808601612c5b565b6114149190612c8e565b61141e9082612c8e565b90506127108161ffff16106114455760405162461bcd60e51b815260040161059890612ca9565b6114526020840184612c5b565b61ffff166000036114755760405162461bcd60e51b815260040161059890612cfc565b61148560a0840160808501612d57565b60ff166000036114a75760405162461bcd60e51b815260040161059890612d74565b6114b760408401602085016129f1565b6040516301ffc9a760e01b81526380ac58cd60e01b60048201526001600160a01b0391909116906301ffc9a790602401602060405180830381865afa158015611504573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115289190612dc8565b6115445760405162461bcd60e51b815260040161059890612de5565b6115546080840160608501612e3e565b6001600160401b0316158061159857506115746080840160608501612e3e565b6001600160401b031661158d6060850160408601612e3e565b6001600160401b0316105b6115b45760405162461bcd60e51b815260040161059890612e5b565b60006115c8610120850161010086016129f1565b6001600160a01b0316036115ee5760405162461bcd60e51b815260040161059890612eb1565b8260686115fb8282613173565b905050611606612031565b7f58fd1674a6da72519d238f5c1e48f31f9751c93939f1cc3bb1febf2a57c539da83604051611635919061376f565b60405180910390a1508015610f65576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020016107ea565b606b805460408051602080840282018101909252828152606093849384938301828280156116d757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116116b9575b5050505050925082516001600160401b038111156116f7576116f761280c565b604051908082528060200260200182016040528015611720578160200160208202803683370190505b50915082516001600160401b0381111561173c5761173c61280c565b604051908082528060200260200182016040528015611765578160200160208202803683370190505b50905060005b83518110156118655783818151811061178657611786613714565b60200260200101516001600160a01b03166370a08231866040518263ffffffff1660e01b81526004016117b99190612a9e565b602060405180830381865afa1580156117d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117fa9190613743565b83828151811061180c5761180c613714565b6020908102919091010152606c80548290811061182b5761182b613714565b906000526020600020015482828151811061184857611848613714565b60209081029190910101528061185d8161372a565b91505061176b565b509193909250565b336118806034546001600160a01b031690565b6001600160a01b0316148061189b575061189b6066336119ef565b6118b75760405162461bcd60e51b815260040161059890612c17565b6070805460ff191690556068546040517fdbd5e84acb116bc193aaea2ba63b0c2999373e07b0c50a75c9c235e3b1a5251f9161190391620100009091046001600160a01b031690612a9e565b60405180910390a1565b6001600160a01b03811660009081526075602090815260409182902080548351818402810184019094528084526060939283018282801561196d57602002820191906000526020600020905b815481526020019060010190808311611959575b50505050509050919050565b611981611ef3565b6001600160a01b0381166119e65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610598565b610ed081611fdf565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b600260015403611a665760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610598565b6002600155565b60004282608001516001600160401b03161015611ac05760405162461bcd60e51b81526020600482015260116024820152701cda59db985d1d5c9948195e1c1a5c9959607a1b6044820152606401610598565b81516020808401516040808601516060808801516080890151935196821b6bffffffffffffffffffffffff199081169688019690965260348701949094521b909216605484015260f01b6001600160f01b031916606883015260c01b6001600160c01b031916606a8201526b282924a1a4a723902a24a2a960a11b6072820152600090607e01604051602081830303815290604052805190602001209050611a0d8360a00151611b9d837f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b90612060565b600081600003611cac576040516331a9108f60e11b8152600481018490526001600160a01b038087169190861690636352211e90602401602060405180830381865afa158015611bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1b91906135e7565b6001600160a01b031614611c415760405162461bcd60e51b815260040161059890613604565b604051632142170760e11b81526001600160a01b03868116600483015261dead6024830152604482018590528516906342842e0e90606401600060405180830381600087803b158015611c9357600080fd5b505af1158015611ca7573d6000803e3d6000fd5b505050505b60685460715461ffff91821691611cc591166001612c8e565b61ffff161115611d095760405162461bcd60e51b815260206004820152600f60248201526e1b585e0818d85c081c995858da1959608a1b6044820152606401610598565b604051630525194b60e31b81526001600160a01b03871690632928ca5890611d35908890600401612a9e565b6020604051808303816000875af1158015611d54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d789190613743565b607154909150611d8d9061ffff166001612c8e565b6071805461ffff191661ffff9290921691909117905595945050505050565b6040805160a081018252606d546001600160a01b039081168252606e5481166020830152606f5490811692820183905261ffff600160a01b820481166060840152600160b01b9091041660808201529060009015801590611e1557506000826080015161ffff16115b15611e5557611e558260400151612710846080015161ffff1686611e399190612f80565b611e4391906137ab565b611e4d9084613659565b925082612084565b60208201516001600160a01b031615801590611e7957506000826060015161ffff16115b15611ed957612710826060015161ffff1684611e959190612f80565b611e9f91906137ab565b611ea99082613659565b9050611ed98260200151612710846060015161ffff1686611eca9190612f80565b611ed491906137ab565b612084565b611ee3818461375c565b9250611197826000015184612084565b6034546001600160a01b031633146112f15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610598565b6000611a0d836001600160a01b03841661215b565b6000610548825490565b6000611a0d8383612255565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261119790849061227f565b6000611a0d836001600160a01b038416612354565b603480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff166120585760405162461bcd60e51b8152600401610598906137cd565b6112f16123a3565b600080600061206f85856123d3565b9150915061207c81612418565b509392505050565b604080516000808252602082019092526001600160a01b0384169083906040516120ae91906135cb565b60006040518083038185875af1925050503d80600081146120eb576040519150601f19603f3d011682016040523d82523d6000602084013e6120f0565b606091505b505080915050806111975760405162461bcd60e51b815260206004820152602f60248201527f756e61626c6520746f206465626974206e61746976652062616c616e6365207060448201526e3632b0b9b2903a393c9030b3b0b4b760891b6064820152608401610598565b6000818152600183016020526040812054801561224457600061217f60018361375c565b85549091506000906121939060019061375c565b90508181146121f85760008660000182815481106121b3576121b3613714565b90600052602060002001549050808760000184815481106121d6576121d6613714565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061220957612209613818565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610548565b6000915050610548565b5092915050565b600082600001828154811061226c5761226c613714565b9060005260206000200154905092915050565b60006122d4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661255d9092919063ffffffff16565b90508051600014806122f55750808060200190518101906122f59190612dc8565b6111975760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610598565b600081815260018301602052604081205461239b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610548565b506000610548565b600054610100900460ff166123ca5760405162461bcd60e51b8152600401610598906137cd565b6112f133611fdf565b60008082516041036124095760208301516040840151606085015160001a6123fd87828585612574565b94509450505050612411565b506000905060025b9250929050565b600081600481111561242c5761242c61382e565b036124345750565b60018160048111156124485761244861382e565b036124905760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b6044820152606401610598565b60028160048111156124a4576124a461382e565b036124f15760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610598565b60038160048111156125055761250561382e565b03610ed05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610598565b606061256c848460008561262e565b949350505050565b6000806fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311156125a15750600090506003612625565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156125f5573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661261e57600060019250925050612625565b9150600090505b94509492505050565b60608247101561268f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610598565b600080866001600160a01b031685876040516126ab91906135cb565b60006040518083038185875af1925050503d80600081146126e8576040519150601f19603f3d011682016040523d82523d6000602084013e6126ed565b606091505b50915091506126fe87838387612709565b979650505050505050565b60608315612778578251600003612771576001600160a01b0385163b6127715760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610598565b508161256c565b61256c838381511561278d5781518083602001fd5b8060405162461bcd60e51b81526004016105989190613844565b6000602082840312156127b957600080fd5b81356001600160e01b031981168114611a0d57600080fd5b6000602082840312156127e357600080fd5b81356001600160401b038111156127f957600080fd5b82016101e08185031215611a0d57600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156128445761284461280c565b60405290565b6001600160a01b0381168114610ed057600080fd5b80356110a98161284a565b61ffff81168114610ed057600080fd5b80356110a98161286a565b6001600160401b0381168114610ed057600080fd5b80356110a981612885565b600082601f8301126128b657600080fd5b81356001600160401b03808211156128d0576128d061280c565b604051601f8301601f19908116603f011681019082821181831017156128f8576128f861280c565b8160405283815286602085880101111561291157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561294357600080fd5b81356001600160401b038082111561295a57600080fd5b9083019060c0828603121561296e57600080fd5b612976612822565b82356129818161284a565b815260208381013590820152604083013561299b8161284a565b604082015260608301356129ae8161286a565b60608201526129bf6080840161289a565b608082015260a0830135828111156129d657600080fd5b6129e2878286016128a5565b60a08301525095945050505050565b600060208284031215612a0357600080fd5b8135611a0d8161284a565b600081518084526020808501945080840160005b83811015612a475781516001600160a01b031687529582019590820190600101612a22565b509495945050505050565b602081526000611a0d6020830184612a0e565b60008060408385031215612a7857600080fd5b8235612a838161284a565b91506020830135612a938161284a565b809150509250929050565b6001600160a01b0391909116815260200190565b60008060408385031215612ac557600080fd5b8235612ad08161284a565b946020939093013593505050565b600081518084526020808501945080840160005b83811015612a4757815187529582019590820190600101612af2565b606081526000612b216060830186612a0e565b8281036020840152612b338186612ade565b90508281036040840152612b478185612ade565b9695505050505050565b602081526000611a0d6020830184612ade565b60006101a08201905061ffff808c16835260018060a01b03808c1660208501526001600160401b03808c166040860152808b1660608601525060ff891660808501528760a08501528087511660c08501528060208801511660e08501528060408801511661010085015250806060870151166101208401528060808701511661014084015250612bf961016083018515159052565b6001600160a01b0383166101808301529a9950505050505050505050565b60208082526024908201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616040820152633236b4b760e11b606082015260800190565b600060208284031215612c6d57600080fd5b8135611a0d8161286a565b634e487b7160e01b600052601160045260246000fd5b61ffff81811683821601908082111561224e5761224e612c78565b60208082526033908201527f54686520746f74616c2066656520626173697320706f696e742073686f756c646040820152720206265206c657373207468616e20313030303606c1b606082015260800190565b60208082526021908201527f73686f756c642070726f76696465206d617843617020666f72206d696e74696e6040820152606760f81b606082015260800190565b60ff81168114610ed057600080fd5b80356110a981612d3d565b600060208284031215612d6957600080fd5b8135611a0d81612d3d565b60208082526026908201527f73686f756c642070726f766964652077616c6c65744c696d697420666f72206d604082015265696e74696e6760d01b606082015260800190565b8015158114610ed057600080fd5b600060208284031215612dda57600080fd5b8151611a0d81612dba565b60208082526039908201527f73686f756c642070726f76696465206f6e6c7920737570706f7274656420636f6040820152786e747261637420696e7465726661636573204552432037323160381b606082015260800190565b600060208284031215612e5057600080fd5b8135611a0d81612885565b60208082526036908201527f43616e6e6f742068617665207374617274446174652067726561746572207468604082015275616e206f7220657175616c20746f20656e644461746560501b606082015260800190565b60208082526032908201527f73686f756c642070726f766964652076616c69642077616c6c65742061646472604082015271195cdcc8199bdc881cd95d1d1b195b595b9d60721b606082015260800190565b600081356105488161286a565b600081356105488161284a565b6000813561054881612885565b6000813561054881612d3d565b6000808335601e19843603018112612f4e57600080fd5b8301803591506001600160401b03821115612f6857600080fd5b6020019150600581901b360382131561241157600080fd5b808202811582820484141761054857610548612c78565b81831015611197576000818152602081208481019084015b80821015612fc557828255600182019150612faf565b505050505050565b6001600160401b03831115612fe457612fe461280c565b600160401b831115612ff857612ff861280c565b8054838255613008848284612f97565b50818160005260208060002060005b8681101561303a57833561302a8161284a565b8282015592820192600101613017565b50505050505050565b6001600160401b0383111561305a5761305a61280c565b600160401b83111561306e5761306e61280c565b805483825561307e848284612f97565b50818160005260208060002060005b8681101561303a578335828201559282019260010161308d565b80546001600160a01b0319166001600160a01b0392909216919091179055565b81356130d28161284a565b6130dc81836130a7565b5060208201356130eb8161284a565b6130f881600184016130a7565b5060028101604083013561310b8161284a565b61311581836130a7565b5060608301356131248161286a565b815460808501356131348161286a565b63ffffffff60a01b199190911660a09290921b61ffff60a01b169190911760b09190911b61ffff60b01b161790555050565b6000813561054881612dba565b61319261317f83612f03565b825461ffff191661ffff91909116178255565b6131c96131a160208401612f10565b82805462010000600160b01b03191660109290921b62010000600160b01b0316919091179055565b6132046131d860408401612f1d565b82805467ffffffffffffffff60b01b191660b09290921b67ffffffffffffffff60b01b16919091179055565b6001810161323561321760608501612f1d565b825467ffffffffffffffff19166001600160401b0391909116178255565b61326261324460808501612f2a565b82805460ff60401b191660409290921b60ff60401b16919091179055565b5060a0820135600282015561327a60c0830183612f37565b613288818360038601612fcd565b505061329760e0830183612f37565b6132a5818360048601613043565b50506132b86101008301600583016130c7565b600881016132e06132cc6101a08501613166565b825490151560ff1660ff1991909116178255565b6111976132f06101c08501612f10565b828054610100600160a81b03191660089290921b610100600160a81b0316919091179055565b6000808335601e1984360301811261332d57600080fd5b83016020810192503590506001600160401b0381111561334c57600080fd5b8060051b360382131561241157600080fd5b8183526000602080850194508260005b85811015612a475781356133818161284a565b6001600160a01b03168752958201959082019060010161336e565b81835260006001600160fb1b038311156133b557600080fd5b8260051b80836020870137939093016020019392505050565b80356133d98161284a565b6001600160a01b0390811683526020820135906133f58261284a565b908116602084015260408201359061340c8261284a565b16604083015260608101356134208161286a565b61ffff908116606084015260808201359061343a8261286a565b808216608085015250505050565b80356110a981612dba565b60006101e061346d846134658561287a565b61ffff169052565b6134796020840161285f565b6001600160a01b031660208501526134936040840161289a565b6001600160401b031660408501526134ad6060840161289a565b6001600160401b031660608501526134c760808401612d4c565b60ff16608085015260a083810135908501526134e660c0840184613316565b8260c08701526134f9838701828461335e565b9250505061350a60e0840184613316565b85830360e087015261351d83828461339c565b925050506101006135328186018286016133ce565b506101a0613541818501613448565b1515908501526101c061355584820161285f565b6001600160a01b03169401939093525090919050565b60408152600061357e6040830184613453565b82810360208401526007815266155c19185d195960ca1b60208201526040810191505092915050565b60005b838110156135c25781810151838201526020016135aa565b50506000910152565b600082516135dd8184602087016135a7565b9190910192915050565b6000602082840312156135f957600080fd5b8151611a0d8161284a565b60208082526035908201527f496e76616c6964204e4654204f776e657220416464726573732e20506c656173604082015274329031b432b1b59030b732103a393c9030b3b0b4b760591b606082015260800190565b8082018082111561054857610548612c78565b600081518084526136848160208601602086016135a7565b601f01601f19169290920160200192915050565b60608152600060018060a01b03808651166060840152602086015160808401528060408701511660a08401525061ffff60608601511660c08301526001600160401b0360808601511660e083015260a085015160c061010084015261370161012084018261366c565b6020840195909552505060400152919050565b634e487b7160e01b600052603260045260246000fd5b60006001820161373c5761373c612c78565b5060010190565b60006020828403121561375557600080fd5b5051919050565b8181038181111561054857610548612c78565b6040815260006137826040830184613453565b8281036020840152600781526610dc99585d195960ca1b60208201526040810191505092915050565b6000826137c857634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b602081526000611a0d602083018461366c56fea2646970667358221220abd3b0853797cc1c8412c1b835fbe6d9544cd108ed13c435cf800d47ea4e440e64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 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.