ETH Price: $2,053.85 (-3.03%)

Contract

0x806Ca46e7df33F6C6f4e28839162F8F85755116A
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer Ownersh...170769902023-04-19 0:04:471052 days ago1681862687IN
0x806Ca46e...85755116A
0 ETH0.0016325256.93402943
Withdraw Bid146374512022-04-22 22:51:041413 days ago1650667864IN
0x806Ca46e...85755116A
0 ETH0.001940450
Make Bid146374482022-04-22 22:50:391413 days ago1650667839IN
0x806Ca46e...85755116A
0.3233717 ETH0.0043028550
Withdraw Bid146374472022-04-22 22:50:361413 days ago1650667836IN
0x806Ca46e...85755116A
0 ETH0.001940450
Make Bid146374432022-04-22 22:49:561413 days ago1650667796IN
0x806Ca46e...85755116A
0.2525 ETH0.0043028550
Withdraw Bid146374422022-04-22 22:49:081413 days ago1650667748IN
0x806Ca46e...85755116A
0 ETH0.001940450
Make Bid146374412022-04-22 22:48:531413 days ago1650667733IN
0x806Ca46e...85755116A
0.2222 ETH0.0043028550
Withdraw Bid146374402022-04-22 22:48:451413 days ago1650667725IN
0x806Ca46e...85755116A
0 ETH0.001940450
Make Bid146374392022-04-22 22:48:311413 days ago1650667711IN
0x806Ca46e...85755116A
0.16665 ETH0.0043028550
Withdraw Bid146374382022-04-22 22:48:201413 days ago1650667700IN
0x806Ca46e...85755116A
0 ETH0.001940450
Make Bid146374372022-04-22 22:48:071413 days ago1650667687IN
0x806Ca46e...85755116A
0.1919 ETH0.0043028550
Withdraw Bid146374362022-04-22 22:48:021413 days ago1650667682IN
0x806Ca46e...85755116A
0 ETH0.001940450
Make Bid146374302022-04-22 22:46:441413 days ago1650667604IN
0x806Ca46e...85755116A
0.3535 ETH0.0043028550
Withdraw Bid146373972022-04-22 22:40:131413 days ago1650667213IN
0x806Ca46e...85755116A
0 ETH0.001940450
Make Bid146373732022-04-22 22:34:101413 days ago1650666850IN
0x806Ca46e...85755116A
0.255025 ETH0.0043028550
Withdraw Bid146373712022-04-22 22:33:531413 days ago1650666833IN
0x806Ca46e...85755116A
0 ETH0.001940450
Make Bid146373682022-04-22 22:33:401413 days ago1650666820IN
0x806Ca46e...85755116A
0.2828 ETH0.0043028550
Withdraw Bid146373302022-04-22 22:24:551413 days ago1650666295IN
0x806Ca46e...85755116A
0 ETH0.0021344455
Make Bid146373272022-04-22 22:24:151413 days ago1650666255IN
0x806Ca46e...85755116A
0.2525 ETH0.0047331355
Withdraw Bid146373202022-04-22 22:22:581413 days ago1650666178IN
0x806Ca46e...85755116A
0 ETH0.0023284860
Make Bid146372912022-04-22 22:16:361413 days ago1650665796IN
0x806Ca46e...85755116A
0.2626 ETH0.0051634260
Withdraw Bid146372622022-04-22 22:09:271413 days ago1650665367IN
0x806Ca46e...85755116A
0 ETH0.0023284860
Make Bid146372552022-04-22 22:08:501413 days ago1650665330IN
0x806Ca46e...85755116A
1.313 ETH0.0051634260
Withdraw Bid146371592022-04-22 21:48:181413 days ago1650664098IN
0x806Ca46e...85755116A
0 ETH0.002910675
Make Bid146371532022-04-22 21:47:161413 days ago1650664036IN
0x806Ca46e...85755116A
0.214221 ETH0.0064542775
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
-146374512022-04-22 22:51:041413 days ago1650667864
0x806Ca46e...85755116A
0.3233717 ETH
-146374482022-04-22 22:50:391413 days ago1650667839
0x806Ca46e...85755116A
0.32017 ETH
-146374472022-04-22 22:50:361413 days ago1650667836
0x806Ca46e...85755116A
0.2525 ETH
-146374432022-04-22 22:49:561413 days ago1650667796
0x806Ca46e...85755116A
0.25 ETH
-146374422022-04-22 22:49:081413 days ago1650667748
0x806Ca46e...85755116A
0.2222 ETH
-146374412022-04-22 22:48:531413 days ago1650667733
0x806Ca46e...85755116A
0.22 ETH
-146374402022-04-22 22:48:451413 days ago1650667725
0x806Ca46e...85755116A
0.16665 ETH
-146374392022-04-22 22:48:311413 days ago1650667711
0x806Ca46e...85755116A
0.165 ETH
-146374382022-04-22 22:48:201413 days ago1650667700
0x806Ca46e...85755116A
0.1919 ETH
-146374372022-04-22 22:48:071413 days ago1650667687
0x806Ca46e...85755116A
0.19 ETH
-146374362022-04-22 22:48:021413 days ago1650667682
0x806Ca46e...85755116A
0.3535 ETH
-146374302022-04-22 22:46:441413 days ago1650667604
0x806Ca46e...85755116A
0.35 ETH
-146373972022-04-22 22:40:131413 days ago1650667213
0x806Ca46e...85755116A
0.255025 ETH
-146373732022-04-22 22:34:101413 days ago1650666850
0x806Ca46e...85755116A
0.2525 ETH
-146373712022-04-22 22:33:531413 days ago1650666833
0x806Ca46e...85755116A
0.2828 ETH
-146373682022-04-22 22:33:401413 days ago1650666820
0x806Ca46e...85755116A
0.28 ETH
-146373302022-04-22 22:24:551413 days ago1650666295
0x806Ca46e...85755116A
0.2525 ETH
-146373272022-04-22 22:24:151413 days ago1650666255
0x806Ca46e...85755116A
0.25 ETH
-146373202022-04-22 22:22:581413 days ago1650666178
0x806Ca46e...85755116A
0.2626 ETH
-146372912022-04-22 22:16:361413 days ago1650665796
0x806Ca46e...85755116A
0.26 ETH
-146372622022-04-22 22:09:271413 days ago1650665367
0x806Ca46e...85755116A
1.313 ETH
-146372552022-04-22 22:08:501413 days ago1650665330
0x806Ca46e...85755116A
1.3 ETH
-146371592022-04-22 21:48:181413 days ago1650664098
0x806Ca46e...85755116A
0.214221 ETH
-146371532022-04-22 21:47:161413 days ago1650664036
0x806Ca46e...85755116A
0.2121 ETH
-146366872022-04-22 19:59:231413 days ago1650657563
0x806Ca46e...85755116A
1.2 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NFTAuction

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 8 : NFTAuction.sol
// SPDX-License-Identifier: MIT
// moved from https://github.com/museum-of-war/auction
pragma solidity 0.8.13;

import "IERC721.sol";
import "IERC721Receiver.sol";
import "IERC20.sol";
import "Ownable.sol";
import "IWithBalance.sol";

