ERC-721
Overview
Max Total Supply
4,444 RES
Holders
1,459
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
7 RESLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
ResurrectionByConiunV2
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-06-23 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.11; interface IERC721A { /** * The caller must own the token or be an approved operator. */ error ApprovalCallerNotOwnerNorApproved(); /** * The token does not exist. */ error ApprovalQueryForNonexistentToken(); /** * The caller cannot approve to their own address. */ error ApproveToCaller(); /** * 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(); struct TokenOwnership { // The address of the owner. address addr; // Keeps track of 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 through `_extraData`. uint24 extraData; } /** * @dev Returns the total amount of tokens stored by the contract. * * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens. */ function totalSupply() external view returns (uint256); // ============================== // IERC165 // ============================== /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); // ============================== // 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`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev 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 standard. See `_mintERC2309` for more details. */ event ConsecutiveTransfer( uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to ); } interface ERC721A__IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, * including the Metadata extension. Built to optimize for lower gas during batch mints. * * Assumes serials are sequentially minted starting at `_startTokenId()` * (defaults to 0, e.g. 0, 1, 2, 3..). * * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256). */ contract ERC721A is IERC721A { // 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 tokenId of the next token 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 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _currentIndex = _startTokenId(); } /** * @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 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 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 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 returns (uint256) { return _burnCounter; } /** * @dev See {IERC165-supportsInterface}. */ 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: 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. } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view 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 { 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; } /** * 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 ownership that has an address and is not burned // before an ownership that does not have an address and is not burned. // Hence, curr will not underflow. // // We can directly compare the packed value. // If the address is zero, packed is zero. while (packed == 0) { packed = _packedOwnerships[--curr]; } return packed; } } } revert OwnerQueryForNonexistentToken(); } /** * 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); } /** * Returns the unpacked `TokenOwnership` struct at `index`. */ function _ownershipAt(uint256 index) internal view returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnerships[index]); } /** * @dev Initializes the ownership slot minted at `index` for efficiency purposes. */ function _initializeOwnershipAt(uint256 index) internal { if (_packedOwnerships[index] == 0) { _packedOwnerships[index] = _packedOwnershipOf(index); } } /** * Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around in the collection over time. */ function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { return _unpackedOwnership(_packedOwnershipOf(tokenId)); } /** * @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 See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return address(uint160(_packedOwnershipOf(tokenId))); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ 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 ""; } /** * @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)) } } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public override { address owner = ownerOf(tokenId); if (_msgSenderERC721A() != owner) if (!isApprovedForAll(owner, _msgSenderERC721A())) { revert ApprovalCallerNotOwnerNorApproved(); } _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { if (operator == _msgSenderERC721A()) revert ApproveToCaller(); _operatorApprovals[_msgSenderERC721A()][operator] = approved; emit ApprovalForAll(_msgSenderERC721A(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { transferFrom(from, to, tokenId); if (to.code.length != 0) if (!_checkContractOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @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 (`_mint`), */ function _exists(uint256 tokenId) internal view returns (bool) { return _startTokenId() <= tokenId && tokenId < _currentIndex && // If within bounds, _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned. } /** * @dev Equivalent to `_safeMint(to, quantity, '')`. */ function _safeMint(address to, uint256 quantity) internal { _safeMint(to, 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 { _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 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 { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); 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 tokenId = startTokenId; uint256 end = startTokenId + quantity; do { emit Transfer(address(0), to, tokenId++); } while (tokenId < end); _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 { 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 Returns the storage slot and value for the approved address of `tokenId`. */ function _getApprovedAddress(uint256 tokenId) private view returns (uint256 approvedAddressSlot, address approvedAddress) { mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals; // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`. assembly { // Compute the slot. mstore(0x00, tokenId) mstore(0x20, tokenApprovalsPtr.slot) approvedAddressSlot := keccak256(0x00, 0x40) // Load the slot's value from storage. approvedAddress := sload(approvedAddressSlot) } } /** * @dev Returns whether the `approvedAddress` is equals to `from` or `msgSender`. */ function _isOwnerOrApproved( address approvedAddress, address from, address msgSender ) private pure returns (bool result) { assembly { // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean. from := and(from, BITMASK_ADDRESS) // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean. msgSender := and(msgSender, BITMASK_ADDRESS) // `msgSender == from || msgSender == approvedAddress`. result := or(eq(msgSender, from), eq(msgSender, approvedAddress)) } } /** * @dev Transfers `tokenId` from `from` to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId); if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner(); ( uint256 approvedAddressSlot, address approvedAddress ) = _getApprovedAddress(tokenId); // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isOwnerOrApproved(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 `_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 ) = _getApprovedAddress(tokenId); if (approvalCheck) { // The nested ifs save around 20+ gas over a compound boolean condition. if (!_isOwnerOrApproved(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++; } } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool 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)) } } } } /** * @dev Directly sets the extra data for the ownership data `index`. */ function _setExtraDataAt(uint256 index, uint24 extraData) internal { 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 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; } /** * @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 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 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 returns (string memory ptr) { assembly { // The maximum value of a uint256 contains 78 digits (1 byte per digit), // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged. // We will need 1 32-byte word to store the length, // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128. ptr := add(mload(0x40), 128) // Update the free memory pointer to allocate. mstore(0x40, ptr) // Cache the end of the memory to calculate the length later. let end := ptr // We write the string from the rightmost digit to the leftmost digit. // The following is essentially a do-while loop that also handles the zero case. // Costs a bit more than early returning for the zero case, // but cheaper in terms of deployment and overall runtime costs. for { // Initialize and perform the first pass without check. let temp := value // Move the pointer 1 byte leftwards to point to an empty character slot. ptr := sub(ptr, 1) // Write the character to the pointer. 48 is the ASCII index of '0'. mstore8(ptr, add(48, mod(temp, 10))) temp := div(temp, 10) } temp { // Keep dividing `temp` until zero. temp := div(temp, 10) } { // Body of the for loop. ptr := sub(ptr, 1) mstore8(ptr, add(48, mod(temp, 10))) } let length := sub(end, ptr) // Move the pointer 32 bytes leftwards to make room for the length. ptr := sub(ptr, 32) // Store the length. mstore(ptr, length) } } } /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @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; } } // OpenZeppelin Contracts v4.4.1 (access/Ownable.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 Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _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); } } /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32( 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if ( uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 ) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "\x19Ethereum Signed Message:\n", Strings.toString(s.length), s ) ); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval( address indexed owner, address indexed approved, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } /* ╦═╗┌─┐┌─┐┬ ┬┬─┐┬─┐┌─┐┌─┐┌┬┐┬┌─┐┌┐┌ ╠╦╝├┤ └─┐│ │├┬┘├┬┘├┤ │ │ ││ ││││ ╩╚═└─┘└─┘└─┘┴└─┴└─└─┘└─┘ ┴ ┴└─┘┘└┘ by Coniun @creator: ConiunIO @security: [email protected] @author: Batuhan KATIRCI (@batuhan_katirci) @website: https://coniun.io/ */ error InvalidSignature(string message); struct CallDataInfo { uint256 _tokenId; address _contractAddress; uint256 _amount; uint256 _backendMintStage; bytes _signature; } contract ResurrectionByConiunV2 is ERC721A, IERC721Receiver, Ownable, ReentrancyGuard { event NftMinted( address indexed contractAddress, address indexed minterAddress, uint256 amount, uint256 mintStartFrom, uint256 sourceTokenId ); using ECDSA for bytes32; string public TOKEN_BASE_URL = "https://temp-cdn.coniun.io/resurrection_metadata/mainnet/"; string public TOKEN_URL_SUFFIX = ".json"; // 0 -> paused // 1 -> whitelist // 2 -> public uint256 public MAX_SUPPLY = 4444; uint256 public MINT_STAGE = 0; uint256 public WALLET_TRANSFER_LIMIT = 2; address private _signerAddress; address private _vaultAddress; address private _editor; constructor(address signerAddress_, address vaultAddress_) ERC721A("RESURRECTION", "RES") { _signerAddress = signerAddress_; _vaultAddress = vaultAddress_; } function getTransferCount(address wallet) public view virtual returns (uint256) { return _getAux(wallet); } function _baseURI() internal view virtual override returns (string memory) { return TOKEN_BASE_URL; } function _suffix() internal view virtual returns (string memory) { return TOKEN_URL_SUFFIX; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); string memory baseURI = _baseURI(); string memory suffix = _suffix(); return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId), suffix)) : ""; } // admin functions function setTokenBaseUrl(string memory _tokenBaseUrl) public editorOrOwner { TOKEN_BASE_URL = _tokenBaseUrl; } function setTokenSuffix(string memory _tokenUrlSuffix) public editorOrOwner { TOKEN_URL_SUFFIX = _tokenUrlSuffix; } function setAuxAdmin(address forAddress, uint64 value) public editorOrOwner { _setAux(forAddress, value); } function adminMint(uint256 quantity, address toAddress) external editorOrOwner { require(totalSupply() + quantity <= MAX_SUPPLY, "max_supply_reached"); _safeMint(toAddress, quantity); } function setSignerAddress(address signerAddress) public editorOrOwner { _signerAddress = signerAddress; } function setMintStage(uint256 _mintStage) public editorOrOwner { MINT_STAGE = _mintStage; } function setWalletTransferLimit(uint256 _walletTransferLimit) public editorOrOwner { WALLET_TRANSFER_LIMIT = _walletTransferLimit; } function setEditor(address editor) public onlyOwner { _editor = editor; } modifier editorOrOwner() { require( _editor == _msgSender() || owner() == _msgSender(), "Editor or Owner required" ); _; } // signature releated functions function getMessageHash( uint256 _amount, uint256 _tokenId, uint256 _backendMintStage, address _contractAddress ) internal pure returns (bytes32) { return keccak256( abi.encodePacked(_amount, _tokenId, _backendMintStage, _contractAddress) ); } function getEthSignedMessageHash(bytes32 _messageHash) private pure returns (bytes32) { return keccak256( abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash) ); } function verifySignature( uint256 _amount, uint256 _tokenId, uint256 _backendMintStage, address _contractAddress, bytes memory signature ) private view returns (bool) { bytes32 messageHash = getMessageHash( _amount, _tokenId, _backendMintStage, _contractAddress ); bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash); return recoverSigner(ethSignedMessageHash, signature) == _signerAddress; } function recoverSigner(bytes32 _ethSignedMessageHash, bytes memory _signature) private pure returns (address) { (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature); return ecrecover(_ethSignedMessageHash, v, r, s); } function splitSignature(bytes memory sig) private pure returns ( bytes32 r, bytes32 s, uint8 v ) { if (sig.length != 65) { revert InvalidSignature("Signature length is not 65 bytes"); } assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := byte(0, mload(add(sig, 96))) } } function dataToBytes( uint256 tokenId, uint256 amount, uint256 backendMintStage, address contractAddress, bytes memory signature ) public pure returns (bytes memory result) { result = abi.encode( tokenId, amount, backendMintStage, contractAddress, signature ); } function bytesToData(bytes memory source) public pure returns ( uint256 tokenId, uint256 amount, uint256 backendMintStage, address contractAddress, bytes memory signature ) { return abi.decode(source, (uint256, uint256, uint256, address, bytes)); } // # 'Mint by Transfer' function // At here we are using IERC721 safeTransferFroom hook // and utilize a mint action // Our backend will create a payload for minting (how many, is eligible etc.) function onERC721Received( address, address from, uint256 tokenId, bytes calldata data ) external nonReentrant returns (bytes4) { if (msg.sender == tx.origin) { revert("only_from_contracts"); } // Verify ownership of the token IERC721 proxy = IERC721(msg.sender); require(proxy.ownerOf(tokenId) == address(this), "nft_not_transferred"); CallDataInfo memory callDataInfo; ( callDataInfo._tokenId, callDataInfo._amount, callDataInfo._backendMintStage, callDataInfo._contractAddress, callDataInfo._signature ) = bytesToData(data); require( totalSupply() + callDataInfo._amount <= MAX_SUPPLY, "max_supply_reached" ); if ( callDataInfo._tokenId != tokenId || callDataInfo._contractAddress != msg.sender ) { revert("calldata_mismatch"); } require( callDataInfo._backendMintStage == MINT_STAGE, "mint_stage_mismatch" ); require(_getAux(from) < WALLET_TRANSFER_LIMIT, "too_many_transfers"); if ( verifySignature( callDataInfo._amount, callDataInfo._tokenId, callDataInfo._backendMintStage, callDataInfo._contractAddress, callDataInfo._signature ) != true ) { revert InvalidSignature("signature_failed"); } proxy.transferFrom(address(this), _vaultAddress, tokenId); emit NftMinted( callDataInfo._contractAddress, // contract from, // minter callDataInfo._amount, // amount _nextTokenId(), // currentIdx tokenId // usedTokenId ); _mint(from, callDataInfo._amount); _setAux(from, _getAux(from) + 1); return IERC721Receiver.onERC721Received.selector; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"signerAddress_","type":"address"},{"internalType":"address","name":"vaultAddress_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[{"internalType":"string","name":"message","type":"string"}],"name":"InvalidSignature","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":"contractAddress","type":"address"},{"indexed":true,"internalType":"address","name":"minterAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"mintStartFrom","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sourceTokenId","type":"uint256"}],"name":"NftMinted","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":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"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_STAGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_BASE_URL","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_URL_SUFFIX","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WALLET_TRANSFER_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"address","name":"toAddress","type":"address"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"source","type":"bytes"}],"name":"bytesToData","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"backendMintStage","type":"uint256"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"backendMintStage","type":"uint256"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"dataToBytes","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"pure","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":"wallet","type":"address"}],"name":"getTransferCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"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":"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":"nonpayable","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":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forAddress","type":"address"},{"internalType":"uint64","name":"value","type":"uint64"}],"name":"setAuxAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"editor","type":"address"}],"name":"setEditor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintStage","type":"uint256"}],"name":"setMintStage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signerAddress","type":"address"}],"name":"setSignerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_tokenBaseUrl","type":"string"}],"name":"setTokenBaseUrl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_tokenUrlSuffix","type":"string"}],"name":"setTokenSuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_walletTransferLimit","type":"uint256"}],"name":"setWalletTransferLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e060405260396080818152906200247e60a03980516200002991600a9160209091019062000199565b5060408051808201909152600580825264173539b7b760d91b60209092019182526200005891600b9162000199565b5061115c600c556000600d556002600e553480156200007657600080fd5b50604051620024b7380380620024b783398101604081905262000099916200025c565b604080518082018252600c81526b2922a9aaa92922a1aa24a7a760a11b60208083019182528351808501909452600384526252455360e81b908401528151919291620000e89160029162000199565b508051620000fe90600390602084019062000199565b50506000805550620001103362000147565b6001600955600f80546001600160a01b039384166001600160a01b03199182161790915560108054929093169116179055620002d1565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001a79062000294565b90600052602060002090601f016020900481019282620001cb576000855562000216565b82601f10620001e657805160ff191683800117855562000216565b8280016001018555821562000216579182015b8281111562000216578251825591602001919060010190620001f9565b506200022492915062000228565b5090565b5b8082111562000224576000815560010162000229565b80516001600160a01b03811681146200025757600080fd5b919050565b600080604083850312156200027057600080fd5b6200027b836200023f565b91506200028b602084016200023f565b90509250929050565b600181811c90821680620002a957607f821691505b60208210811415620002cb57634e487b7160e01b600052602260045260246000fd5b50919050565b61219d80620002e16000396000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c806366d38ba91161011a578063a22cb465116100ad578063cab6b4ef1161007c578063cab6b4ef14610471578063d98892a71461047a578063e985e9c51461048d578063ef73aecc146104c9578063f2fde38b146104d257600080fd5b8063a22cb46514610430578063b88d4fde14610443578063babb36dd14610456578063c87b56dd1461045e57600080fd5b8063825a229e116100e9578063825a229e146103e05780638da5cb5b146103f3578063916784bd1461040457806395d89b411461042857600080fd5b806366d38ba91461039f5780636ea0061b146103b257806370a08231146103c5578063715018a6146103d857600080fd5b806318160ddd1161019d57806342842e0e1161016c57806342842e0e1461034b5780634754198c1461035e5780635b804785146103665780635bfbe8b5146103795780636352211e1461038c57600080fd5b806318160ddd146102ed57806320cf53231461030357806323b872dd1461032f57806332cb6b0c1461034257600080fd5b8063095ea7b3116101d9578063095ea7b3146102885780630dc28efe1461029b5780630ef6a94b146102ae578063150b7a02146102c157600080fd5b806301ffc9a71461020b578063046dc1661461023357806306fdde0314610248578063081812fc1461025d575b600080fd5b61021e6102193660046119f5565b6104e5565b60405190151581526020015b60405180910390f35b610246610241366004611a27565b610537565b005b6102506105a1565b60405161022a9190611a9c565b61027061026b366004611aaf565b610633565b6040516001600160a01b03909116815260200161022a565b610246610296366004611ac8565b610677565b6102466102a9366004611af4565b610717565b6102466102bc366004611bd1565b6107c2565b6102d46102cf366004611c1a565b610814565b6040516001600160e01b0319909116815260200161022a565b600154600054035b60405190815260200161022a565b6102f5610311366004611a27565b6001600160a01b031660009081526005602052604090205460c01c90565b61024661033d366004611cb9565b610cfd565b6102f5600c5481565b610246610359366004611cb9565b610e8e565b610250610eae565b610246610374366004611aaf565b610f3c565b610250610387366004611d1a565b610f80565b61027061039a366004611aaf565b610fb5565b6102466103ad366004611aaf565b610fc0565b6102466103c0366004611bd1565b611004565b6102f56103d3366004611a27565b611056565b6102466110a5565b6102466103ee366004611a27565b6110db565b6008546001600160a01b0316610270565b610417610412366004611d87565b611127565b60405161022a959493929190611dbc565b610250611155565b61024661043e366004611dfa565b611164565b610246610451366004611e2d565b6111fa565b610250611244565b61025061046c366004611aaf565b611251565b6102f5600d5481565b610246610488366004611e99565b6112e5565b61021e61049b366004611ed4565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6102f5600e5481565b6102466104e0366004611a27565b61132e565b60006301ffc9a760e01b6001600160e01b03198316148061051657506380ac58cd60e01b6001600160e01b03198316145b806105315750635b5e139f60e01b6001600160e01b03198316145b92915050565b6011546001600160a01b031633148061055a57506008546001600160a01b031633145b61057f5760405162461bcd60e51b815260040161057690611f02565b60405180910390fd5b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b6060600280546105b090611f39565b80601f01602080910402602001604051908101604052809291908181526020018280546105dc90611f39565b80156106295780601f106105fe57610100808354040283529160200191610629565b820191906000526020600020905b81548152906001019060200180831161060c57829003601f168201915b5050505050905090565b600061063e826113c9565b61065b576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061068282610fb5565b9050336001600160a01b038216146106bb5761069e813361049b565b6106bb576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6011546001600160a01b031633148061073a57506008546001600160a01b031633145b6107565760405162461bcd60e51b815260040161057690611f02565b600c54826107676001546000540390565b6107719190611f8a565b11156107b45760405162461bcd60e51b81526020600482015260126024820152711b585e17dcdd5c1c1b1e57dc995858da195960721b6044820152606401610576565b6107be81836113f0565b5050565b6011546001600160a01b03163314806107e557506008546001600160a01b031633145b6108015760405162461bcd60e51b815260040161057690611f02565b80516107be90600b906020840190611946565b6000600260095414156108695760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610576565b6002600955333214156108b45760405162461bcd60e51b81526020600482015260136024820152726f6e6c795f66726f6d5f636f6e74726163747360681b6044820152606401610576565b6040516331a9108f60e11b815260048101859052339030908290636352211e90602401602060405180830381865afa1580156108f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109189190611fa2565b6001600160a01b0316146109645760405162461bcd60e51b81526020600482015260136024820152721b999d17db9bdd17dd1c985b9cd9995c9c9959606a1b6044820152606401610576565b61099f6040518060a001604052806000815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b6109de85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b60808601526001600160a01b03166020850152606084015260408301819052908252600c5490610a116001546000540390565b610a1b9190611f8a565b1115610a5e5760405162461bcd60e51b81526020600482015260126024820152711b585e17dcdd5c1c1b1e57dc995858da195960721b6044820152606401610576565b805186141580610a7b575060208101516001600160a01b03163314155b15610abc5760405162461bcd60e51b81526020600482015260116024820152700c6c2d8d8c8c2e8c2bedad2e6dac2e8c6d607b1b6044820152606401610576565b600d54816060015114610b075760405162461bcd60e51b81526020600482015260136024820152720dad2dce8bee6e8c2cecabedad2e6dac2e8c6d606b1b6044820152606401610576565b600e546001600160a01b03881660009081526005602052604090205460c01c10610b685760405162461bcd60e51b8152602060048201526012602482015271746f6f5f6d616e795f7472616e736665727360701b6044820152606401610576565b610b898160400151826000015183606001518460200151856080015161140a565b1515600114610bce5760405163151a7bff60e11b815260206004820152601060248201526f1cda59db985d1d5c9957d9985a5b195960821b6044820152606401610576565b6010546040516323b872dd60e01b81523060048201526001600160a01b03918216602482015260448101889052908316906323b872dd90606401600060405180830381600087803b158015610c2257600080fd5b505af1158015610c36573d6000803e3d6000fd5b50505050866001600160a01b031681602001516001600160a01b03167f5d54c166ad7001b2a22879f5c7ccab7651d167bc70137d9851f98337b3232f0b8360400151610c8160005490565b60408051928352602083019190915281018a905260600160405180910390a3610cae8782604001516114c7565b610ce487610cd4896001600160a01b031660009081526005602052604090205460c01c90565b610cdf906001611fbf565b6115a4565b5050600160095550630a85bd0160e11b95945050505050565b6000610d08826115d6565b9050836001600160a01b0316816001600160a01b031614610d3b5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610d8857610d6b863361049b565b610d8857604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610daf57604051633a954ecd60e21b815260040160405180910390fd5b8015610dba57600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040902055600160e11b8316610e455760018401600081815260046020526040902054610e43576000548114610e435760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b610ea9838383604051806020016040528060008152506111fa565b505050565b600a8054610ebb90611f39565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee790611f39565b8015610f345780601f10610f0957610100808354040283529160200191610f34565b820191906000526020600020905b815481529060010190602001808311610f1757829003601f168201915b505050505081565b6011546001600160a01b0316331480610f5f57506008546001600160a01b031633145b610f7b5760405162461bcd60e51b815260040161057690611f02565b600e55565b60608585858585604051602001610f9b959493929190611dbc565b604051602081830303815290604052905095945050505050565b6000610531826115d6565b6011546001600160a01b0316331480610fe357506008546001600160a01b031633145b610fff5760405162461bcd60e51b815260040161057690611f02565b600d55565b6011546001600160a01b031633148061102757506008546001600160a01b031633145b6110435760405162461bcd60e51b815260040161057690611f02565b80516107be90600a906020840190611946565b60006001600160a01b03821661107f576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b6008546001600160a01b031633146110cf5760405162461bcd60e51b815260040161057690611feb565b6110d9600061163e565b565b6008546001600160a01b031633146111055760405162461bcd60e51b815260040161057690611feb565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000806060858060200190518101906111439190612020565b939a9299509097509550909350915050565b6060600380546105b090611f39565b6001600160a01b03821633141561118e5760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611205848484610cfd565b6001600160a01b0383163b1561123e5761122184848484611690565b61123e576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b600b8054610ebb90611f39565b606061125c826113c9565b61127957604051630a14c4b560e41b815260040160405180910390fd5b6000611283611778565b9050600061128f611787565b90508151600014156112b057604051806020016040528060008152506112dd565b816112ba85611796565b826040516020016112cd939291906120ca565b6040516020818303038152906040525b949350505050565b6011546001600160a01b031633148061130857506008546001600160a01b031633145b6113245760405162461bcd60e51b815260040161057690611f02565b6107be82826115a4565b6008546001600160a01b031633146113585760405162461bcd60e51b815260040161057690611feb565b6001600160a01b0381166113bd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610576565b6113c68161163e565b50565b6000805482108015610531575050600090815260046020526040902054600160e01b161590565b6107be8282604051806020016040528060008152506117e5565b604080516020808201889052818301879052606080830187905285901b6bffffffffffffffffffffffff19166080830152825180830360740181526094830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060b484015260d08084018290528451808503909101815260f09093019093528151910120600f5460009291906001600160a01b03166114b18286611852565b6001600160a01b03161498975050505050505050565b6000546001600160a01b0383166114f057604051622e076360e81b815260040160405180910390fd5b8161150e5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600081815260056020526040902080546801000000000000000185020190554260a01b6001841460e11b1717600082815260046020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106115585760005550505050565b6001600160a01b03909116600090815260056020526040902080546001600160c01b031660c09290921b919091179055565b60008160005481101561162557600081815260046020526040902054600160e01b8116611623575b8061161c5750600019016000818152600460205260409020546115fe565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906116c590339089908890889060040161210d565b6020604051808303816000875af1925050508015611700575060408051601f3d908101601f191682019092526116fd9181019061214a565b60015b61175b573d80801561172e576040519150601f19603f3d011682016040523d82523d6000602084013e611733565b606091505b508051611753576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6060600a80546105b090611f39565b6060600b80546105b090611f39565b604080516080810191829052607f0190826030600a8206018353600a90045b80156117d357600183039250600a81066030018353600a90046117b5565b50819003601f19909101908152919050565b6117ef83836114c7565b6001600160a01b0383163b15610ea9576000548281035b6118196000868380600101945086611690565b611836576040516368d2bf6b60e11b815260040160405180910390fd5b81811061180657816000541461184b57600080fd5b5050505050565b600080600080611861856118d1565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa1580156118bc573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b600080600083516041146119285760405163151a7bff60e11b815260206004820181905260248201527f5369676e6174757265206c656e677468206973206e6f742036352062797465736044820152606401610576565b50505060208101516040820151606090920151909260009190911a90565b82805461195290611f39565b90600052602060002090601f01602090048101928261197457600085556119ba565b82601f1061198d57805160ff19168380011785556119ba565b828001600101855582156119ba579182015b828111156119ba57825182559160200191906001019061199f565b506119c69291506119ca565b5090565b5b808211156119c657600081556001016119cb565b6001600160e01b0319811681146113c657600080fd5b600060208284031215611a0757600080fd5b813561161c816119df565b6001600160a01b03811681146113c657600080fd5b600060208284031215611a3957600080fd5b813561161c81611a12565b60005b83811015611a5f578181015183820152602001611a47565b8381111561123e5750506000910152565b60008151808452611a88816020860160208601611a44565b601f01601f19169290920160200192915050565b60208152600061161c6020830184611a70565b600060208284031215611ac157600080fd5b5035919050565b60008060408385031215611adb57600080fd5b8235611ae681611a12565b946020939093013593505050565b60008060408385031215611b0757600080fd5b823591506020830135611b1981611a12565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611b6357611b63611b24565b604052919050565b600067ffffffffffffffff821115611b8557611b85611b24565b50601f01601f191660200190565b6000611ba6611ba184611b6b565b611b3a565b9050828152838383011115611bba57600080fd5b828260208301376000602084830101529392505050565b600060208284031215611be357600080fd5b813567ffffffffffffffff811115611bfa57600080fd5b8201601f81018413611c0b57600080fd5b6112dd84823560208401611b93565b600080600080600060808688031215611c3257600080fd5b8535611c3d81611a12565b94506020860135611c4d81611a12565b935060408601359250606086013567ffffffffffffffff80821115611c7157600080fd5b818801915088601f830112611c8557600080fd5b813581811115611c9457600080fd5b896020828501011115611ca657600080fd5b9699959850939650602001949392505050565b600080600060608486031215611cce57600080fd5b8335611cd981611a12565b92506020840135611ce981611a12565b929592945050506040919091013590565b600082601f830112611d0b57600080fd5b61161c83833560208501611b93565b600080600080600060a08688031215611d3257600080fd5b8535945060208601359350604086013592506060860135611d5281611a12565b9150608086013567ffffffffffffffff811115611d6e57600080fd5b611d7a88828901611cfa565b9150509295509295909350565b600060208284031215611d9957600080fd5b813567ffffffffffffffff811115611db057600080fd5b6112dd84828501611cfa565b85815284602082015283604082015260018060a01b038316606082015260a060808201526000611def60a0830184611a70565b979650505050505050565b60008060408385031215611e0d57600080fd5b8235611e1881611a12565b915060208301358015158114611b1957600080fd5b60008060008060808587031215611e4357600080fd5b8435611e4e81611a12565b93506020850135611e5e81611a12565b925060408501359150606085013567ffffffffffffffff811115611e8157600080fd5b611e8d87828801611cfa565b91505092959194509250565b60008060408385031215611eac57600080fd5b8235611eb781611a12565b9150602083013567ffffffffffffffff81168114611b1957600080fd5b60008060408385031215611ee757600080fd5b8235611ef281611a12565b91506020830135611b1981611a12565b60208082526018908201527f456469746f72206f72204f776e65722072657175697265640000000000000000604082015260600190565b600181811c90821680611f4d57607f821691505b60208210811415611f6e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115611f9d57611f9d611f74565b500190565b600060208284031215611fb457600080fd5b815161161c81611a12565b600067ffffffffffffffff808316818516808303821115611fe257611fe2611f74565b01949350505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600080600080600060a0868803121561203857600080fd5b855194506020860151935060408601519250606086015161205881611a12565b608087015190925067ffffffffffffffff81111561207557600080fd5b8601601f8101881361208657600080fd5b8051612094611ba182611b6b565b8181528960208385010111156120a957600080fd5b6120ba826020830160208601611a44565b8093505050509295509295909350565b600084516120dc818460208901611a44565b8451908301906120f0818360208901611a44565b8451910190612103818360208801611a44565b0195945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061214090830184611a70565b9695505050505050565b60006020828403121561215c57600080fd5b815161161c816119df56fea264697066735822122033d295fd7c5f4dc1a8999fecc428f60af084ca85c86444b499a3794c62ffd90764736f6c634300080b003368747470733a2f2f74656d702d63646e2e636f6e69756e2e696f2f726573757272656374696f6e5f6d657461646174612f6d61696e6e65742f00000000000000000000000086a872197044fcd9a9185e1e5fef6e2cb8f5eaca0000000000000000000000007526dd325c6e2b8eca46cd04698a80403dd0225c
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102065760003560e01c806366d38ba91161011a578063a22cb465116100ad578063cab6b4ef1161007c578063cab6b4ef14610471578063d98892a71461047a578063e985e9c51461048d578063ef73aecc146104c9578063f2fde38b146104d257600080fd5b8063a22cb46514610430578063b88d4fde14610443578063babb36dd14610456578063c87b56dd1461045e57600080fd5b8063825a229e116100e9578063825a229e146103e05780638da5cb5b146103f3578063916784bd1461040457806395d89b411461042857600080fd5b806366d38ba91461039f5780636ea0061b146103b257806370a08231146103c5578063715018a6146103d857600080fd5b806318160ddd1161019d57806342842e0e1161016c57806342842e0e1461034b5780634754198c1461035e5780635b804785146103665780635bfbe8b5146103795780636352211e1461038c57600080fd5b806318160ddd146102ed57806320cf53231461030357806323b872dd1461032f57806332cb6b0c1461034257600080fd5b8063095ea7b3116101d9578063095ea7b3146102885780630dc28efe1461029b5780630ef6a94b146102ae578063150b7a02146102c157600080fd5b806301ffc9a71461020b578063046dc1661461023357806306fdde0314610248578063081812fc1461025d575b600080fd5b61021e6102193660046119f5565b6104e5565b60405190151581526020015b60405180910390f35b610246610241366004611a27565b610537565b005b6102506105a1565b60405161022a9190611a9c565b61027061026b366004611aaf565b610633565b6040516001600160a01b03909116815260200161022a565b610246610296366004611ac8565b610677565b6102466102a9366004611af4565b610717565b6102466102bc366004611bd1565b6107c2565b6102d46102cf366004611c1a565b610814565b6040516001600160e01b0319909116815260200161022a565b600154600054035b60405190815260200161022a565b6102f5610311366004611a27565b6001600160a01b031660009081526005602052604090205460c01c90565b61024661033d366004611cb9565b610cfd565b6102f5600c5481565b610246610359366004611cb9565b610e8e565b610250610eae565b610246610374366004611aaf565b610f3c565b610250610387366004611d1a565b610f80565b61027061039a366004611aaf565b610fb5565b6102466103ad366004611aaf565b610fc0565b6102466103c0366004611bd1565b611004565b6102f56103d3366004611a27565b611056565b6102466110a5565b6102466103ee366004611a27565b6110db565b6008546001600160a01b0316610270565b610417610412366004611d87565b611127565b60405161022a959493929190611dbc565b610250611155565b61024661043e366004611dfa565b611164565b610246610451366004611e2d565b6111fa565b610250611244565b61025061046c366004611aaf565b611251565b6102f5600d5481565b610246610488366004611e99565b6112e5565b61021e61049b366004611ed4565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6102f5600e5481565b6102466104e0366004611a27565b61132e565b60006301ffc9a760e01b6001600160e01b03198316148061051657506380ac58cd60e01b6001600160e01b03198316145b806105315750635b5e139f60e01b6001600160e01b03198316145b92915050565b6011546001600160a01b031633148061055a57506008546001600160a01b031633145b61057f5760405162461bcd60e51b815260040161057690611f02565b60405180910390fd5b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b6060600280546105b090611f39565b80601f01602080910402602001604051908101604052809291908181526020018280546105dc90611f39565b80156106295780601f106105fe57610100808354040283529160200191610629565b820191906000526020600020905b81548152906001019060200180831161060c57829003601f168201915b5050505050905090565b600061063e826113c9565b61065b576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061068282610fb5565b9050336001600160a01b038216146106bb5761069e813361049b565b6106bb576040516367d9dca160e11b815260040160405180910390fd5b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6011546001600160a01b031633148061073a57506008546001600160a01b031633145b6107565760405162461bcd60e51b815260040161057690611f02565b600c54826107676001546000540390565b6107719190611f8a565b11156107b45760405162461bcd60e51b81526020600482015260126024820152711b585e17dcdd5c1c1b1e57dc995858da195960721b6044820152606401610576565b6107be81836113f0565b5050565b6011546001600160a01b03163314806107e557506008546001600160a01b031633145b6108015760405162461bcd60e51b815260040161057690611f02565b80516107be90600b906020840190611946565b6000600260095414156108695760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610576565b6002600955333214156108b45760405162461bcd60e51b81526020600482015260136024820152726f6e6c795f66726f6d5f636f6e74726163747360681b6044820152606401610576565b6040516331a9108f60e11b815260048101859052339030908290636352211e90602401602060405180830381865afa1580156108f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109189190611fa2565b6001600160a01b0316146109645760405162461bcd60e51b81526020600482015260136024820152721b999d17db9bdd17dd1c985b9cd9995c9c9959606a1b6044820152606401610576565b61099f6040518060a001604052806000815260200160006001600160a01b031681526020016000815260200160008152602001606081525090565b6109de85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061112792505050565b60808601526001600160a01b03166020850152606084015260408301819052908252600c5490610a116001546000540390565b610a1b9190611f8a565b1115610a5e5760405162461bcd60e51b81526020600482015260126024820152711b585e17dcdd5c1c1b1e57dc995858da195960721b6044820152606401610576565b805186141580610a7b575060208101516001600160a01b03163314155b15610abc5760405162461bcd60e51b81526020600482015260116024820152700c6c2d8d8c8c2e8c2bedad2e6dac2e8c6d607b1b6044820152606401610576565b600d54816060015114610b075760405162461bcd60e51b81526020600482015260136024820152720dad2dce8bee6e8c2cecabedad2e6dac2e8c6d606b1b6044820152606401610576565b600e546001600160a01b03881660009081526005602052604090205460c01c10610b685760405162461bcd60e51b8152602060048201526012602482015271746f6f5f6d616e795f7472616e736665727360701b6044820152606401610576565b610b898160400151826000015183606001518460200151856080015161140a565b1515600114610bce5760405163151a7bff60e11b815260206004820152601060248201526f1cda59db985d1d5c9957d9985a5b195960821b6044820152606401610576565b6010546040516323b872dd60e01b81523060048201526001600160a01b03918216602482015260448101889052908316906323b872dd90606401600060405180830381600087803b158015610c2257600080fd5b505af1158015610c36573d6000803e3d6000fd5b50505050866001600160a01b031681602001516001600160a01b03167f5d54c166ad7001b2a22879f5c7ccab7651d167bc70137d9851f98337b3232f0b8360400151610c8160005490565b60408051928352602083019190915281018a905260600160405180910390a3610cae8782604001516114c7565b610ce487610cd4896001600160a01b031660009081526005602052604090205460c01c90565b610cdf906001611fbf565b6115a4565b5050600160095550630a85bd0160e11b95945050505050565b6000610d08826115d6565b9050836001600160a01b0316816001600160a01b031614610d3b5760405162a1148160e81b815260040160405180910390fd5b60008281526006602052604090208054338082146001600160a01b03881690911417610d8857610d6b863361049b565b610d8857604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038516610daf57604051633a954ecd60e21b815260040160405180910390fd5b8015610dba57600082555b6001600160a01b038681166000908152600560205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260046020526040902055600160e11b8316610e455760018401600081815260046020526040902054610e43576000548114610e435760008181526004602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b610ea9838383604051806020016040528060008152506111fa565b505050565b600a8054610ebb90611f39565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee790611f39565b8015610f345780601f10610f0957610100808354040283529160200191610f34565b820191906000526020600020905b815481529060010190602001808311610f1757829003601f168201915b505050505081565b6011546001600160a01b0316331480610f5f57506008546001600160a01b031633145b610f7b5760405162461bcd60e51b815260040161057690611f02565b600e55565b60608585858585604051602001610f9b959493929190611dbc565b604051602081830303815290604052905095945050505050565b6000610531826115d6565b6011546001600160a01b0316331480610fe357506008546001600160a01b031633145b610fff5760405162461bcd60e51b815260040161057690611f02565b600d55565b6011546001600160a01b031633148061102757506008546001600160a01b031633145b6110435760405162461bcd60e51b815260040161057690611f02565b80516107be90600a906020840190611946565b60006001600160a01b03821661107f576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526005602052604090205467ffffffffffffffff1690565b6008546001600160a01b031633146110cf5760405162461bcd60e51b815260040161057690611feb565b6110d9600061163e565b565b6008546001600160a01b031633146111055760405162461bcd60e51b815260040161057690611feb565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000806060858060200190518101906111439190612020565b939a9299509097509550909350915050565b6060600380546105b090611f39565b6001600160a01b03821633141561118e5760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611205848484610cfd565b6001600160a01b0383163b1561123e5761122184848484611690565b61123e576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b600b8054610ebb90611f39565b606061125c826113c9565b61127957604051630a14c4b560e41b815260040160405180910390fd5b6000611283611778565b9050600061128f611787565b90508151600014156112b057604051806020016040528060008152506112dd565b816112ba85611796565b826040516020016112cd939291906120ca565b6040516020818303038152906040525b949350505050565b6011546001600160a01b031633148061130857506008546001600160a01b031633145b6113245760405162461bcd60e51b815260040161057690611f02565b6107be82826115a4565b6008546001600160a01b031633146113585760405162461bcd60e51b815260040161057690611feb565b6001600160a01b0381166113bd5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610576565b6113c68161163e565b50565b6000805482108015610531575050600090815260046020526040902054600160e01b161590565b6107be8282604051806020016040528060008152506117e5565b604080516020808201889052818301879052606080830187905285901b6bffffffffffffffffffffffff19166080830152825180830360740181526094830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060b484015260d08084018290528451808503909101815260f09093019093528151910120600f5460009291906001600160a01b03166114b18286611852565b6001600160a01b03161498975050505050505050565b6000546001600160a01b0383166114f057604051622e076360e81b815260040160405180910390fd5b8161150e5760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038316600081815260056020526040902080546801000000000000000185020190554260a01b6001841460e11b1717600082815260046020526040902055808281015b6040516001830192906001600160a01b038716906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48082106115585760005550505050565b6001600160a01b03909116600090815260056020526040902080546001600160c01b031660c09290921b919091179055565b60008160005481101561162557600081815260046020526040902054600160e01b8116611623575b8061161c5750600019016000818152600460205260409020546115fe565b9392505050565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a02906116c590339089908890889060040161210d565b6020604051808303816000875af1925050508015611700575060408051601f3d908101601f191682019092526116fd9181019061214a565b60015b61175b573d80801561172e576040519150601f19603f3d011682016040523d82523d6000602084013e611733565b606091505b508051611753576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b6060600a80546105b090611f39565b6060600b80546105b090611f39565b604080516080810191829052607f0190826030600a8206018353600a90045b80156117d357600183039250600a81066030018353600a90046117b5565b50819003601f19909101908152919050565b6117ef83836114c7565b6001600160a01b0383163b15610ea9576000548281035b6118196000868380600101945086611690565b611836576040516368d2bf6b60e11b815260040160405180910390fd5b81811061180657816000541461184b57600080fd5b5050505050565b600080600080611861856118d1565b6040805160008152602081018083528b905260ff8316918101919091526060810184905260808101839052929550909350915060019060a0016020604051602081039080840390855afa1580156118bc573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b600080600083516041146119285760405163151a7bff60e11b815260206004820181905260248201527f5369676e6174757265206c656e677468206973206e6f742036352062797465736044820152606401610576565b50505060208101516040820151606090920151909260009190911a90565b82805461195290611f39565b90600052602060002090601f01602090048101928261197457600085556119ba565b82601f1061198d57805160ff19168380011785556119ba565b828001600101855582156119ba579182015b828111156119ba57825182559160200191906001019061199f565b506119c69291506119ca565b5090565b5b808211156119c657600081556001016119cb565b6001600160e01b0319811681146113c657600080fd5b600060208284031215611a0757600080fd5b813561161c816119df565b6001600160a01b03811681146113c657600080fd5b600060208284031215611a3957600080fd5b813561161c81611a12565b60005b83811015611a5f578181015183820152602001611a47565b8381111561123e5750506000910152565b60008151808452611a88816020860160208601611a44565b601f01601f19169290920160200192915050565b60208152600061161c6020830184611a70565b600060208284031215611ac157600080fd5b5035919050565b60008060408385031215611adb57600080fd5b8235611ae681611a12565b946020939093013593505050565b60008060408385031215611b0757600080fd5b823591506020830135611b1981611a12565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611b6357611b63611b24565b604052919050565b600067ffffffffffffffff821115611b8557611b85611b24565b50601f01601f191660200190565b6000611ba6611ba184611b6b565b611b3a565b9050828152838383011115611bba57600080fd5b828260208301376000602084830101529392505050565b600060208284031215611be357600080fd5b813567ffffffffffffffff811115611bfa57600080fd5b8201601f81018413611c0b57600080fd5b6112dd84823560208401611b93565b600080600080600060808688031215611c3257600080fd5b8535611c3d81611a12565b94506020860135611c4d81611a12565b935060408601359250606086013567ffffffffffffffff80821115611c7157600080fd5b818801915088601f830112611c8557600080fd5b813581811115611c9457600080fd5b896020828501011115611ca657600080fd5b9699959850939650602001949392505050565b600080600060608486031215611cce57600080fd5b8335611cd981611a12565b92506020840135611ce981611a12565b929592945050506040919091013590565b600082601f830112611d0b57600080fd5b61161c83833560208501611b93565b600080600080600060a08688031215611d3257600080fd5b8535945060208601359350604086013592506060860135611d5281611a12565b9150608086013567ffffffffffffffff811115611d6e57600080fd5b611d7a88828901611cfa565b9150509295509295909350565b600060208284031215611d9957600080fd5b813567ffffffffffffffff811115611db057600080fd5b6112dd84828501611cfa565b85815284602082015283604082015260018060a01b038316606082015260a060808201526000611def60a0830184611a70565b979650505050505050565b60008060408385031215611e0d57600080fd5b8235611e1881611a12565b915060208301358015158114611b1957600080fd5b60008060008060808587031215611e4357600080fd5b8435611e4e81611a12565b93506020850135611e5e81611a12565b925060408501359150606085013567ffffffffffffffff811115611e8157600080fd5b611e8d87828801611cfa565b91505092959194509250565b60008060408385031215611eac57600080fd5b8235611eb781611a12565b9150602083013567ffffffffffffffff81168114611b1957600080fd5b60008060408385031215611ee757600080fd5b8235611ef281611a12565b91506020830135611b1981611a12565b60208082526018908201527f456469746f72206f72204f776e65722072657175697265640000000000000000604082015260600190565b600181811c90821680611f4d57607f821691505b60208210811415611f6e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115611f9d57611f9d611f74565b500190565b600060208284031215611fb457600080fd5b815161161c81611a12565b600067ffffffffffffffff808316818516808303821115611fe257611fe2611f74565b01949350505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600080600080600060a0868803121561203857600080fd5b855194506020860151935060408601519250606086015161205881611a12565b608087015190925067ffffffffffffffff81111561207557600080fd5b8601601f8101881361208657600080fd5b8051612094611ba182611b6b565b8181528960208385010111156120a957600080fd5b6120ba826020830160208601611a44565b8093505050509295509295909350565b600084516120dc818460208901611a44565b8451908301906120f0818360208901611a44565b8451910190612103818360208801611a44565b0195945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061214090830184611a70565b9695505050505050565b60006020828403121561215c57600080fd5b815161161c816119df56fea264697066735822122033d295fd7c5f4dc1a8999fecc428f60af084ca85c86444b499a3794c62ffd90764736f6c634300080b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000086a872197044fcd9a9185e1e5fef6e2cb8f5eaca0000000000000000000000007526dd325c6e2b8eca46cd04698a80403dd0225c
-----Decoded View---------------
Arg [0] : signerAddress_ (address): 0x86A872197044fcd9a9185e1e5FEF6E2cB8f5EaCa
Arg [1] : vaultAddress_ (address): 0x7526dD325c6E2b8eCA46cd04698a80403dD0225C
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000086a872197044fcd9a9185e1e5fef6e2cb8f5eaca
Arg [1] : 0000000000000000000000007526dd325c6e2b8eca46cd04698a80403dd0225c
Deployed Bytecode Sourcemap
64401:7293:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13548:607;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;13548:607:0;;;;;;;;66697:113;;;;;;:::i;:::-;;:::i;:::-;;18813:94;;;:::i;:::-;;;;;;;:::i;20676:192::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2080:32:1;;;2062:51;;2050:2;2035:18;20676:192:0;1916:203:1;20274:344:0;;;;;;:::i;:::-;;:::i;66480:211::-;;;;;;:::i;:::-;;:::i;66230:123::-;;;;;;:::i;:::-;;:::i;69908:1783::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;5270:33:1;;;5252:52;;5240:2;5225:18;69908:1783:0;5108:202:1;12680:291:0;12928:12;;12733:7;12912:13;:28;12680:291;;;5461:25:1;;;5449:2;5434:18;12680:291:0;5315:177:1;65310:138:0;;;;;;:::i;:::-;-1:-1:-1;;;;;15151:25:0;65401:7;15151:25;;;:18;:25;;;;;;9427:3;15151:39;;65310:138;29131:2519;;;;;;:::i;:::-;;:::i;64911:32::-;;;;;;21554:165;;;;;;:::i;:::-;;:::i;64709:95::-;;;:::i;66921:153::-;;;;;;:::i;:::-;;:::i;69037:338::-;;;;;;:::i;:::-;;:::i;18616:138::-;;;;;;:::i;:::-;;:::i;66816:99::-;;;;;;:::i;:::-;;:::i;66106:118::-;;;;;;:::i;:::-;;:::i;14211:214::-;;;;;;:::i;:::-;;:::i;44400:97::-;;;:::i;67080:81::-;;;;;;:::i;:::-;;:::i;43789:::-;43858:6;;-1:-1:-1;;;;;43858:6:0;43789:81;;69381:314;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;18968:98::-;;;:::i;20932:310::-;;;;;;:::i;:::-;;:::i;21782:351::-;;;;;;:::i;:::-;;:::i;64809:40::-;;;:::i;65676:402::-;;;;;;:::i;:::-;;:::i;64948:29::-;;;;;;66359:115;;;;;;:::i;:::-;;:::i;21305:186::-;;;;;;:::i;:::-;-1:-1:-1;;;;;21450:25:0;;;21427:4;21450:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;21305:186;64982:40;;;;;;44642:191;;;;;;:::i;:::-;;:::i;13548:607::-;13658:4;-1:-1:-1;;;;;;;;;13939:25:0;;;;:96;;-1:-1:-1;;;;;;;;;;14010:25:0;;;13939:96;:167;;;-1:-1:-1;;;;;;;;;;14081:25:0;;;13939:167;13925:181;13548:607;-1:-1:-1;;13548:607:0:o;66697:113::-;67215:7;;-1:-1:-1;;;;;67215:7:0;42704:10;67215:23;;:50;;-1:-1:-1;43858:6:0;;-1:-1:-1;;;;;43858:6:0;42704:10;67242:23;67215:50;67199:108;;;;-1:-1:-1;;;67199:108:0;;;;;;;:::i;:::-;;;;;;;;;66774:14:::1;:30:::0;;-1:-1:-1;;;;;;66774:30:0::1;-1:-1:-1::0;;;;;66774:30:0;;;::::1;::::0;;;::::1;::::0;;66697:113::o;18813:94::-;18867:13;18896:5;18889:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18813:94;:::o;20676:192::-;20744:7;20765:16;20773:7;20765;:16::i;:::-;20760:64;;20790:34;;-1:-1:-1;;;20790:34:0;;;;;;;;;;;20760:64;-1:-1:-1;20838:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;20838:24:0;;20676:192::o;20274:344::-;20343:13;20359:16;20367:7;20359;:16::i;:::-;20343:32;-1:-1:-1;42704:10:0;-1:-1:-1;;;;;20386:28:0;;;20382:155;;20428:44;20445:5;42704:10;21305:186;:::i;20428:44::-;20423:114;;20492:35;;-1:-1:-1;;;20492:35:0;;;;;;;;;;;20423:114;20543:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;20543:29:0;-1:-1:-1;;;;;20543:29:0;;;;;;;;;20584:28;;20543:24;;20584:28;;;;;;;20336:282;20274:344;;:::o;66480:211::-;67215:7;;-1:-1:-1;;;;;67215:7:0;42704:10;67215:23;;:50;;-1:-1:-1;43858:6:0;;-1:-1:-1;;;;;43858:6:0;42704:10;67242:23;67215:50;67199:108;;;;-1:-1:-1;;;67199:108:0;;;;;;;:::i;:::-;66615:10:::1;;66603:8;66587:13;12928:12:::0;;12733:7;12912:13;:28;;12680:291;66587:13:::1;:24;;;;:::i;:::-;:38;;66579:69;;;::::0;-1:-1:-1;;;66579:69:0;;11055:2:1;66579:69:0::1;::::0;::::1;11037:21:1::0;11094:2;11074:18;;;11067:30;-1:-1:-1;;;11113:18:1;;;11106:48;11171:18;;66579:69:0::1;10853:342:1::0;66579:69:0::1;66655:30;66665:9;66676:8;66655:9;:30::i;:::-;66480:211:::0;;:::o;66230:123::-;67215:7;;-1:-1:-1;;;;;67215:7:0;42704:10;67215:23;;:50;;-1:-1:-1;43858:6:0;;-1:-1:-1;;;;;43858:6:0;42704:10;67242:23;67215:50;67199:108;;;;-1:-1:-1;;;67199:108:0;;;;;;;:::i;:::-;66313:34;;::::1;::::0;:16:::1;::::0;:34:::1;::::0;::::1;::::0;::::1;:::i;69908:1783::-:0;70051:6;62882:1;63444:7;;:19;;63436:63;;;;-1:-1:-1;;;63436:63:0;;11402:2:1;63436:63:0;;;11384:21:1;11441:2;11421:18;;;11414:30;11480:33;11460:18;;;11453:61;11531:18;;63436:63:0;11200:355:1;63436:63:0;62882:1;63567:7;:18;70070:10:::1;70084:9;70070:23;70066:75;;;70104:29;::::0;-1:-1:-1;;;70104:29:0;;11762:2:1;70104:29:0::1;::::0;::::1;11744:21:1::0;11801:2;11781:18;;;11774:30;-1:-1:-1;;;11820:18:1;;;11813:49;11879:18;;70104:29:0::1;11560:343:1::0;70066:75:0::1;70235:22;::::0;-1:-1:-1;;;70235:22:0;;::::1;::::0;::::1;5461:25:1::0;;;70209:10:0::1;::::0;70269:4:::1;::::0;70209:10;;70235:13:::1;::::0;5434:18:1;;70235:22:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;70235:39:0::1;;70227:71;;;::::0;-1:-1:-1;;;70227:71:0;;12366:2:1;70227:71:0::1;::::0;::::1;12348:21:1::0;12405:2;12385:18;;;12378:30;-1:-1:-1;;;12424:18:1;;;12417:49;12483:18;;70227:71:0::1;12164:343:1::0;70227:71:0::1;70305:32;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70305:32:0::1;70522:17;70534:4;;70522:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;70522:11:0::1;::::0;-1:-1:-1;;;70522:17:0:i:1;:::-;70489:23;::::0;::::1;70344:195:::0;-1:-1:-1;;;;;70344:195:0::1;70451:29;::::0;::::1;70344:195:::0;70412:30:::1;::::0;::::1;70344:195:::0;70383:20:::1;::::0;::::1;70344:195:::0;;;;;;70602:10:::1;::::0;;70562:13:::1;12928:12:::0;;12733:7;12912:13;:28;;12680:291;70562:13:::1;:36;;;;:::i;:::-;:50;;70546:102;;;::::0;-1:-1:-1;;;70546:102:0;;11055:2:1;70546:102:0::1;::::0;::::1;11037:21:1::0;11094:2;11074:18;;;11067:30;-1:-1:-1;;;11113:18:1;;;11106:48;11171:18;;70546:102:0::1;10853:342:1::0;70546:102:0::1;70667:21:::0;;:32;::::1;;::::0;:86:::1;;-1:-1:-1::0;70710:29:0::1;::::0;::::1;::::0;-1:-1:-1;;;;;70710:43:0::1;70743:10;70710:43;;70667:86;70655:150;;;70770:27;::::0;-1:-1:-1;;;70770:27:0;;12714:2:1;70770:27:0::1;::::0;::::1;12696:21:1::0;12753:2;12733:18;;;12726:30;-1:-1:-1;;;12772:18:1;;;12765:47;12829:18;;70770:27:0::1;12512:341:1::0;70655:150:0::1;70861:10;;70827:12;:30;;;:44;70811:97;;;::::0;-1:-1:-1;;;70811:97:0;;13060:2:1;70811:97:0::1;::::0;::::1;13042:21:1::0;13099:2;13079:18;;;13072:30;-1:-1:-1;;;13118:18:1;;;13111:49;13177:18;;70811:97:0::1;12858:343:1::0;70811:97:0::1;70939:21;::::0;-1:-1:-1;;;;;15151:25:0;;15122:6;15151:25;;;:18;:25;;;;;;9427:3;15151:39;70923:37:::1;70915:68;;;::::0;-1:-1:-1;;;70915:68:0;;13408:2:1;70915:68:0::1;::::0;::::1;13390:21:1::0;13447:2;13427:18;;;13420:30;-1:-1:-1;;;13466:18:1;;;13459:48;13524:18;;70915:68:0::1;13206:342:1::0;70915:68:0::1;71002:202;71028:12;:20;;;71059:12;:21;;;71091:12;:30;;;71132:12;:29;;;71172:12;:23;;;71002:15;:202::i;:::-;:210;;71208:4;71002:210;70990:290;;71236:36;::::0;-1:-1:-1;;;71236:36:0;;13755:2:1;71236:36:0::1;::::0;::::1;13737:21:1::0;13794:2;13774:18;;;13767:30;-1:-1:-1;;;13813:18:1;;;13806:46;13869:18;;71236:36:0::1;13553:340:1::0;70990:290:0::1;71320:13;::::0;71286:57:::1;::::0;-1:-1:-1;;;71286:57:0;;71313:4:::1;71286:57;::::0;::::1;14138:34:1::0;-1:-1:-1;;;;;71320:13:0;;::::1;14188:18:1::0;;;14181:43;14240:18;;;14233:34;;;71286:18:0;;::::1;::::0;::::1;::::0;14073::1;;71286:57:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;71423:4;-1:-1:-1::0;;;;;71355:196:0::1;71373:12;:29;;;-1:-1:-1::0;;;;;71355:196:0::1;;71446:12;:20;;;71485:14;12440:7:::0;12463:13;;12393:89;71485:14:::1;71355:196;::::0;;14480:25:1;;;14536:2;14521:18;;14514:34;;;;14564:18;;14557:34;;;14468:2;14453:18;71355:196:0::1;;;;;;;71558:33;71564:4;71570:12;:20;;;71558:5;:33::i;:::-;71598:32;71606:4;71612:13;71620:4;-1:-1:-1::0;;;;;15151:25:0;15122:6;15151:25;;;:18;:25;;;;;;9427:3;15151:39;;15067:130;71612:13:::1;:17;::::0;71628:1:::1;71612:17;:::i;:::-;71598:7;:32::i;:::-;-1:-1:-1::0;;62840:1:0;63726:7;:22;-1:-1:-1;;;;71644:41:0;69908:1783;-1:-1:-1;;;;;69908:1783:0:o;29131:2519::-;29247:27;29277;29296:7;29277:18;:27::i;:::-;29247:57;;29356:4;-1:-1:-1;;;;;29315:45:0;29331:19;-1:-1:-1;;;;;29315:45:0;;29311:93;;29376:28;;-1:-1:-1;;;29376:28:0;;;;;;;;;;;29311:93;29420:27;27981:21;;;27828:15;28017:4;28010:36;28093:4;28077:21;;28171:26;;42704:10;28856:30;;;-1:-1:-1;;;;;28578:26:0;;28835:19;;;28832:55;29602:177;;29683:43;29700:4;42704:10;21305:186;:::i;29683:43::-;29678:101;;29744:35;;-1:-1:-1;;;29744:35:0;;;;;;;;;;;29678:101;-1:-1:-1;;;;;29790:16:0;;29786:52;;29815:23;;-1:-1:-1;;;29815:23:0;;;;;;;;;;;29786:52;29965:15;29962:138;;;30089:1;30068:19;30061:30;29962:138;-1:-1:-1;;;;;30444:24:0;;;;;;;:18;:24;;;;;;30442:26;;-1:-1:-1;;30442:26:0;;;30507:22;;;;;;;;;30505:24;;-1:-1:-1;30505:24:0;;;18529:11;18505:22;18501:40;18488:62;-1:-1:-1;;;18488:62:0;30762:26;;;;:17;:26;;;;;:152;-1:-1:-1;;;31020:46:0;;31016:534;;31116:1;31106:11;;31084:19;31223:30;;;:17;:30;;;;;;31219:322;;31341:13;;31326:11;:28;31322:208;;31464:30;;;;:17;:30;;;;;:52;;;31322:208;31073:477;31016:534;31587:7;31583:2;-1:-1:-1;;;;;31568:27:0;31577:4;-1:-1:-1;;;;;31568:27:0;;;;;;;;;;;29240:2410;;;29131:2519;;;:::o;21554:165::-;21674:39;21691:4;21697:2;21701:7;21674:39;;;;;;;;;;;;:16;:39::i;:::-;21554:165;;;:::o;64709:95::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;66921:153::-;67215:7;;-1:-1:-1;;;;;67215:7:0;42704:10;67215:23;;:50;;-1:-1:-1;43858:6:0;;-1:-1:-1;;;;;43858:6:0;42704:10;67242:23;67215:50;67199:108;;;;-1:-1:-1;;;67199:108:0;;;;;;;:::i;:::-;67024:21:::1;:44:::0;66921:153::o;69037:338::-;69217:19;69273:7;69289:6;69304:16;69329:15;69353:9;69254:115;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;69245:124;;69037:338;;;;;;;:::o;18616:138::-;18680:7;18719:27;18738:7;18719:18;:27::i;66816:99::-;67215:7;;-1:-1:-1;;;;;67215:7:0;42704:10;67215:23;;:50;;-1:-1:-1;43858:6:0;;-1:-1:-1;;;;;43858:6:0;42704:10;67242:23;67215:50;67199:108;;;;-1:-1:-1;;;67199:108:0;;;;;;;:::i;:::-;66886:10:::1;:23:::0;66816:99::o;66106:118::-;67215:7;;-1:-1:-1;;;;;67215:7:0;42704:10;67215:23;;:50;;-1:-1:-1;43858:6:0;;-1:-1:-1;;;;;43858:6:0;42704:10;67242:23;67215:50;67199:108;;;;-1:-1:-1;;;67199:108:0;;;;;;;:::i;:::-;66188:30;;::::1;::::0;:14:::1;::::0;:30:::1;::::0;::::1;::::0;::::1;:::i;14211:214::-:0;14275:7;-1:-1:-1;;;;;14295:19:0;;14291:60;;14323:28;;-1:-1:-1;;;14323:28:0;;;;;;;;;;;14291:60;-1:-1:-1;;;;;;14365:25:0;;;;;:18;:25;;;;;;9074:13;14365:54;;14211:214::o;44400:97::-;43858:6;;-1:-1:-1;;;;;43858:6:0;42704:10;43991:23;43983:68;;;;-1:-1:-1;;;43983:68:0;;;;;;;:::i;:::-;44461:30:::1;44488:1;44461:18;:30::i;:::-;44400:97::o:0;67080:81::-;43858:6;;-1:-1:-1;;;;;43858:6:0;42704:10;43991:23;43983:68;;;;-1:-1:-1;;;43983:68:0;;;;;;;:::i;:::-;67139:7:::1;:16:::0;;-1:-1:-1;;;;;;67139:16:0::1;-1:-1:-1::0;;;;;67139:16:0;;;::::1;::::0;;;::::1;::::0;;67080:81::o;69381:314::-;69467:15;69491:14;69514:24;69547:23;69579:22;69637:6;69626:63;;;;;;;;;;;;:::i;:::-;69619:70;;;;-1:-1:-1;69619:70:0;;-1:-1:-1;69619:70:0;-1:-1:-1;69619:70:0;;-1:-1:-1;69381:314:0;-1:-1:-1;;69381:314:0:o;18968:98::-;19024:13;19053:7;19046:14;;;;;:::i;20932:310::-;-1:-1:-1;;;;;21045:31:0;;42704:10;21045:31;21041:61;;;21085:17;;-1:-1:-1;;;21085:17:0;;;;;;;;;;;21041:61;42704:10;21109:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;21109:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;21109:60:0;;;;;;;;;;21181:55;;540:41:1;;;21109:49:0;;42704:10;21181:55;;513:18:1;21181:55:0;;;;;;;20932:310;;:::o;21782:351::-;21927:31;21940:4;21946:2;21950:7;21927:12;:31::i;:::-;-1:-1:-1;;;;;21969:14:0;;;:19;21965:163;;22002:56;22033:4;22039:2;22043:7;22052:5;22002:30;:56::i;:::-;21997:131;;22078:40;;-1:-1:-1;;;22078:40:0;;;;;;;;;;;21997:131;21782:351;;;;:::o;64809:40::-;;;;;;;:::i;65676:402::-;65774:13;65804:16;65812:7;65804;:16::i;:::-;65799:59;;65829:29;;-1:-1:-1;;;65829:29:0;;;;;;;;;;;65799:59;65865:21;65889:10;:8;:10::i;:::-;65865:34;;65906:20;65929:9;:7;:9::i;:::-;65906:32;;65965:7;65959:21;65984:1;65959:26;;:113;;;;;;;;;;;;;;;;;66021:7;66030:18;66040:7;66030:9;:18::i;:::-;66050:6;66004:53;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;65959:113;65945:127;65676:402;-1:-1:-1;;;;65676:402:0:o;66359:115::-;67215:7;;-1:-1:-1;;;;;67215:7:0;42704:10;67215:23;;:50;;-1:-1:-1;43858:6:0;;-1:-1:-1;;;;;43858:6:0;42704:10;67242:23;67215:50;67199:108;;;;-1:-1:-1;;;67199:108:0;;;;;;;:::i;:::-;66442:26:::1;66450:10;66462:5;66442:7;:26::i;44642:191::-:0;43858:6;;-1:-1:-1;;;;;43858:6:0;42704:10;43991:23;43983:68;;;;-1:-1:-1;;;43983:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;44727:22:0;::::1;44719:73;;;::::0;-1:-1:-1;;;44719:73:0;;17036:2:1;44719:73:0::1;::::0;::::1;17018:21:1::0;17075:2;17055:18;;;17048:30;17114:34;17094:18;;;17087:62;-1:-1:-1;;;17165:18:1;;;17158:36;17211:19;;44719:73:0::1;16834:402:1::0;44719:73:0::1;44799:28;44818:8;44799:18;:28::i;:::-;44642:191:::0;:::o;22372:249::-;22429:4;22503:13;;22493:7;:23;22456:140;;;;-1:-1:-1;;22548:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;22548:43:0;:48;;22372:249::o;22697:98::-;22762:27;22772:2;22776:8;22762:27;;;;;;;;;;;;:9;:27::i;67897:487::-;67572:72;;;;;;;18202:19:1;;;18237:12;;;18230:28;;;18274:12;;;;18267:28;;;18329:15;;;-1:-1:-1;;18325:53:1;18311:12;;;18304:75;67572:72:0;;;;;;;;;18395:13:1;;;67572:72:0;;67552:101;;;;;;18661:66:1;67810::0;;;18649:79:1;18744:12;;;;18737:28;;;67810:66:0;;;;;;;;;;18781:12:1;;;;67810:66:0;;;67790:95;;;;;68364:14;;-1:-1:-1;;67552:101:0;67790:95;-1:-1:-1;;;;;68364:14:0;68314:46;67790:95;68350:9;68314:13;:46::i;:::-;-1:-1:-1;;;;;68314:64:0;;;67897:487;-1:-1:-1;;;;;;;;67897:487:0:o;23993:1345::-;24054:20;24077:13;-1:-1:-1;;;;;24101:16:0;;24097:48;;24126:19;;-1:-1:-1;;;24126:19:0;;;;;;;;;;;24097:48;24156:13;24152:44;;24178:18;;-1:-1:-1;;;24178:18:0;;;;;;;;;;;24152:44;-1:-1:-1;;;;;24624:22:0;;;;;;:18;:22;;9205:2;24624:22;;:70;;24662:31;24650:44;;24624:70;;;18529:11;18505:22;18501:40;-1:-1:-1;20192:15:0;;20167:23;20163:45;18498:51;18488:62;24899:31;;;;:17;:31;;;;;:151;24917:12;25112:23;;;25144:87;25163:35;;25188:9;;;;;-1:-1:-1;;;;;25163:35:0;;;25180:1;;25163:35;;25180:1;;25163:35;25226:3;25216:7;:13;25144:87;;25239:13;:19;-1:-1:-1;21554:165:0;;;:::o;15375:358::-;-1:-1:-1;;;;;15452:25:0;;;15435:14;15452:25;;;:18;:25;;;;;;;-1:-1:-1;;;;;15626:31:0;9427:3;15662:23;;;;15625:61;;;;15693:34;;15375:358::o;15807:913::-;15874:7;15905;15987:13;;15980:4;:20;15976:687;;;16015:14;16032:23;;;:17;:23;;;;;;-1:-1:-1;;;16101:23:0;;16097:555;;16524:87;16531:11;16524:87;;-1:-1:-1;;;16588:6:0;16570:25;;;;:17;:25;;;;;;16524:87;;;16632:6;15807:913;-1:-1:-1;;;15807:913:0:o;16097:555::-;16002:661;15976:687;16683:31;;-1:-1:-1;;;16683:31:0;;;;;;;;;;;44983:177;45072:6;;;-1:-1:-1;;;;;45085:17:0;;;-1:-1:-1;;;;;;45085:17:0;;;;;;;45114:40;;45072:6;;;45085:17;45072:6;;45114:40;;45053:16;;45114:40;45046:114;44983:177;:::o;35232:659::-;35401:133;;-1:-1:-1;;;35401:133:0;;35377:4;;-1:-1:-1;;;;;35401:45:0;;;;;:133;;42704:10;;35487:4;;35502:7;;35520:5;;35401:133;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35401:133:0;;;;;;;;-1:-1:-1;;35401:133:0;;;;;;;;;;;;:::i;:::-;;;35390:496;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35694:13:0;;35690:189;;35732:40;;-1:-1:-1;;;35732:40:0;;;;;;;;;;;35690:189;35851:6;35845:13;35836:6;35832:2;35828:15;35821:38;35390:496;-1:-1:-1;;;;;;35580:64:0;-1:-1:-1;;;35580:64:0;;-1:-1:-1;35232:659:0;;;;;;:::o;65454:109::-;65514:13;65543:14;65536:21;;;;;:::i;65569:101::-;65619:13;65648:16;65641:23;;;;;:::i;39489:1716::-;39924:4;39918:11;;39931:3;39914:21;;39997:17;;;;40615:11;;;40510:5;40731:2;40745;40735:13;;40727:22;40615:11;40714:36;40778:2;40768:13;;40418:583;40791:4;40418:583;;;40944:1;40939:3;40935:11;40928:18;;40987:2;40981:4;40977:13;40973:2;40969:22;40964:3;40956:36;40870:2;40860:13;;40418:583;;;-1:-1:-1;41023:13:0;;;-1:-1:-1;;41126:12:0;;;41174:19;;;41126:12;39489:1716;-1:-1:-1;39489:1716:0:o;23183:559::-;23288:19;23294:2;23298:8;23288:5;:19::i;:::-;-1:-1:-1;;;;;23337:14:0;;;:19;23333:397;;23369:11;23383:13;23423:14;;;23448:193;23469:62;23508:1;23512:2;23516:7;;;;;;23525:5;23469:30;:62::i;:::-;23464:145;;23555:40;;-1:-1:-1;;;23555:40:0;;;;;;;;;;;23464:145;23636:3;23628:5;:11;23448:193;;23707:3;23690:13;;:20;23686:34;;23712:8;;;23686:34;23358:372;;23183:559;;;:::o;68390:256::-;68506:7;68526:9;68537;68548:7;68559:26;68574:10;68559:14;:26::i;:::-;68599:41;;;;;;;;;;;;19031:25:1;;;19104:4;19092:17;;19072:18;;;19065:45;;;;19126:18;;;19119:34;;;19169:18;;;19162:34;;;68525:60:0;;-1:-1:-1;68525:60:0;;-1:-1:-1;68525:60:0;-1:-1:-1;68599:41:0;;19003:19:1;;68599:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68599:41:0;;-1:-1:-1;;68599:41:0;;;68390:256;-1:-1:-1;;;;;;;68390:256:0:o;68652:379::-;68739:9;68757;68775:7;68804:3;:10;68818:2;68804:16;68800:98;;68838:52;;-1:-1:-1;;;68838:52:0;;19409:2:1;68838:52:0;;;19391:21:1;;;19428:18;;;19421:30;19487:34;19467:18;;;19460:62;19539:18;;68838:52:0;19207:356:1;68800:98:0;-1:-1:-1;;;68942:2:0;68933:12;;68927:19;68974:2;68965:12;;68959:19;69014:2;69005:12;;;68999:19;68927;;68996:1;68991:28;;;;;68652:379::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:131::-;-1:-1:-1;;;;;667:31:1;;657:42;;647:70;;713:1;710;703:12;728:247;787:6;840:2;828:9;819:7;815:23;811:32;808:52;;;856:1;853;846:12;808:52;895:9;882:23;914:31;939:5;914:31;:::i;980:258::-;1052:1;1062:113;1076:6;1073:1;1070:13;1062:113;;;1152:11;;;1146:18;1133:11;;;1126:39;1098:2;1091:10;1062:113;;;1193:6;1190:1;1187:13;1184:48;;;-1:-1:-1;;1228:1:1;1210:16;;1203:27;980:258::o;1243:::-;1285:3;1323:5;1317:12;1350:6;1345:3;1338:19;1366:63;1422:6;1415:4;1410:3;1406:14;1399:4;1392:5;1388:16;1366:63;:::i;:::-;1483:2;1462:15;-1:-1:-1;;1458:29:1;1449:39;;;;1490:4;1445:50;;1243:258;-1:-1:-1;;1243:258:1:o;1506:220::-;1655:2;1644:9;1637:21;1618:4;1675:45;1716:2;1705:9;1701:18;1693:6;1675:45;:::i;1731:180::-;1790:6;1843:2;1831:9;1822:7;1818:23;1814:32;1811:52;;;1859:1;1856;1849:12;1811:52;-1:-1:-1;1882:23:1;;1731:180;-1:-1:-1;1731:180:1:o;2124:315::-;2192:6;2200;2253:2;2241:9;2232:7;2228:23;2224:32;2221:52;;;2269:1;2266;2259:12;2221:52;2308:9;2295:23;2327:31;2352:5;2327:31;:::i;:::-;2377:5;2429:2;2414:18;;;;2401:32;;-1:-1:-1;;;2124:315:1:o;2444:::-;2512:6;2520;2573:2;2561:9;2552:7;2548:23;2544:32;2541:52;;;2589:1;2586;2579:12;2541:52;2625:9;2612:23;2602:33;;2685:2;2674:9;2670:18;2657:32;2698:31;2723:5;2698:31;:::i;:::-;2748:5;2738:15;;;2444:315;;;;;:::o;2764:127::-;2825:10;2820:3;2816:20;2813:1;2806:31;2856:4;2853:1;2846:15;2880:4;2877:1;2870:15;2896:275;2967:2;2961:9;3032:2;3013:13;;-1:-1:-1;;3009:27:1;2997:40;;3067:18;3052:34;;3088:22;;;3049:62;3046:88;;;3114:18;;:::i;:::-;3150:2;3143:22;2896:275;;-1:-1:-1;2896:275:1:o;3176:187::-;3225:4;3258:18;3250:6;3247:30;3244:56;;;3280:18;;:::i;:::-;-1:-1:-1;3346:2:1;3325:15;-1:-1:-1;;3321:29:1;3352:4;3317:40;;3176:187::o;3368:338::-;3433:5;3462:53;3478:36;3507:6;3478:36;:::i;:::-;3462:53;:::i;:::-;3453:62;;3538:6;3531:5;3524:21;3578:3;3569:6;3564:3;3560:16;3557:25;3554:45;;;3595:1;3592;3585:12;3554:45;3644:6;3639:3;3632:4;3625:5;3621:16;3608:43;3698:1;3691:4;3682:6;3675:5;3671:18;3667:29;3660:40;3368:338;;;;;:::o;3711:451::-;3780:6;3833:2;3821:9;3812:7;3808:23;3804:32;3801:52;;;3849:1;3846;3839:12;3801:52;3889:9;3876:23;3922:18;3914:6;3911:30;3908:50;;;3954:1;3951;3944:12;3908:50;3977:22;;4030:4;4022:13;;4018:27;-1:-1:-1;4008:55:1;;4059:1;4056;4049:12;4008:55;4082:74;4148:7;4143:2;4130:16;4125:2;4121;4117:11;4082:74;:::i;4167:936::-;4264:6;4272;4280;4288;4296;4349:3;4337:9;4328:7;4324:23;4320:33;4317:53;;;4366:1;4363;4356:12;4317:53;4405:9;4392:23;4424:31;4449:5;4424:31;:::i;:::-;4474:5;-1:-1:-1;4531:2:1;4516:18;;4503:32;4544:33;4503:32;4544:33;:::i;:::-;4596:7;-1:-1:-1;4650:2:1;4635:18;;4622:32;;-1:-1:-1;4705:2:1;4690:18;;4677:32;4728:18;4758:14;;;4755:34;;;4785:1;4782;4775:12;4755:34;4823:6;4812:9;4808:22;4798:32;;4868:7;4861:4;4857:2;4853:13;4849:27;4839:55;;4890:1;4887;4880:12;4839:55;4930:2;4917:16;4956:2;4948:6;4945:14;4942:34;;;4972:1;4969;4962:12;4942:34;5017:7;5012:2;5003:6;4999:2;4995:15;4991:24;4988:37;4985:57;;;5038:1;5035;5028:12;4985:57;4167:936;;;;-1:-1:-1;4167:936:1;;-1:-1:-1;5069:2:1;5061:11;;5091:6;4167:936;-1:-1:-1;;;4167:936:1:o;5497:456::-;5574:6;5582;5590;5643:2;5631:9;5622:7;5618:23;5614:32;5611:52;;;5659:1;5656;5649:12;5611:52;5698:9;5685:23;5717:31;5742:5;5717:31;:::i;:::-;5767:5;-1:-1:-1;5824:2:1;5809:18;;5796:32;5837:33;5796:32;5837:33;:::i;:::-;5497:456;;5889:7;;-1:-1:-1;;;5943:2:1;5928:18;;;;5915:32;;5497:456::o;5958:221::-;6000:5;6053:3;6046:4;6038:6;6034:17;6030:27;6020:55;;6071:1;6068;6061:12;6020:55;6093:80;6169:3;6160:6;6147:20;6140:4;6132:6;6128:17;6093:80;:::i;6184:661::-;6288:6;6296;6304;6312;6320;6373:3;6361:9;6352:7;6348:23;6344:33;6341:53;;;6390:1;6387;6380:12;6341:53;6426:9;6413:23;6403:33;;6483:2;6472:9;6468:18;6455:32;6445:42;;6534:2;6523:9;6519:18;6506:32;6496:42;;6588:2;6577:9;6573:18;6560:32;6601:31;6626:5;6601:31;:::i;:::-;6651:5;-1:-1:-1;6707:3:1;6692:19;;6679:33;6735:18;6724:30;;6721:50;;;6767:1;6764;6757:12;6721:50;6790:49;6831:7;6822:6;6811:9;6807:22;6790:49;:::i;:::-;6780:59;;;6184:661;;;;;;;;:::o;7073:320::-;7141:6;7194:2;7182:9;7173:7;7169:23;7165:32;7162:52;;;7210:1;7207;7200:12;7162:52;7250:9;7237:23;7283:18;7275:6;7272:30;7269:50;;;7315:1;7312;7305:12;7269:50;7338:49;7379:7;7370:6;7359:9;7355:22;7338:49;:::i;7398:531::-;7657:6;7646:9;7639:25;7700:6;7695:2;7684:9;7680:18;7673:34;7743:6;7738:2;7727:9;7723:18;7716:34;7815:1;7811;7806:3;7802:11;7798:19;7790:6;7786:32;7781:2;7770:9;7766:18;7759:60;7856:3;7850;7839:9;7835:19;7828:32;7620:4;7877:46;7918:3;7907:9;7903:19;7895:6;7877:46;:::i;:::-;7869:54;7398:531;-1:-1:-1;;;;;;;7398:531:1:o;7934:416::-;7999:6;8007;8060:2;8048:9;8039:7;8035:23;8031:32;8028:52;;;8076:1;8073;8066:12;8028:52;8115:9;8102:23;8134:31;8159:5;8134:31;:::i;:::-;8184:5;-1:-1:-1;8241:2:1;8226:18;;8213:32;8283:15;;8276:23;8264:36;;8254:64;;8314:1;8311;8304:12;8355:665;8450:6;8458;8466;8474;8527:3;8515:9;8506:7;8502:23;8498:33;8495:53;;;8544:1;8541;8534:12;8495:53;8583:9;8570:23;8602:31;8627:5;8602:31;:::i;:::-;8652:5;-1:-1:-1;8709:2:1;8694:18;;8681:32;8722:33;8681:32;8722:33;:::i;:::-;8774:7;-1:-1:-1;8828:2:1;8813:18;;8800:32;;-1:-1:-1;8883:2:1;8868:18;;8855:32;8910:18;8899:30;;8896:50;;;8942:1;8939;8932:12;8896:50;8965:49;9006:7;8997:6;8986:9;8982:22;8965:49;:::i;:::-;8955:59;;;8355:665;;;;;;;:::o;9025:427::-;9092:6;9100;9153:2;9141:9;9132:7;9128:23;9124:32;9121:52;;;9169:1;9166;9159:12;9121:52;9208:9;9195:23;9227:31;9252:5;9227:31;:::i;:::-;9277:5;-1:-1:-1;9334:2:1;9319:18;;9306:32;9382:18;9369:32;;9357:45;;9347:73;;9416:1;9413;9406:12;9457:388;9525:6;9533;9586:2;9574:9;9565:7;9561:23;9557:32;9554:52;;;9602:1;9599;9592:12;9554:52;9641:9;9628:23;9660:31;9685:5;9660:31;:::i;:::-;9710:5;-1:-1:-1;9767:2:1;9752:18;;9739:32;9780:33;9739:32;9780:33;:::i;9850:348::-;10052:2;10034:21;;;10091:2;10071:18;;;10064:30;10130:26;10125:2;10110:18;;10103:54;10189:2;10174:18;;9850:348::o;10203:380::-;10282:1;10278:12;;;;10325;;;10346:61;;10400:4;10392:6;10388:17;10378:27;;10346:61;10453:2;10445:6;10442:14;10422:18;10419:38;10416:161;;;10499:10;10494:3;10490:20;10487:1;10480:31;10534:4;10531:1;10524:15;10562:4;10559:1;10552:15;10416:161;;10203:380;;;:::o;10588:127::-;10649:10;10644:3;10640:20;10637:1;10630:31;10680:4;10677:1;10670:15;10704:4;10701:1;10694:15;10720:128;10760:3;10791:1;10787:6;10784:1;10781:13;10778:39;;;10797:18;;:::i;:::-;-1:-1:-1;10833:9:1;;10720:128::o;11908:251::-;11978:6;12031:2;12019:9;12010:7;12006:23;12002:32;11999:52;;;12047:1;12044;12037:12;11999:52;12079:9;12073:16;12098:31;12123:5;12098:31;:::i;14602:236::-;14641:3;14669:18;14714:2;14711:1;14707:10;14744:2;14741:1;14737:10;14775:3;14771:2;14767:12;14762:3;14759:21;14756:47;;;14783:18;;:::i;:::-;14819:13;;14602:236;-1:-1:-1;;;;14602:236:1:o;14843:356::-;15045:2;15027:21;;;15064:18;;;15057:30;15123:34;15118:2;15103:18;;15096:62;15190:2;15175:18;;14843:356::o;15204:956::-;15327:6;15335;15343;15351;15359;15412:3;15400:9;15391:7;15387:23;15383:33;15380:53;;;15429:1;15426;15419:12;15380:53;15458:9;15452:16;15442:26;;15508:2;15497:9;15493:18;15487:25;15477:35;;15552:2;15541:9;15537:18;15531:25;15521:35;;15599:2;15588:9;15584:18;15578:25;15612:31;15637:5;15612:31;:::i;:::-;15711:3;15696:19;;15690:26;15662:5;;-1:-1:-1;15739:18:1;15728:30;;15725:50;;;15771:1;15768;15761:12;15725:50;15794:22;;15847:4;15839:13;;15835:27;-1:-1:-1;15825:55:1;;15876:1;15873;15866:12;15825:55;15905:2;15899:9;15930:49;15946:32;15975:2;15946:32;:::i;15930:49::-;16002:2;15995:5;15988:17;16042:7;16037:2;16032;16028;16024:11;16020:20;16017:33;16014:53;;;16063:1;16060;16053:12;16014:53;16076:54;16127:2;16122;16115:5;16111:14;16106:2;16102;16098:11;16076:54;:::i;:::-;16149:5;16139:15;;;;;15204:956;;;;;;;;:::o;16165:664::-;16392:3;16430:6;16424:13;16446:53;16492:6;16487:3;16480:4;16472:6;16468:17;16446:53;:::i;:::-;16562:13;;16521:16;;;;16584:57;16562:13;16521:16;16618:4;16606:17;;16584:57;:::i;:::-;16708:13;;16663:20;;;16730:57;16708:13;16663:20;16764:4;16752:17;;16730:57;:::i;:::-;16803:20;;16165:664;-1:-1:-1;;;;;16165:664:1:o;17241:489::-;-1:-1:-1;;;;;17510:15:1;;;17492:34;;17562:15;;17557:2;17542:18;;17535:43;17609:2;17594:18;;17587:34;;;17657:3;17652:2;17637:18;;17630:31;;;17435:4;;17678:46;;17704:19;;17696:6;17678:46;:::i;:::-;17670:54;17241:489;-1:-1:-1;;;;;;17241:489:1:o;17735:249::-;17804:6;17857:2;17845:9;17836:7;17832:23;17828:32;17825:52;;;17873:1;17870;17863:12;17825:52;17905:9;17899:16;17924:30;17948:5;17924:30;:::i
Swarm Source
ipfs://33d295fd7c5f4dc1a8999fecc428f60af084ca85c86444b499a3794c62ffd907
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.