ERC-721
NFT
Overview
Max Total Supply
5,000 EGGZ
Holders
730
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
50 EGGZLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
EggzNFT
Compiler Version
v0.8.12+commit.f00d7308
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; //@author Soakverse //@title Eggz by Soakverse import "./Ownable.sol"; import "./Strings.sol"; import "./MerkleProof.sol"; import "./ERC721LockRegistry.sol"; contract EggzNFT is Ownable, ERC721X { using Strings for uint256; enum Step { Before, OGWhitelist, PremiumWhitelist, Whitelist, Public, Soldout } string public baseURI; Step public sellingStep; uint256 private constant MAX_SUPPLY = 5000; uint256 private constant MAX_FREEMINT = 4580; bytes32 public ogMerkleRoot; bytes32 public premiumMerkleRoot; bytes32 public merkleRoot; mapping(address => uint256) public amountNftPerWallet; bool public canStake; mapping(uint256 => uint256) public tokensLastStakedAt; // tokenId => timestamp event Stake(uint256 tokenId, address by, uint256 stakedAt); event Unstake( uint256 tokenId, address by, uint256 stakedAt, uint256 unstakedAt ); constructor( bytes32 _ogMerkleRoot, bytes32 _premiumMerkleRoot, bytes32 _merkleRoot, string memory _baseURI ) ERC721X("Eggz By Soakverse", "EGGZ") { ogMerkleRoot = _ogMerkleRoot; premiumMerkleRoot = _premiumMerkleRoot; merkleRoot = _merkleRoot; baseURI = _baseURI; } modifier callerIsUser() { require(tx.origin == msg.sender, "The caller is another contract"); _; } function ogWhitelistMint(uint256 _quantity, bytes32[] calldata _proof) external callerIsUser { require( sellingStep >= Step.OGWhitelist, "Whitelist sale is not activated" ); require( isOGWhiteListed(msg.sender, _quantity, _proof), "Not OG whitelisted" ); require( amountNftPerWallet[msg.sender] + _quantity <= _quantity, "You reached maximum on OG Whitelist Sale" ); require( totalSupply() + _quantity <= MAX_FREEMINT, "Max freemint supply exceeded" ); amountNftPerWallet[msg.sender] += _quantity; _safeMint(msg.sender, _quantity); } function premiumWhitelistMint(bytes32[] calldata _proof) external callerIsUser { require( sellingStep >= Step.PremiumWhitelist, "Premium Whitelist sale is not activated" ); require( isPremiumWhiteListed(msg.sender, _proof), "Not Premium whitelisted" ); require( amountNftPerWallet[msg.sender] + 2 <= 2, "You can only get 2 NFT on the Premium Whitelist Sale" ); require( totalSupply() + 2 <= MAX_FREEMINT, "Max freemint supply exceeded" ); amountNftPerWallet[msg.sender] += 2; _safeMint(msg.sender, 2); } function whitelistMint(bytes32[] calldata _proof) external callerIsUser { require( sellingStep >= Step.Whitelist, "Whitelist sale is not activated" ); require(isWhiteListed(msg.sender, _proof), "Not whitelisted"); require( amountNftPerWallet[msg.sender] + 1 <= 1, "You can only get 1 NFT on the Whitelist Sale" ); require( totalSupply() + 1 <= MAX_FREEMINT, "Max freemint supply exceeded" ); amountNftPerWallet[msg.sender] += 1; _safeMint(msg.sender, 1); } function mint() external callerIsUser { require(sellingStep >= Step.Public, "Public sale is not activated"); require( amountNftPerWallet[msg.sender] + 1 <= 1, "You can only get 1 NFT on the Public Sale" ); require( totalSupply() + 1 <= MAX_FREEMINT, "Max freemint supply exceeded" ); amountNftPerWallet[msg.sender] += 1; _safeMint(msg.sender, 1); } function giveaway(address _to, uint256 _quantity) external onlyOwner { require(sellingStep > Step.Public, "Giveaway is after the public sale"); require(totalSupply() + _quantity <= MAX_SUPPLY, "Max supply exceeded"); _safeMint(_to, _quantity); } function setStep(uint256 _step) external onlyOwner { sellingStep = Step(_step); } function setBaseUri(string memory _baseURI) external onlyOwner { baseURI = _baseURI; } function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { require(_exists(_tokenId), "URI query for nonexistent token"); return string(abi.encodePacked(baseURI, _tokenId.toString(), ".json")); } // ---- OG Whitelist ---- function setOGMerkleRoot(bytes32 _merkleRoot) external onlyOwner { ogMerkleRoot = _merkleRoot; } function isOGWhiteListed( address _account, uint256 _quantity, bytes32[] calldata _proof ) internal view returns (bool) { bytes32 _leaf = keccak256(abi.encodePacked(_account, _quantity)); return _verify(_leaf, ogMerkleRoot, _proof); } // ---- Premium Whitelist ---- function setPremiumMerkleRoot(bytes32 _merkleRoot) external onlyOwner { premiumMerkleRoot = _merkleRoot; } function isPremiumWhiteListed(address _account, bytes32[] calldata _proof) internal view returns (bool) { bytes32 _leaf = keccak256(abi.encodePacked(_account)); return _verify(_leaf, premiumMerkleRoot, _proof); } // ---- Whitelist ---- function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner { merkleRoot = _merkleRoot; } function isWhiteListed(address _account, bytes32[] calldata _proof) internal view returns (bool) { bytes32 _leaf = keccak256(abi.encodePacked(_account)); return _verify(_leaf, merkleRoot, _proof); } function _verify( bytes32 _leaf, bytes32 _root, bytes32[] memory _proof ) internal pure returns (bool) { return MerkleProof.verify(_proof, _root, _leaf); } // ---- STAKING ---- function transferFrom( address from, address to, uint256 tokenId ) public payable override(ERC721X) { require( tokensLastStakedAt[tokenId] == 0, "Cannot transfer staked token" ); super.transferFrom(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable override(ERC721X) { require( tokensLastStakedAt[tokenId] == 0, "Cannot transfer staked token" ); super.safeTransferFrom(from, to, tokenId, _data); } function stake(uint256 tokenId) public { require(canStake, "staking not open"); require( msg.sender == ownerOf(tokenId) || msg.sender == owner(), "caller must be owner of token or contract owner" ); require(tokensLastStakedAt[tokenId] == 0, "already staking"); tokensLastStakedAt[tokenId] = block.timestamp; emit Stake(tokenId, msg.sender, tokensLastStakedAt[tokenId]); } function unstake(uint256 tokenId) public { require( msg.sender == ownerOf(tokenId) || msg.sender == owner(), "caller must be owner of token or contract owner" ); require(tokensLastStakedAt[tokenId] > 0, "not staking"); uint256 lsa = tokensLastStakedAt[tokenId]; tokensLastStakedAt[tokenId] = 0; emit Unstake(tokenId, msg.sender, block.timestamp, lsa); } function setTokensStakeStatus(uint256[] memory tokenIds, bool setStake) external { for (uint256 i; i < tokenIds.length; i++) { uint256 tokenId = tokenIds[i]; if (setStake) { stake(tokenId); } else { unstake(tokenId); } } } function setCanStake(bool b) external onlyOwner { canStake = b; } function _startTokenId() internal pure override returns (uint256) { return 1; } function withdrawAll() external onlyOwner { uint256 balance = address(this).balance; require(balance > 0, "there is nothing to withdraw"); _withdraw(owner(), address(this).balance); } function _withdraw(address _address, uint256 _amount) private { (bool success, ) = _address.call{value: _amount}(""); require(success, "could not withdraw"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; import "./IERC721A.sol"; /** * @dev Interface of ERC721 token receiver. */ interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @title ERC721A * * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721) * Non-Fungible Token Standard, including the Metadata extension. * Optimized for lower gas during batch mints. * * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...) * starting from `_startTokenId()`. * * Assumptions: * * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364). struct TokenApprovalRef { address value; } // ============================================================= // CONSTANTS // ============================================================= // Mask of an entry in packed address data. uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1; // The bit position of `numberMinted` in packed address data. uint256 private constant _BITPOS_NUMBER_MINTED = 64; // The bit position of `numberBurned` in packed address data. uint256 private constant _BITPOS_NUMBER_BURNED = 128; // The bit position of `aux` in packed address data. uint256 private constant _BITPOS_AUX = 192; // Mask of all 256 bits in packed address data except the 64 bits for `aux`. uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1; // The bit position of `startTimestamp` in packed ownership. uint256 private constant _BITPOS_START_TIMESTAMP = 160; // The bit mask of the `burned` bit in packed ownership. uint256 private constant _BITMASK_BURNED = 1 << 224; // The bit position of the `nextInitialized` bit in packed ownership. uint256 private constant _BITPOS_NEXT_INITIALIZED = 225; // The bit mask of the `nextInitialized` bit in packed ownership. uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225; // The bit position of `extraData` in packed ownership. uint256 private constant _BITPOS_EXTRA_DATA = 232; // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`. uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1; // The mask of the lower 160 bits for addresses. uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; // The maximum `quantity` that can be minted with {_mintERC2309}. // This limit is to prevent overflows on the address data entries. // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309} // is required to cause an overflow, which is unrealistic. uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000; // The `Transfer` event signature is given by: // `keccak256(bytes("Transfer(address,address,uint256)"))`. bytes32 private constant _TRANSFER_EVENT_SIGNATURE = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // ============================================================= // STORAGE // ============================================================= // The next token ID to be minted. uint256 private _currentIndex; // The number of tokens burned. uint256 private _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. // See {_packedOwnershipOf} implementation for details. // // Bits Layout: // - [0..159] `addr` // - [160..223] `startTimestamp` // - [224] `burned` // - [225] `nextInitialized` // - [232..255] `extraData` mapping(uint256 => uint256) private _packedOwnerships; // Mapping owner address to address data. // // Bits Layout: // - [0..63] `balance` // - [64..127] `numberMinted` // - [128..191] `numberBurned` // - [192..255] `aux` mapping(address => uint256) private _packedAddressData; // Mapping from token ID to approved address. mapping(uint256 => TokenApprovalRef) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // ============================================================= // CONSTRUCTOR // ============================================================= constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } // ============================================================= // TOKEN COUNTING OPERATIONS // ============================================================= /** * @dev Returns the starting token ID. * To change the starting token ID, please override this function. */ function _startTokenId() internal view virtual returns (uint256) { return 0; } /** * @dev Returns the next token ID to be minted. */ function _nextTokenId() internal view virtual returns (uint256) { return _currentIndex; } /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() public view virtual override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than `_currentIndex - _startTokenId()` times. unchecked { return _currentIndex - _burnCounter - _startTokenId(); } } /** * @dev Returns the total amount of tokens minted in the contract. */ function _totalMinted() internal view virtual returns (uint256) { // Counter underflow is impossible as `_currentIndex` does not decrement, // and it is initialized to `_startTokenId()`. unchecked { return _currentIndex - _startTokenId(); } } /** * @dev Returns the total number of tokens burned. */ function _totalBurned() internal view virtual returns (uint256) { return _burnCounter; } // ============================================================= // ADDRESS DATA OPERATIONS // ============================================================= /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) public view virtual override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens minted by `owner`. */ function _numberMinted(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the number of tokens burned by or on behalf of `owner`. */ function _numberBurned(address owner) internal view returns (uint256) { return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY; } /** * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). */ function _getAux(address owner) internal view returns (uint64) { return uint64(_packedAddressData[owner] >> _BITPOS_AUX); } /** * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used). * If there are multiple variables, please pack them into a uint64. */ function _setAux(address owner, uint64 aux) internal virtual { uint256 packed = _packedAddressData[owner]; uint256 auxCasted; // Cast `aux` with assembly to avoid redundant masking. assembly { auxCasted := aux } packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX); _packedAddressData[owner] = packed; } // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { // The interface IDs are constants representing the first 4 bytes // of the XOR of all function selectors in the interface. // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165) // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`) return interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165. interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721. interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata. } // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the token collection symbol. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, it can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } // ============================================================= // OWNERSHIPS OPERATIONS // ============================================================= /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around over time. */ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @dev Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal virtual { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Returns the packed ownership data of `tokenId`. */ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) { uint256 curr = tokenId; unchecked { if (_startTokenId() <= curr) if (curr < _currentIndex) { uint256 packed = _packedOwnerships[curr]; // If not burned. if (packed & _BITMASK_BURNED == 0) { // Invariant: // There will always be an initialized ownership slot // (i.e. `ownership.addr != address(0) && ownership.burned == false`) // before an unintialized ownership slot // (i.e. `ownership.addr == address(0) && ownership.burned == false`) // Hence, `curr` will not underflow. // // We can directly compare the packed value. // If the address is zero, packed will be zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * @dev Returns the unpacked `TokenOwnership` struct from `packed`. */ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) { ownership.addr = address(uint160(packed)); ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP); ownership.burned = packed & _BITMASK_BURNED != 0; ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA); } /** * @dev Packs ownership data into a single uint256. */ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`. result := or( owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags) ) } } /** * @dev Returns the `nextInitialized` flag set if `quantity` equals 1. */ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) { // For branchless setting of the `nextInitialized` flag. assembly { // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`. result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1)) } } // ============================================================= // APPROVAL OPERATIONS // ============================================================= /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) public payable virtual override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId].value = to; emit Approval(owner, to, tokenId); } /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId].value; } /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) public virtual override { _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted. See {_mint}. */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned. } /** * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`. */ function _isSenderApprovedOrOwner( address approvedAddress, address owner, address msgSender ) private pure returns (bool result) { assembly { // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean. owner := and(owner, _BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, _BITMASK_ADDRESS) // `msgSender == owner || msgSender == approvedAddress`. result := or(eq(msgSender, owner), eq(msgSender, approvedAddress)) } } /** * @dev Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedSlotAndAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId]; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`. assembly { approvedAddressSlot := tokenApproval.slot approvedAddress := sload(approvedAddressSlot) } } // ============================================================= // TRANSFER OPERATIONS // ============================================================= /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public payable virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); ( uint256 approvedAddressSlot, address approvedAddress ) = _getApprovedSlotAndAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if ( !_isSenderApprovedOrOwner( approvedAddress, from, _msgSenderERC721A() ) ) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // We can directly increment and decrement the balances. --_packedAddressData[from]; // Updates: `balance -= 1`. ++_packedAddressData[to]; // Updates: `balance += 1`. // Updates: // - `address` to the next owner. // - `startTimestamp` to the timestamp of transfering. // - `burned` to `false`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( to, _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public payable virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public payable virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @dev Hook that is called before a set of serially-ordered token IDs * are about to be transferred. This includes minting. * And also called before burning one token. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token IDs * have been transferred. This includes minting. * And also called after one token has been burned. * * `startTokenId` - the first token ID to be transferred. * `quantity` - the amount to be transferred. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * `from` - Previous owner of the given token ID. * `to` - Target address that will receive the token. * `tokenId` - Token ID to be transferred. * `_data` - Optional data to send along with the call. * * Returns whether the call correctly returned the expected magic value. */ function _checkContractOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { try ERC721A__IERC721Receiver(to).onERC721Received( _msgSenderERC721A(), from, tokenId, _data ) returns (bytes4 retval) { return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } // ============================================================= // MINT OPERATIONS // ============================================================= /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event for each mint. */ function _mint(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // `balance` and `numberMinted` have a maximum limit of 2**64. // `tokenId` has a maximum limit of 2**256. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); uint256 toMasked; uint256 end = startTokenId + quantity; // Use assembly to loop and emit the `Transfer` event for gas savings. // The duplicated `log4` removes an extra check and reduces stack juggling. // The assembly, together with the surrounding Solidity code, have been // delicately arranged to nudge the compiler into producing optimized opcodes. assembly { // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean. toMasked := and(to, _BITMASK_ADDRESS) // Emit the `Transfer` event. log4( 0, // Start of data (0, since no data). 0, // End of data (0, since no data). _TRANSFER_EVENT_SIGNATURE, // Signature. 0, // `address(0)`. toMasked, // `to`. startTokenId // `tokenId`. ) // The `iszero(eq(,))` check ensures that large values of `quantity` // that overflows uint256 will make the loop run out of gas. // The compiler will optimize the `iszero` away for performance. for { let tokenId := add(startTokenId, 1) } iszero(eq(tokenId, end)) { tokenId := add(tokenId, 1) } { // Emit the `Transfer` event. Similar to above. log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId) } } if (toMasked == 0) revert MintToZeroAddress(); _currentIndex = end; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * This function is intended for efficient minting only during contract creation. * * It emits only one {ConsecutiveTransfer} as defined in * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309), * instead of a sequence of {Transfer} event(s). * * Calling this function outside of contract creation WILL make your contract * non-compliant with the ERC721 standard. * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309 * {ConsecutiveTransfer} event is only permissible during contract creation. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {ConsecutiveTransfer} event. */ function _mintERC2309(address to, uint256 quantity) internal virtual { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are unrealistic due to the above check for `quantity` to be below the limit. unchecked { // Updates: // - `balance += quantity`. // - `numberMinted += quantity`. // // We can directly add to the `balance` and `numberMinted`. _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1); // Updates: // - `address` to the owner. // - `startTimestamp` to the timestamp of minting. // - `burned` to `false`. // - `nextInitialized` to `quantity == 1`. _packedOwnerships[startTokenId] = _packOwnershipData( to, _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0) ); emit ConsecutiveTransfer( startTokenId, startTokenId + quantity - 1, address(0), to ); _currentIndex = startTokenId + quantity; } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * See {_mint}. * * Emits a {Transfer} event for each mint. */ function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { _mint(to, quantity); unchecked { if (to.code.length != 0) { uint256 end = _currentIndex; uint256 index = end - quantity; do { if ( !_checkContractOnERC721Received( address(0), to, index++, _data ) ) { revert TransferToNonERC721ReceiverImplementer(); } } while (index < end); // Reentrancy protection. if (_currentIndex != end) revert(); } } } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ""); } // ============================================================= // BURN OPERATIONS // ============================================================= /** * @dev Equivalent to `_burn(tokenId, false)`. */ function _burn(uint256 tokenId) internal virtual { _burn(tokenId, false); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId, bool approvalCheck) internal virtual { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); address from = address(uint160(prevOwnershipPacked)); ( uint256 approvedAddressSlot, address approvedAddress ) = _getApprovedSlotAndAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if ( !_isSenderApprovedOrOwner( approvedAddress, from, _msgSenderERC721A() ) ) if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved(); } _beforeTokenTransfers(from, address(0), tokenId, 1); // Clear approvals from the previous owner. assembly { if approvedAddress { // This is equivalent to `delete _tokenApprovals[tokenId]`. sstore(approvedAddressSlot, 0) } } // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256. unchecked { // Updates: // - `balance -= 1`. // - `numberBurned += 1`. // // We can directly decrement the balance, and increment the number burned. // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`. _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1; // Updates: // - `address` to the last owner. // - `startTimestamp` to the timestamp of burning. // - `burned` to `true`. // - `nextInitialized` to `true`. _packedOwnerships[tokenId] = _packOwnershipData( from, (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked) ); // If the next slot may not have been initialized (i.e. `nextInitialized == false`) . if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) { uint256 nextTokenId = tokenId + 1; // If the next slot's address is zero and not burned (i.e. packed value is zero). if (_packedOwnerships[nextTokenId] == 0) { // If the next slot is within bounds. if (nextTokenId != _currentIndex) { // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`. _packedOwnerships[nextTokenId] = prevOwnershipPacked; } } } } emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } // ============================================================= // EXTRA DATA OPERATIONS // ============================================================= /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual { uint256 packed = _packedOwnerships[index]; if (packed == 0) revert OwnershipNotInitializedForExtraData(); uint256 extraDataCasted; // Cast `extraData` with assembly to avoid redundant masking. assembly { extraDataCasted := extraData } packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA); _packedOwnerships[index] = packed; } /** * @dev Called during each token transfer to set the 24bit `extraData` field. * Intended to be overridden by the cosumer contract. * * `previousExtraData` - the value of `extraData` before transfer. * * Calling conditions: * * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ function _extraData( address from, address to, uint24 previousExtraData ) internal view virtual returns (uint24) {} /** * @dev Returns the next extra data for the packed ownership data. * The returned result is shifted into position. */ function _nextExtraData( address from, address to, uint256 prevOwnershipPacked ) private view returns (uint256) { uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA); return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA; } // ============================================================= // OTHER OPERATIONS // ============================================================= /** * @dev Returns the message sender (defaults to `msg.sender`). * * If you are writing GSN compatible contracts, you need to override this function. */ function _msgSenderERC721A() internal view virtual returns (address) { return msg.sender; } /** * @dev Converts a uint256 to its ASCII string decimal representation. */ function _toString(uint256 value) internal pure virtual returns (string memory str) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), but // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned. // We will need 1 word for the trailing zeros padding, 1 word for the length, // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0. let m := add(mload(0x40), 0xa0) // Update the free memory pointer to allocate. mstore(0x40, m) // Assign the `str` to the end. str := sub(m, 0x20) // Zeroize the slot after the string. mstore(str, 0) // Cache the end of the memory to calculate the length later. let end := str // We write the string from rightmost digit to leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // prettier-ignore for { let temp := value } 1 {} { str := sub(str, 1) // Write the character to the pointer. // The ASCII index of the '0' character is 48. mstore8(str, add(48, mod(temp, 10))) // Keep dividing `temp` until zero. temp := div(temp, 10) // prettier-ignore if iszero(temp) { break } } let length := sub(end, str) // Move the pointer 32 bytes leftwards to make room for the length. str := sub(str, 0x20) // Store the length. mstore(str, length) } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.2; /* * ,_, * (',') * {/"\} * -"-"- */ import "./ERC721A.sol"; import "./LockRegistry.sol"; contract ERC721X is LockRegistry, ERC721A { /* * bytes4(keccak256('freeId(uint256,address)')) == 0x94d216d6 * bytes4(keccak256('isUnlocked(uint256)')) == 0x72abc8b7 * bytes4(keccak256('lockCount(uint256)')) == 0x650b00f6 * bytes4(keccak256('lockId(uint256)')) == 0x2799cde0 * bytes4(keccak256('lockMap(uint256,uint256)')) == 0x2cba8123 * bytes4(keccak256('lockMapIndex(uint256,address)')) == 0x09308e5d * bytes4(keccak256('unlockId(uint256)')) == 0x40a9c8df * bytes4(keccak256('approvedContract(address)')) == 0xb1a6505f * * => 0x94d216d6 ^ 0x72abc8b7 ^ 0x650b00f6 ^ 0x2799cde0 ^ * 0x2cba8123 ^ 0x09308e5d ^ 0x40a9c8df ^ 0xb1a6505f == 0x706e8489 */ bytes4 private constant _INTERFACE_ID_ERC721x = 0x706e8489; constructor(string memory _name, string memory _symbol) ERC721A(_name, _symbol) {} function supportsInterface(bytes4 _interfaceId) public view virtual override(ERC721A) returns (bool) { return _interfaceId == _INTERFACE_ID_ERC721x || super.supportsInterface(_interfaceId); } function transferFrom( address _from, address _to, uint256 _tokenId ) public payable virtual override { require(isUnlocked(_tokenId), "Token is locked"); ERC721A.transferFrom(_from, _to, _tokenId); } function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes memory _data ) public payable virtual override { require(isUnlocked(_tokenId), "Token is locked"); ERC721A.safeTransferFrom(_from, _to, _tokenId, _data); } function lockId(uint256 _id) external virtual override { require(_exists(_id), "Token !exist"); _lockId(_id); } function unlockId(uint256 _id) external virtual override { require(_exists(_id), "Token !exist"); _unlockId(_id); } function freeId(uint256 _id, address _contract) external virtual override { require(_exists(_id), "Token !exist"); _freeId(_id, _contract); } }
// SPDX-License-Identifier: MIT // ERC721A Contracts v4.2.3 // Creator: Chiru Labs pragma solidity ^0.8.4; /** * @dev Interface of ERC721A. */ interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * Cannot query the balance for the zero address. */ error BalanceQueryForZeroAddress(); /** * Cannot mint to the zero address. */ error MintToZeroAddress(); /** * The quantity of tokens minted must be more than zero. */ error MintZeroQuantity(); /** * The token does not exist. */ error OwnerQueryForNonexistentToken(); /** * The caller must own the token or be an approved operator. */ error TransferCallerNotOwnerNorApproved(); /** * The token must be owned by `from`. */ error TransferFromIncorrectOwner(); /** * Cannot safely transfer to a contract that does not implement the * ERC721Receiver interface. */ error TransferToNonERC721ReceiverImplementer(); /** * Cannot transfer to the zero address. */ error TransferToZeroAddress(); /** * The token does not exist. */ error URIQueryForNonexistentToken(); /** * The `quantity` minted with ERC2309 exceeds the safety limit. */ error MintERC2309QuantityExceedsLimit(); /** * The `extraData` cannot be set on an unintialized ownership slot. */ error OwnershipNotInitializedForExtraData(); // ============================================================= // STRUCTS // ============================================================= struct TokenOwnership { // The address of the owner. address addr; // Stores the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}. uint24 extraData; } // ============================================================= // TOKEN COUNTERS // ============================================================= /** * @dev Returns the total number of tokens in existence. * Burned tokens will reduce the count. * To get the total number of tokens minted, please see {_totalMinted}. */ function totalSupply() external view returns (uint256); // ============================================================= // IERC165 // ============================================================= /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) * to learn more about how these ids are created. * * This function call must use less than 30000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================================================= // IERC721 // ============================================================= /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval( address indexed owner, address indexed approved, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables or disables * (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); /** * @dev Returns the number of tokens in `owner`'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, * checking first that contract recipients are aware of the ERC721 protocol * to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move * this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external payable; /** * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Transfers `tokenId` from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} * whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token * by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external payable; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the * zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external payable; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} * for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll}. */ function isApprovedForAll(address owner, address operator) external view returns (bool); // ============================================================= // IERC721Metadata // ============================================================= /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); // ============================================================= // IERC2309 // ============================================================= /** * @dev Emitted when tokens in `fromTokenId` to `toTokenId` * (inclusive) is transferred from `from` to `to`, as defined in the * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard. * * See {_mintERC2309} for more details. */ event ConsecutiveTransfer( uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to ); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.2; interface IERC721X { /** * @dev Returns if the token is locked (non-transferrable) or not. */ function isUnlocked(uint256 _id) external view returns (bool); /** * @dev Returns the amount of locks on the token. */ function lockCount(uint256 _tokenId) external view returns (uint256); /** * @dev Returns if a contract is allowed to lock/unlock tokens. */ function approvedContract(address _contract) external view returns (bool); /** * @dev Returns the contract that locked a token at a specific index in the mapping. */ function lockMap(uint256 _tokenId, uint256 _index) external view returns (address); /** * @dev Returns the mapping index of a contract that locked a token. */ function lockMapIndex(uint256 _tokenId, address _contract) external view returns (uint256); /** * @dev Locks a token, preventing it from being transferrable */ function lockId(uint256 _id) external; /** * @dev Unlocks a token. */ function unlockId(uint256 _id) external; /** * @dev Unlocks a token from a given contract if the contract is no longer approved. */ function freeId(uint256 _id, address _contract) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.2; /* * ,_, * (',') * {/"\} * -"-"- */ import "./Ownable.sol"; import "./IERC721X.sol"; abstract contract LockRegistry is Ownable, IERC721X { mapping(address => bool) public override approvedContract; mapping(uint256 => uint256) public override lockCount; mapping(uint256 => mapping(uint256 => address)) public override lockMap; mapping(uint256 => mapping(address => uint256)) public override lockMapIndex; event TokenLocked( uint256 indexed tokenId, address indexed approvedContract ); event TokenUnlocked( uint256 indexed tokenId, address indexed approvedContract ); function isUnlocked(uint256 _id) public view override returns (bool) { return lockCount[_id] == 0; } function updateApprovedContracts( address[] calldata _contracts, bool[] calldata _values ) external onlyOwner { require(_contracts.length == _values.length, "!length"); for (uint256 i = 0; i < _contracts.length; i++) approvedContract[_contracts[i]] = _values[i]; } function _lockId(uint256 _id) internal { require(approvedContract[msg.sender], "Cannot update map"); require( lockMapIndex[_id][msg.sender] == 0, "ID already locked by caller" ); uint256 count = lockCount[_id] + 1; lockMap[_id][count] = msg.sender; lockMapIndex[_id][msg.sender] = count; lockCount[_id]++; emit TokenLocked(_id, msg.sender); } function _unlockId(uint256 _id) internal { require(approvedContract[msg.sender], "Cannot update map"); uint256 index = lockMapIndex[_id][msg.sender]; require(index != 0, "ID not locked by caller"); uint256 last = lockCount[_id]; if (index != last) { address lastContract = lockMap[_id][last]; lockMap[_id][index] = lastContract; lockMap[_id][last] = address(0); lockMapIndex[_id][lastContract] = index; } else lockMap[_id][index] = address(0); lockMapIndex[_id][msg.sender] = 0; lockCount[_id]--; emit TokenUnlocked(_id, msg.sender); } function _freeId(uint256 _id, address _contract) internal { require(!approvedContract[_contract], "Cannot update map"); uint256 index = lockMapIndex[_id][_contract]; require(index != 0, "ID not locked"); uint256 last = lockCount[_id]; if (index != last) { address lastContract = lockMap[_id][last]; lockMap[_id][index] = lastContract; lockMap[_id][last] = address(0); lockMapIndex[_id][lastContract] = index; } else lockMap[_id][index] = address(0); lockMapIndex[_id][_contract] = 0; lockCount[_id]--; emit TokenUnlocked(_id, _contract); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (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 simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _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} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _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 sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _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}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _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) (access/Ownable.sol) pragma solidity ^0.8.0; import "./Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require( newOwner != address(0), "Ownable: new owner is the zero address" ); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"bytes32","name":"_ogMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"_premiumMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"string","name":"_baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAt","type":"uint256"}],"name":"Stake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenUnlocked","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":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unstakedAt","type":"uint256"}],"name":"Unstake","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountNftPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvedContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canStake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_contract","type":"address"}],"name":"freeId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"giveaway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"isUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"lockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockMap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"lockMapIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ogMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"ogWhitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"premiumMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"premiumWhitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sellingStep","outputs":[{"internalType":"enum EggzNFT.Step","name":"","type":"uint8"}],"stateMutability":"view","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":"_baseURI","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"b","type":"bool"}],"name":"setCanStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setOGMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setPremiumMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_step","type":"uint256"}],"name":"setStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bool","name":"setStake","type":"bool"}],"name":"setTokensStakeStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"stake","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":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokensLastStakedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"unlockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_contracts","type":"address[]"},{"internalType":"bool[]","name":"_values","type":"bool[]"}],"name":"updateApprovedContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003c0438038062003c0483398101604081905262000034916200020b565b604051806040016040528060118152602001704567677a20427920536f616b766572736560781b8152506040518060400160405280600481526020016322a3a3ad60e11b81525081816200009762000091620000fb60201b60201c565b620000ff565b8151620000ac9060079060208501906200014f565b508051620000c29060089060208401906200014f565b506001600555505050600f85905550601083905560118290558051620000f090600d9060208401906200014f565b505050505062000344565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200015d9062000307565b90600052602060002090601f016020900481019282620001815760008555620001cc565b82601f106200019c57805160ff1916838001178555620001cc565b82800160010185558215620001cc579182015b82811115620001cc578251825591602001919060010190620001af565b50620001da929150620001de565b5090565b5b80821115620001da5760008155600101620001df565b634e487b7160e01b600052604160045260246000fd5b600080600080608085870312156200022257600080fd5b8451602080870151604088015160608901519397509095509350906001600160401b03808211156200025357600080fd5b818801915088601f8301126200026857600080fd5b8151818111156200027d576200027d620001f5565b604051601f8201601f19908116603f01168101908382118183101715620002a857620002a8620001f5565b816040528281528b86848701011115620002c157600080fd5b600093505b82841015620002e55784840186015181850187015292850192620002c6565b82841115620002f75760008684830101525b989b979a50959850505050505050565b600181811c908216806200031c57607f821691505b602082108114156200033e57634e487b7160e01b600052602260045260246000fd5b50919050565b6138b080620003546000396000f3fe60806040526004361061031e5760003560e01c8063715018a6116101a5578063ac52e644116100ec578063e886718011610095578063f2fde38b1161006f578063f2fde38b1461091c578063f3ea198c1461093c578063f8dcbddb1461095c578063f90a82c81461097c57600080fd5b8063e886718014610893578063e985e9c5146108b3578063ee0eeb09146108fc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610836578063cbccefb214610856578063e396d5251461087d57600080fd5b8063ac52e644146107d3578063b1a6505f146107f3578063b88d4fde1461082357600080fd5b806394d216d61161014e578063a0bcfc7f11610128578063a0bcfc7f14610773578063a22cb46514610793578063a694fc3a146107b357600080fd5b806394d216d61461072457806395d89b41146107445780639ed278091461075957600080fd5b8063853828b61161017f578063853828b6146106c45780638c4c2d49146106d95780638da5cb5b1461070657600080fd5b8063715018a61461066157806372abc8b7146106765780637cb64759146106a457600080fd5b80632799cde01161026957806340a9c8df11610212578063650b00f6116101ec578063650b00f6146105ff5780636c0360eb1461062c57806370a082311461064157600080fd5b806340a9c8df146105ac57806342842e0e146105cc5780636352211e146105df57600080fd5b80632eb4a7ab116102435780632eb4a7ab1461054957806335b504c51461055f578063372f657c1461058c57600080fd5b80632799cde0146104c85780632cba8123146104e85780632e17de781461052957600080fd5b80630a302530116102cb57806323b872dd116102a557806323b872dd14610475578063258a69f71461048857806325c2c020146104a857600080fd5b80630a3025301461042d5780631249c58b1461044357806318160ddd1461045857600080fd5b8063081812fc116102fc578063081812fc1461039c57806309308e5d146103d4578063095ea7b31461041a57600080fd5b806301ffc9a714610323578063050225ea1461035857806306fdde031461037a575b600080fd5b34801561032f57600080fd5b5061034361033e3660046130df565b61099c565b60405190151581526020015b60405180910390f35b34801561036457600080fd5b50610378610373366004613118565b6109e0565b005b34801561038657600080fd5b5061038f610af0565b60405161034f919061319a565b3480156103a857600080fd5b506103bc6103b73660046131ad565b610b82565b6040516001600160a01b03909116815260200161034f565b3480156103e057600080fd5b5061040c6103ef3660046131c6565b600460209081526000928352604080842090915290825290205481565b60405190815260200161034f565b610378610428366004613118565b610bdf565b34801561043957600080fd5b5061040c600f5481565b34801561044f57600080fd5b50610378610c98565b34801561046457600080fd5b50600654600554036000190161040c565b6103786104833660046131f2565b610e7b565b34801561049457600080fd5b506103786104a336600461327a565b610ee7565b3480156104b457600080fd5b506103786104c33660046131ad565b611145565b3480156104d457600080fd5b506103786104e33660046131ad565b611152565b3480156104f457600080fd5b506103bc6105033660046132bc565b60036020908152600092835260408084209091529082529020546001600160a01b031681565b34801561053557600080fd5b506103786105443660046131ad565b6111a2565b34801561055557600080fd5b5061040c60115481565b34801561056b57600080fd5b5061040c61057a3660046131ad565b60146020526000908152604090205481565b34801561059857600080fd5b506103786105a736600461327a565b6112ff565b3480156105b857600080fd5b506103786105c73660046131ad565b611537565b6103786105da3660046131f2565b611584565b3480156105eb57600080fd5b506103bc6105fa3660046131ad565b61159f565b34801561060b57600080fd5b5061040c61061a3660046131ad565b60026020526000908152604090205481565b34801561063857600080fd5b5061038f6115aa565b34801561064d57600080fd5b5061040c61065c3660046132de565b611638565b34801561066d57600080fd5b506103786116a0565b34801561068257600080fd5b506103436106913660046131ad565b6000908152600260205260409020541590565b3480156106b057600080fd5b506103786106bf3660046131ad565b6116b2565b3480156106d057600080fd5b506103786116bf565b3480156106e557600080fd5b5061040c6106f43660046132de565b60126020526000908152604090205481565b34801561071257600080fd5b506000546001600160a01b03166103bc565b34801561073057600080fd5b5061037861073f3660046131c6565b611730565b34801561075057600080fd5b5061038f61177e565b34801561076557600080fd5b506013546103439060ff1681565b34801561077f57600080fd5b5061037861078e366004613398565b61178d565b34801561079f57600080fd5b506103786107ae3660046133f1565b6117a8565b3480156107bf57600080fd5b506103786107ce3660046131ad565b611814565b3480156107df57600080fd5b506103786107ee36600461341b565b6119bd565b3480156107ff57600080fd5b5061034361080e3660046132de565b60016020526000908152604090205460ff1681565b610378610831366004613487565b611ab2565b34801561084257600080fd5b5061038f6108513660046131ad565b611b20565b34801561086257600080fd5b50600e546108709060ff1681565b60405161034f9190613519565b34801561088957600080fd5b5061040c60105481565b34801561089f57600080fd5b506103786108ae366004613541565b611ba9565b3480156108bf57600080fd5b506103436108ce36600461355c565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b34801561090857600080fd5b506103786109173660046131ad565b611bc4565b34801561092857600080fd5b506103786109373660046132de565b611bd1565b34801561094857600080fd5b50610378610957366004613586565b611c5e565b34801561096857600080fd5b506103786109773660046131ad565b611e95565b34801561098857600080fd5b506103786109973660046135d2565b611ed3565b60006001600160e01b031982167f706e84890000000000000000000000000000000000000000000000000000000014806109da57506109da82611f2d565b92915050565b6109e8611fc6565b6004600e5460ff166005811115610a0157610a01613503565b11610a795760405162461bcd60e51b815260206004820152602160248201527f476976656177617920697320616674657220746865207075626c69632073616c60448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6006546005546113889183910360001901610a9491906136a0565b1115610ae25760405162461bcd60e51b815260206004820152601360248201527f4d617820737570706c79206578636565646564000000000000000000000000006044820152606401610a70565b610aec8282612020565b5050565b606060078054610aff906136b8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2b906136b8565b8015610b785780601f10610b4d57610100808354040283529160200191610b78565b820191906000526020600020905b815481529060010190602001808311610b5b57829003601f168201915b5050505050905090565b6000610b8d8261203a565b610bc3576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600b60205260409020546001600160a01b031690565b6000610bea8261159f565b9050336001600160a01b03821614610c3c57610c0681336108ce565b610c3c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b323314610ce75760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6004600e5460ff166005811115610d0057610d00613503565b1015610d4e5760405162461bcd60e51b815260206004820152601c60248201527f5075626c69632073616c65206973206e6f7420616374697661746564000000006044820152606401610a70565b33600090815260126020526040902054600190610d6b90826136a0565b1115610ddf5760405162461bcd60e51b815260206004820152602960248201527f596f752063616e206f6e6c79206765742031204e4654206f6e2074686520507560448201527f626c69632053616c6500000000000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e491900360001901610dfa9060016136a0565b1115610e485760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b336000908152601260205260408120805460019290610e689084906136a0565b90915550610e799050336001612020565b565b60008181526014602052604090205415610ed75760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74207472616e73666572207374616b656420746f6b656e000000006044820152606401610a70565b610ee283838361206f565b505050565b323314610f365760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6002600e5460ff166005811115610f4f57610f4f613503565b1015610fc35760405162461bcd60e51b815260206004820152602760248201527f5072656d69756d2057686974656c6973742073616c65206973206e6f7420616360448201527f74697661746564000000000000000000000000000000000000000000000000006064820152608401610a70565b610fce3383836120d6565b61101a5760405162461bcd60e51b815260206004820152601760248201527f4e6f74205072656d69756d2077686974656c69737465640000000000000000006044820152606401610a70565b3360009081526012602052604090205460029061103790826136a0565b11156110ab5760405162461bcd60e51b815260206004820152603460248201527f596f752063616e206f6e6c79206765742032204e4654206f6e2074686520507260448201527f656d69756d2057686974656c6973742053616c650000000000000000000000006064820152608401610a70565b6006546005546111e4919003600019016110c69060026136a0565b11156111145760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054600292906111349084906136a0565b90915550610aec9050336002612020565b61114d611fc6565b600f55565b61115b8161203a565b6111965760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b61119f8161215b565b50565b6111ab8161159f565b6001600160a01b0316336001600160a01b031614806111d457506000546001600160a01b031633145b6112465760405162461bcd60e51b815260206004820152602f60248201527f63616c6c6572206d757374206265206f776e6572206f6620746f6b656e206f7260448201527f20636f6e7472616374206f776e657200000000000000000000000000000000006064820152608401610a70565b6000818152601460205260409020546112a15760405162461bcd60e51b815260206004820152600b60248201527f6e6f74207374616b696e670000000000000000000000000000000000000000006044820152606401610a70565b6000818152601460209081526040808320805493905580518481523392810192909252428282015260608201839052517fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c29181900360800190a15050565b32331461134e5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6003600e5460ff16600581111561136757611367613503565b10156113b55760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f7420616374697661746564006044820152606401610a70565b6113c03383836122cb565b61140c5760405162461bcd60e51b815260206004820152600f60248201527f4e6f742077686974656c697374656400000000000000000000000000000000006044820152606401610a70565b3360009081526012602052604090205460019061142990826136a0565b111561149d5760405162461bcd60e51b815260206004820152602c60248201527f596f752063616e206f6e6c79206765742031204e4654206f6e2074686520576860448201527f6974656c6973742053616c6500000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e4919003600019016114b89060016136a0565b11156115065760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054600192906115269084906136a0565b90915550610aec9050336001612020565b6115408161203a565b61157b5760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b61119f81612347565b610ee283838360405180602001604052806000815250611ab2565b60006109da82612514565b600d80546115b7906136b8565b80601f01602080910402602001604051908101604052809291908181526020018280546115e3906136b8565b80156116305780601f1061160557610100808354040283529160200191611630565b820191906000526020600020905b81548152906001019060200180831161161357829003601f168201915b505050505081565b60006001600160a01b03821661167a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152600a602052604090205467ffffffffffffffff1690565b6116a8611fc6565b610e79600061259d565b6116ba611fc6565b601155565b6116c7611fc6565b47806117155760405162461bcd60e51b815260206004820152601c60248201527f7468657265206973206e6f7468696e6720746f207769746864726177000000006044820152606401610a70565b61119f61172a6000546001600160a01b031690565b476125ed565b6117398261203a565b6117745760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b610aec8282612690565b606060088054610aff906136b8565b611795611fc6565b8051610aec90600d906020840190613030565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60135460ff166118665760405162461bcd60e51b815260206004820152601060248201527f7374616b696e67206e6f74206f70656e000000000000000000000000000000006044820152606401610a70565b61186f8161159f565b6001600160a01b0316336001600160a01b0316148061189857506000546001600160a01b031633145b61190a5760405162461bcd60e51b815260206004820152602f60248201527f63616c6c6572206d757374206265206f776e6572206f6620746f6b656e206f7260448201527f20636f6e7472616374206f776e657200000000000000000000000000000000006064820152608401610a70565b600081815260146020526040902054156119665760405162461bcd60e51b815260206004820152600f60248201527f616c7265616479207374616b696e6700000000000000000000000000000000006044820152606401610a70565b6000818152601460209081526040918290204290819055825184815233928101929092528183015290517f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff9181900360600190a150565b6119c5611fc6565b828114611a145760405162461bcd60e51b815260206004820152600760248201527f216c656e677468000000000000000000000000000000000000000000000000006044820152606401610a70565b60005b83811015611aab57828282818110611a3157611a316136f3565b9050602002016020810190611a469190613541565b60016000878785818110611a5c57611a5c6136f3565b9050602002016020810190611a7191906132de565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580611aa381613709565b915050611a17565b5050505050565b60008281526014602052604090205415611b0e5760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74207472616e73666572207374616b656420746f6b656e000000006044820152606401610a70565b611b1a84848484612883565b50505050565b6060611b2b8261203a565b611b775760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e006044820152606401610a70565b600d611b82836128eb565b604051602001611b93929190613740565b6040516020818303038152906040529050919050565b611bb1611fc6565b6013805460ff1916911515919091179055565b611bcc611fc6565b601055565b611bd9611fc6565b6001600160a01b038116611c555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a70565b61119f8161259d565b323314611cad5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6001600e5460ff166005811115611cc657611cc6613503565b1015611d145760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f7420616374697661746564006044820152606401610a70565b611d2033848484612995565b611d6c5760405162461bcd60e51b815260206004820152601260248201527f4e6f74204f472077686974656c697374656400000000000000000000000000006044820152606401610a70565b336000908152601260205260409020548390611d899082906136a0565b1115611dfd5760405162461bcd60e51b815260206004820152602860248201527f596f752072656163686564206d6178696d756d206f6e204f472057686974656c60448201527f6973742053616c650000000000000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e49185910360001901611e1891906136a0565b1115611e665760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054859290611e859084906136a0565b90915550610ee290503384612020565b611e9d611fc6565b806005811115611eaf57611eaf613503565b600e805460ff19166001836005811115611ecb57611ecb613503565b021790555050565b60005b8251811015610ee2576000838281518110611ef357611ef36136f3565b602002602001015190508215611f1157611f0c81611814565b611f1a565b611f1a816111a2565b5080611f2581613709565b915050611ed6565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b031983161480611f9057507f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b806109da5750506001600160e01b0319167f5b5e139f000000000000000000000000000000000000000000000000000000001490565b6000546001600160a01b03163314610e795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a70565b610aec828260405180602001604052806000815250612a24565b60008160011115801561204e575060055482105b80156109da575050600090815260096020526040902054600160e01b161590565b600081815260026020526040902054156120cb5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206973206c6f636b656400000000000000000000000000000000006044820152606401610a70565b610ee2838383612a8a565b6040516bffffffffffffffffffffffff19606085901b166020820152600090819060340160405160208183030381529060405280519060200120905061215281601054868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b95945050505050565b3360009081526001602052604090205460ff166121ba5760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b6000818152600460209081526040808320338452909152902054156122215760405162461bcd60e51b815260206004820152601b60248201527f494420616c7265616479206c6f636b65642062792063616c6c657200000000006044820152606401610a70565b60008181526002602052604081205461223b9060016136a0565b6000838152600360209081526040808320848452825280832080546001600160a01b031916339081179091558684526004835281842090845282528083208490558583526002909152812080549293509061229583613709565b9091555050604051339083907f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264390600090a35050565b6040516bffffffffffffffffffffffff19606085901b166020820152600090819060340160405160208183030381529060405280519060200120905061215281601154868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b3360009081526001602052604090205460ff166123a65760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b60008181526004602090815260408083203384529091529020548061240d5760405162461bcd60e51b815260206004820152601760248201527f4944206e6f74206c6f636b65642062792063616c6c65720000000000000000006044820152606401610a70565b6000828152600260205260409020548181146124835760008381526003602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b039093169283179091558254169091558684526004835281842090845290915290208290556124ab565b6000838152600360209081526040808320858452909152902080546001600160a01b03191690555b60008381526004602090815260408083203384528252808320839055858352600290915281208054916124dd8361380a565b9091555050604051339084907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a3505050565b6000818060011161256b5760055481101561256b57600081815260096020526040902054600160e01b8116612569575b80612562575060001901600081815260096020526040902054612544565b9392505050565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b5050905080610ee25760405162461bcd60e51b815260206004820152601260248201527f636f756c64206e6f7420776974686472617700000000000000000000000000006044820152606401610a70565b6001600160a01b03811660009081526001602052604090205460ff16156126f95760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b60008281526004602090815260408083206001600160a01b0385168452909152902054806127695760405162461bcd60e51b815260206004820152600d60248201527f4944206e6f74206c6f636b6564000000000000000000000000000000000000006044820152606401610a70565b6000838152600260205260409020548181146127df5760008481526003602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b03909316928317909155825416909155878452600483528184209084529091529020829055612807565b6000848152600360209081526040808320858452909152902080546001600160a01b03191690555b60008481526004602090815260408083206001600160a01b03871684528252808320839055868352600290915281208054916128428361380a565b90915550506040516001600160a01b0384169085907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a350505050565b600082815260026020526040902054156128df5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206973206c6f636b656400000000000000000000000000000000006044820152606401610a70565b611b1a84848484612c74565b606060006128f883612cb8565b600101905060008167ffffffffffffffff811115612918576129186132f9565b6040519080825280601f01601f191660200182016040528015612942576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846129885761298d565b61294c565b509392505050565b6040516bffffffffffffffffffffffff19606086901b166020820152603481018490526000908190605401604051602081830303815290604052805190602001209050612a1881600f54868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b9150505b949350505050565b612a2e8383612d9a565b6001600160a01b0383163b15610ee2576005548281035b612a586000868380600101945086612ec4565b612a75576040516368d2bf6b60e11b815260040160405180910390fd5b818110612a45578160055414611aab57600080fd5b6000612a9582612514565b9050836001600160a01b0316816001600160a01b031614612ae2576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b602052604090208054338082146001600160a01b03881690911417612b4857612b1286336108ce565b612b48576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516612b88576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015612b9357600082555b6001600160a01b038681166000908152600a60205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260096020526040902055600160e11b8316612c1e5760018401600081815260096020526040902054612c1c576005548114612c1c5760008181526009602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000612a1c828486612fa9565b612c7f848484610e7b565b6001600160a01b0383163b15611b1a57612c9b84848484612ec4565b611b1a576040516368d2bf6b60e11b815260040160405180910390fd5b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612d01577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310612d2d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612d4b57662386f26fc10000830492506010015b6305f5e1008310612d63576305f5e100830492506008015b6127108310612d7757612710830492506004015b60648310612d89576064830492506002015b600a83106109da5760010192915050565b60055481612dd4576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383166000818152600a602090815260408083208054680100000000000000018802019055848352600990915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612e8357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612e4b565b5081612ebb576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055550505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290612ef9903390899088908890600401613821565b6020604051808303816000875af1925050508015612f34575060408051601f3d908101601f19168201909252612f319181019061385d565b60015b612f8f573d808015612f62576040519150601f19603f3d011682016040523d82523d6000602084013e612f67565b606091505b508051612f87576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612a1c565b600082612fb68584612fbf565b14949350505050565b600081815b845181101561298d57612ff082868381518110612fe357612fe36136f3565b6020026020010151613004565b915080612ffc81613709565b915050612fc4565b6000818310613020576000828152602084905260409020612562565b5060009182526020526040902090565b82805461303c906136b8565b90600052602060002090601f01602090048101928261305e57600085556130a4565b82601f1061307757805160ff19168380011785556130a4565b828001600101855582156130a4579182015b828111156130a4578251825591602001919060010190613089565b506130b09291506130b4565b5090565b5b808211156130b057600081556001016130b5565b6001600160e01b03198116811461119f57600080fd5b6000602082840312156130f157600080fd5b8135612562816130c9565b80356001600160a01b038116811461311357600080fd5b919050565b6000806040838503121561312b57600080fd5b613134836130fc565b946020939093013593505050565b60005b8381101561315d578181015183820152602001613145565b83811115611b1a5750506000910152565b60008151808452613186816020860160208601613142565b601f01601f19169290920160200192915050565b602081526000612562602083018461316e565b6000602082840312156131bf57600080fd5b5035919050565b600080604083850312156131d957600080fd5b823591506131e9602084016130fc565b90509250929050565b60008060006060848603121561320757600080fd5b613210846130fc565b925061321e602085016130fc565b9150604084013590509250925092565b60008083601f84011261324057600080fd5b50813567ffffffffffffffff81111561325857600080fd5b6020830191508360208260051b850101111561327357600080fd5b9250929050565b6000806020838503121561328d57600080fd5b823567ffffffffffffffff8111156132a457600080fd5b6132b08582860161322e565b90969095509350505050565b600080604083850312156132cf57600080fd5b50508035926020909101359150565b6000602082840312156132f057600080fd5b612562826130fc565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613338576133386132f9565b604052919050565b600067ffffffffffffffff83111561335a5761335a6132f9565b61336d601f8401601f191660200161330f565b905082815283838301111561338157600080fd5b828260208301376000602084830101529392505050565b6000602082840312156133aa57600080fd5b813567ffffffffffffffff8111156133c157600080fd5b8201601f810184136133d257600080fd5b612a1c84823560208401613340565b8035801515811461311357600080fd5b6000806040838503121561340457600080fd5b61340d836130fc565b91506131e9602084016133e1565b6000806000806040858703121561343157600080fd5b843567ffffffffffffffff8082111561344957600080fd5b6134558883890161322e565b9096509450602087013591508082111561346e57600080fd5b5061347b8782880161322e565b95989497509550505050565b6000806000806080858703121561349d57600080fd5b6134a6856130fc565b93506134b4602086016130fc565b925060408501359150606085013567ffffffffffffffff8111156134d757600080fd5b8501601f810187136134e857600080fd5b6134f787823560208401613340565b91505092959194509250565b634e487b7160e01b600052602160045260246000fd5b602081016006831061353b57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020828403121561355357600080fd5b612562826133e1565b6000806040838503121561356f57600080fd5b613578836130fc565b91506131e9602084016130fc565b60008060006040848603121561359b57600080fd5b83359250602084013567ffffffffffffffff8111156135b957600080fd5b6135c58682870161322e565b9497909650939450505050565b600080604083850312156135e557600080fd5b823567ffffffffffffffff808211156135fd57600080fd5b818501915085601f83011261361157600080fd5b8135602082821115613625576136256132f9565b8160051b925061363681840161330f565b828152928401810192818101908985111561365057600080fd5b948201945b8486101561366e57853582529482019490820190613655565b965061367d90508782016133e1565b9450505050509250929050565b634e487b7160e01b600052601160045260246000fd5b600082198211156136b3576136b361368a565b500190565b600181811c908216806136cc57607f821691505b602082108114156136ed57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561371d5761371d61368a565b5060010190565b60008151613736818560208601613142565b9290920192915050565b600080845481600182811c91508083168061375c57607f831692505b602080841082141561377c57634e487b7160e01b86526022600452602486fd5b81801561379057600181146137a1576137ce565b60ff198616895284890196506137ce565b60008b81526020902060005b868110156137c65781548b8201529085019083016137ad565b505084890196505b5050505050506121526137e18286613724565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000815260050190565b6000816138195761381961368a565b506000190190565b60006001600160a01b03808716835280861660208401525083604083015260806060830152613853608083018461316e565b9695505050505050565b60006020828403121561386f57600080fd5b8151612562816130c956fea264697066735822122005f92bfdbff70a84131e076ea8893046ed01df5e998b0913b5383f87efd3a90964736f6c634300080c0033d8a5ef9b558a496a4ca83e444305247c81d0f5d6fd3e1a956b172509239e31f3d88df37125fbaf36fb8f1c4751d1dd015f7b67b90a71f1530fa754e330aa23deba8f4b48ecc9e8c5d70630df4500684c6d3f59a51316ab198f212a165bc96f2700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d614651765432596b38696d5764794255546a646f55744254467274785042745844784775764c554e575553382f00000000000000000000
Deployed Bytecode
0x60806040526004361061031e5760003560e01c8063715018a6116101a5578063ac52e644116100ec578063e886718011610095578063f2fde38b1161006f578063f2fde38b1461091c578063f3ea198c1461093c578063f8dcbddb1461095c578063f90a82c81461097c57600080fd5b8063e886718014610893578063e985e9c5146108b3578063ee0eeb09146108fc57600080fd5b8063c87b56dd116100c6578063c87b56dd14610836578063cbccefb214610856578063e396d5251461087d57600080fd5b8063ac52e644146107d3578063b1a6505f146107f3578063b88d4fde1461082357600080fd5b806394d216d61161014e578063a0bcfc7f11610128578063a0bcfc7f14610773578063a22cb46514610793578063a694fc3a146107b357600080fd5b806394d216d61461072457806395d89b41146107445780639ed278091461075957600080fd5b8063853828b61161017f578063853828b6146106c45780638c4c2d49146106d95780638da5cb5b1461070657600080fd5b8063715018a61461066157806372abc8b7146106765780637cb64759146106a457600080fd5b80632799cde01161026957806340a9c8df11610212578063650b00f6116101ec578063650b00f6146105ff5780636c0360eb1461062c57806370a082311461064157600080fd5b806340a9c8df146105ac57806342842e0e146105cc5780636352211e146105df57600080fd5b80632eb4a7ab116102435780632eb4a7ab1461054957806335b504c51461055f578063372f657c1461058c57600080fd5b80632799cde0146104c85780632cba8123146104e85780632e17de781461052957600080fd5b80630a302530116102cb57806323b872dd116102a557806323b872dd14610475578063258a69f71461048857806325c2c020146104a857600080fd5b80630a3025301461042d5780631249c58b1461044357806318160ddd1461045857600080fd5b8063081812fc116102fc578063081812fc1461039c57806309308e5d146103d4578063095ea7b31461041a57600080fd5b806301ffc9a714610323578063050225ea1461035857806306fdde031461037a575b600080fd5b34801561032f57600080fd5b5061034361033e3660046130df565b61099c565b60405190151581526020015b60405180910390f35b34801561036457600080fd5b50610378610373366004613118565b6109e0565b005b34801561038657600080fd5b5061038f610af0565b60405161034f919061319a565b3480156103a857600080fd5b506103bc6103b73660046131ad565b610b82565b6040516001600160a01b03909116815260200161034f565b3480156103e057600080fd5b5061040c6103ef3660046131c6565b600460209081526000928352604080842090915290825290205481565b60405190815260200161034f565b610378610428366004613118565b610bdf565b34801561043957600080fd5b5061040c600f5481565b34801561044f57600080fd5b50610378610c98565b34801561046457600080fd5b50600654600554036000190161040c565b6103786104833660046131f2565b610e7b565b34801561049457600080fd5b506103786104a336600461327a565b610ee7565b3480156104b457600080fd5b506103786104c33660046131ad565b611145565b3480156104d457600080fd5b506103786104e33660046131ad565b611152565b3480156104f457600080fd5b506103bc6105033660046132bc565b60036020908152600092835260408084209091529082529020546001600160a01b031681565b34801561053557600080fd5b506103786105443660046131ad565b6111a2565b34801561055557600080fd5b5061040c60115481565b34801561056b57600080fd5b5061040c61057a3660046131ad565b60146020526000908152604090205481565b34801561059857600080fd5b506103786105a736600461327a565b6112ff565b3480156105b857600080fd5b506103786105c73660046131ad565b611537565b6103786105da3660046131f2565b611584565b3480156105eb57600080fd5b506103bc6105fa3660046131ad565b61159f565b34801561060b57600080fd5b5061040c61061a3660046131ad565b60026020526000908152604090205481565b34801561063857600080fd5b5061038f6115aa565b34801561064d57600080fd5b5061040c61065c3660046132de565b611638565b34801561066d57600080fd5b506103786116a0565b34801561068257600080fd5b506103436106913660046131ad565b6000908152600260205260409020541590565b3480156106b057600080fd5b506103786106bf3660046131ad565b6116b2565b3480156106d057600080fd5b506103786116bf565b3480156106e557600080fd5b5061040c6106f43660046132de565b60126020526000908152604090205481565b34801561071257600080fd5b506000546001600160a01b03166103bc565b34801561073057600080fd5b5061037861073f3660046131c6565b611730565b34801561075057600080fd5b5061038f61177e565b34801561076557600080fd5b506013546103439060ff1681565b34801561077f57600080fd5b5061037861078e366004613398565b61178d565b34801561079f57600080fd5b506103786107ae3660046133f1565b6117a8565b3480156107bf57600080fd5b506103786107ce3660046131ad565b611814565b3480156107df57600080fd5b506103786107ee36600461341b565b6119bd565b3480156107ff57600080fd5b5061034361080e3660046132de565b60016020526000908152604090205460ff1681565b610378610831366004613487565b611ab2565b34801561084257600080fd5b5061038f6108513660046131ad565b611b20565b34801561086257600080fd5b50600e546108709060ff1681565b60405161034f9190613519565b34801561088957600080fd5b5061040c60105481565b34801561089f57600080fd5b506103786108ae366004613541565b611ba9565b3480156108bf57600080fd5b506103436108ce36600461355c565b6001600160a01b039182166000908152600c6020908152604080832093909416825291909152205460ff1690565b34801561090857600080fd5b506103786109173660046131ad565b611bc4565b34801561092857600080fd5b506103786109373660046132de565b611bd1565b34801561094857600080fd5b50610378610957366004613586565b611c5e565b34801561096857600080fd5b506103786109773660046131ad565b611e95565b34801561098857600080fd5b506103786109973660046135d2565b611ed3565b60006001600160e01b031982167f706e84890000000000000000000000000000000000000000000000000000000014806109da57506109da82611f2d565b92915050565b6109e8611fc6565b6004600e5460ff166005811115610a0157610a01613503565b11610a795760405162461bcd60e51b815260206004820152602160248201527f476976656177617920697320616674657220746865207075626c69632073616c60448201527f650000000000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6006546005546113889183910360001901610a9491906136a0565b1115610ae25760405162461bcd60e51b815260206004820152601360248201527f4d617820737570706c79206578636565646564000000000000000000000000006044820152606401610a70565b610aec8282612020565b5050565b606060078054610aff906136b8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2b906136b8565b8015610b785780601f10610b4d57610100808354040283529160200191610b78565b820191906000526020600020905b815481529060010190602001808311610b5b57829003601f168201915b5050505050905090565b6000610b8d8261203a565b610bc3576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600b60205260409020546001600160a01b031690565b6000610bea8261159f565b9050336001600160a01b03821614610c3c57610c0681336108ce565b610c3c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b323314610ce75760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6004600e5460ff166005811115610d0057610d00613503565b1015610d4e5760405162461bcd60e51b815260206004820152601c60248201527f5075626c69632073616c65206973206e6f7420616374697661746564000000006044820152606401610a70565b33600090815260126020526040902054600190610d6b90826136a0565b1115610ddf5760405162461bcd60e51b815260206004820152602960248201527f596f752063616e206f6e6c79206765742031204e4654206f6e2074686520507560448201527f626c69632053616c6500000000000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e491900360001901610dfa9060016136a0565b1115610e485760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b336000908152601260205260408120805460019290610e689084906136a0565b90915550610e799050336001612020565b565b60008181526014602052604090205415610ed75760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74207472616e73666572207374616b656420746f6b656e000000006044820152606401610a70565b610ee283838361206f565b505050565b323314610f365760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6002600e5460ff166005811115610f4f57610f4f613503565b1015610fc35760405162461bcd60e51b815260206004820152602760248201527f5072656d69756d2057686974656c6973742073616c65206973206e6f7420616360448201527f74697661746564000000000000000000000000000000000000000000000000006064820152608401610a70565b610fce3383836120d6565b61101a5760405162461bcd60e51b815260206004820152601760248201527f4e6f74205072656d69756d2077686974656c69737465640000000000000000006044820152606401610a70565b3360009081526012602052604090205460029061103790826136a0565b11156110ab5760405162461bcd60e51b815260206004820152603460248201527f596f752063616e206f6e6c79206765742032204e4654206f6e2074686520507260448201527f656d69756d2057686974656c6973742053616c650000000000000000000000006064820152608401610a70565b6006546005546111e4919003600019016110c69060026136a0565b11156111145760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054600292906111349084906136a0565b90915550610aec9050336002612020565b61114d611fc6565b600f55565b61115b8161203a565b6111965760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b61119f8161215b565b50565b6111ab8161159f565b6001600160a01b0316336001600160a01b031614806111d457506000546001600160a01b031633145b6112465760405162461bcd60e51b815260206004820152602f60248201527f63616c6c6572206d757374206265206f776e6572206f6620746f6b656e206f7260448201527f20636f6e7472616374206f776e657200000000000000000000000000000000006064820152608401610a70565b6000818152601460205260409020546112a15760405162461bcd60e51b815260206004820152600b60248201527f6e6f74207374616b696e670000000000000000000000000000000000000000006044820152606401610a70565b6000818152601460209081526040808320805493905580518481523392810192909252428282015260608201839052517fc1e00202ee2c06861d326fc6374026b751863ff64218ccbaa38c3e603a8e72c29181900360800190a15050565b32331461134e5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6003600e5460ff16600581111561136757611367613503565b10156113b55760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f7420616374697661746564006044820152606401610a70565b6113c03383836122cb565b61140c5760405162461bcd60e51b815260206004820152600f60248201527f4e6f742077686974656c697374656400000000000000000000000000000000006044820152606401610a70565b3360009081526012602052604090205460019061142990826136a0565b111561149d5760405162461bcd60e51b815260206004820152602c60248201527f596f752063616e206f6e6c79206765742031204e4654206f6e2074686520576860448201527f6974656c6973742053616c6500000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e4919003600019016114b89060016136a0565b11156115065760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054600192906115269084906136a0565b90915550610aec9050336001612020565b6115408161203a565b61157b5760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b61119f81612347565b610ee283838360405180602001604052806000815250611ab2565b60006109da82612514565b600d80546115b7906136b8565b80601f01602080910402602001604051908101604052809291908181526020018280546115e3906136b8565b80156116305780601f1061160557610100808354040283529160200191611630565b820191906000526020600020905b81548152906001019060200180831161161357829003601f168201915b505050505081565b60006001600160a01b03821661167a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152600a602052604090205467ffffffffffffffff1690565b6116a8611fc6565b610e79600061259d565b6116ba611fc6565b601155565b6116c7611fc6565b47806117155760405162461bcd60e51b815260206004820152601c60248201527f7468657265206973206e6f7468696e6720746f207769746864726177000000006044820152606401610a70565b61119f61172a6000546001600160a01b031690565b476125ed565b6117398261203a565b6117745760405162461bcd60e51b815260206004820152600c60248201526b151bdad95b8808595e1a5cdd60a21b6044820152606401610a70565b610aec8282612690565b606060088054610aff906136b8565b611795611fc6565b8051610aec90600d906020840190613030565b336000818152600c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60135460ff166118665760405162461bcd60e51b815260206004820152601060248201527f7374616b696e67206e6f74206f70656e000000000000000000000000000000006044820152606401610a70565b61186f8161159f565b6001600160a01b0316336001600160a01b0316148061189857506000546001600160a01b031633145b61190a5760405162461bcd60e51b815260206004820152602f60248201527f63616c6c6572206d757374206265206f776e6572206f6620746f6b656e206f7260448201527f20636f6e7472616374206f776e657200000000000000000000000000000000006064820152608401610a70565b600081815260146020526040902054156119665760405162461bcd60e51b815260206004820152600f60248201527f616c7265616479207374616b696e6700000000000000000000000000000000006044820152606401610a70565b6000818152601460209081526040918290204290819055825184815233928101929092528183015290517f02567b2553aeb44e4ddd5d68462774dc3de158cb0f2c2da1740e729b22086aff9181900360600190a150565b6119c5611fc6565b828114611a145760405162461bcd60e51b815260206004820152600760248201527f216c656e677468000000000000000000000000000000000000000000000000006044820152606401610a70565b60005b83811015611aab57828282818110611a3157611a316136f3565b9050602002016020810190611a469190613541565b60016000878785818110611a5c57611a5c6136f3565b9050602002016020810190611a7191906132de565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580611aa381613709565b915050611a17565b5050505050565b60008281526014602052604090205415611b0e5760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f74207472616e73666572207374616b656420746f6b656e000000006044820152606401610a70565b611b1a84848484612883565b50505050565b6060611b2b8261203a565b611b775760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e006044820152606401610a70565b600d611b82836128eb565b604051602001611b93929190613740565b6040516020818303038152906040529050919050565b611bb1611fc6565b6013805460ff1916911515919091179055565b611bcc611fc6565b601055565b611bd9611fc6565b6001600160a01b038116611c555760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610a70565b61119f8161259d565b323314611cad5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610a70565b6001600e5460ff166005811115611cc657611cc6613503565b1015611d145760405162461bcd60e51b815260206004820152601f60248201527f57686974656c6973742073616c65206973206e6f7420616374697661746564006044820152606401610a70565b611d2033848484612995565b611d6c5760405162461bcd60e51b815260206004820152601260248201527f4e6f74204f472077686974656c697374656400000000000000000000000000006044820152606401610a70565b336000908152601260205260409020548390611d899082906136a0565b1115611dfd5760405162461bcd60e51b815260206004820152602860248201527f596f752072656163686564206d6178696d756d206f6e204f472057686974656c60448201527f6973742053616c650000000000000000000000000000000000000000000000006064820152608401610a70565b6006546005546111e49185910360001901611e1891906136a0565b1115611e665760405162461bcd60e51b815260206004820152601c60248201527f4d617820667265656d696e7420737570706c79206578636565646564000000006044820152606401610a70565b3360009081526012602052604081208054859290611e859084906136a0565b90915550610ee290503384612020565b611e9d611fc6565b806005811115611eaf57611eaf613503565b600e805460ff19166001836005811115611ecb57611ecb613503565b021790555050565b60005b8251811015610ee2576000838281518110611ef357611ef36136f3565b602002602001015190508215611f1157611f0c81611814565b611f1a565b611f1a816111a2565b5080611f2581613709565b915050611ed6565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b031983161480611f9057507f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b806109da5750506001600160e01b0319167f5b5e139f000000000000000000000000000000000000000000000000000000001490565b6000546001600160a01b03163314610e795760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a70565b610aec828260405180602001604052806000815250612a24565b60008160011115801561204e575060055482105b80156109da575050600090815260096020526040902054600160e01b161590565b600081815260026020526040902054156120cb5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206973206c6f636b656400000000000000000000000000000000006044820152606401610a70565b610ee2838383612a8a565b6040516bffffffffffffffffffffffff19606085901b166020820152600090819060340160405160208183030381529060405280519060200120905061215281601054868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b95945050505050565b3360009081526001602052604090205460ff166121ba5760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b6000818152600460209081526040808320338452909152902054156122215760405162461bcd60e51b815260206004820152601b60248201527f494420616c7265616479206c6f636b65642062792063616c6c657200000000006044820152606401610a70565b60008181526002602052604081205461223b9060016136a0565b6000838152600360209081526040808320848452825280832080546001600160a01b031916339081179091558684526004835281842090845282528083208490558583526002909152812080549293509061229583613709565b9091555050604051339083907f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264390600090a35050565b6040516bffffffffffffffffffffffff19606085901b166020820152600090819060340160405160208183030381529060405280519060200120905061215281601154868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b3360009081526001602052604090205460ff166123a65760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b60008181526004602090815260408083203384529091529020548061240d5760405162461bcd60e51b815260206004820152601760248201527f4944206e6f74206c6f636b65642062792063616c6c65720000000000000000006044820152606401610a70565b6000828152600260205260409020548181146124835760008381526003602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b039093169283179091558254169091558684526004835281842090845290915290208290556124ab565b6000838152600360209081526040808320858452909152902080546001600160a01b03191690555b60008381526004602090815260408083203384528252808320839055858352600290915281208054916124dd8361380a565b9091555050604051339084907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a3505050565b6000818060011161256b5760055481101561256b57600081815260096020526040902054600160e01b8116612569575b80612562575060001901600081815260096020526040902054612544565b9392505050565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b5050905080610ee25760405162461bcd60e51b815260206004820152601260248201527f636f756c64206e6f7420776974686472617700000000000000000000000000006044820152606401610a70565b6001600160a01b03811660009081526001602052604090205460ff16156126f95760405162461bcd60e51b815260206004820152601160248201527f43616e6e6f7420757064617465206d61700000000000000000000000000000006044820152606401610a70565b60008281526004602090815260408083206001600160a01b0385168452909152902054806127695760405162461bcd60e51b815260206004820152600d60248201527f4944206e6f74206c6f636b6564000000000000000000000000000000000000006044820152606401610a70565b6000838152600260205260409020548181146127df5760008481526003602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b03909316928317909155825416909155878452600483528184209084529091529020829055612807565b6000848152600360209081526040808320858452909152902080546001600160a01b03191690555b60008481526004602090815260408083206001600160a01b03871684528252808320839055868352600290915281208054916128428361380a565b90915550506040516001600160a01b0384169085907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a350505050565b600082815260026020526040902054156128df5760405162461bcd60e51b815260206004820152600f60248201527f546f6b656e206973206c6f636b656400000000000000000000000000000000006044820152606401610a70565b611b1a84848484612c74565b606060006128f883612cb8565b600101905060008167ffffffffffffffff811115612918576129186132f9565b6040519080825280601f01601f191660200182016040528015612942576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846129885761298d565b61294c565b509392505050565b6040516bffffffffffffffffffffffff19606086901b166020820152603481018490526000908190605401604051602081830303815290604052805190602001209050612a1881600f54868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c6792505050565b9150505b949350505050565b612a2e8383612d9a565b6001600160a01b0383163b15610ee2576005548281035b612a586000868380600101945086612ec4565b612a75576040516368d2bf6b60e11b815260040160405180910390fd5b818110612a45578160055414611aab57600080fd5b6000612a9582612514565b9050836001600160a01b0316816001600160a01b031614612ae2576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600b602052604090208054338082146001600160a01b03881690911417612b4857612b1286336108ce565b612b48576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516612b88576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8015612b9357600082555b6001600160a01b038681166000908152600a60205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260096020526040902055600160e11b8316612c1e5760018401600081815260096020526040902054612c1c576005548114612c1c5760008181526009602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000612a1c828486612fa9565b612c7f848484610e7b565b6001600160a01b0383163b15611b1a57612c9b84848484612ec4565b611b1a576040516368d2bf6b60e11b815260040160405180910390fd5b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612d01577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310612d2d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612d4b57662386f26fc10000830492506010015b6305f5e1008310612d63576305f5e100830492506008015b6127108310612d7757612710830492506004015b60648310612d89576064830492506002015b600a83106109da5760010192915050565b60055481612dd4576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383166000818152600a602090815260408083208054680100000000000000018802019055848352600990915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114612e8357808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101612e4b565b5081612ebb576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055550505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290612ef9903390899088908890600401613821565b6020604051808303816000875af1925050508015612f34575060408051601f3d908101601f19168201909252612f319181019061385d565b60015b612f8f573d808015612f62576040519150601f19603f3d011682016040523d82523d6000602084013e612f67565b606091505b508051612f87576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612a1c565b600082612fb68584612fbf565b14949350505050565b600081815b845181101561298d57612ff082868381518110612fe357612fe36136f3565b6020026020010151613004565b915080612ffc81613709565b915050612fc4565b6000818310613020576000828152602084905260409020612562565b5060009182526020526040902090565b82805461303c906136b8565b90600052602060002090601f01602090048101928261305e57600085556130a4565b82601f1061307757805160ff19168380011785556130a4565b828001600101855582156130a4579182015b828111156130a4578251825591602001919060010190613089565b506130b09291506130b4565b5090565b5b808211156130b057600081556001016130b5565b6001600160e01b03198116811461119f57600080fd5b6000602082840312156130f157600080fd5b8135612562816130c9565b80356001600160a01b038116811461311357600080fd5b919050565b6000806040838503121561312b57600080fd5b613134836130fc565b946020939093013593505050565b60005b8381101561315d578181015183820152602001613145565b83811115611b1a5750506000910152565b60008151808452613186816020860160208601613142565b601f01601f19169290920160200192915050565b602081526000612562602083018461316e565b6000602082840312156131bf57600080fd5b5035919050565b600080604083850312156131d957600080fd5b823591506131e9602084016130fc565b90509250929050565b60008060006060848603121561320757600080fd5b613210846130fc565b925061321e602085016130fc565b9150604084013590509250925092565b60008083601f84011261324057600080fd5b50813567ffffffffffffffff81111561325857600080fd5b6020830191508360208260051b850101111561327357600080fd5b9250929050565b6000806020838503121561328d57600080fd5b823567ffffffffffffffff8111156132a457600080fd5b6132b08582860161322e565b90969095509350505050565b600080604083850312156132cf57600080fd5b50508035926020909101359150565b6000602082840312156132f057600080fd5b612562826130fc565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613338576133386132f9565b604052919050565b600067ffffffffffffffff83111561335a5761335a6132f9565b61336d601f8401601f191660200161330f565b905082815283838301111561338157600080fd5b828260208301376000602084830101529392505050565b6000602082840312156133aa57600080fd5b813567ffffffffffffffff8111156133c157600080fd5b8201601f810184136133d257600080fd5b612a1c84823560208401613340565b8035801515811461311357600080fd5b6000806040838503121561340457600080fd5b61340d836130fc565b91506131e9602084016133e1565b6000806000806040858703121561343157600080fd5b843567ffffffffffffffff8082111561344957600080fd5b6134558883890161322e565b9096509450602087013591508082111561346e57600080fd5b5061347b8782880161322e565b95989497509550505050565b6000806000806080858703121561349d57600080fd5b6134a6856130fc565b93506134b4602086016130fc565b925060408501359150606085013567ffffffffffffffff8111156134d757600080fd5b8501601f810187136134e857600080fd5b6134f787823560208401613340565b91505092959194509250565b634e487b7160e01b600052602160045260246000fd5b602081016006831061353b57634e487b7160e01b600052602160045260246000fd5b91905290565b60006020828403121561355357600080fd5b612562826133e1565b6000806040838503121561356f57600080fd5b613578836130fc565b91506131e9602084016130fc565b60008060006040848603121561359b57600080fd5b83359250602084013567ffffffffffffffff8111156135b957600080fd5b6135c58682870161322e565b9497909650939450505050565b600080604083850312156135e557600080fd5b823567ffffffffffffffff808211156135fd57600080fd5b818501915085601f83011261361157600080fd5b8135602082821115613625576136256132f9565b8160051b925061363681840161330f565b828152928401810192818101908985111561365057600080fd5b948201945b8486101561366e57853582529482019490820190613655565b965061367d90508782016133e1565b9450505050509250929050565b634e487b7160e01b600052601160045260246000fd5b600082198211156136b3576136b361368a565b500190565b600181811c908216806136cc57607f821691505b602082108114156136ed57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561371d5761371d61368a565b5060010190565b60008151613736818560208601613142565b9290920192915050565b600080845481600182811c91508083168061375c57607f831692505b602080841082141561377c57634e487b7160e01b86526022600452602486fd5b81801561379057600181146137a1576137ce565b60ff198616895284890196506137ce565b60008b81526020902060005b868110156137c65781548b8201529085019083016137ad565b505084890196505b5050505050506121526137e18286613724565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000815260050190565b6000816138195761381961368a565b506000190190565b60006001600160a01b03808716835280861660208401525083604083015260806060830152613853608083018461316e565b9695505050505050565b60006020828403121561386f57600080fd5b8151612562816130c956fea264697066735822122005f92bfdbff70a84131e076ea8893046ed01df5e998b0913b5383f87efd3a90964736f6c634300080c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
d8a5ef9b558a496a4ca83e444305247c81d0f5d6fd3e1a956b172509239e31f3d88df37125fbaf36fb8f1c4751d1dd015f7b67b90a71f1530fa754e330aa23deba8f4b48ecc9e8c5d70630df4500684c6d3f59a51316ab198f212a165bc96f2700000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d614651765432596b38696d5764794255546a646f55744254467274785042745844784775764c554e575553382f00000000000000000000
-----Decoded View---------------
Arg [0] : _ogMerkleRoot (bytes32): 0xd8a5ef9b558a496a4ca83e444305247c81d0f5d6fd3e1a956b172509239e31f3
Arg [1] : _premiumMerkleRoot (bytes32): 0xd88df37125fbaf36fb8f1c4751d1dd015f7b67b90a71f1530fa754e330aa23de
Arg [2] : _merkleRoot (bytes32): 0xba8f4b48ecc9e8c5d70630df4500684c6d3f59a51316ab198f212a165bc96f27
Arg [3] : _baseURI (string): ipfs://QmaFQvT2Yk8imWdyBUTjdoUtBTFrtxPBtXDxGuvLUNWUS8/
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : d8a5ef9b558a496a4ca83e444305247c81d0f5d6fd3e1a956b172509239e31f3
Arg [1] : d88df37125fbaf36fb8f1c4751d1dd015f7b67b90a71f1530fa754e330aa23de
Arg [2] : ba8f4b48ecc9e8c5d70630df4500684c6d3f59a51316ab198f212a165bc96f27
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000036
Arg [5] : 697066733a2f2f516d614651765432596b38696d5764794255546a646f557442
Arg [6] : 54467274785042745844784775764c554e575553382f00000000000000000000
Deployed Bytecode Sourcemap
218:8531:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1099:271:2;;;;;;;;;;-1:-1:-1;1099:271:2;;;;;:::i;:::-;;:::i;:::-;;;611:14:11;;604:22;586:41;;574:2;559:18;1099:271:2;;;;;;;;4038:273:3;;;;;;;;;;-1:-1:-1;4038:273:3;;;;;:::i;:::-;;:::i;:::-;;10199:98:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;16918:258::-;;;;;;;;;;-1:-1:-1;16918:258:1;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2220:55:11;;;2202:74;;2190:2;2175:18;16918:258:1;2056:226:11;426:92:6;;;;;;;;;;-1:-1:-1;426:92:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;2692:25:11;;;2680:2;2665:18;426:92:6;2546:177:11;16334:434:1;;;;;;:::i;:::-;;:::i;587:27:3:-;;;;;;;;;;;;;;;;3576:456;;;;;;;;;;;;;:::i;5894:317:1:-;;;;;;;;;;-1:-1:-1;6164:12:1;;6148:13;;:28;-1:-1:-1;;6148:46:1;5894:317;;6290:299:3;;;;;;:::i;:::-;;:::i;2257:703::-;;;;;;;;;;-1:-1:-1;2257:703:3;;;;;:::i;:::-;;:::i;4848:108::-;;;;;;;;;;-1:-1:-1;4848:108:3;;;;;:::i;:::-;;:::i;1925:131:2:-;;;;;;;;;;-1:-1:-1;1925:131:2;;;;;:::i;:::-;;:::i;349:71:6:-;;;;;;;;;;-1:-1:-1;349:71:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;349:71:6;;;7396:429:3;;;;;;;;;;-1:-1:-1;7396:429:3;;;;;:::i;:::-;;:::i;658:25::-;;;;;;;;;;;;;;;;777:53;;;;;;;;;;-1:-1:-1;777:53:3;;;;;:::i;:::-;;;;;;;;;;;;;;2966:604;;;;;;;;;;-1:-1:-1;2966:604:3;;;;;:::i;:::-;;:::i;2062:135:2:-;;;;;;;;;;-1:-1:-1;2062:135:2;;;;;:::i;:::-;;:::i;23598:187:1:-;;;;;;:::i;:::-;;:::i;11639:194::-;;;;;;;;;;-1:-1:-1;11639:194:1;;;;;:::i;:::-;;:::i;290:53:6:-;;;;;;;;;;-1:-1:-1;290:53:6;;;;;:::i;:::-;;;;;;;;;;;;;;430:21:3;;;;;;;;;;;;;:::i;7045:274:1:-;;;;;;;;;;-1:-1:-1;7045:274:1;;;;;:::i;:::-;;:::i;1846:101:9:-;;;;;;;;;;;;;:::i;736:112:6:-;;;;;;;;;;-1:-1:-1;736:112:6;;;;;:::i;:::-;799:4;822:14;;;:9;:14;;;;;;:19;;736:112;5702:104:3;;;;;;;;;;-1:-1:-1;5702:104:3;;;;;:::i;:::-;;:::i;8351:211::-;;;;;;;;;;;;;:::i;690:53::-;;;;;;;;;;-1:-1:-1;690:53:3;;;;;:::i;:::-;;;;;;;;;;;;;;1216:85:9;;;;;;;;;;-1:-1:-1;1262:7:9;1288:6;-1:-1:-1;;;;;1288:6:9;1216:85;;2203:161:2;;;;;;;;;;-1:-1:-1;2203:161:2;;;;;:::i;:::-;;:::i;10368:102:1:-;;;;;;;;;;;;;:::i;750:20:3:-;;;;;;;;;;-1:-1:-1;750:20:3;;;;;;;;4416:98;;;;;;;;;;-1:-1:-1;4416:98:3;;;;;:::i;:::-;;:::i;17503:259:1:-;;;;;;;;;;-1:-1:-1;17503:259:1;;;;;:::i;:::-;;:::i;6943:447:3:-;;;;;;;;;;-1:-1:-1;6943:447:3;;;;;:::i;:::-;;:::i;854:316:6:-;;;;;;;;;;-1:-1:-1;854:316:6;;;;;:::i;:::-;;:::i;227:57::-;;;;;;;;;;-1:-1:-1;227:57:6;;;;;:::i;:::-;;;;;;;;;;;;;;;;6595:342:3;;;;;;:::i;:::-;;:::i;4520:292::-;;;;;;;;;;-1:-1:-1;4520:292:3;;;;;:::i;:::-;;:::i;458:23::-;;;;;;;;;;-1:-1:-1;458:23:3;;;;;;;;;;;;;;;:::i;620:32::-;;;;;;;;;;;;;;;;8171:77;;;;;;;;;;-1:-1:-1;8171:77:3;;;;;:::i;:::-;;:::i;17912:206:1:-;;;;;;;;;;-1:-1:-1;17912:206:1;;;;;:::i;:::-;-1:-1:-1;;;;;18076:25:1;;;18049:4;18076:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;17912:206;5285:118:3;;;;;;;;;;-1:-1:-1;5285:118:3;;;;;:::i;:::-;;:::i;2096:232:9:-;;;;;;;;;;-1:-1:-1;2096:232:9;;;;;:::i;:::-;;:::i;1518:733:3:-;;;;;;;;;;-1:-1:-1;1518:733:3;;;;;:::i;:::-;;:::i;4317:93::-;;;;;;;;;;-1:-1:-1;4317:93:3;;;;;:::i;:::-;;:::i;7831:334::-;;;;;;;;;;-1:-1:-1;7831:334:3;;;;;:::i;:::-;;:::i;1099:271:2:-;1234:4;-1:-1:-1;;;;;;1273:37:2;;1289:21;1273:37;;:90;;;1326:37;1350:12;1326:23;:37::i;:::-;1254:109;1099:271;-1:-1:-1;;1099:271:2:o;4038:273:3:-;1109:13:9;:11;:13::i;:::-;4139:11:3::1;4125;::::0;::::1;;:25;::::0;::::1;;;;;;:::i;:::-;;4117:71;;;::::0;-1:-1:-1;;;4117:71:3;;10665:2:11;4117:71:3::1;::::0;::::1;10647:21:11::0;10704:2;10684:18;;;10677:30;10743:34;10723:18;;;10716:62;10814:3;10794:18;;;10787:31;10835:19;;4117:71:3::1;;;;;;;;;6164:12:1::0;;6148:13;;526:4:3::1;::::0;4222:9;;6148:28:1;-1:-1:-1;;6148:46:1;4206:25:3::1;;;;:::i;:::-;:39;;4198:71;;;::::0;-1:-1:-1;;;4198:71:3;;11389:2:11;4198:71:3::1;::::0;::::1;11371:21:11::0;11428:2;11408:18;;;11401:30;11467:21;11447:18;;;11440:49;11506:18;;4198:71:3::1;11187:343:11::0;4198:71:3::1;4279:25;4289:3;4294:9;4279;:25::i;:::-;4038:273:::0;;:::o;10199:98:1:-;10253:13;10285:5;10278:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10199:98;:::o;16918:258::-;17034:7;17062:16;17070:7;17062;:16::i;:::-;17057:64;;17087:34;;;;;;;;;;;;;;17057:64;-1:-1:-1;17139:24:1;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;17139:30:1;;16918:258::o;16334:434::-;16458:13;16474:16;16482:7;16474;:16::i;:::-;16458:32;-1:-1:-1;41055:10:1;-1:-1:-1;;;;;16505:28:1;;;16501:172;;16552:44;16569:5;41055:10;17912:206;:::i;16552:44::-;16547:126;;16623:35;;;;;;;;;;;;;;16547:126;16683:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;16683:35:1;-1:-1:-1;;;;;16683:35:1;;;;;;;;;16733:28;;16683:24;;16733:28;;;;;;;16448:320;16334:434;;:::o;3576:456:3:-;1436:9;1449:10;1436:23;1428:66;;;;-1:-1:-1;;;1428:66:3;;12179:2:11;1428:66:3;;;12161:21:11;12218:2;12198:18;;;12191:30;12257:32;12237:18;;;12230:60;12307:18;;1428:66:3;11977:354:11;1428:66:3;3647:11:::1;3632;::::0;::::1;;:26;::::0;::::1;;;;;;:::i;:::-;;;3624:67;;;::::0;-1:-1:-1;;;3624:67:3;;12538:2:11;3624:67:3::1;::::0;::::1;12520:21:11::0;12577:2;12557:18;;;12550:30;12616;12596:18;;;12589:58;12664:18;;3624:67:3::1;12336:352:11::0;3624:67:3::1;3741:10;3722:30;::::0;;;:18:::1;:30;::::0;;;;;3760:1:::1;::::0;3722:34:::1;::::0;3760:1;3722:34:::1;:::i;:::-;:39;;3701:127;;;::::0;-1:-1:-1;;;3701:127:3;;12895:2:11;3701:127:3::1;::::0;::::1;12877:21:11::0;12934:2;12914:18;;;12907:30;12973:34;12953:18;;;12946:62;13044:11;13024:18;;;13017:39;13073:19;;3701:127:3::1;12693:405:11::0;3701:127:3::1;6164:12:1::0;;6148:13;;576:4:3::1;::::0;6148:28:1;;-1:-1:-1;;6148:46:1;3859:17:3::1;::::0;3875:1:::1;3859:17;:::i;:::-;:33;;3838:108;;;::::0;-1:-1:-1;;;3838:108:3;;13305:2:11;3838:108:3::1;::::0;::::1;13287:21:11::0;13344:2;13324:18;;;13317:30;13383;13363:18;;;13356:58;13431:18;;3838:108:3::1;13103:352:11::0;3838:108:3::1;3975:10;3956:30;::::0;;;:18:::1;:30;::::0;;;;:35;;3990:1:::1;::::0;3956:30;:35:::1;::::0;3990:1;;3956:35:::1;:::i;:::-;::::0;;;-1:-1:-1;4001:24:3::1;::::0;-1:-1:-1;4011:10:3::1;4023:1;4001:9;:24::i;:::-;3576:456::o:0;6290:299::-;6449:27;;;;:18;:27;;;;;;:32;6428:107;;;;-1:-1:-1;;;6428:107:3;;13662:2:11;6428:107:3;;;13644:21:11;13701:2;13681:18;;;13674:30;13740;13720:18;;;13713:58;13788:18;;6428:107:3;13460:352:11;6428:107:3;6545:37;6564:4;6570:2;6574:7;6545:18;:37::i;:::-;6290:299;;;:::o;2257:703::-;1436:9;1449:10;1436:23;1428:66;;;;-1:-1:-1;;;1428:66:3;;12179:2:11;1428:66:3;;;12161:21:11;12218:2;12198:18;;;12191:30;12257:32;12237:18;;;12230:60;12307:18;;1428:66:3;11977:354:11;1428:66:3;2402:21:::1;2387:11;::::0;::::1;;:36;::::0;::::1;;;;;;:::i;:::-;;;2366:122;;;::::0;-1:-1:-1;;;2366:122:3;;14019:2:11;2366:122:3::1;::::0;::::1;14001:21:11::0;14058:2;14038:18;;;14031:30;14097:34;14077:18;;;14070:62;14168:9;14148:18;;;14141:37;14195:19;;2366:122:3::1;13817:403:11::0;2366:122:3::1;2519:40;2540:10;2552:6;;2519:20;:40::i;:::-;2498:110;;;::::0;-1:-1:-1;;;2498:110:3;;14427:2:11;2498:110:3::1;::::0;::::1;14409:21:11::0;14466:2;14446:18;;;14439:30;14505:25;14485:18;;;14478:53;14548:18;;2498:110:3::1;14225:347:11::0;2498:110:3::1;2658:10;2639:30;::::0;;;:18:::1;:30;::::0;;;;;2677:1:::1;::::0;2639:34:::1;::::0;2677:1;2639:34:::1;:::i;:::-;:39;;2618:138;;;::::0;-1:-1:-1;;;2618:138:3;;14779:2:11;2618:138:3::1;::::0;::::1;14761:21:11::0;14818:2;14798:18;;;14791:30;14857:34;14837:18;;;14830:62;14928:22;14908:18;;;14901:50;14968:19;;2618:138:3::1;14577:416:11::0;2618:138:3::1;6164:12:1::0;;6148:13;;576:4:3::1;::::0;6148:28:1;;-1:-1:-1;;6148:46:1;2787:17:3::1;::::0;2803:1:::1;2787:17;:::i;:::-;:33;;2766:108;;;::::0;-1:-1:-1;;;2766:108:3;;13305:2:11;2766:108:3::1;::::0;::::1;13287:21:11::0;13344:2;13324:18;;;13317:30;13383;13363:18;;;13356:58;13431:18;;2766:108:3::1;13103:352:11::0;2766:108:3::1;2903:10;2884:30;::::0;;;:18:::1;:30;::::0;;;;:35;;2918:1:::1;::::0;2884:30;:35:::1;::::0;2918:1;;2884:35:::1;:::i;:::-;::::0;;;-1:-1:-1;2929:24:3::1;::::0;-1:-1:-1;2939:10:3::1;2951:1;2929:9;:24::i;4848:108::-:0;1109:13:9;:11;:13::i;:::-;4923:12:3::1;:26:::0;4848:108::o;1925:131:2:-;1998:12;2006:3;1998:7;:12::i;:::-;1990:37;;;;-1:-1:-1;;;1990:37:2;;15200:2:11;1990:37:2;;;15182:21:11;15239:2;15219:18;;;15212:30;-1:-1:-1;;;15258:18:11;;;15251:42;15310:18;;1990:37:2;14998:336:11;1990:37:2;2037:12;2045:3;2037:7;:12::i;:::-;1925:131;:::o;7396:429:3:-;7482:16;7490:7;7482;:16::i;:::-;-1:-1:-1;;;;;7468:30:3;:10;-1:-1:-1;;;;;7468:30:3;;:55;;;-1:-1:-1;1262:7:9;1288:6;-1:-1:-1;;;;;1288:6:9;7502:10:3;:21;7468:55;7447:149;;;;-1:-1:-1;;;7447:149:3;;15541:2:11;7447:149:3;;;15523:21:11;15580:2;15560:18;;;15553:30;15619:34;15599:18;;;15592:62;15690:17;15670:18;;;15663:45;15725:19;;7447:149:3;15339:411:11;7447:149:3;7644:1;7614:27;;;:18;:27;;;;;;7606:55;;;;-1:-1:-1;;;7606:55:3;;15957:2:11;7606:55:3;;;15939:21:11;15996:2;15976:18;;;15969:30;16035:13;16015:18;;;16008:41;16066:18;;7606:55:3;15755:335:11;7606:55:3;7671:11;7685:27;;;:18;:27;;;;;;;;;;7722:31;;;7768:50;;16326:25:11;;;7785:10:3;16367:18:11;;;16360:83;;;;7797:15:3;16459:18:11;;;16452:34;16517:2;16502:18;;16495:34;;;7768:50:3;;;;;;16313:3:11;7768:50:3;;;7437:388;7396:429;:::o;2966:604::-;1436:9;1449:10;1436:23;1428:66;;;;-1:-1:-1;;;1428:66:3;;12179:2:11;1428:66:3;;;12161:21:11;12218:2;12198:18;;;12191:30;12257:32;12237:18;;;12230:60;12307:18;;1428:66:3;11977:354:11;1428:66:3;3084:14:::1;3069:11;::::0;::::1;;:29;::::0;::::1;;;;;;:::i;:::-;;;3048:107;;;::::0;-1:-1:-1;;;3048:107:3;;16742:2:11;3048:107:3::1;::::0;::::1;16724:21:11::0;16781:2;16761:18;;;16754:30;16820:33;16800:18;;;16793:61;16871:18;;3048:107:3::1;16540:355:11::0;3048:107:3::1;3173:33;3187:10;3199:6;;3173:13;:33::i;:::-;3165:61;;;::::0;-1:-1:-1;;;3165:61:3;;17102:2:11;3165:61:3::1;::::0;::::1;17084:21:11::0;17141:2;17121:18;;;17114:30;17180:17;17160:18;;;17153:45;17215:18;;3165:61:3::1;16900:339:11::0;3165:61:3::1;3276:10;3257:30;::::0;;;:18:::1;:30;::::0;;;;;3295:1:::1;::::0;3257:34:::1;::::0;3295:1;3257:34:::1;:::i;:::-;:39;;3236:130;;;::::0;-1:-1:-1;;;3236:130:3;;17446:2:11;3236:130:3::1;::::0;::::1;17428:21:11::0;17485:2;17465:18;;;17458:30;17524:34;17504:18;;;17497:62;17595:14;17575:18;;;17568:42;17627:19;;3236:130:3::1;17244:408:11::0;3236:130:3::1;6164:12:1::0;;6148:13;;576:4:3::1;::::0;6148:28:1;;-1:-1:-1;;6148:46:1;3397:17:3::1;::::0;3413:1:::1;3397:17;:::i;:::-;:33;;3376:108;;;::::0;-1:-1:-1;;;3376:108:3;;13305:2:11;3376:108:3::1;::::0;::::1;13287:21:11::0;13344:2;13324:18;;;13317:30;13383;13363:18;;;13356:58;13431:18;;3376:108:3::1;13103:352:11::0;3376:108:3::1;3513:10;3494:30;::::0;;;:18:::1;:30;::::0;;;;:35;;3528:1:::1;::::0;3494:30;:35:::1;::::0;3528:1;;3494:35:::1;:::i;:::-;::::0;;;-1:-1:-1;3539:24:3::1;::::0;-1:-1:-1;3549:10:3::1;3561:1;3539:9;:24::i;2062:135:2:-:0;2137:12;2145:3;2137:7;:12::i;:::-;2129:37;;;;-1:-1:-1;;;2129:37:2;;15200:2:11;2129:37:2;;;15182:21:11;15239:2;15219:18;;;15212:30;-1:-1:-1;;;15258:18:11;;;15251:42;15310:18;;2129:37:2;14998:336:11;2129:37:2;2176:14;2186:3;2176:9;:14::i;23598:187:1:-;23739:39;23756:4;23762:2;23766:7;23739:39;;;;;;;;;;;;:16;:39::i;11639:194::-;11751:7;11797:27;11816:7;11797:18;:27::i;430:21:3:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7045:274:1:-;7157:7;-1:-1:-1;;;;;7184:19:1;;7180:60;;7212:28;;;;;;;;;;;;;;7180:60;-1:-1:-1;;;;;;7257:25:1;;;;;:18;:25;;;;;;1360:13;7257:55;;7045:274::o;1846:101:9:-;1109:13;:11;:13::i;:::-;1910:30:::1;1937:1;1910:18;:30::i;5702:104:3:-:0;1109:13:9;:11;:13::i;:::-;5775:10:3::1;:24:::0;5702:104::o;8351:211::-;1109:13:9;:11;:13::i;:::-;8421:21:3::1;8460:11:::0;8452:52:::1;;;::::0;-1:-1:-1;;;8452:52:3;;17859:2:11;8452:52:3::1;::::0;::::1;17841:21:11::0;17898:2;17878:18;;;17871:30;17937;17917:18;;;17910:58;17985:18;;8452:52:3::1;17657:352:11::0;8452:52:3::1;8514:41;8524:7;1262::9::0;1288:6;-1:-1:-1;;;;;1288:6:9;;1216:85;8524:7:3::1;8533:21;8514:9;:41::i;2203:161:2:-:0;2295:12;2303:3;2295:7;:12::i;:::-;2287:37;;;;-1:-1:-1;;;2287:37:2;;15200:2:11;2287:37:2;;;15182:21:11;15239:2;15219:18;;;15212:30;-1:-1:-1;;;15258:18:11;;;15251:42;15310:18;;2287:37:2;14998:336:11;2287:37:2;2334:23;2342:3;2347:9;2334:7;:23::i;10368:102:1:-;10424:13;10456:7;10449:14;;;;;:::i;4416:98:3:-;1109:13:9;:11;:13::i;:::-;4489:18:3;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;17503:259:1:-:0;41055:10;17625:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;17625:49:1;;;;;;;;;;;;:60;;-1:-1:-1;;17625:60:1;;;;;;;;;;17700:55;;586:41:11;;;17625:49:1;;41055:10;17700:55;;559:18:11;17700:55:1;;;;;;;17503:259;;:::o;6943:447:3:-;7000:8;;;;6992:37;;;;-1:-1:-1;;;6992:37:3;;18216:2:11;6992:37:3;;;18198:21:11;18255:2;18235:18;;;18228:30;18294:18;18274;;;18267:46;18330:18;;6992:37:3;18014:340:11;6992:37:3;7074:16;7082:7;7074;:16::i;:::-;-1:-1:-1;;;;;7060:30:3;:10;-1:-1:-1;;;;;7060:30:3;;:55;;;-1:-1:-1;1262:7:9;1288:6;-1:-1:-1;;;;;1288:6:9;7094:10:3;:21;7060:55;7039:149;;;;-1:-1:-1;;;7039:149:3;;15541:2:11;7039:149:3;;;15523:21:11;15580:2;15560:18;;;15553:30;15619:34;15599:18;;;15592:62;15690:17;15670:18;;;15663:45;15725:19;;7039:149:3;15339:411:11;7039:149:3;7206:27;;;;:18;:27;;;;;;:32;7198:60;;;;-1:-1:-1;;;7198:60:3;;18561:2:11;7198:60:3;;;18543:21:11;18600:2;18580:18;;;18573:30;18639:17;18619:18;;;18612:45;18674:18;;7198:60:3;18359:339:11;7198:60:3;7268:27;;;;:18;:27;;;;;;;;;7298:15;7268:45;;;;7328:55;;18905:25:11;;;7343:10:3;18946:18:11;;;18939:83;;;;19038:18;;;19031:34;7328:55:3;;;;;;;18893:2:11;7328:55:3;;;6943:447;:::o;854:316:6:-;1109:13:9;:11;:13::i;:::-;1002:35:6;;::::1;994:55;;;::::0;-1:-1:-1;;;994:55:6;;19278:2:11;994:55:6::1;::::0;::::1;19260:21:11::0;19317:1;19297:18;;;19290:29;19355:9;19335:18;;;19328:37;19382:18;;994:55:6::1;19076:330:11::0;994:55:6::1;1064:9;1059:104;1079:21:::0;;::::1;1059:104;;;1153:7;;1161:1;1153:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;1119:16;:31;1136:10;;1147:1;1136:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;1119:31:6::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;1119:31:6;:44;;-1:-1:-1;;1119:44:6::1;::::0;::::1;;::::0;;;::::1;::::0;;1102:3;::::1;::::0;::::1;:::i;:::-;;;;1059:104;;;;854:316:::0;;;;:::o;6595:342:3:-;6786:27;;;;:18;:27;;;;;;:32;6765:107;;;;-1:-1:-1;;;6765:107:3;;13662:2:11;6765:107:3;;;13644:21:11;13701:2;13681:18;;;13674:30;13740;13720:18;;;13713:58;13788:18;;6765:107:3;13460:352:11;6765:107:3;6882:48;6905:4;6911:2;6915:7;6924:5;6882:22;:48::i;:::-;6595:342;;;;:::o;4520:292::-;4634:13;4671:17;4679:8;4671:7;:17::i;:::-;4663:61;;;;-1:-1:-1;;;4663:61:3;;19942:2:11;4663:61:3;;;19924:21:11;19981:2;19961:18;;;19954:30;20020:33;20000:18;;;19993:61;20071:18;;4663:61:3;19740:355:11;4663:61:3;4766:7;4775:19;:8;:17;:19::i;:::-;4749:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4735:70;;4520:292;;;:::o;8171:77::-;1109:13:9;:11;:13::i;:::-;8229:8:3::1;:12:::0;;-1:-1:-1;;8229:12:3::1;::::0;::::1;;::::0;;;::::1;::::0;;8171:77::o;5285:118::-;1109:13:9;:11;:13::i;:::-;5365:17:3::1;:31:::0;5285:118::o;2096:232:9:-;1109:13;:11;:13::i;:::-;-1:-1:-1;;;;;2197:22:9;::::1;2176:107;;;::::0;-1:-1:-1;;;2176:107:9;;22099:2:11;2176:107:9::1;::::0;::::1;22081:21:11::0;22138:2;22118:18;;;22111:30;22177:34;22157:18;;;22150:62;22248:8;22228:18;;;22221:36;22274:19;;2176:107:9::1;21897:402:11::0;2176:107:9::1;2293:28;2312:8;2293:18;:28::i;1518:733:3:-:0;1436:9;1449:10;1436:23;1428:66;;;;-1:-1:-1;;;1428:66:3;;12179:2:11;1428:66:3;;;12161:21:11;12218:2;12198:18;;;12191:30;12257:32;12237:18;;;12230:60;12307:18;;1428:66:3;11977:354:11;1428:66:3;1677:16:::1;1662:11;::::0;::::1;;:31;::::0;::::1;;;;;;:::i;:::-;;;1641:109;;;::::0;-1:-1:-1;;;1641:109:3;;16742:2:11;1641:109:3::1;::::0;::::1;16724:21:11::0;16781:2;16761:18;;;16754:30;16820:33;16800:18;;;16793:61;16871:18;;1641:109:3::1;16540:355:11::0;1641:109:3::1;1781:46;1797:10;1809:9;1820:6;;1781:15;:46::i;:::-;1760:111;;;::::0;-1:-1:-1;;;1760:111:3;;22506:2:11;1760:111:3::1;::::0;::::1;22488:21:11::0;22545:2;22525:18;;;22518:30;22584:20;22564:18;;;22557:48;22622:18;;1760:111:3::1;22304:342:11::0;1760:111:3::1;1921:10;1902:30;::::0;;;:18:::1;:30;::::0;;;;;1948:9;;1902:42:::1;::::0;1948:9;;1902:42:::1;:::i;:::-;:55;;1881:142;;;::::0;-1:-1:-1;;;1881:142:3;;22853:2:11;1881:142:3::1;::::0;::::1;22835:21:11::0;22892:2;22872:18;;;22865:30;22931:34;22911:18;;;22904:62;23002:10;22982:18;;;22975:38;23030:19;;1881:142:3::1;22651:404:11::0;1881:142:3::1;6164:12:1::0;;6148:13;;576:4:3::1;::::0;2070:9;;6148:28:1;-1:-1:-1;;6148:46:1;2054:25:3::1;;;;:::i;:::-;:41;;2033:116;;;::::0;-1:-1:-1;;;2033:116:3;;13305:2:11;2033:116:3::1;::::0;::::1;13287:21:11::0;13344:2;13324:18;;;13317:30;13383;13363:18;;;13356:58;13431:18;;2033:116:3::1;13103:352:11::0;2033:116:3::1;2178:10;2159:30;::::0;;;:18:::1;:30;::::0;;;;:43;;2193:9;;2159:30;:43:::1;::::0;2193:9;;2159:43:::1;:::i;:::-;::::0;;;-1:-1:-1;2212:32:3::1;::::0;-1:-1:-1;2222:10:3::1;2234:9:::0;2212::::1;:32::i;4317:93::-:0;1109:13:9;:11;:13::i;:::-;4397:5:3::1;4392:11;;;;;;;;:::i;:::-;4378;:25:::0;;-1:-1:-1;;4378:25:3::1;::::0;;::::1;::::0;::::1;;;;;;:::i;:::-;;;;;;4317:93:::0;:::o;7831:334::-;7939:9;7934:225;7954:8;:15;7950:1;:19;7934:225;;;7990:15;8008:8;8017:1;8008:11;;;;;;;;:::i;:::-;;;;;;;7990:29;;8037:8;8033:116;;;8065:14;8071:7;8065:5;:14::i;:::-;8033:116;;;8118:16;8126:7;8118;:16::i;:::-;-1:-1:-1;7971:3:3;;;;:::i;:::-;;;;7934:225;;9271:674:1;9396:4;9718:25;-1:-1:-1;;;;;;9718:25:1;;;;:101;;-1:-1:-1;9794:25:1;-1:-1:-1;;;;;;9794:25:1;;;9718:101;:177;;;-1:-1:-1;;;;;;;;9870:25:1;;;;9271:674::o;1374:130:9:-;1262:7;1288:6;-1:-1:-1;;;;;1288:6:9;41055:10:1;1437:23:9;1429:68;;;;-1:-1:-1;;;1429:68:9;;23262:2:11;1429:68:9;;;23244:21:11;;;23281:18;;;23274:30;23340:34;23320:18;;;23313:62;23392:18;;1429:68:9;23060:356:11;34749:110:1;34825:27;34835:2;34839:8;34825:27;;;;;;;;;;;;:9;:27::i;18367:277::-;18432:4;18486:7;8337:1:3;18467:26:1;;:65;;;;;18519:13;;18509:7;:23;18467:65;:151;;;;-1:-1:-1;;18569:26:1;;;;:17;:26;;;;;;-1:-1:-1;;;18569:44:1;:49;;18367:277::o;1376:247:2:-;799:4:6;822:14;;;:9;:14;;;;;;:19;1516:48:2;;;;-1:-1:-1;;;1516:48:2;;23623:2:11;1516:48:2;;;23605:21:11;23662:2;23642:18;;;23635:30;23701:17;23681:18;;;23674:45;23736:18;;1516:48:2;23421:339:11;1516:48:2;1574:42;1595:5;1602:3;1607:8;1574:20;:42::i;5409:260:3:-;5577:26;;-1:-1:-1;;23914:2:11;23910:15;;;23906:88;5577:26:3;;;23894:101:11;5531:4:3;;;;24011:12:11;;5577:26:3;;;;;;;;;;;;5567:37;;;;;;5551:53;;5621:41;5629:5;5636:17;;5655:6;;5621:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5621:7:3;;-1:-1:-1;;;5621:41:3:i;:::-;5614:48;5409:260;-1:-1:-1;;;;;5409:260:3:o;1176:435:6:-;1250:10;1233:28;;;;:16;:28;;;;;;;;1225:58;;;;-1:-1:-1;;;1225:58:6;;24236:2:11;1225:58:6;;;24218:21:11;24275:2;24255:18;;;24248:30;24314:19;24294:18;;;24287:47;24351:18;;1225:58:6;24034:341:11;1225:58:6;1314:17;;;;:12;:17;;;;;;;;1332:10;1314:29;;;;;;;;:34;1293:108;;;;-1:-1:-1;;;1293:108:6;;24582:2:11;1293:108:6;;;24564:21:11;24621:2;24601:18;;;24594:30;24660:29;24640:18;;;24633:57;24707:18;;1293:108:6;24380:351:11;1293:108:6;1412:13;1428:14;;;:9;:14;;;;;;:18;;1445:1;1428:18;:::i;:::-;1456:12;;;;:7;:12;;;;;;;;:19;;;;;;;;:32;;-1:-1:-1;;;;;;1456:32:6;1478:10;1456:32;;;;;;1498:17;;;:12;:17;;;;;:29;;;;;;;;:37;;;1545:14;;;:9;:14;;;;;:16;;1412:34;;-1:-1:-1;1545:14:6;:16;;;:::i;:::-;;;;-1:-1:-1;;1576:28:6;;1593:10;;1588:3;;1576:28;;;;;1215:396;1176:435;:::o;5812:246:3:-;5973:26;;-1:-1:-1;;23914:2:11;23910:15;;;23906:88;5973:26:3;;;23894:101:11;5927:4:3;;;;24011:12:11;;5973:26:3;;;;;;;;;;;;5963:37;;;;;;5947:53;;6017:34;6025:5;6032:10;;6044:6;;6017:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6017:7:3;;-1:-1:-1;;;6017:34:3:i;1617:660:6:-;1693:10;1676:28;;;;:16;:28;;;;;;;;1668:58;;;;-1:-1:-1;;;1668:58:6;;24236:2:11;1668:58:6;;;24218:21:11;24275:2;24255:18;;;24248:30;24314:19;24294:18;;;24287:47;24351:18;;1668:58:6;24034:341:11;1668:58:6;1736:13;1752:17;;;:12;:17;;;;;;;;1770:10;1752:29;;;;;;;;1799:10;1791:46;;;;-1:-1:-1;;;1791:46:6;;24938:2:11;1791:46:6;;;24920:21:11;24977:2;24957:18;;;24950:30;25016:25;24996:18;;;24989:53;25059:18;;1791:46:6;24736:347:11;1791:46:6;1848:12;1863:14;;;:9;:14;;;;;;1891:13;;;1887:269;;1920:20;1943:12;;;:7;:12;;;;;;;;:18;;;;;;;;;;1975:19;;;;;;:34;;-1:-1:-1;;;;;;1975:34:6;;;-1:-1:-1;;;;;1943:18:6;;;1975:34;;;;;;2023:31;;;;;;2068:17;;;:12;:17;;;;;:31;;;;;;;;:39;;;1887:269;;;2154:1;2124:12;;;:7;:12;;;;;;;;:19;;;;;;;;:32;;-1:-1:-1;;;;;;2124:32:6;;;1887:269;2198:1;2166:17;;;:12;:17;;;;;;;;2184:10;2166:29;;;;;;;:33;;;2209:14;;;:9;:14;;;;;:16;;;;;;:::i;:::-;;;;-1:-1:-1;;2240:30:6;;2259:10;;2254:3;;2240:30;;;;;1658:619;;1617:660;:::o;12879:1277:1:-;12970:7;13008;;8337:1:3;13054:23:1;13050:1042;;13106:13;;13099:4;:20;13095:997;;;13143:14;13160:23;;;:17;:23;;;;;;-1:-1:-1;;;13247:24:1;;13243:831;;13902:111;13909:11;13902:111;;-1:-1:-1;;;13979:6:1;13961:25;;;;:17;:25;;;;;;13902:111;;;14045:6;12879:1277;-1:-1:-1;;;12879:1277:1:o;13243:831::-;13121:971;13095:997;14118:31;;;;;;;;;;;;;;2482:187:9;2555:16;2574:6;;-1:-1:-1;;;;;2590:17:9;;;-1:-1:-1;;;;;;2590:17:9;;;;;;2622:40;;2574:6;;;;;;;2622:40;;2555:16;2622:40;2545:124;2482:187;:::o;8568:179:3:-;8641:12;8659:8;-1:-1:-1;;;;;8659:13:3;8680:7;8659:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8640:52;;;8710:7;8702:38;;;;-1:-1:-1;;;8702:38:3;;25641:2:11;8702:38:3;;;25623:21:11;25680:2;25660:18;;;25653:30;25719:20;25699:18;;;25692:48;25757:18;;8702:38:3;25439:342:11;2283:664:6;-1:-1:-1;;;;;2360:27:6;;;;;;:16;:27;;;;;;;;2359:28;2351:58;;;;-1:-1:-1;;;2351:58:6;;24236:2:11;2351:58:6;;;24218:21:11;24275:2;24255:18;;;24248:30;24314:19;24294:18;;;24287:47;24351:18;;2351:58:6;24034:341:11;2351:58:6;2419:13;2435:17;;;:12;:17;;;;;;;;-1:-1:-1;;;;;2435:28:6;;;;;;;;;;2481:10;2473:36;;;;-1:-1:-1;;;2473:36:6;;25988:2:11;2473:36:6;;;25970:21:11;26027:2;26007:18;;;26000:30;26066:15;26046:18;;;26039:43;26099:18;;2473:36:6;25786:337:11;2473:36:6;2520:12;2535:14;;;:9;:14;;;;;;2563:13;;;2559:269;;2592:20;2615:12;;;:7;:12;;;;;;;;:18;;;;;;;;;;2647:19;;;;;;:34;;-1:-1:-1;;;;;;2647:34:6;;;-1:-1:-1;;;;;2615:18:6;;;2647:34;;;;;;2695:31;;;;;;2740:17;;;:12;:17;;;;;:31;;;;;;;;:39;;;2559:269;;;2826:1;2796:12;;;:7;:12;;;;;;;;:19;;;;;;;;:32;;-1:-1:-1;;;;;;2796:32:6;;;2559:269;2869:1;2838:17;;;:12;:17;;;;;;;;-1:-1:-1;;;;;2838:28:6;;;;;;;;;:32;;;2880:14;;;:9;:14;;;;;:16;;;;;;:::i;:::-;;;;-1:-1:-1;;2911:29:6;;-1:-1:-1;;;;;2911:29:6;;;2925:3;;2911:29;;;;;2341:606;;2283:664;;:::o;1629:290:2:-;799:4:6;822:14;;;:9;:14;;;;;;:19;1801:48:2;;;;-1:-1:-1;;;1801:48:2;;23623:2:11;1801:48:2;;;23605:21:11;23662:2;23642:18;;;23635:30;23701:17;23681:18;;;23674:45;23736:18;;1801:48:2;23421:339:11;1801:48:2;1859:53;1884:5;1891:3;1896:8;1906:5;1859:24;:53::i;410:696:10:-;466:13;515:14;532:17;543:5;532:10;:17::i;:::-;552:1;532:21;515:38;;567:20;601:6;590:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;590:18:10;-1:-1:-1;567:41:10;-1:-1:-1;728:28:10;;;744:2;728:28;783:280;-1:-1:-1;;814:5:10;953:8;948:2;937:14;;932:30;814:5;919:44;1007:2;998:11;;;-1:-1:-1;1031:10:10;1027:21;;1043:5;;1027:21;783:280;;;-1:-1:-1;1083:6:10;410:696;-1:-1:-1;;;410:696:10:o;4962:282:3:-;5146:37;;-1:-1:-1;;26494:2:11;26490:15;;;26486:88;5146:37:3;;;26474:101:11;26591:12;;;26584:28;;;5104:4:3;;;;26628:12:11;;5146:37:3;;;;;;;;;;;;5136:48;;;;;;5120:64;;5201:36;5209:5;5216:12;;5230:6;;5201:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5201:7:3;;-1:-1:-1;;;5201:36:3:i;:::-;5194:43;;;4962:282;;;;;;;:::o;33817:853:1:-;33943:19;33949:2;33953:8;33943:5;:19::i;:::-;-1:-1:-1;;;;;34001:14:1;;;:19;33997:657;;34054:13;;34101:14;;;34133:413;34188:200;34256:1;34288:2;34320:7;;;;;;34357:5;34188:30;:200::i;:::-;34158:349;;34444:40;;-1:-1:-1;;;34444:40:1;;;;;;;;;;;34158:349;34541:3;34533:5;:11;34133:413;;34626:3;34609:13;;:20;34605:34;;34631:8;;;20577:2930;20714:27;20744;20763:7;20744:18;:27::i;:::-;20714:57;;20827:4;-1:-1:-1;;;;;20786:45:1;20802:19;-1:-1:-1;;;;;20786:45:1;;20782:98;;20852:28;;;;;;;;;;;;;;20782:98;20905:27;19710:24;;;:15;:24;;;;;19934:26;;41055:10;19347:30;;;-1:-1:-1;;;;;19044:28:1;;19325:20;;;19322:56;21109:279;;21285:43;21302:4;41055:10;17912:206;:::i;21285:43::-;21280:108;;21353:35;;;;;;;;;;;;;;21280:108;-1:-1:-1;;;;;21403:16:1;;21399:52;;21428:23;;;;;;;;;;;;;;21399:52;21594:15;21591:157;;;21732:1;21711:19;21704:30;21591:157;-1:-1:-1;;;;;22120:24:1;;;;;;;:18;:24;;;;;;22118:26;;-1:-1:-1;;22118:26:1;;;22188:22;;;;;;;;;22186:24;;-1:-1:-1;22186:24:1;;;15184:11;15159:23;15155:41;15109:109;-1:-1:-1;;;15109:109:1;22474:26;;;;:17;:26;;;;;:192;-1:-1:-1;;;22783:47:1;;22779:617;;22887:1;22877:11;;22855:19;23008:30;;;:17;:30;;;;;;23004:378;;23144:13;;23129:11;:28;23125:239;;23289:30;;;;:17;:30;;;;;:52;;;23125:239;22837:559;22779:617;23440:7;23436:2;-1:-1:-1;;;;;23421:27:1;23430:4;-1:-1:-1;;;;;23421:27:1;;;;;;;;;;;20704:2803;;;20577:2930;;;:::o;6064:195:3:-;6189:4;6212:40;6231:6;6239:5;6246;6212:18;:40::i;24366:396:1:-;24535:31;24548:4;24554:2;24558:7;24535:12;:31::i;:::-;-1:-1:-1;;;;;24580:14:1;;;:19;24576:180;;24618:56;24649:4;24655:2;24659:7;24668:5;24618:30;:56::i;:::-;24613:143;;24701:40;;-1:-1:-1;;;24701:40:1;;;;;;;;;;;10009:890:7;10062:7;;10146:6;10137:15;;10133:99;;10181:6;10172:15;;;-1:-1:-1;10215:2:7;10205:12;10133:99;10258:6;10249:5;:15;10245:99;;10293:6;10284:15;;;-1:-1:-1;10327:2:7;10317:12;10245:99;10370:6;10361:5;:15;10357:99;;10405:6;10396:15;;;-1:-1:-1;10439:2:7;10429:12;10357:99;10482:5;10473;:14;10469:96;;10516:5;10507:14;;;-1:-1:-1;10549:1:7;10539:11;10469:96;10591:5;10582;:14;10578:96;;10625:5;10616:14;;;-1:-1:-1;10658:1:7;10648:11;10578:96;10700:5;10691;:14;10687:96;;10734:5;10725:14;;;-1:-1:-1;10767:1:7;10757:11;10687:96;10809:5;10800;:14;10796:64;;10844:1;10834:11;10886:6;10009:890;-1:-1:-1;;10009:890:7:o;28039:2954:1:-;28134:13;;28161;28157:44;;28183:18;;;;;;;;;;;;;;28157:44;-1:-1:-1;;;;;28676:22:1;;;;;;:18;:22;;;;1495:2;28676:22;;;:103;;28746:32;28718:61;;28676:103;;;29015:31;;;:17;:31;;;;;-1:-1:-1;15645:15:1;;15619:24;15615:46;15184:11;15159:23;15155:41;15152:52;15109:109;;29015:190;;29264:23;;;;29015:31;;28676:22;;30016:25;28676:22;;29872:328;30520:1;30506:12;30502:20;30461:339;30560:3;30551:7;30548:16;30461:339;;30774:7;30764:8;30761:1;30734:25;30731:1;30728;30723:59;30612:1;30599:15;30461:339;;;-1:-1:-1;30831:13:1;30827:45;;30853:19;;;;;;;;;;;;;;30827:45;30887:13;:19;-1:-1:-1;6290:299:3;;;:::o;26788:805:1:-;26978:166;;-1:-1:-1;;;26978:166:1;;26946:4;;-1:-1:-1;;;;;26978:45:1;;;;;:166;;41055:10;;27078:4;;27100:7;;27125:5;;26978:166;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26978:166:1;;;;;;;;-1:-1:-1;;26978:166:1;;;;;;;;;;;;:::i;:::-;;;26962:625;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27352:13:1;;27348:229;;27397:40;;-1:-1:-1;;;27397:40:1;;;;;;;;;;;27348:229;27537:6;27531:13;27522:6;27518:2;27514:15;27507:38;26962:625;-1:-1:-1;;;;;;27214:80:1;-1:-1:-1;;;27214:80:1;;-1:-1:-1;27191:103:1;;1153:184:8;1274:4;1326;1297:25;1310:5;1317:4;1297:12;:25::i;:::-;:33;;1153:184;-1:-1:-1;;;;1153:184:8:o;1991:318::-;2098:7;2144:4;2098:7;2158:116;2182:5;:12;2178:1;:16;2158:116;;;2230:33;2240:12;2254:5;2260:1;2254:8;;;;;;;;:::i;:::-;;;;;;;2230:9;:33::i;:::-;2215:48;-1:-1:-1;2196:3:8;;;;:::i;:::-;;;;2158:116;;9128:147;9191:7;9221:1;9217;:5;:51;;9373:13;9468:15;;;9503:4;9496:15;;;9549:4;9533:21;;9217:51;;;-1:-1:-1;9373:13:8;9468:15;;;9503:4;9496:15;9549:4;9533:21;;;9128:147::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:177:11;-1:-1:-1;;;;;;92:5:11;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:196::-;706:20;;-1:-1:-1;;;;;755:54:11;;745:65;;735:93;;824:1;821;814:12;735:93;638:196;;;:::o;839:254::-;907:6;915;968:2;956:9;947:7;943:23;939:32;936:52;;;984:1;981;974:12;936:52;1007:29;1026:9;1007:29;:::i;:::-;997:39;1083:2;1068:18;;;;1055:32;;-1:-1:-1;;;839:254:11:o;1098:258::-;1170:1;1180:113;1194:6;1191:1;1188:13;1180:113;;;1270:11;;;1264:18;1251:11;;;1244:39;1216:2;1209:10;1180:113;;;1311:6;1308:1;1305:13;1302:48;;;-1:-1:-1;;1346:1:11;1328:16;;1321:27;1098:258::o;1361:269::-;1414:3;1452:5;1446:12;1479:6;1474:3;1467:19;1495:63;1551:6;1544:4;1539:3;1535:14;1528:4;1521:5;1517:16;1495:63;:::i;:::-;1612:2;1591:15;-1:-1:-1;;1587:29:11;1578:39;;;;1619:4;1574:50;;1361:269;-1:-1:-1;;1361:269:11:o;1635:231::-;1784:2;1773:9;1766:21;1747:4;1804:56;1856:2;1845:9;1841:18;1833:6;1804:56;:::i;1871:180::-;1930:6;1983:2;1971:9;1962:7;1958:23;1954:32;1951:52;;;1999:1;1996;1989:12;1951:52;-1:-1:-1;2022:23:11;;1871:180;-1:-1:-1;1871:180:11:o;2287:254::-;2355:6;2363;2416:2;2404:9;2395:7;2391:23;2387:32;2384:52;;;2432:1;2429;2422:12;2384:52;2468:9;2455:23;2445:33;;2497:38;2531:2;2520:9;2516:18;2497:38;:::i;:::-;2487:48;;2287:254;;;;;:::o;2910:328::-;2987:6;2995;3003;3056:2;3044:9;3035:7;3031:23;3027:32;3024:52;;;3072:1;3069;3062:12;3024:52;3095:29;3114:9;3095:29;:::i;:::-;3085:39;;3143:38;3177:2;3166:9;3162:18;3143:38;:::i;:::-;3133:48;;3228:2;3217:9;3213:18;3200:32;3190:42;;2910:328;;;;;:::o;3243:367::-;3306:8;3316:6;3370:3;3363:4;3355:6;3351:17;3347:27;3337:55;;3388:1;3385;3378:12;3337:55;-1:-1:-1;3411:20:11;;3454:18;3443:30;;3440:50;;;3486:1;3483;3476:12;3440:50;3523:4;3515:6;3511:17;3499:29;;3583:3;3576:4;3566:6;3563:1;3559:14;3551:6;3547:27;3543:38;3540:47;3537:67;;;3600:1;3597;3590:12;3537:67;3243:367;;;;;:::o;3615:437::-;3701:6;3709;3762:2;3750:9;3741:7;3737:23;3733:32;3730:52;;;3778:1;3775;3768:12;3730:52;3818:9;3805:23;3851:18;3843:6;3840:30;3837:50;;;3883:1;3880;3873:12;3837:50;3922:70;3984:7;3975:6;3964:9;3960:22;3922:70;:::i;:::-;4011:8;;3896:96;;-1:-1:-1;3615:437:11;-1:-1:-1;;;;3615:437:11:o;4242:248::-;4310:6;4318;4371:2;4359:9;4350:7;4346:23;4342:32;4339:52;;;4387:1;4384;4377:12;4339:52;-1:-1:-1;;4410:23:11;;;4480:2;4465:18;;;4452:32;;-1:-1:-1;4242:248:11:o;4495:186::-;4554:6;4607:2;4595:9;4586:7;4582:23;4578:32;4575:52;;;4623:1;4620;4613:12;4575:52;4646:29;4665:9;4646:29;:::i;4686:184::-;-1:-1:-1;;;4735:1:11;4728:88;4835:4;4832:1;4825:15;4859:4;4856:1;4849:15;4875:275;4946:2;4940:9;5011:2;4992:13;;-1:-1:-1;;4988:27:11;4976:40;;5046:18;5031:34;;5067:22;;;5028:62;5025:88;;;5093:18;;:::i;:::-;5129:2;5122:22;4875:275;;-1:-1:-1;4875:275:11:o;5155:407::-;5220:5;5254:18;5246:6;5243:30;5240:56;;;5276:18;;:::i;:::-;5314:57;5359:2;5338:15;;-1:-1:-1;;5334:29:11;5365:4;5330:40;5314:57;:::i;:::-;5305:66;;5394:6;5387:5;5380:21;5434:3;5425:6;5420:3;5416:16;5413:25;5410:45;;;5451:1;5448;5441:12;5410:45;5500:6;5495:3;5488:4;5481:5;5477:16;5464:43;5554:1;5547:4;5538:6;5531:5;5527:18;5523:29;5516:40;5155:407;;;;;:::o;5567:451::-;5636:6;5689:2;5677:9;5668:7;5664:23;5660:32;5657:52;;;5705:1;5702;5695:12;5657:52;5745:9;5732:23;5778:18;5770:6;5767:30;5764:50;;;5810:1;5807;5800:12;5764:50;5833:22;;5886:4;5878:13;;5874:27;-1:-1:-1;5864:55:11;;5915:1;5912;5905:12;5864:55;5938:74;6004:7;5999:2;5986:16;5981:2;5977;5973:11;5938:74;:::i;6023:160::-;6088:20;;6144:13;;6137:21;6127:32;;6117:60;;6173:1;6170;6163:12;6188:254;6253:6;6261;6314:2;6302:9;6293:7;6289:23;6285:32;6282:52;;;6330:1;6327;6320:12;6282:52;6353:29;6372:9;6353:29;:::i;:::-;6343:39;;6401:35;6432:2;6421:9;6417:18;6401:35;:::i;6447:770::-;6566:6;6574;6582;6590;6643:2;6631:9;6622:7;6618:23;6614:32;6611:52;;;6659:1;6656;6649:12;6611:52;6699:9;6686:23;6728:18;6769:2;6761:6;6758:14;6755:34;;;6785:1;6782;6775:12;6755:34;6824:70;6886:7;6877:6;6866:9;6862:22;6824:70;:::i;:::-;6913:8;;-1:-1:-1;6798:96:11;-1:-1:-1;7001:2:11;6986:18;;6973:32;;-1:-1:-1;7017:16:11;;;7014:36;;;7046:1;7043;7036:12;7014:36;;7085:72;7149:7;7138:8;7127:9;7123:24;7085:72;:::i;:::-;6447:770;;;;-1:-1:-1;7176:8:11;-1:-1:-1;;;;6447:770:11:o;7222:667::-;7317:6;7325;7333;7341;7394:3;7382:9;7373:7;7369:23;7365:33;7362:53;;;7411:1;7408;7401:12;7362:53;7434:29;7453:9;7434:29;:::i;:::-;7424:39;;7482:38;7516:2;7505:9;7501:18;7482:38;:::i;:::-;7472:48;;7567:2;7556:9;7552:18;7539:32;7529:42;;7622:2;7611:9;7607:18;7594:32;7649:18;7641:6;7638:30;7635:50;;;7681:1;7678;7671:12;7635:50;7704:22;;7757:4;7749:13;;7745:27;-1:-1:-1;7735:55:11;;7786:1;7783;7776:12;7735:55;7809:74;7875:7;7870:2;7857:16;7852:2;7848;7844:11;7809:74;:::i;:::-;7799:84;;;7222:667;;;;;;;:::o;7894:184::-;-1:-1:-1;;;7943:1:11;7936:88;8043:4;8040:1;8033:15;8067:4;8064:1;8057:15;8083:394;8224:2;8209:18;;8257:1;8246:13;;8236:201;;-1:-1:-1;;;8290:1:11;8283:88;8394:4;8391:1;8384:15;8422:4;8419:1;8412:15;8236:201;8446:25;;;8083:394;:::o;8482:180::-;8538:6;8591:2;8579:9;8570:7;8566:23;8562:32;8559:52;;;8607:1;8604;8597:12;8559:52;8630:26;8646:9;8630:26;:::i;8667:260::-;8735:6;8743;8796:2;8784:9;8775:7;8771:23;8767:32;8764:52;;;8812:1;8809;8802:12;8764:52;8835:29;8854:9;8835:29;:::i;:::-;8825:39;;8883:38;8917:2;8906:9;8902:18;8883:38;:::i;8932:505::-;9027:6;9035;9043;9096:2;9084:9;9075:7;9071:23;9067:32;9064:52;;;9112:1;9109;9102:12;9064:52;9148:9;9135:23;9125:33;;9209:2;9198:9;9194:18;9181:32;9236:18;9228:6;9225:30;9222:50;;;9268:1;9265;9258:12;9222:50;9307:70;9369:7;9360:6;9349:9;9345:22;9307:70;:::i;:::-;8932:505;;9396:8;;-1:-1:-1;9281:96:11;;-1:-1:-1;;;;8932:505:11:o;9442:1016::-;9532:6;9540;9593:2;9581:9;9572:7;9568:23;9564:32;9561:52;;;9609:1;9606;9599:12;9561:52;9649:9;9636:23;9678:18;9719:2;9711:6;9708:14;9705:34;;;9735:1;9732;9725:12;9705:34;9773:6;9762:9;9758:22;9748:32;;9818:7;9811:4;9807:2;9803:13;9799:27;9789:55;;9840:1;9837;9830:12;9789:55;9876:2;9863:16;9898:4;9921:2;9917;9914:10;9911:36;;;9927:18;;:::i;:::-;9973:2;9970:1;9966:10;9956:20;;9996:28;10020:2;10016;10012:11;9996:28;:::i;:::-;10058:15;;;10128:11;;;10124:20;;;10089:12;;;;10156:19;;;10153:39;;;10188:1;10185;10178:12;10153:39;10212:11;;;;10232:142;10248:6;10243:3;10240:15;10232:142;;;10314:17;;10302:30;;10265:12;;;;10352;;;;10232:142;;;10393:5;-1:-1:-1;10417:35:11;;-1:-1:-1;10433:18:11;;;10417:35;:::i;:::-;10407:45;;;;;;9442:1016;;;;;:::o;10865:184::-;-1:-1:-1;;;10914:1:11;10907:88;11014:4;11011:1;11004:15;11038:4;11035:1;11028:15;11054:128;11094:3;11125:1;11121:6;11118:1;11115:13;11112:39;;;11131:18;;:::i;:::-;-1:-1:-1;11167:9:11;;11054:128::o;11535:437::-;11614:1;11610:12;;;;11657;;;11678:61;;11732:4;11724:6;11720:17;11710:27;;11678:61;11785:2;11777:6;11774:14;11754:18;11751:38;11748:218;;;-1:-1:-1;;;11819:1:11;11812:88;11923:4;11920:1;11913:15;11951:4;11948:1;11941:15;11748:218;;11535:437;;;:::o;19411:184::-;-1:-1:-1;;;19460:1:11;19453:88;19560:4;19557:1;19550:15;19584:4;19581:1;19574:15;19600:135;19639:3;-1:-1:-1;;19660:17:11;;19657:43;;;19680:18;;:::i;:::-;-1:-1:-1;19727:1:11;19716:13;;19600:135::o;20226:185::-;20268:3;20306:5;20300:12;20321:52;20366:6;20361:3;20354:4;20347:5;20343:16;20321:52;:::i;:::-;20389:16;;;;;20226:185;-1:-1:-1;;20226:185:11:o;20534:1358::-;20811:3;20840:1;20873:6;20867:13;20903:3;20925:1;20953:9;20949:2;20945:18;20935:28;;21013:2;21002:9;20998:18;21035;21025:61;;21079:4;21071:6;21067:17;21057:27;;21025:61;21105:2;21153;21145:6;21142:14;21122:18;21119:38;21116:222;;;-1:-1:-1;;;21187:3:11;21180:90;21293:4;21290:1;21283:15;21323:4;21318:3;21311:17;21116:222;21354:18;21381:104;;;;21499:1;21494:320;;;;21347:467;;21381:104;-1:-1:-1;;21414:24:11;;21402:37;;21459:16;;;;-1:-1:-1;21381:104:11;;21494:320;20173:1;20166:14;;;20210:4;20197:18;;21589:1;21603:165;21617:6;21614:1;21611:13;21603:165;;;21695:14;;21682:11;;;21675:35;21738:16;;;;21632:10;;21603:165;;;21607:3;;21797:6;21792:3;21788:16;21781:23;;21347:467;;;;;;;21830:56;21855:30;21881:3;21873:6;21855:30;:::i;:::-;20488:7;20476:20;;20521:1;20512:11;;20416:113;25088:136;25127:3;25155:5;25145:39;;25164:18;;:::i;:::-;-1:-1:-1;;;25200:18:11;;25088:136::o;26651:523::-;26845:4;-1:-1:-1;;;;;26955:2:11;26947:6;26943:15;26932:9;26925:34;27007:2;26999:6;26995:15;26990:2;26979:9;26975:18;26968:43;;27047:6;27042:2;27031:9;27027:18;27020:34;27090:3;27085:2;27074:9;27070:18;27063:31;27111:57;27163:3;27152:9;27148:19;27140:6;27111:57;:::i;:::-;27103:65;26651:523;-1:-1:-1;;;;;;26651:523:11:o;27179:249::-;27248:6;27301:2;27289:9;27280:7;27276:23;27272:32;27269:52;;;27317:1;27314;27307:12;27269:52;27349:9;27343:16;27368:30;27392:5;27368:30;:::i
Swarm Source
ipfs://05f92bfdbff70a84131e076ea8893046ed01df5e998b0913b5383f87efd3a909
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.