/// @title An Auction Contract for bidding and selling single and batched NFTs
/// @author Avo Labs GmbH
/// @notice This contract can be used for auctioning any NFTs, and accepts any ERC20 token as payment
contract NFTAuction is Ownable {
    address[] public whitelistedPassCollections; //Only owners of tokens from any of these collections can make bids
    mapping(address => mapping(uint256 => Auction)) public nftContractAuctions;
    mapping(address => uint256) failedTransferCredits;
    //Each Auction is unique to each NFT (contract + id pairing).
    struct Auction {
        //map token ID to
        uint32 bidIncreasePercentage;
        uint32 auctionBidPeriod; //Increments the length of time the auction is open in which a new bid can be made after each bid.
        uint64 auctionEnd;
        uint128 minPrice;
        uint128 buyNowPrice;
        uint128 nftHighestBid;
        address nftHighestBidder;
        address nftSeller;
        address whitelistedBuyer; //The seller can specify a whitelisted address for a sale (this is effectively a direct sale).
        address nftRecipient; //The bidder can specify a recipient for the NFT if their bid is successful.
        address ERC20Token; // The seller can specify an ERC20 token that can be used to bid or purchase the NFT.
        address[] feeRecipients;
        uint32[] feePercentages;
    }
    /*
     * Default values that are used if not specified by the NFT seller.
     */
    uint32 public defaultBidIncreasePercentage;
    uint32 public minimumSettableIncreasePercentage;
    uint32 public maximumMinPricePercentage;
    uint32 public defaultAuctionBidPeriod;

    /*╔═════════════════════════════╗
      ║           EVENTS            ║
      ╚═════════════════════════════╝*/

    event NftAuctionCreated(
        address nftContractAddress,
        uint256 tokenId,
        address nftSeller,
        address erc20Token,
        uint128 minPrice,
        uint128 buyNowPrice,
        uint32 auctionBidPeriod,
        uint32 bidIncreasePercentage,
        address[] feeRecipients,
        uint32[] feePercentages
    );

    event SaleCreated(
        address nftContractAddress,
        uint256 tokenId,
        address nftSeller,
        address erc20Token,
        uint128 buyNowPrice,
        address whitelistedBuyer,
        address[] feeRecipients,
        uint32[] feePercentages
    );

    event BidMade(
        address nftContractAddress,
        uint256 tokenId,
        address bidder,
        uint256 ethAmount,
        address erc20Token,
        uint256 tokenAmount
    );

    event AuctionPeriodUpdated(
        address nftContractAddress,
        uint256 tokenId,
        uint64 auctionEndPeriod
    );

    event NFTTransferredAndSellerPaid(
        address nftContractAddress,
        uint256 tokenId,
        address nftSeller,
        uint128 nftHighestBid,
        address nftHighestBidder,
        address nftRecipient
    );

    event AuctionSettled(
        address nftContractAddress,
        uint256 tokenId,
        address auctionSettler
    );

    event AuctionWithdrawn(
        address nftContractAddress,
        uint256 tokenId,
        address nftOwner
    );

    event BidWithdrawn(
        address nftContractAddress,
        uint256 tokenId,
        address highestBidder
    );

    event WhitelistedBuyerUpdated(
        address nftContractAddress,
        uint256 tokenId,
        address newWhitelistedBuyer
    );

    event MinimumPriceUpdated(
        address nftContractAddress,
        uint256 tokenId,
        uint256 newMinPrice
    );

    event BuyNowPriceUpdated(
        address nftContractAddress,
        uint256 tokenId,
        uint128 newBuyNowPrice
    );
    event HighestBidTaken(address nftContractAddress, uint256 tokenId);
    /**********************************/
    /*╔═════════════════════════════╗
      ║             END             ║
      ║            EVENTS           ║
      ╚═════════════════════════════╝*/
    /**********************************/
    /*╔═════════════════════════════╗
      ║          MODIFIERS          ║
      ╚═════════════════════════════╝*/

    modifier hasWhitelistedToken() {
        { //Block scoping to prevent "Stack too deep"
            bool isWhitelisted;
            for (uint256 i = 0; i < whitelistedPassCollections.length; i++) {
                if(IWithBalance(whitelistedPassCollections[i]).balanceOf(msg.sender) > 0) {
                    isWhitelisted = true;
                    break;
                }
            }
            require(isWhitelisted, "Sender has no whitelisted NFTs");
        }
        _;
    }

    modifier isAuctionNotStartedByOwner(
        address _nftContractAddress,
        uint256 _tokenId
    ) {
        require(
            nftContractAuctions[_nftContractAddress][_tokenId].nftSeller !=
                msg.sender,
            "Auction already started by owner"
        );

        if (
            nftContractAuctions[_nftContractAddress][_tokenId].nftSeller !=
            address(0)
        ) {
            require(
                msg.sender == IERC721(_nftContractAddress).ownerOf(_tokenId),
                "Sender doesn't own NFT"
            );

            _resetAuction(_nftContractAddress, _tokenId);
        }
        _;
    }

    modifier auctionOngoing(address _nftContractAddress, uint256 _tokenId) {
        require(
            _isAuctionOngoing(_nftContractAddress, _tokenId),
            "Auction has ended"
        );
        _;
    }

    modifier priceGreaterThanZero(uint256 _price) {
        require(_price > 0, "Price cannot be 0");
        _;
    }
    /*
     * The minimum price must be 80% of the buyNowPrice(if set).
     */
    modifier minPriceDoesNotExceedLimit(
        uint128 _buyNowPrice,
        uint128 _minPrice
    ) {
        require(
            _buyNowPrice == 0 ||
                _getPortionOfBid(_buyNowPrice, maximumMinPricePercentage) >=
                _minPrice,
            "MinPrice > 80% of buyNowPrice"
        );
        _;
    }

    modifier notNftSeller(address _nftContractAddress, uint256 _tokenId) {
        require(
            msg.sender !=
                nftContractAuctions[_nftContractAddress][_tokenId].nftSeller,
            "Owner cannot bid on own NFT"
        );
        _;
    }
    modifier onlyNftSeller(address _nftContractAddress, uint256 _tokenId) {
        require(
            msg.sender ==
                nftContractAuctions[_nftContractAddress][_tokenId].nftSeller,
            "Only nft seller"
        );
        _;
    }
    /*
     * The bid amount was either equal the buyNowPrice or it must be higher than the previous
     * bid by the specified bid increase percentage.
     */
    modifier bidAmountMeetsBidRequirements(
        address _nftContractAddress,
        uint256 _tokenId,
        uint128 _tokenAmount
    ) {
        require(
            _doesBidMeetBidRequirements(
                _nftContractAddress,
                _tokenId,
                _tokenAmount
            ),
            "Not enough funds to bid on NFT"
        );
        _;
    }
    // check if the highest bidder can purchase this NFT.
    modifier onlyApplicableBuyer(
        address _nftContractAddress,
        uint256 _tokenId
    ) {
        require(
            !_isWhitelistedSale(_nftContractAddress, _tokenId) ||
                nftContractAuctions[_nftContractAddress][_tokenId]
                    .whitelistedBuyer ==
                msg.sender,
            "Only the whitelisted buyer"
        );
        _;
    }

    modifier minimumBidNotMade(address _nftContractAddress, uint256 _tokenId) {
        require(
            !_isMinimumBidMade(_nftContractAddress, _tokenId),
            "The auction has a valid bid made"
        );
        _;
    }

    /*
     * Payment is accepted if the payment is made in the ERC20 token or ETH specified by the seller.
     * Early bids on NFTs not yet up for auction must be made in ETH.
     */
    modifier paymentAccepted(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _tokenAmount
    ) {
        require(
            _isPaymentAccepted(
                _nftContractAddress,
                _tokenId,
                _erc20Token,
                _tokenAmount
            ),
            "Bid to be in specified ERC20/Eth"
        );
        _;
    }

    modifier isAuctionOver(address _nftContractAddress, uint256 _tokenId) {
        require(
            !_isAuctionOngoing(_nftContractAddress, _tokenId),
            "Auction is not yet over"
        );
        _;
    }

    modifier notZeroAddress(address _address) {
        require(_address != address(0), "Cannot specify 0 address");
        _;
    }

    modifier increasePercentageAboveMinimum(uint32 _bidIncreasePercentage) {
        require(
            _bidIncreasePercentage >= minimumSettableIncreasePercentage,
            "Bid increase percentage too low"
        );
        _;
    }

    modifier isFeePercentagesLessThanMaximum(uint32[] memory _feePercentages) {
        uint32 totalPercent;
        for (uint256 i = 0; i < _feePercentages.length; i++) {
            totalPercent = totalPercent + _feePercentages[i];
        }
        require(totalPercent <= 10000, "Fee percentages exceed maximum");
        _;
    }

    modifier correctFeeRecipientsAndPercentages(
        uint256 _recipientsLength,
        uint256 _percentagesLength
    ) {
        require(
            _recipientsLength == _percentagesLength,
            "Recipients != percentages"
        );
        _;
    }

    modifier isNotASale(address _nftContractAddress, uint256 _tokenId) {
        require(
            !_isASale(_nftContractAddress, _tokenId),
            "Not applicable for a sale"
        );
        _;
    }

    /**********************************/
    /*╔═════════════════════════════╗
      ║             END             ║
      ║          MODIFIERS          ║
      ╚═════════════════════════════╝*/
    /**********************************/
    // constructor
    constructor(address[] memory _whitelistedPassCollectionsAddresses) {
        defaultBidIncreasePercentage = 100;
        defaultAuctionBidPeriod = 86400; //1 day
        minimumSettableIncreasePercentage = 100;
        maximumMinPricePercentage = 8000;

        uint256 collectionsCount = _whitelistedPassCollectionsAddresses.length;
        for (uint256 i = 0; i < collectionsCount; i++) {
            whitelistedPassCollections.push(_whitelistedPassCollectionsAddresses[i]);
        }
    }
    /**********************************/
    /*╔══════════════════════════════╗
      ║     WHITELIST FUNCTIONS      ║
      ╚══════════════════════════════╝*/
    /*
     * Add whitelisted pass collection.
     */
    function addWhitelistedCollection(address _collectionContractAddress)
    external
    onlyOwner
    {
        whitelistedPassCollections.push(_collectionContractAddress);
    }
    /*
     * Remove whitelisted pass collection by index.
     */
    function removeWhitelistedCollection(uint256 index)
    external
    onlyOwner
    {
        whitelistedPassCollections[index] = whitelistedPassCollections[whitelistedPassCollections.length - 1];
        whitelistedPassCollections.pop();
    }
    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║     WHITELIST FUNCTIONS      ║
      ╚══════════════════════════════╝*/
    /**********************************/
    /*╔══════════════════════════════╗
      ║    AUCTION CHECK FUNCTIONS   ║
      ╚══════════════════════════════╝*/
    function _isAuctionOngoing(address _nftContractAddress, uint256 _tokenId)
        internal
        view
        returns (bool)
    {
        uint64 auctionEndTimestamp = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].auctionEnd;
        //if the auctionEnd is set to 0, the auction is technically on-going, however
        //the minimum bid price (minPrice) has not yet been met.
        return (auctionEndTimestamp == 0 ||
            block.timestamp < auctionEndTimestamp);
    }

    /*
     * Check if a bid has been made. This is applicable in the early bid scenario
     * to ensure that if an auction is created after an early bid, the auction
     * begins appropriately or is settled if the buy now price is met.
     */
    function _isABidMade(address _nftContractAddress, uint256 _tokenId)
        internal
        view
        returns (bool)
    {
        return (nftContractAuctions[_nftContractAddress][_tokenId]
            .nftHighestBid > 0);
    }

    /*
     *if the minPrice is set by the seller, check that the highest bid meets or exceeds that price.
     */
    function _isMinimumBidMade(address _nftContractAddress, uint256 _tokenId)
        internal
        view
        returns (bool)
    {
        uint128 minPrice = nftContractAuctions[_nftContractAddress][_tokenId]
            .minPrice;
        return
            minPrice > 0 &&
            (nftContractAuctions[_nftContractAddress][_tokenId].nftHighestBid >=
                minPrice);
    }

    /*
     * If the buy now price is set by the seller, check that the highest bid meets that price.
     */
    function _isBuyNowPriceMet(address _nftContractAddress, uint256 _tokenId)
        internal
        view
        returns (bool)
    {
        uint128 buyNowPrice = nftContractAuctions[_nftContractAddress][_tokenId]
            .buyNowPrice;
        return
            buyNowPrice > 0 &&
            nftContractAuctions[_nftContractAddress][_tokenId].nftHighestBid >=
            buyNowPrice;
    }

    /*
     * Check that a bid is applicable for the purchase of the NFT.
     * In the case of a sale: the bid needs to meet the buyNowPrice.
     * In the case of an auction: the bid needs to be a % higher than the previous bid.
     */
    function _doesBidMeetBidRequirements(
        address _nftContractAddress,
        uint256 _tokenId,
        uint128 _tokenAmount
    ) internal view returns (bool) {
        uint128 buyNowPrice = nftContractAuctions[_nftContractAddress][_tokenId]
            .buyNowPrice;
        //if buyNowPrice is met, ignore increase percentage
        if (
            buyNowPrice > 0 &&
            (msg.value >= buyNowPrice || _tokenAmount >= buyNowPrice)
        ) {
            return true;
        }
        //if the NFT is up for auction, the bid needs to be a % higher than the previous bid
        uint256 bidIncreaseAmount = (nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBid *
            (10000 +
                _getBidIncreasePercentage(_nftContractAddress, _tokenId))) /
            10000;
        return (msg.value >= bidIncreaseAmount ||
            _tokenAmount >= bidIncreaseAmount);
    }

    /*
     * An NFT is up for sale if the buyNowPrice is set, but the minPrice is not set.
     * Therefore the only way to conclude the NFT sale is to meet the buyNowPrice.
     */
    function _isASale(address _nftContractAddress, uint256 _tokenId)
        internal
        view
        returns (bool)
    {
        return (nftContractAuctions[_nftContractAddress][_tokenId].buyNowPrice >
            0 &&
            nftContractAuctions[_nftContractAddress][_tokenId].minPrice == 0);
    }

    function _isWhitelistedSale(address _nftContractAddress, uint256 _tokenId)
        internal
        view
        returns (bool)
    {
        return (nftContractAuctions[_nftContractAddress][_tokenId]
            .whitelistedBuyer != address(0));
    }

    /*
     * The highest bidder is allowed to purchase the NFT if
     * no whitelisted buyer is set by the NFT seller.
     * Otherwise, the highest bidder must equal the whitelisted buyer.
     */
    function _isHighestBidderAllowedToPurchaseNFT(
        address _nftContractAddress,
        uint256 _tokenId
    ) internal view returns (bool) {
        return
            (!_isWhitelistedSale(_nftContractAddress, _tokenId)) ||
            _isHighestBidderWhitelisted(_nftContractAddress, _tokenId);
    }

    function _isHighestBidderWhitelisted(
        address _nftContractAddress,
        uint256 _tokenId
    ) internal view returns (bool) {
        return (nftContractAuctions[_nftContractAddress][_tokenId]
            .nftHighestBidder ==
            nftContractAuctions[_nftContractAddress][_tokenId]
                .whitelistedBuyer);
    }

    /**
     * Payment is accepted in the following scenarios:
     * (1) Auction already created - can accept ETH or Specified Token
     *  --------> Cannot bid with ETH & an ERC20 Token together in any circumstance<------
     * (2) Auction not created - only ETH accepted (cannot early bid with an ERC20 Token
     * (3) Cannot make a zero bid (no ETH or Token amount)
     */
    function _isPaymentAccepted(
        address _nftContractAddress,
        uint256 _tokenId,
        address _bidERC20Token,
        uint128 _tokenAmount
    ) internal view returns (bool) {
        address auctionERC20Token = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].ERC20Token;
        if (_isERC20Auction(auctionERC20Token)) {
            return
                msg.value == 0 &&
                auctionERC20Token == _bidERC20Token &&
                _tokenAmount > 0;
        } else {
            return
                msg.value != 0 &&
                _bidERC20Token == address(0) &&
                _tokenAmount == 0;
        }
    }

    function _isERC20Auction(address _auctionERC20Token)
        internal
        pure
        returns (bool)
    {
        return _auctionERC20Token != address(0);
    }

    /*
     * Returns the percentage of the total bid (used to calculate fee payments)
     */
    function _getPortionOfBid(uint256 _totalBid, uint256 _percentage)
        internal
        pure
        returns (uint256)
    {
        return (_totalBid * (_percentage)) / 10000;
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║    AUCTION CHECK FUNCTIONS   ║
      ╚══════════════════════════════╝*/
    /**********************************/
    /*╔══════════════════════════════╗
      ║    DEFAULT GETTER FUNCTIONS  ║
      ╚══════════════════════════════╝*/
    /*****************************************************************
     * These functions check if the applicable auction parameter has *
     * been set by the NFT seller. If not, return the default value. *
     *****************************************************************/

    function _getBidIncreasePercentage(
        address _nftContractAddress,
        uint256 _tokenId
    ) internal view returns (uint32) {
        uint32 bidIncreasePercentage = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].bidIncreasePercentage;

        if (bidIncreasePercentage == 0) {
            return defaultBidIncreasePercentage;
        } else {
            return bidIncreasePercentage;
        }
    }

    function _getAuctionBidPeriod(address _nftContractAddress, uint256 _tokenId)
        internal
        view
        returns (uint32)
    {
        uint32 auctionBidPeriod = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].auctionBidPeriod;

        if (auctionBidPeriod == 0) {
            return defaultAuctionBidPeriod;
        } else {
            return auctionBidPeriod;
        }
    }

    /*
     * The default value for the NFT recipient is the highest bidder
     */
    function _getNftRecipient(address _nftContractAddress, uint256 _tokenId)
        internal
        view
        returns (address)
    {
        address nftRecipient = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftRecipient;

        if (nftRecipient == address(0)) {
            return
                nftContractAuctions[_nftContractAddress][_tokenId]
                    .nftHighestBidder;
        } else {
            return nftRecipient;
        }
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║    DEFAULT GETTER FUNCTIONS  ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║  TRANSFER NFTS TO CONTRACT   ║
      ╚══════════════════════════════╝*/
    function _transferNftToAuctionContract(
        address _nftContractAddress,
        uint256 _tokenId
    ) internal {
        address _nftSeller = nftContractAuctions[_nftContractAddress][_tokenId]
            .nftSeller;
        if (IERC721(_nftContractAddress).ownerOf(_tokenId) == _nftSeller) {
            IERC721(_nftContractAddress).transferFrom(
                _nftSeller,
                address(this),
                _tokenId
            );
            require(
                IERC721(_nftContractAddress).ownerOf(_tokenId) == address(this),
                "nft transfer failed"
            );
        } else {
            require(
                IERC721(_nftContractAddress).ownerOf(_tokenId) == address(this),
                "Seller doesn't own NFT"
            );
        }
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║  TRANSFER NFTS TO CONTRACT   ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║       AUCTION CREATION       ║
      ╚══════════════════════════════╝*/

    /**
     * Setup parameters applicable to all auctions and whitelised sales:
     * -> ERC20 Token for payment (if specified by the seller) : _erc20Token
     * -> minimum price : _minPrice
     * -> buy now price : _buyNowPrice
     * -> the nft seller: msg.sender
     * -> The fee recipients & their respective percentages for a sucessful auction/sale
     */
    function _setupAuction(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _minPrice,
        uint128 _buyNowPrice,
        address[] memory _feeRecipients,
        uint32[] memory _feePercentages
    )
        internal
        minPriceDoesNotExceedLimit(_buyNowPrice, _minPrice)
        correctFeeRecipientsAndPercentages(
            _feeRecipients.length,
            _feePercentages.length
        )
        isFeePercentagesLessThanMaximum(_feePercentages)
    {
        if (_erc20Token != address(0)) {
            nftContractAuctions[_nftContractAddress][_tokenId]
                .ERC20Token = _erc20Token;
        }
        nftContractAuctions[_nftContractAddress][_tokenId]
            .feeRecipients = _feeRecipients;
        nftContractAuctions[_nftContractAddress][_tokenId]
            .feePercentages = _feePercentages;
        nftContractAuctions[_nftContractAddress][_tokenId]
            .buyNowPrice = _buyNowPrice;
        nftContractAuctions[_nftContractAddress][_tokenId].minPrice = _minPrice;
        nftContractAuctions[_nftContractAddress][_tokenId].nftSeller = msg
            .sender;
    }

    function _createNewNftAuction(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _minPrice,
        uint128 _buyNowPrice,
        address[] memory _feeRecipients,
        uint32[] memory _feePercentages
    ) internal {
        // Sending the NFT to this contract
        _setupAuction(
            _nftContractAddress,
            _tokenId,
            _erc20Token,
            _minPrice,
            _buyNowPrice,
            _feeRecipients,
            _feePercentages
        );
        emit NftAuctionCreated(
            _nftContractAddress,
            _tokenId,
            msg.sender,
            _erc20Token,
            _minPrice,
            _buyNowPrice,
            _getAuctionBidPeriod(_nftContractAddress, _tokenId),
            _getBidIncreasePercentage(_nftContractAddress, _tokenId),
            _feeRecipients,
            _feePercentages
        );
        _updateOngoingAuction(_nftContractAddress, _tokenId);
    }

    /**
     * Create an auction that uses the default bid increase percentage
     * & the default auction bid period.
     */
    function createDefaultNftAuction(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _minPrice,
        uint128 _buyNowPrice,
        address[] memory _feeRecipients,
        uint32[] memory _feePercentages
    )
        external
        isAuctionNotStartedByOwner(_nftContractAddress, _tokenId)
        priceGreaterThanZero(_minPrice)
    {
        _createNewNftAuction(
            _nftContractAddress,
            _tokenId,
            _erc20Token,
            _minPrice,
            _buyNowPrice,
            _feeRecipients,
            _feePercentages
        );
    }

    function createNewNftAuction(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _minPrice,
        uint128 _buyNowPrice,
        uint32 _auctionBidPeriod, //this is the time that the auction lasts until another bid occurs
        uint32 _bidIncreasePercentage,
        address[] memory _feeRecipients,
        uint32[] memory _feePercentages
    )
        external
        isAuctionNotStartedByOwner(_nftContractAddress, _tokenId)
        priceGreaterThanZero(_minPrice)
        increasePercentageAboveMinimum(_bidIncreasePercentage)
    {
        nftContractAuctions[_nftContractAddress][_tokenId]
            .auctionBidPeriod = _auctionBidPeriod;
        nftContractAuctions[_nftContractAddress][_tokenId]
            .bidIncreasePercentage = _bidIncreasePercentage;
        _createNewNftAuction(
            _nftContractAddress,
            _tokenId,
            _erc20Token,
            _minPrice,
            _buyNowPrice,
            _feeRecipients,
            _feePercentages
        );
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║       AUCTION CREATION       ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║            SALES             ║
      ╚══════════════════════════════╝*/

    /********************************************************************
     * Allows for a standard sale mechanism where the NFT seller can    *
     * can select an address to be whitelisted. This address is then    *
     * allowed to make a bid on the NFT. No other address can bid on    *
     * the NFT.                                                         *
     ********************************************************************/
    function _setupSale(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _buyNowPrice,
        address _whitelistedBuyer,
        address[] memory _feeRecipients,
        uint32[] memory _feePercentages
    )
        internal
        correctFeeRecipientsAndPercentages(
            _feeRecipients.length,
            _feePercentages.length
        )
        isFeePercentagesLessThanMaximum(_feePercentages)
    {
        if (_erc20Token != address(0)) {
            nftContractAuctions[_nftContractAddress][_tokenId]
                .ERC20Token = _erc20Token;
        }
        nftContractAuctions[_nftContractAddress][_tokenId]
            .feeRecipients = _feeRecipients;
        nftContractAuctions[_nftContractAddress][_tokenId]
            .feePercentages = _feePercentages;
        nftContractAuctions[_nftContractAddress][_tokenId]
            .buyNowPrice = _buyNowPrice;
        nftContractAuctions[_nftContractAddress][_tokenId]
            .whitelistedBuyer = _whitelistedBuyer;
        nftContractAuctions[_nftContractAddress][_tokenId].nftSeller = msg
            .sender;
    }

    function createSale(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _buyNowPrice,
        address _whitelistedBuyer,
        address[] memory _feeRecipients,
        uint32[] memory _feePercentages
    )
        external
        isAuctionNotStartedByOwner(_nftContractAddress, _tokenId)
        priceGreaterThanZero(_buyNowPrice)
    {
        //min price = 0
        _setupSale(
            _nftContractAddress,
            _tokenId,
            _erc20Token,
            _buyNowPrice,
            _whitelistedBuyer,
            _feeRecipients,
            _feePercentages
        );

        emit SaleCreated(
            _nftContractAddress,
            _tokenId,
            msg.sender,
            _erc20Token,
            _buyNowPrice,
            _whitelistedBuyer,
            _feeRecipients,
            _feePercentages
        );
        //check if buyNowPrice is meet and conclude sale, otherwise reverse the early bid
        if (_isABidMade(_nftContractAddress, _tokenId)) {
            if (
                //we only revert the underbid if the seller specifies a different
                //whitelisted buyer to the highest bidder
                _isHighestBidderAllowedToPurchaseNFT(
                    _nftContractAddress,
                    _tokenId
                )
            ) {
                if (_isBuyNowPriceMet(_nftContractAddress, _tokenId)) {
                    _transferNftToAuctionContract(
                        _nftContractAddress,
                        _tokenId
                    );
                    _transferNftAndPaySeller(_nftContractAddress, _tokenId);
                }
            } else {
                _reverseAndResetPreviousBid(_nftContractAddress, _tokenId);
            }
        }
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║            SALES             ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔═════════════════════════════╗
      ║        BID FUNCTIONS        ║
      ╚═════════════════════════════╝*/

    /********************************************************************
     * Make bids with ETH or an ERC20 Token specified by the NFT seller.*
     * Additionally, a buyer can pay the asking price to conclude a sale*
     * of an NFT.                                                      *
     ********************************************************************/

    function _makeBid(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _tokenAmount
    )
        internal
        hasWhitelistedToken
        notNftSeller(_nftContractAddress, _tokenId)
        paymentAccepted(
            _nftContractAddress,
            _tokenId,
            _erc20Token,
            _tokenAmount
        )
        bidAmountMeetsBidRequirements(
            _nftContractAddress,
            _tokenId,
            _tokenAmount
        )
    {
        _reversePreviousBidAndUpdateHighestBid(
            _nftContractAddress,
            _tokenId,
            _tokenAmount
        );
        emit BidMade(
            _nftContractAddress,
            _tokenId,
            msg.sender,
            msg.value,
            _erc20Token,
            _tokenAmount
        );
        _updateOngoingAuction(_nftContractAddress, _tokenId);
    }

    function makeBid(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _tokenAmount
    )
        external
        payable
        auctionOngoing(_nftContractAddress, _tokenId)
        onlyApplicableBuyer(_nftContractAddress, _tokenId)
    {
        _makeBid(_nftContractAddress, _tokenId, _erc20Token, _tokenAmount);
    }

    function makeCustomBid(
        address _nftContractAddress,
        uint256 _tokenId,
        address _erc20Token,
        uint128 _tokenAmount,
        address _nftRecipient
    )
        external
        payable
        auctionOngoing(_nftContractAddress, _tokenId)
        notZeroAddress(_nftRecipient)
        onlyApplicableBuyer(_nftContractAddress, _tokenId)
    {
        nftContractAuctions[_nftContractAddress][_tokenId]
            .nftRecipient = _nftRecipient;
        _makeBid(_nftContractAddress, _tokenId, _erc20Token, _tokenAmount);
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║        BID FUNCTIONS         ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║       UPDATE AUCTION         ║
      ╚══════════════════════════════╝*/

    /***************************************************************
     * Settle an auction or sale if the buyNowPrice is met or set  *
     *  auction period to begin if the minimum price has been met. *
     ***************************************************************/
    function _updateOngoingAuction(
        address _nftContractAddress,
        uint256 _tokenId
    ) internal {
        if (_isBuyNowPriceMet(_nftContractAddress, _tokenId)) {
            _transferNftToAuctionContract(_nftContractAddress, _tokenId);
            _transferNftAndPaySeller(_nftContractAddress, _tokenId);
            return;
        }
        //min price not set, nft not up for auction yet
        if (_isMinimumBidMade(_nftContractAddress, _tokenId)) {
            _transferNftToAuctionContract(_nftContractAddress, _tokenId);
            _updateAuctionEnd(_nftContractAddress, _tokenId);
        }
    }

    function _updateAuctionEnd(address _nftContractAddress, uint256 _tokenId)
        internal
    {
        //the auction end is always set to now + the bid period
        nftContractAuctions[_nftContractAddress][_tokenId].auctionEnd =
            _getAuctionBidPeriod(_nftContractAddress, _tokenId) +
            uint64(block.timestamp);
        emit AuctionPeriodUpdated(
            _nftContractAddress,
            _tokenId,
            nftContractAuctions[_nftContractAddress][_tokenId].auctionEnd
        );
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║       UPDATE AUCTION         ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║       RESET FUNCTIONS        ║
      ╚══════════════════════════════╝*/

    /*
     * Reset all auction related parameters for an NFT.
     * This effectively removes an EFT as an item up for auction
     */
    function _resetAuction(address _nftContractAddress, uint256 _tokenId)
        internal
    {
        nftContractAuctions[_nftContractAddress][_tokenId].minPrice = 0;
        nftContractAuctions[_nftContractAddress][_tokenId].buyNowPrice = 0;
        nftContractAuctions[_nftContractAddress][_tokenId].auctionEnd = 0;
        nftContractAuctions[_nftContractAddress][_tokenId].auctionBidPeriod = 0;
        nftContractAuctions[_nftContractAddress][_tokenId]
            .bidIncreasePercentage = 0;
        nftContractAuctions[_nftContractAddress][_tokenId].nftSeller = address(
            0
        );
        nftContractAuctions[_nftContractAddress][_tokenId]
            .whitelistedBuyer = address(0);
        nftContractAuctions[_nftContractAddress][_tokenId].ERC20Token = address(
            0
        );
    }

    /*
     * Reset all bid related parameters for an NFT.
     * This effectively sets an NFT as having no active bids
     */
    function _resetBids(address _nftContractAddress, uint256 _tokenId)
        internal
    {
        nftContractAuctions[_nftContractAddress][_tokenId]
            .nftHighestBidder = address(0);
        nftContractAuctions[_nftContractAddress][_tokenId].nftHighestBid = 0;
        nftContractAuctions[_nftContractAddress][_tokenId]
            .nftRecipient = address(0);
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║       RESET FUNCTIONS        ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║         UPDATE BIDS          ║
      ╚══════════════════════════════╝*/
    /******************************************************************
     * Internal functions that update bid parameters and reverse bids *
     * to ensure contract only holds the highest bid.                 *
     ******************************************************************/
    function _updateHighestBid(
        address _nftContractAddress,
        uint256 _tokenId,
        uint128 _tokenAmount
    ) internal {
        address auctionERC20Token = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].ERC20Token;
        if (_isERC20Auction(auctionERC20Token)) {
            IERC20(auctionERC20Token).transferFrom(
                msg.sender,
                address(this),
                _tokenAmount
            );
            nftContractAuctions[_nftContractAddress][_tokenId]
                .nftHighestBid = _tokenAmount;
        } else {
            nftContractAuctions[_nftContractAddress][_tokenId]
                .nftHighestBid = uint128(msg.value);
        }
        nftContractAuctions[_nftContractAddress][_tokenId]
            .nftHighestBidder = msg.sender;
    }

    function _reverseAndResetPreviousBid(
        address _nftContractAddress,
        uint256 _tokenId
    ) internal {
        address nftHighestBidder = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBidder;

        uint128 nftHighestBid = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBid;
        _resetBids(_nftContractAddress, _tokenId);

        _payout(_nftContractAddress, _tokenId, nftHighestBidder, nftHighestBid);
    }

    function _reversePreviousBidAndUpdateHighestBid(
        address _nftContractAddress,
        uint256 _tokenId,
        uint128 _tokenAmount
    ) internal {
        address prevNftHighestBidder = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBidder;

        uint256 prevNftHighestBid = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBid;
        _updateHighestBid(_nftContractAddress, _tokenId, _tokenAmount);

        if (prevNftHighestBidder != address(0)) {
            _payout(
                _nftContractAddress,
                _tokenId,
                prevNftHighestBidder,
                prevNftHighestBid
            );
        }
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║         UPDATE BIDS          ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║  TRANSFER NFT & PAY SELLER   ║
      ╚══════════════════════════════╝*/
    function _transferNftAndPaySeller(
        address _nftContractAddress,
        uint256 _tokenId
    ) internal {
        address _nftSeller = nftContractAuctions[_nftContractAddress][_tokenId]
            .nftSeller;
        address _nftHighestBidder = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBidder;
        address _nftRecipient = _getNftRecipient(_nftContractAddress, _tokenId);
        uint128 _nftHighestBid = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBid;
        _resetBids(_nftContractAddress, _tokenId);

        _payFeesAndSeller(
            _nftContractAddress,
            _tokenId,
            _nftSeller,
            _nftHighestBid
        );
        IERC721(_nftContractAddress).transferFrom(
            address(this),
            _nftRecipient,
            _tokenId
        );

        _resetAuction(_nftContractAddress, _tokenId);
        emit NFTTransferredAndSellerPaid(
            _nftContractAddress,
            _tokenId,
            _nftSeller,
            _nftHighestBid,
            _nftHighestBidder,
            _nftRecipient
        );
    }

    function _payFeesAndSeller(
        address _nftContractAddress,
        uint256 _tokenId,
        address _nftSeller,
        uint256 _highestBid
    ) internal {
        uint256 feesPaid;
        for (
            uint256 i = 0;
            i <
            nftContractAuctions[_nftContractAddress][_tokenId]
                .feeRecipients
                .length;
            i++
        ) {
            uint256 fee = _getPortionOfBid(
                _highestBid,
                nftContractAuctions[_nftContractAddress][_tokenId]
                    .feePercentages[i]
            );
            feesPaid = feesPaid + fee;
            _payout(
                _nftContractAddress,
                _tokenId,
                nftContractAuctions[_nftContractAddress][_tokenId]
                    .feeRecipients[i],
                fee
            );
        }
        _payout(
            _nftContractAddress,
            _tokenId,
            _nftSeller,
            (_highestBid - feesPaid)
        );
    }

    function _payout(
        address _nftContractAddress,
        uint256 _tokenId,
        address _recipient,
        uint256 _amount
    ) internal {
        address auctionERC20Token = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].ERC20Token;
        if (_isERC20Auction(auctionERC20Token)) {
            IERC20(auctionERC20Token).transfer(_recipient, _amount);
        } else {
            // attempt to send the funds to the recipient
            (bool success, ) = payable(_recipient).call{
                value: _amount,
                gas: 20000
            }("");
            // if it failed, update their credit balance so they can pull it later
            if (!success) {
                failedTransferCredits[_recipient] =
                    failedTransferCredits[_recipient] +
                    _amount;
            }
        }
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║  TRANSFER NFT & PAY SELLER   ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║      SETTLE & WITHDRAW       ║
      ╚══════════════════════════════╝*/
    function settleAuction(address _nftContractAddress, uint256 _tokenId)
        external
        isAuctionOver(_nftContractAddress, _tokenId)
    {
        _transferNftAndPaySeller(_nftContractAddress, _tokenId);
        emit AuctionSettled(_nftContractAddress, _tokenId, msg.sender);
    }

    function withdrawAuction(address _nftContractAddress, uint256 _tokenId)
        external
    {
        //only the NFT owner can prematurely close and auction
        require(
            IERC721(_nftContractAddress).ownerOf(_tokenId) == msg.sender,
            "Not NFT owner"
        );
        _resetAuction(_nftContractAddress, _tokenId);
        emit AuctionWithdrawn(_nftContractAddress, _tokenId, msg.sender);
    }

    function withdrawBid(address _nftContractAddress, uint256 _tokenId)
        external
        minimumBidNotMade(_nftContractAddress, _tokenId)
    {
        address nftHighestBidder = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBidder;
        require(msg.sender == nftHighestBidder, "Cannot withdraw funds");

        uint128 nftHighestBid = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBid;
        _resetBids(_nftContractAddress, _tokenId);

        _payout(_nftContractAddress, _tokenId, nftHighestBidder, nftHighestBid);

        emit BidWithdrawn(_nftContractAddress, _tokenId, msg.sender);
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║      SETTLE & WITHDRAW       ║
      ╚══════════════════════════════╝*/
    /**********************************/

    /*╔══════════════════════════════╗
      ║       UPDATE AUCTION         ║
      ╚══════════════════════════════╝*/
    function updateWhitelistedBuyer(
        address _nftContractAddress,
        uint256 _tokenId,
        address _newWhitelistedBuyer
    ) external onlyNftSeller(_nftContractAddress, _tokenId) {
        require(_isASale(_nftContractAddress, _tokenId), "Not a sale");
        nftContractAuctions[_nftContractAddress][_tokenId]
            .whitelistedBuyer = _newWhitelistedBuyer;
        //if an underbid is by a non whitelisted buyer,reverse that bid
        address nftHighestBidder = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBidder;
        uint128 nftHighestBid = nftContractAuctions[_nftContractAddress][
            _tokenId
        ].nftHighestBid;
        if (nftHighestBid > 0 && !(nftHighestBidder == _newWhitelistedBuyer)) {
            //we only revert the underbid if the seller specifies a different
            //whitelisted buyer to the highest bider

            _resetBids(_nftContractAddress, _tokenId);

            _payout(
                _nftContractAddress,
                _tokenId,
                nftHighestBidder,
                nftHighestBid
            );
        }

        emit WhitelistedBuyerUpdated(
            _nftContractAddress,
            _tokenId,
            _newWhitelistedBuyer
        );
    }

    function updateMinimumPrice(
        address _nftContractAddress,
        uint256 _tokenId,
        uint128 _newMinPrice
    )
        external
        onlyNftSeller(_nftContractAddress, _tokenId)
        minimumBidNotMade(_nftContractAddress, _tokenId)
        isNotASale(_nftContractAddress, _tokenId)
        priceGreaterThanZero(_newMinPrice)
        minPriceDoesNotExceedLimit(
            nftContractAuctions[_nftContractAddress][_tokenId].buyNowPrice,
            _newMinPrice
        )
    {
        nftContractAuctions[_nftContractAddress][_tokenId]
            .minPrice = _newMinPrice;

        emit MinimumPriceUpdated(_nftContractAddress, _tokenId, _newMinPrice);

        if (_isMinimumBidMade(_nftContractAddress, _tokenId)) {
            _transferNftToAuctionContract(_nftContractAddress, _tokenId);
            _updateAuctionEnd(_nftContractAddress, _tokenId);
        }
    }

    function updateBuyNowPrice(
        address _nftContractAddress,
        uint256 _tokenId,
        uint128 _newBuyNowPrice
    )
        external
        onlyNftSeller(_nftContractAddress, _tokenId)
        priceGreaterThanZero(_newBuyNowPrice)
        minPriceDoesNotExceedLimit(
            _newBuyNowPrice,
            nftContractAuctions[_nftContractAddress][_tokenId].minPrice
        )
    {
        nftContractAuctions[_nftContractAddress][_tokenId]
            .buyNowPrice = _newBuyNowPrice;
        emit BuyNowPriceUpdated(_nftContractAddress, _tokenId, _newBuyNowPrice);
        if (_isBuyNowPriceMet(_nftContractAddress, _tokenId)) {
            _transferNftToAuctionContract(_nftContractAddress, _tokenId);
            _transferNftAndPaySeller(_nftContractAddress, _tokenId);
        }
    }

    /*
     * The NFT seller can opt to end an auction by taking the current highest bid.
     */
    function takeHighestBid(address _nftContractAddress, uint256 _tokenId)
        external
        onlyNftSeller(_nftContractAddress, _tokenId)
    {
        require(
            _isABidMade(_nftContractAddress, _tokenId),
            "cannot payout 0 bid"
        );
        _transferNftToAuctionContract(_nftContractAddress, _tokenId);
        _transferNftAndPaySeller(_nftContractAddress, _tokenId);
        emit HighestBidTaken(_nftContractAddress, _tokenId);
    }

    /*
     * Query the owner of an NFT deposited for auction
     */
    function ownerOfNFT(address _nftContractAddress, uint256 _tokenId)
        external
        view
        returns (address)
    {
        address nftSeller = nftContractAuctions[_nftContractAddress][_tokenId]
            .nftSeller;
        require(nftSeller != address(0), "NFT not deposited");

        return nftSeller;
    }

    /*
     * If the transfer of a bid has failed, allow the recipient to reclaim their amount later.
     */
    function withdrawAllFailedCredits() external {
        uint256 amount = failedTransferCredits[msg.sender];

        require(amount != 0, "no credits to withdraw");

        failedTransferCredits[msg.sender] = 0;

        (bool successfulWithdraw, ) = msg.sender.call{
            value: amount,
            gas: 20000
        }("");
        require(successfulWithdraw, "withdraw failed");
    }

    /**********************************/
    /*╔══════════════════════════════╗
      ║             END              ║
      ║       UPDATE AUCTION         ║
      ╚══════════════════════════════╝*/
    /**********************************/
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "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

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

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}

// SPDX-License-Identifier: MIT

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

pragma solidity ^0.8.0;

import "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 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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IWithBalance {
    function balanceOf(address owner) external view returns (uint256);
}

Settings
{
  "evmVersion": "istanbul",
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "libraries": {
    "NFTAuction.sol": {}
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address[]","name":"_whitelistedPassCollectionsAddresses","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"auctionEndPeriod","type":"uint64"}],"name":"AuctionPeriodUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"auctionSettler","type":"address"}],"name":"AuctionSettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"nftOwner","type":"address"}],"name":"AuctionWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"erc20Token","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"BidMade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"highestBidder","type":"address"}],"name":"BidWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"newBuyNowPrice","type":"uint128"}],"name":"BuyNowPriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"HighestBidTaken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinPrice","type":"uint256"}],"name":"MinimumPriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"nftSeller","type":"address"},{"indexed":false,"internalType":"uint128","name":"nftHighestBid","type":"uint128"},{"indexed":false,"internalType":"address","name":"nftHighestBidder","type":"address"},{"indexed":false,"internalType":"address","name":"nftRecipient","type":"address"}],"name":"NFTTransferredAndSellerPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"nftSeller","type":"address"},{"indexed":false,"internalType":"address","name":"erc20Token","type":"address"},{"indexed":false,"internalType":"uint128","name":"minPrice","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"buyNowPrice","type":"uint128"},{"indexed":false,"internalType":"uint32","name":"auctionBidPeriod","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"bidIncreasePercentage","type":"uint32"},{"indexed":false,"internalType":"address[]","name":"feeRecipients","type":"address[]"},{"indexed":false,"internalType":"uint32[]","name":"feePercentages","type":"uint32[]"}],"name":"NftAuctionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"nftSeller","type":"address"},{"indexed":false,"internalType":"address","name":"erc20Token","type":"address"},{"indexed":false,"internalType":"uint128","name":"buyNowPrice","type":"uint128"},{"indexed":false,"internalType":"address","name":"whitelistedBuyer","type":"address"},{"indexed":false,"internalType":"address[]","name":"feeRecipients","type":"address[]"},{"indexed":false,"internalType":"uint32[]","name":"feePercentages","type":"uint32[]"}],"name":"SaleCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"newWhitelistedBuyer","type":"address"}],"name":"WhitelistedBuyerUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"_collectionContractAddress","type":"address"}],"name":"addWhitelistedCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_erc20Token","type":"address"},{"internalType":"uint128","name":"_minPrice","type":"uint128"},{"internalType":"uint128","name":"_buyNowPrice","type":"uint128"},{"internalType":"address[]","name":"_feeRecipients","type":"address[]"},{"internalType":"uint32[]","name":"_feePercentages","type":"uint32[]"}],"name":"createDefaultNftAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_erc20Token","type":"address"},{"internalType":"uint128","name":"_minPrice","type":"uint128"},{"internalType":"uint128","name":"_buyNowPrice","type":"uint128"},{"internalType":"uint32","name":"_auctionBidPeriod","type":"uint32"},{"internalType":"uint32","name":"_bidIncreasePercentage","type":"uint32"},{"internalType":"address[]","name":"_feeRecipients","type":"address[]"},{"internalType":"uint32[]","name":"_feePercentages","type":"uint32[]"}],"name":"createNewNftAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_erc20Token","type":"address"},{"internalType":"uint128","name":"_buyNowPrice","type":"uint128"},{"internalType":"address","name":"_whitelistedBuyer","type":"address"},{"internalType":"address[]","name":"_feeRecipients","type":"address[]"},{"internalType":"uint32[]","name":"_feePercentages","type":"uint32[]"}],"name":"createSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultAuctionBidPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultBidIncreasePercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_erc20Token","type":"address"},{"internalType":"uint128","name":"_tokenAmount","type":"uint128"}],"name":"makeBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_erc20Token","type":"address"},{"internalType":"uint128","name":"_tokenAmount","type":"uint128"},{"internalType":"address","name":"_nftRecipient","type":"address"}],"name":"makeCustomBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"maximumMinPricePercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumSettableIncreasePercentage","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftContractAuctions","outputs":[{"internalType":"uint32","name":"bidIncreasePercentage","type":"uint32"},{"internalType":"uint32","name":"auctionBidPeriod","type":"uint32"},{"internalType":"uint64","name":"auctionEnd","type":"uint64"},{"internalType":"uint128","name":"minPrice","type":"uint128"},{"internalType":"uint128","name":"buyNowPrice","type":"uint128"},{"internalType":"uint128","name":"nftHighestBid","type":"uint128"},{"internalType":"address","name":"nftHighestBidder","type":"address"},{"internalType":"address","name":"nftSeller","type":"address"},{"internalType":"address","name":"whitelistedBuyer","type":"address"},{"internalType":"address","name":"nftRecipient","type":"address"},{"internalType":"address","name":"ERC20Token","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"ownerOfNFT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"removeWhitelistedCollection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"settleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"takeHighestBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint128","name":"_newBuyNowPrice","type":"uint128"}],"name":"updateBuyNowPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint128","name":"_newMinPrice","type":"uint128"}],"name":"updateMinimumPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_newWhitelistedBuyer","type":"address"}],"name":"updateWhitelistedBuyer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whitelistedPassCollections","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAllFailedCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"withdrawAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"withdrawBid","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040516200408e3803806200408e833981016040819052620000349162000147565b600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600480546001600160801b0319166e01518000001f400000006400000064179055805160005b818110156200010b576001838281518110620000bb57620000bb62000219565b60209081029190910181015182546001810184556000938452919092200180546001600160a01b0319166001600160a01b039092169190911790558062000102816200022f565b9150506200009b565b50505062000257565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200014257600080fd5b919050565b600060208083850312156200015b57600080fd5b82516001600160401b03808211156200017357600080fd5b818501915085601f8301126200018857600080fd5b8151818111156200019d576200019d62000114565b8060051b604051601f19603f83011681018181108582111715620001c557620001c562000114565b604052918252848201925083810185019188831115620001e457600080fd5b938501935b828510156200020d57620001fd856200012a565b84529385019392850192620001e9565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b6000600182016200025057634e487b7160e01b600052601160045260246000fd5b5060010190565b613e2780620002676000396000f3fe6080604052600436106101665760003560e01c80639041e273116100d1578063d18e629c1161008a578063f2fde38b11610064578063f2fde38b1461052f578063f45671f11461054f578063f583bac71461056f578063f7f829a41461058f57600080fd5b8063d18e629c146104cf578063db227338146104ef578063ebea60251461050f57600080fd5b80639041e2731461042657806399157d70146104465780639c0b996614610466578063b6ad691414610483578063c24d5a5c14610498578063cd4eda1c146104ab57600080fd5b80634cb8ef5b116101235780634cb8ef5b146103805780635138b08c146103a0578063565c5172146103c0578063715018a6146103d3578063848e5c77146103e85780638da5cb5b1461040857600080fd5b8063041fa0b81461016b578063076b73ac146102a8578063186779d5146102ca57806320950fc6146103035780632f9c95761461033b5780633d87d5fb1461035b575b600080fd5b34801561017757600080fd5b5061021f610186366004613471565b60026020818152600093845260408085209091529183529120805460018201549282015460038301546004840154600585015460069095015463ffffffff8086169764010000000087049091169667ffffffffffffffff600160401b880416966001600160801b03600160801b91829004811697848216979290940416946001600160a01b03938416949184169390811692811691168b565b6040805163ffffffff9c8d1681529b909a1660208c015267ffffffffffffffff909816988a01989098526001600160801b0395861660608a015293851660808901529390911660a08701526001600160a01b0390811660c087015291821660e0860152811661010085015291821661012084015216610140820152610160015b60405180910390f35b3480156102b457600080fd5b506102c86102c336600461349d565b6105af565b005b3480156102d657600080fd5b506004546102ee90600160601b900463ffffffff1681565b60405163ffffffff909116815260200161029f565b34801561030f57600080fd5b5061032361031e366004613471565b610727565b6040516001600160a01b03909116815260200161029f565b34801561034757600080fd5b506102c86103563660046134fb565b61079c565b34801561036757600080fd5b506004546102ee90640100000000900463ffffffff1681565b34801561038c57600080fd5b506102c861039b366004613471565b610a10565b3480156103ac57600080fd5b506102c86103bb366004613471565b610b71565b6102c86103ce366004613539565b610c15565b3480156103df57600080fd5b506102c8610d97565b3480156103f457600080fd5b506102c8610403366004613471565b610e0b565b34801561041457600080fd5b506000546001600160a01b0316610323565b34801561043257600080fd5b506102c86104413660046136f4565b610ef5565b34801561045257600080fd5b506103236104613660046137a8565b61104b565b34801561047257600080fd5b506004546102ee9063ffffffff1681565b34801561048f57600080fd5b506102c8611075565b6102c86104a63660046137c1565b611170565b3480156104b757600080fd5b506004546102ee90600160401b900463ffffffff1681565b3480156104db57600080fd5b506102c86104ea366004613812565b61125d565b3480156104fb57600080fd5b506102c861050a3660046137a8565b6112d8565b34801561051b57600080fd5b506102c861052a366004613471565b6113b1565b34801561053b57600080fd5b506102c861054a366004613812565b6114ab565b34801561055b57600080fd5b506102c861056a36600461382f565b611595565b34801561057b57600080fd5b506102c861058a36600461388a565b611780565b34801561059b57600080fd5b506102c86105aa3660046134fb565b6119fb565b6001600160a01b038381166000908152600260209081526040808320868452909152902060030154849184911633146106035760405162461bcd60e51b81526004016105fa90613960565b60405180910390fd5b61060d8585611b9b565b6106465760405162461bcd60e51b815260206004820152600a6024820152694e6f7420612073616c6560b01b60448201526064016105fa565b6001600160a01b0385811660009081526002602081815260408084208985529091529091206004810180546001600160a01b03191687851617905590810154600190910154911690600160801b90046001600160801b031680158015906106bf5750846001600160a01b0316826001600160a01b031614155b156106e3576106ce8787611c0e565b6106e3878784846001600160801b0316611c67565b7f7502912f483c1fb3f89bf8664bea10db517c2093040d379e78e169e06752364687878760405161071693929190613989565b60405180910390a150505050505050565b6001600160a01b038083166000908152600260209081526040808320858452909152812060030154909116806107935760405162461bcd60e51b8152602060048201526011602482015270139195081b9bdd0819195c1bdcda5d1959607a1b60448201526064016105fa565b90505b92915050565b6001600160a01b038381166000908152600260209081526040808320868452909152902060030154849184911633146107e75760405162461bcd60e51b81526004016105fa90613960565b84846107f38282611db6565b156108405760405162461bcd60e51b815260206004820181905260248201527f5468652061756374696f6e2068617320612076616c696420626964206d61646560448201526064016105fa565b868661084c8282611b9b565b156108995760405162461bcd60e51b815260206004820152601960248201527f4e6f74206170706c696361626c6520666f7220612073616c650000000000000060448201526064016105fa565b866001600160801b0316600081116108c35760405162461bcd60e51b81526004016105fa906139ac565b6001600160a01b038a1660009081526002602090815260408083208c84529091529020600101546001600160801b03168881158061092757506004546001600160801b038281169161092491851690600160401b900463ffffffff16611e3a565b10155b6109435760405162461bcd60e51b81526004016105fa906139d7565b6001600160a01b038c1660009081526002602090815260408083208e84529091529081902080546001600160801b03808e16600160801b029116179055517fdcf27af4c564afa0c536dd1fa48e5fef0d9833378a1bddacc95922b902ebfc32906109d7908e908e908e906001600160a01b0393909316835260208301919091526001600160801b0316604082015260600190565b60405180910390a16109e98c8c611db6565b15610a02576109f88c8c611e53565b610a028c8c6120cc565b505050505050505050505050565b8181610a1c8282611db6565b15610a695760405162461bcd60e51b815260206004820181905260248201527f5468652061756374696f6e2068617320612076616c696420626964206d61646560448201526064016105fa565b6001600160a01b038085166000908152600260208181526040808420888552909152909120015416338114610ad85760405162461bcd60e51b815260206004820152601560248201527443616e6e6f742077697468647261772066756e647360581b60448201526064016105fa565b6001600160a01b0385166000908152600260209081526040808320878452909152902060010154600160801b90046001600160801b0316610b198686611c0e565b610b2e868684846001600160801b0316611c67565b7f10d9bddf66f639dd3c5a6ad2db5ae3102c2b468dfb90a4b0da219435f24a970d868633604051610b6193929190613989565b60405180910390a1505050505050565b8181610b7d828261217b565b15610bca5760405162461bcd60e51b815260206004820152601760248201527f41756374696f6e206973206e6f7420796574206f76657200000000000000000060448201526064016105fa565b610bd484846121cb565b7fe6b94748c5d6e0d188a0fcb9b7f2973b01fc0095627f1ec5accdcd9d2e65ca36848433604051610c0793929190613989565b60405180910390a150505050565b8484610c21828261217b565b610c615760405162461bcd60e51b8152602060048201526011602482015270105d58dd1a5bdb881a185cc8195b991959607a1b60448201526064016105fa565b826001600160a01b038116610cb85760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f74207370656369667920302061646472657373000000000000000060448201526064016105fa565b8787610cc4828261233d565b1580610cf757506001600160a01b0382811660009081526002602090815260408083208584529091529020600401541633145b610d435760405162461bcd60e51b815260206004820152601a60248201527f4f6e6c79207468652077686974656c697374656420627579657200000000000060448201526064016105fa565b6001600160a01b038a811660009081526002602090815260408083208d8452909152902060050180546001600160a01b031916918816919091179055610d8b8a8a8a8a61236a565b50505050505050505050565b6000546001600160a01b03163314610dc15760405162461bcd60e51b81526004016105fa90613a0e565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6001600160a01b03828116600090815260026020908152604080832085845290915290206003015483918391163314610e565760405162461bcd60e51b81526004016105fa90613960565b610e608484612638565b610ea25760405162461bcd60e51b815260206004820152601360248201527218d85b9b9bdd081c185e5bdd5d080c08189a59606a1b60448201526064016105fa565b610eac8484611e53565b610eb684846121cb565b604080516001600160a01b0386168152602081018590527f711f4eae05533b90c24ff0ae762d6e9e1ef1b2c85d4c484a2913c5201bcbb7c99101610c07565b6001600160a01b0380881660009081526002602090815260408083208a84529091529020600301548891889133911603610f415760405162461bcd60e51b81526004016105fa90613a43565b6001600160a01b0382811660009081526002602090815260408083208584529091529020600301541615611012576040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa158015610fb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd89190613a78565b6001600160a01b0316336001600160a01b0316146110085760405162461bcd60e51b81526004016105fa90613a95565b6110128282612675565b856001600160801b03166000811161103c5760405162461bcd60e51b81526004016105fa906139ac565b610d8b8a8a8a8a8a8a8a6126dd565b6001818154811061105b57600080fd5b6000918252602090912001546001600160a01b0316905081565b33600090815260036020526040812054908190036110ce5760405162461bcd60e51b81526020600482015260166024820152756e6f206372656469747320746f20776974686472617760501b60448201526064016105fa565b3360008181526003602052604080822082905551909190614e2090849084818181858888f193505050503d8060008114611124576040519150601f19603f3d011682016040523d82523d6000602084013e611129565b606091505b505090508061116c5760405162461bcd60e51b815260206004820152600f60248201526e1dda5d1a191c985dc819985a5b1959608a1b60448201526064016105fa565b5050565b838361117c828261217b565b6111bc5760405162461bcd60e51b8152602060048201526011602482015270105d58dd1a5bdb881a185cc8195b991959607a1b60448201526064016105fa565b85856111c8828261233d565b15806111fb57506001600160a01b0382811660009081526002602090815260408083208584529091529020600401541633145b6112475760405162461bcd60e51b815260206004820152601a60248201527f4f6e6c79207468652077686974656c697374656420627579657200000000000060448201526064016105fa565b6112538888888861236a565b5050505050505050565b6000546001600160a01b031633146112875760405162461bcd60e51b81526004016105fa90613a0e565b6001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146113025760405162461bcd60e51b81526004016105fa90613a0e565b60018054611311908290613adb565b8154811061132157611321613af2565b600091825260209091200154600180546001600160a01b03909216918390811061134d5761134d613af2565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600180548061138c5761138c613b08565b600082815260209020810160001990810180546001600160a01b031916905501905550565b6040516331a9108f60e11b81526004810182905233906001600160a01b03841690636352211e90602401602060405180830381865afa1580156113f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141c9190613a78565b6001600160a01b0316146114625760405162461bcd60e51b815260206004820152600d60248201526c2737ba1027232a1037bbb732b960991b60448201526064016105fa565b61146c8282612675565b7fec19f84af4aad6523d37faa19e243c77717842cca9bf492dc5379830cac958d082823360405161149f93929190613989565b60405180910390a15050565b6000546001600160a01b031633146114d55760405162461bcd60e51b81526004016105fa90613a0e565b6001600160a01b03811661153a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105fa565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0380881660009081526002602090815260408083208a845290915290206003015488918891339116036115e15760405162461bcd60e51b81526004016105fa90613a43565b6001600160a01b03828116600090815260026020908152604080832085845290915290206003015416156116b2576040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa158015611654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116789190613a78565b6001600160a01b0316336001600160a01b0316146116a85760405162461bcd60e51b81526004016105fa90613a95565b6116b28282612675565b856001600160801b0316600081116116dc5760405162461bcd60e51b81526004016105fa906139ac565b6116eb8a8a8a8a8a8a8a61275a565b7fb4cb1faa7b4f2b837334e4a12fb94a1cfc320c32b70dd31e113d1795b9d0f0568a8a338b8b8b8b8b604051611728989796959493929190613b98565b60405180910390a161173a8a8a612638565b15610d8b576117498a8a612980565b15611776576117588a8a6129ca565b15611771576117678a8a611e53565b6117718a8a6121cb565b610d8b565b610d8b8a8a612a4a565b6001600160a01b03808a1660009081526002602090815260408083208c84529091529020600301548a918a91339116036117cc5760405162461bcd60e51b81526004016105fa90613a43565b6001600160a01b038281166000908152600260209081526040808320858452909152902060030154161561189d576040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa15801561183f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118639190613a78565b6001600160a01b0316336001600160a01b0316146118935760405162461bcd60e51b81526004016105fa90613a95565b61189d8282612675565b876001600160801b0316600081116118c75760405162461bcd60e51b81526004016105fa906139ac565b600454869063ffffffff6401000000009091048116908216101561192d5760405162461bcd60e51b815260206004820152601f60248201527f42696420696e6372656173652070657263656e7461676520746f6f206c6f770060448201526064016105fa565b87600260008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e815260200190815260200160002060000160046101000a81548163ffffffff021916908363ffffffff16021790555086600260008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff1602179055506119ec8d8d8d8d8d8b8b6126dd565b50505050505050505050505050565b6001600160a01b03838116600090815260026020908152604080832086845290915290206003015484918491163314611a465760405162461bcd60e51b81526004016105fa90613960565b826001600160801b031660008111611a705760405162461bcd60e51b81526004016105fa906139ac565b6001600160a01b038616600090815260026020908152604080832088845290915290205484906001600160801b03600160801b90910481169082161580611add57506004546001600160801b0382811691611ada91851690600160401b900463ffffffff16611e3a565b10155b611af95760405162461bcd60e51b81526004016105fa906139d7565b6001600160a01b03881660008181526002602090815260408083208b845282529182902060010180546001600160801b0319166001600160801b038b1690811790915582519384529083018a9052908201527fcc66420416a999e685e3938d2c6252ed709db214d0435f13da0b1e5339bcac769060600160405180910390a1611b8288886129ca565b1561125357611b918888611e53565b61125388886121cb565b6001600160a01b03821660009081526002602090815260408083208484529091528120600101546001600160801b0316158015906107935750506001600160a01b039190911660009081526002602090815260408083209383529290522054600160801b90046001600160801b03161590565b6001600160a01b0391909116600090815260026020818152604080842094845293905291902090810180546001600160a01b03199081169091556001820180546001600160801b03169055600590910180549091169055565b6001600160a01b038481166000908152600260209081526040808320878452909152902060060154168015611d0f5760405163a9059cbb60e01b81526001600160a01b0384811660048301526024820184905282169063a9059cbb906044016020604051808303816000875af1158015611ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d099190613c0e565b50611daf565b6000836001600160a01b031683614e2090604051600060405180830381858888f193505050503d8060008114611d61576040519150601f19603f3d011682016040523d82523d6000602084013e611d66565b606091505b5050905080611dad576001600160a01b038416600090815260036020526040902054611d93908490613c30565b6001600160a01b0385166000908152600360205260409020555b505b5050505050565b6001600160a01b0382166000908152600260209081526040808320848452909152812054600160801b90046001600160801b03168015801590611e3257506001600160a01b03841660009081526002602090815260408083208684529091529020600101546001600160801b03808316600160801b9092041610155b949350505050565b6000612710611e498385613c48565b6107939190613c7d565b6001600160a01b038281166000818152600260209081526040808320868452909152908190206003015490516331a9108f60e11b815260048101859052921691829190636352211e90602401602060405180830381865afa158015611ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee09190613a78565b6001600160a01b031603612012576040516323b872dd60e01b81526001600160a01b038281166004830152306024830152604482018490528416906323b872dd90606401600060405180830381600087803b158015611f3e57600080fd5b505af1158015611f52573d6000803e3d6000fd5b50506040516331a9108f60e11b8152600481018590523092506001600160a01b0386169150636352211e90602401602060405180830381865afa158015611f9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc19190613a78565b6001600160a01b03161461200d5760405162461bcd60e51b81526020600482015260136024820152721b999d081d1c985b9cd9995c8819985a5b1959606a1b60448201526064016105fa565b505050565b6040516331a9108f60e11b81526004810183905230906001600160a01b03851690636352211e90602401602060405180830381865afa158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d9190613a78565b6001600160a01b03161461200d5760405162461bcd60e51b815260206004820152601660248201527514d95b1b195c88191bd95cdb89dd081bdddb8813919560521b60448201526064016105fa565b426120d78383612ab1565b63ffffffff166120e79190613c91565b6001600160a01b038316600081815260026020908152604080832086845282529182902080546fffffffffffffffff00000000000000001916600160401b67ffffffffffffffff96871681029190911791829055835194855291840186905204909216918101919091527fc1ce6cc1337b95ed3c849e00bffc0d93e89e5e80cc5d198db838140827ac75949060600161149f565b6001600160a01b0382166000908152600260209081526040808320848452909152812054600160401b900467ffffffffffffffff16801580611e32575067ffffffffffffffff1642109392505050565b6001600160a01b038281166000908152600260208181526040808420868552909152822060038101549101549083169216906122078585612b08565b6001600160a01b0386166000908152600260209081526040808320888452909152902060010154909150600160801b90046001600160801b031661224b8686611c0e565b612260868686846001600160801b0316612b67565b6040516323b872dd60e01b81523060048201526001600160a01b038381166024830152604482018790528716906323b872dd90606401600060405180830381600087803b1580156122b057600080fd5b505af11580156122c4573d6000803e3d6000fd5b505050506122d28686612675565b604080516001600160a01b03808916825260208201889052808716928201929092526001600160801b0383166060820152818516608082015290831660a08201527f8df77c988c9550e96e43a66277f716818a74ed2188cdacb49d790623e6f225719060c001610b61565b6001600160a01b039182166000908152600260209081526040808320938352929052206004015416151590565b6000805b6001548110156124235760006001828154811061238d5761238d613af2565b6000918252602090912001546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156123de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124029190613cbd565b11156124115760019150612423565b8061241b81613cd6565b91505061236e565b50806124715760405162461bcd60e51b815260206004820152601e60248201527f53656e64657220686173206e6f2077686974656c6973746564204e465473000060448201526064016105fa565b506001600160a01b038085166000908152600260209081526040808320878452909152902060030154859185911633036124ed5760405162461bcd60e51b815260206004820152601b60248201527f4f776e65722063616e6e6f7420626964206f6e206f776e204e4654000000000060448201526064016105fa565b858585856124fd84848484612c93565b6125495760405162461bcd60e51b815260206004820181905260248201527f42696420746f20626520696e207370656369666965642045524332302f45746860448201526064016105fa565b898988612557838383612d30565b6125a35760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f7567682066756e647320746f20626964206f6e204e4654000060448201526064016105fa565b6125ae8d8d8c612e3e565b7fdfd4ac8cb43d5458b7a6f74f2d6461d77d4985704bdbc2fd4c4816444bbfd5e08d8d33348f8f604051612626969594939291906001600160a01b03968716815260208101959095529285166040850152606084019190915290921660808201526001600160801b039190911660a082015260c00190565b60405180910390a16119ec8d8d612ea6565b6001600160a01b039190911660009081526002602090815260408083209383529290522060010154600160801b90046001600160801b0316151590565b6001600160a01b039190911660009081526002602090815260408083209383529290529081206001810180546001600160801b03191690559081556003810180546001600160a01b031990811690915560048201805482169055600690910180549091169055565b6126ec87878787878787612eec565b7f3379e969de5522101a0f0912ffe00daf15361dbcbf9cd5c328e0dd97aa25cdf987873388888861271d8e8e612ab1565b6127278f8f61318d565b8a8a60405161273f9a99989796959493929190613cef565b60405180910390a16127518787612ea6565b50505050505050565b815181518082146127a95760405162461bcd60e51b8152602060048201526019602482015278526563697069656e747320213d2070657263656e746167657360381b60448201526064016105fa565b826000805b82518110156127f0578281815181106127c9576127c9613af2565b6020026020010151826127dc9190613d7d565b9150806127e881613cd6565b9150506127ae565b506127108163ffffffff1611156128495760405162461bcd60e51b815260206004820152601e60248201527f4665652070657263656e746167657320657863656564206d6178696d756d000060448201526064016105fa565b6001600160a01b03891615612895576001600160a01b038b811660009081526002602090815260408083208e8452909152902060060180546001600160a01b031916918b169190911790555b6001600160a01b038b1660009081526002602090815260408083208d8452825290912087516128cc92600790920191890190613339565b506001600160a01b038b1660009081526002602090815260408083208d8452825290912086516129049260089092019188019061339e565b505050506001600160a01b039788166000908152600260209081526040808320998352989052969096206001810180546001600160801b03969096166001600160801b0319909616959095179094555050600482018054919095166001600160a01b031991821617909455600301805490931633179092555050565b600061298c838361233d565b158061079357506001600160a01b03808416600090815260026020818152604080842087855290915290912060048101549101548216911614610793565b6001600160a01b03821660009081526002602090815260408083208484529091528120600101546001600160801b03168015801590611e3257506001600160a01b03841660009081526002602090815260408083208684529091529020600101546001600160801b03808316600160801b90920416101591505092915050565b6001600160a01b03828116600090815260026020818152604080842086855290915290912090810154600190910154911690600160801b90046001600160801b0316612a968484611c0e565b612aab848484846001600160801b0316611c67565b50505050565b6001600160a01b0382166000908152600260209081526040808320848452909152812054640100000000900463ffffffff16808203612b01575050600454600160601b900463ffffffff16610796565b9050610796565b6001600160a01b03808316600090815260026020908152604080832085845290915281206005015490911680612b015750506001600160a01b038083166000908152600260208181526040808420868552909152909120015416610796565b6000805b6001600160a01b0386166000908152600260209081526040808320888452909152902060070154811015612c7d576001600160a01b038616600090815260026020908152604080832088845290915281206008018054612c0091869185908110612bd757612bd7613af2565b6000918252602090912060088204015460079091166004026101000a900463ffffffff16611e3a565b9050612c0c8184613c30565b6001600160a01b03881660009081526002602090815260408083208a845290915290206007018054919450612c6a918991899186908110612c4f57612c4f613af2565b6000918252602090912001546001600160a01b031684611c67565b5080612c7581613cd6565b915050612b6b565b50611daf858585612c8e8587613adb565b611c67565b6001600160a01b0384811660009081526002602090815260408083208784529091528120600601549091168015612d005734158015612ce35750836001600160a01b0316816001600160a01b0316145b8015612cf857506000836001600160801b0316115b915050611e32565b3415801590612d1657506001600160a01b038416155b8015612cf8575050506001600160801b0316159392505050565b6001600160a01b03831660009081526002602090815260408083208584529091528120600101546001600160801b03168015801590612d945750806001600160801b031634101580612d945750806001600160801b0316836001600160801b031610155b15612da3576001915050612e37565b6000612710612db2878761318d565b612dbe90612710613d7d565b6001600160a01b03881660009081526002602090815260408083208a8452909152902060010154612e059163ffffffff1690600160801b90046001600160801b0316613d9c565b612e0f9190613dcb565b6001600160801b031690508034101580612e32575080846001600160801b031610155b925050505b9392505050565b6001600160a01b03838116600090815260026020818152604080842087855290915290912090810154600190910154911690600160801b90046001600160801b0316612e8b8585856131ce565b6001600160a01b03821615611daf57611daf85858484611c67565b612eb082826129ca565b15612ec957612ebf8282611e53565b61116c82826121cb565b612ed38282611db6565b1561116c57612ee28282611e53565b61116c82826120cc565b82846001600160801b0382161580612f2a57506004546001600160801b0382811691612f2791851690600160401b900463ffffffff16611e3a565b10155b612f465760405162461bcd60e51b81526004016105fa906139d7565b83518351808214612f955760405162461bcd60e51b8152602060048201526019602482015278526563697069656e747320213d2070657263656e746167657360381b60448201526064016105fa565b846000805b8251811015612fdc57828181518110612fb557612fb5613af2565b602002602001015182612fc89190613d7d565b915080612fd481613cd6565b915050612f9a565b506127108163ffffffff1611156130355760405162461bcd60e51b815260206004820152601e60248201527f4665652070657263656e746167657320657863656564206d6178696d756d000060448201526064016105fa565b6001600160a01b038b16156130a3578a600260008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e815260200190815260200160002060060160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b6001600160a01b038d1660009081526002602090815260408083208f8452825290912089516130da926007909201918b0190613339565b506001600160a01b038d1660009081526002602090815260408083208f845282529091208851613112926008909201918a019061339e565b505050506001600160a01b039990991660009081526002602090815260408083209a8352999052979097206001810180546001600160801b039687166001600160801b03199091161790558054958516600160801b0295909416949094178355505060030180546001600160a01b0319163317905550505050565b6001600160a01b038216600090815260026020908152604080832084845290915281205463ffffffff16808203612b0157505060045463ffffffff16610796565b6001600160a01b0383811660009081526002602090815260408083208684529091529020600601541680156132c0576040516323b872dd60e01b81523360048201523060248201526001600160801b03831660448201526001600160a01b038216906323b872dd906064016020604051808303816000875af1158015613258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061327c9190613c0e565b506001600160a01b0384166000908152600260209081526040808320868452909152902060010180546001600160801b03808516600160801b0291161790556132ff565b6001600160a01b0384166000908152600260209081526040808320868452909152902060010180546001600160801b03348116600160801b0291161790555b50506001600160a01b0390911660009081526002602081815260408084209484529390529190200180546001600160a01b03191633179055565b82805482825590600052602060002090810192821561338e579160200282015b8281111561338e57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613359565b5061339a929150613444565b5090565b8280548282559060005260206000209060070160089004810192821561338e5791602002820160005b8382111561340b57835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026133c7565b801561343b5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261340b565b505061339a9291505b5b8082111561339a5760008155600101613445565b6001600160a01b038116811461346e57600080fd5b50565b6000806040838503121561348457600080fd5b823561348f81613459565b946020939093013593505050565b6000806000606084860312156134b257600080fd5b83356134bd81613459565b92506020840135915060408401356134d481613459565b809150509250925092565b80356001600160801b03811681146134f657600080fd5b919050565b60008060006060848603121561351057600080fd5b833561351b81613459565b925060208401359150613530604085016134df565b90509250925092565b600080600080600060a0868803121561355157600080fd5b853561355c81613459565b945060208601359350604086013561357381613459565b9250613581606087016134df565b9150608086013561359181613459565b809150509295509295909350565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156135de576135de61359f565b604052919050565b600067ffffffffffffffff8211156136005761360061359f565b5060051b60200190565b600082601f83011261361b57600080fd5b8135602061363061362b836135e6565b6135b5565b82815260059290921b8401810191818101908684111561364f57600080fd5b8286015b8481101561367357803561366681613459565b8352918301918301613653565b509695505050505050565b803563ffffffff811681146134f657600080fd5b600082601f8301126136a357600080fd5b813560206136b361362b836135e6565b82815260059290921b840181019181810190868411156136d257600080fd5b8286015b84811015613673576136e78161367e565b83529183019183016136d6565b600080600080600080600060e0888a03121561370f57600080fd5b873561371a81613459565b965060208801359550604088013561373181613459565b945061373f606089016134df565b935061374d608089016134df565b925060a088013567ffffffffffffffff8082111561376a57600080fd5b6137768b838c0161360a565b935060c08a013591508082111561378c57600080fd5b506137998a828b01613692565b91505092959891949750929550565b6000602082840312156137ba57600080fd5b5035919050565b600080600080608085870312156137d757600080fd5b84356137e281613459565b93506020850135925060408501356137f981613459565b9150613807606086016134df565b905092959194509250565b60006020828403121561382457600080fd5b813561079381613459565b600080600080600080600060e0888a03121561384a57600080fd5b873561385581613459565b965060208801359550604088013561386c81613459565b945061387a606089016134df565b9350608088013561374d81613459565b60008060008060008060008060006101208a8c0312156138a957600080fd5b89356138b481613459565b985060208a0135975060408a01356138cb81613459565b96506138d960608b016134df565b95506138e760808b016134df565b94506138f560a08b0161367e565b935061390360c08b0161367e565b925060e08a013567ffffffffffffffff8082111561392057600080fd5b61392c8d838e0161360a565b93506101008c013591508082111561394357600080fd5b506139508c828d01613692565b9150509295985092959850929598565b6020808252600f908201526e27b7363c9037333a1039b2b63632b960891b604082015260600190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b602080825260119082015270050726963652063616e6e6f74206265203607c1b604082015260600190565b6020808252601d908201527f4d696e5072696365203e20383025206f66206275794e6f775072696365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252818101527f41756374696f6e20616c72656164792073746172746564206279206f776e6572604082015260600190565b600060208284031215613a8a57600080fd5b815161079381613459565b60208082526016908201527514d95b99195c88191bd95cdb89dd081bdddb8813919560521b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015613aed57613aed613ac5565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600081518084526020808501945080840160005b83811015613b575781516001600160a01b031687529582019590820190600101613b32565b509495945050505050565b600081518084526020808501945080840160005b83811015613b5757815163ffffffff1687529582019590820190600101613b76565b6001600160a01b03898116825260208201899052878116604083015286811660608301526001600160801b0386166080830152841660a082015261010060c08201819052600090613beb83820186613b1e565b905082810360e0840152613bff8185613b62565b9b9a5050505050505050505050565b600060208284031215613c2057600080fd5b8151801515811461079357600080fd5b60008219821115613c4357613c43613ac5565b500190565b6000816000190483118215151615613c6257613c62613ac5565b500290565b634e487b7160e01b600052601260045260246000fd5b600082613c8c57613c8c613c67565b500490565b600067ffffffffffffffff808316818516808303821115613cb457613cb4613ac5565b01949350505050565b600060208284031215613ccf57600080fd5b5051919050565b600060018201613ce857613ce8613ac5565b5060010190565b6001600160a01b038b81168252602082018b90528981166040830152881660608201526001600160801b038781166080830152861660a082015263ffffffff85811660c0830152841660e08201526101406101008201819052600090613d5783820186613b1e565b9050828103610120840152613d6c8185613b62565b9d9c50505050505050505050505050565b600063ffffffff808316818516808303821115613cb457613cb4613ac5565b60006001600160801b0380831681851681830481118215151615613dc257613dc2613ac5565b02949350505050565b60006001600160801b0380841680613de557613de5613c67565b9216919091049291505056fea26469706673582212206a536cf573a2864b43e335f913d2731550811ae78d2ef81b8f5eadbaeb12395764736f6c634300080d003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000d3228e099e6596988ae0b73eaa62591c875e56930000000000000000000000005dc23613fd54a87c3b8a7134534110f5180433c8000000000000000000000000932aeac0eebaa1fe8fdb53c4f81312cba5f771a8

