ETH Price: $3,798.01 (+6.41%)

Token

Bored & Dangerous (BOOK)
 

Overview

Max Total Supply

14,890 BOOK

Holders

2,235

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
yesmanbayc.eth
Balance
3 BOOK
0xa109d59498a94f71d7491e4aee0125f600283cc9
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Bored & Dangerous, almost a year in the making, is a historic moment for the NFT space. This work is the result of 3,000 members of Jenkins the Valet’s “The Writer’s Room” banding together to drive the creative direction of the work.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
BoredAndDangerous

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 8 : BoredAndDangerous.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.15;

import {ERC721} from "solmate/tokens/ERC721.sol";
import {ERC2981} from "openzeppelin-contracts/contracts/token/common/ERC2981.sol";
import {MerkleProof} from "openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol";
import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol";


interface IERC721 {
    function ownerOf(uint tokenId) external view returns (address);
}


contract BoredAndDangerous is ERC721, ERC2981 {
    /// @notice The original writer's room contract
    address public constant WRITERS_ROOM = 0x880644ddF208E471C6f2230d31f9027578FA6FcC;

    /// @notice The grace period for refund claiming
    uint public constant DUTCH_AUCTION_GRACE_PERIOD = 12 hours;
    /// @notice The mint cap in the dutch auction
    uint public constant DUTCH_AUCTION_MINT_CAP = 2;
    /// @notice The first token id that dutch auction minters will receive, inclusive
    uint public immutable DUTCH_AUCTION_START_ID;
    /// @notice The last token id that dutch auction minters will receive, inclusive
    uint public immutable DUTCH_AUCTION_END_ID;

    /// @notice The price for writelist mints
    uint public writelistPrice;

    /// @notice The address which can admin mint for free, set merkle roots, and set auction params
    address public mintingOwner;
    /// @notice The address which can update the metadata uri
    address public metadataOwner;
    /// @notice The address which will be returned for the ERC721 owner() standard for setting royalties
    address public royaltyOwner;

    /// @notice Records the price and time when the final dutch auction token sells out
    struct DutchAuctionFinalization {
        uint128 price;
        uint128 time;
    }
    /// @notice The instantiation of the dutch auction finalization struct
    DutchAuctionFinalization public dutchEnd;

    /// @notice The token id which will be minted next in the dutch auction
    uint public dutchAuctionNextId;
    /// @notice The token id which will be minted next in the writelist mint
    uint public writelistMintNextId;

    /// @notice Records whether a whitelist allocation has been started, and how many are remaining to claim
    struct Writelist {
        uint128 remaining;
        bool used;
    }

    /// @notice Whether free mints for writers' room holders are open
    bool public writelistMintWritersRoomFreeOpen;

    /// @notice Whether paid mints for writers' room holders are open
    bool public writelistMintWritersRoomOpen;

    /// @notice Construct this from (address, amount) tuple elements
    bytes32 public giveawayMerkleRoot;
    /// @notice Caches writelist allocations once they've been used
    mapping(address => Writelist) public giveawayWritelist;

    /// @notice Construct this from (address, tokenId) tuple elements
    bytes32 public apeMerkleRoot;
    /// @notice Maps (address, tokenId) hash to bool, true if token has minted
    mapping(bytes32 => bool) public apeWritelistUsed;

    /// @notice Maps tokenId to bool, true if token has minted
    mapping(uint => bool) public writersroomWritelistUsed;

    /// @notice Total number of tokens which have minted
    uint public totalSupply = 0;

    /// @notice The prefix to attach to the tokenId to get the metadata uri
    string public baseTokenURI;

    /// @notice Struct is packed to fit within a single 256-bit slot
    struct DutchAuctionMintHistory {
        uint128 amount;
        uint128 price;
    }
    /// @notice Store the mint history for an individual address. Used to issue refunds
    mapping(address => DutchAuctionMintHistory) public mintHistory;

    /// @notice Struct is packed to fit within a single 256-bit slot
    /// @dev uint64 has max value 1.8e19, or 18 ether
    /// @dev uint32 has max value 4.2e9, which corresponds to max timestamp of year 2106
    struct DutchAuctionParams {
        uint64 startPrice;
        uint64 endPrice;
        uint64 priceIncrement;
        uint32 startTime;
        uint32 timeIncrement;
    }
    /// @notice The instantiation of dutch auction parameters
    DutchAuctionParams public params;

    /// @notice Emitted when a token is minted
    event Mint(address indexed owner, uint indexed tokenId);
    /// @notice Emitted when an accounts receives its dutch auction refund
    event DutchAuctionRefund(address indexed account);

    /// @notice Raised when an unauthorized user calls a gated function
    error AccessControl();
    /// @notice Raised when a non-EOA account calls a gated function
    error OnlyEOA(address msgSender);
    /// @notice Raised when a user exceeds their mint cap
    error ExceededUserMintCap();
    /// @notice Raised when the mint has not reached the required timestamp
    error MintNotOpen();
    /// @notice Raised when the user attempts to writelist mint on behalf of a token they do not own
    error DoesNotOwnToken(uint tokenId);
    /// @notice Raised when the user attempts to mint after the dutch auction finishes
    error DutchAuctionOver();
    /// @notice Raised when the admin attempts to withdraw funds before the dutch auction grace period has ended
    error DutchAuctionGracePeriod(uint endPrice, uint endTime);
    /// @notice Raised when a user attempts to claim their dutch auction refund before the dutch auction ends
    error DutchAuctionNotOver();
    /// @notice Raised when the admin attempts to mint within the dutch auction range while the auction is still ongoing
    error DutchAuctionNotOverAdmin();
    /// @notice Raised when the admin attempts to set dutch auction parameters that don't make sense
    error DutchAuctionBadParamsAdmin();
    /// @notice Raised when `sender` does not pass the proper ether amount to `recipient`
    error FailedToSendEther(address sender, address recipient);
    /// @notice Raised when a user tries to writelist mint twice
    error WritelistUsed();
    /// @notice Raised when two calldata arrays do not have the same length
    error MismatchedArrays();
    /// @notice Raised when the user attempts to mint zero items
    error MintZero();

    constructor(uint _DUTCH_AUCTION_START_ID, uint _DUTCH_AUCTION_END_ID) ERC721("Bored & Dangerous", "BOOK") {
        DUTCH_AUCTION_START_ID = _DUTCH_AUCTION_START_ID;
        DUTCH_AUCTION_END_ID = _DUTCH_AUCTION_END_ID;
        dutchAuctionNextId = _DUTCH_AUCTION_START_ID;
        writelistMintNextId = _DUTCH_AUCTION_END_ID + 1;
        mintingOwner = msg.sender;
        metadataOwner = msg.sender;
        royaltyOwner = msg.sender;
    }

    /// @notice Admin mint a token
    function ownerMint(address recipient, uint tokenId) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }

        if (DUTCH_AUCTION_START_ID <= tokenId && tokenId <= DUTCH_AUCTION_END_ID) {
            revert DutchAuctionNotOverAdmin();
        }

        unchecked {
            ++totalSupply;
        }
        _mint(recipient, tokenId);
    }

    /// @notice Admin mint a batch of tokens
    function ownerMintBatch(address[] calldata recipients, uint[] calldata tokenIds) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        
        if (recipients.length != tokenIds.length) {
            revert MismatchedArrays();
        }

        unchecked {
            totalSupply += tokenIds.length;
            for (uint i = 0; i < tokenIds.length; ++i) {
                if (DUTCH_AUCTION_START_ID <= tokenIds[i] && tokenIds[i] <= DUTCH_AUCTION_END_ID) {
                    revert DutchAuctionNotOverAdmin();
                }
                _mint(recipients[i], tokenIds[i]);
            }
        }
    }
    
    ///////////////////
    // DUTCH AUCTION //
    ///////////////////

    /// @notice The current dutch auction price
    /// @dev Reverts if dutch auction has not started yet
    /// @dev Returns the end price even if the dutch auction has sold out
    function dutchAuctionPrice() public view returns (uint) {
        DutchAuctionParams memory _params = params;
        uint numIncrements = (block.timestamp - _params.startTime) / _params.timeIncrement;
        uint price = _params.startPrice - numIncrements * _params.priceIncrement;
        if (price < _params.endPrice) {
            price = _params.endPrice;
        }
        return price;
    }

    /// @notice Dutch auction with refunds
    /// @param amount The number of NFTs to mint, either 1 or 2
    function dutchAuctionMint(uint amount) external payable {
        // Enforce EOA mints
        _onlyEOA(msg.sender);

        if (amount == 0) {
            revert MintZero();
        }

        DutchAuctionMintHistory memory userMintHistory = mintHistory[msg.sender];

        // Enforce per-account mint cap
        if (userMintHistory.amount + amount > DUTCH_AUCTION_MINT_CAP) {
            revert ExceededUserMintCap();
        }

	    uint256 _dutchAuctionNextId = dutchAuctionNextId;
        // Enforce global mint cap
        if (_dutchAuctionNextId + amount > DUTCH_AUCTION_END_ID + 1) {
            revert DutchAuctionOver();
        }

        DutchAuctionParams memory _params = params;

        // Enforce timing
        if (block.timestamp < _params.startTime || _params.startPrice == 0) {
            revert MintNotOpen();
        }
        
        // Calculate dutch auction price
        uint numIncrements = (block.timestamp - _params.startTime) / _params.timeIncrement;
        uint price = _params.startPrice - numIncrements * _params.priceIncrement;
        if (price < _params.endPrice) {
            price = _params.endPrice;
        }

        // Check mint price
        if (msg.value != amount * price) {
            revert FailedToSendEther(msg.sender, address(this));
        }
        unchecked {
            uint128 newPrice = (userMintHistory.amount * userMintHistory.price + uint128(amount * price)) / uint128(userMintHistory.amount + amount);
            mintHistory[msg.sender] = DutchAuctionMintHistory({
                amount: userMintHistory.amount + uint128(amount),
                price: newPrice
            });
            for (uint i = 0; i < amount; ++i) {
                _mint(msg.sender, _dutchAuctionNextId++);
            }
            totalSupply += amount;
            if (_dutchAuctionNextId > DUTCH_AUCTION_END_ID) {
                dutchEnd = DutchAuctionFinalization({
                    price: uint128(price),
                    time: uint128(block.timestamp)
                });
            }
	        dutchAuctionNextId = _dutchAuctionNextId;
        }
    }

    /// @notice Provide dutch auction refunds to people who minted early
    /// @dev Deliberately left unguarded so users can either claim their own, or batch refund others
    function claimDutchAuctionRefund(address[] calldata accounts) external {
        // Check if dutch auction over
        if (dutchEnd.price == 0) {
            revert DutchAuctionNotOver();
        }
        for (uint i = 0; i < accounts.length; ++i) {
            address account = accounts[i];
            DutchAuctionMintHistory memory mint = mintHistory[account];
            // If an account has already been refunded, skip instead of reverting
            // This prevents griefing attacks when performing batch refunds
            if (mint.price > 0) {
                uint refundAmount = mint.amount * (mint.price - dutchEnd.price);
                delete mintHistory[account];
                (bool sent,) = account.call{value: refundAmount}("");
                // Revert if the address has a malicious receive function
                // This is not a griefing vector because the function can be retried
                // without the failing recipient
                if (!sent) {
                    revert FailedToSendEther(address(this), account);
                }
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    // WRITELIST MINTS (free writer's room, paid writer's room, paid bored/mutant ape, paid giveaway) //
    ////////////////////////////////////////////////////////////////////////////////////////////////////

    /// @notice Free mint from writelist ticket allocation
    function writelistMintWritersRoomFree(uint[] calldata tokenIds) external {
        if (!writelistMintWritersRoomFreeOpen) {
            revert MintNotOpen();
        }
        for (uint i = 0; i < tokenIds.length; ++i) {
            address tokenOwner = IERC721(WRITERS_ROOM).ownerOf(tokenIds[i]);
            // This will revert is specific tokenId already minted
            _mint(tokenOwner, tokenIds[i]);
        }
        totalSupply += tokenIds.length;
    }

    /// @notice Paid mint for a writer's room NFT
    function writelistMintWritersRoom(uint[] calldata tokenIds) external payable {
        if (!writelistMintWritersRoomOpen) {
            revert MintNotOpen();
        }
        // Check payment
        if (msg.value != tokenIds.length * writelistPrice) {
            revert FailedToSendEther(msg.sender, address(this));
        }

        for (uint i = 0; i < tokenIds.length; ++i) {
            if (writersroomWritelistUsed[tokenIds[i]]) {
                revert WritelistUsed();
            }
            writersroomWritelistUsed[tokenIds[i]] = true;
            address tokenOwner = IERC721(WRITERS_ROOM).ownerOf(tokenIds[i]);
            _mint(tokenOwner, writelistMintNextId++);
        }
        totalSupply += tokenIds.length;
    }

    /// @notice Mint for a licensed bored ape or mutant ape
    function writelistMintApes(address tokenContract, uint tokenId, bytes32 leaf, bytes32[] calldata proof) external payable {
        // Check payment
        if (msg.value != writelistPrice) {
            revert FailedToSendEther(msg.sender, address(this));
        }
        
        bytes32 tokenHash = keccak256(abi.encodePacked(tokenContract, tokenId));
        
        // Create storage element tracking user mints if this is the first mint for them
        if (apeWritelistUsed[tokenHash]) {
            revert WritelistUsed();
        }
        // Verify that (tokenContract, tokenId) correspond to Merkle leaf
        require(tokenHash == leaf, "Token contract and id don't match Merkle leaf");

        // Verify that (leaf, proof) matches the Merkle root
        require(verify(apeMerkleRoot, leaf, proof), "Not a valid leaf in the Merkle tree");

        // Get the current tokenOwner and mint to them
        address tokenOwner = IERC721(tokenContract).ownerOf(tokenId);

        apeWritelistUsed[tokenHash] = true;
        ++totalSupply;

        _mint(tokenOwner, writelistMintNextId++);
    }

    /// @notice Mint from writelist allocation
    function writelistMintGiveaway(address tokenOwner, uint8 amount, uint8 totalAllocation, bytes32 leaf, bytes32[] memory proof) external payable {
        // Check payment
        if (msg.value != amount * writelistPrice) {
            revert FailedToSendEther(msg.sender, address(this));
        }

        Writelist memory writelist = giveawayWritelist[tokenOwner];
        
        // Create storage element tracking user mints if this is the first mint for them
        if (!writelist.used) {    
            // Verify that (tokenOwner, amount) correspond to Merkle leaf
            require(keccak256(abi.encodePacked(tokenOwner, totalAllocation)) == leaf, "Sender and amount don't match Merkle leaf");

            // Verify that (leaf, proof) matches the Merkle root
            require(verify(giveawayMerkleRoot, leaf, proof), "Not a valid leaf in the Merkle tree");

            writelist.used = true;
            // Save some gas by never writing to this slot if it will be reset to zero at method end
            if (amount != totalAllocation) {
                writelist.remaining = totalAllocation - amount;
            }
        }
        else {
            writelist.remaining -= amount;
        }

        giveawayWritelist[tokenOwner] = writelist;
        totalSupply += amount;
        for (uint i = 0; i < amount; ++i) {
            _mint(tokenOwner, writelistMintNextId++);
        }
    }

    /// @notice Ensure the proof and leaf match the merkle root
    function verify(bytes32 root, bytes32 leaf, bytes32[] memory proof) public pure returns (bool) {
        return MerkleProof.verify(proof, root, leaf);
    }

    /////////////////////////
    // ADMIN FUNCTIONALITY //
    /////////////////////////

    /// @notice Set metadata
    function setBaseTokenURI(string memory _baseTokenURI) external {
        if (msg.sender != metadataOwner) {
            revert AccessControl();
        }
        baseTokenURI = _baseTokenURI;
    }

    /// @notice Set merkle root
    function setGiveawayMerkleRoot(bytes32 _giveawayMerkleRoot) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        giveawayMerkleRoot = _giveawayMerkleRoot;
    }

    /// @notice Set merkle root
    function setApeMerkleRoot(bytes32 _apeMerkleRoot) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        apeMerkleRoot = _apeMerkleRoot;
    }

    /// @notice Set parameters
    function setDutchAuctionStruct(DutchAuctionParams calldata _params) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        if (!(_params.startPrice >= _params.endPrice && _params.endPrice > 0 && _params.startTime > 0 && _params.timeIncrement > 0)) {
            revert DutchAuctionBadParamsAdmin();
        }
        params = DutchAuctionParams({
            startPrice: _params.startPrice,
            endPrice: _params.endPrice,
            priceIncrement: _params.priceIncrement,
            startTime: _params.startTime,
            timeIncrement: _params.timeIncrement
        });
    }

    /// @notice Set writelistMintNextId
    /// @dev Should not be used, but failsafe in case the admin accidentally mints a token id in the writelist range too early
    function setWritelistMintNextId(uint _writelistMintNextId) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        writelistMintNextId = _writelistMintNextId;
    }

    /// @notice Set writelistMintWritersRoomFreeOpen
    function setWritelistMintWritersRoomFreeOpen(bool _value) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        writelistMintWritersRoomFreeOpen = _value;
    }

    /// @notice Set writelistMintWritersRoomOpen
    function setWritelistMintWritersRoomOpen(bool _value) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        writelistMintWritersRoomOpen = _value;
    }

    /// @notice Set writelistPrice
    function setWritelistPrice(uint _price) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        writelistPrice = _price;
    }

    /// @notice Claim funds
    function claimFunds(address payable recipient) external {
        if (!(msg.sender == mintingOwner || msg.sender == metadataOwner || msg.sender == royaltyOwner)) {
            revert AccessControl();
        }

        // Wait for the grace period after scheduled end to allow claiming of dutch auction refunds
        if (!(dutchEnd.price > 0 && block.timestamp >= dutchEnd.time + DUTCH_AUCTION_GRACE_PERIOD)) {
            revert DutchAuctionGracePeriod(dutchEnd.price, dutchEnd.time);
        }

        (bool sent,) = recipient.call{value: address(this).balance}("");
        if (!sent) {
            revert FailedToSendEther(address(this), recipient);
        }
    }

    ////////////////////////////////////
    // ACCESS CONTROL ADDRESS UPDATES //
    ////////////////////////////////////

    /// @notice Update the mintingOwner
    /// @dev Can also be used to revoke this power by setting to 0x0
    function setMintingOwner(address _mintingOwner) external {
        if (msg.sender != mintingOwner) {
            revert AccessControl();
        }
        mintingOwner = _mintingOwner;
    }

    /// @notice Update the metadataOwner
    /// @dev Can also be used to revoke this power by setting to 0x0
    /// @dev Should only be revoked after setting an IPFS url so others can pin
    function setMetadataOwner(address _metadataOwner) external {
        if (msg.sender != metadataOwner) {
            revert AccessControl();
        }
        metadataOwner = _metadataOwner;
    }

    /// @notice Update the royaltyOwner
    /// @dev Can also be used to revoke this power by setting to 0x0
    function setRoyaltyOwner(address _royaltyOwner) external {
        if (msg.sender != royaltyOwner) {
            revert AccessControl();
        }
        royaltyOwner = _royaltyOwner;
    }

    /// @notice The address which can set royalties
    function owner() external view returns (address) {
        return royaltyOwner;
    }

    // ROYALTY FUNCTIONALITY

    /// @dev See {IERC165-supportsInterface}.
    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC2981) returns (bool) {
        return
            interfaceId == 0x2a55205a || // ERC165 Interface ID for ERC2981
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

    /// @dev See {ERC2981-_setDefaultRoyalty}.
    function setDefaultRoyalty(address receiver, uint96 feeNumerator) external {
        if (msg.sender != royaltyOwner) {
            revert AccessControl();
        }
        _setDefaultRoyalty(receiver, feeNumerator);
    }

    /// @dev See {ERC2981-_deleteDefaultRoyalty}.
    function deleteDefaultRoyalty() external {
        if (msg.sender != royaltyOwner) {
            revert AccessControl();
        }
        _deleteDefaultRoyalty();
    }

    /// @dev See {ERC2981-_setTokenRoyalty}.
    function setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) external {
        if (msg.sender != royaltyOwner) {
            revert AccessControl();
        }
        _setTokenRoyalty(tokenId, receiver, feeNumerator);
    }

    /// @dev See {ERC2981-_resetTokenRoyalty}.
    function resetTokenRoyalty(uint256 tokenId) external {
        if (msg.sender != royaltyOwner) {
            revert AccessControl();
        }
        _resetTokenRoyalty(tokenId);
    }

    // METADATA FUNCTIONALITY

    /// @notice Returns the metadata URI for a given token
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        return string(abi.encodePacked(baseTokenURI, Strings.toString(tokenId)));
    }

    // INTERNAL FUNCTIONS

    /// @dev Revert if the account is a smart contract. Does not protect against calls from the constructor.
    /// @param account The account to check
    function _onlyEOA(address account) internal view {
        if (msg.sender != tx.origin || account.code.length > 0) {
            revert OnlyEOA(account);
        }
    }
}

