Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
NFT
Overview
Max Total Supply
14,890 BOOK
Holders
2,236
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 BOOKLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
BoredAndDangerous
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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); } } }
// 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; } }
// 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]; } }
// 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) } } }
// 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); } }
// 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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); }
{ "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
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
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.