Deployed Bytecode

0x6080604052600436106101665760003560e01c80639041e273116100d1578063d18e629c1161008a578063f2fde38b11610064578063f2fde38b1461052f578063f45671f11461054f578063f583bac71461056f578063f7f829a41461058f57600080fd5b8063d18e629c146104cf578063db227338146104ef578063ebea60251461050f57600080fd5b80639041e2731461042657806399157d70146104465780639c0b996614610466578063b6ad691414610483578063c24d5a5c14610498578063cd4eda1c146104ab57600080fd5b80634cb8ef5b116101235780634cb8ef5b146103805780635138b08c146103a0578063565c5172146103c0578063715018a6146103d3578063848e5c77146103e85780638da5cb5b1461040857600080fd5b8063041fa0b81461016b578063076b73ac146102a8578063186779d5146102ca57806320950fc6146103035780632f9c95761461033b5780633d87d5fb1461035b575b600080fd5b34801561017757600080fd5b5061021f610186366004613471565b60026020818152600093845260408085209091529183529120805460018201549282015460038301546004840154600585015460069095015463ffffffff8086169764010000000087049091169667ffffffffffffffff600160401b880416966001600160801b03600160801b91829004811697848216979290940416946001600160a01b03938416949184169390811692811691168b565b6040805163ffffffff9c8d1681529b909a1660208c015267ffffffffffffffff909816988a01989098526001600160801b0395861660608a015293851660808901529390911660a08701526001600160a01b0390811660c087015291821660e0860152811661010085015291821661012084015216610140820152610160015b60405180910390f35b3480156102b457600080fd5b506102c86102c336600461349d565b6105af565b005b3480156102d657600080fd5b506004546102ee90600160601b900463ffffffff1681565b60405163ffffffff909116815260200161029f565b34801561030f57600080fd5b5061032361031e366004613471565b610727565b6040516001600160a01b03909116815260200161029f565b34801561034757600080fd5b506102c86103563660046134fb565b61079c565b34801561036757600080fd5b506004546102ee90640100000000900463ffffffff1681565b34801561038c57600080fd5b506102c861039b366004613471565b610a10565b3480156103ac57600080fd5b506102c86103bb366004613471565b610b71565b6102c86103ce366004613539565b610c15565b3480156103df57600080fd5b506102c8610d97565b3480156103f457600080fd5b506102c8610403366004613471565b610e0b565b34801561041457600080fd5b506000546001600160a01b0316610323565b34801561043257600080fd5b506102c86104413660046136f4565b610ef5565b34801561045257600080fd5b506103236104613660046137a8565b61104b565b34801561047257600080fd5b506004546102ee9063ffffffff1681565b34801561048f57600080fd5b506102c8611075565b6102c86104a63660046137c1565b611170565b3480156104b757600080fd5b506004546102ee90600160401b900463ffffffff1681565b3480156104db57600080fd5b506102c86104ea366004613812565b61125d565b3480156104fb57600080fd5b506102c861050a3660046137a8565b6112d8565b34801561051b57600080fd5b506102c861052a366004613471565b6113b1565b34801561053b57600080fd5b506102c861054a366004613812565b6114ab565b34801561055b57600080fd5b506102c861056a36600461382f565b611595565b34801561057b57600080fd5b506102c861058a36600461388a565b611780565b34801561059b57600080fd5b506102c86105aa3660046134fb565b6119fb565b6001600160a01b038381166000908152600260209081526040808320868452909152902060030154849184911633146106035760405162461bcd60e51b81526004016105fa90613960565b60405180910390fd5b61060d8585611b9b565b6106465760405162461bcd60e51b815260206004820152600a6024820152694e6f7420612073616c6560b01b60448201526064016105fa565b6001600160a01b0385811660009081526002602081815260408084208985529091529091206004810180546001600160a01b03191687851617905590810154600190910154911690600160801b90046001600160801b031680158015906106bf5750846001600160a01b0316826001600160a01b031614155b156106e3576106ce8787611c0e565b6106e3878784846001600160801b0316611c67565b7f7502912f483c1fb3f89bf8664bea10db517c2093040d379e78e169e06752364687878760405161071693929190613989565b60405180910390a150505050505050565b6001600160a01b038083166000908152600260209081526040808320858452909152812060030154909116806107935760405162461bcd60e51b8152602060048201526011602482015270139195081b9bdd0819195c1bdcda5d1959607a1b60448201526064016105fa565b90505b92915050565b6001600160a01b038381166000908152600260209081526040808320868452909152902060030154849184911633146107e75760405162461bcd60e51b81526004016105fa90613960565b84846107f38282611db6565b156108405760405162461bcd60e51b815260206004820181905260248201527f5468652061756374696f6e2068617320612076616c696420626964206d61646560448201526064016105fa565b868661084c8282611b9b565b156108995760405162461bcd60e51b815260206004820152601960248201527f4e6f74206170706c696361626c6520666f7220612073616c650000000000000060448201526064016105fa565b866001600160801b0316600081116108c35760405162461bcd60e51b81526004016105fa906139ac565b6001600160a01b038a1660009081526002602090815260408083208c84529091529020600101546001600160801b03168881158061092757506004546001600160801b038281169161092491851690600160401b900463ffffffff16611e3a565b10155b6109435760405162461bcd60e51b81526004016105fa906139d7565b6001600160a01b038c1660009081526002602090815260408083208e84529091529081902080546001600160801b03808e16600160801b029116179055517fdcf27af4c564afa0c536dd1fa48e5fef0d9833378a1bddacc95922b902ebfc32906109d7908e908e908e906001600160a01b0393909316835260208301919091526001600160801b0316604082015260600190565b60405180910390a16109e98c8c611db6565b15610a02576109f88c8c611e53565b610a028c8c6120cc565b505050505050505050505050565b8181610a1c8282611db6565b15610a695760405162461bcd60e51b815260206004820181905260248201527f5468652061756374696f6e2068617320612076616c696420626964206d61646560448201526064016105fa565b6001600160a01b038085166000908152600260208181526040808420888552909152909120015416338114610ad85760405162461bcd60e51b815260206004820152601560248201527443616e6e6f742077697468647261772066756e647360581b60448201526064016105fa565b6001600160a01b0385166000908152600260209081526040808320878452909152902060010154600160801b90046001600160801b0316610b198686611c0e565b610b2e868684846001600160801b0316611c67565b7f10d9bddf66f639dd3c5a6ad2db5ae3102c2b468dfb90a4b0da219435f24a970d868633604051610b6193929190613989565b60405180910390a1505050505050565b8181610b7d828261217b565b15610bca5760405162461bcd60e51b815260206004820152601760248201527f41756374696f6e206973206e6f7420796574206f76657200000000000000000060448201526064016105fa565b610bd484846121cb565b7fe6b94748c5d6e0d188a0fcb9b7f2973b01fc0095627f1ec5accdcd9d2e65ca36848433604051610c0793929190613989565b60405180910390a150505050565b8484610c21828261217b565b610c615760405162461bcd60e51b8152602060048201526011602482015270105d58dd1a5bdb881a185cc8195b991959607a1b60448201526064016105fa565b826001600160a01b038116610cb85760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f74207370656369667920302061646472657373000000000000000060448201526064016105fa565b8787610cc4828261233d565b1580610cf757506001600160a01b0382811660009081526002602090815260408083208584529091529020600401541633145b610d435760405162461bcd60e51b815260206004820152601a60248201527f4f6e6c79207468652077686974656c697374656420627579657200000000000060448201526064016105fa565b6001600160a01b038a811660009081526002602090815260408083208d8452909152902060050180546001600160a01b031916918816919091179055610d8b8a8a8a8a61236a565b50505050505050505050565b6000546001600160a01b03163314610dc15760405162461bcd60e51b81526004016105fa90613a0e565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6001600160a01b03828116600090815260026020908152604080832085845290915290206003015483918391163314610e565760405162461bcd60e51b81526004016105fa90613960565b610e608484612638565b610ea25760405162461bcd60e51b815260206004820152601360248201527218d85b9b9bdd081c185e5bdd5d080c08189a59606a1b60448201526064016105fa565b610eac8484611e53565b610eb684846121cb565b604080516001600160a01b0386168152602081018590527f711f4eae05533b90c24ff0ae762d6e9e1ef1b2c85d4c484a2913c5201bcbb7c99101610c07565b6001600160a01b0380881660009081526002602090815260408083208a84529091529020600301548891889133911603610f415760405162461bcd60e51b81526004016105fa90613a43565b6001600160a01b0382811660009081526002602090815260408083208584529091529020600301541615611012576040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa158015610fb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd89190613a78565b6001600160a01b0316336001600160a01b0316146110085760405162461bcd60e51b81526004016105fa90613a95565b6110128282612675565b856001600160801b03166000811161103c5760405162461bcd60e51b81526004016105fa906139ac565b610d8b8a8a8a8a8a8a8a6126dd565b6001818154811061105b57600080fd5b6000918252602090912001546001600160a01b0316905081565b33600090815260036020526040812054908190036110ce5760405162461bcd60e51b81526020600482015260166024820152756e6f206372656469747320746f20776974686472617760501b60448201526064016105fa565b3360008181526003602052604080822082905551909190614e2090849084818181858888f193505050503d8060008114611124576040519150601f19603f3d011682016040523d82523d6000602084013e611129565b606091505b505090508061116c5760405162461bcd60e51b815260206004820152600f60248201526e1dda5d1a191c985dc819985a5b1959608a1b60448201526064016105fa565b5050565b838361117c828261217b565b6111bc5760405162461bcd60e51b8152602060048201526011602482015270105d58dd1a5bdb881a185cc8195b991959607a1b60448201526064016105fa565b85856111c8828261233d565b15806111fb57506001600160a01b0382811660009081526002602090815260408083208584529091529020600401541633145b6112475760405162461bcd60e51b815260206004820152601a60248201527f4f6e6c79207468652077686974656c697374656420627579657200000000000060448201526064016105fa565b6112538888888861236a565b5050505050505050565b6000546001600160a01b031633146112875760405162461bcd60e51b81526004016105fa90613a0e565b6001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146113025760405162461bcd60e51b81526004016105fa90613a0e565b60018054611311908290613adb565b8154811061132157611321613af2565b600091825260209091200154600180546001600160a01b03909216918390811061134d5761134d613af2565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600180548061138c5761138c613b08565b600082815260209020810160001990810180546001600160a01b031916905501905550565b6040516331a9108f60e11b81526004810182905233906001600160a01b03841690636352211e90602401602060405180830381865afa1580156113f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141c9190613a78565b6001600160a01b0316146114625760405162461bcd60e51b815260206004820152600d60248201526c2737ba1027232a1037bbb732b960991b60448201526064016105fa565b61146c8282612675565b7fec19f84af4aad6523d37faa19e243c77717842cca9bf492dc5379830cac958d082823360405161149f93929190613989565b60405180910390a15050565b6000546001600160a01b031633146114d55760405162461bcd60e51b81526004016105fa90613a0e565b6001600160a01b03811661153a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105fa565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0380881660009081526002602090815260408083208a845290915290206003015488918891339116036115e15760405162461bcd60e51b81526004016105fa90613a43565b6001600160a01b03828116600090815260026020908152604080832085845290915290206003015416156116b2576040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa158015611654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116789190613a78565b6001600160a01b0316336001600160a01b0316146116a85760405162461bcd60e51b81526004016105fa90613a95565b6116b28282612675565b856001600160801b0316600081116116dc5760405162461bcd60e51b81526004016105fa906139ac565b6116eb8a8a8a8a8a8a8a61275a565b7fb4cb1faa7b4f2b837334e4a12fb94a1cfc320c32b70dd31e113d1795b9d0f0568a8a338b8b8b8b8b604051611728989796959493929190613b98565b60405180910390a161173a8a8a612638565b15610d8b576117498a8a612980565b15611776576117588a8a6129ca565b15611771576117678a8a611e53565b6117718a8a6121cb565b610d8b565b610d8b8a8a612a4a565b6001600160a01b03808a1660009081526002602090815260408083208c84529091529020600301548a918a91339116036117cc5760405162461bcd60e51b81526004016105fa90613a43565b6001600160a01b038281166000908152600260209081526040808320858452909152902060030154161561189d576040516331a9108f60e11b8152600481018290526001600160a01b03831690636352211e90602401602060405180830381865afa15801561183f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118639190613a78565b6001600160a01b0316336001600160a01b0316146118935760405162461bcd60e51b81526004016105fa90613a95565b61189d8282612675565b876001600160801b0316600081116118c75760405162461bcd60e51b81526004016105fa906139ac565b600454869063ffffffff6401000000009091048116908216101561192d5760405162461bcd60e51b815260206004820152601f60248201527f42696420696e6372656173652070657263656e7461676520746f6f206c6f770060448201526064016105fa565b87600260008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e815260200190815260200160002060000160046101000a81548163ffffffff021916908363ffffffff16021790555086600260008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e815260200190815260200160002060000160006101000a81548163ffffffff021916908363ffffffff1602179055506119ec8d8d8d8d8d8b8b6126dd565b50505050505050505050505050565b6001600160a01b03838116600090815260026020908152604080832086845290915290206003015484918491163314611a465760405162461bcd60e51b81526004016105fa90613960565b826001600160801b031660008111611a705760405162461bcd60e51b81526004016105fa906139ac565b6001600160a01b038616600090815260026020908152604080832088845290915290205484906001600160801b03600160801b90910481169082161580611add57506004546001600160801b0382811691611ada91851690600160401b900463ffffffff16611e3a565b10155b611af95760405162461bcd60e51b81526004016105fa906139d7565b6001600160a01b03881660008181526002602090815260408083208b845282529182902060010180546001600160801b0319166001600160801b038b1690811790915582519384529083018a9052908201527fcc66420416a999e685e3938d2c6252ed709db214d0435f13da0b1e5339bcac769060600160405180910390a1611b8288886129ca565b1561125357611b918888611e53565b61125388886121cb565b6001600160a01b03821660009081526002602090815260408083208484529091528120600101546001600160801b0316158015906107935750506001600160a01b039190911660009081526002602090815260408083209383529290522054600160801b90046001600160801b03161590565b6001600160a01b0391909116600090815260026020818152604080842094845293905291902090810180546001600160a01b03199081169091556001820180546001600160801b03169055600590910180549091169055565b6001600160a01b038481166000908152600260209081526040808320878452909152902060060154168015611d0f5760405163a9059cbb60e01b81526001600160a01b0384811660048301526024820184905282169063a9059cbb906044016020604051808303816000875af1158015611ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d099190613c0e565b50611daf565b6000836001600160a01b031683614e2090604051600060405180830381858888f193505050503d8060008114611d61576040519150601f19603f3d011682016040523d82523d6000602084013e611d66565b606091505b5050905080611dad576001600160a01b038416600090815260036020526040902054611d93908490613c30565b6001600160a01b0385166000908152600360205260409020555b505b5050505050565b6001600160a01b0382166000908152600260209081526040808320848452909152812054600160801b90046001600160801b03168015801590611e3257506001600160a01b03841660009081526002602090815260408083208684529091529020600101546001600160801b03808316600160801b9092041610155b949350505050565b6000612710611e498385613c48565b6107939190613c7d565b6001600160a01b038281166000818152600260209081526040808320868452909152908190206003015490516331a9108f60e11b815260048101859052921691829190636352211e90602401602060405180830381865afa158015611ebc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee09190613a78565b6001600160a01b031603612012576040516323b872dd60e01b81526001600160a01b038281166004830152306024830152604482018490528416906323b872dd90606401600060405180830381600087803b158015611f3e57600080fd5b505af1158015611f52573d6000803e3d6000fd5b50506040516331a9108f60e11b8152600481018590523092506001600160a01b0386169150636352211e90602401602060405180830381865afa158015611f9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fc19190613a78565b6001600160a01b03161461200d5760405162461bcd60e51b81526020600482015260136024820152721b999d081d1c985b9cd9995c8819985a5b1959606a1b60448201526064016105fa565b505050565b6040516331a9108f60e11b81526004810183905230906001600160a01b03851690636352211e90602401602060405180830381865afa158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d9190613a78565b6001600160a01b03161461200d5760405162461bcd60e51b815260206004820152601660248201527514d95b1b195c88191bd95cdb89dd081bdddb8813919560521b60448201526064016105fa565b426120d78383612ab1565b63ffffffff166120e79190613c91565b6001600160a01b038316600081815260026020908152604080832086845282529182902080546fffffffffffffffff00000000000000001916600160401b67ffffffffffffffff96871681029190911791829055835194855291840186905204909216918101919091527fc1ce6cc1337b95ed3c849e00bffc0d93e89e5e80cc5d198db838140827ac75949060600161149f565b6001600160a01b0382166000908152600260209081526040808320848452909152812054600160401b900467ffffffffffffffff16801580611e32575067ffffffffffffffff1642109392505050565b6001600160a01b038281166000908152600260208181526040808420868552909152822060038101549101549083169216906122078585612b08565b6001600160a01b0386166000908152600260209081526040808320888452909152902060010154909150600160801b90046001600160801b031661224b8686611c0e565b612260868686846001600160801b0316612b67565b6040516323b872dd60e01b81523060048201526001600160a01b038381166024830152604482018790528716906323b872dd90606401600060405180830381600087803b1580156122b057600080fd5b505af11580156122c4573d6000803e3d6000fd5b505050506122d28686612675565b604080516001600160a01b03808916825260208201889052808716928201929092526001600160801b0383166060820152818516608082015290831660a08201527f8df77c988c9550e96e43a66277f716818a74ed2188cdacb49d790623e6f225719060c001610b61565b6001600160a01b039182166000908152600260209081526040808320938352929052206004015416151590565b6000805b6001548110156124235760006001828154811061238d5761238d613af2565b6000918252602090912001546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156123de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124029190613cbd565b11156124115760019150612423565b8061241b81613cd6565b91505061236e565b50806124715760405162461bcd60e51b815260206004820152601e60248201527f53656e64657220686173206e6f2077686974656c6973746564204e465473000060448201526064016105fa565b506001600160a01b038085166000908152600260209081526040808320878452909152902060030154859185911633036124ed5760405162461bcd60e51b815260206004820152601b60248201527f4f776e65722063616e6e6f7420626964206f6e206f776e204e4654000000000060448201526064016105fa565b858585856124fd84848484612c93565b6125495760405162461bcd60e51b815260206004820181905260248201527f42696420746f20626520696e207370656369666965642045524332302f45746860448201526064016105fa565b898988612557838383612d30565b6125a35760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f7567682066756e647320746f20626964206f6e204e4654000060448201526064016105fa565b6125ae8d8d8c612e3e565b7fdfd4ac8cb43d5458b7a6f74f2d6461d77d4985704bdbc2fd4c4816444bbfd5e08d8d33348f8f604051612626969594939291906001600160a01b03968716815260208101959095529285166040850152606084019190915290921660808201526001600160801b039190911660a082015260c00190565b60405180910390a16119ec8d8d612ea6565b6001600160a01b039190911660009081526002602090815260408083209383529290522060010154600160801b90046001600160801b0316151590565b6001600160a01b039190911660009081526002602090815260408083209383529290529081206001810180546001600160801b03191690559081556003810180546001600160a01b031990811690915560048201805482169055600690910180549091169055565b6126ec87878787878787612eec565b7f3379e969de5522101a0f0912ffe00daf15361dbcbf9cd5c328e0dd97aa25cdf987873388888861271d8e8e612ab1565b6127278f8f61318d565b8a8a60405161273f9a99989796959493929190613cef565b60405180910390a16127518787612ea6565b50505050505050565b815181518082146127a95760405162461bcd60e51b8152602060048201526019602482015278526563697069656e747320213d2070657263656e746167657360381b60448201526064016105fa565b826000805b82518110156127f0578281815181106127c9576127c9613af2565b6020026020010151826127dc9190613d7d565b9150806127e881613cd6565b9150506127ae565b506127108163ffffffff1611156128495760405162461bcd60e51b815260206004820152601e60248201527f4665652070657263656e746167657320657863656564206d6178696d756d000060448201526064016105fa565b6001600160a01b03891615612895576001600160a01b038b811660009081526002602090815260408083208e8452909152902060060180546001600160a01b031916918b169190911790555b6001600160a01b038b1660009081526002602090815260408083208d8452825290912087516128cc92600790920191890190613339565b506001600160a01b038b1660009081526002602090815260408083208d8452825290912086516129049260089092019188019061339e565b505050506001600160a01b039788166000908152600260209081526040808320998352989052969096206001810180546001600160801b03969096166001600160801b0319909616959095179094555050600482018054919095166001600160a01b031991821617909455600301805490931633179092555050565b600061298c838361233d565b158061079357506001600160a01b03808416600090815260026020818152604080842087855290915290912060048101549101548216911614610793565b6001600160a01b03821660009081526002602090815260408083208484529091528120600101546001600160801b03168015801590611e3257506001600160a01b03841660009081526002602090815260408083208684529091529020600101546001600160801b03808316600160801b90920416101591505092915050565b6001600160a01b03828116600090815260026020818152604080842086855290915290912090810154600190910154911690600160801b90046001600160801b0316612a968484611c0e565b612aab848484846001600160801b0316611c67565b50505050565b6001600160a01b0382166000908152600260209081526040808320848452909152812054640100000000900463ffffffff16808203612b01575050600454600160601b900463ffffffff16610796565b9050610796565b6001600160a01b03808316600090815260026020908152604080832085845290915281206005015490911680612b015750506001600160a01b038083166000908152600260208181526040808420868552909152909120015416610796565b6000805b6001600160a01b0386166000908152600260209081526040808320888452909152902060070154811015612c7d576001600160a01b038616600090815260026020908152604080832088845290915281206008018054612c0091869185908110612bd757612bd7613af2565b6000918252602090912060088204015460079091166004026101000a900463ffffffff16611e3a565b9050612c0c8184613c30565b6001600160a01b03881660009081526002602090815260408083208a845290915290206007018054919450612c6a918991899186908110612c4f57612c4f613af2565b6000918252602090912001546001600160a01b031684611c67565b5080612c7581613cd6565b915050612b6b565b50611daf858585612c8e8587613adb565b611c67565b6001600160a01b0384811660009081526002602090815260408083208784529091528120600601549091168015612d005734158015612ce35750836001600160a01b0316816001600160a01b0316145b8015612cf857506000836001600160801b0316115b915050611e32565b3415801590612d1657506001600160a01b038416155b8015612cf8575050506001600160801b0316159392505050565b6001600160a01b03831660009081526002602090815260408083208584529091528120600101546001600160801b03168015801590612d945750806001600160801b031634101580612d945750806001600160801b0316836001600160801b031610155b15612da3576001915050612e37565b6000612710612db2878761318d565b612dbe90612710613d7d565b6001600160a01b03881660009081526002602090815260408083208a8452909152902060010154612e059163ffffffff1690600160801b90046001600160801b0316613d9c565b612e0f9190613dcb565b6001600160801b031690508034101580612e32575080846001600160801b031610155b925050505b9392505050565b6001600160a01b03838116600090815260026020818152604080842087855290915290912090810154600190910154911690600160801b90046001600160801b0316612e8b8585856131ce565b6001600160a01b03821615611daf57611daf85858484611c67565b612eb082826129ca565b15612ec957612ebf8282611e53565b61116c82826121cb565b612ed38282611db6565b1561116c57612ee28282611e53565b61116c82826120cc565b82846001600160801b0382161580612f2a57506004546001600160801b0382811691612f2791851690600160401b900463ffffffff16611e3a565b10155b612f465760405162461bcd60e51b81526004016105fa906139d7565b83518351808214612f955760405162461bcd60e51b8152602060048201526019602482015278526563697069656e747320213d2070657263656e746167657360381b60448201526064016105fa565b846000805b8251811015612fdc57828181518110612fb557612fb5613af2565b602002602001015182612fc89190613d7d565b915080612fd481613cd6565b915050612f9a565b506127108163ffffffff1611156130355760405162461bcd60e51b815260206004820152601e60248201527f4665652070657263656e746167657320657863656564206d6178696d756d000060448201526064016105fa565b6001600160a01b038b16156130a3578a600260008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e815260200190815260200160002060060160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b6001600160a01b038d1660009081526002602090815260408083208f8452825290912089516130da926007909201918b0190613339565b506001600160a01b038d1660009081526002602090815260408083208f845282529091208851613112926008909201918a019061339e565b505050506001600160a01b039990991660009081526002602090815260408083209a8352999052979097206001810180546001600160801b039687166001600160801b03199091161790558054958516600160801b0295909416949094178355505060030180546001600160a01b0319163317905550505050565b6001600160a01b038216600090815260026020908152604080832084845290915281205463ffffffff16808203612b0157505060045463ffffffff16610796565b6001600160a01b0383811660009081526002602090815260408083208684529091529020600601541680156132c0576040516323b872dd60e01b81523360048201523060248201526001600160801b03831660448201526001600160a01b038216906323b872dd906064016020604051808303816000875af1158015613258573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061327c9190613c0e565b506001600160a01b0384166000908152600260209081526040808320868452909152902060010180546001600160801b03808516600160801b0291161790556132ff565b6001600160a01b0384166000908152600260209081526040808320868452909152902060010180546001600160801b03348116600160801b0291161790555b50506001600160a01b0390911660009081526002602081815260408084209484529390529190200180546001600160a01b03191633179055565b82805482825590600052602060002090810192821561338e579160200282015b8281111561338e57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613359565b5061339a929150613444565b5090565b8280548282559060005260206000209060070160089004810192821561338e5791602002820160005b8382111561340b57835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026133c7565b801561343b5782816101000a81549063ffffffff021916905560040160208160030104928301926001030261340b565b505061339a9291505b5b8082111561339a5760008155600101613445565b6001600160a01b038116811461346e57600080fd5b50565b6000806040838503121561348457600080fd5b823561348f81613459565b946020939093013593505050565b6000806000606084860312156134b257600080fd5b83356134bd81613459565b92506020840135915060408401356134d481613459565b809150509250925092565b80356001600160801b03811681146134f657600080fd5b919050565b60008060006060848603121561351057600080fd5b833561351b81613459565b925060208401359150613530604085016134df565b90509250925092565b600080600080600060a0868803121561355157600080fd5b853561355c81613459565b945060208601359350604086013561357381613459565b9250613581606087016134df565b9150608086013561359181613459565b809150509295509295909350565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156135de576135de61359f565b604052919050565b600067ffffffffffffffff8211156136005761360061359f565b5060051b60200190565b600082601f83011261361b57600080fd5b8135602061363061362b836135e6565b6135b5565b82815260059290921b8401810191818101908684111561364f57600080fd5b8286015b8481101561367357803561366681613459565b8352918301918301613653565b509695505050505050565b803563ffffffff811681146134f657600080fd5b600082601f8301126136a357600080fd5b813560206136b361362b836135e6565b82815260059290921b840181019181810190868411156136d257600080fd5b8286015b84811015613673576136e78161367e565b83529183019183016136d6565b600080600080600080600060e0888a03121561370f57600080fd5b873561371a81613459565b965060208801359550604088013561373181613459565b945061373f606089016134df565b935061374d608089016134df565b925060a088013567ffffffffffffffff8082111561376a57600080fd5b6137768b838c0161360a565b935060c08a013591508082111561378c57600080fd5b506137998a828b01613692565b91505092959891949750929550565b6000602082840312156137ba57600080fd5b5035919050565b600080600080608085870312156137d757600080fd5b84356137e281613459565b93506020850135925060408501356137f981613459565b9150613807606086016134df565b905092959194509250565b60006020828403121561382457600080fd5b813561079381613459565b600080600080600080600060e0888a03121561384a57600080fd5b873561385581613459565b965060208801359550604088013561386c81613459565b945061387a606089016134df565b9350608088013561374d81613459565b60008060008060008060008060006101208a8c0312156138a957600080fd5b89356138b481613459565b985060208a0135975060408a01356138cb81613459565b96506138d960608b016134df565b95506138e760808b016134df565b94506138f560a08b0161367e565b935061390360c08b0161367e565b925060e08a013567ffffffffffffffff8082111561392057600080fd5b61392c8d838e0161360a565b93506101008c013591508082111561394357600080fd5b506139508c828d01613692565b9150509295985092959850929598565b6020808252600f908201526e27b7363c9037333a1039b2b63632b960891b604082015260600190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b602080825260119082015270050726963652063616e6e6f74206265203607c1b604082015260600190565b6020808252601d908201527f4d696e5072696365203e20383025206f66206275794e6f775072696365000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252818101527f41756374696f6e20616c72656164792073746172746564206279206f776e6572604082015260600190565b600060208284031215613a8a57600080fd5b815161079381613459565b60208082526016908201527514d95b99195c88191bd95cdb89dd081bdddb8813919560521b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015613aed57613aed613ac5565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600081518084526020808501945080840160005b83811015613b575781516001600160a01b031687529582019590820190600101613b32565b509495945050505050565b600081518084526020808501945080840160005b83811015613b5757815163ffffffff1687529582019590820190600101613b76565b6001600160a01b03898116825260208201899052878116604083015286811660608301526001600160801b0386166080830152841660a082015261010060c08201819052600090613beb83820186613b1e565b905082810360e0840152613bff8185613b62565b9b9a5050505050505050505050565b600060208284031215613c2057600080fd5b8151801515811461079357600080fd5b60008219821115613c4357613c43613ac5565b500190565b6000816000190483118215151615613c6257613c62613ac5565b500290565b634e487b7160e01b600052601260045260246000fd5b600082613c8c57613c8c613c67565b500490565b600067ffffffffffffffff808316818516808303821115613cb457613cb4613ac5565b01949350505050565b600060208284031215613ccf57600080fd5b5051919050565b600060018201613ce857613ce8613ac5565b5060010190565b6001600160a01b038b81168252602082018b90528981166040830152881660608201526001600160801b038781166080830152861660a082015263ffffffff85811660c0830152841660e08201526101406101008201819052600090613d5783820186613b1e565b9050828103610120840152613d6c8185613b62565b9d9c50505050505050505050505050565b600063ffffffff808316818516808303821115613cb457613cb4613ac5565b60006001600160801b0380831681851681830481118215151615613dc257613dc2613ac5565b02949350505050565b60006001600160801b0380841680613de557613de5613c67565b9216919091049291505056fea26469706673582212206a536cf573a2864b43e335f913d2731550811ae78d2ef81b8f5eadbaeb12395764736f6c634300080d0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000d3228e099e6596988ae0b73eaa62591c875e56930000000000000000000000005dc23613fd54a87c3b8a7134534110f5180433c8000000000000000000000000932aeac0eebaa1fe8fdb53c4f81312cba5f771a8

-----Decoded View---------------
Arg [0] : _whitelistedPassCollectionsAddresses (address[]): 0xD3228e099E6596988Ae0b73EAa62591c875e5693,0x5DC23613fD54A87C3b8A7134534110F5180433C8,0x932aEAc0eEBaA1fE8fdB53C4f81312cBA5F771A8

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [2] : 000000000000000000000000d3228e099e6596988ae0b73eaa62591c875e5693
Arg [3] : 0000000000000000000000005dc23613fd54a87c3b8a7134534110f5180433c8
Arg [4] : 000000000000000000000000932aeac0eebaa1fe8fdb53c4f81312cba5f771a8


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.