File 2 of 8 : ERC721.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 indexed id);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id);

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /*//////////////////////////////////////////////////////////////
                         METADATA STORAGE/LOGIC
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    function tokenURI(uint256 id) public view virtual returns (string memory);

    /*//////////////////////////////////////////////////////////////
                      ERC721 BALANCE/OWNER STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

    function ownerOf(uint256 id) public view virtual returns (address owner) {
        require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
    }

    function balanceOf(address owner) public view virtual returns (uint256) {
        require(owner != address(0), "ZERO_ADDRESS");

        return _balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                         ERC721 APPROVAL STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) public getApproved;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /*//////////////////////////////////////////////////////////////
                              ERC721 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 id) public virtual {
        address owner = _ownerOf[id];

        require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        require(from == _ownerOf[id], "WRONG_FROM");

        require(to != address(0), "INVALID_RECIPIENT");

        require(
            msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
            "NOT_AUTHORIZED"
        );

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");

        require(_ownerOf[id] == address(0), "ALREADY_MINTED");

        // Counter overflow is incredibly unrealistic.
        unchecked {
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        emit Transfer(address(0), to, id);
    }

    function _burn(uint256 id) internal virtual {
        address owner = _ownerOf[id];

        require(owner != address(0), "NOT_MINTED");

        // Ownership check above ensures no underflow.
        unchecked {
            _balanceOf[owner]--;
        }

        delete _ownerOf[id];

        delete getApproved[id];

        emit Transfer(owner, address(0), id);
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL SAFE MINT LOGIC
    //////////////////////////////////////////////////////////////*/

    function _safeMint(address to, uint256 id) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _safeMint(
        address to,
        uint256 id,
        bytes memory data
    ) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }
}

