More Info
Private Name Tags
Latest 25 from a total of 28 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Rebate | 18227094 | 511 days ago | IN | 0 ETH | 0.00172826 | ||||
Rebate | 18221883 | 511 days ago | IN | 0 ETH | 0.00385873 | ||||
Rebate | 18221622 | 511 days ago | IN | 0 ETH | 0.00423709 | ||||
End Auction | 18221456 | 511 days ago | IN | 0 ETH | 0.01289376 | ||||
Buy | 18221446 | 511 days ago | IN | 0.33 ETH | 0.00345202 | ||||
Buy | 18221441 | 511 days ago | IN | 0.12 ETH | 0.01540823 | ||||
Buy | 18221439 | 511 days ago | IN | 0.12 ETH | 0.01603486 | ||||
Buy | 18221437 | 511 days ago | IN | 0.13 ETH | 0.01589473 | ||||
Buy | 18221419 | 511 days ago | IN | 0.16 ETH | 0.00952062 | ||||
Buy | 18221419 | 511 days ago | IN | 0.16 ETH | 0.00957697 | ||||
Buy | 18221403 | 511 days ago | IN | 0.2 ETH | 0.01111438 | ||||
Buy | 18221403 | 511 days ago | IN | 0.38 ETH | 0.00284237 | ||||
Buy | 18221384 | 511 days ago | IN | 0.69 ETH | 0.01558963 | ||||
Buy | 18221034 | 511 days ago | IN | 0.95 ETH | 0.02580525 | ||||
Create Or Update... | 18191712 | 516 days ago | IN | 0 ETH | 0.00517123 | ||||
Cancel Auction | 18071882 | 532 days ago | IN | 0 ETH | 0.00189096 | ||||
Create Or Update... | 18064656 | 533 days ago | IN | 0 ETH | 0.00542531 | ||||
Approve Admin | 18061966 | 534 days ago | IN | 0 ETH | 0.00096573 | ||||
Approve Admin | 18061082 | 534 days ago | IN | 0 ETH | 0.00071887 | ||||
Approve Admin | 18061081 | 534 days ago | IN | 0 ETH | 0.00072495 | ||||
Approve Admin | 18061080 | 534 days ago | IN | 0 ETH | 0.000742 | ||||
Approve Admin | 18061079 | 534 days ago | IN | 0 ETH | 0.00073905 | ||||
Approve Admin | 18061078 | 534 days ago | IN | 0 ETH | 0.00081799 | ||||
Approve Admin | 18061077 | 534 days ago | IN | 0 ETH | 0.0007623 | ||||
Approve Admin | 18061076 | 534 days ago | IN | 0 ETH | 0.00070369 |
Latest 9 internal transactions
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
DutchAuction
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; pragma experimental ABIEncoderV2; import {IERC721, IERC165} from "../../openzeppelin/token/ERC721/IERC721.sol"; import {IERC1155} from "../../openzeppelin/token/ERC1155/IERC1155.sol"; import {ReentrancyGuard} from "../../openzeppelin/security/ReentrancyGuard.sol"; import {IERC20} from "../../openzeppelin/token/ERC20/IERC20.sol"; import {SafeERC20} from "../../openzeppelin/token/ERC20/utils/SafeERC20.sol"; import {AdminControl} from "../../manifold/libraries-solidity/access/AdminControl.sol"; import {Address} from "../../openzeppelin/utils/Address.sol"; import {IERC721CreatorCore} from "../../manifold/creator-core/core/IERC721CreatorCore.sol"; import {IERC1155CreatorCore} from "../../manifold/creator-core/core/IERC1155CreatorCore.sol"; import "../../mojito/interfaces/IRoyaltyEngine.sol"; import "../../openzeppelin/utils/structs/EnumerableSet.sol"; import {IDutchAuction} from "../../mojito/interfaces/IDutchAuction.sol"; /** * @title DutchAuction * @dev This contract enables collectors and curators to run their own auctions.It is a unique type of auction * where the price of an item starts high and gradually decreases until it reachs the reserved price * */ contract DutchAuction is ReentrancyGuard, AdminControl { using SafeERC20 for IERC20; using EnumerableSet for EnumerableSet.AddressSet; /// @notice details of the buyer /// @param price the price of the NFTs /// @param quantity the nft quantity purchased at actual price /// @param tax the tax rate /// @param priceDiscount the discount price of the nfts /// @param quantityDiscount the nft quantity purchased at the discount price /// @param taxDiscount the tax for discount price /// @param totalCap the total nfts brought by the buyer /// @param rebateClaimed represents that rebate is claimed or not struct BuyerDetails { uint256[] price; uint256[] quantity; uint256[] tax; uint256[] priceDiscount; uint256[] quantityDiscount; uint256[] taxDiscount; uint256 totalCap; bool rebateClaimed; } /// @notice LatestSaleDetails of the particular auction id /// @param finalPrice the price of the latest buy /// @param nextTokenId the id of the next token to buy /// @param currentSupply the total number of tokens purchased by all buyers /// @param fullDiscountSupply the total number of tokens purchased with full discount /// @param zeroDiscountSupply the total number of tokens purchased with zero discount /// @param auctionEnded represents that auction is ended or not /// @param isReachedMaxId represents that minting reacheed the maxId struct LatestSaleDetails { uint256 finalPrice; uint256 nextTokenId; uint256 currentSupply; uint256 fullDiscountSupply; uint256 zeroDiscountSupply; bool auctionEnded; bool isReachedMaxId; } /// @notice emits an event when the auction is created or updated. /// @param auctionId contains the id of the created sale /// @param list contains the details of auction created /// @param createdOrUpdated the details provide whether auction is created or updated event AuctionCreatedorUpdated( string auctionId, IDutchAuction.DutchAuctionList list, string createdOrUpdated ); /// @notice emits an event when the NFT is purchased. /// @param auctionId the id of the created auction /// @param quantity the number of tokens purchased /// @param unit1155 the uints if ERC1155 /// @param currentPrice the current price of the single token /// @param price the price amount of the purchase /// @param tax the tax amount of the purchase /// @param nonce the nonce used for the signature /// @param buyer the buyer address /// @param tokenIds the token ids brought by the buyer event BuyExecuted( string auctionId, uint256 quantity, uint256 unit1155, uint256 currentPrice, uint256 price, uint256 tax, string nonce, address buyer, uint256[] tokenIds ); /// @notice emits an event when auction is ended /// @param auctionId the id of the created auction /// @param soldQuantity the total number of tokens sold /// @param finalPrice the final price of the NFT /// @param tokenIds the token ids brought by the buyer event AuctionEnded( string auctionId, uint256 soldQuantity, uint256 finalPrice, uint256[] tokenIds ); /// @notice emits an event when the rebate is claimed /// @param auctionId the id of the created sale /// @param buyer the buyer address where the rebate is paid /// @param rebateAmount the rebate amount paid to the buyer /// @param rebateTax the rebate tax paid to the buyer /// @param paymentCurrency the currency the rebate is paid at event Rebated( string auctionId, address buyer, uint256 rebateAmount, uint256 rebateTax, address paymentCurrency ); /// @notice emits an event when the auction is cancelled /// @param auctionId contains the id of the created auction event CancelAuction(string auctionId); /// @notice emits an event when an royalty payout is executed /// @param tokenContract the NFT contract address /// @param recipient the address of the royalty recipient(s) /// @param shares the shares sent to the royalty recipient(s) event RoyaltyPayout( address tokenContract, address recipient, uint256 shares ); /// @notice emits an event when EndTime is updated /// @param auctionId contains the id of the created auction /// @param endTimeNew The new EndTime event EndTimeUpdated(string auctionId, uint256 endTimeNew); /// @notice emits an event when Reserved Price is updated /// @param auctionId contains the id of the created auction /// @param reservePriceNew The new reserved price address event ReservePriceUpdated(string auctionId, uint256 reservePriceNew); /// @notice emits an event when an utility And royalty address are updated. /// @param dutchUtilityNew The new DutchUtility address /// @param royaltySupporNew The new royaltySupport address event UpdatedUtilityAndRoyaltyAddress( address dutchUtilityNew, address royaltySupporNew ); // The address of the RoyaltyEngine to use via this contract IRoyaltyEngine public royaltySupport; // The address of the DutchUtility to use via this contract IDutchAuction public dutchUtility; // interface ID constants bytes4 private constant ERC721_INTERFACE_ID = 0x80ac58cd; bytes4 private constant ERC1155_INTERFACE_ID = 0xd9b67a26; // to validate auction Id mapping(string => bool) public usedAuctionId; // to list the auction details with respect to the auction id mapping(string => IDutchAuction.DutchAuctionList) private listings; // to set the buyers address with respect to the auction id mapping(string => EnumerableSet.AddressSet) private buyerAddress; // to set the sale details with respect to the auction id mapping(string => LatestSaleDetails) private latestSaleInfo; // to set the buyerInfo with respect to the auction id and buyer mapping(string => mapping(address => BuyerDetails)) private buyerInfo; // to validate discount signature mapping(bytes => bool) public discountUsed; constructor(IRoyaltyEngine _royaltySupport, address dutchUtilityArg) { require(dutchUtilityArg != address(0), "invalid dutchUtilityArg"); royaltySupport = _royaltySupport; dutchUtility = IDutchAuction(dutchUtilityArg); } /** * @notice createOrUpdateDutchAuction, creates and updates an auction * @param list the listing details to create an auction * @param dutchAuctionID the id of the auction */ function createOrUpdateDutchAuction( string memory dutchAuctionID, IDutchAuction.DutchAuctionList memory list ) external nonReentrant { // checks caller: to be only called by the tokenOwner or admin require( isAdmin(msg.sender) || list.collectionList.tokenOwner == msg.sender, "allowed: only admin or token owner" ); //calls the error handelling functionalities on utility contract dutchUtility.__beforeCreateAuction(list); // calls if the auction is created or updated if (!usedAuctionId[dutchAuctionID]) { listings[dutchAuctionID] = list; usedAuctionId[dutchAuctionID] = true; emit AuctionCreatedorUpdated(dutchAuctionID, list, "listed"); } else if (usedAuctionId[dutchAuctionID]) { require(list.auctionStartTime > block.timestamp, "sale started"); listings[dutchAuctionID] = list; emit AuctionCreatedorUpdated(dutchAuctionID, list, "updated"); } } /** * @notice buy, buying the token(s) at current dutch auction price * @param dutchAuctionID the id of the created auction * @param price the buy amount to purchase NFT(s) * @param tax the tax amount of the purchase * @param quantity the number of tokens to be purchased * @param unit1155 the quantity for 1155 * @param blacklistedProof the merkle tree path of buyer address * @param discount the discount related information */ function buy( string memory dutchAuctionID, uint256 price, uint256 tax, uint256 quantity, uint256 unit1155, bytes32[] memory blacklistedProof, IDutchAuction.Discount memory discount ) external payable nonReentrant { // checks for auctionId is created for auction require(usedAuctionId[dutchAuctionID], "unsupported auction"); IDutchAuction.NftContractList memory nftData = listings[dutchAuctionID] .collectionList; // checks whether is paying the amount with required amount if (listings[dutchAuctionID].paymentCurrency == address(0)) { require(msg.value == price + tax, "insufficient ETH"); } uint256 refundTax; // refund Tax uint256 tempAmount; // refund Amount // validates the purchase data before buying the NFT (tempAmount, refundTax) = dutchUtility.__buyValidation( dutchAuctionID, msg.sender, IDutchAuction.BuyList( price, tax, quantity, unit1155, blacklistedProof, discount ) ); // transfers the excess amount to buyer if ( listings[dutchAuctionID].paymentCurrency == address(0) && (tempAmount + refundTax > 0) ) { (bool success, ) = payable(msg.sender).call{ value: (tempAmount + refundTax) }(new bytes(0)); require(success, "txn failed"); } // updates the actual price and tax based the current price. price = price - tempAmount; tax = tax - refundTax; // adds buyer to the sale if (!buyerAddress[dutchAuctionID].contains(msg.sender)) { buyerAddress[dutchAuctionID].add(msg.sender); } // adds discount signature if (nftData.isSignerRequired) { discountUsed[discount.signature] = true; } else if (discount.discountPercentage > 0) { discountUsed[discount.signature] = true; } uint256 buyQuantity = ( nftData.saleType == IDutchAuction.TypeOfSale.single_tokens_multiple_Quantity ? unit1155 : quantity ); // adds the buy details based on discount % if ( nftData.isDiscountRequired && discount.discountPercentage == 10000 ) { latestSaleInfo[dutchAuctionID].fullDiscountSupply += buyQuantity; } else if ( nftData.isDiscountRequired && discount.discountPercentage > 0 ) { buyerInfo[dutchAuctionID][msg.sender].priceDiscount.push(price); buyerInfo[dutchAuctionID][msg.sender].taxDiscount.push(tax); buyerInfo[dutchAuctionID][msg.sender].quantityDiscount.push( buyQuantity ); } else if ( discount.discountPercentage == 0 || !nftData.isDiscountRequired ) { latestSaleInfo[dutchAuctionID].zeroDiscountSupply += buyQuantity; buyerInfo[dutchAuctionID][msg.sender].price.push(price); buyerInfo[dutchAuctionID][msg.sender].tax.push(tax); buyerInfo[dutchAuctionID][msg.sender].quantity.push(buyQuantity); } // updating the purchase quantity and currentPrice buyerInfo[dutchAuctionID][msg.sender].totalCap += buyQuantity; latestSaleInfo[dutchAuctionID].currentSupply += buyQuantity; // Current Price is Stored in TempAmount Variable. tempAmount = dutchUtility.getCurrentDutchPrice(dutchAuctionID); latestSaleInfo[dutchAuctionID].finalPrice = tempAmount; if (latestSaleInfo[dutchAuctionID].nextTokenId == 0) { latestSaleInfo[dutchAuctionID].nextTokenId = nftData.startTokenId; } // Payment Transfer if (listings[dutchAuctionID].paymentCurrency != address(0)) { if (nftData.isRebate) { IERC20(listings[dutchAuctionID].paymentCurrency) .safeTransferFrom(msg.sender, address(this), price + tax); } } if (!nftData.isRebate) { paymentTransaction( dutchAuctionID, price, tax, listings[dutchAuctionID].paymentCurrency, msg.sender, false ); } uint256[] memory tokenIds; // transfer or mint the NFT if (nftData.isInstantDeliver) { ( tokenIds, latestSaleInfo[dutchAuctionID].nextTokenId ) = __tokenTransaction( dutchAuctionID, msg.sender, quantity, nftData.saleType == IDutchAuction.TypeOfSale.single_tokens_multiple_Quantity ? unit1155 : nftData.unit1155 ); } emit BuyExecuted( dutchAuctionID, quantity, unit1155, tempAmount, price, tax, discount.nonce, msg.sender, tokenIds ); } /** * @notice endAuction, ending the auction * @param dutchAuctionID the id of the created auction */ function endAuction( string memory dutchAuctionID, bool isPriceAsReserve ) external nonReentrant { // checks for auctionId is created for auction require(usedAuctionId[dutchAuctionID], "unsupported auction"); IDutchAuction.NftContractList memory nftData = listings[dutchAuctionID] .collectionList; // calculates the total price of the auction uint256 totalPrice = 0; // calculates the tax of the total auction uint256 totalTax = 0; // checks the caller to be only the token owner or admin require( isAdmin(msg.sender) || nftData.tokenOwner == msg.sender, "allowed: only admin or token owner" ); // checks the auction is crossed the end time or all nft are sold out or reached the max id require( listings[dutchAuctionID].auctionEndTime <= block.timestamp || latestSaleInfo[dutchAuctionID].currentSupply == ( nftData.saleType == IDutchAuction.TypeOfSale.single_tokens_multiple_Quantity ? nftData.unit1155 : nftData.noOfTokens ) || latestSaleInfo[dutchAuctionID].isReachedMaxId, "can't end" ); // checks whether the auction is already ended require(!latestSaleInfo[dutchAuctionID].auctionEnded, "already ended"); // checks for any bid in the provided auction require(latestSaleInfo[dutchAuctionID].currentSupply > 0, "no bids"); // Sets Reserve price as final price. if (isPriceAsReserve) { latestSaleInfo[dutchAuctionID].finalPrice = listings[dutchAuctionID] .reservedPrice; } // checks the contract has sufficient balance if (nftData.isRebate) { (totalPrice, totalTax) = dutchUtility.computeSettlementAmountAndTax( dutchAuctionID ); // transferring the payment to the represented address paymentTransaction( dutchAuctionID, totalPrice, totalTax, listings[dutchAuctionID].paymentCurrency, msg.sender, true ); } uint256[] memory tokenIds; uint256[] memory totalTokenIds = new uint256[]( latestSaleInfo[dutchAuctionID].currentSupply ); // transferring the nft to the represented buyers if (!nftData.isInstantDeliver) { uint256 count = 0; for ( uint256 i = 0; i < buyerAddress[dutchAuctionID].length(); i++ ) { address buyerAdddress = buyerAddress[dutchAuctionID].at(i); uint256 totalCap = buyerInfo[dutchAuctionID][buyerAdddress] .totalCap; uint256 tokenCount = nftData.saleType == IDutchAuction.TypeOfSale.single_tokens_multiple_Quantity ? 1 : totalCap; uint256 quantity = nftData.saleType == IDutchAuction.TypeOfSale.single_tokens_multiple_Quantity ? totalCap : nftData.unit1155; ( tokenIds, latestSaleInfo[dutchAuctionID].nextTokenId ) = __tokenTransaction( dutchAuctionID, buyerAdddress, tokenCount, quantity ); for (uint256 j = 0; j < tokenIds.length; j++) { totalTokenIds[count] = tokenIds[j]; count++; } } } emit AuctionEnded( dutchAuctionID, latestSaleInfo[dutchAuctionID].currentSupply, latestSaleInfo[dutchAuctionID].finalPrice, totalTokenIds ); latestSaleInfo[dutchAuctionID].auctionEnded = true; } /** * @notice cancelAuction, cancels the auction * @param auctionId the auction id to cancel */ function cancelAuction(string memory auctionId) external adminRequired { require(usedAuctionId[auctionId], "unsupported auction"); require(!latestSaleInfo[auctionId].auctionEnded, "already ended"); require(latestSaleInfo[auctionId].finalPrice == 0, "sale started"); delete (listings[auctionId]); emit CancelAuction(auctionId); } /** * @notice rebate, transferring the excess amount to the buyer * @param dutchAuctionID the id of the created auction * @param buyer the buyer wallet address */ function rebate( string memory dutchAuctionID, address buyer ) external nonReentrant { // checks for auctionId is created for auction require(usedAuctionId[dutchAuctionID], "unsupported auction"); // Checks for buyer is a part of buyers list in the auction require( buyerAddress[dutchAuctionID].contains(buyer), "invalid address" ); // checks whether the auction is ended or sold out all NFTs require( latestSaleInfo[dutchAuctionID].auctionEnded || latestSaleInfo[dutchAuctionID].currentSupply == ( listings[dutchAuctionID].collectionList.saleType == IDutchAuction.TypeOfSale.single_tokens_multiple_Quantity ? listings[dutchAuctionID].collectionList.unit1155 : listings[dutchAuctionID].collectionList.noOfTokens ), "not ended" ); // checks whether the rebate is already claimed require( !buyerInfo[dutchAuctionID][buyer].rebateClaimed, "already claimed" ); uint256 rebateAmount; uint256 rebateTax; // gets the rebate amount and tax from claimable() (rebateAmount, rebateTax) = dutchUtility.claimable( dutchAuctionID, buyer ); // checks the rebate amount is greater than zero require(rebateAmount > 0, "no claim"); emit Rebated( dutchAuctionID, buyer, rebateAmount, rebateTax, listings[dutchAuctionID].paymentCurrency ); buyerInfo[dutchAuctionID][buyer].rebateClaimed = true; // transfers the payment to the buyer address _handlePayment( msg.sender, payable(buyer), listings[dutchAuctionID].paymentCurrency, rebateAmount + rebateTax, true ); } /** * @notice Settles the payment to all settlement addresses concerned. * @param _dutchAuctionID the id of the auction * @param _totalAmount the totalAmount to be paid by the seller * @param tax the tax to be paid * @param _paymentToken the address of payment Token * @param _from the from address * @param isRebate the transaction status for rebate or not */ function paymentTransaction( string memory _dutchAuctionID, uint256 _totalAmount, uint256 tax, address _paymentToken, address _from, bool isRebate ) private { IDutchAuction.SettlementList memory settlement = listings[ _dutchAuctionID ].payoutList; uint256 totalCommession; _handlePayment( _from, settlement.taxSettlementAddress, _paymentToken, tax, isRebate ); // transfers the platformFee amount to the platformSettlementAddress if ( settlement.platformSettlementAddress != address(0) && settlement.platformFeePercentage > 0 ) { _handlePayment( _from, settlement.platformSettlementAddress, _paymentToken, totalCommession += ((_totalAmount * settlement.platformFeePercentage) / 10000), isRebate ); } // transfers the commissionfee amount to the commissionAddress if ( settlement.commissionAddress != address(0) && settlement.commissionFeePercentage > 0 ) { totalCommession += ((_totalAmount * settlement.commissionFeePercentage) / 10000); _handlePayment( _from, settlement.commissionAddress, _paymentToken, ((_totalAmount * settlement.commissionFeePercentage) / 10000), isRebate ); } _totalAmount = _totalAmount - totalCommession; // royalty fee payout settlement if (royaltySupport != IRoyaltyEngine(address(0))) { ( address payable[] memory recipients, uint256[] memory bps // Royalty amount denominated in basis points ) = royaltySupport.getCollectionRoyalty( listings[_dutchAuctionID].collectionList.nftContractAddress ); // payouts each royalty for (uint256 i = 0; i < recipients.length; ) { uint256 feeAmount; feeAmount = (bps[i] * _totalAmount) / 10000; // ensures that we aren't somehow paying out more than we have require(_totalAmount >= feeAmount, "insolvent"); emit RoyaltyPayout( listings[_dutchAuctionID].collectionList.nftContractAddress, recipients[i], feeAmount ); _handlePayment( msg.sender, recipients[i], _paymentToken, feeAmount, isRebate ); unchecked { _totalAmount -= feeAmount; ++i; } } } // transfers the balance to the paymentSettlementAddress _handlePayment( _from, settlement.paymentSettlementAddress, _paymentToken, _totalAmount, isRebate ); } /** * @notice Settles the payment based on the given parameters * @param _to the address to whom need to settle the payment * @param _paymentToken the address of the ERC20 Payment Token * @param _amount the amount to be transferred */ function _handlePayment( address _from, address payable _to, address _paymentToken, uint256 _amount, bool isRebate ) private { bool success; if (_paymentToken == address(0)) { // transfers the native currency (success, ) = _to.call{value: _amount}(new bytes(0)); require(success, "txn failed"); } else { if (isRebate) { // transfers the ERC20 currency from contract IERC20(_paymentToken).safeTransfer(_to, _amount); } else if (!isRebate) { // transfers the ERC20 currency from buyer wallet IERC20(_paymentToken).safeTransferFrom(_from, _to, _amount); } } } /** * @notice Transfers the nfts for erc-721/1155 collection * @param dutchAuctionID the id of created auction * @param buyer the address of the nft to be minted or transferred * @param quantity the number of tokens to be minted or transferred * @param unit1155 the units of tokens if erc-1155 collection */ function __tokenTransaction( string memory dutchAuctionID, address buyer, uint256 quantity, uint256 unit1155 ) private returns (uint256[] memory buyTokenIds, uint256 tokenId) { buyTokenIds = new uint256[](quantity); tokenId = latestSaleInfo[dutchAuctionID].nextTokenId; IDutchAuction.NftContractList memory nftData = listings[dutchAuctionID] .collectionList; // transfers the token. if (!nftData.isMint) { for (uint256 i = 0; i < quantity; i++) { if ( IERC165(nftData.nftContractAddress).supportsInterface( ERC721_INTERFACE_ID ) ) { while ( IERC721(nftData.nftContractAddress).ownerOf(tokenId) != nftData.tokenOwner ) { require( nftData.endTokenId >= tokenId, "not enough token" ); tokenId += 1; } // Transfers the ERC721 token(s) IERC721(nftData.nftContractAddress).safeTransferFrom( nftData.tokenOwner, buyer, tokenId ); buyTokenIds[i] = tokenId; tokenId += 1; } else if ( IERC165(nftData.nftContractAddress).supportsInterface( ERC1155_INTERFACE_ID ) ) { if ( nftData.saleType == IDutchAuction .TypeOfSale .multiple_tokens_with_Same_Quantity ) { while ( IERC1155(nftData.nftContractAddress).balanceOf( nftData.tokenOwner, tokenId ) < unit1155 ) { require( nftData.endTokenId >= tokenId, "not enough token" ); tokenId += 1; } // Transfers the ERC1155 Token(s) IERC1155(nftData.nftContractAddress).safeTransferFrom( nftData.tokenOwner, buyer, tokenId, unit1155, "0x" ); buyTokenIds[i] = tokenId; tokenId += 1; } else if ( nftData.saleType == IDutchAuction.TypeOfSale.single_tokens_multiple_Quantity ) { require( IERC1155(nftData.nftContractAddress).balanceOf( nftData.tokenOwner, tokenId ) > unit1155, "insufficient quantity" ); // transferring erc-1155 IERC1155(nftData.nftContractAddress).safeTransferFrom( nftData.tokenOwner, buyer, tokenId, unit1155, "0x" ); buyTokenIds[i] = tokenId; } } } return (buyTokenIds, tokenId); // mints the NFT to buyer address } else if (nftData.isMint) { if ( IERC165(nftData.nftContractAddress).supportsInterface( ERC721_INTERFACE_ID ) ) { // mints for erc-721 collection buyTokenIds = IERC721CreatorCore(nftData.nftContractAddress) .mintExtensionBatch(buyer, uint16(quantity)); } else if ( IERC165(nftData.nftContractAddress).supportsInterface( ERC1155_INTERFACE_ID ) ) { address[] memory to = new address[](1); uint256[] memory amounts = new uint256[](quantity); string[] memory uris; to[0] = buyer; if ( nftData.saleType == IDutchAuction.TypeOfSale.multiple_tokens_with_Same_Quantity ) { for (uint256 i = 0; i < quantity; i++) { amounts[i] = unit1155; } // mints nft for erc-1155 collections for new nfts buyTokenIds = IERC1155CreatorCore( nftData.nftContractAddress ).mintExtensionNew(to, amounts, uris); } else if ( nftData.saleType == IDutchAuction.TypeOfSale.single_tokens_multiple_Quantity ) { amounts[0] = unit1155; if (tokenId == 0) { // mints nft for erc-1155 collections as new nfts buyTokenIds = IERC1155CreatorCore( nftData.nftContractAddress ).mintExtensionNew(to, amounts, uris); latestSaleInfo[dutchAuctionID] .nextTokenId = buyTokenIds[0]; } else { // mints nft for erc-1155 collections as existing nfts buyTokenIds[0] = tokenId; IERC1155CreatorCore(nftData.nftContractAddress) .mintExtensionExisting(to, buyTokenIds, amounts); } } } if (nftData.maxTokenIDRange != -1) { if ( buyTokenIds[buyTokenIds.length - 1] >= uint256(nftData.maxTokenIDRange) ) { latestSaleInfo[dutchAuctionID].isReachedMaxId = true; } require( buyTokenIds[buyTokenIds.length - 1] <= uint256(nftData.maxTokenIDRange), "reached max id" ); } return (buyTokenIds, buyTokenIds[buyTokenIds.length - 1]); } } /** * @notice Withdraw the funds to owner * @param paymentCurrency the address of the paymentCurrency */ function withdraw(address paymentCurrency) external onlyOwner { bool success; if (paymentCurrency == address(0)) { (success, ) = payable(msg.sender).call{ value: address(this).balance }(new bytes(0)); require(success, "txn failed"); } else if (paymentCurrency != address(0)) { // transfers the ERC20 currency IERC20(paymentCurrency).safeTransfer( payable(msg.sender), IERC20(paymentCurrency).balanceOf(address(this)) ); } } /** * @notice Updates the end time of auction * @param dutchAuctionID the id of created auction * @param endTime the end time to update */ function updateEndTime( string memory dutchAuctionID, uint32 endTime ) external adminRequired { require(usedAuctionId[dutchAuctionID], "unsupported auction"); // checks whether the auction is already ended require(!latestSaleInfo[dutchAuctionID].auctionEnded, "already ended"); emit EndTimeUpdated(dutchAuctionID, endTime); listings[dutchAuctionID].auctionEndTime = endTime; } /** * @notice Updates the state variables in contract * @param dutchAuctionID the id of created Auction * @param reservedPrice the reserved price to update */ function updateReservePrice( string memory dutchAuctionID, uint128 reservedPrice ) external adminRequired { require(usedAuctionId[dutchAuctionID], "unsupported auction"); require( reservedPrice < dutchUtility.getCurrentDutchPrice(dutchAuctionID), "invalid arg" ); emit ReservePriceUpdated(dutchAuctionID, reservedPrice); listings[dutchAuctionID].reservedPrice = reservedPrice; } /** * @notice Updates the state variables in contract * @param royaltySupportArg the address for royalty payment support * @param dutchUtilityArg the address for utility support */ function updateUtilityAndRoyaltyAddress( address royaltySupportArg, address dutchUtilityArg ) external adminRequired { require(dutchUtilityArg != address(0), "Invalid dutchUtilityArg"); emit UpdatedUtilityAndRoyaltyAddress( dutchUtilityArg, royaltySupportArg ); royaltySupport = IRoyaltyEngine(royaltySupportArg); dutchUtility = IDutchAuction(dutchUtilityArg); } /** * @notice Gets the detils of the listed sale * @param dutchAuctionID the id of the created auction */ function getListings( string memory dutchAuctionID ) external view returns (IDutchAuction.DutchAuctionList memory auctionist) { return listings[dutchAuctionID]; } /** * @notice Gets the detils collection details of listed sale * @param dutchAuctionID the id of the created auction */ function getLatestSaleInfo( string memory dutchAuctionID ) external view returns (LatestSaleDetails memory saleDetails) { return latestSaleInfo[dutchAuctionID]; } /** * @notice Gets the buyers sale info of the listed sale * @param dutchAuctionID the id of the created auction * @param buyer the address of the buyer */ function getBuyerInfo( string memory dutchAuctionID, address buyer ) external view returns (BuyerDetails memory buyerDetails) { return buyerInfo[dutchAuctionID][buyer]; } /** * @notice Gets the list of all the buyers in the sale * @param dutchAuctionID the id of the created auction */ function getBuyerAddress( string memory dutchAuctionID ) external view returns (address[] memory buyers) { return buyerAddress[dutchAuctionID].values(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @author: manifold.xyz import "../../../openzeppelin/security/ReentrancyGuard.sol"; import "../../../openzeppelin/utils/Strings.sol"; import "../../../openzeppelin/utils/introspection/ERC165.sol"; import "../../../openzeppelin/utils/introspection/ERC165Checker.sol"; import "../../../openzeppelin/utils/structs/EnumerableSet.sol"; import "../../../openzeppelin-upgradeable/utils/AddressUpgradeable.sol"; import "../extensions/ICreatorExtensionTokenURI.sol"; import "./ICreatorCore.sol"; /** * @dev Core creator implementation */ abstract contract CreatorCore is ReentrancyGuard, ICreatorCore, ERC165 { using Strings for uint256; using EnumerableSet for EnumerableSet.AddressSet; using AddressUpgradeable for address; /// @custom:oz-upgrades-unsafe-allow state-variable-assignment uint256 _tokenCount = 0; // Track registered extensions data EnumerableSet.AddressSet internal _extensions; EnumerableSet.AddressSet internal _blacklistedExtensions; mapping(address => address) internal _extensionPermissions; mapping(address => bool) internal _extensionApproveTransfers; // For tracking which extension a token was minted by mapping(uint256 => address) internal _tokensExtension; // The baseURI for a given extension mapping(address => string) private _extensionBaseURI; mapping(address => bool) private _extensionBaseURIIdentical; // The prefix for any tokens with a uri configured mapping(address => string) private _extensionURIPrefix; // Mapping for individual token URIs mapping(uint256 => string) internal _tokenURIs; // Royalty configurations mapping(address => address payable[]) internal _extensionRoyaltyReceivers; mapping(address => uint256[]) internal _extensionRoyaltyBPS; mapping(uint256 => address payable[]) internal _tokenRoyaltyReceivers; mapping(uint256 => uint256[]) internal _tokenRoyaltyBPS; /** * External interface identifiers for royalties */ /** * @dev CreatorCore * * bytes4(keccak256('getRoyalties(uint256)')) == 0xbb3bafd6 * * => 0xbb3bafd6 = 0xbb3bafd6 */ bytes4 private constant _INTERFACE_ID_ROYALTIES_CREATORCORE = 0xbb3bafd6; /** * @dev Rarible: RoyaltiesV1 * * bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb * bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f * * => 0xb9c4d9fb ^ 0x0ebd4c7f = 0xb7799584 */ bytes4 private constant _INTERFACE_ID_ROYALTIES_RARIBLE = 0xb7799584; /** * @dev Foundation * * bytes4(keccak256('getFees(uint256)')) == 0xd5a06d4c * * => 0xd5a06d4c = 0xd5a06d4c */ bytes4 private constant _INTERFACE_ID_ROYALTIES_FOUNDATION = 0xd5a06d4c; /** * @dev EIP-2981 * * bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a * * => 0x2a55205a = 0x2a55205a */ bytes4 private constant _INTERFACE_ID_ROYALTIES_EIP2981 = 0x2a55205a; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(ICreatorCore).interfaceId || super.supportsInterface(interfaceId) || interfaceId == _INTERFACE_ID_ROYALTIES_CREATORCORE || interfaceId == _INTERFACE_ID_ROYALTIES_RARIBLE || interfaceId == _INTERFACE_ID_ROYALTIES_FOUNDATION || interfaceId == _INTERFACE_ID_ROYALTIES_EIP2981; } /** * @dev Only allows registered extensions to call the specified function */ modifier extensionRequired() { require( _extensions.contains(msg.sender), "Must be registered extension" ); _; } /** * @dev Only allows non-blacklisted extensions */ modifier nonBlacklistRequired(address extension) { require( !_blacklistedExtensions.contains(extension), "Extension blacklisted" ); _; } /** * @dev See {ICreatorCore-getExtensions}. */ function getExtensions() external view override returns (address[] memory extensions) { extensions = new address[](_extensions.length()); for (uint256 i = 0; i < _extensions.length(); i++) { extensions[i] = _extensions.at(i); } return extensions; } /** * @dev Register an extension */ function _registerExtension( address extension, string calldata baseURI, bool baseURIIdentical ) internal { require(extension != address(this), "Creator: Invalid"); require( extension.isContract(), "Creator: Extension must be a contract" ); if (!_extensions.contains(extension)) { _extensionBaseURI[extension] = baseURI; _extensionBaseURIIdentical[extension] = baseURIIdentical; emit ExtensionRegistered(extension, msg.sender); _extensions.add(extension); } } /** * @dev Unregister an extension */ function _unregisterExtension(address extension) internal { if (_extensions.contains(extension)) { emit ExtensionUnregistered(extension, msg.sender); _extensions.remove(extension); } } /** * @dev Blacklist an extension */ function _blacklistExtension(address extension) internal { require(extension != address(this), "Cannot blacklist yourself"); if (_extensions.contains(extension)) { emit ExtensionUnregistered(extension, msg.sender); _extensions.remove(extension); } if (!_blacklistedExtensions.contains(extension)) { emit ExtensionBlacklisted(extension, msg.sender); _blacklistedExtensions.add(extension); } } /** * @dev Set base token uri for an extension */ function _setBaseTokenURIExtension(string calldata uri, bool identical) internal { _extensionBaseURI[msg.sender] = uri; _extensionBaseURIIdentical[msg.sender] = identical; } /** * @dev Set token uri prefix for an extension */ function _setTokenURIPrefixExtension(string calldata prefix) internal { _extensionURIPrefix[msg.sender] = prefix; } /** * @dev Set token uri for a token of an extension */ function _setTokenURIExtension(uint256 tokenId, string calldata uri) internal { require(_tokensExtension[tokenId] == msg.sender, "Invalid token"); _tokenURIs[tokenId] = uri; } /** * @dev Set base token uri for tokens with no extension */ function _setBaseTokenURI(string memory uri) internal { _extensionBaseURI[address(this)] = uri; } /** * @dev Set token uri prefix for tokens with no extension */ function _setTokenURIPrefix(string calldata prefix) internal { _extensionURIPrefix[address(this)] = prefix; } /** * @dev Set token uri for a token with no extension */ function _setTokenURI(uint256 tokenId, string calldata uri) internal { require(_tokensExtension[tokenId] == address(this), "Invalid token"); _tokenURIs[tokenId] = uri; } /** * @dev Retrieve a token's URI */ function _tokenURI(uint256 tokenId) internal view returns (string memory) { address extension = _tokensExtension[tokenId]; require( !_blacklistedExtensions.contains(extension), "Extension blacklisted" ); if (bytes(_tokenURIs[tokenId]).length != 0) { if (bytes(_extensionURIPrefix[extension]).length != 0) { return string( abi.encodePacked( _extensionURIPrefix[extension], _tokenURIs[tokenId] ) ); } return _tokenURIs[tokenId]; } if ( ERC165Checker.supportsInterface( extension, type(ICreatorExtensionTokenURI).interfaceId ) ) { return ICreatorExtensionTokenURI(extension).tokenURI( address(this), tokenId ); } if (bytes(_extensionBaseURI[extension]).length != 0) { if (!_extensionBaseURIIdentical[extension]) { return string( abi.encodePacked( _extensionBaseURI[extension], tokenId.toString() ) ); } else { return _extensionBaseURI[extension]; } } else { if (!_extensionBaseURIIdentical[address(this)]) { return string( abi.encodePacked( _extensionBaseURI[address(this)], tokenId.toString() ) ); }else{ return _extensionBaseURI[address(this)]; } } } /** * Get token extension */ function _tokenExtension( uint256 tokenId ) internal view returns (address extension) { extension = _tokensExtension[tokenId]; require(extension != address(this), "No extension for token"); require( !_blacklistedExtensions.contains(extension), "Extension blacklisted" ); return extension; } /** * Helper to get royalties for a token */ function _getRoyalties( uint256 tokenId ) internal view returns (address payable[] storage, uint256[] storage) { return (_getRoyaltyReceivers(tokenId), _getRoyaltyBPS(tokenId)); } /** * Helper to get royalty receivers for a token */ function _getRoyaltyReceivers( uint256 tokenId ) internal view returns (address payable[] storage) { if (_tokenRoyaltyReceivers[tokenId].length > 0) { return _tokenRoyaltyReceivers[tokenId]; } else if ( _extensionRoyaltyReceivers[_tokensExtension[tokenId]].length > 0 ) { return _extensionRoyaltyReceivers[_tokensExtension[tokenId]]; } return _extensionRoyaltyReceivers[address(this)]; } /** * Helper to get royalty basis points for a token */ function _getRoyaltyBPS( uint256 tokenId ) internal view returns (uint256[] storage) { if (_tokenRoyaltyBPS[tokenId].length > 0) { return _tokenRoyaltyBPS[tokenId]; } else if (_extensionRoyaltyBPS[_tokensExtension[tokenId]].length > 0) { return _extensionRoyaltyBPS[_tokensExtension[tokenId]]; } return _extensionRoyaltyBPS[address(this)]; } function _getRoyaltyInfo( uint256 tokenId, uint256 value ) internal view returns (address receiver, uint256 amount) { address payable[] storage receivers = _getRoyaltyReceivers(tokenId); require(receivers.length <= 1, "More than 1 royalty receiver"); if (receivers.length == 0) { return (address(this), 0); } return (receivers[0], (_getRoyaltyBPS(tokenId)[0] * value) / 10000); } /** * Set royalties for a token */ function _setRoyalties( uint256 tokenId, address payable[] calldata receivers, uint256[] calldata basisPoints ) internal { require(receivers.length == basisPoints.length, "Invalid input"); uint256 totalBasisPoints; for (uint256 i = 0; i < basisPoints.length; i++) { totalBasisPoints += basisPoints[i]; } require(totalBasisPoints < 10000, "Invalid total royalties"); _tokenRoyaltyReceivers[tokenId] = receivers; _tokenRoyaltyBPS[tokenId] = basisPoints; emit RoyaltiesUpdated(tokenId, receivers, basisPoints); } /** * Set royalties for all tokens of an extension */ function _setRoyaltiesExtension( address extension, address payable[] calldata receivers, uint256[] calldata basisPoints ) internal { require(receivers.length == basisPoints.length, "Invalid input"); uint256 totalBasisPoints; for (uint256 i = 0; i < basisPoints.length; i++) { totalBasisPoints += basisPoints[i]; } require(totalBasisPoints < 10000, "Invalid total royalties"); _extensionRoyaltyReceivers[extension] = receivers; _extensionRoyaltyBPS[extension] = basisPoints; if (extension == address(this)) { emit DefaultRoyaltiesUpdated(receivers, basisPoints); } else { emit ExtensionRoyaltiesUpdated(extension, receivers, basisPoints); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @author: manifold.xyz import "../../../openzeppelin/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 ExtensionRoyaltiesUpdated( address indexed extension, address payable[] receivers, uint256[] basisPoints ); event ExtensionApproveTransferUpdated( address indexed extension, bool enabled ); /** * @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 (uint256[] memory); function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory); function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @author: manifold.xyz import "./CreatorCore.sol"; /** * @dev Core ERC1155 creator interface */ interface IERC1155CreatorCore is ICreatorCore { /** * @dev mint a token with no extension. Can only be called by an admin. * * @param to - Can be a single element array (all tokens go to same address) or multi-element array (single token to many recipients) * @param amounts - Can be a single element array (all recipients get the same amount) or a multi-element array * @param uris - If no elements, all tokens use the default uri. * If any element is an empty string, the corresponding token uses the default uri. * * * Requirements: If to is a multi-element array, then uris must be empty or single element array * If to is a multi-element array, then amounts must be a single element array or a multi-element array of the same size * If to is a single element array, uris must be empty or the same length as amounts * * Examples: * mintBaseNew(['0x....1', '0x....2'], [1], []) * Mints a single new token, and gives 1 each to '0x....1' and '0x....2'. Token uses default uri. * * mintBaseNew(['0x....1', '0x....2'], [1, 2], []) * Mints a single new token, and gives 1 to '0x....1' and 2 to '0x....2'. Token uses default uri. * * mintBaseNew(['0x....1'], [1, 2], ["", "http://token2.com"]) * Mints two new tokens to '0x....1'. 1 of the first token, 2 of the second. 1st token uses default uri, second uses "http://token2.com". * * @return Returns list of tokenIds minted */ function mintBaseNew(address[] calldata to, uint256[] calldata amounts, string[] calldata uris) external returns (uint256[] memory); /** * @dev batch mint existing token with no extension. Can only be called by an admin. * * @param to - Can be a single element array (all tokens go to same address) or multi-element array (single token to many recipients) * @param tokenIds - Can be a single element array (all recipients get the same token) or a multi-element array * @param amounts - Can be a single element array (all recipients get the same amount) or a multi-element array * * Requirements: If any of the parameters are multi-element arrays, they need to be the same length as other multi-element arrays * * Examples: * mintBaseExisting(['0x....1', '0x....2'], [1], [10]) * Mints 10 of tokenId 1 to each of '0x....1' and '0x....2'. * * mintBaseExisting(['0x....1', '0x....2'], [1, 2], [10, 20]) * Mints 10 of tokenId 1 to '0x....1' and 20 of tokenId 2 to '0x....2'. * * mintBaseExisting(['0x....1'], [1, 2], [10, 20]) * Mints 10 of tokenId 1 and 20 of tokenId 2 to '0x....1'. * * mintBaseExisting(['0x....1', '0x....2'], [1], [10, 20]) * Mints 10 of tokenId 1 to '0x....1' and 20 of tokenId 1 to '0x....2'. * */ function mintBaseExisting(address[] calldata to, uint256[] calldata tokenIds, uint256[] calldata amounts) external; /** * @dev mint a token from an extension. Can only be called by a registered extension. * * @param to - Can be a single element array (all tokens go to same address) or multi-element array (single token to many recipients) * @param amounts - Can be a single element array (all recipients get the same amount) or a multi-element array * @param uris - If no elements, all tokens use the default uri. * If any element is an empty string, the corresponding token uses the default uri. * * * Requirements: If to is a multi-element array, then uris must be empty or single element array * If to is a multi-element array, then amounts must be a single element array or a multi-element array of the same size * If to is a single element array, uris must be empty or the same length as amounts * * Examples: * mintExtensionNew(['0x....1', '0x....2'], [1], []) * Mints a single new token, and gives 1 each to '0x....1' and '0x....2'. Token uses default uri. * * mintExtensionNew(['0x....1', '0x....2'], [1, 2], []) * Mints a single new token, and gives 1 to '0x....1' and 2 to '0x....2'. Token uses default uri. * * mintExtensionNew(['0x....1'], [1, 2], ["", "http://token2.com"]) * Mints two new tokens to '0x....1'. 1 of the first token, 2 of the second. 1st token uses default uri, second uses "http://token2.com". * * @return Returns list of tokenIds minted */ function mintExtensionNew(address[] calldata to, uint256[] calldata amounts, string[] calldata uris) external returns (uint256[] memory); /** * @dev batch mint existing token from extension. Can only be called by a registered extension. * * @param to - Can be a single element array (all tokens go to same address) or multi-element array (single token to many recipients) * @param tokenIds - Can be a single element array (all recipients get the same token) or a multi-element array * @param amounts - Can be a single element array (all recipients get the same amount) or a multi-element array * * Requirements: If any of the parameters are multi-element arrays, they need to be the same length as other multi-element arrays * * Examples: * mintExtensionExisting(['0x....1', '0x....2'], [1], [10]) * Mints 10 of tokenId 1 to each of '0x....1' and '0x....2'. * * mintExtensionExisting(['0x....1', '0x....2'], [1, 2], [10, 20]) * Mints 10 of tokenId 1 to '0x....1' and 20 of tokenId 2 to '0x....2'. * * mintExtensionExisting(['0x....1'], [1, 2], [10, 20]) * Mints 10 of tokenId 1 and 20 of tokenId 2 to '0x....1'. * * mintExtensionExisting(['0x....1', '0x....2'], [1], [10, 20]) * Mints 10 of tokenId 1 to '0x....1' and 20 of tokenId 1 to '0x....2'. * */ function mintExtensionExisting(address[] calldata to, uint256[] calldata tokenIds, uint256[] calldata amounts) external; /** * @dev burn tokens. Can only be called by token owner or approved address. * On burn, calls back to the registered extension's onBurn method */ function burn(address account, uint256[] calldata tokenIds, uint256[] calldata amounts) external; /** * @dev Total amount of tokens in with a given tokenId. */ function totalSupply(uint256 tokenId) external view returns (uint256); }
// 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 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 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; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @author: manifold.xyz import "../../../openzeppelin/utils/introspection/IERC165.sol"; /** * @dev Implement this if you want your extension to have overloadable URI's */ interface ICreatorExtensionTokenURI is IERC165 { /** * Get the uri for a given creator/tokenId */ function tokenURI(address creator, uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @author: manifold.xyz import "../../../openzeppelin/utils/introspection/ERC165.sol"; import "../../../openzeppelin/utils/structs/EnumerableSet.sol"; import "../../../openzeppelin/access/Ownable.sol"; import "./IAdminControl.sol"; abstract contract AdminControl is Ownable, 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 pragma solidity ^0.8.0; /// @author: manifold.xyz import "../../../openzeppelin/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: GPL-3.0 pragma solidity ^0.8.0; pragma experimental ABIEncoderV2; /** * @title Interface for Dutch Auction */ interface IDutchAuction { struct NftContractList { // The NFT contract of Erc-721/1155 for Sale address nftContractAddress; // The From tokenId of the nft for sale uint256 startTokenId; // The To tokenId of the nft for sale uint256 endTokenId; // The quantity of each token If Erc-1155 collection uint256 unit1155; // The address of the token owner address tokenOwner; // total number of nfts for sale uint64 noOfTokens; // The limit which an each address is allowed uint64 walletLimit; // The limit for each transaction uint64 txnLimit; // To specify for mint on Demand bool isMint; // the max token id randge to mint int256 maxTokenIDRange; // To specify nft for Instant Delivery bool isInstantDeliver; // To be Specified for allowing rebate bool isRebate; // To be Specified for allowing discount bool isDiscountRequired; // To specify for AuthSign for buy bool isSignerRequired; // select the type of sale TypeOfSale saleType; // The root hash of the whitelisted buyers bytes32 blacklistedBuyers; } enum TypeOfSale { // refers for sale type of Erc-721 collections erc_721_nft_type, // refers for sale type of Erc-1155 collections with multiple Quantity single_tokens_multiple_Quantity, // refers for sale type of Erc-1155 collections with multiple tokens with Same Quantity multiple_tokens_with_Same_Quantity } struct DutchAuctionList { // details of the nft collection list NftContractList collectionList; // The starting price of the sale uint128 startingPrice; // The minimum price of the sale uint128 reservedPrice; // The price to be reduced in certain time interval uint128 reducePrice; // The time of the sale starts uint32 auctionStartTime; // The time of the sale ends uint32 auctionEndTime; // The time interval of the price decrement uint32 timeForPriceDecrement; // The start time for price decrement to half of previous price uint32 halfLifeTime; // The allowed Payment Currency for the sale address paymentCurrency; // The list of settlement Address and Settlement Price SettlementList payoutList; } struct SettlementList { // The settlement address for the listed tokens address payable paymentSettlementAddress; // The tax settlement address for settlement of tax fee address payable taxSettlementAddress; // The commission address for settlement of commission fee address payable commissionAddress; // The platform address for settlement of platform fee address payable platformSettlementAddress; // The commission fee given in basis points uint16 commissionFeePercentage; // The platform fee given in basis points uint16 platformFeePercentage; } struct BuyerDetails { // The price of the NFTs while buying uint256[] price; // The quatity of the nfts uint256[] quantity; // The tax for price uint256[] tax; // The discount price of the nfts uint256[] priceDiscount; // The nft quantity bought at the discount price uint256[] quantityDiscount; // The tax for discount price uint256[] taxDiscount; // The Total tokens purchased by seller uint256 totalCap; // The rebate claimed status bool rebateClaimed; } struct LatestSaleDetails { // The price of the latest sale uint256 finalPrice; // The id of the next token to buy uint256 nextTokenId; // The total number of tokens purchased uint256 currentSupply; // The total number of tokens purchased with full discount uint256 fullDiscountSupply; // The total number of tokens purchased with zero discount uint256 zeroDiscountSupply; // represents that auction is ended or not bool auctionEnded; // represents that maxId reached bool isReachedMaxId; } struct Discount { // The discount percentage uint16 discountPercentage; // The expire timeof discount signature uint32 expirationTime; // The nonce value string nonce; // The signature generated by admin bytes signature; // The signer of the signature. address signer; } struct BuyList { // The buy amount to purchase NFT(s) uint256 price; // The tax amount of the purchase uint256 tax; // The number of tokens to be purchased uint256 quantity; // The quantity for 1155 if ERC1155 uint256 unit1155; // The merkle tree path of buyer address bytes32[] blacklistedProof; // the discount information IDutchAuction.Discount discount; } function usedAuctionId(string memory dutchAuctionID) external view returns (bool); /** * @notice checks the address is admin address ornot * @param walletAddress the id of the created auction */ function isAdmin(address walletAddress) external view returns (bool); /** * @notice checks the signature is used already or not * @param signature the discount signature */ function discountUsed(bytes memory signature) external view returns (bool); /** * @notice gets the detils of the listed sale * @param dutchAuctionID the id of the created auction */ function getListings( string memory dutchAuctionID ) external view returns (DutchAuctionList memory auctionist); /** * @notice gets the detils collection details of listed sale * @param dutchAuctionID the id of the created auction */ function getLatestSaleInfo( string memory dutchAuctionID ) external view returns (LatestSaleDetails memory saleDetails); /** * @notice gets the buyers sale info of the listed sale * @param dutchAuctionID the id of the created auction * @param buyer the address of the buyer */ function getBuyerInfo( string memory dutchAuctionID, address buyer ) external view returns (BuyerDetails memory buyerDetails); /** * @notice gets the list of all the buyers in the sale * @param dutchAuctionID the id of the created auction */ function getBuyerAddress( string memory dutchAuctionID ) external view returns (address[] memory buyers); /** * @notice validates auction data before auction creation and updation * @param auctionList the List of the auction data */ function __beforeCreateAuction( DutchAuctionList memory auctionList ) external view; /** * @notice validates tha buy data before buy in dutch Auction * @param dutchAuctionID the id of the created auction */ function __buyValidation( string memory dutchAuctionID, address buyer, IDutchAuction.BuyList memory buyList ) external view returns (uint256, uint256); /** * @notice gets the current dutch auction price * @param dutchAuctionId the id of the created auction */ function getCurrentDutchPrice( string memory dutchAuctionId ) external view returns (uint256 currentPrice); /** * @notice gets the claimable amount in rebate type auction * @param dutchAuctionID the id of the created auction * @param buyer the address of buyer wallet */ function claimable( string memory dutchAuctionID, address buyer ) external view returns (uint256 totalClaimable, uint256 totalTaxClaimable); /** * @notice gets the settlement amount and tax for endAuction() * @param dutchAuctionID the id of the created auction */ function computeSettlementAmountAndTax( string memory dutchAuctionID ) external returns (uint256, uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; pragma experimental ABIEncoderV2; /** * @title Interface for RoyaltyEngine */ interface IRoyaltyEngine { /** * @notice Emits when an collection level Royalty is configured * @param collectionAddress contract address * @param receivers set of royalty receivers * @param basisPoints set of royalty Bps */ event RoyaltiesUpdated( address indexed collectionAddress, address payable[] receivers, uint256[] basisPoints ); /** * @notice Emits when an Token level Royalty is configured * @param collectionAddress contract address * @param tokenId Token Id * @param receivers set of royalty receivers * @param basisPoints set of royalty Bps */ event TokenRoyaltiesUpdated( address collectionAddress, uint256 indexed tokenId, address payable[] receivers, uint256[] basisPoints ); /** * @notice Emits when address is added into Black List. * @param account BlackListed NFT contract address or wallet address * @param sender caller address **/ event AddedBlacklistedAddress( address indexed account, address indexed sender ); /** * @notice Eits when address is removed from Black List. * @param account BlackListed NFT contract address or wallet address * @param sender caller address **/ event RevokedBlacklistedAddress( address indexed account, address indexed sender ); /** * @notice Setting royalty for NFT Collection. * @param collectionAddress NFT contract address * @param receivers set of royalty receivers * @param basisPoints set of royalty Bps */ function setRoyalty( address collectionAddress, address payable[] calldata receivers, uint256[] calldata basisPoints ) external; /** * @notice Setting royalty for token. * @param collectionAddress contract address * @param tokenId Token Id * @param receivers set of royalty receivers * @param basisPoints set of royalty Bps */ function setTokenRoyalty( address collectionAddress, uint256 tokenId, address payable[] calldata receivers, uint256[] calldata basisPoints ) external; /** * @notice getting collection level royalty information * @param collectionAddress contract address * @return receivers returns set of royalty receivers address * @return basisPoints returns set of Bps to calculate Shares. **/ function getCollectionRoyalty(address collectionAddress) external view returns (address payable[] memory receivers, uint256[] memory basisPoints); /** * @notice getting royalty information from Other royalty standard. * @param collectionAddress contract address * @param tokenId Token Id * @return receivers returns set of royalty receivers address * @return basisPoints returns set of Bps to calculate Shares. **/ function getRoyalty(address collectionAddress, uint256 tokenId) external view returns (address payable[] memory receivers, uint256[] memory basisPoints); /** * @notice Compute royalty Shares * @param collectionAddress contract address * @param tokenId Token Id * @param amount amount involved to compute the Shares. * @return receivers returns set of royalty receivers address * @return basisPoints returns set of Bps. * @return feeAmount returns set of Shares. **/ function getRoyaltySplitshare( address collectionAddress, uint256 tokenId, uint256 amount ) external view returns ( address payable[] memory receivers, uint256[] memory basisPoints, uint256[] memory feeAmount ); /** * @notice Adds address as blacklist * @param commonAddress user wallet address **/ function blacklistAddress(address commonAddress) external; /** * @notice revoke the blacklistedAddress * @param commonAddress address info **/ function revokeBlacklistedAddress(address commonAddress) external; /** * @notice checks the blacklistedAddress * @param commonAddress address info **/ function isBlacklistedAddress(address commonAddress) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Address.sol) pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT 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; /// @custom:oz-upgrades-unsafe-allow constructor 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 make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount ) external returns (bool); /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.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`, 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 be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Address.sol) pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface, */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return _supportsERC165Interface(account, type(IERC165).interfaceId) && !_supportsERC165Interface(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && _supportsERC165Interface(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in _interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!_supportsERC165Interface(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * Interface identification is specified in ERC-165. */ function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) { bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); (bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams); if (result.length < 32) return false; return success && abi.decode(result, (bool)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } }
{ "optimizer": { "enabled": true, "runs": 125 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IRoyaltyEngine","name":"_royaltySupport","type":"address"},{"internalType":"address","name":"dutchUtilityArg","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":false,"internalType":"string","name":"auctionId","type":"string"},{"components":[{"components":[{"internalType":"address","name":"nftContractAddress","type":"address"},{"internalType":"uint256","name":"startTokenId","type":"uint256"},{"internalType":"uint256","name":"endTokenId","type":"uint256"},{"internalType":"uint256","name":"unit1155","type":"uint256"},{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"uint64","name":"noOfTokens","type":"uint64"},{"internalType":"uint64","name":"walletLimit","type":"uint64"},{"internalType":"uint64","name":"txnLimit","type":"uint64"},{"internalType":"bool","name":"isMint","type":"bool"},{"internalType":"int256","name":"maxTokenIDRange","type":"int256"},{"internalType":"bool","name":"isInstantDeliver","type":"bool"},{"internalType":"bool","name":"isRebate","type":"bool"},{"internalType":"bool","name":"isDiscountRequired","type":"bool"},{"internalType":"bool","name":"isSignerRequired","type":"bool"},{"internalType":"enum IDutchAuction.TypeOfSale","name":"saleType","type":"uint8"},{"internalType":"bytes32","name":"blacklistedBuyers","type":"bytes32"}],"internalType":"struct IDutchAuction.NftContractList","name":"collectionList","type":"tuple"},{"internalType":"uint128","name":"startingPrice","type":"uint128"},{"internalType":"uint128","name":"reservedPrice","type":"uint128"},{"internalType":"uint128","name":"reducePrice","type":"uint128"},{"internalType":"uint32","name":"auctionStartTime","type":"uint32"},{"internalType":"uint32","name":"auctionEndTime","type":"uint32"},{"internalType":"uint32","name":"timeForPriceDecrement","type":"uint32"},{"internalType":"uint32","name":"halfLifeTime","type":"uint32"},{"internalType":"address","name":"paymentCurrency","type":"address"},{"components":[{"internalType":"address payable","name":"paymentSettlementAddress","type":"address"},{"internalType":"address payable","name":"taxSettlementAddress","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 IDutchAuction.SettlementList","name":"payoutList","type":"tuple"}],"indexed":false,"internalType":"struct IDutchAuction.DutchAuctionList","name":"list","type":"tuple"},{"indexed":false,"internalType":"string","name":"createdOrUpdated","type":"string"}],"name":"AuctionCreatedorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"auctionId","type":"string"},{"indexed":false,"internalType":"uint256","name":"soldQuantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"finalPrice","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"AuctionEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"auctionId","type":"string"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unit1155","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tax","type":"uint256"},{"indexed":false,"internalType":"string","name":"nonce","type":"string"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"BuyExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"auctionId","type":"string"}],"name":"CancelAuction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"auctionId","type":"string"},{"indexed":false,"internalType":"uint256","name":"endTimeNew","type":"uint256"}],"name":"EndTimeUpdated","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":"string","name":"auctionId","type":"string"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"rebateAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rebateTax","type":"uint256"},{"indexed":false,"internalType":"address","name":"paymentCurrency","type":"address"}],"name":"Rebated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"auctionId","type":"string"},{"indexed":false,"internalType":"uint256","name":"reservePriceNew","type":"uint256"}],"name":"ReservePriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenContract","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"RoyaltyPayout","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"dutchUtilityNew","type":"address"},{"indexed":false,"internalType":"address","name":"royaltySupporNew","type":"address"}],"name":"UpdatedUtilityAndRoyaltyAddress","type":"event"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"approveAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"tax","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"unit1155","type":"uint256"},{"internalType":"bytes32[]","name":"blacklistedProof","type":"bytes32[]"},{"components":[{"internalType":"uint16","name":"discountPercentage","type":"uint16"},{"internalType":"uint32","name":"expirationTime","type":"uint32"},{"internalType":"string","name":"nonce","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct IDutchAuction.Discount","name":"discount","type":"tuple"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"auctionId","type":"string"}],"name":"cancelAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"},{"components":[{"components":[{"internalType":"address","name":"nftContractAddress","type":"address"},{"internalType":"uint256","name":"startTokenId","type":"uint256"},{"internalType":"uint256","name":"endTokenId","type":"uint256"},{"internalType":"uint256","name":"unit1155","type":"uint256"},{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"uint64","name":"noOfTokens","type":"uint64"},{"internalType":"uint64","name":"walletLimit","type":"uint64"},{"internalType":"uint64","name":"txnLimit","type":"uint64"},{"internalType":"bool","name":"isMint","type":"bool"},{"internalType":"int256","name":"maxTokenIDRange","type":"int256"},{"internalType":"bool","name":"isInstantDeliver","type":"bool"},{"internalType":"bool","name":"isRebate","type":"bool"},{"internalType":"bool","name":"isDiscountRequired","type":"bool"},{"internalType":"bool","name":"isSignerRequired","type":"bool"},{"internalType":"enum IDutchAuction.TypeOfSale","name":"saleType","type":"uint8"},{"internalType":"bytes32","name":"blacklistedBuyers","type":"bytes32"}],"internalType":"struct IDutchAuction.NftContractList","name":"collectionList","type":"tuple"},{"internalType":"uint128","name":"startingPrice","type":"uint128"},{"internalType":"uint128","name":"reservedPrice","type":"uint128"},{"internalType":"uint128","name":"reducePrice","type":"uint128"},{"internalType":"uint32","name":"auctionStartTime","type":"uint32"},{"internalType":"uint32","name":"auctionEndTime","type":"uint32"},{"internalType":"uint32","name":"timeForPriceDecrement","type":"uint32"},{"internalType":"uint32","name":"halfLifeTime","type":"uint32"},{"internalType":"address","name":"paymentCurrency","type":"address"},{"components":[{"internalType":"address payable","name":"paymentSettlementAddress","type":"address"},{"internalType":"address payable","name":"taxSettlementAddress","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 IDutchAuction.SettlementList","name":"payoutList","type":"tuple"}],"internalType":"struct IDutchAuction.DutchAuctionList","name":"list","type":"tuple"}],"name":"createOrUpdateDutchAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"discountUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dutchUtility","outputs":[{"internalType":"contract IDutchAuction","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"},{"internalType":"bool","name":"isPriceAsReserve","type":"bool"}],"name":"endAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdmins","outputs":[{"internalType":"address[]","name":"admins","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"}],"name":"getBuyerAddress","outputs":[{"internalType":"address[]","name":"buyers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"},{"internalType":"address","name":"buyer","type":"address"}],"name":"getBuyerInfo","outputs":[{"components":[{"internalType":"uint256[]","name":"price","type":"uint256[]"},{"internalType":"uint256[]","name":"quantity","type":"uint256[]"},{"internalType":"uint256[]","name":"tax","type":"uint256[]"},{"internalType":"uint256[]","name":"priceDiscount","type":"uint256[]"},{"internalType":"uint256[]","name":"quantityDiscount","type":"uint256[]"},{"internalType":"uint256[]","name":"taxDiscount","type":"uint256[]"},{"internalType":"uint256","name":"totalCap","type":"uint256"},{"internalType":"bool","name":"rebateClaimed","type":"bool"}],"internalType":"struct DutchAuction.BuyerDetails","name":"buyerDetails","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"}],"name":"getLatestSaleInfo","outputs":[{"components":[{"internalType":"uint256","name":"finalPrice","type":"uint256"},{"internalType":"uint256","name":"nextTokenId","type":"uint256"},{"internalType":"uint256","name":"currentSupply","type":"uint256"},{"internalType":"uint256","name":"fullDiscountSupply","type":"uint256"},{"internalType":"uint256","name":"zeroDiscountSupply","type":"uint256"},{"internalType":"bool","name":"auctionEnded","type":"bool"},{"internalType":"bool","name":"isReachedMaxId","type":"bool"}],"internalType":"struct DutchAuction.LatestSaleDetails","name":"saleDetails","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"}],"name":"getListings","outputs":[{"components":[{"components":[{"internalType":"address","name":"nftContractAddress","type":"address"},{"internalType":"uint256","name":"startTokenId","type":"uint256"},{"internalType":"uint256","name":"endTokenId","type":"uint256"},{"internalType":"uint256","name":"unit1155","type":"uint256"},{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"uint64","name":"noOfTokens","type":"uint64"},{"internalType":"uint64","name":"walletLimit","type":"uint64"},{"internalType":"uint64","name":"txnLimit","type":"uint64"},{"internalType":"bool","name":"isMint","type":"bool"},{"internalType":"int256","name":"maxTokenIDRange","type":"int256"},{"internalType":"bool","name":"isInstantDeliver","type":"bool"},{"internalType":"bool","name":"isRebate","type":"bool"},{"internalType":"bool","name":"isDiscountRequired","type":"bool"},{"internalType":"bool","name":"isSignerRequired","type":"bool"},{"internalType":"enum IDutchAuction.TypeOfSale","name":"saleType","type":"uint8"},{"internalType":"bytes32","name":"blacklistedBuyers","type":"bytes32"}],"internalType":"struct IDutchAuction.NftContractList","name":"collectionList","type":"tuple"},{"internalType":"uint128","name":"startingPrice","type":"uint128"},{"internalType":"uint128","name":"reservedPrice","type":"uint128"},{"internalType":"uint128","name":"reducePrice","type":"uint128"},{"internalType":"uint32","name":"auctionStartTime","type":"uint32"},{"internalType":"uint32","name":"auctionEndTime","type":"uint32"},{"internalType":"uint32","name":"timeForPriceDecrement","type":"uint32"},{"internalType":"uint32","name":"halfLifeTime","type":"uint32"},{"internalType":"address","name":"paymentCurrency","type":"address"},{"components":[{"internalType":"address payable","name":"paymentSettlementAddress","type":"address"},{"internalType":"address payable","name":"taxSettlementAddress","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 IDutchAuction.SettlementList","name":"payoutList","type":"tuple"}],"internalType":"struct IDutchAuction.DutchAuctionList","name":"auctionist","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"},{"internalType":"address","name":"buyer","type":"address"}],"name":"rebate","outputs":[],"stateMutability":"nonpayable","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":[],"name":"royaltySupport","outputs":[{"internalType":"contract IRoyaltyEngine","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"updateEndTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"dutchAuctionID","type":"string"},{"internalType":"uint128","name":"reservedPrice","type":"uint128"}],"name":"updateReservePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"royaltySupportArg","type":"address"},{"internalType":"address","name":"dutchUtilityArg","type":"address"}],"name":"updateUtilityAndRoyaltyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"usedAuctionId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"paymentCurrency","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620060f1380380620060f1833981016040819052620000349162000120565b6001600081815581546001600160a01b031916339081179092556040518291907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b038116620000d55760405162461bcd60e51b815260206004820152601760248201527f696e76616c69642064757463685574696c697479417267000000000000000000604482015260640160405180910390fd5b600480546001600160a01b039384166001600160a01b031991821617909155600580549290931691161790556200015f565b6001600160a01b03811681146200011d57600080fd5b50565b600080604083850312156200013457600080fd5b8251620001418162000107565b6020840151909250620001548162000107565b809150509250929050565b615f82806200016f6000396000f3fe6080604052600436106101565760003560e01c806358e656e4116100c157806395318d861161007a57806395318d86146103ef578063a628ec5d1461040f578063b60e7a3b14610422578063b7b429aa14610442578063d78ccb8b146104bc578063da20872a146104f7578063f2fde38b1461051757600080fd5b806358e656e41461032a57806359bb679a14610365578063681569e9146103855780636d73e669146103a5578063715018a6146103c55780638da5cb5b146103da57600080fd5b806324d7806c1161011357806324d7806c146102685780632d3456701461028857806331ae450b146102a85780634970d03e146102ca57806350e58ea6146102ea57806351cff8d91461030a57600080fd5b8063015109451461015b57806301ffc9a7146101915780630397b87b146101c15780630a28e844146101ee5780631376789b146102105780631ae9cd9814610248575b600080fd5b34801561016757600080fd5b5061017b610176366004614b61565b610537565b6040516101889190614bed565b60405180910390f35b34801561019d57600080fd5b506101b16101ac366004614cc8565b6107e9565b6040519015158152602001610188565b3480156101cd57600080fd5b506101e16101dc366004614cf2565b61081e565b6040516101889190614f47565b3480156101fa57600080fd5b5061020e610209366004614f6a565b610b5d565b005b34801561021c57600080fd5b50600554610230906001600160a01b031681565b6040516001600160a01b039091168152602001610188565b34801561025457600080fd5b5061020e610263366004614b61565b610ca5565b34801561027457600080fd5b506101b1610283366004614fb7565b6110cc565b34801561029457600080fd5b5061020e6102a3366004614fb7565b6110fb565b3480156102b457600080fd5b506102bd611180565b604051610188919061500d565b3480156102d657600080fd5b5061020e6102e5366004615020565b61122e565b3480156102f657600080fd5b5061020e610305366004615067565b61132f565b34801561031657600080fd5b5061020e610325366004614fb7565b611a9c565b34801561033657600080fd5b506101b1610345366004614cf2565b805160208183018101805160068252928201919093012091525460ff1681565b34801561037157600080fd5b5061020e6103803660046150c4565b611bf0565b34801561039157600080fd5b506102bd6103a0366004614cf2565b611da0565b3480156103b157600080fd5b5061020e6103c0366004614fb7565b611dc8565b3480156103d157600080fd5b5061020e611e47565b3480156103e657600080fd5b50610230611ec0565b3480156103fb57600080fd5b5061020e61040a3660046152fd565b611ecf565b61020e61041d3660046154f4565b6126c4565b34801561042e57600080fd5b5061020e61043d366004614cf2565b6130c7565b34801561044e57600080fd5b5061046261045d366004614cf2565b6132cc565b6040516101889190600060e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015260c0830151151560c083015292915050565b3480156104c857600080fd5b506101b16104d7366004614cf2565b8051602081830181018051600b8252928201919093012091525460ff1681565b34801561050357600080fd5b50600454610230906001600160a01b031681565b34801561052357600080fd5b5061020e610532366004614fb7565b61338c565b610581604051806101000160405280606081526020016060815260200160608152602001606081526020016060815260200160608152602001600081526020016000151581525090565b600a83604051610591919061561f565b9081526040805191829003602090810183206001600160a01b038616600090815290825282902080546101209281028501830190935261010084018381529092849284919084018282801561060557602002820191906000526020600020905b8154815260200190600101908083116105f1575b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561065d57602002820191906000526020600020905b815481526020019060010190808311610649575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156106b557602002820191906000526020600020905b8154815260200190600101908083116106a1575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561070d57602002820191906000526020600020905b8154815260200190600101908083116106f9575b505050505081526020016004820180548060200260200160405190810160405280929190818152602001828054801561076557602002820191906000526020600020905b815481526020019060010190808311610751575b50505050508152602001600582018054806020026020016040519081016040528092919081815260200182805480156107bd57602002820191906000526020600020905b8154815260200190600101908083116107a9575b50505091835250506006820154602082015260079091015460ff16151560409091015290505b92915050565b60006001600160e01b03198216632a9f3abf60e11b14806107e357506301ffc9a760e01b6001600160e01b03198316146107e3565b604080516103408101825260006101408201818152610160830182905261018083018290526101a083018290526101c083018290526101e08301829052610200830182905261022083018290526102408301829052610260830182905261028083018290526102a083018290526102c083018290526102e0830182905261030083018290526103208301829052825260208083018290528284018290526060808401839052608080850184905260a080860185905260c080870186905260e08701869052610100870186905287519081018852858152938401859052958301849052908201839052810182905292830152610120810191909152600782604051610928919061561f565b90815260408051918290036020018220610340830190915280546001600160a01b039081166101408401908152600183015461016085015260028084015461018086015260038401546101a086015260048401549283166101c08601526001600160401b03600160a01b90930483166101e08601526005840154808416610200870152600160401b810490931661022086015260ff600160801b909304831615156102408601526006840154610260860152600784015480841615156102808701526101008104841615156102a0870152620100008104841615156102c087015263010000008104841615156102e087015285938592610300860192600160201b900490911690811115610a3e57610a3e614d26565b6002811115610a4f57610a4f614d26565b81526008919091015460209182015290825260098301546001600160801b0380821684840152600160801b918290048116604080860191909152600a86015491821660608087019190915263ffffffff9383048416608080880191909152600160a01b808504861660a0808a0191909152600160c01b8604871660c0808b0191909152600160e01b90960490961660e0890152600b8901546001600160a01b039081166101008a015284519586018552600c8a015481168652600d8a0154811697860197909752600e890154871693850193909352600f909701549485169083015261ffff908404811695820195909552600160b01b90920490931692810192909252610120015292915050565b33610b66611ec0565b6001600160a01b03161480610b815750610b8160023361347c565b610ba65760405162461bcd60e51b8152600401610b9d9061563b565b60405180910390fd5b600682604051610bb6919061561f565b9081526040519081900360200190205460ff16610be55760405162461bcd60e51b8152600401610b9d9061567f565b600982604051610bf5919061561f565b9081526040519081900360200190206005015460ff1615610c285760405162461bcd60e51b8152600401610b9d906156ac565b7f714e5610970185b216fa0c83f3d271b2598e7d7b69067891f2477008e82899e28282604051610c599291906156ff565b60405180910390a180600783604051610c72919061561f565b9081526020016040518091039020600a0160146101000a81548163ffffffff021916908363ffffffff1602179055505050565b600260005403610cc75760405162461bcd60e51b8152600401610b9d90615727565b6002600055604051600690610cdd90849061561f565b9081526040519081900360200190205460ff16610d0c5760405162461bcd60e51b8152600401610b9d9061567f565b610d3581600884604051610d20919061561f565b9081526040519081900360200190209061347c565b610d735760405162461bcd60e51b815260206004820152600f60248201526e696e76616c6964206164647265737360881b6044820152606401610b9d565b600982604051610d83919061561f565b9081526040519081900360200190206005015460ff1680610e6657506001600783604051610db1919061561f565b9081526040519081900360200190206007015460ff600160201b909104166002811115610de057610de0614d26565b14610e1e57600782604051610df5919061561f565b908152604051908190036020019020600401546001600160401b03600160a01b90910416610e42565b600782604051610e2e919061561f565b908152604051908190036020019020600301545b600983604051610e52919061561f565b908152602001604051809103902060020154145b610e9e5760405162461bcd60e51b81526020600482015260096024820152681b9bdd08195b99195960ba1b6044820152606401610b9d565b600a82604051610eae919061561f565b90815260408051602092819003830190206001600160a01b0384166000908152925290206007015460ff1615610f185760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b6044820152606401610b9d565b60055460405163d8130ec960e01b815260009182916001600160a01b039091169063d8130ec990610f4f908790879060040161575e565b6040805180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f9190615788565b909250905081610fcc5760405162461bcd60e51b81526020600482015260086024820152676e6f20636c61696d60c01b6044820152606401610b9d565b7f265be343ba17e4fb0f7aa786f7b36cfd1bd54098b49d11c302d5e2c267e4e35384848484600789604051611001919061561f565b908152604051908190036020018120600b015461102d95949392916001600160a01b03909116906157ac565b60405180910390a16001600a85604051611047919061561f565b90815260408051602092819003830181206001600160a01b0388166000908152935291206007908101805460ff1916931515939093179092556110c191339186919061109490899061561f565b908152604051908190036020019020600b01546001600160a01b03166110ba8587615807565b60016134a1565b505060016000555050565b6000816001600160a01b03166110e0611ec0565b6001600160a01b031614806107e357506107e360028361347c565b33611104611ec0565b6001600160a01b03161461112a5760405162461bcd60e51b8152600401610b9d9061581a565b61113560028261347c565b1561117d5760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a361117b60028261357d565b505b50565b606061118c6002613592565b6001600160401b038111156111a3576111a3614a3b565b6040519080825280602002602001820160405280156111cc578160200160208202803683370190505b50905060005b6111dc6002613592565b81101561122a576111ee60028261359c565b8282815181106112005761120061584f565b6001600160a01b03909216602092830291909101909101528061122281615865565b9150506111d2565b5090565b33611237611ec0565b6001600160a01b03161480611252575061125260023361347c565b61126e5760405162461bcd60e51b8152600401610b9d9061563b565b6001600160a01b0381166112be5760405162461bcd60e51b8152602060048201526017602482015276496e76616c69642064757463685574696c69747941726760481b6044820152606401610b9d565b604080516001600160a01b038084168252841660208201527f88bd3dbca0ee348f905e71c0d342bb50b637a5044709b0c4e0ee0f3672711fb0910160405180910390a1600480546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6002600054036113515760405162461bcd60e51b8152600401610b9d90615727565b600260005560405160069061136790849061561f565b9081526040519081900360200190205460ff166113965760405162461bcd60e51b8152600401610b9d9061567f565b60006007836040516113a8919061561f565b9081526040805191829003602090810183206102008401835280546001600160a01b0390811685526001820154928501929092526002808201549385019390935260038101546060850152600481015491821660808501526001600160401b03600160a01b909204821660a0850152600581015480831660c0860152600160401b810490921660e085015260ff600160801b9092048216151561010080860191909152600682015461012086015260078201548084161515610140870152908104831615156101608601526201000081048316151561018086015263010000008104831615156101a086015290926101c0850192600160201b909204909116908111156114b7576114b7614d26565b60028111156114c8576114c8614d26565b815260200160088201548152505090506000806114e4336110cc565b806114fb575060808301516001600160a01b031633145b6115175760405162461bcd60e51b8152600401610b9d9061587e565b42600786604051611528919061561f565b908152604051908190036020019020600a015463ffffffff600160a01b909104161115806115ac57506001836101c00151600281111561156a5761156a614d26565b14611582578260a001516001600160401b0316611588565b82606001515b600986604051611598919061561f565b908152602001604051809103902060020154145b806115df57506009856040516115c2919061561f565b9081526040519081900360200190206005015460ff610100909104165b6116175760405162461bcd60e51b815260206004820152600960248201526818d85b89dd08195b9960ba1b6044820152606401610b9d565b600985604051611627919061561f565b9081526040519081900360200190206005015460ff161561165a5760405162461bcd60e51b8152600401610b9d906156ac565b600060098660405161166c919061561f565b908152602001604051809103902060020154116116b55760405162461bcd60e51b81526020600482015260076024820152666e6f206269647360c81b6044820152606401610b9d565b831561170e576007856040516116cb919061561f565b9081526040519081900360200181206009908101546001600160801b03600160801b90910416916116fd90889061561f565b908152604051908190036020019020555b826101600151156117cd576005546040516308fa05ed60e41b81526001600160a01b0390911690638fa05ed0906117499088906004016158c0565b60408051808303816000875af1158015611767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178b9190615788565b80925081935050506117cd8583836007896040516117a9919061561f565b908152604051908190036020019020600b01546001600160a01b03163360016135a8565b606060006009876040516117e1919061561f565b9081526020016040518091039020600201546001600160401b0381111561180a5761180a614a3b565b604051908082528060200260200182016040528015611833578160200160208202803683370190505b5090508461014001516119e0576000805b61186a60088a604051611857919061561f565b9081526020016040518091039020613592565b8110156119dd57600061189c8260088c604051611887919061561f565b9081526040519081900360200190209061359c565b90506000600a8b6040516118b0919061561f565b90815260408051602092819003830190206001600160a01b03851660009081529252812060060154915060018a6101c0015160028111156118f3576118f3614d26565b146118fe5781611901565b60015b9050600060018b6101c00151600281111561191e5761191e614d26565b1461192d578a6060015161192f565b825b905061193d8d858484613941565b60098f60405161194d919061561f565b90815260405190819003602001902060010155975060005b88518110156119c5578881815181106119805761198061584f565b602002602001015188888151811061199a5761199a61584f565b6020908102919091010152866119af81615865565b97505080806119bd90615865565b915050611965565b505050505080806119d590615865565b915050611844565b50505b7fea6186ac627a0a0d08856980003659f2072d5606356dd0876c1f8adf32db9eea87600989604051611a12919061561f565b90815260200160405180910390206002015460098a604051611a34919061561f565b90815260405190819003602001812054611a5193929186906158d3565b60405180910390a16001600988604051611a6b919061561f565b908152604051908190036020019020600501805491151560ff19909216919091179055505060016000555050505050565b33611aa5611ec0565b6001600160a01b031614611acb5760405162461bcd60e51b8152600401610b9d9061581a565b60006001600160a01b038216611b62576040805160008152602081019182905233914791611af89161561f565b60006040518083038185875af1925050503d8060008114611b35576040519150601f19603f3d011682016040523d82523d6000602084013e611b3a565b606091505b50508091505080611b5d5760405162461bcd60e51b8152600401610b9d90615904565b61117b565b6001600160a01b0382161561117b576040516370a0823160e01b815230600482015261117b9033906001600160a01b038516906370a0823190602401602060405180830381865afa158015611bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bdf9190615928565b6001600160a01b0385169190614585565b33611bf9611ec0565b6001600160a01b03161480611c145750611c1460023361347c565b611c305760405162461bcd60e51b8152600401610b9d9061563b565b600682604051611c40919061561f565b9081526040519081900360200190205460ff16611c6f5760405162461bcd60e51b8152600401610b9d9061567f565b600554604051637b30fb3760e01b81526001600160a01b0390911690637b30fb3790611c9f9085906004016158c0565b602060405180830381865afa158015611cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce09190615928565b816001600160801b031610611d255760405162461bcd60e51b815260206004820152600b60248201526a696e76616c69642061726760a81b6044820152606401610b9d565b7f48b64378db8c62f5caa2374925f19177b79350106ba7458ef776d7b0a18bc3fd8282604051611d56929190615941565b60405180910390a180600783604051611d6f919061561f565b90815260405190819003602001902060090180546001600160801b03928316600160801b0292169190911790555050565b60606107e3600883604051611db5919061561f565b90815260200160405180910390206145e0565b33611dd1611ec0565b6001600160a01b031614611df75760405162461bcd60e51b8152600401610b9d9061581a565b611e0260028261347c565b61117d5760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a361117b6002826145ed565b33611e50611ec0565b6001600160a01b031614611e765760405162461bcd60e51b8152600401610b9d9061581a565b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b6001546001600160a01b031690565b600260005403611ef15760405162461bcd60e51b8152600401610b9d90615727565b6002600055611eff336110cc565b80611f1757508051608001516001600160a01b031633145b611f335760405162461bcd60e51b8152600401610b9d9061587e565b600554604051632f4176d160e21b81526001600160a01b039091169063bd05db4490611f63908490600401614f47565b60006040518083038186803b158015611f7b57600080fd5b505afa158015611f8f573d6000803e3d6000fd5b50505050600682604051611fa3919061561f565b9081526040519081900360200190205460ff1661232d5780600783604051611fcb919061561f565b90815260408051602092819003830190208351805182546001600160a01b0319166001600160a01b039182161783559381015160018301559182015160028083019190915560608301516003830155608083015160048301805460a0860151929096166001600160e01b031990961695909517600160a01b6001600160401b03928316021790945560c083015160058301805460e0860151610100808801519489166001600160801b031990931692909217600160401b91909816029690961760ff60801b1916600160801b9215159290920291909117905561012083015160068301556101408301516007830180546101608601516101808701516101a088015161ffff1990931694151561ff001916949094179015159097029690961763ffff00001916620100009215159290920263ff000000191691909117630100000095151595909502949094178085556101c08401519294859392909164ff00000000191690600160201b90849081111561214757612147614d26565b02179055506101e091909101516008909101556020828101516040808501516001600160801b03928316600160801b9184168202176009860155606080870151600a870180546080808b015160a0808d015160c08e015160e08f015197909b166001600160a01b03199586161763ffffffff9384169099029890981767ffffffffffffffff60a01b1916600160a01b988316890263ffffffff60c01b191617600160c01b9a83169a909a02999099176001600160e01b0316600160e01b919095160293909317909155610100890151600b8901805483166001600160a01b03928316179055610120909901518051600c8a0180548416918c1691909117905596870151600d890180548316918b1691909117905586850151600e89018054909216908a1617905590850151600f9096018054918601519590940151959096166001600160b01b03199096169590951761ffff9384169095029490941761ffff60b01b1916600160b01b9290931691909102919091179055516001906006906122d090859061561f565b908152604051908190036020018120805492151560ff19909316929092179091557f46fdb56149abcbd8b12b678efa8d730a35cd5ff17fe865c2a8de896ce412140c90612320908490849061596b565b60405180910390a16126bb565b60068260405161233d919061561f565b9081526040519081900360200190205460ff16156126bb5742816080015163ffffffff161161237e5760405162461bcd60e51b8152600401610b9d906159b8565b8060078360405161238f919061561f565b90815260408051602092819003830190208351805182546001600160a01b0319166001600160a01b039182161783559381015160018301559182015160028083019190915560608301516003830155608083015160048301805460a0860151929096166001600160e01b031990961695909517600160a01b6001600160401b03928316021790945560c083015160058301805460e0860151610100808801519489166001600160801b031990931692909217600160401b91909816029690961760ff60801b1916600160801b9215159290920291909117905561012083015160068301556101408301516007830180546101608601516101808701516101a088015161ffff1990931694151561ff001916949094179015159097029690961763ffff00001916620100009215159290920263ff000000191691909117630100000095151595909502949094178085556101c08401519294859392909164ff00000000191690600160201b90849081111561250b5761250b614d26565b02179055506101e091909101516008909101556020828101516040808501516001600160801b03928316600160801b9184168202176009860155606080870151600a870180546080808b015160a0808d015160c08e015160e08f015197909b166001600160a01b03199586161763ffffffff9384169099029890981767ffffffffffffffff60a01b1916600160a01b988316890263ffffffff60c01b191617600160c01b9a83169a909a02999099176001600160e01b0316600160e01b919095160293909317909155610100890151600b8901805483166001600160a01b03928316179055610120909901518051600c8a0180548416918c1691909117905596870151600d890180548316918b1691909117905586850151600e89018054909216908a1617905590850151600f9096018054918601519590940151959096166001600160b01b03199096169590951761ffff9384169095029490941761ffff60b01b1916600160b01b9290931691909102919091179055517f46fdb56149abcbd8b12b678efa8d730a35cd5ff17fe865c2a8de896ce412140c906126b290849084906159de565b60405180910390a15b50506001600055565b6002600054036126e65760405162461bcd60e51b8152600401610b9d90615727565b60026000556040516006906126fc90899061561f565b9081526040519081900360200190205460ff1661272b5760405162461bcd60e51b8152600401610b9d9061567f565b600060078860405161273d919061561f565b9081526040805191829003602090810183206102008401835280546001600160a01b0390811685526001820154928501929092526002808201549385019390935260038101546060850152600481015491821660808501526001600160401b03600160a01b909204821660a0850152600581015480831660c0860152600160401b810490921660e085015260ff600160801b9092048216151561010080860191909152600682015461012086015260078201548084161515610140870152908104831615156101608601526201000081048316151561018086015263010000008104831615156101a086015290926101c0850192600160201b9092049091169081111561284c5761284c614d26565b600281111561285d5761285d614d26565b8152602001600882015481525050905060006001600160a01b0316600789604051612888919061561f565b908152604051908190036020019020600b01546001600160a01b0316036128f4576128b38688615807565b34146128f45760405162461bcd60e51b815260206004820152601060248201526f0d2dce6eaccccd2c6d2cadce8408aa8960831b6044820152606401610b9d565b6005546040805160c08101825289815260208101899052808201889052606081018790526080810186905260a081018590529051633a33fe3160e11b815260009283926001600160a01b0390911691637467fc6291612959918e913391600401615a97565b6040805180830381865afa158015612975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129999190615788565b6040519093509091506000906007906129b3908d9061561f565b908152604051908190036020019020600b01546001600160a01b03161480156129e5575060006129e38383615807565b115b15612a75576000336129f78484615807565b60408051600081526020810191829052612a109161561f565b60006040518083038185875af1925050503d8060008114612a4d576040519150601f19603f3d011682016040523d82523d6000602084013e612a52565b606091505b5050905080612a735760405162461bcd60e51b8152600401610b9d90615904565b505b612a7f818a615b4f565b9850612a8b8289615b4f565b9750612aa13360088c604051610d20919061561f565b612ad057612ace3360088c604051612ab9919061561f565b908152604051908190036020019020906145ed565b505b826101a0015115612b16576001600b8560600151604051612af1919061561f565b908152604051908190036020019020805491151560ff19909216919091179055612b58565b835161ffff1615612b58576001600b8560600151604051612b37919061561f565b908152604051908190036020019020805491151560ff199092169190911790555b60006001846101c001516002811115612b7357612b73614d26565b14612b7e5787612b80565b865b90508361018001518015612b9d5750846000015161ffff16612710145b15612bde578060098c604051612bb3919061561f565b90815260200160405180910390206003016000828254612bd39190615807565b90915550612dd19050565b8361018001518015612bf45750845161ffff1615155b15612cc057600a8b604051612c09919061561f565b90815260408051918290036020908101832033600090815290825291822060030180546001810182559083529120018b9055600a90612c49908d9061561f565b90815260408051918290036020908101832033600090815290825291822060050180546001810182559083529120018a9055600a90612c89908d9061561f565b9081526040805160209281900383019020336000908152908352908120600401805460018101825590825291902001819055612dd1565b845161ffff161580612cd55750836101800151155b15612dd1578060098c604051612ceb919061561f565b90815260200160405180910390206004016000828254612d0b9190615807565b9091555050604051600a90612d21908d9061561f565b90815260408051918290036020908101832033600090815290825291822080546001810182559083529120018b9055600a90612d5e908d9061561f565b90815260408051918290036020908101832033600090815290825291822060020180546001810182559083529120018a9055600a90612d9e908d9061561f565b90815260408051602092819003830190203360009081529083529081206001908101805491820181558252919020018190555b80600a8c604051612de2919061561f565b9081526040805160209281900383019020336000908152925281206006018054909190612e10908490615807565b925050819055508060098c604051612e28919061561f565b90815260200160405180910390206002016000828254612e489190615807565b9091555050600554604051637b30fb3760e01b81526001600160a01b0390911690637b30fb3790612e7d908e906004016158c0565b602060405180830381865afa158015612e9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ebe9190615928565b91508160098c604051612ed1919061561f565b90815260405190819003602001812091909155600990612ef2908d9061561f565b908152602001604051809103902060010154600003612f3457836020015160098c604051612f20919061561f565b908152604051908190036020019020600101555b60006001600160a01b031660078c604051612f4f919061561f565b908152604051908190036020019020600b01546001600160a01b031614612fbe5783610160015115612fbe57612fbe3330612f8a8c8e615807565b60078f604051612f9a919061561f565b908152604051908190036020019020600b01546001600160a01b0316929190614602565b836101600151613002576130028b8b8b60078f604051612fde919061561f565b908152604051908190036020019020600b01546001600160a01b03163360006135a8565b606084610140015115613069576130438c338b6001896101c00151600281111561302e5761302e614d26565b1461303d578860600151613941565b8b613941565b60098e604051613053919061561f565b9081526040519081900360200190206001015590505b7fe522439914124e6027e1ac135772716d749ed8857d1c8a9cbd2c5d294088b8908c8a8a868f8f8c6040015133896040516130ac99989796959493929190615b62565b60405180910390a15050600160005550505050505050505050565b336130d0611ec0565b6001600160a01b031614806130eb57506130eb60023361347c565b6131075760405162461bcd60e51b8152600401610b9d9061563b565b600681604051613117919061561f565b9081526040519081900360200190205460ff166131465760405162461bcd60e51b8152600401610b9d9061567f565b600981604051613156919061561f565b9081526040519081900360200190206005015460ff16156131895760405162461bcd60e51b8152600401610b9d906156ac565b600981604051613199919061561f565b90815260405190819003602001902054156131c65760405162461bcd60e51b8152600401610b9d906159b8565b6007816040516131d6919061561f565b90815260405190819003602001812080546001600160a01b0319908116825560006001830181905560028301819055600383018190556004830180546001600160e01b03191690556005830180546001600160881b03191690556006830181905560078301805464ffffffffff191690556008830181905560098301819055600a830155600b8201805482169055600c8201805482169055600d8201805482169055600e820180549091169055600f0180546001600160c01b03191690557f69b2e335395b4abc91c9fba47beb681d9191216ff34810e7515ce98556c74b79906132c19083906158c0565b60405180910390a150565b6133106040518060e0016040528060008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000151581525090565b600982604051613320919061561f565b90815260408051918290036020908101832060e0840183528054845260018101549184019190915260028101549183019190915260038101546060830152600481015460808301526005015460ff808216151560a084015261010090910416151560c082015292915050565b33613395611ec0565b6001600160a01b0316146133bb5760405162461bcd60e51b8152600401610b9d9061581a565b6001600160a01b0381166134205760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b9d565b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b60006001600160a01b03841661354157604080516000815260208101918290526001600160a01b0387169185916134d79161561f565b60006040518083038185875af1925050503d8060008114613514576040519150601f19603f3d011682016040523d82523d6000602084013e613519565b606091505b5050809150508061353c5760405162461bcd60e51b8152600401610b9d90615904565b613575565b811561355b5761353c6001600160a01b0385168685614585565b81613575576135756001600160a01b038516878786614602565b505050505050565b600061349a836001600160a01b038416614629565b60006107e3825490565b600061349a838361471c565b60006007876040516135ba919061561f565b908152604080516020928190038301812060c082018352600c8101546001600160a01b039081168352600d8201548116948301859052600e820154811693830193909352600f01549182166060820152600160a01b820461ffff9081166080830152600160b01b90920490911660a0820152915060009061363f9085908789876134a1565b60608201516001600160a01b031615801590613663575060008260a0015161ffff16115b156136a6576136a6848360600151876127108660a0015161ffff168c6136899190615bdc565b6136939190615bf3565b61369d9086615807565b945084876134a1565b60408201516001600160a01b0316158015906136ca57506000826080015161ffff16115b1561372d57612710826080015161ffff16886136e69190615bdc565b6136f09190615bf3565b6136fa9082615807565b905061372d84836040015187612710866080015161ffff168c61371d9190615bdc565b6137279190615bf3565b876134a1565b6137378188615b4f565b6004549097506001600160a01b0316156139265760045460405160009182916001600160a01b03909116906333ff942290600790613776908e9061561f565b908152604051908190036020018120546001600160e01b031960e084901b1682526001600160a01b03166004820152602401600060405180830381865afa1580156137c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526137ed9190810190615c7b565b9150915060005b82518110156139225760006127108b8484815181106138155761381561584f565b60200260200101516138279190615bdc565b6138319190615bf3565b9050808b101561386f5760405162461bcd60e51b81526020600482015260096024820152681a5b9cdbdb1d995b9d60ba1b6044820152606401610b9d565b7f033f17ae2b7a9ab7cd350d5a345cc0b666e599db545d85e2f0eab9cb10264d2060078d6040516138a0919061561f565b9081526040519081900360200190205485516001600160a01b03909116908690859081106138d0576138d061584f565b6020026020010151836040516138e893929190615d3f565b60405180910390a1613916338584815181106139065761390661584f565b60200260200101518b848b6134a1565b909903986001016137f4565b5050505b613937848360000151878a876134a1565b5050505050505050565b60606000836001600160401b0381111561395d5761395d614a3b565b604051908082528060200260200182016040528015613986578160200160208202803683370190505b509150600986604051613999919061561f565b908152602001604051809103902060010154905060006007876040516139bf919061561f565b9081526040805191829003602090810183206102008401835280546001600160a01b0390811685526001820154928501929092526002808201549385019390935260038101546060850152600481015491821660808501526001600160401b03600160a01b909204821660a0850152600581015480831660c0860152600160401b810490921660e085015260ff600160801b9092048216151561010080860191909152600682015461012086015260078201548084161515610140870152908104831615156101608601526201000081048316151561018086015263010000008104831615156101a086015290926101c0850192600160201b90920490911690811115613ace57613ace614d26565b6002811115613adf57613adf614d26565b81526020016008820154815250509050806101000151613fdb5760005b85811015613fd45781516040516301ffc9a760e01b81526001600160a01b03909116906301ffc9a790613b3a906380ac58cd60e01b90600401615d63565b602060405180830381865afa158015613b57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b7b9190615d78565b15613cde575b81608001516001600160a01b031682600001516001600160a01b0316636352211e856040518263ffffffff1660e01b8152600401613bc191815260200190565b602060405180830381865afa158015613bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c029190615d95565b6001600160a01b031614613c46578282604001511015613c345760405162461bcd60e51b8152600401610b9d90615db2565b613c3f600184615807565b9250613b81565b81516080830151604051632142170760e11b81526001600160a01b03909216916342842e0e91613c7c918b908890600401615d3f565b600060405180830381600087803b158015613c9657600080fd5b505af1158015613caa573d6000803e3d6000fd5b5050505082848281518110613cc157613cc161584f565b6020908102919091010152613cd7600184615807565b9250613fc2565b81516040516301ffc9a760e01b81526001600160a01b03909116906301ffc9a790613d1490636cdb3d1360e11b90600401615d63565b602060405180830381865afa158015613d31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d559190615d78565b15613fc2576002826101c001516002811115613d7357613d73614d26565b03613e61575b81516080830151604051627eeac760e11b815287926001600160a01b03169162fdd58e91613dac91908890600401615ddc565b602060405180830381865afa158015613dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ded9190615928565b1015613e29578282604001511015613e175760405162461bcd60e51b8152600401610b9d90615db2565b613e22600184615807565b9250613d79565b81516080830151604051637921219560e11b81526001600160a01b039092169163f242432a91613c7c918b9088908b90600401615df5565b6001826101c001516002811115613e7a57613e7a614d26565b03613fc25781516080830151604051627eeac760e11b815287926001600160a01b03169162fdd58e91613eb291908890600401615ddc565b602060405180830381865afa158015613ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ef39190615928565b11613f385760405162461bcd60e51b8152602060048201526015602482015274696e73756666696369656e74207175616e7469747960581b6044820152606401610b9d565b81516080830151604051637921219560e11b81526001600160a01b039092169163f242432a91613f70918b9088908b90600401615df5565b600060405180830381600087803b158015613f8a57600080fd5b505af1158015613f9e573d6000803e3d6000fd5b5050505082848281518110613fb557613fb561584f565b6020026020010181815250505b80613fcc81615865565b915050613afc565b505061457c565b8061010001511561457a5780516040516301ffc9a760e01b81526001600160a01b03909116906301ffc9a79061401c906380ac58cd60e01b90600401615d63565b602060405180830381865afa158015614039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061405d9190615d78565b156140e657805160405163e00aab4b60e01b81526001600160a01b03888116600483015261ffff881660248301529091169063e00aab4b906044016000604051808303816000875af11580156140b7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140df9190810190615e38565b9250614461565b80516040516301ffc9a760e01b81526001600160a01b03909116906301ffc9a79061411c90636cdb3d1360e11b90600401615d63565b602060405180830381865afa158015614139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061415d9190615d78565b1561446157604080516001808252818301909252600091602080830190803683370190505090506000866001600160401b0381111561419e5761419e614a3b565b6040519080825280602002602001820160405280156141c7578160200160208202803683370190505b509050606088836000815181106141e0576141e061584f565b6001600160a01b03909216602092830291909101909101526002846101c00151600281111561421157614211614d26565b036142d35760005b8881101561425157878382815181106142345761423461584f565b60209081029190910101528061424981615865565b915050614219565b508351604051634637423960e11b81526001600160a01b0390911690638c6e84729061428590869086908690600401615e6c565b6000604051808303816000875af11580156142a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526142cc9190810190615e38565b955061445d565b6001846101c0015160028111156142ec576142ec614d26565b0361445d5786826000815181106143055761430561584f565b602002602001018181525050846000036143d8578351604051634637423960e11b81526001600160a01b0390911690638c6e84729061434c90869086908690600401615e6c565b6000604051808303816000875af115801561436b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526143939190810190615e38565b9550856000815181106143a8576143a861584f565b602002602001015160098b6040516143c0919061561f565b9081526040519081900360200190206001015561445d565b84866000815181106143ec576143ec61584f565b602090810291909101015283516040516339b2213760e21b81526001600160a01b039091169063e6c884dc9061442a9086908a908790600401615ef3565b600060405180830381600087803b15801561444457600080fd5b505af1158015614458573d6000803e3d6000fd5b505050505b5050505b806101200151600019146145485780610120015183600185516144849190615b4f565b815181106144945761449461584f565b6020026020010151106144dc5760016009886040516144b3919061561f565b90815260405190819003602001902060050180549115156101000261ff00199092169190911790555b80610120015183600185516144f19190615b4f565b815181106145015761450161584f565b602002602001015111156145485760405162461bcd60e51b815260206004820152600e60248201526d1c995858da1959081b585e081a5960921b6044820152606401610b9d565b8283600185516145589190615b4f565b815181106145685761456861584f565b6020026020010151925092505061457c565b505b94509492505050565b6145db8363a9059cbb60e01b84846040516024016145a4929190615ddc565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614746565b505050565b6060600061349a83614818565b600061349a836001600160a01b038416614874565b614623846323b872dd60e01b8585856040516024016145a493929190615d3f565b50505050565b6000818152600183016020526040812054801561471257600061464d600183615b4f565b855490915060009061466190600190615b4f565b90508181146146c65760008660000182815481106146815761468161584f565b90600052602060002001549050808760000184815481106146a4576146a461584f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806146d7576146d7615f36565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506107e3565b60009150506107e3565b60008260000182815481106147335761473361584f565b9060005260206000200154905092915050565b600061479b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166148c39092919063ffffffff16565b8051909150156145db57808060200190518101906147b99190615d78565b6145db5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b9d565b60608160000180548060200260200160405190810160405280929190818152602001828054801561486857602002820191906000526020600020905b815481526020019060010190808311614854575b50505050509050919050565b60008181526001830160205260408120546148bb575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556107e3565b5060006107e3565b60606148d284846000856148da565b949350505050565b60608247101561493b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610b9d565b843b6149895760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b9d565b600080866001600160a01b031685876040516149a5919061561f565b60006040518083038185875af1925050503d80600081146149e2576040519150601f19603f3d011682016040523d82523d6000602084013e6149e7565b606091505b50915091506149f7828286614a02565b979650505050505050565b60608315614a1157508161349a565b825115614a215782518084602001fd5b8160405162461bcd60e51b8152600401610b9d91906158c0565b634e487b7160e01b600052604160045260246000fd5b60405161020081016001600160401b0381118282101715614a7457614a74614a3b565b60405290565b60405161014081016001600160401b0381118282101715614a7457614a74614a3b565b604051601f8201601f191681016001600160401b0381118282101715614ac557614ac5614a3b565b604052919050565b600082601f830112614ade57600080fd5b81356001600160401b03811115614af757614af7614a3b565b614b0a601f8201601f1916602001614a9d565b818152846020838601011115614b1f57600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b038116811461117d57600080fd5b8035614b5c81614b3c565b919050565b60008060408385031215614b7457600080fd5b82356001600160401b03811115614b8a57600080fd5b614b9685828601614acd565b9250506020830135614ba781614b3c565b809150509250929050565b600081518084526020808501945080840160005b83811015614be257815187529582019590820190600101614bc6565b509495945050505050565b6020815260008251610100806020850152614c0c610120850183614bb2565b91506020850151601f1980868503016040870152614c2a8483614bb2565b93506040870151915080868503016060870152614c478483614bb2565b93506060870151915080868503016080870152614c648483614bb2565b935060808701519150808685030160a0870152614c818483614bb2565b935060a08701519150808685030160c087015250614c9f8382614bb2565b92505060c085015160e085015260e0850151614cbe8286018215159052565b5090949350505050565b600060208284031215614cda57600080fd5b81356001600160e01b03198116811461349a57600080fd5b600060208284031215614d0457600080fd5b81356001600160401b03811115614d1a57600080fd5b6148d284828501614acd565b634e487b7160e01b600052602160045260246000fd5b60038110614d5a57634e487b7160e01b600052602160045260246000fd5b9052565b80516001600160a01b031682526020810151602083015260408101516040830152606081015160608301526080810151614da360808401826001600160a01b03169052565b5060a0810151614dbe60a08401826001600160401b03169052565b5060c0810151614dd960c08401826001600160401b03169052565b5060e0810151614df460e08401826001600160401b03169052565b506101008181015115159083015261012080820151908301526101408082015115159083015261016080820151151590830152610180808201511515908301526101a0808201511515908301526101c080820151614e5482850182614d3c565b50506101e090810151910152565b614e6d828251614d5e565b6020818101516001600160801b03908116610200850152604080840151821661022086015260608085015190921661024086015260808085015163ffffffff90811661026088015260a080870151821661028089015260c087015182166102a089015260e08701519091166102c08801526101008601516001600160a01b039081166102e089015261012090960151805187166103008901529485015186166103208801529184015185166103408701529183015190931661036085015281015161ffff908116610380850152910151166103a090910152565b6103c081016107e38284614e62565b803563ffffffff81168114614b5c57600080fd5b60008060408385031215614f7d57600080fd5b82356001600160401b03811115614f9357600080fd5b614f9f85828601614acd565b925050614fae60208401614f56565b90509250929050565b600060208284031215614fc957600080fd5b813561349a81614b3c565b600081518084526020808501945080840160005b83811015614be25781516001600160a01b031687529582019590820190600101614fe8565b60208152600061349a6020830184614fd4565b6000806040838503121561503357600080fd5b823561503e81614b3c565b91506020830135614ba781614b3c565b801515811461117d57600080fd5b8035614b5c8161504e565b6000806040838503121561507a57600080fd5b82356001600160401b0381111561509057600080fd5b61509c85828601614acd565b9250506020830135614ba78161504e565b80356001600160801b0381168114614b5c57600080fd5b600080604083850312156150d757600080fd5b82356001600160401b038111156150ed57600080fd5b6150f985828601614acd565b925050614fae602084016150ad565b80356001600160401b0381168114614b5c57600080fd5b803560038110614b5c57600080fd5b6000610200828403121561514157600080fd5b615149614a51565b905061515482614b51565b815260208201356020820152604082013560408201526060820135606082015261518060808301614b51565b608082015261519160a08301615108565b60a08201526151a260c08301615108565b60c08201526151b360e08301615108565b60e08201526101006151c681840161505c565b9082015261012082810135908201526101406151e381840161505c565b908201526101606151f583820161505c565b9082015261018061520783820161505c565b908201526101a061521983820161505c565b908201526101c061522b83820161511f565b81830152506101e080830135818301525092915050565b803561ffff81168114614b5c57600080fd5b600060c0828403121561526657600080fd5b60405160c081018181106001600160401b038211171561528857615288614a3b565b604052905080823561529981614b3c565b815260208301356152a981614b3c565b602082015260408301356152bc81614b3c565b604082015260608301356152cf81614b3c565b60608201526152e060808401615242565b60808201526152f160a08401615242565b60a08201525092915050565b6000808284036103e081121561531257600080fd5b83356001600160401b0381111561532857600080fd5b61533486828701614acd565b9350506103c0601f198201121561534a57600080fd5b50615353614a7a565b615360856020860161512e565b815261536f61022085016150ad565b602082015261538161024085016150ad565b604082015261539361026085016150ad565b60608201526153a56102808501614f56565b60808201526153b76102a08501614f56565b60a08201526153c96102c08501614f56565b60c08201526153db6102e08501614f56565b60e08201526153ed6103008501614b51565b610100820152615401856103208601615254565b610120820152809150509250929050565b60006001600160401b0382111561542b5761542b614a3b565b5060051b60200190565b600060a0828403121561544757600080fd5b60405160a081016001600160401b03828210818311171561546a5761546a614a3b565b8160405282935061547a85615242565b835261548860208601614f56565b602084015260408501359150808211156154a157600080fd5b6154ad86838701614acd565b604084015260608501359150808211156154c657600080fd5b506154d385828601614acd565b60608301525060808301356154e781614b3c565b6080919091015292915050565b600080600080600080600060e0888a03121561550f57600080fd5b87356001600160401b038082111561552657600080fd5b6155328b838c01614acd565b985060209150818a0135975060408a0135965060608a0135955060808a0135945060a08a01358181111561556557600080fd5b8a01601f81018c1361557657600080fd5b803561558961558482615412565b614a9d565b81815260059190911b8201840190848101908e8311156155a857600080fd5b928501925b828410156155c6578335825292850192908501906155ad565b965050505060c08a01359150808211156155df57600080fd5b506155ec8a828b01615435565b91505092959891949750929550565b60005b838110156156165781810151838201526020016155fe565b50506000910152565b600082516156318184602087016155fb565b9190910192915050565b60208082526024908201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616040820152633236b4b760e11b606082015260800190565b6020808252601390820152723ab739bab83837b93a32b21030bab1ba34b7b760691b604082015260600190565b6020808252600d908201526c185b1c9958591e48195b991959609a1b604082015260600190565b600081518084526156eb8160208601602086016155fb565b601f01601f19169290920160200192915050565b60408152600061571260408301856156d3565b905063ffffffff831660208301529392505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60408152600061577160408301856156d3565b905060018060a01b03831660208301529392505050565b6000806040838503121561579b57600080fd5b505080516020909101519092909150565b60a0815260006157bf60a08301886156d3565b6001600160a01b0396871660208401526040830195909552506060810192909252909216608090920191909152919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156107e3576107e36157f1565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060018201615877576158776157f1565b5060010190565b60208082526022908201527f616c6c6f7765643a206f6e6c792061646d696e206f7220746f6b656e206f776e60408201526132b960f11b606082015260800190565b60208152600061349a60208301846156d3565b6080815260006158e660808301876156d3565b85602084015284604084015282810360608401526149f78185614bb2565b6020808252600a90820152691d1e1b8819985a5b195960b21b604082015260600190565b60006020828403121561593a57600080fd5b5051919050565b60408152600061595460408301856156d3565b905060018060801b03831660208301529392505050565b600061040080835261597f818401866156d3565b905061598e6020840185614e62565b8281036103e084015260068152651b1a5cdd195960d21b6020820152604081019150509392505050565b6020808252600c908201526b1cd85b19481cdd185c9d195960a21b604082015260600190565b60006104008083526159f2818401866156d3565b9050615a016020840185614e62565b8281036103e084015260078152661d5c19185d195960ca1b6020820152604081019150509392505050565b61ffff815116825263ffffffff60208201511660208301526000604082015160a06040850152615a5f60a08501826156d3565b905060608301518482036060860152615a7882826156d3565b6080948501516001600160a01b03169590940194909452509092915050565b606081526000615aaa60608301866156d3565b602060018060a01b03861681850152838203604085015260c082018551835281860151828401526040860151604084015260608601516060840152608086015160c0608085015281815180845260e0860191508483019350600092505b80831015615b275783518252928401926001929092019190840190615b07565b5060a0880151935084810360a0860152615b418185615a2c565b9a9950505050505050505050565b818103818111156107e3576107e36157f1565b6000610120808352615b768184018d6156d3565b90508a60208401528960408401528860608401528760808401528660a084015282810360c0840152615ba881876156d3565b6001600160a01b03861660e08501528381036101008501529050615bcc8185614bb2565b9c9b505050505050505050505050565b80820281158282048414176107e3576107e36157f1565b600082615c1057634e487b7160e01b600052601260045260246000fd5b500490565b600082601f830112615c2657600080fd5b81516020615c3661558483615412565b82815260059290921b84018101918181019086841115615c5557600080fd5b8286015b84811015615c705780518352918301918301615c59565b509695505050505050565b60008060408385031215615c8e57600080fd5b82516001600160401b0380821115615ca557600080fd5b818501915085601f830112615cb957600080fd5b81516020615cc961558483615412565b82815260059290921b84018101918181019089841115615ce857600080fd5b948201945b83861015615d0f578551615d0081614b3c565b82529482019490820190615ced565b91880151919650909350505080821115615d2857600080fd5b50615d3585828601615c15565b9150509250929050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160e01b031991909116815260200190565b600060208284031215615d8a57600080fd5b815161349a8161504e565b600060208284031215615da757600080fd5b815161349a81614b3c565b60208082526010908201526f3737ba1032b737bab3b4103a37b5b2b760811b604082015260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260029082015261060f60f31b60c082015260e00190565b600060208284031215615e4a57600080fd5b81516001600160401b03811115615e6057600080fd5b6148d284828501615c15565b606081526000615e7f6060830186614fd4565b602083820381850152615e928287614bb2565b915083820360408501528185518084528284019150828160051b85010183880160005b83811015615ee357601f19878403018552615ed18383516156d3565b94860194925090850190600101615eb5565b50909a9950505050505050505050565b606081526000615f066060830186614fd4565b8281036020840152615f188186614bb2565b90508281036040840152615f2c8185614bb2565b9695505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d8be8d571f336ade3d1b6c9e8b3ce7907b34278fcd07cc9098a3ba76ee9b9a3464736f6c634300081100330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d8c3d2ccdcd1f1a4f91e370b9dbef02be2364a65
Deployed Bytecode
0x6080604052600436106101565760003560e01c806358e656e4116100c157806395318d861161007a57806395318d86146103ef578063a628ec5d1461040f578063b60e7a3b14610422578063b7b429aa14610442578063d78ccb8b146104bc578063da20872a146104f7578063f2fde38b1461051757600080fd5b806358e656e41461032a57806359bb679a14610365578063681569e9146103855780636d73e669146103a5578063715018a6146103c55780638da5cb5b146103da57600080fd5b806324d7806c1161011357806324d7806c146102685780632d3456701461028857806331ae450b146102a85780634970d03e146102ca57806350e58ea6146102ea57806351cff8d91461030a57600080fd5b8063015109451461015b57806301ffc9a7146101915780630397b87b146101c15780630a28e844146101ee5780631376789b146102105780631ae9cd9814610248575b600080fd5b34801561016757600080fd5b5061017b610176366004614b61565b610537565b6040516101889190614bed565b60405180910390f35b34801561019d57600080fd5b506101b16101ac366004614cc8565b6107e9565b6040519015158152602001610188565b3480156101cd57600080fd5b506101e16101dc366004614cf2565b61081e565b6040516101889190614f47565b3480156101fa57600080fd5b5061020e610209366004614f6a565b610b5d565b005b34801561021c57600080fd5b50600554610230906001600160a01b031681565b6040516001600160a01b039091168152602001610188565b34801561025457600080fd5b5061020e610263366004614b61565b610ca5565b34801561027457600080fd5b506101b1610283366004614fb7565b6110cc565b34801561029457600080fd5b5061020e6102a3366004614fb7565b6110fb565b3480156102b457600080fd5b506102bd611180565b604051610188919061500d565b3480156102d657600080fd5b5061020e6102e5366004615020565b61122e565b3480156102f657600080fd5b5061020e610305366004615067565b61132f565b34801561031657600080fd5b5061020e610325366004614fb7565b611a9c565b34801561033657600080fd5b506101b1610345366004614cf2565b805160208183018101805160068252928201919093012091525460ff1681565b34801561037157600080fd5b5061020e6103803660046150c4565b611bf0565b34801561039157600080fd5b506102bd6103a0366004614cf2565b611da0565b3480156103b157600080fd5b5061020e6103c0366004614fb7565b611dc8565b3480156103d157600080fd5b5061020e611e47565b3480156103e657600080fd5b50610230611ec0565b3480156103fb57600080fd5b5061020e61040a3660046152fd565b611ecf565b61020e61041d3660046154f4565b6126c4565b34801561042e57600080fd5b5061020e61043d366004614cf2565b6130c7565b34801561044e57600080fd5b5061046261045d366004614cf2565b6132cc565b6040516101889190600060e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a0830151151560a083015260c0830151151560c083015292915050565b3480156104c857600080fd5b506101b16104d7366004614cf2565b8051602081830181018051600b8252928201919093012091525460ff1681565b34801561050357600080fd5b50600454610230906001600160a01b031681565b34801561052357600080fd5b5061020e610532366004614fb7565b61338c565b610581604051806101000160405280606081526020016060815260200160608152602001606081526020016060815260200160608152602001600081526020016000151581525090565b600a83604051610591919061561f565b9081526040805191829003602090810183206001600160a01b038616600090815290825282902080546101209281028501830190935261010084018381529092849284919084018282801561060557602002820191906000526020600020905b8154815260200190600101908083116105f1575b505050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561065d57602002820191906000526020600020905b815481526020019060010190808311610649575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156106b557602002820191906000526020600020905b8154815260200190600101908083116106a1575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561070d57602002820191906000526020600020905b8154815260200190600101908083116106f9575b505050505081526020016004820180548060200260200160405190810160405280929190818152602001828054801561076557602002820191906000526020600020905b815481526020019060010190808311610751575b50505050508152602001600582018054806020026020016040519081016040528092919081815260200182805480156107bd57602002820191906000526020600020905b8154815260200190600101908083116107a9575b50505091835250506006820154602082015260079091015460ff16151560409091015290505b92915050565b60006001600160e01b03198216632a9f3abf60e11b14806107e357506301ffc9a760e01b6001600160e01b03198316146107e3565b604080516103408101825260006101408201818152610160830182905261018083018290526101a083018290526101c083018290526101e08301829052610200830182905261022083018290526102408301829052610260830182905261028083018290526102a083018290526102c083018290526102e0830182905261030083018290526103208301829052825260208083018290528284018290526060808401839052608080850184905260a080860185905260c080870186905260e08701869052610100870186905287519081018852858152938401859052958301849052908201839052810182905292830152610120810191909152600782604051610928919061561f565b90815260408051918290036020018220610340830190915280546001600160a01b039081166101408401908152600183015461016085015260028084015461018086015260038401546101a086015260048401549283166101c08601526001600160401b03600160a01b90930483166101e08601526005840154808416610200870152600160401b810490931661022086015260ff600160801b909304831615156102408601526006840154610260860152600784015480841615156102808701526101008104841615156102a0870152620100008104841615156102c087015263010000008104841615156102e087015285938592610300860192600160201b900490911690811115610a3e57610a3e614d26565b6002811115610a4f57610a4f614d26565b81526008919091015460209182015290825260098301546001600160801b0380821684840152600160801b918290048116604080860191909152600a86015491821660608087019190915263ffffffff9383048416608080880191909152600160a01b808504861660a0808a0191909152600160c01b8604871660c0808b0191909152600160e01b90960490961660e0890152600b8901546001600160a01b039081166101008a015284519586018552600c8a015481168652600d8a0154811697860197909752600e890154871693850193909352600f909701549485169083015261ffff908404811695820195909552600160b01b90920490931692810192909252610120015292915050565b33610b66611ec0565b6001600160a01b03161480610b815750610b8160023361347c565b610ba65760405162461bcd60e51b8152600401610b9d9061563b565b60405180910390fd5b600682604051610bb6919061561f565b9081526040519081900360200190205460ff16610be55760405162461bcd60e51b8152600401610b9d9061567f565b600982604051610bf5919061561f565b9081526040519081900360200190206005015460ff1615610c285760405162461bcd60e51b8152600401610b9d906156ac565b7f714e5610970185b216fa0c83f3d271b2598e7d7b69067891f2477008e82899e28282604051610c599291906156ff565b60405180910390a180600783604051610c72919061561f565b9081526020016040518091039020600a0160146101000a81548163ffffffff021916908363ffffffff1602179055505050565b600260005403610cc75760405162461bcd60e51b8152600401610b9d90615727565b6002600055604051600690610cdd90849061561f565b9081526040519081900360200190205460ff16610d0c5760405162461bcd60e51b8152600401610b9d9061567f565b610d3581600884604051610d20919061561f565b9081526040519081900360200190209061347c565b610d735760405162461bcd60e51b815260206004820152600f60248201526e696e76616c6964206164647265737360881b6044820152606401610b9d565b600982604051610d83919061561f565b9081526040519081900360200190206005015460ff1680610e6657506001600783604051610db1919061561f565b9081526040519081900360200190206007015460ff600160201b909104166002811115610de057610de0614d26565b14610e1e57600782604051610df5919061561f565b908152604051908190036020019020600401546001600160401b03600160a01b90910416610e42565b600782604051610e2e919061561f565b908152604051908190036020019020600301545b600983604051610e52919061561f565b908152602001604051809103902060020154145b610e9e5760405162461bcd60e51b81526020600482015260096024820152681b9bdd08195b99195960ba1b6044820152606401610b9d565b600a82604051610eae919061561f565b90815260408051602092819003830190206001600160a01b0384166000908152925290206007015460ff1615610f185760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b6044820152606401610b9d565b60055460405163d8130ec960e01b815260009182916001600160a01b039091169063d8130ec990610f4f908790879060040161575e565b6040805180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f9190615788565b909250905081610fcc5760405162461bcd60e51b81526020600482015260086024820152676e6f20636c61696d60c01b6044820152606401610b9d565b7f265be343ba17e4fb0f7aa786f7b36cfd1bd54098b49d11c302d5e2c267e4e35384848484600789604051611001919061561f565b908152604051908190036020018120600b015461102d95949392916001600160a01b03909116906157ac565b60405180910390a16001600a85604051611047919061561f565b90815260408051602092819003830181206001600160a01b0388166000908152935291206007908101805460ff1916931515939093179092556110c191339186919061109490899061561f565b908152604051908190036020019020600b01546001600160a01b03166110ba8587615807565b60016134a1565b505060016000555050565b6000816001600160a01b03166110e0611ec0565b6001600160a01b031614806107e357506107e360028361347c565b33611104611ec0565b6001600160a01b03161461112a5760405162461bcd60e51b8152600401610b9d9061581a565b61113560028261347c565b1561117d5760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a361117b60028261357d565b505b50565b606061118c6002613592565b6001600160401b038111156111a3576111a3614a3b565b6040519080825280602002602001820160405280156111cc578160200160208202803683370190505b50905060005b6111dc6002613592565b81101561122a576111ee60028261359c565b8282815181106112005761120061584f565b6001600160a01b03909216602092830291909101909101528061122281615865565b9150506111d2565b5090565b33611237611ec0565b6001600160a01b03161480611252575061125260023361347c565b61126e5760405162461bcd60e51b8152600401610b9d9061563b565b6001600160a01b0381166112be5760405162461bcd60e51b8152602060048201526017602482015276496e76616c69642064757463685574696c69747941726760481b6044820152606401610b9d565b604080516001600160a01b038084168252841660208201527f88bd3dbca0ee348f905e71c0d342bb50b637a5044709b0c4e0ee0f3672711fb0910160405180910390a1600480546001600160a01b039384166001600160a01b03199182161790915560058054929093169116179055565b6002600054036113515760405162461bcd60e51b8152600401610b9d90615727565b600260005560405160069061136790849061561f565b9081526040519081900360200190205460ff166113965760405162461bcd60e51b8152600401610b9d9061567f565b60006007836040516113a8919061561f565b9081526040805191829003602090810183206102008401835280546001600160a01b0390811685526001820154928501929092526002808201549385019390935260038101546060850152600481015491821660808501526001600160401b03600160a01b909204821660a0850152600581015480831660c0860152600160401b810490921660e085015260ff600160801b9092048216151561010080860191909152600682015461012086015260078201548084161515610140870152908104831615156101608601526201000081048316151561018086015263010000008104831615156101a086015290926101c0850192600160201b909204909116908111156114b7576114b7614d26565b60028111156114c8576114c8614d26565b815260200160088201548152505090506000806114e4336110cc565b806114fb575060808301516001600160a01b031633145b6115175760405162461bcd60e51b8152600401610b9d9061587e565b42600786604051611528919061561f565b908152604051908190036020019020600a015463ffffffff600160a01b909104161115806115ac57506001836101c00151600281111561156a5761156a614d26565b14611582578260a001516001600160401b0316611588565b82606001515b600986604051611598919061561f565b908152602001604051809103902060020154145b806115df57506009856040516115c2919061561f565b9081526040519081900360200190206005015460ff610100909104165b6116175760405162461bcd60e51b815260206004820152600960248201526818d85b89dd08195b9960ba1b6044820152606401610b9d565b600985604051611627919061561f565b9081526040519081900360200190206005015460ff161561165a5760405162461bcd60e51b8152600401610b9d906156ac565b600060098660405161166c919061561f565b908152602001604051809103902060020154116116b55760405162461bcd60e51b81526020600482015260076024820152666e6f206269647360c81b6044820152606401610b9d565b831561170e576007856040516116cb919061561f565b9081526040519081900360200181206009908101546001600160801b03600160801b90910416916116fd90889061561f565b908152604051908190036020019020555b826101600151156117cd576005546040516308fa05ed60e41b81526001600160a01b0390911690638fa05ed0906117499088906004016158c0565b60408051808303816000875af1158015611767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178b9190615788565b80925081935050506117cd8583836007896040516117a9919061561f565b908152604051908190036020019020600b01546001600160a01b03163360016135a8565b606060006009876040516117e1919061561f565b9081526020016040518091039020600201546001600160401b0381111561180a5761180a614a3b565b604051908082528060200260200182016040528015611833578160200160208202803683370190505b5090508461014001516119e0576000805b61186a60088a604051611857919061561f565b9081526020016040518091039020613592565b8110156119dd57600061189c8260088c604051611887919061561f565b9081526040519081900360200190209061359c565b90506000600a8b6040516118b0919061561f565b90815260408051602092819003830190206001600160a01b03851660009081529252812060060154915060018a6101c0015160028111156118f3576118f3614d26565b146118fe5781611901565b60015b9050600060018b6101c00151600281111561191e5761191e614d26565b1461192d578a6060015161192f565b825b905061193d8d858484613941565b60098f60405161194d919061561f565b90815260405190819003602001902060010155975060005b88518110156119c5578881815181106119805761198061584f565b602002602001015188888151811061199a5761199a61584f565b6020908102919091010152866119af81615865565b97505080806119bd90615865565b915050611965565b505050505080806119d590615865565b915050611844565b50505b7fea6186ac627a0a0d08856980003659f2072d5606356dd0876c1f8adf32db9eea87600989604051611a12919061561f565b90815260200160405180910390206002015460098a604051611a34919061561f565b90815260405190819003602001812054611a5193929186906158d3565b60405180910390a16001600988604051611a6b919061561f565b908152604051908190036020019020600501805491151560ff19909216919091179055505060016000555050505050565b33611aa5611ec0565b6001600160a01b031614611acb5760405162461bcd60e51b8152600401610b9d9061581a565b60006001600160a01b038216611b62576040805160008152602081019182905233914791611af89161561f565b60006040518083038185875af1925050503d8060008114611b35576040519150601f19603f3d011682016040523d82523d6000602084013e611b3a565b606091505b50508091505080611b5d5760405162461bcd60e51b8152600401610b9d90615904565b61117b565b6001600160a01b0382161561117b576040516370a0823160e01b815230600482015261117b9033906001600160a01b038516906370a0823190602401602060405180830381865afa158015611bbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bdf9190615928565b6001600160a01b0385169190614585565b33611bf9611ec0565b6001600160a01b03161480611c145750611c1460023361347c565b611c305760405162461bcd60e51b8152600401610b9d9061563b565b600682604051611c40919061561f565b9081526040519081900360200190205460ff16611c6f5760405162461bcd60e51b8152600401610b9d9061567f565b600554604051637b30fb3760e01b81526001600160a01b0390911690637b30fb3790611c9f9085906004016158c0565b602060405180830381865afa158015611cbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ce09190615928565b816001600160801b031610611d255760405162461bcd60e51b815260206004820152600b60248201526a696e76616c69642061726760a81b6044820152606401610b9d565b7f48b64378db8c62f5caa2374925f19177b79350106ba7458ef776d7b0a18bc3fd8282604051611d56929190615941565b60405180910390a180600783604051611d6f919061561f565b90815260405190819003602001902060090180546001600160801b03928316600160801b0292169190911790555050565b60606107e3600883604051611db5919061561f565b90815260200160405180910390206145e0565b33611dd1611ec0565b6001600160a01b031614611df75760405162461bcd60e51b8152600401610b9d9061581a565b611e0260028261347c565b61117d5760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a361117b6002826145ed565b33611e50611ec0565b6001600160a01b031614611e765760405162461bcd60e51b8152600401610b9d9061581a565b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b6001546001600160a01b031690565b600260005403611ef15760405162461bcd60e51b8152600401610b9d90615727565b6002600055611eff336110cc565b80611f1757508051608001516001600160a01b031633145b611f335760405162461bcd60e51b8152600401610b9d9061587e565b600554604051632f4176d160e21b81526001600160a01b039091169063bd05db4490611f63908490600401614f47565b60006040518083038186803b158015611f7b57600080fd5b505afa158015611f8f573d6000803e3d6000fd5b50505050600682604051611fa3919061561f565b9081526040519081900360200190205460ff1661232d5780600783604051611fcb919061561f565b90815260408051602092819003830190208351805182546001600160a01b0319166001600160a01b039182161783559381015160018301559182015160028083019190915560608301516003830155608083015160048301805460a0860151929096166001600160e01b031990961695909517600160a01b6001600160401b03928316021790945560c083015160058301805460e0860151610100808801519489166001600160801b031990931692909217600160401b91909816029690961760ff60801b1916600160801b9215159290920291909117905561012083015160068301556101408301516007830180546101608601516101808701516101a088015161ffff1990931694151561ff001916949094179015159097029690961763ffff00001916620100009215159290920263ff000000191691909117630100000095151595909502949094178085556101c08401519294859392909164ff00000000191690600160201b90849081111561214757612147614d26565b02179055506101e091909101516008909101556020828101516040808501516001600160801b03928316600160801b9184168202176009860155606080870151600a870180546080808b015160a0808d015160c08e015160e08f015197909b166001600160a01b03199586161763ffffffff9384169099029890981767ffffffffffffffff60a01b1916600160a01b988316890263ffffffff60c01b191617600160c01b9a83169a909a02999099176001600160e01b0316600160e01b919095160293909317909155610100890151600b8901805483166001600160a01b03928316179055610120909901518051600c8a0180548416918c1691909117905596870151600d890180548316918b1691909117905586850151600e89018054909216908a1617905590850151600f9096018054918601519590940151959096166001600160b01b03199096169590951761ffff9384169095029490941761ffff60b01b1916600160b01b9290931691909102919091179055516001906006906122d090859061561f565b908152604051908190036020018120805492151560ff19909316929092179091557f46fdb56149abcbd8b12b678efa8d730a35cd5ff17fe865c2a8de896ce412140c90612320908490849061596b565b60405180910390a16126bb565b60068260405161233d919061561f565b9081526040519081900360200190205460ff16156126bb5742816080015163ffffffff161161237e5760405162461bcd60e51b8152600401610b9d906159b8565b8060078360405161238f919061561f565b90815260408051602092819003830190208351805182546001600160a01b0319166001600160a01b039182161783559381015160018301559182015160028083019190915560608301516003830155608083015160048301805460a0860151929096166001600160e01b031990961695909517600160a01b6001600160401b03928316021790945560c083015160058301805460e0860151610100808801519489166001600160801b031990931692909217600160401b91909816029690961760ff60801b1916600160801b9215159290920291909117905561012083015160068301556101408301516007830180546101608601516101808701516101a088015161ffff1990931694151561ff001916949094179015159097029690961763ffff00001916620100009215159290920263ff000000191691909117630100000095151595909502949094178085556101c08401519294859392909164ff00000000191690600160201b90849081111561250b5761250b614d26565b02179055506101e091909101516008909101556020828101516040808501516001600160801b03928316600160801b9184168202176009860155606080870151600a870180546080808b015160a0808d015160c08e015160e08f015197909b166001600160a01b03199586161763ffffffff9384169099029890981767ffffffffffffffff60a01b1916600160a01b988316890263ffffffff60c01b191617600160c01b9a83169a909a02999099176001600160e01b0316600160e01b919095160293909317909155610100890151600b8901805483166001600160a01b03928316179055610120909901518051600c8a0180548416918c1691909117905596870151600d890180548316918b1691909117905586850151600e89018054909216908a1617905590850151600f9096018054918601519590940151959096166001600160b01b03199096169590951761ffff9384169095029490941761ffff60b01b1916600160b01b9290931691909102919091179055517f46fdb56149abcbd8b12b678efa8d730a35cd5ff17fe865c2a8de896ce412140c906126b290849084906159de565b60405180910390a15b50506001600055565b6002600054036126e65760405162461bcd60e51b8152600401610b9d90615727565b60026000556040516006906126fc90899061561f565b9081526040519081900360200190205460ff1661272b5760405162461bcd60e51b8152600401610b9d9061567f565b600060078860405161273d919061561f565b9081526040805191829003602090810183206102008401835280546001600160a01b0390811685526001820154928501929092526002808201549385019390935260038101546060850152600481015491821660808501526001600160401b03600160a01b909204821660a0850152600581015480831660c0860152600160401b810490921660e085015260ff600160801b9092048216151561010080860191909152600682015461012086015260078201548084161515610140870152908104831615156101608601526201000081048316151561018086015263010000008104831615156101a086015290926101c0850192600160201b9092049091169081111561284c5761284c614d26565b600281111561285d5761285d614d26565b8152602001600882015481525050905060006001600160a01b0316600789604051612888919061561f565b908152604051908190036020019020600b01546001600160a01b0316036128f4576128b38688615807565b34146128f45760405162461bcd60e51b815260206004820152601060248201526f0d2dce6eaccccd2c6d2cadce8408aa8960831b6044820152606401610b9d565b6005546040805160c08101825289815260208101899052808201889052606081018790526080810186905260a081018590529051633a33fe3160e11b815260009283926001600160a01b0390911691637467fc6291612959918e913391600401615a97565b6040805180830381865afa158015612975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129999190615788565b6040519093509091506000906007906129b3908d9061561f565b908152604051908190036020019020600b01546001600160a01b03161480156129e5575060006129e38383615807565b115b15612a75576000336129f78484615807565b60408051600081526020810191829052612a109161561f565b60006040518083038185875af1925050503d8060008114612a4d576040519150601f19603f3d011682016040523d82523d6000602084013e612a52565b606091505b5050905080612a735760405162461bcd60e51b8152600401610b9d90615904565b505b612a7f818a615b4f565b9850612a8b8289615b4f565b9750612aa13360088c604051610d20919061561f565b612ad057612ace3360088c604051612ab9919061561f565b908152604051908190036020019020906145ed565b505b826101a0015115612b16576001600b8560600151604051612af1919061561f565b908152604051908190036020019020805491151560ff19909216919091179055612b58565b835161ffff1615612b58576001600b8560600151604051612b37919061561f565b908152604051908190036020019020805491151560ff199092169190911790555b60006001846101c001516002811115612b7357612b73614d26565b14612b7e5787612b80565b865b90508361018001518015612b9d5750846000015161ffff16612710145b15612bde578060098c604051612bb3919061561f565b90815260200160405180910390206003016000828254612bd39190615807565b90915550612dd19050565b8361018001518015612bf45750845161ffff1615155b15612cc057600a8b604051612c09919061561f565b90815260408051918290036020908101832033600090815290825291822060030180546001810182559083529120018b9055600a90612c49908d9061561f565b90815260408051918290036020908101832033600090815290825291822060050180546001810182559083529120018a9055600a90612c89908d9061561f565b9081526040805160209281900383019020336000908152908352908120600401805460018101825590825291902001819055612dd1565b845161ffff161580612cd55750836101800151155b15612dd1578060098c604051612ceb919061561f565b90815260200160405180910390206004016000828254612d0b9190615807565b9091555050604051600a90612d21908d9061561f565b90815260408051918290036020908101832033600090815290825291822080546001810182559083529120018b9055600a90612d5e908d9061561f565b90815260408051918290036020908101832033600090815290825291822060020180546001810182559083529120018a9055600a90612d9e908d9061561f565b90815260408051602092819003830190203360009081529083529081206001908101805491820181558252919020018190555b80600a8c604051612de2919061561f565b9081526040805160209281900383019020336000908152925281206006018054909190612e10908490615807565b925050819055508060098c604051612e28919061561f565b90815260200160405180910390206002016000828254612e489190615807565b9091555050600554604051637b30fb3760e01b81526001600160a01b0390911690637b30fb3790612e7d908e906004016158c0565b602060405180830381865afa158015612e9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ebe9190615928565b91508160098c604051612ed1919061561f565b90815260405190819003602001812091909155600990612ef2908d9061561f565b908152602001604051809103902060010154600003612f3457836020015160098c604051612f20919061561f565b908152604051908190036020019020600101555b60006001600160a01b031660078c604051612f4f919061561f565b908152604051908190036020019020600b01546001600160a01b031614612fbe5783610160015115612fbe57612fbe3330612f8a8c8e615807565b60078f604051612f9a919061561f565b908152604051908190036020019020600b01546001600160a01b0316929190614602565b836101600151613002576130028b8b8b60078f604051612fde919061561f565b908152604051908190036020019020600b01546001600160a01b03163360006135a8565b606084610140015115613069576130438c338b6001896101c00151600281111561302e5761302e614d26565b1461303d578860600151613941565b8b613941565b60098e604051613053919061561f565b9081526040519081900360200190206001015590505b7fe522439914124e6027e1ac135772716d749ed8857d1c8a9cbd2c5d294088b8908c8a8a868f8f8c6040015133896040516130ac99989796959493929190615b62565b60405180910390a15050600160005550505050505050505050565b336130d0611ec0565b6001600160a01b031614806130eb57506130eb60023361347c565b6131075760405162461bcd60e51b8152600401610b9d9061563b565b600681604051613117919061561f565b9081526040519081900360200190205460ff166131465760405162461bcd60e51b8152600401610b9d9061567f565b600981604051613156919061561f565b9081526040519081900360200190206005015460ff16156131895760405162461bcd60e51b8152600401610b9d906156ac565b600981604051613199919061561f565b90815260405190819003602001902054156131c65760405162461bcd60e51b8152600401610b9d906159b8565b6007816040516131d6919061561f565b90815260405190819003602001812080546001600160a01b0319908116825560006001830181905560028301819055600383018190556004830180546001600160e01b03191690556005830180546001600160881b03191690556006830181905560078301805464ffffffffff191690556008830181905560098301819055600a830155600b8201805482169055600c8201805482169055600d8201805482169055600e820180549091169055600f0180546001600160c01b03191690557f69b2e335395b4abc91c9fba47beb681d9191216ff34810e7515ce98556c74b79906132c19083906158c0565b60405180910390a150565b6133106040518060e0016040528060008152602001600081526020016000815260200160008152602001600081526020016000151581526020016000151581525090565b600982604051613320919061561f565b90815260408051918290036020908101832060e0840183528054845260018101549184019190915260028101549183019190915260038101546060830152600481015460808301526005015460ff808216151560a084015261010090910416151560c082015292915050565b33613395611ec0565b6001600160a01b0316146133bb5760405162461bcd60e51b8152600401610b9d9061581a565b6001600160a01b0381166134205760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b9d565b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b60006001600160a01b03841661354157604080516000815260208101918290526001600160a01b0387169185916134d79161561f565b60006040518083038185875af1925050503d8060008114613514576040519150601f19603f3d011682016040523d82523d6000602084013e613519565b606091505b5050809150508061353c5760405162461bcd60e51b8152600401610b9d90615904565b613575565b811561355b5761353c6001600160a01b0385168685614585565b81613575576135756001600160a01b038516878786614602565b505050505050565b600061349a836001600160a01b038416614629565b60006107e3825490565b600061349a838361471c565b60006007876040516135ba919061561f565b908152604080516020928190038301812060c082018352600c8101546001600160a01b039081168352600d8201548116948301859052600e820154811693830193909352600f01549182166060820152600160a01b820461ffff9081166080830152600160b01b90920490911660a0820152915060009061363f9085908789876134a1565b60608201516001600160a01b031615801590613663575060008260a0015161ffff16115b156136a6576136a6848360600151876127108660a0015161ffff168c6136899190615bdc565b6136939190615bf3565b61369d9086615807565b945084876134a1565b60408201516001600160a01b0316158015906136ca57506000826080015161ffff16115b1561372d57612710826080015161ffff16886136e69190615bdc565b6136f09190615bf3565b6136fa9082615807565b905061372d84836040015187612710866080015161ffff168c61371d9190615bdc565b6137279190615bf3565b876134a1565b6137378188615b4f565b6004549097506001600160a01b0316156139265760045460405160009182916001600160a01b03909116906333ff942290600790613776908e9061561f565b908152604051908190036020018120546001600160e01b031960e084901b1682526001600160a01b03166004820152602401600060405180830381865afa1580156137c5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526137ed9190810190615c7b565b9150915060005b82518110156139225760006127108b8484815181106138155761381561584f565b60200260200101516138279190615bdc565b6138319190615bf3565b9050808b101561386f5760405162461bcd60e51b81526020600482015260096024820152681a5b9cdbdb1d995b9d60ba1b6044820152606401610b9d565b7f033f17ae2b7a9ab7cd350d5a345cc0b666e599db545d85e2f0eab9cb10264d2060078d6040516138a0919061561f565b9081526040519081900360200190205485516001600160a01b03909116908690859081106138d0576138d061584f565b6020026020010151836040516138e893929190615d3f565b60405180910390a1613916338584815181106139065761390661584f565b60200260200101518b848b6134a1565b909903986001016137f4565b5050505b613937848360000151878a876134a1565b5050505050505050565b60606000836001600160401b0381111561395d5761395d614a3b565b604051908082528060200260200182016040528015613986578160200160208202803683370190505b509150600986604051613999919061561f565b908152602001604051809103902060010154905060006007876040516139bf919061561f565b9081526040805191829003602090810183206102008401835280546001600160a01b0390811685526001820154928501929092526002808201549385019390935260038101546060850152600481015491821660808501526001600160401b03600160a01b909204821660a0850152600581015480831660c0860152600160401b810490921660e085015260ff600160801b9092048216151561010080860191909152600682015461012086015260078201548084161515610140870152908104831615156101608601526201000081048316151561018086015263010000008104831615156101a086015290926101c0850192600160201b90920490911690811115613ace57613ace614d26565b6002811115613adf57613adf614d26565b81526020016008820154815250509050806101000151613fdb5760005b85811015613fd45781516040516301ffc9a760e01b81526001600160a01b03909116906301ffc9a790613b3a906380ac58cd60e01b90600401615d63565b602060405180830381865afa158015613b57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b7b9190615d78565b15613cde575b81608001516001600160a01b031682600001516001600160a01b0316636352211e856040518263ffffffff1660e01b8152600401613bc191815260200190565b602060405180830381865afa158015613bde573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c029190615d95565b6001600160a01b031614613c46578282604001511015613c345760405162461bcd60e51b8152600401610b9d90615db2565b613c3f600184615807565b9250613b81565b81516080830151604051632142170760e11b81526001600160a01b03909216916342842e0e91613c7c918b908890600401615d3f565b600060405180830381600087803b158015613c9657600080fd5b505af1158015613caa573d6000803e3d6000fd5b5050505082848281518110613cc157613cc161584f565b6020908102919091010152613cd7600184615807565b9250613fc2565b81516040516301ffc9a760e01b81526001600160a01b03909116906301ffc9a790613d1490636cdb3d1360e11b90600401615d63565b602060405180830381865afa158015613d31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d559190615d78565b15613fc2576002826101c001516002811115613d7357613d73614d26565b03613e61575b81516080830151604051627eeac760e11b815287926001600160a01b03169162fdd58e91613dac91908890600401615ddc565b602060405180830381865afa158015613dc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ded9190615928565b1015613e29578282604001511015613e175760405162461bcd60e51b8152600401610b9d90615db2565b613e22600184615807565b9250613d79565b81516080830151604051637921219560e11b81526001600160a01b039092169163f242432a91613c7c918b9088908b90600401615df5565b6001826101c001516002811115613e7a57613e7a614d26565b03613fc25781516080830151604051627eeac760e11b815287926001600160a01b03169162fdd58e91613eb291908890600401615ddc565b602060405180830381865afa158015613ecf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ef39190615928565b11613f385760405162461bcd60e51b8152602060048201526015602482015274696e73756666696369656e74207175616e7469747960581b6044820152606401610b9d565b81516080830151604051637921219560e11b81526001600160a01b039092169163f242432a91613f70918b9088908b90600401615df5565b600060405180830381600087803b158015613f8a57600080fd5b505af1158015613f9e573d6000803e3d6000fd5b5050505082848281518110613fb557613fb561584f565b6020026020010181815250505b80613fcc81615865565b915050613afc565b505061457c565b8061010001511561457a5780516040516301ffc9a760e01b81526001600160a01b03909116906301ffc9a79061401c906380ac58cd60e01b90600401615d63565b602060405180830381865afa158015614039573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061405d9190615d78565b156140e657805160405163e00aab4b60e01b81526001600160a01b03888116600483015261ffff881660248301529091169063e00aab4b906044016000604051808303816000875af11580156140b7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140df9190810190615e38565b9250614461565b80516040516301ffc9a760e01b81526001600160a01b03909116906301ffc9a79061411c90636cdb3d1360e11b90600401615d63565b602060405180830381865afa158015614139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061415d9190615d78565b1561446157604080516001808252818301909252600091602080830190803683370190505090506000866001600160401b0381111561419e5761419e614a3b565b6040519080825280602002602001820160405280156141c7578160200160208202803683370190505b509050606088836000815181106141e0576141e061584f565b6001600160a01b03909216602092830291909101909101526002846101c00151600281111561421157614211614d26565b036142d35760005b8881101561425157878382815181106142345761423461584f565b60209081029190910101528061424981615865565b915050614219565b508351604051634637423960e11b81526001600160a01b0390911690638c6e84729061428590869086908690600401615e6c565b6000604051808303816000875af11580156142a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526142cc9190810190615e38565b955061445d565b6001846101c0015160028111156142ec576142ec614d26565b0361445d5786826000815181106143055761430561584f565b602002602001018181525050846000036143d8578351604051634637423960e11b81526001600160a01b0390911690638c6e84729061434c90869086908690600401615e6c565b6000604051808303816000875af115801561436b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526143939190810190615e38565b9550856000815181106143a8576143a861584f565b602002602001015160098b6040516143c0919061561f565b9081526040519081900360200190206001015561445d565b84866000815181106143ec576143ec61584f565b602090810291909101015283516040516339b2213760e21b81526001600160a01b039091169063e6c884dc9061442a9086908a908790600401615ef3565b600060405180830381600087803b15801561444457600080fd5b505af1158015614458573d6000803e3d6000fd5b505050505b5050505b806101200151600019146145485780610120015183600185516144849190615b4f565b815181106144945761449461584f565b6020026020010151106144dc5760016009886040516144b3919061561f565b90815260405190819003602001902060050180549115156101000261ff00199092169190911790555b80610120015183600185516144f19190615b4f565b815181106145015761450161584f565b602002602001015111156145485760405162461bcd60e51b815260206004820152600e60248201526d1c995858da1959081b585e081a5960921b6044820152606401610b9d565b8283600185516145589190615b4f565b815181106145685761456861584f565b6020026020010151925092505061457c565b505b94509492505050565b6145db8363a9059cbb60e01b84846040516024016145a4929190615ddc565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614746565b505050565b6060600061349a83614818565b600061349a836001600160a01b038416614874565b614623846323b872dd60e01b8585856040516024016145a493929190615d3f565b50505050565b6000818152600183016020526040812054801561471257600061464d600183615b4f565b855490915060009061466190600190615b4f565b90508181146146c65760008660000182815481106146815761468161584f565b90600052602060002001549050808760000184815481106146a4576146a461584f565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806146d7576146d7615f36565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506107e3565b60009150506107e3565b60008260000182815481106147335761473361584f565b9060005260206000200154905092915050565b600061479b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166148c39092919063ffffffff16565b8051909150156145db57808060200190518101906147b99190615d78565b6145db5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b9d565b60608160000180548060200260200160405190810160405280929190818152602001828054801561486857602002820191906000526020600020905b815481526020019060010190808311614854575b50505050509050919050565b60008181526001830160205260408120546148bb575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556107e3565b5060006107e3565b60606148d284846000856148da565b949350505050565b60608247101561493b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610b9d565b843b6149895760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b9d565b600080866001600160a01b031685876040516149a5919061561f565b60006040518083038185875af1925050503d80600081146149e2576040519150601f19603f3d011682016040523d82523d6000602084013e6149e7565b606091505b50915091506149f7828286614a02565b979650505050505050565b60608315614a1157508161349a565b825115614a215782518084602001fd5b8160405162461bcd60e51b8152600401610b9d91906158c0565b634e487b7160e01b600052604160045260246000fd5b60405161020081016001600160401b0381118282101715614a7457614a74614a3b565b60405290565b60405161014081016001600160401b0381118282101715614a7457614a74614a3b565b604051601f8201601f191681016001600160401b0381118282101715614ac557614ac5614a3b565b604052919050565b600082601f830112614ade57600080fd5b81356001600160401b03811115614af757614af7614a3b565b614b0a601f8201601f1916602001614a9d565b818152846020838601011115614b1f57600080fd5b816020850160208301376000918101602001919091529392505050565b6001600160a01b038116811461117d57600080fd5b8035614b5c81614b3c565b919050565b60008060408385031215614b7457600080fd5b82356001600160401b03811115614b8a57600080fd5b614b9685828601614acd565b9250506020830135614ba781614b3c565b809150509250929050565b600081518084526020808501945080840160005b83811015614be257815187529582019590820190600101614bc6565b509495945050505050565b6020815260008251610100806020850152614c0c610120850183614bb2565b91506020850151601f1980868503016040870152614c2a8483614bb2565b93506040870151915080868503016060870152614c478483614bb2565b93506060870151915080868503016080870152614c648483614bb2565b935060808701519150808685030160a0870152614c818483614bb2565b935060a08701519150808685030160c087015250614c9f8382614bb2565b92505060c085015160e085015260e0850151614cbe8286018215159052565b5090949350505050565b600060208284031215614cda57600080fd5b81356001600160e01b03198116811461349a57600080fd5b600060208284031215614d0457600080fd5b81356001600160401b03811115614d1a57600080fd5b6148d284828501614acd565b634e487b7160e01b600052602160045260246000fd5b60038110614d5a57634e487b7160e01b600052602160045260246000fd5b9052565b80516001600160a01b031682526020810151602083015260408101516040830152606081015160608301526080810151614da360808401826001600160a01b03169052565b5060a0810151614dbe60a08401826001600160401b03169052565b5060c0810151614dd960c08401826001600160401b03169052565b5060e0810151614df460e08401826001600160401b03169052565b506101008181015115159083015261012080820151908301526101408082015115159083015261016080820151151590830152610180808201511515908301526101a0808201511515908301526101c080820151614e5482850182614d3c565b50506101e090810151910152565b614e6d828251614d5e565b6020818101516001600160801b03908116610200850152604080840151821661022086015260608085015190921661024086015260808085015163ffffffff90811661026088015260a080870151821661028089015260c087015182166102a089015260e08701519091166102c08801526101008601516001600160a01b039081166102e089015261012090960151805187166103008901529485015186166103208801529184015185166103408701529183015190931661036085015281015161ffff908116610380850152910151166103a090910152565b6103c081016107e38284614e62565b803563ffffffff81168114614b5c57600080fd5b60008060408385031215614f7d57600080fd5b82356001600160401b03811115614f9357600080fd5b614f9f85828601614acd565b925050614fae60208401614f56565b90509250929050565b600060208284031215614fc957600080fd5b813561349a81614b3c565b600081518084526020808501945080840160005b83811015614be25781516001600160a01b031687529582019590820190600101614fe8565b60208152600061349a6020830184614fd4565b6000806040838503121561503357600080fd5b823561503e81614b3c565b91506020830135614ba781614b3c565b801515811461117d57600080fd5b8035614b5c8161504e565b6000806040838503121561507a57600080fd5b82356001600160401b0381111561509057600080fd5b61509c85828601614acd565b9250506020830135614ba78161504e565b80356001600160801b0381168114614b5c57600080fd5b600080604083850312156150d757600080fd5b82356001600160401b038111156150ed57600080fd5b6150f985828601614acd565b925050614fae602084016150ad565b80356001600160401b0381168114614b5c57600080fd5b803560038110614b5c57600080fd5b6000610200828403121561514157600080fd5b615149614a51565b905061515482614b51565b815260208201356020820152604082013560408201526060820135606082015261518060808301614b51565b608082015261519160a08301615108565b60a08201526151a260c08301615108565b60c08201526151b360e08301615108565b60e08201526101006151c681840161505c565b9082015261012082810135908201526101406151e381840161505c565b908201526101606151f583820161505c565b9082015261018061520783820161505c565b908201526101a061521983820161505c565b908201526101c061522b83820161511f565b81830152506101e080830135818301525092915050565b803561ffff81168114614b5c57600080fd5b600060c0828403121561526657600080fd5b60405160c081018181106001600160401b038211171561528857615288614a3b565b604052905080823561529981614b3c565b815260208301356152a981614b3c565b602082015260408301356152bc81614b3c565b604082015260608301356152cf81614b3c565b60608201526152e060808401615242565b60808201526152f160a08401615242565b60a08201525092915050565b6000808284036103e081121561531257600080fd5b83356001600160401b0381111561532857600080fd5b61533486828701614acd565b9350506103c0601f198201121561534a57600080fd5b50615353614a7a565b615360856020860161512e565b815261536f61022085016150ad565b602082015261538161024085016150ad565b604082015261539361026085016150ad565b60608201526153a56102808501614f56565b60808201526153b76102a08501614f56565b60a08201526153c96102c08501614f56565b60c08201526153db6102e08501614f56565b60e08201526153ed6103008501614b51565b610100820152615401856103208601615254565b610120820152809150509250929050565b60006001600160401b0382111561542b5761542b614a3b565b5060051b60200190565b600060a0828403121561544757600080fd5b60405160a081016001600160401b03828210818311171561546a5761546a614a3b565b8160405282935061547a85615242565b835261548860208601614f56565b602084015260408501359150808211156154a157600080fd5b6154ad86838701614acd565b604084015260608501359150808211156154c657600080fd5b506154d385828601614acd565b60608301525060808301356154e781614b3c565b6080919091015292915050565b600080600080600080600060e0888a03121561550f57600080fd5b87356001600160401b038082111561552657600080fd5b6155328b838c01614acd565b985060209150818a0135975060408a0135965060608a0135955060808a0135945060a08a01358181111561556557600080fd5b8a01601f81018c1361557657600080fd5b803561558961558482615412565b614a9d565b81815260059190911b8201840190848101908e8311156155a857600080fd5b928501925b828410156155c6578335825292850192908501906155ad565b965050505060c08a01359150808211156155df57600080fd5b506155ec8a828b01615435565b91505092959891949750929550565b60005b838110156156165781810151838201526020016155fe565b50506000910152565b600082516156318184602087016155fb565b9190910192915050565b60208082526024908201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616040820152633236b4b760e11b606082015260800190565b6020808252601390820152723ab739bab83837b93a32b21030bab1ba34b7b760691b604082015260600190565b6020808252600d908201526c185b1c9958591e48195b991959609a1b604082015260600190565b600081518084526156eb8160208601602086016155fb565b601f01601f19169290920160200192915050565b60408152600061571260408301856156d3565b905063ffffffff831660208301529392505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b60408152600061577160408301856156d3565b905060018060a01b03831660208301529392505050565b6000806040838503121561579b57600080fd5b505080516020909101519092909150565b60a0815260006157bf60a08301886156d3565b6001600160a01b0396871660208401526040830195909552506060810192909252909216608090920191909152919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156107e3576107e36157f1565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060018201615877576158776157f1565b5060010190565b60208082526022908201527f616c6c6f7765643a206f6e6c792061646d696e206f7220746f6b656e206f776e60408201526132b960f11b606082015260800190565b60208152600061349a60208301846156d3565b6080815260006158e660808301876156d3565b85602084015284604084015282810360608401526149f78185614bb2565b6020808252600a90820152691d1e1b8819985a5b195960b21b604082015260600190565b60006020828403121561593a57600080fd5b5051919050565b60408152600061595460408301856156d3565b905060018060801b03831660208301529392505050565b600061040080835261597f818401866156d3565b905061598e6020840185614e62565b8281036103e084015260068152651b1a5cdd195960d21b6020820152604081019150509392505050565b6020808252600c908201526b1cd85b19481cdd185c9d195960a21b604082015260600190565b60006104008083526159f2818401866156d3565b9050615a016020840185614e62565b8281036103e084015260078152661d5c19185d195960ca1b6020820152604081019150509392505050565b61ffff815116825263ffffffff60208201511660208301526000604082015160a06040850152615a5f60a08501826156d3565b905060608301518482036060860152615a7882826156d3565b6080948501516001600160a01b03169590940194909452509092915050565b606081526000615aaa60608301866156d3565b602060018060a01b03861681850152838203604085015260c082018551835281860151828401526040860151604084015260608601516060840152608086015160c0608085015281815180845260e0860191508483019350600092505b80831015615b275783518252928401926001929092019190840190615b07565b5060a0880151935084810360a0860152615b418185615a2c565b9a9950505050505050505050565b818103818111156107e3576107e36157f1565b6000610120808352615b768184018d6156d3565b90508a60208401528960408401528860608401528760808401528660a084015282810360c0840152615ba881876156d3565b6001600160a01b03861660e08501528381036101008501529050615bcc8185614bb2565b9c9b505050505050505050505050565b80820281158282048414176107e3576107e36157f1565b600082615c1057634e487b7160e01b600052601260045260246000fd5b500490565b600082601f830112615c2657600080fd5b81516020615c3661558483615412565b82815260059290921b84018101918181019086841115615c5557600080fd5b8286015b84811015615c705780518352918301918301615c59565b509695505050505050565b60008060408385031215615c8e57600080fd5b82516001600160401b0380821115615ca557600080fd5b818501915085601f830112615cb957600080fd5b81516020615cc961558483615412565b82815260059290921b84018101918181019089841115615ce857600080fd5b948201945b83861015615d0f578551615d0081614b3c565b82529482019490820190615ced565b91880151919650909350505080821115615d2857600080fd5b50615d3585828601615c15565b9150509250929050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160e01b031991909116815260200190565b600060208284031215615d8a57600080fd5b815161349a8161504e565b600060208284031215615da757600080fd5b815161349a81614b3c565b60208082526010908201526f3737ba1032b737bab3b4103a37b5b2b760811b604082015260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260a06080820181905260029082015261060f60f31b60c082015260e00190565b600060208284031215615e4a57600080fd5b81516001600160401b03811115615e6057600080fd5b6148d284828501615c15565b606081526000615e7f6060830186614fd4565b602083820381850152615e928287614bb2565b915083820360408501528185518084528284019150828160051b85010183880160005b83811015615ee357601f19878403018552615ed18383516156d3565b94860194925090850190600101615eb5565b50909a9950505050505050505050565b606081526000615f066060830186614fd4565b8281036020840152615f188186614bb2565b90508281036040840152615f2c8185614bb2565b9695505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d8be8d571f336ade3d1b6c9e8b3ce7907b34278fcd07cc9098a3ba76ee9b9a3464736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d8c3d2ccdcd1f1a4f91e370b9dbef02be2364a65
-----Decoded View---------------
Arg [0] : _royaltySupport (address): 0x0000000000000000000000000000000000000000
Arg [1] : dutchUtilityArg (address): 0xD8C3d2CCdcD1F1a4F91e370b9dBef02bE2364A65
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 000000000000000000000000d8c3d2ccdcd1f1a4f91e370b9dbef02be2364a65
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $2,687.25 | 1.28 | $3,439.69 |
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.