Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 10 from a total of 10 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Safe Transfer Fr... | 23219676 | 102 days ago | IN | 0 ETH | 0.00008541 | ||||
| Safe Transfer Fr... | 22627937 | 184 days ago | IN | 0 ETH | 0.00007309 | ||||
| Set Approval For... | 22626621 | 184 days ago | IN | 0 ETH | 0.00018796 | ||||
| Safe Transfer Fr... | 22625333 | 185 days ago | IN | 0 ETH | 0.0005624 | ||||
| Transfer From | 22624519 | 185 days ago | IN | 0 ETH | 0.0002723 | ||||
| Safe Transfer Fr... | 22624391 | 185 days ago | IN | 0 ETH | 0.00021277 | ||||
| Safe Transfer Fr... | 22623580 | 185 days ago | IN | 0 ETH | 0.00013698 | ||||
| Safe Transfer Fr... | 22623542 | 185 days ago | IN | 0 ETH | 0.00014309 | ||||
| Set Approval For... | 22592653 | 189 days ago | IN | 0 ETH | 0.00009408 | ||||
| Mint Batch | 22592650 | 189 days ago | IN | 0 ETH | 0.00465596 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SilkNFT
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2025-05-30 */ // Sources flattened with hardhat v2.23.0 https://hardhat.org // SPDX-License-Identifier: MIT // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/access/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.0; // File @openzeppelin/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4906.sol) pragma solidity ^0.8.0; /// @title EIP-721 Metadata Update Extension interface IERC4906 is IERC165, IERC721 { /// @dev This event emits when the metadata of a token is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFT. event MetadataUpdate(uint256 _tokenId); /// @dev This event emits when the metadata of a range of tokens is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFTs. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT // 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/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // 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/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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/[email protected] // Original license: SPDX_License_Identifier: MIT // 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/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 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 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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 `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @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); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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 {} /** * @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 {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/extensions/ERC721URIStorage.sol) pragma solidity ^0.8.0; /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is IERC4906, ERC721 { using Strings for uint256; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; /** * @dev See {IERC165-supportsInterface} */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) { return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = _baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } return super.tokenURI(tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Emits {MetadataUpdate}. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; emit MetadataUpdate(tokenId); } /** * @dev See {ERC721-_burn}. This override additionally checks to see if a * token-specific URI was set for the token, and if so, it deletes the token URI from * the storage mapping. */ function _burn(uint256 tokenId) internal virtual override { super._burn(tokenId); if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) pragma solidity ^0.8.0; /** * @dev Provides a set of functions to operate with Base64 strings. * * _Available since v4.5._ */ library Base64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // 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 contracts/SilkNFT.sol // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.9; contract SilkNFT is ERC721URIStorage, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIdCounter; struct NFTData { string frontURI; string backURI; bool isFlipped; } modifier onlyTokenOwner(uint256 tokenId) { require( ownerOf(tokenId) == msg.sender, "Ownable: caller is not the owner" ); _; } mapping(uint256 => NFTData) public nftData; event NFTMinted(address to, uint256 tokenId); event NFTFlipped(uint256 tokenId, bool isFlipped); string private _contractURI; constructor( string memory _name, string memory _symbol, string memory contractURI_ ) ERC721(_name, _symbol) { _contractURI = contractURI_; _tokenIdCounter.increment(); } function contractURI() public view returns (string memory) { return _contractURI; } function setContractURI(string memory newContractURI) public onlyOwner { _contractURI = newContractURI; } function mint( address to, string memory frontURI, string memory backURI ) public onlyOwner returns (uint256) { uint256 tokenId = _tokenIdCounter.current(); _tokenIdCounter.increment(); _mint(to, tokenId); nftData[tokenId] = NFTData({ frontURI: frontURI, backURI: backURI, isFlipped: false }); _setTokenURI(tokenId, frontURI); emit NFTMinted(to, tokenId); return tokenId; } function flip(uint256 tokenId) external onlyTokenOwner(tokenId) { bool hasDoubleSided = bytes(nftData[tokenId].backURI).length > 0; if (!hasDoubleSided) { revert("NFT is not double sided"); } nftData[tokenId].isFlipped = !nftData[tokenId].isFlipped; string memory newURI = nftData[tokenId].isFlipped ? nftData[tokenId].backURI : nftData[tokenId].frontURI; _setTokenURI(tokenId, newURI); emit NFTFlipped(tokenId, nftData[tokenId].isFlipped); } function currentTokenId() public view returns (uint256) { return _tokenIdCounter.current(); } function burn(uint256 tokenId) external onlyTokenOwner(tokenId) { _burn(tokenId); } function mintBatch( address to, string[] memory frontURIs, string[] memory backURIs ) public onlyOwner returns (uint256[] memory) { require( frontURIs.length == backURIs.length, "Array lengths must be equal" ); uint256[] memory mintedTokenIds = new uint256[](frontURIs.length); for (uint i = 0; i < frontURIs.length; i++) { uint256 tokenId = _tokenIdCounter.current(); _tokenIdCounter.increment(); _mint(to, tokenId); nftData[tokenId] = NFTData({ frontURI: frontURIs[i], backURI: backURIs[i], isFlipped: false }); _setTokenURI(tokenId, frontURIs[i]); mintedTokenIds[i] = tokenId; emit NFTMinted(to, tokenId); } return mintedTokenIds; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"contractURI_","type":"string"}],"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":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isFlipped","type":"bool"}],"name":"NFTFlipped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NFTMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"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":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"flip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"frontURI","type":"string"},{"internalType":"string","name":"backURI","type":"string"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string[]","name":"frontURIs","type":"string[]"},{"internalType":"string[]","name":"backURIs","type":"string[]"}],"name":"mintBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftData","outputs":[{"internalType":"string","name":"frontURI","type":"string"},{"internalType":"string","name":"backURI","type":"string"},{"internalType":"bool","name":"isFlipped","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newContractURI","type":"string"}],"name":"setContractURI","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"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b50604051620025a9380380620025a9833981016040819052620000349162000288565b8251839083906200004d90600090602085019062000115565b5080516200006390600190602084019062000115565b505050620000806200007a620000b660201b60201c565b620000ba565b80516200009590600a90602084019062000115565b50620000ad60086200010c60201b62000f481760201c565b50505062000356565b3390565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80546001019055565b828054620001239062000319565b90600052602060002090601f01602090048101928262000147576000855562000192565b82601f106200016257805160ff191683800117855562000192565b8280016001018555821562000192579182015b828111156200019257825182559160200191906001019062000175565b50620001a0929150620001a4565b5090565b5b80821115620001a05760008155600101620001a5565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001e357600080fd5b81516001600160401b0380821115620002005762000200620001bb565b604051601f8301601f19908116603f011681019082821181831017156200022b576200022b620001bb565b816040528381526020925086838588010111156200024857600080fd5b600091505b838210156200026c57858201830151818301840152908201906200024d565b838211156200027e5760008385830101525b9695505050505050565b6000806000606084860312156200029e57600080fd5b83516001600160401b0380821115620002b657600080fd5b620002c487838801620001d1565b94506020860151915080821115620002db57600080fd5b620002e987838801620001d1565b935060408601519150808211156200030057600080fd5b506200030f86828701620001d1565b9150509250925092565b600181811c908216806200032e57607f821691505b602082108114156200035057634e487b7160e01b600052602260045260246000fd5b50919050565b61224380620003666000396000f3fe608060405234801561001057600080fd5b50600436106101575760003560e01c80638c210975116100c3578063b88d4fde1161007c578063b88d4fde146102dd578063c87b56dd146102f0578063e53757c614610303578063e8a3d48514610323578063e985e9c51461032b578063f2fde38b1461036757600080fd5b80638c210975146102695780638da5cb5b1461028b578063938e3d7b1461029c57806395d89b41146102af57806399071190146102b7578063a22cb465146102ca57600080fd5b806323b872dd1161011557806323b872dd1461020257806342842e0e1461021557806342966c68146102285780636352211e1461023b57806370a082311461024e578063715018a61461026157600080fd5b80629a9b7b1461015c57806301ffc9a71461017757806306fdde031461019a578063081812fc146101af578063095ea7b3146101da578063221e885d146101ef575b600080fd5b61016461037a565b6040519081526020015b60405180910390f35b61018a610185366004611adb565b61038a565b604051901515815260200161016e565b6101a26103b5565b60405161016e9190611b50565b6101c26101bd366004611b63565b610447565b6040516001600160a01b03909116815260200161016e565b6101ed6101e8366004611b98565b61046e565b005b6101ed6101fd366004611b63565b610589565b6101ed610210366004611bc2565b61076e565b6101ed610223366004611bc2565b61079f565b6101ed610236366004611b63565b6107ba565b6101c2610249366004611b63565b6107f8565b61016461025c366004611bfe565b610858565b6101ed6108de565b61027c610277366004611b63565b6108f2565b60405161016e93929190611c19565b6007546001600160a01b03166101c2565b6101ed6102aa366004611d10565b610a27565b6101a2610a42565b6101646102c5366004611d45565b610a51565b6101ed6102d8366004611db9565b610b46565b6101ed6102eb366004611df5565b610b51565b6101a26102fe366004611b63565b610b89565b610316610311366004611f10565b610c9a565b60405161016e9190611f7a565b6101a2610ec0565b61018a610339366004611fbe565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6101ed610375366004611bfe565b610ecf565b600061038560085490565b905090565b60006001600160e01b03198216632483248360e11b14806103af57506103af82610f51565b92915050565b6060600080546103c490611ff1565b80601f01602080910402602001604051908101604052809291908181526020018280546103f090611ff1565b801561043d5780601f106104125761010080835404028352916020019161043d565b820191906000526020600020905b81548152906001019060200180831161042057829003601f168201915b5050505050905090565b600061045282610fa1565b506000908152600460205260409020546001600160a01b031690565b6000610479826107f8565b9050806001600160a01b0316836001600160a01b031614156104ec5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061050857506105088133610339565b61057a5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016104e3565b6105848383611000565b505050565b8033610594826107f8565b6001600160a01b0316146105ba5760405162461bcd60e51b81526004016104e39061202c565b600082815260096020526040812060010180548291906105d990611ff1565b90501190508061062b5760405162461bcd60e51b815260206004820152601760248201527f4e4654206973206e6f7420646f75626c6520736964656400000000000000000060448201526064016104e3565b6000838152600960205260408120600201805460ff19811660ff9182161590811790925516610667576000848152600960205260409020610679565b60008481526009602052604090206001015b805461068490611ff1565b80601f01602080910402602001604051908101604052809291908181526020018280546106b090611ff1565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b5050505050905061070e848261106e565b600084815260096020526040908190206002015490517fb49c2a69e3eaafe66564c18a0137e408343d5e033e94927f49275bc387b385469161076091879160ff16909182521515602082015260400190565b60405180910390a150505050565b6107783382611140565b6107945760405162461bcd60e51b81526004016104e390612061565b6105848383836111be565b61058483838360405180602001604052806000815250610b51565b80336107c5826107f8565b6001600160a01b0316146107eb5760405162461bcd60e51b81526004016104e39061202c565b6107f482611322565b5050565b6000818152600260205260408120546001600160a01b0316806103af5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016104e3565b60006001600160a01b0382166108c25760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016104e3565b506001600160a01b031660009081526003602052604090205490565b6108e6611362565b6108f0600061138c565b565b60096020526000908152604090208054819061090d90611ff1565b80601f016020809104026020016040519081016040528092919081815260200182805461093990611ff1565b80156109865780601f1061095b57610100808354040283529160200191610986565b820191906000526020600020905b81548152906001019060200180831161096957829003601f168201915b50505050509080600101805461099b90611ff1565b80601f01602080910402602001604051908101604052809291908181526020018280546109c790611ff1565b8015610a145780601f106109e957610100808354040283529160200191610a14565b820191906000526020600020905b8154815290600101906020018083116109f757829003601f168201915b5050506002909301549192505060ff1683565b610a2f611362565b80516107f490600a9060208401906119f6565b6060600180546103c490611ff1565b6000610a5b611362565b6000610a6660085490565b9050610a76600880546001019055565b610a8085826113de565b604080516060810182528581526020808201869052600082840181905284815260098252929092208151805192939192610abd92849201906119f6565b506020828101518051610ad692600185019201906119f6565b50604091909101516002909101805460ff1916911515919091179055610afc818561106e565b604080516001600160a01b0387168152602081018390527f4cc0a9c4a99ddc700de1af2c9f916a7cbfdb71f14801ccff94061ad1ef8a8040910160405180910390a1949350505050565b6107f4338383611569565b610b5b3383611140565b610b775760405162461bcd60e51b81526004016104e390612061565b610b8384848484611638565b50505050565b6060610b9482610fa1565b60008281526006602052604081208054610bad90611ff1565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd990611ff1565b8015610c265780601f10610bfb57610100808354040283529160200191610c26565b820191906000526020600020905b815481529060010190602001808311610c0957829003601f168201915b505050505090506000610c4460408051602081019091526000815290565b9050805160001415610c57575092915050565b815115610c89578082604051602001610c719291906120ae565b60405160208183030381529060405292505050919050565b610c928461166b565b949350505050565b6060610ca4611362565b8151835114610cf55760405162461bcd60e51b815260206004820152601b60248201527f4172726179206c656e67746873206d75737420626520657175616c000000000060448201526064016104e3565b6000835167ffffffffffffffff811115610d1157610d11611c51565b604051908082528060200260200182016040528015610d3a578160200160208202803683370190505b50905060005b8451811015610eb7576000610d5460085490565b9050610d64600880546001019055565b610d6e87826113de565b6040518060600160405280878481518110610d8b57610d8b6120dd565b60200260200101518152602001868481518110610daa57610daa6120dd565b60209081029190910181015182526000918101829052838252600981526040909120825180519192610de1928492909101906119f6565b506020828101518051610dfa92600185019201906119f6565b5060408201518160020160006101000a81548160ff021916908315150217905550905050610e4181878481518110610e3457610e346120dd565b602002602001015161106e565b80838381518110610e5457610e546120dd565b602090810291909101810191909152604080516001600160a01b038a1681529182018390527f4cc0a9c4a99ddc700de1af2c9f916a7cbfdb71f14801ccff94061ad1ef8a8040910160405180910390a15080610eaf816120f3565b915050610d40565b50949350505050565b6060600a80546103c490611ff1565b610ed7611362565b6001600160a01b038116610f3c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104e3565b610f458161138c565b50565b80546001019055565b60006001600160e01b031982166380ac58cd60e01b1480610f8257506001600160e01b03198216635b5e139f60e01b145b806103af57506301ffc9a760e01b6001600160e01b03198316146103af565b6000818152600260205260409020546001600160a01b0316610f455760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016104e3565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611035826107f8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000828152600260205260409020546001600160a01b03166110e95760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b60648201526084016104e3565b60008281526006602090815260409091208251611108928401906119f6565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b60008061114c836107f8565b9050806001600160a01b0316846001600160a01b0316148061119357506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80610c925750836001600160a01b03166111ac84610447565b6001600160a01b031614949350505050565b826001600160a01b03166111d1826107f8565b6001600160a01b0316146111f75760405162461bcd60e51b81526004016104e39061211c565b6001600160a01b0382166112595760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016104e3565b826001600160a01b031661126c826107f8565b6001600160a01b0316146112925760405162461bcd60e51b81526004016104e39061211c565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61132b816116df565b6000818152600660205260409020805461134490611ff1565b159050610f45576000818152600660205260408120610f4591611a7a565b6007546001600160a01b031633146108f05760405162461bcd60e51b81526004016104e39061202c565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166114345760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104e3565b6000818152600260205260409020546001600160a01b0316156114995760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104e3565b6000818152600260205260409020546001600160a01b0316156114fe5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104e3565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031614156115cb5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104e3565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6116438484846111be565b61164f84848484611774565b610b835760405162461bcd60e51b81526004016104e390612161565b606061167682610fa1565b600061168d60408051602081019091526000815290565b905060008151116116ad57604051806020016040528060008152506116d8565b806116b784611881565b6040516020016116c89291906120ae565b6040516020818303038152906040525b9392505050565b60006116ea826107f8565b90506116f5826107f8565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006001600160a01b0384163b1561187657604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906117b89033908990889088906004016121b3565b602060405180830381600087803b1580156117d257600080fd5b505af1925050508015611802575060408051601f3d908101601f191682019092526117ff918101906121f0565b60015b61185c573d808015611830576040519150601f19603f3d011682016040523d82523d6000602084013e611835565b606091505b5080516118545760405162461bcd60e51b81526004016104e390612161565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610c92565b506001949350505050565b6060600061188e8361191e565b600101905060008167ffffffffffffffff8111156118ae576118ae611c51565b6040519080825280601f01601f1916602001820160405280156118d8576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461191157611916565b6118e2565b509392505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061195d5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611989576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106119a757662386f26fc10000830492506010015b6305f5e10083106119bf576305f5e100830492506008015b61271083106119d357612710830492506004015b606483106119e5576064830492506002015b600a83106103af5760010192915050565b828054611a0290611ff1565b90600052602060002090601f016020900481019282611a245760008555611a6a565b82601f10611a3d57805160ff1916838001178555611a6a565b82800160010185558215611a6a579182015b82811115611a6a578251825591602001919060010190611a4f565b50611a76929150611ab0565b5090565b508054611a8690611ff1565b6000825580601f10611a96575050565b601f016020900490600052602060002090810190610f4591905b5b80821115611a765760008155600101611ab1565b6001600160e01b031981168114610f4557600080fd5b600060208284031215611aed57600080fd5b81356116d881611ac5565b60005b83811015611b13578181015183820152602001611afb565b83811115610b835750506000910152565b60008151808452611b3c816020860160208601611af8565b601f01601f19169290920160200192915050565b6020815260006116d86020830184611b24565b600060208284031215611b7557600080fd5b5035919050565b80356001600160a01b0381168114611b9357600080fd5b919050565b60008060408385031215611bab57600080fd5b611bb483611b7c565b946020939093013593505050565b600080600060608486031215611bd757600080fd5b611be084611b7c565b9250611bee60208501611b7c565b9150604084013590509250925092565b600060208284031215611c1057600080fd5b6116d882611b7c565b606081526000611c2c6060830186611b24565b8281036020840152611c3e8186611b24565b9150508215156040830152949350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611c9057611c90611c51565b604052919050565b600067ffffffffffffffff831115611cb257611cb2611c51565b611cc5601f8401601f1916602001611c67565b9050828152838383011115611cd957600080fd5b828260208301376000602084830101529392505050565b600082601f830112611d0157600080fd5b6116d883833560208501611c98565b600060208284031215611d2257600080fd5b813567ffffffffffffffff811115611d3957600080fd5b610c9284828501611cf0565b600080600060608486031215611d5a57600080fd5b611d6384611b7c565b9250602084013567ffffffffffffffff80821115611d8057600080fd5b611d8c87838801611cf0565b93506040860135915080821115611da257600080fd5b50611daf86828701611cf0565b9150509250925092565b60008060408385031215611dcc57600080fd5b611dd583611b7c565b915060208301358015158114611dea57600080fd5b809150509250929050565b60008060008060808587031215611e0b57600080fd5b611e1485611b7c565b9350611e2260208601611b7c565b925060408501359150606085013567ffffffffffffffff811115611e4557600080fd5b8501601f81018713611e5657600080fd5b611e6587823560208401611c98565b91505092959194509250565b600082601f830112611e8257600080fd5b8135602067ffffffffffffffff80831115611e9f57611e9f611c51565b8260051b611eae838201611c67565b9384528581018301938381019088861115611ec857600080fd5b84880192505b85831015611f0457823584811115611ee65760008081fd5b611ef48a87838c0101611cf0565b8352509184019190840190611ece565b98975050505050505050565b600080600060608486031215611f2557600080fd5b611f2e84611b7c565b9250602084013567ffffffffffffffff80821115611f4b57600080fd5b611f5787838801611e71565b93506040860135915080821115611f6d57600080fd5b50611daf86828701611e71565b6020808252825182820181905260009190848201906040850190845b81811015611fb257835183529284019291840191600101611f96565b50909695505050505050565b60008060408385031215611fd157600080fd5b611fda83611b7c565b9150611fe860208401611b7c565b90509250929050565b600181811c9082168061200557607f821691505b6020821081141561202657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b600083516120c0818460208801611af8565b8351908301906120d4818360208801611af8565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561211557634e487b7160e01b600052601160045260246000fd5b5060010190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121e690830184611b24565b9695505050505050565b60006020828403121561220257600080fd5b81516116d881611ac556fea26469706673582212207f9d3897109a85fa01ac5af12f35e8d0acedda25f7176f0f2093269f6edb096264736f6c63430008090033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000001253746f72696573206f6e20436972636c657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003536f4300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b726569676c6f63776770666d3465696669786a6e346362357573776c6f6c6969716d657a726b7a3666727a667965673475356362616c34000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101575760003560e01c80638c210975116100c3578063b88d4fde1161007c578063b88d4fde146102dd578063c87b56dd146102f0578063e53757c614610303578063e8a3d48514610323578063e985e9c51461032b578063f2fde38b1461036757600080fd5b80638c210975146102695780638da5cb5b1461028b578063938e3d7b1461029c57806395d89b41146102af57806399071190146102b7578063a22cb465146102ca57600080fd5b806323b872dd1161011557806323b872dd1461020257806342842e0e1461021557806342966c68146102285780636352211e1461023b57806370a082311461024e578063715018a61461026157600080fd5b80629a9b7b1461015c57806301ffc9a71461017757806306fdde031461019a578063081812fc146101af578063095ea7b3146101da578063221e885d146101ef575b600080fd5b61016461037a565b6040519081526020015b60405180910390f35b61018a610185366004611adb565b61038a565b604051901515815260200161016e565b6101a26103b5565b60405161016e9190611b50565b6101c26101bd366004611b63565b610447565b6040516001600160a01b03909116815260200161016e565b6101ed6101e8366004611b98565b61046e565b005b6101ed6101fd366004611b63565b610589565b6101ed610210366004611bc2565b61076e565b6101ed610223366004611bc2565b61079f565b6101ed610236366004611b63565b6107ba565b6101c2610249366004611b63565b6107f8565b61016461025c366004611bfe565b610858565b6101ed6108de565b61027c610277366004611b63565b6108f2565b60405161016e93929190611c19565b6007546001600160a01b03166101c2565b6101ed6102aa366004611d10565b610a27565b6101a2610a42565b6101646102c5366004611d45565b610a51565b6101ed6102d8366004611db9565b610b46565b6101ed6102eb366004611df5565b610b51565b6101a26102fe366004611b63565b610b89565b610316610311366004611f10565b610c9a565b60405161016e9190611f7a565b6101a2610ec0565b61018a610339366004611fbe565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6101ed610375366004611bfe565b610ecf565b600061038560085490565b905090565b60006001600160e01b03198216632483248360e11b14806103af57506103af82610f51565b92915050565b6060600080546103c490611ff1565b80601f01602080910402602001604051908101604052809291908181526020018280546103f090611ff1565b801561043d5780601f106104125761010080835404028352916020019161043d565b820191906000526020600020905b81548152906001019060200180831161042057829003601f168201915b5050505050905090565b600061045282610fa1565b506000908152600460205260409020546001600160a01b031690565b6000610479826107f8565b9050806001600160a01b0316836001600160a01b031614156104ec5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061050857506105088133610339565b61057a5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016104e3565b6105848383611000565b505050565b8033610594826107f8565b6001600160a01b0316146105ba5760405162461bcd60e51b81526004016104e39061202c565b600082815260096020526040812060010180548291906105d990611ff1565b90501190508061062b5760405162461bcd60e51b815260206004820152601760248201527f4e4654206973206e6f7420646f75626c6520736964656400000000000000000060448201526064016104e3565b6000838152600960205260408120600201805460ff19811660ff9182161590811790925516610667576000848152600960205260409020610679565b60008481526009602052604090206001015b805461068490611ff1565b80601f01602080910402602001604051908101604052809291908181526020018280546106b090611ff1565b80156106fd5780601f106106d2576101008083540402835291602001916106fd565b820191906000526020600020905b8154815290600101906020018083116106e057829003601f168201915b5050505050905061070e848261106e565b600084815260096020526040908190206002015490517fb49c2a69e3eaafe66564c18a0137e408343d5e033e94927f49275bc387b385469161076091879160ff16909182521515602082015260400190565b60405180910390a150505050565b6107783382611140565b6107945760405162461bcd60e51b81526004016104e390612061565b6105848383836111be565b61058483838360405180602001604052806000815250610b51565b80336107c5826107f8565b6001600160a01b0316146107eb5760405162461bcd60e51b81526004016104e39061202c565b6107f482611322565b5050565b6000818152600260205260408120546001600160a01b0316806103af5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016104e3565b60006001600160a01b0382166108c25760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016104e3565b506001600160a01b031660009081526003602052604090205490565b6108e6611362565b6108f0600061138c565b565b60096020526000908152604090208054819061090d90611ff1565b80601f016020809104026020016040519081016040528092919081815260200182805461093990611ff1565b80156109865780601f1061095b57610100808354040283529160200191610986565b820191906000526020600020905b81548152906001019060200180831161096957829003601f168201915b50505050509080600101805461099b90611ff1565b80601f01602080910402602001604051908101604052809291908181526020018280546109c790611ff1565b8015610a145780601f106109e957610100808354040283529160200191610a14565b820191906000526020600020905b8154815290600101906020018083116109f757829003601f168201915b5050506002909301549192505060ff1683565b610a2f611362565b80516107f490600a9060208401906119f6565b6060600180546103c490611ff1565b6000610a5b611362565b6000610a6660085490565b9050610a76600880546001019055565b610a8085826113de565b604080516060810182528581526020808201869052600082840181905284815260098252929092208151805192939192610abd92849201906119f6565b506020828101518051610ad692600185019201906119f6565b50604091909101516002909101805460ff1916911515919091179055610afc818561106e565b604080516001600160a01b0387168152602081018390527f4cc0a9c4a99ddc700de1af2c9f916a7cbfdb71f14801ccff94061ad1ef8a8040910160405180910390a1949350505050565b6107f4338383611569565b610b5b3383611140565b610b775760405162461bcd60e51b81526004016104e390612061565b610b8384848484611638565b50505050565b6060610b9482610fa1565b60008281526006602052604081208054610bad90611ff1565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd990611ff1565b8015610c265780601f10610bfb57610100808354040283529160200191610c26565b820191906000526020600020905b815481529060010190602001808311610c0957829003601f168201915b505050505090506000610c4460408051602081019091526000815290565b9050805160001415610c57575092915050565b815115610c89578082604051602001610c719291906120ae565b60405160208183030381529060405292505050919050565b610c928461166b565b949350505050565b6060610ca4611362565b8151835114610cf55760405162461bcd60e51b815260206004820152601b60248201527f4172726179206c656e67746873206d75737420626520657175616c000000000060448201526064016104e3565b6000835167ffffffffffffffff811115610d1157610d11611c51565b604051908082528060200260200182016040528015610d3a578160200160208202803683370190505b50905060005b8451811015610eb7576000610d5460085490565b9050610d64600880546001019055565b610d6e87826113de565b6040518060600160405280878481518110610d8b57610d8b6120dd565b60200260200101518152602001868481518110610daa57610daa6120dd565b60209081029190910181015182526000918101829052838252600981526040909120825180519192610de1928492909101906119f6565b506020828101518051610dfa92600185019201906119f6565b5060408201518160020160006101000a81548160ff021916908315150217905550905050610e4181878481518110610e3457610e346120dd565b602002602001015161106e565b80838381518110610e5457610e546120dd565b602090810291909101810191909152604080516001600160a01b038a1681529182018390527f4cc0a9c4a99ddc700de1af2c9f916a7cbfdb71f14801ccff94061ad1ef8a8040910160405180910390a15080610eaf816120f3565b915050610d40565b50949350505050565b6060600a80546103c490611ff1565b610ed7611362565b6001600160a01b038116610f3c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104e3565b610f458161138c565b50565b80546001019055565b60006001600160e01b031982166380ac58cd60e01b1480610f8257506001600160e01b03198216635b5e139f60e01b145b806103af57506301ffc9a760e01b6001600160e01b03198316146103af565b6000818152600260205260409020546001600160a01b0316610f455760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016104e3565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611035826107f8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000828152600260205260409020546001600160a01b03166110e95760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201526d32bc34b9ba32b73a103a37b5b2b760911b60648201526084016104e3565b60008281526006602090815260409091208251611108928401906119f6565b506040518281527ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce79060200160405180910390a15050565b60008061114c836107f8565b9050806001600160a01b0316846001600160a01b0316148061119357506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b80610c925750836001600160a01b03166111ac84610447565b6001600160a01b031614949350505050565b826001600160a01b03166111d1826107f8565b6001600160a01b0316146111f75760405162461bcd60e51b81526004016104e39061211c565b6001600160a01b0382166112595760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016104e3565b826001600160a01b031661126c826107f8565b6001600160a01b0316146112925760405162461bcd60e51b81526004016104e39061211c565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61132b816116df565b6000818152600660205260409020805461134490611ff1565b159050610f45576000818152600660205260408120610f4591611a7a565b6007546001600160a01b031633146108f05760405162461bcd60e51b81526004016104e39061202c565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166114345760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104e3565b6000818152600260205260409020546001600160a01b0316156114995760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104e3565b6000818152600260205260409020546001600160a01b0316156114fe5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104e3565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b816001600160a01b0316836001600160a01b031614156115cb5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104e3565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6116438484846111be565b61164f84848484611774565b610b835760405162461bcd60e51b81526004016104e390612161565b606061167682610fa1565b600061168d60408051602081019091526000815290565b905060008151116116ad57604051806020016040528060008152506116d8565b806116b784611881565b6040516020016116c89291906120ae565b6040516020818303038152906040525b9392505050565b60006116ea826107f8565b90506116f5826107f8565b600083815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526003845282852080546000190190558785526002909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006001600160a01b0384163b1561187657604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906117b89033908990889088906004016121b3565b602060405180830381600087803b1580156117d257600080fd5b505af1925050508015611802575060408051601f3d908101601f191682019092526117ff918101906121f0565b60015b61185c573d808015611830576040519150601f19603f3d011682016040523d82523d6000602084013e611835565b606091505b5080516118545760405162461bcd60e51b81526004016104e390612161565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610c92565b506001949350505050565b6060600061188e8361191e565b600101905060008167ffffffffffffffff8111156118ae576118ae611c51565b6040519080825280601f01601f1916602001820160405280156118d8576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461191157611916565b6118e2565b509392505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061195d5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611989576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106119a757662386f26fc10000830492506010015b6305f5e10083106119bf576305f5e100830492506008015b61271083106119d357612710830492506004015b606483106119e5576064830492506002015b600a83106103af5760010192915050565b828054611a0290611ff1565b90600052602060002090601f016020900481019282611a245760008555611a6a565b82601f10611a3d57805160ff1916838001178555611a6a565b82800160010185558215611a6a579182015b82811115611a6a578251825591602001919060010190611a4f565b50611a76929150611ab0565b5090565b508054611a8690611ff1565b6000825580601f10611a96575050565b601f016020900490600052602060002090810190610f4591905b5b80821115611a765760008155600101611ab1565b6001600160e01b031981168114610f4557600080fd5b600060208284031215611aed57600080fd5b81356116d881611ac5565b60005b83811015611b13578181015183820152602001611afb565b83811115610b835750506000910152565b60008151808452611b3c816020860160208601611af8565b601f01601f19169290920160200192915050565b6020815260006116d86020830184611b24565b600060208284031215611b7557600080fd5b5035919050565b80356001600160a01b0381168114611b9357600080fd5b919050565b60008060408385031215611bab57600080fd5b611bb483611b7c565b946020939093013593505050565b600080600060608486031215611bd757600080fd5b611be084611b7c565b9250611bee60208501611b7c565b9150604084013590509250925092565b600060208284031215611c1057600080fd5b6116d882611b7c565b606081526000611c2c6060830186611b24565b8281036020840152611c3e8186611b24565b9150508215156040830152949350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611c9057611c90611c51565b604052919050565b600067ffffffffffffffff831115611cb257611cb2611c51565b611cc5601f8401601f1916602001611c67565b9050828152838383011115611cd957600080fd5b828260208301376000602084830101529392505050565b600082601f830112611d0157600080fd5b6116d883833560208501611c98565b600060208284031215611d2257600080fd5b813567ffffffffffffffff811115611d3957600080fd5b610c9284828501611cf0565b600080600060608486031215611d5a57600080fd5b611d6384611b7c565b9250602084013567ffffffffffffffff80821115611d8057600080fd5b611d8c87838801611cf0565b93506040860135915080821115611da257600080fd5b50611daf86828701611cf0565b9150509250925092565b60008060408385031215611dcc57600080fd5b611dd583611b7c565b915060208301358015158114611dea57600080fd5b809150509250929050565b60008060008060808587031215611e0b57600080fd5b611e1485611b7c565b9350611e2260208601611b7c565b925060408501359150606085013567ffffffffffffffff811115611e4557600080fd5b8501601f81018713611e5657600080fd5b611e6587823560208401611c98565b91505092959194509250565b600082601f830112611e8257600080fd5b8135602067ffffffffffffffff80831115611e9f57611e9f611c51565b8260051b611eae838201611c67565b9384528581018301938381019088861115611ec857600080fd5b84880192505b85831015611f0457823584811115611ee65760008081fd5b611ef48a87838c0101611cf0565b8352509184019190840190611ece565b98975050505050505050565b600080600060608486031215611f2557600080fd5b611f2e84611b7c565b9250602084013567ffffffffffffffff80821115611f4b57600080fd5b611f5787838801611e71565b93506040860135915080821115611f6d57600080fd5b50611daf86828701611e71565b6020808252825182820181905260009190848201906040850190845b81811015611fb257835183529284019291840191600101611f96565b50909695505050505050565b60008060408385031215611fd157600080fd5b611fda83611b7c565b9150611fe860208401611b7c565b90509250929050565b600181811c9082168061200557607f821691505b6020821081141561202657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b600083516120c0818460208801611af8565b8351908301906120d4818360208801611af8565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561211557634e487b7160e01b600052601160045260246000fd5b5060010190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906121e690830184611b24565b9695505050505050565b60006020828403121561220257600080fd5b81516116d881611ac556fea26469706673582212207f9d3897109a85fa01ac5af12f35e8d0acedda25f7176f0f2093269f6edb096264736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000001253746f72696573206f6e20436972636c657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003536f4300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042697066733a2f2f6261666b726569676c6f63776770666d3465696669786a6e346362357573776c6f6c6969716d657a726b7a3666727a667965673475356362616c34000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): Stories on Circles
Arg [1] : _symbol (string): SoC
Arg [2] : contractURI_ (string): ipfs://bafkreiglocwgpfm4eifixjn4cb5uswloliiqmezrkz6frzfyeg4u5cbal4
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [4] : 53746f72696573206f6e20436972636c65730000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [6] : 536f430000000000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000042
Arg [8] : 697066733a2f2f6261666b726569676c6f63776770666d3465696669786a6e34
Arg [9] : 6362357573776c6f6c6969716d657a726b7a3666727a66796567347535636261
Arg [10] : 6c34000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
66393:3334:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68591:107;;;:::i;:::-;;;160:25:1;;;148:2;133:18;68591:107:0;;;;;;;;59249:207;;;;;;:::i;:::-;;:::i;:::-;;;747:14:1;;740:22;722:41;;710:2;695:18;59249:207:0;582:187:1;43731:100:0;;;:::i;:::-;;;;;;;:::i;45243:171::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1874:32:1;;;1856:51;;1844:2;1829:18;45243:171:0;1710:203:1;44761:416:0;;;;;;:::i;:::-;;:::i;:::-;;68030:553;;;;;;:::i;:::-;;:::i;45943:301::-;;;;;;:::i;:::-;;:::i;46315:151::-;;;;;;:::i;:::-;;:::i;68706:97::-;;;;;;:::i;:::-;;:::i;43441:223::-;;;;;;:::i;:::-;;:::i;43172:207::-;;;;;;:::i;:::-;;:::i;2979:103::-;;;:::i;66836:42::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;2338:87::-;2411:6;;-1:-1:-1;;;;;2411:6:0;2338:87;;67370:119;;;;;;:::i;:::-;;:::i;43900:104::-;;;:::i;67497:525::-;;;;;;:::i;:::-;;:::i;45486:155::-;;;;;;:::i;:::-;;:::i;46537:279::-;;;;;;:::i;:::-;;:::i;59527:624::-;;;;;;:::i;:::-;;:::i;68811:913::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;67265:97::-;;;:::i;45712:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;45833:25:0;;;45809:4;45833:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;45712:164;3237:201;;;;;;:::i;:::-;;:::i;68591:107::-;68638:7;68665:25;:15;65771:14;;65679:114;68665:25;68658:32;;68591:107;:::o;59249:207::-;59351:4;-1:-1:-1;;;;;;59375:33:0;;-1:-1:-1;;;59375:33:0;;:73;;;59412:36;59436:11;59412:23;:36::i;:::-;59368:80;59249:207;-1:-1:-1;;59249:207:0:o;43731:100::-;43785:13;43818:5;43811:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43731:100;:::o;45243:171::-;45319:7;45339:23;45354:7;45339:14;:23::i;:::-;-1:-1:-1;45382:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;45382:24:0;;45243:171::o;44761:416::-;44842:13;44858:23;44873:7;44858:14;:23::i;:::-;44842:39;;44906:5;-1:-1:-1;;;;;44900:11:0;:2;-1:-1:-1;;;;;44900:11:0;;;44892:57;;;;-1:-1:-1;;;44892:57:0;;9501:2:1;44892:57:0;;;9483:21:1;9540:2;9520:18;;;9513:30;9579:34;9559:18;;;9552:62;-1:-1:-1;;;9630:18:1;;;9623:31;9671:19;;44892:57:0;;;;;;;;;914:10;-1:-1:-1;;;;;44984:21:0;;;;:62;;-1:-1:-1;45009:37:0;45026:5;914:10;45712:164;:::i;45009:37::-;44962:173;;;;-1:-1:-1;;;44962:173:0;;9903:2:1;44962:173:0;;;9885:21:1;9942:2;9922:18;;;9915:30;9981:34;9961:18;;;9954:62;10052:31;10032:18;;;10025:59;10101:19;;44962:173:0;9701:425:1;44962:173:0;45148:21;45157:2;45161:7;45148:8;:21::i;:::-;44831:346;44761:416;;:::o;68030:553::-;68085:7;66738:10;66718:16;68085:7;66718;:16::i;:::-;-1:-1:-1;;;;;66718:30:0;;66696:112;;;;-1:-1:-1;;;66696:112:0;;;;;;;:::i;:::-;68105:19:::1;68133:16:::0;;;:7:::1;:16;::::0;;;;:24:::1;;68127:38:::0;;68105:19;;68133:24;68127:38:::1;::::0;::::1;:::i;:::-;;;:42;68105:64;;68187:14;68182:81;;68218:33;::::0;-1:-1:-1;;;68218:33:0;;10694:2:1;68218:33:0::1;::::0;::::1;10676:21:1::0;10733:2;10713:18;;;10706:30;10772:25;10752:18;;;10745:53;10815:18;;68218:33:0::1;10492:347:1::0;68182:81:0::1;68305:16;::::0;;;:7:::1;:16;::::0;;;;:26:::1;;::::0;;-1:-1:-1;;68275:56:0;::::1;68305:26;::::0;;::::1;68304:27;68275:56:::0;;::::1;::::0;;;68365:26;:107:::1;;68447:16;::::0;;;:7:::1;:16;::::0;;;;68365:107:::1;;;68407:16;::::0;;;:7:::1;:16;::::0;;;;:24:::1;;68365:107;68342:130;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68483:29;68496:7;68505:6;68483:12;:29::i;:::-;68548:16;::::0;;;:7:::1;:16;::::0;;;;;;:26:::1;;::::0;68528:47;;::::1;::::0;::::1;::::0;68539:7;;68548:26:::1;;::::0;11012:25:1;;;11080:14;11073:22;11068:2;11053:18;;11046:50;11000:2;10985:18;;10844:258;68528:47:0::1;;;;;;;;68094:489;;68030:553:::0;;:::o;45943:301::-;46104:41;914:10;46137:7;46104:18;:41::i;:::-;46096:99;;;;-1:-1:-1;;;46096:99:0;;;;;;;:::i;:::-;46208:28;46218:4;46224:2;46228:7;46208:9;:28::i;46315:151::-;46419:39;46436:4;46442:2;46446:7;46419:39;;;;;;;;;;;;:16;:39::i;68706:97::-;68761:7;66738:10;66718:16;68761:7;66718;:16::i;:::-;-1:-1:-1;;;;;66718:30:0;;66696:112;;;;-1:-1:-1;;;66696:112:0;;;;;;;:::i;:::-;68781:14:::1;68787:7;68781:5;:14::i;:::-;68706:97:::0;;:::o;43441:223::-;43513:7;48174:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48174:16:0;;43577:56;;;;-1:-1:-1;;;43577:56:0;;11723:2:1;43577:56:0;;;11705:21:1;11762:2;11742:18;;;11735:30;-1:-1:-1;;;11781:18:1;;;11774:54;11845:18;;43577:56:0;11521:348:1;43172:207:0;43244:7;-1:-1:-1;;;;;43272:19:0;;43264:73;;;;-1:-1:-1;;;43264:73:0;;12076:2:1;43264:73:0;;;12058:21:1;12115:2;12095:18;;;12088:30;12154:34;12134:18;;;12127:62;-1:-1:-1;;;12205:18:1;;;12198:39;12254:19;;43264:73:0;11874:405:1;43264:73:0;-1:-1:-1;;;;;;43355:16:0;;;;;:9;:16;;;;;;;43172:207::o;2979:103::-;2224:13;:11;:13::i;:::-;3044:30:::1;3071:1;3044:18;:30::i;:::-;2979:103::o:0;66836:42::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;66836:42:0;;;;;;;-1:-1:-1;;66836:42:0;;;:::o;67370:119::-;2224:13;:11;:13::i;:::-;67452:29;;::::1;::::0;:12:::1;::::0;:29:::1;::::0;::::1;::::0;::::1;:::i;43900:104::-:0;43956:13;43989:7;43982:14;;;;;:::i;67497:525::-;67630:7;2224:13;:11;:13::i;:::-;67650:15:::1;67668:25;:15;65771:14:::0;;65679:114;67668:25:::1;67650:43;;67704:27;:15;65890:19:::0;;65908:1;65890:19;;;65801:127;67704:27:::1;67742:18;67748:2;67752:7;67742:5;:18::i;:::-;67792:115;::::0;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;67792:115:0;;;;;;67773:16;;;:7:::1;:16:::0;;;;;;:134;;;;67792:115;;67773:16;;:134:::1;::::0;:16;;:134:::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;67773:134:0::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;67773:134:0::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;;-1:-1:-1;;67773:134:0::1;::::0;::::1;;::::0;;;::::1;::::0;;67918:31:::1;67931:7:::0;67940:8;67918:12:::1;:31::i;:::-;67967:22;::::0;;-1:-1:-1;;;;;12476:32:1;;12458:51;;12540:2;12525:18;;12518:34;;;67967:22:0::1;::::0;12431:18:1;67967:22:0::1;;;;;;;68007:7:::0;67497:525;-1:-1:-1;;;;67497:525:0:o;45486:155::-;45581:52;914:10;45614:8;45624;45581:18;:52::i;46537:279::-;46668:41;914:10;46701:7;46668:18;:41::i;:::-;46660:99;;;;-1:-1:-1;;;46660:99:0;;;;;;;:::i;:::-;46770:38;46784:4;46790:2;46794:7;46803:4;46770:13;:38::i;:::-;46537:279;;;;:::o;59527:624::-;59600:13;59626:23;59641:7;59626:14;:23::i;:::-;59662;59688:19;;;:10;:19;;;;;59662:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59718:18;59739:10;44682:9;;;;;;;;;-1:-1:-1;44682:9:0;;;44605:94;59739:10;59718:31;;59831:4;59825:18;59847:1;59825:23;59821:72;;;-1:-1:-1;59872:9:0;59527:624;-1:-1:-1;;59527:624:0:o;59821:72::-;59997:23;;:27;59993:108;;60072:4;60078:9;60055:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60041:48;;;;59527:624;;;:::o;59993:108::-;60120:23;60135:7;60120:14;:23::i;:::-;60113:30;59527:624;-1:-1:-1;;;;59527:624:0:o;68811:913::-;68955:16;2224:13;:11;:13::i;:::-;69026:8:::1;:15;69006:9;:16;:35;68984:112;;;::::0;-1:-1:-1;;;68984:112:0;;13240:2:1;68984:112:0::1;::::0;::::1;13222:21:1::0;13279:2;13259:18;;;13252:30;13318:29;13298:18;;;13291:57;13365:18;;68984:112:0::1;13038:351:1::0;68984:112:0::1;69107:31;69155:9;:16;69141:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;69141:31:0::1;;69107:65;;69190:6;69185:500;69206:9;:16;69202:1;:20;69185:500;;;69244:15;69262:25;:15;65771:14:::0;;65679:114;69262:25:::1;69244:43;;69302:27;:15;65890:19:::0;;65908:1;65890:19;;;65801:127;69302:27:::1;69344:18;69350:2;69354:7;69344:5;:18::i;:::-;69398:139;;;;;;;;69435:9;69445:1;69435:12;;;;;;;;:::i;:::-;;;;;;;69398:139;;;;69475:8;69484:1;69475:11;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;69398:139;;69516:5:::1;69398:139:::0;;::::1;::::0;;;69379:16;;;:7:::1;:16:::0;;;;;;:158;;;;:16;;:158:::1;::::0;:16;;:158;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;69379:158:0::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69552:35;69565:7;69574:9;69584:1;69574:12;;;;;;;;:::i;:::-;;;;;;;69552;:35::i;:::-;69622:7;69602:14;69617:1;69602:17;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;:27;;;;69651:22:::1;::::0;;-1:-1:-1;;;;;12476:32:1;;12458:51;;12525:18;;;12518:34;;;69651:22:0::1;::::0;12431:18:1;69651:22:0::1;;;;;;;-1:-1:-1::0;69224:3:0;::::1;::::0;::::1;:::i;:::-;;;;69185:500;;;-1:-1:-1::0;69702:14:0;68811:913;-1:-1:-1;;;;68811:913:0:o;67265:97::-;67309:13;67342:12;67335:19;;;;;:::i;3237:201::-;2224:13;:11;:13::i;:::-;-1:-1:-1;;;;;3326:22:0;::::1;3318:73;;;::::0;-1:-1:-1;;;3318:73:0;;13965:2:1;3318:73:0::1;::::0;::::1;13947:21:1::0;14004:2;13984:18;;;13977:30;14043:34;14023:18;;;14016:62;-1:-1:-1;;;14094:18:1;;;14087:36;14140:19;;3318:73:0::1;13763:402:1::0;3318:73:0::1;3402:28;3421:8;3402:18;:28::i;:::-;3237:201:::0;:::o;65801:127::-;65890:19;;65908:1;65890:19;;;65801:127::o;42803:305::-;42905:4;-1:-1:-1;;;;;;42942:40:0;;-1:-1:-1;;;42942:40:0;;:105;;-1:-1:-1;;;;;;;42999:48:0;;-1:-1:-1;;;42999:48:0;42942:105;:158;;;-1:-1:-1;;;;;;;;;;23795:40:0;;;43064:36;23686:157;54806:135;48576:4;48174:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48174:16:0;54880:53;;;;-1:-1:-1;;;54880:53:0;;11723:2:1;54880:53:0;;;11705:21:1;11762:2;11742:18;;;11735:30;-1:-1:-1;;;11781:18:1;;;11774:54;11845:18;;54880:53:0;11521:348:1;54119:174:0;54194:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;54194:29:0;-1:-1:-1;;;;;54194:29:0;;;;;;;;:24;;54248:23;54194:24;54248:14;:23::i;:::-;-1:-1:-1;;;;;54239:46:0;;;;;;;;;;;54119:174;;:::o;60347:258::-;48576:4;48174:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48174:16:0;60439:75;;;;-1:-1:-1;;;60439:75:0;;14372:2:1;60439:75:0;;;14354:21:1;14411:2;14391:18;;;14384:30;14450:34;14430:18;;;14423:62;-1:-1:-1;;;14501:18:1;;;14494:44;14555:19;;60439:75:0;14170:410:1;60439:75:0;60525:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;:::-;-1:-1:-1;60574:23:0;;160:25:1;;;60574:23:0;;148:2:1;133:18;60574:23:0;;;;;;;60347:258;;:::o;48806:264::-;48899:4;48916:13;48932:23;48947:7;48932:14;:23::i;:::-;48916:39;;48985:5;-1:-1:-1;;;;;48974:16:0;:7;-1:-1:-1;;;;;48974:16:0;;:52;;;-1:-1:-1;;;;;;45833:25:0;;;45809:4;45833:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;48994:32;48974:87;;;;49054:7;-1:-1:-1;;;;;49030:31:0;:20;49042:7;49030:11;:20::i;:::-;-1:-1:-1;;;;;49030:31:0;;48966:96;48806:264;-1:-1:-1;;;;48806:264:0:o;52771:1229::-;52896:4;-1:-1:-1;;;;;52869:31:0;:23;52884:7;52869:14;:23::i;:::-;-1:-1:-1;;;;;52869:31:0;;52861:81;;;;-1:-1:-1;;;52861:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;52961:16:0;;52953:65;;;;-1:-1:-1;;;52953:65:0;;15193:2:1;52953:65:0;;;15175:21:1;15232:2;15212:18;;;15205:30;15271:34;15251:18;;;15244:62;-1:-1:-1;;;15322:18:1;;;15315:34;15366:19;;52953:65:0;14991:400:1;52953:65:0;53203:4;-1:-1:-1;;;;;53176:31:0;:23;53191:7;53176:14;:23::i;:::-;-1:-1:-1;;;;;53176:31:0;;53168:81;;;;-1:-1:-1;;;53168:81:0;;;;;;;:::i;:::-;53321:24;;;;:15;:24;;;;;;;;53314:31;;-1:-1:-1;;;;;;53314:31:0;;;;;;-1:-1:-1;;;;;53797:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;53797:20:0;;;53832:13;;;;;;;;;:18;;53314:31;53832:18;;;53872:16;;;:7;:16;;;;;;:21;;;;;;;;;;53911:27;;53337:7;;53911:27;;;44831:346;44761:416;;:::o;60830:206::-;60899:20;60911:7;60899:11;:20::i;:::-;60942:19;;;;:10;:19;;;;;60936:33;;;;;:::i;:::-;:38;;-1:-1:-1;60932:97:0;;60998:19;;;;:10;:19;;;;;60991:26;;;:::i;2503:132::-;2411:6;;-1:-1:-1;;;;;2411:6:0;914:10;2567:23;2559:68;;;;-1:-1:-1;;;2559:68:0;;;;;;;:::i;3598:191::-;3691:6;;;-1:-1:-1;;;;;3708:17:0;;;-1:-1:-1;;;;;;3708:17:0;;;;;;;3741:40;;3691:6;;;3708:17;3691:6;;3741:40;;3672:16;;3741:40;3661:128;3598:191;:::o;50370:942::-;-1:-1:-1;;;;;50450:16:0;;50442:61;;;;-1:-1:-1;;;50442:61:0;;15598:2:1;50442:61:0;;;15580:21:1;;;15617:18;;;15610:30;15676:34;15656:18;;;15649:62;15728:18;;50442:61:0;15396:356:1;50442:61:0;48576:4;48174:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48174:16:0;48600:31;50514:58;;;;-1:-1:-1;;;50514:58:0;;15959:2:1;50514:58:0;;;15941:21:1;15998:2;15978:18;;;15971:30;16037;16017:18;;;16010:58;16085:18;;50514:58:0;15757:352:1;50514:58:0;48576:4;48174:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48174:16:0;48600:31;50723:58;;;;-1:-1:-1;;;50723:58:0;;15959:2:1;50723:58:0;;;15941:21:1;15998:2;15978:18;;;15971:30;16037;16017:18;;;16010:58;16085:18;;50723:58:0;15757:352:1;50723:58:0;-1:-1:-1;;;;;51130:13:0;;;;;;:9;:13;;;;;;;;:18;;51147:1;51130:18;;;51172:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;51172:21:0;;;;;51211:33;51180:7;;51130:13;;51211:33;;51130:13;;51211:33;68706:97;;:::o;54436:281::-;54557:8;-1:-1:-1;;;;;54548:17:0;:5;-1:-1:-1;;;;;54548:17:0;;;54540:55;;;;-1:-1:-1;;;54540:55:0;;16316:2:1;54540:55:0;;;16298:21:1;16355:2;16335:18;;;16328:30;16394:27;16374:18;;;16367:55;16439:18;;54540:55:0;16114:349:1;54540:55:0;-1:-1:-1;;;;;54606:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;54606:46:0;;;;;;;;;;54668:41;;722::1;;;54668::0;;695:18:1;54668:41:0;;;;;;;54436:281;;;:::o;47697:270::-;47810:28;47820:4;47826:2;47830:7;47810:9;:28::i;:::-;47857:47;47880:4;47886:2;47890:7;47899:4;47857:22;:47::i;:::-;47849:110;;;;-1:-1:-1;;;47849:110:0;;;;;;;:::i;44075:281::-;44148:13;44174:23;44189:7;44174:14;:23::i;:::-;44210:21;44234:10;44682:9;;;;;;;;;-1:-1:-1;44682:9:0;;;44605:94;44234:10;44210:34;;44286:1;44268:7;44262:21;:25;:86;;;;;;;;;;;;;;;;;44314:7;44323:18;:7;:16;:18::i;:::-;44297:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;44262:86;44255:93;44075:281;-1:-1:-1;;;44075:281:0:o;51651:783::-;51711:13;51727:23;51742:7;51727:14;:23::i;:::-;51711:39;;51927:23;51942:7;51927:14;:23::i;:::-;51998:24;;;;:15;:24;;;;;;;;51991:31;;-1:-1:-1;;;;;;51991:31:0;;;;;;-1:-1:-1;;;;;52243:16:0;;;;;:9;:16;;;;;:21;;-1:-1:-1;;52243:21:0;;;52293:16;;;:7;:16;;;;;;52286:23;;;;;;;52327:36;51919:31;;-1:-1:-1;52014:7:0;;52327:36;;51998:24;;52327:36;68706:97;;:::o;55505:853::-;55659:4;-1:-1:-1;;;;;55680:13:0;;14902:19;:23;55676:675;;55716:71;;-1:-1:-1;;;55716:71:0;;-1:-1:-1;;;;;55716:36:0;;;;;:71;;914:10;;55767:4;;55773:7;;55782:4;;55716:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55716:71:0;;;;;;;;-1:-1:-1;;55716:71:0;;;;;;;;;;;;:::i;:::-;;;55712:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55957:13:0;;55953:328;;56000:60;;-1:-1:-1;;;56000:60:0;;;;;;;:::i;55953:328::-;56231:6;56225:13;56216:6;56212:2;56208:15;56201:38;55712:584;-1:-1:-1;;;;;;55838:51:0;-1:-1:-1;;;55838:51:0;;-1:-1:-1;55831:58:0;;55676:675;-1:-1:-1;56335:4:0;55505:853;;;;;;:::o;38939:716::-;38995:13;39046:14;39063:17;39074:5;39063:10;:17::i;:::-;39083:1;39063:21;39046:38;;39099:20;39133:6;39122:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39122:18:0;-1:-1:-1;39099:41:0;-1:-1:-1;39264:28:0;;;39280:2;39264:28;39321:288;-1:-1:-1;;39353:5:0;-1:-1:-1;;;39490:2:0;39479:14;;39474:30;39353:5;39461:44;39551:2;39542:11;;;-1:-1:-1;39576:10:0;39572:21;;39588:5;;39572:21;39321:288;;;-1:-1:-1;39630:6:0;38939:716;-1:-1:-1;;;38939:716:0:o;34322:948::-;34375:7;;-1:-1:-1;;;34453:17:0;;34449:106;;-1:-1:-1;;;34491:17:0;;;-1:-1:-1;34537:2:0;34527:12;34449:106;34582:8;34573:5;:17;34569:106;;34620:8;34611:17;;;-1:-1:-1;34657:2:0;34647:12;34569:106;34702:8;34693:5;:17;34689:106;;34740:8;34731:17;;;-1:-1:-1;34777:2:0;34767:12;34689:106;34822:7;34813:5;:16;34809:103;;34859:7;34850:16;;;-1:-1:-1;34895:1:0;34885:11;34809:103;34939:7;34930:5;:16;34926:103;;34976:7;34967:16;;;-1:-1:-1;35012:1:0;35002:11;34926:103;35056:7;35047:5;:16;35043:103;;35093:7;35084:16;;;-1:-1:-1;35129:1:0;35119:11;35043:103;35173:7;35164:5;:16;35160:68;;35211:1;35201:11;35256:6;34322:948;-1:-1:-1;;34322:948:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;196:131:1;-1:-1:-1;;;;;;270:32:1;;260:43;;250:71;;317:1;314;307:12;332:245;390:6;443:2;431:9;422:7;418:23;414:32;411:52;;;459:1;456;449:12;411:52;498:9;485:23;517:30;541:5;517:30;:::i;774:258::-;846:1;856:113;870:6;867:1;864:13;856:113;;;946:11;;;940:18;927:11;;;920:39;892:2;885:10;856:113;;;987:6;984:1;981:13;978:48;;;-1:-1:-1;;1022:1:1;1004:16;;997:27;774:258::o;1037:::-;1079:3;1117:5;1111:12;1144:6;1139:3;1132:19;1160:63;1216:6;1209:4;1204:3;1200:14;1193:4;1186:5;1182:16;1160:63;:::i;:::-;1277:2;1256:15;-1:-1:-1;;1252:29:1;1243:39;;;;1284:4;1239:50;;1037:258;-1:-1:-1;;1037:258:1:o;1300:220::-;1449:2;1438:9;1431:21;1412:4;1469:45;1510:2;1499:9;1495:18;1487:6;1469:45;:::i;1525:180::-;1584:6;1637:2;1625:9;1616:7;1612:23;1608:32;1605:52;;;1653:1;1650;1643:12;1605:52;-1:-1:-1;1676:23:1;;1525:180;-1:-1:-1;1525:180:1:o;1918:173::-;1986:20;;-1:-1:-1;;;;;2035:31:1;;2025:42;;2015:70;;2081:1;2078;2071:12;2015:70;1918:173;;;:::o;2096:254::-;2164:6;2172;2225:2;2213:9;2204:7;2200:23;2196:32;2193:52;;;2241:1;2238;2231:12;2193:52;2264:29;2283:9;2264:29;:::i;:::-;2254:39;2340:2;2325:18;;;;2312:32;;-1:-1:-1;;;2096:254:1:o;2355:328::-;2432:6;2440;2448;2501:2;2489:9;2480:7;2476:23;2472:32;2469:52;;;2517:1;2514;2507:12;2469:52;2540:29;2559:9;2540:29;:::i;:::-;2530:39;;2588:38;2622:2;2611:9;2607:18;2588:38;:::i;:::-;2578:48;;2673:2;2662:9;2658:18;2645:32;2635:42;;2355:328;;;;;:::o;2688:186::-;2747:6;2800:2;2788:9;2779:7;2775:23;2771:32;2768:52;;;2816:1;2813;2806:12;2768:52;2839:29;2858:9;2839:29;:::i;2879:464::-;3098:2;3087:9;3080:21;3061:4;3124:45;3165:2;3154:9;3150:18;3142:6;3124:45;:::i;:::-;3217:9;3209:6;3205:22;3200:2;3189:9;3185:18;3178:50;3245:33;3271:6;3263;3245:33;:::i;:::-;3237:41;;;3328:6;3321:14;3314:22;3309:2;3298:9;3294:18;3287:50;2879:464;;;;;;:::o;3348:127::-;3409:10;3404:3;3400:20;3397:1;3390:31;3440:4;3437:1;3430:15;3464:4;3461:1;3454:15;3480:275;3551:2;3545:9;3616:2;3597:13;;-1:-1:-1;;3593:27:1;3581:40;;3651:18;3636:34;;3672:22;;;3633:62;3630:88;;;3698:18;;:::i;:::-;3734:2;3727:22;3480:275;;-1:-1:-1;3480:275:1:o;3760:407::-;3825:5;3859:18;3851:6;3848:30;3845:56;;;3881:18;;:::i;:::-;3919:57;3964:2;3943:15;;-1:-1:-1;;3939:29:1;3970:4;3935:40;3919:57;:::i;:::-;3910:66;;3999:6;3992:5;3985:21;4039:3;4030:6;4025:3;4021:16;4018:25;4015:45;;;4056:1;4053;4046:12;4015:45;4105:6;4100:3;4093:4;4086:5;4082:16;4069:43;4159:1;4152:4;4143:6;4136:5;4132:18;4128:29;4121:40;3760:407;;;;;:::o;4172:222::-;4215:5;4268:3;4261:4;4253:6;4249:17;4245:27;4235:55;;4286:1;4283;4276:12;4235:55;4308:80;4384:3;4375:6;4362:20;4355:4;4347:6;4343:17;4308:80;:::i;4399:322::-;4468:6;4521:2;4509:9;4500:7;4496:23;4492:32;4489:52;;;4537:1;4534;4527:12;4489:52;4577:9;4564:23;4610:18;4602:6;4599:30;4596:50;;;4642:1;4639;4632:12;4596:50;4665;4707:7;4698:6;4687:9;4683:22;4665:50;:::i;4726:617::-;4823:6;4831;4839;4892:2;4880:9;4871:7;4867:23;4863:32;4860:52;;;4908:1;4905;4898:12;4860:52;4931:29;4950:9;4931:29;:::i;:::-;4921:39;;5011:2;5000:9;4996:18;4983:32;5034:18;5075:2;5067:6;5064:14;5061:34;;;5091:1;5088;5081:12;5061:34;5114:50;5156:7;5147:6;5136:9;5132:22;5114:50;:::i;:::-;5104:60;;5217:2;5206:9;5202:18;5189:32;5173:48;;5246:2;5236:8;5233:16;5230:36;;;5262:1;5259;5252:12;5230:36;;5285:52;5329:7;5318:8;5307:9;5303:24;5285:52;:::i;:::-;5275:62;;;4726:617;;;;;:::o;5348:347::-;5413:6;5421;5474:2;5462:9;5453:7;5449:23;5445:32;5442:52;;;5490:1;5487;5480:12;5442:52;5513:29;5532:9;5513:29;:::i;:::-;5503:39;;5592:2;5581:9;5577:18;5564:32;5639:5;5632:13;5625:21;5618:5;5615:32;5605:60;;5661:1;5658;5651:12;5605:60;5684:5;5674:15;;;5348:347;;;;;:::o;5700:667::-;5795:6;5803;5811;5819;5872:3;5860:9;5851:7;5847:23;5843:33;5840:53;;;5889:1;5886;5879:12;5840:53;5912:29;5931:9;5912:29;:::i;:::-;5902:39;;5960:38;5994:2;5983:9;5979:18;5960:38;:::i;:::-;5950:48;;6045:2;6034:9;6030:18;6017:32;6007:42;;6100:2;6089:9;6085:18;6072:32;6127:18;6119:6;6116:30;6113:50;;;6159:1;6156;6149:12;6113:50;6182:22;;6235:4;6227:13;;6223:27;-1:-1:-1;6213:55:1;;6264:1;6261;6254:12;6213:55;6287:74;6353:7;6348:2;6335:16;6330:2;6326;6322:11;6287:74;:::i;:::-;6277:84;;;5700:667;;;;;;;:::o;6372:943::-;6425:5;6478:3;6471:4;6463:6;6459:17;6455:27;6445:55;;6496:1;6493;6486:12;6445:55;6532:6;6519:20;6558:4;6581:18;6618:2;6614;6611:10;6608:36;;;6624:18;;:::i;:::-;6670:2;6667:1;6663:10;6693:28;6717:2;6713;6709:11;6693:28;:::i;:::-;6755:15;;;6825;;;6821:24;;;6786:12;;;;6857:15;;;6854:35;;;6885:1;6882;6875:12;6854:35;6921:2;6913:6;6909:15;6898:26;;6933:353;6949:6;6944:3;6941:15;6933:353;;;7035:3;7022:17;7071:2;7058:11;7055:19;7052:109;;;7115:1;7144:2;7140;7133:14;7052:109;7186:57;7239:3;7234:2;7220:11;7212:6;7208:24;7204:33;7186:57;:::i;:::-;7174:70;;-1:-1:-1;6966:12:1;;;;7264;;;;6933:353;;;7304:5;6372:943;-1:-1:-1;;;;;;;;6372:943:1:o;7320:687::-;7467:6;7475;7483;7536:2;7524:9;7515:7;7511:23;7507:32;7504:52;;;7552:1;7549;7542:12;7504:52;7575:29;7594:9;7575:29;:::i;:::-;7565:39;;7655:2;7644:9;7640:18;7627:32;7678:18;7719:2;7711:6;7708:14;7705:34;;;7735:1;7732;7725:12;7705:34;7758:60;7810:7;7801:6;7790:9;7786:22;7758:60;:::i;:::-;7748:70;;7871:2;7860:9;7856:18;7843:32;7827:48;;7900:2;7890:8;7887:16;7884:36;;;7916:1;7913;7906:12;7884:36;;7939:62;7993:7;7982:8;7971:9;7967:24;7939:62;:::i;8012:632::-;8183:2;8235:21;;;8305:13;;8208:18;;;8327:22;;;8154:4;;8183:2;8406:15;;;;8380:2;8365:18;;;8154:4;8449:169;8463:6;8460:1;8457:13;8449:169;;;8524:13;;8512:26;;8593:15;;;;8558:12;;;;8485:1;8478:9;8449:169;;;-1:-1:-1;8635:3:1;;8012:632;-1:-1:-1;;;;;;8012:632:1:o;8649:260::-;8717:6;8725;8778:2;8766:9;8757:7;8753:23;8749:32;8746:52;;;8794:1;8791;8784:12;8746:52;8817:29;8836:9;8817:29;:::i;:::-;8807:39;;8865:38;8899:2;8888:9;8884:18;8865:38;:::i;:::-;8855:48;;8649:260;;;;;:::o;8914:380::-;8993:1;8989:12;;;;9036;;;9057:61;;9111:4;9103:6;9099:17;9089:27;;9057:61;9164:2;9156:6;9153:14;9133:18;9130:38;9127:161;;;9210:10;9205:3;9201:20;9198:1;9191:31;9245:4;9242:1;9235:15;9273:4;9270:1;9263:15;9127:161;;8914:380;;;:::o;10131:356::-;10333:2;10315:21;;;10352:18;;;10345:30;10411:34;10406:2;10391:18;;10384:62;10478:2;10463:18;;10131:356::o;11107:409::-;11309:2;11291:21;;;11348:2;11328:18;;;11321:30;11387:34;11382:2;11367:18;;11360:62;-1:-1:-1;;;11453:2:1;11438:18;;11431:43;11506:3;11491:19;;11107:409::o;12563:470::-;12742:3;12780:6;12774:13;12796:53;12842:6;12837:3;12830:4;12822:6;12818:17;12796:53;:::i;:::-;12912:13;;12871:16;;;;12934:57;12912:13;12871:16;12968:4;12956:17;;12934:57;:::i;:::-;13007:20;;12563:470;-1:-1:-1;;;;12563:470:1:o;13394:127::-;13455:10;13450:3;13446:20;13443:1;13436:31;13486:4;13483:1;13476:15;13510:4;13507:1;13500:15;13526:232;13565:3;-1:-1:-1;;13586:17:1;;13583:140;;;13645:10;13640:3;13636:20;13633:1;13626:31;13680:4;13677:1;13670:15;13708:4;13705:1;13698:15;13583:140;-1:-1:-1;13750:1:1;13739:13;;13526:232::o;14585:401::-;14787:2;14769:21;;;14826:2;14806:18;;;14799:30;14865:34;14860:2;14845:18;;14838:62;-1:-1:-1;;;14931:2:1;14916:18;;14909:35;14976:3;14961:19;;14585:401::o;16468:414::-;16670:2;16652:21;;;16709:2;16689:18;;;16682:30;16748:34;16743:2;16728:18;;16721:62;-1:-1:-1;;;16814:2:1;16799:18;;16792:48;16872:3;16857:19;;16468:414::o;16887:489::-;-1:-1:-1;;;;;17156:15:1;;;17138:34;;17208:15;;17203:2;17188:18;;17181:43;17255:2;17240:18;;17233:34;;;17303:3;17298:2;17283:18;;17276:31;;;17081:4;;17324:46;;17350:19;;17342:6;17324:46;:::i;:::-;17316:54;16887:489;-1:-1:-1;;;;;;16887:489:1:o;17381:249::-;17450:6;17503:2;17491:9;17482:7;17478:23;17474:32;17471:52;;;17519:1;17516;17509:12;17471:52;17551:9;17545:16;17570:30;17594:5;17570:30;:::i
Swarm Source
ipfs://7f9d3897109a85fa01ac5af12f35e8d0acedda25f7176f0f2093269f6edb0962
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.