/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721TokenReceiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721TokenReceiver.onERC721Received.selector;
    }
}

File 3 of 8 : ERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.0;

import "../../interfaces/IERC2981.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
        return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

File 4 of 8 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be proved to be a part of a Merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and the sibling nodes in `proof`,
     * consuming from one or the other at each step according to the instructions given by
     * `proofFlags`.
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuild the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value for the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i] ? leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++] : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            return hashes[totalHashes - 1];
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

File 5 of 8 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

File 6 of 8 : IERC2981.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.0;

import "../utils/introspection/IERC165.sol";

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

File 7 of 8 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 8 of 8 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

Settings
{
  "remappings": [
    "@rari-capital/solmate/=lib/solmate/",
    "contracts/=contracts/",
    "ds-test/=lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "murky/=lib/murky/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solmate/=lib/solmate/src/",
    "src/=src/",
    "script/=script/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_DUTCH_AUCTION_START_ID","type":"uint256"},{"internalType":"uint256","name":"_DUTCH_AUCTION_END_ID","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControl","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"DoesNotOwnToken","type":"error"},{"inputs":[],"name":"DutchAuctionBadParamsAdmin","type":"error"},{"inputs":[{"internalType":"uint256","name":"endPrice","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"DutchAuctionGracePeriod","type":"error"},{"inputs":[],"name":"DutchAuctionNotOver","type":"error"},{"inputs":[],"name":"DutchAuctionNotOverAdmin","type":"error"},{"inputs":[],"name":"DutchAuctionOver","type":"error"},{"inputs":[],"name":"ExceededUserMintCap","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"FailedToSendEther","type":"error"},{"inputs":[],"name":"MintNotOpen","type":"error"},{"inputs":[],"name":"MintZero","type":"error"},{"inputs":[],"name":"MismatchedArrays","type":"error"},{"inputs":[{"internalType":"address","name":"msgSender","type":"address"}],"name":"OnlyEOA","type":"error"},{"inputs":[],"name":"WritelistUsed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"DutchAuctionRefund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DUTCH_AUCTION_END_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DUTCH_AUCTION_GRACE_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DUTCH_AUCTION_MINT_CAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DUTCH_AUCTION_START_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WRITERS_ROOM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"apeMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"apeWritelistUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"claimDutchAuctionRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"recipient","type":"address"}],"name":"claimFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deleteDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"dutchAuctionMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"dutchAuctionNextId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dutchAuctionPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dutchEnd","outputs":[{"internalType":"uint128","name":"price","type":"uint128"},{"internalType":"uint128","name":"time","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"giveawayMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"giveawayWritelist","outputs":[{"internalType":"uint128","name":"remaining","type":"uint128"},{"internalType":"bool","name":"used","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metadataOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintHistory","outputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint128","name":"price","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"ownerMintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"params","outputs":[{"internalType":"uint64","name":"startPrice","type":"uint64"},{"internalType":"uint64","name":"endPrice","type":"uint64"},{"internalType":"uint64","name":"priceIncrement","type":"uint64"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"timeIncrement","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"resetTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_apeMerkleRoot","type":"bytes32"}],"name":"setApeMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseTokenURI","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"startPrice","type":"uint64"},{"internalType":"uint64","name":"endPrice","type":"uint64"},{"internalType":"uint64","name":"priceIncrement","type":"uint64"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"timeIncrement","type":"uint32"}],"internalType":"struct BoredAndDangerous.DutchAuctionParams","name":"_params","type":"tuple"}],"name":"setDutchAuctionStruct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_giveawayMerkleRoot","type":"bytes32"}],"name":"setGiveawayMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_metadataOwner","type":"address"}],"name":"setMetadataOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mintingOwner","type":"address"}],"name":"setMintingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_royaltyOwner","type":"address"}],"name":"setRoyaltyOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setTokenRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_writelistMintNextId","type":"uint256"}],"name":"setWritelistMintNextId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setWritelistMintWritersRoomFreeOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setWritelistMintWritersRoomOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setWritelistPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"verify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"writelistMintApes","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"},{"internalType":"uint8","name":"amount","type":"uint8"},{"internalType":"uint8","name":"totalAllocation","type":"uint8"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"writelistMintGiveaway","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"writelistMintNextId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"writelistMintWritersRoom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"writelistMintWritersRoomFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"writelistMintWritersRoomFreeOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"writelistMintWritersRoomOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"writelistPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"writersroomWritelistUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60c060405260006015553480156200001657600080fd5b5060405162003cf538038062003cf58339810160408190526200003991620000f6565b60405180604001604052806011815260200170426f72656420262044616e6765726f757360781b81525060405180604001604052806004815260200163424f4f4b60e01b8152508160009081620000919190620001c0565b506001620000a08282620001c0565b505050608082905260a0819052600d829055620000bf8160016200028c565b600e55505060098054336001600160a01b03199182168117909255600a8054821683179055600b80549091169091179055620002b3565b600080604083850312156200010a57600080fd5b505080516020909101519092909150565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200014657607f821691505b6020821081036200016757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620001bb57600081815260208120601f850160051c81016020861015620001965750805b601f850160051c820191505b81811015620001b757828155600101620001a2565b5050505b505050565b81516001600160401b03811115620001dc57620001dc6200011b565b620001f481620001ed845462000131565b846200016d565b602080601f8311600181146200022c5760008415620002135750858301515b600019600386901b1c1916600185901b178555620001b7565b600085815260208120601f198616915b828110156200025d578886015182559484019460019091019084016200023c565b50858210156200027c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008219821115620002ae57634e487b7160e01b600052601160045260246000fd5b500190565b60805160a0516139f26200030360003960008181610941015281816117e1015281816118d80152818161276f01526129ad015260008181610988015281816117b701526118ae01526139f26000f3fe6080604052600436106103c35760003560e01c80638a88b8b3116101f2578063b77dc4871161010d578063d79a8ab1116100a0578063ecde3c891161006f578063ecde3c8914610c77578063f1085dfb14610c97578063f8cce6c014610cad578063ff02c51714610cc057600080fd5b8063d79a8ab114610be6578063db5eb70214610c06578063e985e9c514610c26578063ec3ccec214610c6157600080fd5b8063cff0ab96116100dc578063cff0ab9614610af3578063d076503014610b81578063d299c49b14610bb1578063d547cfb714610bd157600080fd5b8063b77dc48714610a87578063b88d4fde14610a9d578063bb0fdd8d14610abd578063c87b56dd14610ad357600080fd5b8063a1876cc411610185578063a90af91211610154578063a90af91214610a1d578063aa1b103f14610a32578063b0f7676714610a47578063b113c60814610a6757600080fd5b8063a1876cc4146109aa578063a22cb465146109bd578063a537f74d146109dd578063a5da2e60146109f257600080fd5b806396062e1f116101c157806396062e1f1461090f57806396473b061461092f5780639d5e2a24146109635780639e55dcb61461097657600080fd5b80638a88b8b3146108925780638da5cb5b146108c25780638fab5047146108e057806395d89b41146108fa57600080fd5b8063484b973c116102e257806363c97d63116102755780636f8b4a72116102445780636f8b4a72146107d157806370a08231146108325780637fb3165a146108525780638a616bc01461087257600080fd5b806363c97d631461075b578063659cdef61461077b578063693d0df21461079b5780636f26d648146107bb57600080fd5b80635ad388d4116102b15780635ad388d41461069b5780635c49d2cb146106ba5780635ecc1566146106da5780636352211e1461073b57600080fd5b8063484b973c146106255780634ab165541461064557806351312f2f146106655780635944c7531461067b57600080fd5b80632525b3d71161035a5780633423e548116103295780633423e548146105b257806335137cd0146105d257806338935c1c146105f257806342842e0e1461060557600080fd5b80632525b3d7146105135780632a55205a146105335780632ab545b51461057257806330176e131461059257600080fd5b8063095ea7b311610396578063095ea7b31461048f57806318160ddd146104af5780631b8cae7b146104d357806323b872dd146104f357600080fd5b806301ffc9a7146103c857806304634d8d146103fd57806306fdde031461041f578063081812fc14610441575b600080fd5b3480156103d457600080fd5b506103e86103e3366004612e89565b610ce8565b60405190151581526020015b60405180910390f35b34801561040957600080fd5b5061041d610418366004612ed2565b610d55565b005b34801561042b57600080fd5b50610434610d8e565b6040516103f49190612f37565b34801561044d57600080fd5b5061047761045c366004612f6a565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016103f4565b34801561049b57600080fd5b5061041d6104aa366004612f83565b610e1c565b3480156104bb57600080fd5b506104c560155481565b6040519081526020016103f4565b3480156104df57600080fd5b5061041d6104ee366004612faf565b610f03565b3480156104ff57600080fd5b5061041d61050e366004612fc7565b61111c565b34801561051f57600080fd5b5061041d61052e366004613008565b6112e3565b34801561053f57600080fd5b5061055361054e366004613025565b611330565b604080516001600160a01b0390931683526020830191909152016103f4565b34801561057e57600080fd5b5061041d61058d366004612f6a565b6113de565b34801561059e57600080fd5b5061041d6105ad36600461308d565b61140e565b3480156105be57600080fd5b506103e86105cd3660046131a0565b611445565b3480156105de57600080fd5b5061041d6105ed366004613008565b61145a565b61041d610600366004613233565b6114a7565b34801561061157600080fd5b5061041d610620366004612fc7565b611691565b34801561063157600080fd5b5061041d610640366004612f83565b611789565b34801561065157600080fd5b5061041d610660366004613274565b611835565b34801561067157600080fd5b506104c5600d5481565b34801561068757600080fd5b5061041d6106963660046132df565b611988565b3480156106a757600080fd5b50600f546103e890610100900460ff1681565b3480156106c657600080fd5b50600954610477906001600160a01b031681565b3480156106e657600080fd5b5061071b6106f5366004613008565b6017602052600090815260409020546001600160801b0380821691600160801b90041682565b604080516001600160801b039384168152929091166020830152016103f4565b34801561074757600080fd5b50610477610756366004612f6a565b6119be565b34801561076757600080fd5b5061041d61077636600461332d565b611a15565b34801561078757600080fd5b5061041d61079636600461332d565b611a5a565b3480156107a757600080fd5b5061041d6107b6366004613008565b611a98565b3480156107c757600080fd5b506104c5600e5481565b3480156107dd57600080fd5b506108136107ec366004613008565b6011602052600090815260409020546001600160801b03811690600160801b900460ff1682565b604080516001600160801b0390931683529015156020830152016103f4565b34801561083e57600080fd5b506104c561084d366004613008565b611be7565b34801561085e57600080fd5b5061041d61086d366004612f6a565b611c4a565b34801561087e57600080fd5b5061041d61088d366004612f6a565b611c7a565b34801561089e57600080fd5b506103e86108ad366004612f6a565b60136020526000908152604090205460ff1681565b3480156108ce57600080fd5b50600b546001600160a01b0316610477565b3480156108ec57600080fd5b50600f546103e89060ff1681565b34801561090657600080fd5b50610434611cb9565b34801561091b57600080fd5b5061041d61092a366004612f6a565b611cc6565b34801561093b57600080fd5b506104c57f000000000000000000000000000000000000000000000000000000000000000081565b61041d610971366004613348565b611cf6565b34801561098257600080fd5b506104c57f000000000000000000000000000000000000000000000000000000000000000081565b61041d6109b83660046133c2565b611f0c565b3480156109c957600080fd5b5061041d6109d836600461343c565b612149565b3480156109e957600080fd5b506104c56121b5565b3480156109fe57600080fd5b50600c5461071b906001600160801b0380821691600160801b90041682565b348015610a2957600080fd5b506104c5600281565b348015610a3e57600080fd5b5061041d61228b565b348015610a5357600080fd5b5061041d610a62366004612f6a565b6122c2565b348015610a7357600080fd5b50600a54610477906001600160a01b031681565b348015610a9357600080fd5b506104c561a8c081565b348015610aa957600080fd5b5061041d610ab8366004613468565b6122f2565b348015610ac957600080fd5b506104c560085481565b348015610adf57600080fd5b50610434610aee366004612f6a565b6123d3565b348015610aff57600080fd5b50601854610b40906001600160401b0380821691600160401b8104821691600160801b8204169063ffffffff600160c01b8204811691600160e01b90041685565b604080516001600160401b0396871681529486166020860152929094169183019190915263ffffffff9081166060830152909116608082015260a0016103f4565b348015610b8d57600080fd5b506103e8610b9c366004612f6a565b60146020526000908152604090205460ff1681565b348015610bbd57600080fd5b5061041d610bcc366004613233565b612407565b348015610bdd57600080fd5b50610434612591565b348015610bf257600080fd5b5061041d610c01366004613233565b61259e565b348015610c1257600080fd5b50600b54610477906001600160a01b031681565b348015610c3257600080fd5b506103e8610c41366004613506565b600560209081526000928352604080842090915290825290205460ff1681565b348015610c6d57600080fd5b506104c560105481565b348015610c8357600080fd5b5061041d610c92366004613008565b612689565b348015610ca357600080fd5b506104c560125481565b61041d610cbb366004612f6a565b6126d6565b348015610ccc57600080fd5b5061047773880644ddf208e471c6f2230d31f9027578fa6fcc81565b600063152a902d60e11b6001600160e01b031983161480610d1957506301ffc9a760e01b6001600160e01b03198316145b80610d3457506380ac58cd60e01b6001600160e01b03198316145b80610d4f5750635b5e139f60e01b6001600160e01b03198316145b92915050565b600b546001600160a01b03163314610d8057604051631f7c4bf360e01b815260040160405180910390fd5b610d8a8282612a12565b5050565b60008054610d9b9061353f565b80601f0160208091040260200160405190810160405280929190818152602001828054610dc79061353f565b8015610e145780601f10610de957610100808354040283529160200191610e14565b820191906000526020600020905b815481529060010190602001808311610df757829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610e6557506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610ea75760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6009546001600160a01b03163314610f2e57604051631f7c4bf360e01b815260040160405180910390fd5b610f3e6040820160208301613573565b6001600160401b0316610f546020830183613573565b6001600160401b031610158015610f8357506000610f786040830160208401613573565b6001600160401b0316115b8015610fa457506000610f9c608083016060840161359c565b63ffffffff16115b8015610fc557506000610fbd60a083016080840161359c565b63ffffffff16115b610fe2576040516340636ec960e01b815260040160405180910390fd5b6040805160a0810190915280610ffb6020840184613573565b6001600160401b0316815260200182602001602081019061101c9190613573565b6001600160401b0316815260200161103a6060840160408501613573565b6001600160401b03168152602001611058608084016060850161359c565b63ffffffff16815260200161107360a084016080850161359c565b63ffffffff9081169091528151601880546020850151604086015160608701516080909701518616600160e01b026001600160e01b0397909616600160c01b0263ffffffff60c01b196001600160401b03928316600160801b02166bffffffffffffffffffffffff60801b19938316600160401b026fffffffffffffffffffffffffffffffff199095169290961691909117929092171692909217919091179290921617905550565b6000818152600260205260409020546001600160a01b038481169116146111725760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b6044820152606401610e9e565b6001600160a01b0382166111bc5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610e9e565b336001600160a01b03841614806111f657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061121757506000818152600460205260409020546001600160a01b031633145b6112545760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610e9e565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600b546001600160a01b0316331461130e57604051631f7c4bf360e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60008281526007602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916113a55750604080518082019091526006546001600160a01b0381168252600160a01b90046001600160601b031660208201525b6020810151600090612710906113c4906001600160601b0316876135d8565b6113ce919061360d565b91519350909150505b9250929050565b6009546001600160a01b0316331461140957604051631f7c4bf360e01b815260040160405180910390fd5b600e55565b600a546001600160a01b0316331461143957604051631f7c4bf360e01b815260040160405180910390fd5b6016610d8a828261366f565b6000611452828585612acc565b949350505050565b6009546001600160a01b0316331461148557604051631f7c4bf360e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b600f54610100900460ff166114cf5760405163951b974f60e01b815260040160405180910390fd5b6008546114dc90826135d8565b34146115035760405163b0b0ec3560e01b8152336004820152306024820152604401610e9e565b60005b8181101561167257601460008484848181106115245761152461372e565b602090810292909201358352508101919091526040016000205460ff161561155f576040516303a9a53560e61b815260040160405180910390fd5b6001601460008585858181106115775761157761372e565b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550600073880644ddf208e471c6f2230d31f9027578fa6fcc6001600160a01b0316636352211e8585858181106115da576115da61372e565b905060200201356040518263ffffffff1660e01b81526004016115ff91815260200190565b602060405180830381865afa15801561161c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116409190613744565b600e8054919250611661918391600061165883613761565b91905055612ae2565b5061166b81613761565b9050611506565b508181905060156000828254611688919061377a565b90915550505050565b61169c83838361111c565b6001600160a01b0382163b15806117455750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015611715573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117399190613792565b6001600160e01b031916145b6117845760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610e9e565b505050565b6009546001600160a01b031633146117b457604051631f7c4bf360e01b815260040160405180910390fd5b807f00000000000000000000000000000000000000000000000000000000000000001115801561180457507f00000000000000000000000000000000000000000000000000000000000000008111155b156118225760405163a80cc22160e01b815260040160405180910390fd5b601580546001019055610d8a8282612ae2565b6009546001600160a01b0316331461186057604051631f7c4bf360e01b815260040160405180910390fd5b8281146118805760405163a121188760e01b815260040160405180910390fd5b601580548201905560005b81811015611981578282828181106118a5576118a561372e565b905060200201357f00000000000000000000000000000000000000000000000000000000000000001115801561191357507f00000000000000000000000000000000000000000000000000000000000000008383838181106119095761190961372e565b9050602002013511155b156119315760405163a80cc22160e01b815260040160405180910390fd5b6119798585838181106119465761194661372e565b905060200201602081019061195b9190613008565b84848481811061196d5761196d61372e565b90506020020135612ae2565b60010161188b565b5050505050565b600b546001600160a01b031633146119b357604051631f7c4bf360e01b815260040160405180910390fd5b611784838383612bed565b6000818152600260205260409020546001600160a01b031680611a105760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b6044820152606401610e9e565b919050565b6009546001600160a01b03163314611a4057604051631f7c4bf360e01b815260040160405180910390fd5b600f80549115156101000261ff0019909216919091179055565b6009546001600160a01b03163314611a8557604051631f7c4bf360e01b815260040160405180910390fd5b600f805460ff1916911515919091179055565b6009546001600160a01b0316331480611abb5750600a546001600160a01b031633145b80611ad05750600b546001600160a01b031633145b611aed57604051631f7c4bf360e01b815260040160405180910390fd5b600c546001600160801b031615801590611b265750600c54611b229061a8c090600160801b90046001600160801b031661377a565b4210155b611b6257600c54604051634433b4ab60e11b81526001600160801b038083166004830152600160801b9092049091166024820152604401610e9e565b6000816001600160a01b03164760405160006040518083038185875af1925050503d8060008114611baf576040519150601f19603f3d011682016040523d82523d6000602084013e611bb4565b606091505b5050905080610d8a5760405163b0b0ec3560e01b81523060048201526001600160a01b0383166024820152604401610e9e565b60006001600160a01b038216611c2e5760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401610e9e565b506001600160a01b031660009081526003602052604090205490565b6009546001600160a01b03163314611c7557604051631f7c4bf360e01b815260040160405180910390fd5b601255565b600b546001600160a01b03163314611ca557604051631f7c4bf360e01b815260040160405180910390fd5b600090815260076020526040812055565b50565b60018054610d9b9061353f565b6009546001600160a01b03163314611cf157604051631f7c4bf360e01b815260040160405180910390fd5b600855565b6008543414611d205760405163b0b0ec3560e01b8152336004820152306024820152604401610e9e565b6040516bffffffffffffffffffffffff19606087901b1660208201526034810185905260009060540160408051601f1981840301815291815281516020928301206000818152601390935291205490915060ff1615611d92576040516303a9a53560e61b815260040160405180910390fd5b838114611df75760405162461bcd60e51b815260206004820152602d60248201527f546f6b656e20636f6e747261637420616e6420696420646f6e2774206d61746360448201526c341026b2b935b632903632b0b360991b6064820152608401610e9e565b611e376012548585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061144592505050565b611e535760405162461bcd60e51b8152600401610e9e906137af565b6040516331a9108f60e11b8152600481018690526000906001600160a01b03881690636352211e90602401602060405180830381865afa158015611e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ebf9190613744565b6000838152601360205260408120805460ff191660011790556015805492935091611ee990613761565b90915550600e8054611f0391839190600061165883613761565b50505050505050565b600854611f1c9060ff86166135d8565b3414611f435760405163b0b0ec3560e01b8152336004820152306024820152604401610e9e565b6001600160a01b0385166000908152601160209081526040918290208251808401909352546001600160801b0381168352600160801b900460ff161515908201819052612086576040516bffffffffffffffffffffffff19606088901b1660208201526001600160f81b031960f886901b166034820152839060350160405160208183030381529060405280519060200120146120345760405162461bcd60e51b815260206004820152602960248201527f53656e64657220616e6420616d6f756e7420646f6e2774206d61746368204d656044820152683935b632903632b0b360b91b6064820152608401610e9e565b6120416010548484611445565b61205d5760405162461bcd60e51b8152600401610e9e906137af565b6001602082015260ff858116908516146120815761207b85856137f2565b60ff1681525b6120a8565b8460ff168160000181815161209b9190613815565b6001600160801b03169052505b6001600160a01b0386166000908152601160209081526040822083518154928501511515600160801b0270ffffffffffffffffffffffffffffffffff199093166001600160801b03909116179190911790556015805460ff8816929061210f90849061377a565b90915550600090505b8560ff16811015611f0357600e805461213991899190600061165883613761565b61214281613761565b9050612118565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6040805160a0810182526018546001600160401b038082168352600160401b820481166020840152600160801b8204169282019290925263ffffffff600160c01b8304811660608301819052600160e01b9093041660808201819052600092839190612221904261383d565b61222b919061360d565b9050600082604001516001600160401b03168261224891906135d8565b835161225d91906001600160401b031661383d565b905082602001516001600160401b0316811015612284575060208201516001600160401b03165b9392505050565b600b546001600160a01b031633146122b657604051631f7c4bf360e01b815260040160405180910390fd5b6122c06000600655565b565b6009546001600160a01b031633146122ed57604051631f7c4bf360e01b815260040160405180910390fd5b601055565b6122fd85858561111c565b6001600160a01b0384163b15806123945750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906123459033908a90899089908990600401613854565b6020604051808303816000875af1158015612364573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123889190613792565b6001600160e01b031916145b6119815760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610e9e565b606060166123e083612cb8565b6040516020016123f19291906138a8565b6040516020818303038152906040529050919050565b600c546001600160801b0316600003612433576040516318e998a560e01b815260040160405180910390fd5b60005b818110156117845760008383838181106124525761245261372e565b90506020020160208101906124679190613008565b6001600160a01b0381166000908152601760209081526040918290208251808401909352546001600160801b038082168452600160801b90910416908201819052919250901561257e57600c5460208201516000916124d1916001600160801b0390911690613815565b82516124dd919061392f565b6001600160a01b038416600081815260176020526040808220829055516001600160801b039390931693509183908381818185875af1925050503d8060008114612543576040519150601f19603f3d011682016040523d82523d6000602084013e612548565b606091505b505090508061257b5760405163b0b0ec3560e01b81523060048201526001600160a01b0385166024820152604401610e9e565b50505b50508061258a90613761565b9050612436565b60168054610d9b9061353f565b600f5460ff166125c15760405163951b974f60e01b815260040160405180910390fd5b60005b8181101561167257600073880644ddf208e471c6f2230d31f9027578fa6fcc636352211e8585858181106125fa576125fa61372e565b905060200201356040518263ffffffff1660e01b815260040161261f91815260200190565b602060405180830381865afa15801561263c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126609190613744565b90506126788185858581811061196d5761196d61372e565b5061268281613761565b90506125c4565b600a546001600160a01b031633146126b457604051631f7c4bf360e01b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6126df33612db8565b806000036127005760405163220328c760e11b815260040160405180910390fd5b336000908152601760209081526040918290208251808401909352546001600160801b03808216808552600160801b909204169183019190915260029061274890849061377a565b111561276757604051630c599a5960e31b815260040160405180910390fd5b600d546127957f0000000000000000000000000000000000000000000000000000000000000000600161377a565b61279f848361377a565b11156127be5760405163bdec14e360e01b815260040160405180910390fd5b6040805160a0810182526018546001600160401b038082168352600160401b820481166020840152600160801b8204169282019290925263ffffffff600160c01b8304811660608301819052600160e01b9093041660808201529042108061282e575080516001600160401b0316155b1561284c5760405163951b974f60e01b815260040160405180910390fd5b6000816080015163ffffffff16826060015163ffffffff164261286f919061383d565b612879919061360d565b9050600082604001516001600160401b03168261289691906135d8565b83516128ab91906001600160401b031661383d565b905082602001516001600160401b03168110156128d2575060208201516001600160401b03165b6128dc81876135d8565b34146129035760405163b0b0ec3560e01b8152336004820152306024820152604401610e9e565b845160208601516000916001600160801b038082168a01811692909102848a02011681612932576129326135f7565b60408051808201825289516001600160801b03908c01811682529390920483811660208085019182523360009081526017909152928320935190518516600160801b029416939093179091559091505b878110156129a25761299a3387806001019850612ae2565b600101612982565b5060158054880190557f0000000000000000000000000000000000000000000000000000000000000000851115612a0457604080518082019091526001600160801b03808416808352429091166020909201829052600160801b90910217600c555b505050600d91909155505050565b6127106001600160601b0382161115612a3d5760405162461bcd60e51b8152600401610e9e9061395e565b6001600160a01b038216612a935760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610e9e565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600655565b600082612ad98584612dfa565b14949350505050565b6001600160a01b038216612b2c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610e9e565b6000818152600260205260409020546001600160a01b031615612b825760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610e9e565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6127106001600160601b0382161115612c185760405162461bcd60e51b8152600401610e9e9061395e565b6001600160a01b038216612c6e5760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610e9e565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752600790529190942093519051909116600160a01b029116179055565b606081600003612cdf5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612d095780612cf381613761565b9150612d029050600a8361360d565b9150612ce3565b6000816001600160401b03811115612d2357612d23613047565b6040519080825280601f01601f191660200182016040528015612d4d576020820181803683370190505b5090505b841561145257612d6260018361383d565b9150612d6f600a866139a8565b612d7a90603061377a565b60f81b818381518110612d8f57612d8f61372e565b60200101906001600160f81b031916908160001a905350612db1600a8661360d565b9450612d51565b3332141580612dd157506000816001600160a01b03163b115b15611cb6576040516393575bef60e01b81526001600160a01b0382166004820152602401610e9e565b600081815b8451811015612e3f57612e2b82868381518110612e1e57612e1e61372e565b6020026020010151612e47565b915080612e3781613761565b915050612dff565b509392505050565b6000818310612e63576000828152602084905260409020612284565b5060009182526020526040902090565b6001600160e01b031981168114611cb657600080fd5b600060208284031215612e9b57600080fd5b813561228481612e73565b6001600160a01b0381168114611cb657600080fd5b80356001600160601b0381168114611a1057600080fd5b60008060408385031215612ee557600080fd5b8235612ef081612ea6565b9150612efe60208401612ebb565b90509250929050565b60005b83811015612f22578181015183820152602001612f0a565b83811115612f31576000848401525b50505050565b6020815260008251806020840152612f56816040850160208701612f07565b601f01601f19169190910160400192915050565b600060208284031215612f7c57600080fd5b5035919050565b60008060408385031215612f9657600080fd5b8235612fa181612ea6565b946020939093013593505050565b600060a08284031215612fc157600080fd5b50919050565b600080600060608486031215612fdc57600080fd5b8335612fe781612ea6565b92506020840135612ff781612ea6565b929592945050506040919091013590565b60006020828403121561301a57600080fd5b813561228481612ea6565b6000806040838503121561303857600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561308557613085613047565b604052919050565b600060208083850312156130a057600080fd5b82356001600160401b03808211156130b757600080fd5b818501915085601f8301126130cb57600080fd5b8135818111156130dd576130dd613047565b6130ef601f8201601f1916850161305d565b9150808252868482850101111561310557600080fd5b8084840185840137600090820190930192909252509392505050565b600082601f83011261313257600080fd5b813560206001600160401b0382111561314d5761314d613047565b8160051b61315c82820161305d565b928352848101820192828101908785111561317657600080fd5b83870192505b848310156131955782358252918301919083019061317c565b979650505050505050565b6000806000606084860312156131b557600080fd5b833592506020840135915060408401356001600160401b038111156131d957600080fd5b6131e586828701613121565b9150509250925092565b60008083601f84011261320157600080fd5b5081356001600160401b0381111561321857600080fd5b6020830191508360208260051b85010111156113d757600080fd5b6000806020838503121561324657600080fd5b82356001600160401b0381111561325c57600080fd5b613268858286016131ef565b90969095509350505050565b6000806000806040858703121561328a57600080fd5b84356001600160401b03808211156132a157600080fd5b6132ad888389016131ef565b909650945060208701359150808211156132c657600080fd5b506132d3878288016131ef565b95989497509550505050565b6000806000606084860312156132f457600080fd5b83359250602084013561330681612ea6565b915061331460408501612ebb565b90509250925092565b80358015158114611a1057600080fd5b60006020828403121561333f57600080fd5b6122848261331d565b60008060008060006080868803121561336057600080fd5b853561336b81612ea6565b9450602086013593506040860135925060608601356001600160401b0381111561339457600080fd5b6133a0888289016131ef565b969995985093965092949392505050565b803560ff81168114611a1057600080fd5b600080600080600060a086880312156133da57600080fd5b85356133e581612ea6565b94506133f3602087016133b1565b9350613401604087016133b1565b92506060860135915060808601356001600160401b0381111561342357600080fd5b61342f88828901613121565b9150509295509295909350565b6000806040838503121561344f57600080fd5b823561345a81612ea6565b9150612efe6020840161331d565b60008060008060006080868803121561348057600080fd5b853561348b81612ea6565b9450602086013561349b81612ea6565b93506040860135925060608601356001600160401b03808211156134be57600080fd5b818801915088601f8301126134d257600080fd5b8135818111156134e157600080fd5b8960208285010111156134f357600080fd5b9699959850939650602001949392505050565b6000806040838503121561351957600080fd5b823561352481612ea6565b9150602083013561353481612ea6565b809150509250929050565b600181811c9082168061355357607f821691505b602082108103612fc157634e487b7160e01b600052602260045260246000fd5b60006020828403121561358557600080fd5b81356001600160401b038116811461228457600080fd5b6000602082840312156135ae57600080fd5b813563ffffffff8116811461228457600080fd5b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156135f2576135f26135c2565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261361c5761361c6135f7565b500490565b601f82111561178457600081815260208120601f850160051c810160208610156136485750805b601f850160051c820191505b8181101561366757828155600101613654565b505050505050565b81516001600160401b0381111561368857613688613047565b61369c81613696845461353f565b84613621565b602080601f8311600181146136d157600084156136b95750858301515b600019600386901b1c1916600185901b178555613667565b600085815260208120601f198616915b82811015613700578886015182559484019460019091019084016136e1565b508582101561371e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561375657600080fd5b815161228481612ea6565b600060018201613773576137736135c2565b5060010190565b6000821982111561378d5761378d6135c2565b500190565b6000602082840312156137a457600080fd5b815161228481612e73565b60208082526023908201527f4e6f7420612076616c6964206c65616620696e20746865204d65726b6c65207460408201526272656560e81b606082015260800190565b600060ff821660ff84168082101561380c5761380c6135c2565b90039392505050565b60006001600160801b0383811690831681811015613835576138356135c2565b039392505050565b60008282101561384f5761384f6135c2565b500390565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b60008084546138b68161353f565b600182811680156138ce57600181146138e357613912565b60ff1984168752821515830287019450613912565b8860005260208060002060005b858110156139095781548a8201529084019082016138f0565b50505082870194505b505050508351613926818360208801612f07565b01949350505050565b60006001600160801b0380831681851681830481118215151615613955576139556135c2565b02949350505050565b6020808252602a908201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646040820152692073616c65507269636560b01b606082015260800190565b6000826139b7576139b76135f7565b50069056fea2646970667358221220bfd511e5f783d0ed97ae0564829d1a6a67dc8f6e1974f38b7dea43c25636067a64736f6c634300080f00330000000000000000000000000000000000000000000000000000000000001b1f000000000000000000000000000000000000000000000000000000000000245d

Deployed Bytecode

0x6080604052600436106103c35760003560e01c80638a88b8b3116101f2578063b77dc4871161010d578063d79a8ab1116100a0578063ecde3c891161006f578063ecde3c8914610c77578063f1085dfb14610c97578063f8cce6c014610cad578063ff02c51714610cc057600080fd5b8063d79a8ab114610be6578063db5eb70214610c06578063e985e9c514610c26578063ec3ccec214610c6157600080fd5b8063cff0ab96116100dc578063cff0ab9614610af3578063d076503014610b81578063d299c49b14610bb1578063d547cfb714610bd157600080fd5b8063b77dc48714610a87578063b88d4fde14610a9d578063bb0fdd8d14610abd578063c87b56dd14610ad357600080fd5b8063a1876cc411610185578063a90af91211610154578063a90af91214610a1d578063aa1b103f14610a32578063b0f7676714610a47578063b113c60814610a6757600080fd5b8063a1876cc4146109aa578063a22cb465146109bd578063a537f74d146109dd578063a5da2e60146109f257600080fd5b806396062e1f116101c157806396062e1f1461090f57806396473b061461092f5780639d5e2a24146109635780639e55dcb61461097657600080fd5b80638a88b8b3146108925780638da5cb5b146108c25780638fab5047146108e057806395d89b41146108fa57600080fd5b8063484b973c116102e257806363c97d63116102755780636f8b4a72116102445780636f8b4a72146107d157806370a08231146108325780637fb3165a146108525780638a616bc01461087257600080fd5b806363c97d631461075b578063659cdef61461077b578063693d0df21461079b5780636f26d648146107bb57600080fd5b80635ad388d4116102b15780635ad388d41461069b5780635c49d2cb146106ba5780635ecc1566146106da5780636352211e1461073b57600080fd5b8063484b973c146106255780634ab165541461064557806351312f2f146106655780635944c7531461067b57600080fd5b80632525b3d71161035a5780633423e548116103295780633423e548146105b257806335137cd0146105d257806338935c1c146105f257806342842e0e1461060557600080fd5b80632525b3d7146105135780632a55205a146105335780632ab545b51461057257806330176e131461059257600080fd5b8063095ea7b311610396578063095ea7b31461048f57806318160ddd146104af5780631b8cae7b146104d357806323b872dd146104f357600080fd5b806301ffc9a7146103c857806304634d8d146103fd57806306fdde031461041f578063081812fc14610441575b600080fd5b3480156103d457600080fd5b506103e86103e3366004612e89565b610ce8565b60405190151581526020015b60405180910390f35b34801561040957600080fd5b5061041d610418366004612ed2565b610d55565b005b34801561042b57600080fd5b50610434610d8e565b6040516103f49190612f37565b34801561044d57600080fd5b5061047761045c366004612f6a565b6004602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016103f4565b34801561049b57600080fd5b5061041d6104aa366004612f83565b610e1c565b3480156104bb57600080fd5b506104c560155481565b6040519081526020016103f4565b3480156104df57600080fd5b5061041d6104ee366004612faf565b610f03565b3480156104ff57600080fd5b5061041d61050e366004612fc7565b61111c565b34801561051f57600080fd5b5061041d61052e366004613008565b6112e3565b34801561053f57600080fd5b5061055361054e366004613025565b611330565b604080516001600160a01b0390931683526020830191909152016103f4565b34801561057e57600080fd5b5061041d61058d366004612f6a565b6113de565b34801561059e57600080fd5b5061041d6105ad36600461308d565b61140e565b3480156105be57600080fd5b506103e86105cd3660046131a0565b611445565b3480156105de57600080fd5b5061041d6105ed366004613008565b61145a565b61041d610600366004613233565b6114a7565b34801561061157600080fd5b5061041d610620366004612fc7565b611691565b34801561063157600080fd5b5061041d610640366004612f83565b611789565b34801561065157600080fd5b5061041d610660366004613274565b611835565b34801561067157600080fd5b506104c5600d5481565b34801561068757600080fd5b5061041d6106963660046132df565b611988565b3480156106a757600080fd5b50600f546103e890610100900460ff1681565b3480156106c657600080fd5b50600954610477906001600160a01b031681565b3480156106e657600080fd5b5061071b6106f5366004613008565b6017602052600090815260409020546001600160801b0380821691600160801b90041682565b604080516001600160801b039384168152929091166020830152016103f4565b34801561074757600080fd5b50610477610756366004612f6a565b6119be565b34801561076757600080fd5b5061041d61077636600461332d565b611a15565b34801561078757600080fd5b5061041d61079636600461332d565b611a5a565b3480156107a757600080fd5b5061041d6107b6366004613008565b611a98565b3480156107c757600080fd5b506104c5600e5481565b3480156107dd57600080fd5b506108136107ec366004613008565b6011602052600090815260409020546001600160801b03811690600160801b900460ff1682565b604080516001600160801b0390931683529015156020830152016103f4565b34801561083e57600080fd5b506104c561084d366004613008565b611be7565b34801561085e57600080fd5b5061041d61086d366004612f6a565b611c4a565b34801561087e57600080fd5b5061041d61088d366004612f6a565b611c7a565b34801561089e57600080fd5b506103e86108ad366004612f6a565b60136020526000908152604090205460ff1681565b3480156108ce57600080fd5b50600b546001600160a01b0316610477565b3480156108ec57600080fd5b50600f546103e89060ff1681565b34801561090657600080fd5b50610434611cb9565b34801561091b57600080fd5b5061041d61092a366004612f6a565b611cc6565b34801561093b57600080fd5b506104c57f000000000000000000000000000000000000000000000000000000000000245d81565b61041d610971366004613348565b611cf6565b34801561098257600080fd5b506104c57f0000000000000000000000000000000000000000000000000000000000001b1f81565b61041d6109b83660046133c2565b611f0c565b3480156109c957600080fd5b5061041d6109d836600461343c565b612149565b3480156109e957600080fd5b506104c56121b5565b3480156109fe57600080fd5b50600c5461071b906001600160801b0380821691600160801b90041682565b348015610a2957600080fd5b506104c5600281565b348015610a3e57600080fd5b5061041d61228b565b348015610a5357600080fd5b5061041d610a62366004612f6a565b6122c2565b348015610a7357600080fd5b50600a54610477906001600160a01b031681565b348015610a9357600080fd5b506104c561a8c081565b348015610aa957600080fd5b5061041d610ab8366004613468565b6122f2565b348015610ac957600080fd5b506104c560085481565b348015610adf57600080fd5b50610434610aee366004612f6a565b6123d3565b348015610aff57600080fd5b50601854610b40906001600160401b0380821691600160401b8104821691600160801b8204169063ffffffff600160c01b8204811691600160e01b90041685565b604080516001600160401b0396871681529486166020860152929094169183019190915263ffffffff9081166060830152909116608082015260a0016103f4565b348015610b8d57600080fd5b506103e8610b9c366004612f6a565b60146020526000908152604090205460ff1681565b348015610bbd57600080fd5b5061041d610bcc366004613233565b612407565b348015610bdd57600080fd5b50610434612591565b348015610bf257600080fd5b5061041d610c01366004613233565b61259e565b348015610c1257600080fd5b50600b54610477906001600160a01b031681565b348015610c3257600080fd5b506103e8610c41366004613506565b600560209081526000928352604080842090915290825290205460ff1681565b348015610c6d57600080fd5b506104c560105481565b348015610c8357600080fd5b5061041d610c92366004613008565b612689565b348015610ca357600080fd5b506104c560125481565b61041d610cbb366004612f6a565b6126d6565b348015610ccc57600080fd5b5061047773880644ddf208e471c6f2230d31f9027578fa6fcc81565b600063152a902d60e11b6001600160e01b031983161480610d1957506301ffc9a760e01b6001600160e01b03198316145b80610d3457506380ac58cd60e01b6001600160e01b03198316145b80610d4f5750635b5e139f60e01b6001600160e01b03198316145b92915050565b600b546001600160a01b03163314610d8057604051631f7c4bf360e01b815260040160405180910390fd5b610d8a8282612a12565b5050565b60008054610d9b9061353f565b80601f0160208091040260200160405190810160405280929190818152602001828054610dc79061353f565b8015610e145780601f10610de957610100808354040283529160200191610e14565b820191906000526020600020905b815481529060010190602001808311610df757829003601f168201915b505050505081565b6000818152600260205260409020546001600160a01b031633811480610e6557506001600160a01b038116600090815260056020908152604080832033845290915290205460ff165b610ea75760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b60008281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6009546001600160a01b03163314610f2e57604051631f7c4bf360e01b815260040160405180910390fd5b610f3e6040820160208301613573565b6001600160401b0316610f546020830183613573565b6001600160401b031610158015610f8357506000610f786040830160208401613573565b6001600160401b0316115b8015610fa457506000610f9c608083016060840161359c565b63ffffffff16115b8015610fc557506000610fbd60a083016080840161359c565b63ffffffff16115b610fe2576040516340636ec960e01b815260040160405180910390fd5b6040805160a0810190915280610ffb6020840184613573565b6001600160401b0316815260200182602001602081019061101c9190613573565b6001600160401b0316815260200161103a6060840160408501613573565b6001600160401b03168152602001611058608084016060850161359c565b63ffffffff16815260200161107360a084016080850161359c565b63ffffffff9081169091528151601880546020850151604086015160608701516080909701518616600160e01b026001600160e01b0397909616600160c01b0263ffffffff60c01b196001600160401b03928316600160801b02166bffffffffffffffffffffffff60801b19938316600160401b026fffffffffffffffffffffffffffffffff199095169290961691909117929092171692909217919091179290921617905550565b6000818152600260205260409020546001600160a01b038481169116146111725760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b6044820152606401610e9e565b6001600160a01b0382166111bc5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610e9e565b336001600160a01b03841614806111f657506001600160a01b038316600090815260056020908152604080832033845290915290205460ff165b8061121757506000818152600460205260409020546001600160a01b031633145b6112545760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b6044820152606401610e9e565b6001600160a01b0380841660008181526003602090815260408083208054600019019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600b546001600160a01b0316331461130e57604051631f7c4bf360e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b60008281526007602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046001600160601b03169282019290925282916113a55750604080518082019091526006546001600160a01b0381168252600160a01b90046001600160601b031660208201525b6020810151600090612710906113c4906001600160601b0316876135d8565b6113ce919061360d565b91519350909150505b9250929050565b6009546001600160a01b0316331461140957604051631f7c4bf360e01b815260040160405180910390fd5b600e55565b600a546001600160a01b0316331461143957604051631f7c4bf360e01b815260040160405180910390fd5b6016610d8a828261366f565b6000611452828585612acc565b949350505050565b6009546001600160a01b0316331461148557604051631f7c4bf360e01b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b600f54610100900460ff166114cf5760405163951b974f60e01b815260040160405180910390fd5b6008546114dc90826135d8565b34146115035760405163b0b0ec3560e01b8152336004820152306024820152604401610e9e565b60005b8181101561167257601460008484848181106115245761152461372e565b602090810292909201358352508101919091526040016000205460ff161561155f576040516303a9a53560e61b815260040160405180910390fd5b6001601460008585858181106115775761157761372e565b90506020020135815260200190815260200160002060006101000a81548160ff021916908315150217905550600073880644ddf208e471c6f2230d31f9027578fa6fcc6001600160a01b0316636352211e8585858181106115da576115da61372e565b905060200201356040518263ffffffff1660e01b81526004016115ff91815260200190565b602060405180830381865afa15801561161c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116409190613744565b600e8054919250611661918391600061165883613761565b91905055612ae2565b5061166b81613761565b9050611506565b508181905060156000828254611688919061377a565b90915550505050565b61169c83838361111c565b6001600160a01b0382163b15806117455750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401526000608484015290919084169063150b7a029060a4016020604051808303816000875af1158015611715573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117399190613792565b6001600160e01b031916145b6117845760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610e9e565b505050565b6009546001600160a01b031633146117b457604051631f7c4bf360e01b815260040160405180910390fd5b807f0000000000000000000000000000000000000000000000000000000000001b1f1115801561180457507f000000000000000000000000000000000000000000000000000000000000245d8111155b156118225760405163a80cc22160e01b815260040160405180910390fd5b601580546001019055610d8a8282612ae2565b6009546001600160a01b0316331461186057604051631f7c4bf360e01b815260040160405180910390fd5b8281146118805760405163a121188760e01b815260040160405180910390fd5b601580548201905560005b81811015611981578282828181106118a5576118a561372e565b905060200201357f0000000000000000000000000000000000000000000000000000000000001b1f1115801561191357507f000000000000000000000000000000000000000000000000000000000000245d8383838181106119095761190961372e565b9050602002013511155b156119315760405163a80cc22160e01b815260040160405180910390fd5b6119798585838181106119465761194661372e565b905060200201602081019061195b9190613008565b84848481811061196d5761196d61372e565b90506020020135612ae2565b60010161188b565b5050505050565b600b546001600160a01b031633146119b357604051631f7c4bf360e01b815260040160405180910390fd5b611784838383612bed565b6000818152600260205260409020546001600160a01b031680611a105760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b6044820152606401610e9e565b919050565b6009546001600160a01b03163314611a4057604051631f7c4bf360e01b815260040160405180910390fd5b600f80549115156101000261ff0019909216919091179055565b6009546001600160a01b03163314611a8557604051631f7c4bf360e01b815260040160405180910390fd5b600f805460ff1916911515919091179055565b6009546001600160a01b0316331480611abb5750600a546001600160a01b031633145b80611ad05750600b546001600160a01b031633145b611aed57604051631f7c4bf360e01b815260040160405180910390fd5b600c546001600160801b031615801590611b265750600c54611b229061a8c090600160801b90046001600160801b031661377a565b4210155b611b6257600c54604051634433b4ab60e11b81526001600160801b038083166004830152600160801b9092049091166024820152604401610e9e565b6000816001600160a01b03164760405160006040518083038185875af1925050503d8060008114611baf576040519150601f19603f3d011682016040523d82523d6000602084013e611bb4565b606091505b5050905080610d8a5760405163b0b0ec3560e01b81523060048201526001600160a01b0383166024820152604401610e9e565b60006001600160a01b038216611c2e5760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b6044820152606401610e9e565b506001600160a01b031660009081526003602052604090205490565b6009546001600160a01b03163314611c7557604051631f7c4bf360e01b815260040160405180910390fd5b601255565b600b546001600160a01b03163314611ca557604051631f7c4bf360e01b815260040160405180910390fd5b600090815260076020526040812055565b50565b60018054610d9b9061353f565b6009546001600160a01b03163314611cf157604051631f7c4bf360e01b815260040160405180910390fd5b600855565b6008543414611d205760405163b0b0ec3560e01b8152336004820152306024820152604401610e9e565b6040516bffffffffffffffffffffffff19606087901b1660208201526034810185905260009060540160408051601f1981840301815291815281516020928301206000818152601390935291205490915060ff1615611d92576040516303a9a53560e61b815260040160405180910390fd5b838114611df75760405162461bcd60e51b815260206004820152602d60248201527f546f6b656e20636f6e747261637420616e6420696420646f6e2774206d61746360448201526c341026b2b935b632903632b0b360991b6064820152608401610e9e565b611e376012548585858080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061144592505050565b611e535760405162461bcd60e51b8152600401610e9e906137af565b6040516331a9108f60e11b8152600481018690526000906001600160a01b03881690636352211e90602401602060405180830381865afa158015611e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ebf9190613744565b6000838152601360205260408120805460ff191660011790556015805492935091611ee990613761565b90915550600e8054611f0391839190600061165883613761565b50505050505050565b600854611f1c9060ff86166135d8565b3414611f435760405163b0b0ec3560e01b8152336004820152306024820152604401610e9e565b6001600160a01b0385166000908152601160209081526040918290208251808401909352546001600160801b0381168352600160801b900460ff161515908201819052612086576040516bffffffffffffffffffffffff19606088901b1660208201526001600160f81b031960f886901b166034820152839060350160405160208183030381529060405280519060200120146120345760405162461bcd60e51b815260206004820152602960248201527f53656e64657220616e6420616d6f756e7420646f6e2774206d61746368204d656044820152683935b632903632b0b360b91b6064820152608401610e9e565b6120416010548484611445565b61205d5760405162461bcd60e51b8152600401610e9e906137af565b6001602082015260ff858116908516146120815761207b85856137f2565b60ff1681525b6120a8565b8460ff168160000181815161209b9190613815565b6001600160801b03169052505b6001600160a01b0386166000908152601160209081526040822083518154928501511515600160801b0270ffffffffffffffffffffffffffffffffff199093166001600160801b03909116179190911790556015805460ff8816929061210f90849061377a565b90915550600090505b8560ff16811015611f0357600e805461213991899190600061165883613761565b61214281613761565b9050612118565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6040805160a0810182526018546001600160401b038082168352600160401b820481166020840152600160801b8204169282019290925263ffffffff600160c01b8304811660608301819052600160e01b9093041660808201819052600092839190612221904261383d565b61222b919061360d565b9050600082604001516001600160401b03168261224891906135d8565b835161225d91906001600160401b031661383d565b905082602001516001600160401b0316811015612284575060208201516001600160401b03165b9392505050565b600b546001600160a01b031633146122b657604051631f7c4bf360e01b815260040160405180910390fd5b6122c06000600655565b565b6009546001600160a01b031633146122ed57604051631f7c4bf360e01b815260040160405180910390fd5b601055565b6122fd85858561111c565b6001600160a01b0384163b15806123945750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906123459033908a90899089908990600401613854565b6020604051808303816000875af1158015612364573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123889190613792565b6001600160e01b031916145b6119815760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b6044820152606401610e9e565b606060166123e083612cb8565b6040516020016123f19291906138a8565b6040516020818303038152906040529050919050565b600c546001600160801b0316600003612433576040516318e998a560e01b815260040160405180910390fd5b60005b818110156117845760008383838181106124525761245261372e565b90506020020160208101906124679190613008565b6001600160a01b0381166000908152601760209081526040918290208251808401909352546001600160801b038082168452600160801b90910416908201819052919250901561257e57600c5460208201516000916124d1916001600160801b0390911690613815565b82516124dd919061392f565b6001600160a01b038416600081815260176020526040808220829055516001600160801b039390931693509183908381818185875af1925050503d8060008114612543576040519150601f19603f3d011682016040523d82523d6000602084013e612548565b606091505b505090508061257b5760405163b0b0ec3560e01b81523060048201526001600160a01b0385166024820152604401610e9e565b50505b50508061258a90613761565b9050612436565b60168054610d9b9061353f565b600f5460ff166125c15760405163951b974f60e01b815260040160405180910390fd5b60005b8181101561167257600073880644ddf208e471c6f2230d31f9027578fa6fcc636352211e8585858181106125fa576125fa61372e565b905060200201356040518263ffffffff1660e01b815260040161261f91815260200190565b602060405180830381865afa15801561263c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126609190613744565b90506126788185858581811061196d5761196d61372e565b5061268281613761565b90506125c4565b600a546001600160a01b031633146126b457604051631f7c4bf360e01b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6126df33612db8565b806000036127005760405163220328c760e11b815260040160405180910390fd5b336000908152601760209081526040918290208251808401909352546001600160801b03808216808552600160801b909204169183019190915260029061274890849061377a565b111561276757604051630c599a5960e31b815260040160405180910390fd5b600d546127957f000000000000000000000000000000000000000000000000000000000000245d600161377a565b61279f848361377a565b11156127be5760405163bdec14e360e01b815260040160405180910390fd5b6040805160a0810182526018546001600160401b038082168352600160401b820481166020840152600160801b8204169282019290925263ffffffff600160c01b8304811660608301819052600160e01b9093041660808201529042108061282e575080516001600160401b0316155b1561284c5760405163951b974f60e01b815260040160405180910390fd5b6000816080015163ffffffff16826060015163ffffffff164261286f919061383d565b612879919061360d565b9050600082604001516001600160401b03168261289691906135d8565b83516128ab91906001600160401b031661383d565b905082602001516001600160401b03168110156128d2575060208201516001600160401b03165b6128dc81876135d8565b34146129035760405163b0b0ec3560e01b8152336004820152306024820152604401610e9e565b845160208601516000916001600160801b038082168a01811692909102848a02011681612932576129326135f7565b60408051808201825289516001600160801b03908c01811682529390920483811660208085019182523360009081526017909152928320935190518516600160801b029416939093179091559091505b878110156129a25761299a3387806001019850612ae2565b600101612982565b5060158054880190557f000000000000000000000000000000000000000000000000000000000000245d851115612a0457604080518082019091526001600160801b03808416808352429091166020909201829052600160801b90910217600c555b505050600d91909155505050565b6127106001600160601b0382161115612a3d5760405162461bcd60e51b8152600401610e9e9061395e565b6001600160a01b038216612a935760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610e9e565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600655565b600082612ad98584612dfa565b14949350505050565b6001600160a01b038216612b2c5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b6044820152606401610e9e565b6000818152600260205260409020546001600160a01b031615612b825760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b6044820152606401610e9e565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6127106001600160601b0382161115612c185760405162461bcd60e51b8152600401610e9e9061395e565b6001600160a01b038216612c6e5760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610e9e565b6040805180820182526001600160a01b0393841681526001600160601b0392831660208083019182526000968752600790529190942093519051909116600160a01b029116179055565b606081600003612cdf5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612d095780612cf381613761565b9150612d029050600a8361360d565b9150612ce3565b6000816001600160401b03811115612d2357612d23613047565b6040519080825280601f01601f191660200182016040528015612d4d576020820181803683370190505b5090505b841561145257612d6260018361383d565b9150612d6f600a866139a8565b612d7a90603061377a565b60f81b818381518110612d8f57612d8f61372e565b60200101906001600160f81b031916908160001a905350612db1600a8661360d565b9450612d51565b3332141580612dd157506000816001600160a01b03163b115b15611cb6576040516393575bef60e01b81526001600160a01b0382166004820152602401610e9e565b600081815b8451811015612e3f57612e2b82868381518110612e1e57612e1e61372e565b6020026020010151612e47565b915080612e3781613761565b915050612dff565b509392505050565b6000818310612e63576000828152602084905260409020612284565b5060009182526020526040902090565b6001600160e01b031981168114611cb657600080fd5b600060208284031215612e9b57600080fd5b813561228481612e73565b6001600160a01b0381168114611cb657600080fd5b80356001600160601b0381168114611a1057600080fd5b60008060408385031215612ee557600080fd5b8235612ef081612ea6565b9150612efe60208401612ebb565b90509250929050565b60005b83811015612f22578181015183820152602001612f0a565b83811115612f31576000848401525b50505050565b6020815260008251806020840152612f56816040850160208701612f07565b601f01601f19169190910160400192915050565b600060208284031215612f7c57600080fd5b5035919050565b60008060408385031215612f9657600080fd5b8235612fa181612ea6565b946020939093013593505050565b600060a08284031215612fc157600080fd5b50919050565b600080600060608486031215612fdc57600080fd5b8335612fe781612ea6565b92506020840135612ff781612ea6565b929592945050506040919091013590565b60006020828403121561301a57600080fd5b813561228481612ea6565b6000806040838503121561303857600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561308557613085613047565b604052919050565b600060208083850312156130a057600080fd5b82356001600160401b03808211156130b757600080fd5b818501915085601f8301126130cb57600080fd5b8135818111156130dd576130dd613047565b6130ef601f8201601f1916850161305d565b9150808252868482850101111561310557600080fd5b8084840185840137600090820190930192909252509392505050565b600082601f83011261313257600080fd5b813560206001600160401b0382111561314d5761314d613047565b8160051b61315c82820161305d565b928352848101820192828101908785111561317657600080fd5b83870192505b848310156131955782358252918301919083019061317c565b979650505050505050565b6000806000606084860312156131b557600080fd5b833592506020840135915060408401356001600160401b038111156131d957600080fd5b6131e586828701613121565b9150509250925092565b60008083601f84011261320157600080fd5b5081356001600160401b0381111561321857600080fd5b6020830191508360208260051b85010111156113d757600080fd5b6000806020838503121561324657600080fd5b82356001600160401b0381111561325c57600080fd5b613268858286016131ef565b90969095509350505050565b6000806000806040858703121561328a57600080fd5b84356001600160401b03808211156132a157600080fd5b6132ad888389016131ef565b909650945060208701359150808211156132c657600080fd5b506132d3878288016131ef565b95989497509550505050565b6000806000606084860312156132f457600080fd5b83359250602084013561330681612ea6565b915061331460408501612ebb565b90509250925092565b80358015158114611a1057600080fd5b60006020828403121561333f57600080fd5b6122848261331d565b60008060008060006080868803121561336057600080fd5b853561336b81612ea6565b9450602086013593506040860135925060608601356001600160401b0381111561339457600080fd5b6133a0888289016131ef565b969995985093965092949392505050565b803560ff81168114611a1057600080fd5b600080600080600060a086880312156133da57600080fd5b85356133e581612ea6565b94506133f3602087016133b1565b9350613401604087016133b1565b92506060860135915060808601356001600160401b0381111561342357600080fd5b61342f88828901613121565b9150509295509295909350565b6000806040838503121561344f57600080fd5b823561345a81612ea6565b9150612efe6020840161331d565b60008060008060006080868803121561348057600080fd5b853561348b81612ea6565b9450602086013561349b81612ea6565b93506040860135925060608601356001600160401b03808211156134be57600080fd5b818801915088601f8301126134d257600080fd5b8135818111156134e157600080fd5b8960208285010111156134f357600080fd5b9699959850939650602001949392505050565b6000806040838503121561351957600080fd5b823561352481612ea6565b9150602083013561353481612ea6565b809150509250929050565b600181811c9082168061355357607f821691505b602082108103612fc157634e487b7160e01b600052602260045260246000fd5b60006020828403121561358557600080fd5b81356001600160401b038116811461228457600080fd5b6000602082840312156135ae57600080fd5b813563ffffffff8116811461228457600080fd5b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156135f2576135f26135c2565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261361c5761361c6135f7565b500490565b601f82111561178457600081815260208120601f850160051c810160208610156136485750805b601f850160051c820191505b8181101561366757828155600101613654565b505050505050565b81516001600160401b0381111561368857613688613047565b61369c81613696845461353f565b84613621565b602080601f8311600181146136d157600084156136b95750858301515b600019600386901b1c1916600185901b178555613667565b600085815260208120601f198616915b82811015613700578886015182559484019460019091019084016136e1565b508582101561371e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561375657600080fd5b815161228481612ea6565b600060018201613773576137736135c2565b5060010190565b6000821982111561378d5761378d6135c2565b500190565b6000602082840312156137a457600080fd5b815161228481612e73565b60208082526023908201527f4e6f7420612076616c6964206c65616620696e20746865204d65726b6c65207460408201526272656560e81b606082015260800190565b600060ff821660ff84168082101561380c5761380c6135c2565b90039392505050565b60006001600160801b0383811690831681811015613835576138356135c2565b039392505050565b60008282101561384f5761384f6135c2565b500390565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290526000828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b60008084546138b68161353f565b600182811680156138ce57600181146138e357613912565b60ff1984168752821515830287019450613912565b8860005260208060002060005b858110156139095781548a8201529084019082016138f0565b50505082870194505b505050508351613926818360208801612f07565b01949350505050565b60006001600160801b0380831681851681830481118215151615613955576139556135c2565b02949350505050565b6020808252602a908201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646040820152692073616c65507269636560b01b606082015260800190565b6000826139b7576139b76135f7565b50069056fea2646970667358221220bfd511e5f783d0ed97ae0564829d1a6a67dc8f6e1974f38b7dea43c25636067a64736f6c634300080f0033

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

0000000000000000000000000000000000000000000000000000000000001b1f000000000000000000000000000000000000000000000000000000000000245d

-----Decoded View---------------
Arg [0] : _DUTCH_AUCTION_START_ID (uint256): 6943
Arg [1] : _DUTCH_AUCTION_END_ID (uint256): 9309

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000001b1f
Arg [1] : 000000000000000000000000000000000000000000000000000000000000245d


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.