Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
0 PCC
Holders
13
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
0 PCCLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ProticoChattingChip
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-12-04 */ // File: @openzeppelin/contracts/utils/Counters.sol // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @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() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: @openzeppelin/contracts/interfaces/IERC1271.sol // OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. * * _Available since v4.1._ */ interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param hash Hash of the data to be signed * @param signature Signature byte array associated with _data */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @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`. * * 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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * 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); } // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @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); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @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 // Deprecated in v4.8 } 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"); } } /** * @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) { 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. /// @solidity memory-safe-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 { 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 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)); } } // File: @openzeppelin/contracts/utils/cryptography/SignatureChecker.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/SignatureChecker.sol) pragma solidity ^0.8.0; /** * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like * Argent and Gnosis Safe. * * _Available since v4.1._ */ library SignatureChecker { /** * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`. * * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus * change through time. It could return true at block N and false at block N+1 (or the opposite). */ function isValidSignatureNow( address signer, bytes32 hash, bytes memory signature ) internal view returns (bool) { (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature); if (error == ECDSA.RecoverError.NoError && recovered == signer) { return true; } (bool success, bytes memory result) = signer.staticcall( abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature) ); return (success && result.length == 32 && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector)); } } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/token/ERC721/ERC721.sol // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // 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; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @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) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @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, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), 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-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @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 { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @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. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @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`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a 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 _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256, /* firstTokenId */ uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} } // File: @openzeppelin/contracts/access/IAccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File: @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File: contracts/Easter Egg.sol //SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; library AddressMap { struct Map { address[] keys; mapping(address => bool) values; mapping(address => uint) indexOf; } function get(Map storage map, address key) public view returns (bool) { return map.values[key]; } function getKeyAtIndex(Map storage map, uint index) public view returns (address) { return map.keys[index]; } function size(Map storage map) public view returns (uint) { return map.keys.length; } function set( Map storage map, address key ) public { if (!map.values[key]) { map.values[key] = true; map.indexOf[key] = map.keys.length; map.keys.push(key); } } function remove(Map storage map, address key) public { if (!map.values[key]) { return; } delete map.values[key]; uint index = map.indexOf[key]; uint lastIndex = map.keys.length - 1; address lastKey = map.keys[lastIndex]; map.indexOf[lastKey] = index; delete map.indexOf[key]; map.keys[index] = lastKey; map.keys.pop(); } } contract ProticoChattingChip is ERC721, ReentrancyGuard, AccessControl { using SignatureChecker for address; using Counters for Counters.Counter; using AddressMap for AddressMap.Map; Counters.Counter private _tokenIdCounter; uint256 constant MaxSupply = 30000; uint256 constant MaxPerDomain = 1000; bytes32[30] private _sites = [ bytes32(0x9649c7eb6df175f417fcfb2eeeaf6e39367ec7a45034048a3d5cff5e2ea8519f), bytes32(0x45a2112d850d7101c902a913c185ba0d28e0ecdcfd1d540e2497f2750714f69a), bytes32(0x0445d458f1aa05b40e476e9a57218b91110ad2174ae15f7057715e84693f7100), bytes32(0xeb867819c51fbf7d44c73a332082c0b6142546289310c6ff4fac832120012ed3), bytes32(0x89ae9c604bc971f8b6a5aee73a1c4e71c952d16a3bcf995e1642f2db167bc5a7), bytes32(0x9f514643ee17437be8788be62d7db6953296791a2ad0db024063a20a97a08682), bytes32(0x94d13d04140fd5b04a3196ba600a958460fc847c28b74d6e9c1f26bb50c56b45), bytes32(0x9e01a36b730e791ed57eabb8379758d7601ffc79b6d613cb7744191938672887), bytes32(0x1345e844ae191c4c9f5ed685ecca259e4530dec934838661f002fc3ac3c3b83c), bytes32(0x588e7f25cc1ab5b40a3b6770561d285a5299071e36dbffe3cba46f5360110f5d), bytes32(0x6449d685d467441665612dc60098ae2a5f0e16d0e60f1d9d0b63e3c037c5df8d), bytes32(0xc9fc5126b89092478eb63279a7cd259ea24c24bc945b91b5c8366967b05ee6d1), bytes32(0x574014404853e93615346db284ca5bd068542f139762d459e11e64fee33e7abd), bytes32(0x0e84102fc2bc70ee46419905395f8fb46f7c0be0c9e694e4e699b087cde9be16), bytes32(0xd14db021bc6bdaf39de490427d6a1e0e265463ff19e83094dc76f0d3150fc716), bytes32(0x4c85a4f44366822767ab3fa89b6b2a8cf6b30a44a96152d7c26a77f634f9cbe0), bytes32(0xf0ca7fdd544d43a37b1fd3242551a298fbfed3edb8403c9e925c4cde8c19fe8e), bytes32(0x207eeb1c4a1ac75d8ac74d64bfabb5e81199384099507fa4233771c134adad72), bytes32(0x131e81156f0505f36093d6b4d5e6f14643b9f367da7fd717f3239c1599c620a8), bytes32(0x2ccc2d85ad9b8899ddbad3cef1c367ed84bf8d19014acd04588e48f6e837436e), bytes32(0x702c587833b68bf050b53037adba2bb8f7f93d875c5a372389d8d6987074f503), bytes32(0xb0af795fa00c85296c52b9fa3873a6acb561de2ac8e8ae0a84338bfbbcb6a3d7), bytes32(0xa57c78e6f3324d0ef1b1412366a8b123674f9423dd1effc63656d7e48d05bc30), bytes32(0xf7f00296c339c4e3d3b2aa84cbe9a6cadb9d8aabd2eb784064fb12ecf2029b0e), bytes32(0xbf9c1eb5724df6704047f4b9f5ddb73e21e53efedd725685ab9d9820c5dc99b2), bytes32(0xcc57ea92f884c55cc87b03761c95b7d99a2324f4baec0a72a0df10cbab77911b), bytes32(0xdc6ab7e871c6a47b07c00e6bbd11ee902e47d00afc2191d614116b87900973dc), bytes32(0xf2e4f0dcb4243c2dc76aeee61f15ba1d87db55775678f6d67d7a49130db786e4), bytes32(0x3a95202072e7adc1c3e2598fd97fd22472790fb26ec4f768f6b77c4c12995fb2), bytes32(0x6ce43a2f8178c89cac275597661b9ce9f6b7ef6a93e8c97b0ccf437dad1e511e) ]; mapping(bytes32 => AddressMap.Map) private _list; mapping(bytes32 => bool) private _siteExists; string private _tokenURI; constructor() ERC721("Protico Chatting Chip", "PCC") { _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); _tokenURI = "ipfs://QmWn9Lcv4PhFq1FEXXQjphkQyVaY4ewv1g1cxdYd4fTzBr"; for (uint i; i < _sites.length; i++) { _siteExists[_sites[i]] = true; } } function mint( string memory _http, bytes memory _signature ) external nonReentrant { uint256 tokenId = _tokenIdCounter.current(); require(tokenId < MaxSupply, "Not claimable"); bytes32 hashedDomain = keccak256(abi.encodePacked(_http)); require(_siteExists[hashedDomain], "Domain is not claimable."); require(_list[hashedDomain].size() < MaxPerDomain, "Domain is not claimable."); require(isSignatureValid(_http, _signature), "Invalid signature"); bool hasMinted = _list[hashedDomain].get(msg.sender); require(!hasMinted, "Address already has the token on this domain."); _list[hashedDomain].set(msg.sender); _tokenIdCounter.increment(); _safeMint(msg.sender, tokenId); } function isSignatureValid(string memory _http, bytes memory _signature) internal view returns (bool) { bytes32 result = keccak256(abi.encodePacked(msg.sender, _http)); bytes32 hash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", result)); return msg.sender.isValidSignatureNow(hash, _signature); } function setTokenURI(string memory _uri) external virtual onlyRole(DEFAULT_ADMIN_ROLE) { _tokenURI = _uri; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); return _tokenURI; } function getMinted(string memory _http) external view onlyRole(DEFAULT_ADMIN_ROLE) returns (address[] memory) { bytes32 hashedDomain = keccak256(abi.encodePacked(_http)); return _list[hashedDomain].keys; } function isValidDomain(string memory _http) external view returns (bool) { bytes32 hashedDomain = keccak256(abi.encodePacked(_http)); return _siteExists[hashedDomain]; } function claimable(string memory _http) external view returns (bool) { bytes32 hashedDomain = keccak256(abi.encodePacked(_http)); uint256 tokenId = _tokenIdCounter.current(); bool hasMinted = _list[hashedDomain].get(msg.sender); return tokenId < MaxSupply && _siteExists[hashedDomain] && _list[hashedDomain].size() < MaxPerDomain && !hasMinted; } // The following functions are overrides required by Solidity. function supportsInterface(bytes4 interfaceId) public view override(ERC721, AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":"string","name":"_http","type":"string"}],"name":"claimable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_http","type":"string"}],"name":"getMinted","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"string","name":"_http","type":"string"}],"name":"isValidDomain","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_http","type":"string"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","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":"string","name":"_uri","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6104406040527f9649c7eb6df175f417fcfb2eeeaf6e39367ec7a45034048a3d5cff5e2ea8519f60809081527f45a2112d850d7101c902a913c185ba0d28e0ecdcfd1d540e2497f2750714f69a60a0527f0445d458f1aa05b40e476e9a57218b91110ad2174ae15f7057715e84693f710060c0527feb867819c51fbf7d44c73a332082c0b6142546289310c6ff4fac832120012ed360e0527f89ae9c604bc971f8b6a5aee73a1c4e71c952d16a3bcf995e1642f2db167bc5a7610100527f9f514643ee17437be8788be62d7db6953296791a2ad0db024063a20a97a08682610120527f94d13d04140fd5b04a3196ba600a958460fc847c28b74d6e9c1f26bb50c56b45610140527f9e01a36b730e791ed57eabb8379758d7601ffc79b6d613cb7744191938672887610160527f1345e844ae191c4c9f5ed685ecca259e4530dec934838661f002fc3ac3c3b83c610180527f588e7f25cc1ab5b40a3b6770561d285a5299071e36dbffe3cba46f5360110f5d6101a0527f6449d685d467441665612dc60098ae2a5f0e16d0e60f1d9d0b63e3c037c5df8d6101c0527fc9fc5126b89092478eb63279a7cd259ea24c24bc945b91b5c8366967b05ee6d16101e0527f574014404853e93615346db284ca5bd068542f139762d459e11e64fee33e7abd610200527f0e84102fc2bc70ee46419905395f8fb46f7c0be0c9e694e4e699b087cde9be16610220527fd14db021bc6bdaf39de490427d6a1e0e265463ff19e83094dc76f0d3150fc716610240527f4c85a4f44366822767ab3fa89b6b2a8cf6b30a44a96152d7c26a77f634f9cbe0610260527ff0ca7fdd544d43a37b1fd3242551a298fbfed3edb8403c9e925c4cde8c19fe8e610280527f207eeb1c4a1ac75d8ac74d64bfabb5e81199384099507fa4233771c134adad726102a0527f131e81156f0505f36093d6b4d5e6f14643b9f367da7fd717f3239c1599c620a86102c0527f2ccc2d85ad9b8899ddbad3cef1c367ed84bf8d19014acd04588e48f6e837436e6102e0527f702c587833b68bf050b53037adba2bb8f7f93d875c5a372389d8d6987074f503610300527fb0af795fa00c85296c52b9fa3873a6acb561de2ac8e8ae0a84338bfbbcb6a3d7610320527fa57c78e6f3324d0ef1b1412366a8b123674f9423dd1effc63656d7e48d05bc30610340527ff7f00296c339c4e3d3b2aa84cbe9a6cadb9d8aabd2eb784064fb12ecf2029b0e610360527fbf9c1eb5724df6704047f4b9f5ddb73e21e53efedd725685ab9d9820c5dc99b2610380527fcc57ea92f884c55cc87b03761c95b7d99a2324f4baec0a72a0df10cbab77911b6103a0527fdc6ab7e871c6a47b07c00e6bbd11ee902e47d00afc2191d614116b87900973dc6103c0527ff2e4f0dcb4243c2dc76aeee61f15ba1d87db55775678f6d67d7a49130db786e46103e0527f3a95202072e7adc1c3e2598fd97fd22472790fb26ec4f768f6b77c4c12995fb2610400527f6ce43a2f8178c89cac275597661b9ce9f6b7ef6a93e8c97b0ccf437dad1e511e610420526200046990600990601e6200064e565b503480156200047757600080fd5b50604080518082018252601581527f50726f7469636f204368617474696e672043686970000000000000000000000060208083019182528351808501909452600384526250434360e81b908401528151919291620004d89160009162000691565b508051620004ee90600190602084019062000691565b5050600160065550620005036000336200059a565b60405180606001604052806035815260200162002c5b603591398051620005339160299160209091019062000691565b5060005b601e8110156200059357600160286000600984601e81106200055d576200055d6200078b565b015481526020810191909152604001600020805460ff1916911515919091179055806200058a8162000761565b91505062000537565b50620007a1565b620005a68282620005aa565b5050565b60008281526007602090815260408083206001600160a01b038516845290915290205460ff16620005a65760008281526007602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200060a3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b82601e81019282156200067f579160200282015b828111156200067f57825182559160200191906001019062000662565b506200068d9291506200070d565b5090565b8280546200069f9062000724565b90600052602060002090601f016020900481019282620006c357600085556200067f565b82601f10620006de57805160ff19168380011785556200067f565b828001600101855582156200067f57918201828111156200067f57825182559160200191906001019062000662565b5b808211156200068d57600081556001016200070e565b600181811c908216806200073957607f821691505b602082108114156200075b57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156200078457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b6124aa80620007b16000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c80636352211e116100c3578063a22cb4651161007c578063a22cb465146102f9578063b88d4fde1461030c578063c87b56dd1461031f578063d547741f14610332578063e0df5b6f14610345578063e985e9c51461035857600080fd5b80636352211e1461029057806370a08231146102a3578063821c48a4146102b657806391d14854146102d657806395d89b41146102e9578063a217fddf146102f157600080fd5b80632f2ff15d116101155780632f2ff15d1461021e57806336568abe146102315780633f4962ec1461024457806342842e0e146102575780634737576e1461026a578063484ba3921461027d57600080fd5b806301ffc9a71461015d57806306fdde0314610185578063081812fc1461019a578063095ea7b3146101c557806323b872dd146101da578063248a9ca3146101ed575b600080fd5b61017061016b366004611fd0565b610394565b60405190151581526020015b60405180910390f35b61018d6103a5565b60405161017c919061223b565b6101ad6101a8366004611f7b565b610437565b6040516001600160a01b03909116815260200161017c565b6101d86101d3366004611f34565b61045e565b005b6101d86101e8366004611e59565b610579565b6102106101fb366004611f7b565b60009081526007602052604090206001015490565b60405190815260200161017c565b6101d861022c366004611fad565b6105aa565b6101d861023f366004611fad565b6105cf565b61017061025236600461200a565b61064d565b6101d8610265366004611e59565b6107f9565b6101d861027836600461203f565b610814565b61017061028b36600461200a565b610bb9565b6101ad61029e366004611f7b565b610bfc565b6102106102b1366004611e0b565b610c5c565b6102c96102c436600461200a565b610ce2565b60405161017c91906121d5565b6101706102e4366004611fad565b610d82565b61018d610dad565b610210600081565b6101d8610307366004611efd565b610dbc565b6101d861031a366004611e95565b610dc7565b61018d61032d366004611f7b565b610dff565b6101d8610340366004611fad565b610e9c565b6101d861035336600461200a565b610ec1565b610170610366366004611e26565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600061039f82610edf565b92915050565b6060600080546103b4906123c3565b80601f01602080910402602001604051908101604052809291908181526020018280546103e0906123c3565b801561042d5780601f106104025761010080835404028352916020019161042d565b820191906000526020600020905b81548152906001019060200180831161041057829003601f168201915b5050505050905090565b600061044282610f04565b506000908152600460205260409020546001600160a01b031690565b600061046982610bfc565b9050806001600160a01b0316836001600160a01b031614156104dc5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806104f857506104f88133610366565b61056a5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016104d3565b6105748383610f66565b505050565b6105833382610fd4565b61059f5760405162461bcd60e51b81526004016104d39061224e565b610574838383611053565b6000828152600760205260409020600101546105c5816111c4565b61057483836111ce565b6001600160a01b038116331461063f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016104d3565b6106498282611254565b5050565b600080826040516020016106619190612107565b604051602081830303815290604052805190602001209050600061068460085490565b600083815260276020526040808220905163cf1d8fd560e01b8152600481019190915233602482015291925090738828d87c8e53910485320e93e090c59715a4b2229063cf1d8fd59060440160206040518083038186803b1580156106e857600080fd5b505af41580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190611f5e565b905061753082108015610741575060008381526028602052604090205460ff165b80156107e65750600083815260276020526040908190209051633775465d60e11b81526103e891738828d87c8e53910485320e93e090c59715a4b22291636eea8cba916107949160040190815260200190565b60206040518083038186803b1580156107ac57600080fd5b505af41580156107c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e49190611f94565b105b80156107f0575080155b95945050505050565b61057483838360405180602001604052806000815250610dc7565b61081c6112bb565b600061082760085490565b9050617530811061086a5760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b60448201526064016104d3565b60008360405160200161087d9190612107565b60408051601f1981840301815291815281516020928301206000818152602890935291205490915060ff166108ef5760405162461bcd60e51b81526020600482015260186024820152772237b6b0b4b71034b9903737ba1031b630b4b6b0b136329760411b60448201526064016104d3565b600081815260276020526040908190209051633775465d60e11b81526103e891738828d87c8e53910485320e93e090c59715a4b22291636eea8cba9161093b9160040190815260200190565b60206040518083038186803b15801561095357600080fd5b505af4158015610967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b9190611f94565b106109d35760405162461bcd60e51b81526020600482015260186024820152772237b6b0b4b71034b9903737ba1031b630b4b6b0b136329760411b60448201526064016104d3565b6109dd8484611315565b610a1d5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b60448201526064016104d3565b600081815260276020526040808220905163cf1d8fd560e01b81526004810191909152336024820152738828d87c8e53910485320e93e090c59715a4b2229063cf1d8fd59060440160206040518083038186803b158015610a7d57600080fd5b505af4158015610a91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab59190611f5e565b90508015610b1b5760405162461bcd60e51b815260206004820152602d60248201527f4164647265737320616c7265616479206861732074686520746f6b656e206f6e60448201526c103a3434b9903237b6b0b4b71760991b60648201526084016104d3565b6000828152602760205260409081902090516301a7282160e21b81526004810191909152336024820152738828d87c8e53910485320e93e090c59715a4b2229063069ca0849060440160006040518083038186803b158015610b7c57600080fd5b505af4158015610b90573d6000803e3d6000fd5b50505050610ba2600880546001019055565b610bac33846113a7565b5050506106496001600655565b60008082604051602001610bcd9190612107565b60408051601f1981840301815291815281516020928301206000908152602890925290205460ff169392505050565b6000818152600260205260408120546001600160a01b03168061039f5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016104d3565b60006001600160a01b038216610cc65760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016104d3565b506001600160a01b031660009081526003602052604090205490565b60606000610cef816111c4565b600083604051602001610d029190612107565b60408051601f1981840301815282825280516020918201206000818152602783528390208054808402860184019094528385529094509190830182828015610d7357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610d55575b50505050509250505b50919050565b60009182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600180546103b4906123c3565b6106493383836113c1565b610dd13383610fd4565b610ded5760405162461bcd60e51b81526004016104d39061224e565b610df984848484611490565b50505050565b6060610e0a82610f04565b60298054610e17906123c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610e43906123c3565b8015610e905780601f10610e6557610100808354040283529160200191610e90565b820191906000526020600020905b815481529060010190602001808311610e7357829003601f168201915b50505050509050919050565b600082815260076020526040902060010154610eb7816111c4565b6105748383611254565b6000610ecc816111c4565b8151610574906029906020850190611cc9565b60006001600160e01b03198216637965db0b60e01b148061039f575061039f826114c3565b6000818152600260205260409020546001600160a01b0316610f635760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016104d3565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610f9b82610bfc565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610fe083610bfc565b9050806001600160a01b0316846001600160a01b0316148061102757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b8061104b5750836001600160a01b031661104084610437565b6001600160a01b0316145b949350505050565b826001600160a01b031661106682610bfc565b6001600160a01b03161461108c5760405162461bcd60e51b81526004016104d3906122ed565b6001600160a01b0382166110ee5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016104d3565b6110fb8383836001611513565b826001600160a01b031661110e82610bfc565b6001600160a01b0316146111345760405162461bcd60e51b81526004016104d3906122ed565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b610f63813361159b565b6111d88282610d82565b6106495760008281526007602090815260408083206001600160a01b03851684529091529020805460ff191660011790556112103390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61125e8282610d82565b156106495760008281526007602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6002600654141561130e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104d3565b6002600655565b600080338460405160200161132b9291906120cf565b60405160208183030381529060405280519060200120905060008160405160200161138291907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60408051601f19818403018152919052805160209091012090506107f03382866115f4565b610649828260405180602001604052806000815250611738565b816001600160a01b0316836001600160a01b031614156114235760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104d3565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61149b848484611053565b6114a78484848461176b565b610df95760405162461bcd60e51b81526004016104d39061229b565b60006001600160e01b031982166380ac58cd60e01b14806114f457506001600160e01b03198216635b5e139f60e01b145b8061039f57506301ffc9a760e01b6001600160e01b031983161461039f565b6001811115610df9576001600160a01b03841615611559576001600160a01b03841660009081526003602052604081208054839290611553908490612369565b90915550505b6001600160a01b03831615610df9576001600160a01b03831660009081526003602052604081208054839290611590908490612332565b909155505050505050565b6115a58282610d82565b610649576115b281611878565b6115bd83602061188a565b6040516020016115ce929190612123565b60408051601f198184030181529082905262461bcd60e51b82526104d39160040161223b565b60008060006116038585611a26565b9092509050600081600481111561161c5761161c61240e565b14801561163a5750856001600160a01b0316826001600160a01b0316145b1561164a57600192505050611731565b600080876001600160a01b0316631626ba7e60e01b8888604051602401611672929190612222565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516116b09190612107565b600060405180830381855afa9150503d80600081146116eb576040519150601f19603f3d011682016040523d82523d6000602084013e6116f0565b606091505b5091509150818015611703575080516020145b801561172a57508051630b135d3f60e11b906117289083016020908101908401611f94565b145b9450505050505b9392505050565b6117428383611a6c565b61174f600084848461176b565b6105745760405162461bcd60e51b81526004016104d39061229b565b60006001600160a01b0384163b1561186d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906117af903390899088908890600401612198565b602060405180830381600087803b1580156117c957600080fd5b505af19250505080156117f9575060408051601f3d908101601f191682019092526117f691810190611fed565b60015b611853573d808015611827576040519150601f19603f3d011682016040523d82523d6000602084013e61182c565b606091505b50805161184b5760405162461bcd60e51b81526004016104d39061229b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061104b565b506001949350505050565b606061039f6001600160a01b03831660145b6060600061189983600261234a565b6118a4906002612332565b67ffffffffffffffff8111156118bc576118bc61243a565b6040519080825280601f01601f1916602001820160405280156118e6576020820181803683370190505b509050600360fc1b8160008151811061190157611901612424565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061193057611930612424565b60200101906001600160f81b031916908160001a905350600061195484600261234a565b61195f906001612332565b90505b60018111156119d7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061199357611993612424565b1a60f81b8282815181106119a9576119a9612424565b60200101906001600160f81b031916908160001a90535060049490941c936119d0816123ac565b9050611962565b5083156117315760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016104d3565b600080825160411415611a5d5760208301516040840151606085015160001a611a5187828585611c05565b94509450505050611a65565b506000905060025b9250929050565b6001600160a01b038216611ac25760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104d3565b6000818152600260205260409020546001600160a01b031615611b275760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104d3565b611b35600083836001611513565b6000818152600260205260409020546001600160a01b031615611b9a5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104d3565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611c3c5750600090506003611cc0565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611c90573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611cb957600060019250925050611cc0565b9150600090505b94509492505050565b828054611cd5906123c3565b90600052602060002090601f016020900481019282611cf75760008555611d3d565b82601f10611d1057805160ff1916838001178555611d3d565b82800160010185558215611d3d579182015b82811115611d3d578251825591602001919060010190611d22565b50611d49929150611d4d565b5090565b5b80821115611d495760008155600101611d4e565b80356001600160a01b0381168114611d7957600080fd5b919050565b600082601f830112611d8f57600080fd5b813567ffffffffffffffff80821115611daa57611daa61243a565b604051601f8301601f19908116603f01168101908282118183101715611dd257611dd261243a565b81604052838152866020858801011115611deb57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215611e1d57600080fd5b61173182611d62565b60008060408385031215611e3957600080fd5b611e4283611d62565b9150611e5060208401611d62565b90509250929050565b600080600060608486031215611e6e57600080fd5b611e7784611d62565b9250611e8560208501611d62565b9150604084013590509250925092565b60008060008060808587031215611eab57600080fd5b611eb485611d62565b9350611ec260208601611d62565b925060408501359150606085013567ffffffffffffffff811115611ee557600080fd5b611ef187828801611d7e565b91505092959194509250565b60008060408385031215611f1057600080fd5b611f1983611d62565b91506020830135611f2981612450565b809150509250929050565b60008060408385031215611f4757600080fd5b611f5083611d62565b946020939093013593505050565b600060208284031215611f7057600080fd5b815161173181612450565b600060208284031215611f8d57600080fd5b5035919050565b600060208284031215611fa657600080fd5b5051919050565b60008060408385031215611fc057600080fd5b82359150611e5060208401611d62565b600060208284031215611fe257600080fd5b81356117318161245e565b600060208284031215611fff57600080fd5b81516117318161245e565b60006020828403121561201c57600080fd5b813567ffffffffffffffff81111561203357600080fd5b61104b84828501611d7e565b6000806040838503121561205257600080fd5b823567ffffffffffffffff8082111561206a57600080fd5b61207686838701611d7e565b9350602085013591508082111561208c57600080fd5b5061209985828601611d7e565b9150509250929050565b600081518084526120bb816020860160208601612380565b601f01601f19169290920160200192915050565b6bffffffffffffffffffffffff198360601b168152600082516120f9816014850160208701612380565b919091016014019392505050565b60008251612119818460208701612380565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161215b816017850160208801612380565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161218c816028840160208801612380565b01602801949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121cb908301846120a3565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156122165783516001600160a01b0316835292840192918401916001016121f1565b50909695505050505050565b82815260406020820152600061104b60408301846120a3565b60208152600061173160208301846120a3565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60008219821115612345576123456123f8565b500190565b6000816000190483118215151615612364576123646123f8565b500290565b60008282101561237b5761237b6123f8565b500390565b60005b8381101561239b578181015183820152602001612383565b83811115610df95750506000910152565b6000816123bb576123bb6123f8565b506000190190565b600181811c908216806123d757607f821691505b60208210811415610d7c57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610f6357600080fd5b6001600160e01b031981168114610f6357600080fdfea26469706673582212200c961fe1c5a6eed832ca649f504716fcc362332384260cea33d9c392f1c1456764736f6c63430008070033697066733a2f2f516d576e394c637634506846713146455858516a70686b51795661593465777631673163786459643466547a4272
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101585760003560e01c80636352211e116100c3578063a22cb4651161007c578063a22cb465146102f9578063b88d4fde1461030c578063c87b56dd1461031f578063d547741f14610332578063e0df5b6f14610345578063e985e9c51461035857600080fd5b80636352211e1461029057806370a08231146102a3578063821c48a4146102b657806391d14854146102d657806395d89b41146102e9578063a217fddf146102f157600080fd5b80632f2ff15d116101155780632f2ff15d1461021e57806336568abe146102315780633f4962ec1461024457806342842e0e146102575780634737576e1461026a578063484ba3921461027d57600080fd5b806301ffc9a71461015d57806306fdde0314610185578063081812fc1461019a578063095ea7b3146101c557806323b872dd146101da578063248a9ca3146101ed575b600080fd5b61017061016b366004611fd0565b610394565b60405190151581526020015b60405180910390f35b61018d6103a5565b60405161017c919061223b565b6101ad6101a8366004611f7b565b610437565b6040516001600160a01b03909116815260200161017c565b6101d86101d3366004611f34565b61045e565b005b6101d86101e8366004611e59565b610579565b6102106101fb366004611f7b565b60009081526007602052604090206001015490565b60405190815260200161017c565b6101d861022c366004611fad565b6105aa565b6101d861023f366004611fad565b6105cf565b61017061025236600461200a565b61064d565b6101d8610265366004611e59565b6107f9565b6101d861027836600461203f565b610814565b61017061028b36600461200a565b610bb9565b6101ad61029e366004611f7b565b610bfc565b6102106102b1366004611e0b565b610c5c565b6102c96102c436600461200a565b610ce2565b60405161017c91906121d5565b6101706102e4366004611fad565b610d82565b61018d610dad565b610210600081565b6101d8610307366004611efd565b610dbc565b6101d861031a366004611e95565b610dc7565b61018d61032d366004611f7b565b610dff565b6101d8610340366004611fad565b610e9c565b6101d861035336600461200a565b610ec1565b610170610366366004611e26565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600061039f82610edf565b92915050565b6060600080546103b4906123c3565b80601f01602080910402602001604051908101604052809291908181526020018280546103e0906123c3565b801561042d5780601f106104025761010080835404028352916020019161042d565b820191906000526020600020905b81548152906001019060200180831161041057829003601f168201915b5050505050905090565b600061044282610f04565b506000908152600460205260409020546001600160a01b031690565b600061046982610bfc565b9050806001600160a01b0316836001600160a01b031614156104dc5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806104f857506104f88133610366565b61056a5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016104d3565b6105748383610f66565b505050565b6105833382610fd4565b61059f5760405162461bcd60e51b81526004016104d39061224e565b610574838383611053565b6000828152600760205260409020600101546105c5816111c4565b61057483836111ce565b6001600160a01b038116331461063f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016104d3565b6106498282611254565b5050565b600080826040516020016106619190612107565b604051602081830303815290604052805190602001209050600061068460085490565b600083815260276020526040808220905163cf1d8fd560e01b8152600481019190915233602482015291925090738828d87c8e53910485320e93e090c59715a4b2229063cf1d8fd59060440160206040518083038186803b1580156106e857600080fd5b505af41580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107209190611f5e565b905061753082108015610741575060008381526028602052604090205460ff165b80156107e65750600083815260276020526040908190209051633775465d60e11b81526103e891738828d87c8e53910485320e93e090c59715a4b22291636eea8cba916107949160040190815260200190565b60206040518083038186803b1580156107ac57600080fd5b505af41580156107c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e49190611f94565b105b80156107f0575080155b95945050505050565b61057483838360405180602001604052806000815250610dc7565b61081c6112bb565b600061082760085490565b9050617530811061086a5760405162461bcd60e51b815260206004820152600d60248201526c4e6f7420636c61696d61626c6560981b60448201526064016104d3565b60008360405160200161087d9190612107565b60408051601f1981840301815291815281516020928301206000818152602890935291205490915060ff166108ef5760405162461bcd60e51b81526020600482015260186024820152772237b6b0b4b71034b9903737ba1031b630b4b6b0b136329760411b60448201526064016104d3565b600081815260276020526040908190209051633775465d60e11b81526103e891738828d87c8e53910485320e93e090c59715a4b22291636eea8cba9161093b9160040190815260200190565b60206040518083038186803b15801561095357600080fd5b505af4158015610967573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b9190611f94565b106109d35760405162461bcd60e51b81526020600482015260186024820152772237b6b0b4b71034b9903737ba1031b630b4b6b0b136329760411b60448201526064016104d3565b6109dd8484611315565b610a1d5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b60448201526064016104d3565b600081815260276020526040808220905163cf1d8fd560e01b81526004810191909152336024820152738828d87c8e53910485320e93e090c59715a4b2229063cf1d8fd59060440160206040518083038186803b158015610a7d57600080fd5b505af4158015610a91573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab59190611f5e565b90508015610b1b5760405162461bcd60e51b815260206004820152602d60248201527f4164647265737320616c7265616479206861732074686520746f6b656e206f6e60448201526c103a3434b9903237b6b0b4b71760991b60648201526084016104d3565b6000828152602760205260409081902090516301a7282160e21b81526004810191909152336024820152738828d87c8e53910485320e93e090c59715a4b2229063069ca0849060440160006040518083038186803b158015610b7c57600080fd5b505af4158015610b90573d6000803e3d6000fd5b50505050610ba2600880546001019055565b610bac33846113a7565b5050506106496001600655565b60008082604051602001610bcd9190612107565b60408051601f1981840301815291815281516020928301206000908152602890925290205460ff169392505050565b6000818152600260205260408120546001600160a01b03168061039f5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016104d3565b60006001600160a01b038216610cc65760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016104d3565b506001600160a01b031660009081526003602052604090205490565b60606000610cef816111c4565b600083604051602001610d029190612107565b60408051601f1981840301815282825280516020918201206000818152602783528390208054808402860184019094528385529094509190830182828015610d7357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610d55575b50505050509250505b50919050565b60009182526007602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600180546103b4906123c3565b6106493383836113c1565b610dd13383610fd4565b610ded5760405162461bcd60e51b81526004016104d39061224e565b610df984848484611490565b50505050565b6060610e0a82610f04565b60298054610e17906123c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610e43906123c3565b8015610e905780601f10610e6557610100808354040283529160200191610e90565b820191906000526020600020905b815481529060010190602001808311610e7357829003601f168201915b50505050509050919050565b600082815260076020526040902060010154610eb7816111c4565b6105748383611254565b6000610ecc816111c4565b8151610574906029906020850190611cc9565b60006001600160e01b03198216637965db0b60e01b148061039f575061039f826114c3565b6000818152600260205260409020546001600160a01b0316610f635760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016104d3565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610f9b82610bfc565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610fe083610bfc565b9050806001600160a01b0316846001600160a01b0316148061102757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b8061104b5750836001600160a01b031661104084610437565b6001600160a01b0316145b949350505050565b826001600160a01b031661106682610bfc565b6001600160a01b03161461108c5760405162461bcd60e51b81526004016104d3906122ed565b6001600160a01b0382166110ee5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016104d3565b6110fb8383836001611513565b826001600160a01b031661110e82610bfc565b6001600160a01b0316146111345760405162461bcd60e51b81526004016104d3906122ed565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b610f63813361159b565b6111d88282610d82565b6106495760008281526007602090815260408083206001600160a01b03851684529091529020805460ff191660011790556112103390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b61125e8282610d82565b156106495760008281526007602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6002600654141561130e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104d3565b6002600655565b600080338460405160200161132b9291906120cf565b60405160208183030381529060405280519060200120905060008160405160200161138291907f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60408051601f19818403018152919052805160209091012090506107f03382866115f4565b610649828260405180602001604052806000815250611738565b816001600160a01b0316836001600160a01b031614156114235760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104d3565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61149b848484611053565b6114a78484848461176b565b610df95760405162461bcd60e51b81526004016104d39061229b565b60006001600160e01b031982166380ac58cd60e01b14806114f457506001600160e01b03198216635b5e139f60e01b145b8061039f57506301ffc9a760e01b6001600160e01b031983161461039f565b6001811115610df9576001600160a01b03841615611559576001600160a01b03841660009081526003602052604081208054839290611553908490612369565b90915550505b6001600160a01b03831615610df9576001600160a01b03831660009081526003602052604081208054839290611590908490612332565b909155505050505050565b6115a58282610d82565b610649576115b281611878565b6115bd83602061188a565b6040516020016115ce929190612123565b60408051601f198184030181529082905262461bcd60e51b82526104d39160040161223b565b60008060006116038585611a26565b9092509050600081600481111561161c5761161c61240e565b14801561163a5750856001600160a01b0316826001600160a01b0316145b1561164a57600192505050611731565b600080876001600160a01b0316631626ba7e60e01b8888604051602401611672929190612222565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199094169390931790925290516116b09190612107565b600060405180830381855afa9150503d80600081146116eb576040519150601f19603f3d011682016040523d82523d6000602084013e6116f0565b606091505b5091509150818015611703575080516020145b801561172a57508051630b135d3f60e11b906117289083016020908101908401611f94565b145b9450505050505b9392505050565b6117428383611a6c565b61174f600084848461176b565b6105745760405162461bcd60e51b81526004016104d39061229b565b60006001600160a01b0384163b1561186d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906117af903390899088908890600401612198565b602060405180830381600087803b1580156117c957600080fd5b505af19250505080156117f9575060408051601f3d908101601f191682019092526117f691810190611fed565b60015b611853573d808015611827576040519150601f19603f3d011682016040523d82523d6000602084013e61182c565b606091505b50805161184b5760405162461bcd60e51b81526004016104d39061229b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061104b565b506001949350505050565b606061039f6001600160a01b03831660145b6060600061189983600261234a565b6118a4906002612332565b67ffffffffffffffff8111156118bc576118bc61243a565b6040519080825280601f01601f1916602001820160405280156118e6576020820181803683370190505b509050600360fc1b8160008151811061190157611901612424565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061193057611930612424565b60200101906001600160f81b031916908160001a905350600061195484600261234a565b61195f906001612332565b90505b60018111156119d7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061199357611993612424565b1a60f81b8282815181106119a9576119a9612424565b60200101906001600160f81b031916908160001a90535060049490941c936119d0816123ac565b9050611962565b5083156117315760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016104d3565b600080825160411415611a5d5760208301516040840151606085015160001a611a5187828585611c05565b94509450505050611a65565b506000905060025b9250929050565b6001600160a01b038216611ac25760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104d3565b6000818152600260205260409020546001600160a01b031615611b275760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104d3565b611b35600083836001611513565b6000818152600260205260409020546001600160a01b031615611b9a5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104d3565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611c3c5750600090506003611cc0565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611c90573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611cb957600060019250925050611cc0565b9150600090505b94509492505050565b828054611cd5906123c3565b90600052602060002090601f016020900481019282611cf75760008555611d3d565b82601f10611d1057805160ff1916838001178555611d3d565b82800160010185558215611d3d579182015b82811115611d3d578251825591602001919060010190611d22565b50611d49929150611d4d565b5090565b5b80821115611d495760008155600101611d4e565b80356001600160a01b0381168114611d7957600080fd5b919050565b600082601f830112611d8f57600080fd5b813567ffffffffffffffff80821115611daa57611daa61243a565b604051601f8301601f19908116603f01168101908282118183101715611dd257611dd261243a565b81604052838152866020858801011115611deb57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215611e1d57600080fd5b61173182611d62565b60008060408385031215611e3957600080fd5b611e4283611d62565b9150611e5060208401611d62565b90509250929050565b600080600060608486031215611e6e57600080fd5b611e7784611d62565b9250611e8560208501611d62565b9150604084013590509250925092565b60008060008060808587031215611eab57600080fd5b611eb485611d62565b9350611ec260208601611d62565b925060408501359150606085013567ffffffffffffffff811115611ee557600080fd5b611ef187828801611d7e565b91505092959194509250565b60008060408385031215611f1057600080fd5b611f1983611d62565b91506020830135611f2981612450565b809150509250929050565b60008060408385031215611f4757600080fd5b611f5083611d62565b946020939093013593505050565b600060208284031215611f7057600080fd5b815161173181612450565b600060208284031215611f8d57600080fd5b5035919050565b600060208284031215611fa657600080fd5b5051919050565b60008060408385031215611fc057600080fd5b82359150611e5060208401611d62565b600060208284031215611fe257600080fd5b81356117318161245e565b600060208284031215611fff57600080fd5b81516117318161245e565b60006020828403121561201c57600080fd5b813567ffffffffffffffff81111561203357600080fd5b61104b84828501611d7e565b6000806040838503121561205257600080fd5b823567ffffffffffffffff8082111561206a57600080fd5b61207686838701611d7e565b9350602085013591508082111561208c57600080fd5b5061209985828601611d7e565b9150509250929050565b600081518084526120bb816020860160208601612380565b601f01601f19169290920160200192915050565b6bffffffffffffffffffffffff198360601b168152600082516120f9816014850160208701612380565b919091016014019392505050565b60008251612119818460208701612380565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161215b816017850160208801612380565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161218c816028840160208801612380565b01602801949350505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121cb908301846120a3565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156122165783516001600160a01b0316835292840192918401916001016121f1565b50909695505050505050565b82815260406020820152600061104b60408301846120a3565b60208152600061173160208301846120a3565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60008219821115612345576123456123f8565b500190565b6000816000190483118215151615612364576123646123f8565b500290565b60008282101561237b5761237b6123f8565b500390565b60005b8381101561239b578181015183820152602001612383565b83811115610df95750506000910152565b6000816123bb576123bb6123f8565b506000190190565b600181811c908216806123d757607f821691505b60208210811415610d7c57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610f6357600080fd5b6001600160e01b031981168114610f6357600080fdfea26469706673582212200c961fe1c5a6eed832ca649f504716fcc362332384260cea33d9c392f1c1456764736f6c63430008070033
Deployed Bytecode Sourcemap
79783:5663:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85258:185;;;;;;:::i;:::-;;:::i;:::-;;;9386:14:1;;9379:22;9361:41;;9349:2;9334:18;85258:185:0;;;;;;;;52372:100;;;:::i;:::-;;;;;;;:::i;53884:171::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;8021:32:1;;;8003:51;;7991:2;7976:18;53884:171:0;7857:203:1;53402:416:0;;;;;;:::i;:::-;;:::i;:::-;;54584:335;;;;;;:::i;:::-;;:::i;74725:131::-;;;;;;:::i;:::-;74799:7;74826:12;;;:6;:12;;;;;:22;;;;74725:131;;;;9559:25:1;;;9547:2;9532:18;74725:131:0;9413:177:1;75166:147:0;;;;;;:::i;:::-;;:::i;76310:218::-;;;;;;:::i;:::-;;:::i;84813:371::-;;;;;;:::i;:::-;;:::i;54990:185::-;;;;;;:::i;:::-;;:::i;83026:746::-;;;;;;:::i;:::-;;:::i;84623:184::-;;;;;;:::i;:::-;;:::i;52082:223::-;;;;;;:::i;:::-;;:::i;51813:207::-;;;;;;:::i;:::-;;:::i;84399:218::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;73198:147::-;;;;;;:::i;:::-;;:::i;52541:104::-;;;:::i;72303:49::-;;72348:4;72303:49;;54127:155;;;;;;:::i;:::-;;:::i;55246:322::-;;;;;;:::i;:::-;;:::i;84244:149::-;;;;;;:::i;:::-;;:::i;75606:::-;;;;;;:::i;:::-;;:::i;84122:116::-;;;;;;:::i;:::-;;:::i;54353:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;54474:25:0;;;54450:4;54474:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;54353:164;85258:185;85378:4;85401:36;85425:11;85401:23;:36::i;:::-;85394:43;85258:185;-1:-1:-1;;85258:185:0:o;52372:100::-;52426:13;52459:5;52452:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52372:100;:::o;53884:171::-;53960:7;53980:23;53995:7;53980:14;:23::i;:::-;-1:-1:-1;54023:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;54023:24:0;;53884:171::o;53402:416::-;53483:13;53499:23;53514:7;53499:14;:23::i;:::-;53483:39;;53547:5;-1:-1:-1;;;;;53541:11:0;:2;-1:-1:-1;;;;;53541:11:0;;;53533:57;;;;-1:-1:-1;;;53533:57:0;;16012:2:1;53533:57:0;;;15994:21:1;16051:2;16031:18;;;16024:30;16090:34;16070:18;;;16063:62;-1:-1:-1;;;16141:18:1;;;16134:31;16182:19;;53533:57:0;;;;;;;;;49903:10;-1:-1:-1;;;;;53625:21:0;;;;:62;;-1:-1:-1;53650:37:0;53667:5;49903:10;54353:164;:::i;53650:37::-;53603:173;;;;-1:-1:-1;;;53603:173:0;;16414:2:1;53603:173:0;;;16396:21:1;16453:2;16433:18;;;16426:30;16492:34;16472:18;;;16465:62;16563:31;16543:18;;;16536:59;16612:19;;53603:173:0;16212:425:1;53603:173:0;53789:21;53798:2;53802:7;53789:8;:21::i;:::-;53472:346;53402:416;;:::o;54584:335::-;54779:41;49903:10;54812:7;54779:18;:41::i;:::-;54771:99;;;;-1:-1:-1;;;54771:99:0;;;;;;;:::i;:::-;54883:28;54893:4;54899:2;54903:7;54883:9;:28::i;75166:147::-;74799:7;74826:12;;;:6;:12;;;;;:22;;;72794:16;72805:4;72794:10;:16::i;:::-;75280:25:::1;75291:4;75297:7;75280:10;:25::i;76310:218::-:0;-1:-1:-1;;;;;76406:23:0;;49903:10;76406:23;76398:83;;;;-1:-1:-1;;;76398:83:0;;17204:2:1;76398:83:0;;;17186:21:1;17243:2;17223:18;;;17216:30;17282:34;17262:18;;;17255:62;-1:-1:-1;;;17333:18:1;;;17326:45;17388:19;;76398:83:0;17002:411:1;76398:83:0;76494:26;76506:4;76512:7;76494:11;:26::i;:::-;76310:218;;:::o;84813:371::-;84876:4;84889:20;84939:5;84922:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;84912:34;;;;;;84889:57;;84953:15;84971:25;:15;964:14;;872:114;84971:25;85003:14;85020:19;;;:5;:19;;;;;;:35;;-1:-1:-1;;;85020:35:0;;;;;17834:25:1;;;;85044:10:0;17875:18:1;;;17868:60;84953:43:0;;-1:-1:-1;85003:14:0;85020:23;;;;17807:18:1;;85020:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85003:52;;80052:5;85071:7;:19;:48;;;;-1:-1:-1;85094:25:0;;;;:11;:25;;;;;;;;85071:48;:93;;;;-1:-1:-1;85123:19:0;;;;:5;:19;;;;;;;:26;;-1:-1:-1;;;85123:26:0;;80094:4;;85123:24;;;;:26;;;;9559:25:1;;;9547:2;9532:18;;9413:177;85123:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;85071:93;:107;;;;;85169:9;85168:10;85071:107;85064:114;84813:371;-1:-1:-1;;;;;84813:371:0:o;54990:185::-;55128:39;55145:4;55151:2;55155:7;55128:39;;;;;;;;;;;;:16;:39::i;83026:746::-;4864:21;:19;:21::i;:::-;83130:15:::1;83148:25;:15;964:14:::0;;872:114;83148:25:::1;83130:43;;80052:5;83188:7;:19;83180:45;;;::::0;-1:-1:-1;;;83180:45:0;;14546:2:1;83180:45:0::1;::::0;::::1;14528:21:1::0;14585:2;14565:18;;;14558:30;-1:-1:-1;;;14604:18:1;;;14597:43;14657:18;;83180:45:0::1;14344:337:1::0;83180:45:0::1;83234:20;83284:5;83267:23;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;83267:23:0;;::::1;::::0;;;;;;83257:34;;83267:23:::1;83257:34:::0;;::::1;::::0;83306:25:::1;::::0;;;:11:::1;:25:::0;;;;;;83257:34;;-1:-1:-1;83306:25:0::1;;83298:62;;;::::0;-1:-1:-1;;;83298:62:0;;13088:2:1;83298:62:0::1;::::0;::::1;13070:21:1::0;13127:2;13107:18;;;13100:30;-1:-1:-1;;;13146:18:1;;;13139:54;13210:18;;83298:62:0::1;12886:348:1::0;83298:62:0::1;83375:19;::::0;;;:5:::1;:19;::::0;;;;;;:26;;-1:-1:-1;;;83375:26:0;;80094:4:::1;::::0;83375:24:::1;::::0;::::1;::::0;:26:::1;::::0;::::1;;9559:25:1::0;;;9547:2;9532:18;;9413:177;83375:26:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:41;83367:78;;;::::0;-1:-1:-1;;;83367:78:0;;13088:2:1;83367:78:0::1;::::0;::::1;13070:21:1::0;13127:2;13107:18;;;13100:30;-1:-1:-1;;;13146:18:1;;;13139:54;13210:18;;83367:78:0::1;12886:348:1::0;83367:78:0::1;83460:35;83477:5;83484:10;83460:16;:35::i;:::-;83452:65;;;::::0;-1:-1:-1;;;83452:65:0;;14200:2:1;83452:65:0::1;::::0;::::1;14182:21:1::0;14239:2;14219:18;;;14212:30;-1:-1:-1;;;14258:18:1;;;14251:47;14315:18;;83452:65:0::1;13998:341:1::0;83452:65:0::1;83526:14;83543:19:::0;;;:5:::1;:19;::::0;;;;;:35;;-1:-1:-1;;;83543:35:0;;::::1;::::0;::::1;17834:25:1::0;;;;83567:10:0::1;17875:18:1::0;;;17868:60;83543:23:0::1;::::0;::::1;::::0;17807:18:1;;83543:35:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83526:52;;83594:9;83593:10;83585:68;;;::::0;-1:-1:-1;;;83585:68:0;;11911:2:1;83585:68:0::1;::::0;::::1;11893:21:1::0;11950:2;11930:18;;;11923:30;11989:34;11969:18;;;11962:62;-1:-1:-1;;;12040:18:1;;;12033:43;12093:19;;83585:68:0::1;11709:409:1::0;83585:68:0::1;83660:19;::::0;;;:5:::1;:19;::::0;;;;;;:35;;-1:-1:-1;;;83660:35:0;;::::1;::::0;::::1;17834:25:1::0;;;;83684:10:0::1;17875:18:1::0;;;17868:60;83660:23:0::1;::::0;::::1;::::0;17807:18:1;;83660:35:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;83702:27;:15;1083:19:::0;;1101:1;1083:19;;;994:127;83702:27:::1;83736:30;83746:10;83758:7;83736:9;:30::i;:::-;83123:649;;;4908:20:::0;4302:1;5428:7;:22;5245:213;84623:184;84690:4;84703:20;84753:5;84736:23;;;;;;;;:::i;:::-;;;;-1:-1:-1;;84736:23:0;;;;;;;;;84726:34;;84736:23;84726:34;;;;84776:25;;;;:11;:25;;;;;;;;;84623:184;-1:-1:-1;;;84623:184:0:o;52082:223::-;52154:7;56969:16;;;:7;:16;;;;;;-1:-1:-1;;;;;56969:16:0;;52218:56;;;;-1:-1:-1;;;52218:56:0;;15659:2:1;52218:56:0;;;15641:21:1;15698:2;15678:18;;;15671:30;-1:-1:-1;;;15717:18:1;;;15710:54;15781:18;;52218:56:0;15457:348:1;51813:207:0;51885:7;-1:-1:-1;;;;;51913:19:0;;51905:73;;;;-1:-1:-1;;;51905:73:0;;14888:2:1;51905:73:0;;;14870:21:1;14927:2;14907:18;;;14900:30;14966:34;14946:18;;;14939:62;-1:-1:-1;;;15017:18:1;;;15010:39;15066:19;;51905:73:0;14686:405:1;51905:73:0;-1:-1:-1;;;;;;51996:16:0;;;;;:9;:16;;;;;;;51813:207::o;84399:218::-;84491:16;72348:4;72794:16;72348:4;72794:10;:16::i;:::-;84516:20:::1;84566:5;84549:23;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;84549:23:0;;::::1;::::0;;;;;;84539:34;;84549:23:::1;84539:34:::0;;::::1;::::0;84587:19:::1;::::0;;;:5:::1;:19:::0;;;;;84580:31;;;;::::1;::::0;;;;;;;;;;84539:34;;-1:-1:-1;84587:19:0;84580:31;;::::1;84587:19:::0;84580:31;;::::1;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;84580:31:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;;;72821:1;84399:218:::0;;;;:::o;73198:147::-;73284:4;73308:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;73308:29:0;;;;;;;;;;;;;;;73198:147::o;52541:104::-;52597:13;52630:7;52623:14;;;;;:::i;54127:155::-;54222:52;49903:10;54255:8;54265;54222:18;:52::i;55246:322::-;55420:41;49903:10;55453:7;55420:18;:41::i;:::-;55412:99;;;;-1:-1:-1;;;55412:99:0;;;;;;;:::i;:::-;55522:38;55536:4;55542:2;55546:7;55555:4;55522:13;:38::i;:::-;55246:322;;;;:::o;84244:149::-;84317:13;84339:23;84354:7;84339:14;:23::i;:::-;84378:9;84371:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84244:149;;;:::o;75606:::-;74799:7;74826:12;;;:6;:12;;;;;:22;;;72794:16;72805:4;72794:10;:16::i;:::-;75721:26:::1;75733:4;75739:7;75721:11;:26::i;84122:116::-:0;72348:4;72794:16;72348:4;72794:10;:16::i;:::-;84216;;::::1;::::0;:9:::1;::::0;:16:::1;::::0;::::1;::::0;::::1;:::i;72902:204::-:0;72987:4;-1:-1:-1;;;;;;73011:47:0;;-1:-1:-1;;;73011:47:0;;:87;;;73062:36;73086:11;73062:23;:36::i;63703:135::-;57371:4;56969:16;;;:7;:16;;;;;;-1:-1:-1;;;;;56969:16:0;63777:53;;;;-1:-1:-1;;;63777:53:0;;15659:2:1;63777:53:0;;;15641:21:1;15698:2;15678:18;;;15671:30;-1:-1:-1;;;15717:18:1;;;15710:54;15781:18;;63777:53:0;15457:348:1;63777:53:0;63703:135;:::o;62982:174::-;63057:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;63057:29:0;-1:-1:-1;;;;;63057:29:0;;;;;;;;:24;;63111:23;63057:24;63111:14;:23::i;:::-;-1:-1:-1;;;;;63102:46:0;;;;;;;;;;;62982:174;;:::o;57601:264::-;57694:4;57711:13;57727:23;57742:7;57727:14;:23::i;:::-;57711:39;;57780:5;-1:-1:-1;;;;;57769:16:0;:7;-1:-1:-1;;;;;57769:16:0;;:52;;;-1:-1:-1;;;;;;54474:25:0;;;54450:4;54474:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;57789:32;57769:87;;;;57849:7;-1:-1:-1;;;;;57825:31:0;:20;57837:7;57825:11;:20::i;:::-;-1:-1:-1;;;;;57825:31:0;;57769:87;57761:96;57601:264;-1:-1:-1;;;;57601:264:0:o;61600:1263::-;61759:4;-1:-1:-1;;;;;61732:31:0;:23;61747:7;61732:14;:23::i;:::-;-1:-1:-1;;;;;61732:31:0;;61724:81;;;;-1:-1:-1;;;61724:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;61824:16:0;;61816:65;;;;-1:-1:-1;;;61816:65:0;;13441:2:1;61816:65:0;;;13423:21:1;13480:2;13460:18;;;13453:30;13519:34;13499:18;;;13492:62;-1:-1:-1;;;13570:18:1;;;13563:34;13614:19;;61816:65:0;13239:400:1;61816:65:0;61894:42;61915:4;61921:2;61925:7;61934:1;61894:20;:42::i;:::-;62066:4;-1:-1:-1;;;;;62039:31:0;:23;62054:7;62039:14;:23::i;:::-;-1:-1:-1;;;;;62039:31:0;;62031:81;;;;-1:-1:-1;;;62031:81:0;;;;;;;:::i;:::-;62184:24;;;;:15;:24;;;;;;;;62177:31;;-1:-1:-1;;;;;;62177:31:0;;;;;;-1:-1:-1;;;;;62660:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;62660:20:0;;;62695:13;;;;;;;;;:18;;62177:31;62695:18;;;62735:16;;;:7;:16;;;;;;:21;;;;;;;;;;62774:27;;62200:7;;62774:27;;;53472:346;53402:416;;:::o;73649:105::-;73716:30;73727:4;49903:10;73716;:30::i;77907:238::-;77991:22;77999:4;78005:7;77991;:22::i;:::-;77986:152;;78030:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;78030:29:0;;;;;;;;;:36;;-1:-1:-1;;78030:36:0;78062:4;78030:36;;;78113:12;49903:10;;49823:98;78113:12;-1:-1:-1;;;;;78086:40:0;78104:7;-1:-1:-1;;;;;78086:40:0;78098:4;78086:40;;;;;;;;;;77907:238;;:::o;78325:239::-;78409:22;78417:4;78423:7;78409;:22::i;:::-;78405:152;;;78480:5;78448:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;78448:29:0;;;;;;;;;;:37;;-1:-1:-1;;78448:37:0;;;78505:40;49903:10;;78448:12;;78505:40;;78480:5;78505:40;78325:239;;:::o;4944:293::-;4346:1;5078:7;;:19;;5070:63;;;;-1:-1:-1;;;5070:63:0;;16844:2:1;5070:63:0;;;16826:21:1;16883:2;16863:18;;;16856:30;16922:33;16902:18;;;16895:61;16973:18;;5070:63:0;16642:355:1;5070:63:0;4346:1;5211:7;:18;4944:293::o;83778:338::-;83873:4;83888:14;83932:10;83944:5;83915:35;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83905:46;;;;;;83888:63;;83960:12;84038:6;83985:60;;;;;;;6923:66:1;6911:79;;7015:2;7006:12;;6999:28;;;;7052:2;7043:12;;6681:380;83985:60:0;;;;-1:-1:-1;;83985:60:0;;;;;;;;;83975:71;;83985:60;83975:71;;;;;-1:-1:-1;84062:48:0;:10;83975:71;84099:10;84062:30;:48::i;58207:110::-;58283:26;58293:2;58297:7;58283:26;;;;;;;;;;;;:9;:26::i;63299:315::-;63454:8;-1:-1:-1;;;;;63445:17:0;:5;-1:-1:-1;;;;;63445:17:0;;;63437:55;;;;-1:-1:-1;;;63437:55:0;;13846:2:1;63437:55:0;;;13828:21:1;13885:2;13865:18;;;13858:30;13924:27;13904:18;;;13897:55;13969:18;;63437:55:0;13644:349:1;63437:55:0;-1:-1:-1;;;;;63503:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;63503:46:0;;;;;;;;;;63565:41;;9361::1;;;63565::0;;9334:18:1;63565:41:0;;;;;;;63299:315;;;:::o;56449:313::-;56605:28;56615:4;56621:2;56625:7;56605:9;:28::i;:::-;56652:47;56675:4;56681:2;56685:7;56694:4;56652:22;:47::i;:::-;56644:110;;;;-1:-1:-1;;;56644:110:0;;;;;;;:::i;51444:305::-;51546:4;-1:-1:-1;;;;;;51583:40:0;;-1:-1:-1;;;51583:40:0;;:105;;-1:-1:-1;;;;;;;51640:48:0;;-1:-1:-1;;;51640:48:0;51583:105;:158;;;-1:-1:-1;;;;;;;;;;23417:40:0;;;51705:36;23308:157;65987:410;66177:1;66165:9;:13;66161:229;;;-1:-1:-1;;;;;66199:18:0;;;66195:87;;-1:-1:-1;;;;;66238:15:0;;;;;;:9;:15;;;;;:28;;66257:9;;66238:15;:28;;66257:9;;66238:28;:::i;:::-;;;;-1:-1:-1;;66195:87:0;-1:-1:-1;;;;;66300:16:0;;;66296:83;;-1:-1:-1;;;;;66337:13:0;;;;;;:9;:13;;;;;:26;;66354:9;;66337:13;:26;;66354:9;;66337:26;:::i;:::-;;;;-1:-1:-1;;65987:410:0;;;;:::o;74044:492::-;74133:22;74141:4;74147:7;74133;:22::i;:::-;74128:401;;74321:28;74341:7;74321:19;:28::i;:::-;74422:38;74450:4;74457:2;74422:19;:38::i;:::-;74226:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;74226:257:0;;;;;;;;;;-1:-1:-1;;;74172:345:0;;;;;;;:::i;48454:683::-;48594:4;48612:17;48631:24;48659:33;48676:4;48682:9;48659:16;:33::i;:::-;48611:81;;-1:-1:-1;48611:81:0;-1:-1:-1;48716:26:0;48707:5;:35;;;;;;;;:::i;:::-;;:58;;;;;48759:6;-1:-1:-1;;;;;48746:19:0;:9;-1:-1:-1;;;;;48746:19:0;;48707:58;48703:102;;;48789:4;48782:11;;;;;;48703:102;48818:12;48832:19;48855:6;-1:-1:-1;;;;;48855:17:0;48910:34;;;48946:4;48952:9;48887:75;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;48887:75:0;;;;;;;;;;;;;;-1:-1:-1;;;;;48887:75:0;-1:-1:-1;;;;;;48887:75:0;;;;;;;;;;48855:118;;;;48887:75;48855:118;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48817:156;;;;48992:7;:43;;;;;49016:6;:13;49033:2;49016:19;48992:43;:136;;;;-1:-1:-1;49052:29:0;;-1:-1:-1;;;49093:34:0;49052:29;;;;;;;;;;;;:::i;:::-;:76;48992:136;48984:145;;;;;;48454:683;;;;;;:::o;58544:319::-;58673:18;58679:2;58683:7;58673:5;:18::i;:::-;58724:53;58755:1;58759:2;58763:7;58772:4;58724:22;:53::i;:::-;58702:153;;;;-1:-1:-1;;;58702:153:0;;;;;;;:::i;64402:853::-;64556:4;-1:-1:-1;;;;;64577:13:0;;7709:19;:23;64573:675;;64613:71;;-1:-1:-1;;;64613:71:0;;-1:-1:-1;;;;;64613:36:0;;;;;:71;;49903:10;;64664:4;;64670:7;;64679:4;;64613:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64613:71:0;;;;;;;;-1:-1:-1;;64613:71:0;;;;;;;;;;;;:::i;:::-;;;64609:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64854:13:0;;64850:328;;64897:60;;-1:-1:-1;;;64897:60:0;;;;;;;:::i;64850:328::-;65128:6;65122:13;65113:6;65109:2;65105:15;65098:38;64609:584;-1:-1:-1;;;;;;64735:51:0;-1:-1:-1;;;64735:51:0;;-1:-1:-1;64728:58:0;;64573:675;-1:-1:-1;65232:4:0;64402:853;;;;;;:::o;38513:151::-;38571:13;38604:52;-1:-1:-1;;;;;38616:22:0;;36668:2;37909:447;37984:13;38010:19;38042:10;38046:6;38042:1;:10;:::i;:::-;:14;;38055:1;38042:14;:::i;:::-;38032:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38032:25:0;;38010:47;;-1:-1:-1;;;38068:6:0;38075:1;38068:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;38068:15:0;;;;;;;;;-1:-1:-1;;;38094:6:0;38101:1;38094:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;38094:15:0;;;;;;;;-1:-1:-1;38125:9:0;38137:10;38141:6;38137:1;:10;:::i;:::-;:14;;38150:1;38137:14;:::i;:::-;38125:26;;38120:131;38157:1;38153;:5;38120:131;;;-1:-1:-1;;;38201:5:0;38209:3;38201:11;38192:21;;;;;;;:::i;:::-;;;;38180:6;38187:1;38180:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;38180:33:0;;;;;;;;-1:-1:-1;38238:1:0;38228:11;;;;;38160:3;;;:::i;:::-;;;38120:131;;;-1:-1:-1;38269:10:0;;38261:55;;;;-1:-1:-1;;;38261:55:0;;10717:2:1;38261:55:0;;;10699:21:1;;;10736:18;;;10729:30;10795:34;10775:18;;;10768:62;10847:18;;38261:55:0;10515:356:1;40878:747:0;40959:7;40968:12;40997:9;:16;41017:2;40997:22;40993:625;;;41341:4;41326:20;;41320:27;41391:4;41376:20;;41370:27;41449:4;41434:20;;41428:27;41036:9;41420:36;41492:25;41503:4;41420:36;41320:27;41370;41492:10;:25::i;:::-;41485:32;;;;;;;;;40993:625;-1:-1:-1;41566:1:0;;-1:-1:-1;41570:35:0;40993:625;40878:747;;;;;:::o;59199:942::-;-1:-1:-1;;;;;59279:16:0;;59271:61;;;;-1:-1:-1;;;59271:61:0;;15298:2:1;59271:61:0;;;15280:21:1;;;15317:18;;;15310:30;15376:34;15356:18;;;15349:62;15428:18;;59271:61:0;15096:356:1;59271:61:0;57371:4;56969:16;;;:7;:16;;;;;;-1:-1:-1;;;;;56969:16:0;57395:31;59343:58;;;;-1:-1:-1;;;59343:58:0;;12731:2:1;59343:58:0;;;12713:21:1;12770:2;12750:18;;;12743:30;12809;12789:18;;;12782:58;12857:18;;59343:58:0;12529:352:1;59343:58:0;59414:48;59443:1;59447:2;59451:7;59460:1;59414:20;:48::i;:::-;57371:4;56969:16;;;:7;:16;;;;;;-1:-1:-1;;;;;56969:16:0;57395:31;59552:58;;;;-1:-1:-1;;;59552:58:0;;12731:2:1;59552:58:0;;;12713:21:1;12770:2;12750:18;;;12743:30;12809;12789:18;;;12782:58;12857:18;;59552:58:0;12529:352:1;59552:58:0;-1:-1:-1;;;;;59959:13:0;;;;;;:9;:13;;;;;;;;:18;;59976:1;59959:18;;;60001:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;60001:21:0;;;;;60040:33;60009:7;;59959:13;;60040:33;;59959:13;;60040:33;76310:218;;:::o;43879:1520::-;44010:7;;44944:66;44931:79;;44927:163;;;-1:-1:-1;45043:1:0;;-1:-1:-1;45047:30:0;45027:51;;44927:163;45204:24;;;45187:14;45204:24;;;;;;;;;10115:25:1;;;10188:4;10176:17;;10156:18;;;10149:45;;;;10210:18;;;10203:34;;;10253:18;;;10246:34;;;45204:24:0;;10087:19:1;;45204:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;45204:24:0;;-1:-1:-1;;45204:24:0;;;-1:-1:-1;;;;;;;45243:20:0;;45239:103;;45296:1;45300:29;45280:50;;;;;;;45239:103;45362:6;-1:-1:-1;45370:20:0;;-1:-1:-1;43879:1520:0;;;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:173:1;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:718::-;234:5;287:3;280:4;272:6;268:17;264:27;254:55;;305:1;302;295:12;254:55;341:6;328:20;367:18;404:2;400;397:10;394:36;;;410:18;;:::i;:::-;485:2;479:9;453:2;539:13;;-1:-1:-1;;535:22:1;;;559:2;531:31;527:40;515:53;;;583:18;;;603:22;;;580:46;577:72;;;629:18;;:::i;:::-;669:10;665:2;658:22;704:2;696:6;689:18;750:3;743:4;738:2;730:6;726:15;722:26;719:35;716:55;;;767:1;764;757:12;716:55;831:2;824:4;816:6;812:17;805:4;797:6;793:17;780:54;878:1;871:4;866:2;858:6;854:15;850:26;843:37;898:6;889:15;;;;;;192:718;;;;:::o;915:186::-;974:6;1027:2;1015:9;1006:7;1002:23;998:32;995:52;;;1043:1;1040;1033:12;995:52;1066:29;1085:9;1066:29;:::i;1106:260::-;1174:6;1182;1235:2;1223:9;1214:7;1210:23;1206:32;1203:52;;;1251:1;1248;1241:12;1203:52;1274:29;1293:9;1274:29;:::i;:::-;1264:39;;1322:38;1356:2;1345:9;1341:18;1322:38;:::i;:::-;1312:48;;1106:260;;;;;:::o;1371:328::-;1448:6;1456;1464;1517:2;1505:9;1496:7;1492:23;1488:32;1485:52;;;1533:1;1530;1523:12;1485:52;1556:29;1575:9;1556:29;:::i;:::-;1546:39;;1604:38;1638:2;1627:9;1623:18;1604:38;:::i;:::-;1594:48;;1689:2;1678:9;1674:18;1661:32;1651:42;;1371:328;;;;;:::o;1704:537::-;1799:6;1807;1815;1823;1876:3;1864:9;1855:7;1851:23;1847:33;1844:53;;;1893:1;1890;1883:12;1844:53;1916:29;1935:9;1916:29;:::i;:::-;1906:39;;1964:38;1998:2;1987:9;1983:18;1964:38;:::i;:::-;1954:48;;2049:2;2038:9;2034:18;2021:32;2011:42;;2104:2;2093:9;2089:18;2076:32;2131:18;2123:6;2120:30;2117:50;;;2163:1;2160;2153:12;2117:50;2186:49;2227:7;2218:6;2207:9;2203:22;2186:49;:::i;:::-;2176:59;;;1704:537;;;;;;;:::o;2246:315::-;2311:6;2319;2372:2;2360:9;2351:7;2347:23;2343:32;2340:52;;;2388:1;2385;2378:12;2340:52;2411:29;2430:9;2411:29;:::i;:::-;2401:39;;2490:2;2479:9;2475:18;2462:32;2503:28;2525:5;2503:28;:::i;:::-;2550:5;2540:15;;;2246:315;;;;;:::o;2566:254::-;2634:6;2642;2695:2;2683:9;2674:7;2670:23;2666:32;2663:52;;;2711:1;2708;2701:12;2663:52;2734:29;2753:9;2734:29;:::i;:::-;2724:39;2810:2;2795:18;;;;2782:32;;-1:-1:-1;;;2566:254:1:o;2825:245::-;2892:6;2945:2;2933:9;2924:7;2920:23;2916:32;2913:52;;;2961:1;2958;2951:12;2913:52;2993:9;2987:16;3012:28;3034:5;3012:28;:::i;3075:180::-;3134:6;3187:2;3175:9;3166:7;3162:23;3158:32;3155:52;;;3203:1;3200;3193:12;3155:52;-1:-1:-1;3226:23:1;;3075:180;-1:-1:-1;3075:180:1:o;3260:184::-;3330:6;3383:2;3371:9;3362:7;3358:23;3354:32;3351:52;;;3399:1;3396;3389:12;3351:52;-1:-1:-1;3422:16:1;;3260:184;-1:-1:-1;3260:184:1:o;3449:254::-;3517:6;3525;3578:2;3566:9;3557:7;3553:23;3549:32;3546:52;;;3594:1;3591;3584:12;3546:52;3630:9;3617:23;3607:33;;3659:38;3693:2;3682:9;3678:18;3659:38;:::i;3708:245::-;3766:6;3819:2;3807:9;3798:7;3794:23;3790:32;3787:52;;;3835:1;3832;3825:12;3787:52;3874:9;3861:23;3893:30;3917:5;3893:30;:::i;3958:249::-;4027:6;4080:2;4068:9;4059:7;4055:23;4051:32;4048:52;;;4096:1;4093;4086:12;4048:52;4128:9;4122:16;4147:30;4171:5;4147:30;:::i;4212:321::-;4281:6;4334:2;4322:9;4313:7;4309:23;4305:32;4302:52;;;4350:1;4347;4340:12;4302:52;4390:9;4377:23;4423:18;4415:6;4412:30;4409:50;;;4455:1;4452;4445:12;4409:50;4478:49;4519:7;4510:6;4499:9;4495:22;4478:49;:::i;4538:540::-;4625:6;4633;4686:2;4674:9;4665:7;4661:23;4657:32;4654:52;;;4702:1;4699;4692:12;4654:52;4742:9;4729:23;4771:18;4812:2;4804:6;4801:14;4798:34;;;4828:1;4825;4818:12;4798:34;4851:49;4892:7;4883:6;4872:9;4868:22;4851:49;:::i;:::-;4841:59;;4953:2;4942:9;4938:18;4925:32;4909:48;;4982:2;4972:8;4969:16;4966:36;;;4998:1;4995;4988:12;4966:36;;5021:51;5064:7;5053:8;5042:9;5038:24;5021:51;:::i;:::-;5011:61;;;4538:540;;;;;:::o;5457:257::-;5498:3;5536:5;5530:12;5563:6;5558:3;5551:19;5579:63;5635:6;5628:4;5623:3;5619:14;5612:4;5605:5;5601:16;5579:63;:::i;:::-;5696:2;5675:15;-1:-1:-1;;5671:29:1;5662:39;;;;5703:4;5658:50;;5457:257;-1:-1:-1;;5457:257:1:o;5719:397::-;5933:26;5929:31;5920:6;5916:2;5912:15;5908:53;5903:3;5896:66;5878:3;5991:6;5985:13;6007:62;6062:6;6057:2;6052:3;6048:12;6041:4;6033:6;6029:17;6007:62;:::i;:::-;6089:16;;;;6107:2;6085:25;;5719:397;-1:-1:-1;;;5719:397:1:o;6121:274::-;6250:3;6288:6;6282:13;6304:53;6350:6;6345:3;6338:4;6330:6;6326:17;6304:53;:::i;:::-;6373:16;;;;;6121:274;-1:-1:-1;;6121:274:1:o;7066:786::-;7477:25;7472:3;7465:38;7447:3;7532:6;7526:13;7548:62;7603:6;7598:2;7593:3;7589:12;7582:4;7574:6;7570:17;7548:62;:::i;:::-;-1:-1:-1;;;7669:2:1;7629:16;;;7661:11;;;7654:40;7719:13;;7741:63;7719:13;7790:2;7782:11;;7775:4;7763:17;;7741:63;:::i;:::-;7824:17;7843:2;7820:26;;7066:786;-1:-1:-1;;;;7066:786:1:o;8065:488::-;-1:-1:-1;;;;;8334:15:1;;;8316:34;;8386:15;;8381:2;8366:18;;8359:43;8433:2;8418:18;;8411:34;;;8481:3;8476:2;8461:18;;8454:31;;;8259:4;;8502:45;;8527:19;;8519:6;8502:45;:::i;:::-;8494:53;8065:488;-1:-1:-1;;;;;;8065:488:1:o;8558:658::-;8729:2;8781:21;;;8851:13;;8754:18;;;8873:22;;;8700:4;;8729:2;8952:15;;;;8926:2;8911:18;;;8700:4;8995:195;9009:6;9006:1;9003:13;8995:195;;;9074:13;;-1:-1:-1;;;;;9070:39:1;9058:52;;9165:15;;;;9130:12;;;;9106:1;9024:9;8995:195;;;-1:-1:-1;9207:3:1;;8558:658;-1:-1:-1;;;;;;8558:658:1:o;9595:288::-;9770:6;9759:9;9752:25;9813:2;9808;9797:9;9793:18;9786:30;9733:4;9833:44;9873:2;9862:9;9858:18;9850:6;9833:44;:::i;10291:219::-;10440:2;10429:9;10422:21;10403:4;10460:44;10500:2;10489:9;10485:18;10477:6;10460:44;:::i;10876:409::-;11078:2;11060:21;;;11117:2;11097:18;;;11090:30;11156:34;11151:2;11136:18;;11129:62;-1:-1:-1;;;11222:2:1;11207:18;;11200:43;11275:3;11260:19;;10876:409::o;11290:414::-;11492:2;11474:21;;;11531:2;11511:18;;;11504:30;11570:34;11565:2;11550:18;;11543:62;-1:-1:-1;;;11636:2:1;11621:18;;11614:48;11694:3;11679:19;;11290:414::o;12123:401::-;12325:2;12307:21;;;12364:2;12344:18;;;12337:30;12403:34;12398:2;12383:18;;12376:62;-1:-1:-1;;;12469:2:1;12454:18;;12447:35;12514:3;12499:19;;12123:401::o;18121:128::-;18161:3;18192:1;18188:6;18185:1;18182:13;18179:39;;;18198:18;;:::i;:::-;-1:-1:-1;18234:9:1;;18121:128::o;18254:168::-;18294:7;18360:1;18356;18352:6;18348:14;18345:1;18342:21;18337:1;18330:9;18323:17;18319:45;18316:71;;;18367:18;;:::i;:::-;-1:-1:-1;18407:9:1;;18254:168::o;18427:125::-;18467:4;18495:1;18492;18489:8;18486:34;;;18500:18;;:::i;:::-;-1:-1:-1;18537:9:1;;18427:125::o;18557:258::-;18629:1;18639:113;18653:6;18650:1;18647:13;18639:113;;;18729:11;;;18723:18;18710:11;;;18703:39;18675:2;18668:10;18639:113;;;18770:6;18767:1;18764:13;18761:48;;;-1:-1:-1;;18805:1:1;18787:16;;18780:27;18557:258::o;18820:136::-;18859:3;18887:5;18877:39;;18896:18;;:::i;:::-;-1:-1:-1;;;18932:18:1;;18820:136::o;18961:380::-;19040:1;19036:12;;;;19083;;;19104:61;;19158:4;19150:6;19146:17;19136:27;;19104:61;19211:2;19203:6;19200:14;19180:18;19177:38;19174:161;;;19257:10;19252:3;19248:20;19245:1;19238:31;19292:4;19289:1;19282:15;19320:4;19317:1;19310:15;19346:127;19407:10;19402:3;19398:20;19395:1;19388:31;19438:4;19435:1;19428:15;19462:4;19459:1;19452:15;19478:127;19539:10;19534:3;19530:20;19527:1;19520:31;19570:4;19567:1;19560:15;19594:4;19591:1;19584:15;19610:127;19671:10;19666:3;19662:20;19659:1;19652:31;19702:4;19699:1;19692:15;19726:4;19723:1;19716:15;19742:127;19803:10;19798:3;19794:20;19791:1;19784:31;19834:4;19831:1;19824:15;19858:4;19855:1;19848:15;19874:118;19960:5;19953:13;19946:21;19939:5;19936:32;19926:60;;19982:1;19979;19972:12;19997:131;-1:-1:-1;;;;;;20071:32:1;;20061:43;;20051:71;;20118:1;20115;20108:12
Swarm Source
ipfs://0c961fe1c5a6eed832ca649f504716fcc362332384260cea33d9c392f1c14567
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.