BscScan - Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 174 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer From | 45325058 | 11 mins ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45323639 | 1 hr ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45322427 | 2 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45322000 | 2 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45321012 | 3 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45320710 | 3 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45319803 | 4 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45319406 | 4 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45318285 | 5 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45318115 | 5 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45297234 | 23 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45297108 | 23 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45296631 | 23 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45296320 | 24 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45293878 | 26 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45291143 | 28 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45290906 | 28 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45290867 | 28 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45290846 | 28 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45273490 | 43 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45271073 | 45 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45269349 | 46 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45268503 | 47 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45268457 | 47 hrs ago | IN | 0 BNB | 0.00009493 | ||||
Transfer From | 45268393 | 47 hrs ago | IN | 0 BNB | 0.00009493 |
Loading...
Loading
Contract Name:
TOPNFT
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/** *Submitted for verification at BscScan.com on 2024-11-11 */ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @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 { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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); } } // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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); } // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; /** * @dev Required interface of an ERC-721 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 ERC-721 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 ERC-721 * 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 address zero. * * 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); } // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.20; /** * @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); } // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC-721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC-721 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); } // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/utils/ERC721Utils.sol) pragma solidity ^0.8.20; /** * @dev Library that provide common ERC-721 utility functions. * * See https://eips.ethereum.org/EIPS/eip-721[ERC-721]. * * _Available since v5.1._ */ library ERC721Utils { /** * @dev Performs an acceptance check for the provided `operator` by calling {IERC721-onERC721Received} * on the `to` address. The `operator` is generally the address that initiated the token transfer (i.e. `msg.sender`). * * The acceptance call is not executed and treated as a no-op if the target address doesn't contain code (i.e. an EOA). * Otherwise, the recipient must implement {IERC721Receiver-onERC721Received} and return the acceptance magic value to accept * the transfer. */ function checkOnERC721Received( address operator, address from, address to, uint256 tokenId, bytes memory data ) internal { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { // Token rejected revert IERC721Errors.ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { // non-IERC721Receiver implementer revert IERC721Errors.ERC721InvalidReceiver(to); } else { assembly ("memory-safe") { revert(add(32, reason), mload(reason)) } } } } } } // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } } // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } } // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * 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²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) 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²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_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. uint256 twos = denominator & (0 - denominator); 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²⁵⁶ / 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²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. 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⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // 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²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, 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; } } /** * @dev 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) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * 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; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(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 { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } } // OpenZeppelin Contracts (last updated v5.1.0) (utils/Strings.sol) pragma solidity ^0.8.20; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(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) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } 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 Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } } // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 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); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.20; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC-721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors { using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; mapping(uint256 tokenId => address) private _owners; mapping(address owner => uint256) private _balances; mapping(uint256 tokenId => address) private _tokenApprovals; mapping(address owner => mapping(address operator => 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 returns (uint256) { if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual returns (string memory) { _requireOwned(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string.concat(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 { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC-721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is 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`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { return _tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if: * - `spender` does not have approval from `owner` for `tokenId`. * - `spender` does not have approval to manage all of `owner`'s assets. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { unchecked { _balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { _balances[from] -= 1; } } if (to != address(0)) { unchecked { _balances[to] += 1; } } _owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @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 { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * 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 { _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); ERC721Utils.checkOnERC721Received(_msgSender(), address(0), to, tokenId, data); } /** * @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 { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @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 { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC-721 standard 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 like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` cannot be the zero address. * - 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) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); ERC721Utils.checkOnERC721Received(_msgSender(), from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } _tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { if (operator == address(0)) { revert ERC721InvalidOperator(operator); } _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } } // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.20; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.20; /** * @dev This implements an optional extension of {ERC721} defined in the ERC that adds enumerability * of all the token ids in the contract as well as all token ids owned by each account. * * CAUTION: {ERC721} extensions that implement custom `balanceOf` logic, such as {ERC721Consecutive}, * interfere with enumerability and should not be used together with {ERC721Enumerable}. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { mapping(address owner => mapping(uint256 index => uint256)) private _ownedTokens; mapping(uint256 tokenId => uint256) private _ownedTokensIndex; uint256[] private _allTokens; mapping(uint256 tokenId => uint256) private _allTokensIndex; /** * @dev An `owner`'s token query was out of bounds for `index`. * * NOTE: The owner being `address(0)` indicates a global out of bounds index. */ error ERC721OutOfBoundsIndex(address owner, uint256 index); /** * @dev Batch mint is not allowed. */ error ERC721EnumerableForbiddenBatchMint(); /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) { if (index >= balanceOf(owner)) { revert ERC721OutOfBoundsIndex(owner, index); } return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual returns (uint256) { if (index >= totalSupply()) { revert ERC721OutOfBoundsIndex(address(0), index); } return _allTokens[index]; } /** * @dev See {ERC721-_update}. */ function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) { address previousOwner = super._update(to, tokenId, auth); if (previousOwner == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (previousOwner != to) { _removeTokenFromOwnerEnumeration(previousOwner, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (previousOwner != to) { _addTokenToOwnerEnumeration(to, tokenId); } return previousOwner; } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = balanceOf(to) - 1; _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = balanceOf(from); uint256 tokenIndex = _ownedTokensIndex[tokenId]; mapping(uint256 index => uint256) storage _ownedTokensByOwner = _ownedTokens[from]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokensByOwner[lastTokenIndex]; _ownedTokensByOwner[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokensByOwner[lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } /** * See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch */ function _increaseBalance(address account, uint128 amount) internal virtual override { if (amount > 0) { revert ERC721EnumerableForbiddenBatchMint(); } super._increaseBalance(account, amount); } } // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.20; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or * {IERC721-setApprovalForAll}. */ abstract contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) { return this.onERC721Received.selector; } } // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { bool private _paused; /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (paused()) { revert EnforcedPause(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert ExpectedPause(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } pragma solidity ^0.8.20; contract TOPNFT is Ownable, ERC721Enumerable ,ERC721Holder, Pausable { using Strings for uint256; string private _customBaseURI; uint256 private totalMinted; uint256 public TOTAL_COUNT = 500; address public initialOwnerAddress = address(0x9Df5dAfd0AC54b2A75Cce36F9CDbC7da5Ba9eBb0); event PreMint(address indexed minter, uint256 count); constructor() ERC721("TOP MINER", "TOP MINER") Ownable(initialOwnerAddress) { _customBaseURI = "https://www.topminer.info/nft/metadata/"; totalMinted = 0; } function totalSupply() public view override returns (uint256) { return totalMinted; } function _baseURI() internal view virtual override returns (string memory) { return _customBaseURI; } function setBaseURI(string memory newBaseURI) external onlyOwner { _customBaseURI = newBaseURI; } function setTotalCount(uint256 count) external onlyOwner { TOTAL_COUNT = TOTAL_COUNT + count; } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _ownerOf(tokenId) != address(0) , "ATPNFT: URI query for nonexistent token"); return string(abi.encodePacked(_baseURI(), tokenId.toString())); } function burn(uint256 tokenId) external onlyOwner { _burn(tokenId); totalMinted--; } function mint(address to, uint256 tokenId) external onlyOwner whenNotPaused{ _safeMint(to, tokenId); } function preMint(address to,uint256 _count) external onlyOwner whenNotPaused{ require(_count > 0, "NFT: zero count"); require(totalMinted + _count <= TOTAL_COUNT, "NFT: not enough NFT"); for (uint256 i = 0; i < _count; i++) { uint256 tokenId = totalMinted + 1; _safeMint(to, tokenId); totalMinted++; } emit PreMint( to , _count); } function depositNFT(address nftContract, uint256 tokenId) public { IERC721(nftContract).safeTransferFrom(msg.sender, address(this), tokenId); } function withdrawNFT(address nftContract, uint256 tokenId, address to) public onlyOwner { IERC721(nftContract).safeTransferFrom(address(this), to, tokenId); } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC721EnumerableForbiddenBatchMint","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ERC721OutOfBoundsIndex","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"PreMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"TOTAL_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"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":[{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"depositNFT","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":[],"name":"initialOwnerAddress","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":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"preMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"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":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"setTotalCount","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftContract","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawNFT","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526101f4600e55739df5dafd0ac54b2a75cce36f9cdbc7da5ba9ebb0600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200006a575f80fd5b506040518060400160405280600981526020017f544f50204d494e455200000000000000000000000000000000000000000000008152506040518060400160405280600981526020017f544f50204d494e45520000000000000000000000000000000000000000000000815250600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200016c575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620001639190620002f9565b60405180910390fd5b6200017d81620001f560201b60201c565b5081600190816200018f919062000578565b508060029081620001a1919062000578565b5050505f600b5f6101000a81548160ff02191690831515021790555060405180606001604052806027815260200162003a4160279139600c9081620001e7919062000578565b505f600d819055506200065c565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620002e182620002b6565b9050919050565b620002f381620002d5565b82525050565b5f6020820190506200030e5f830184620002e8565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200039057607f821691505b602082108103620003a657620003a56200034b565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200040a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003cd565b620004168683620003cd565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620004606200045a62000454846200042e565b62000437565b6200042e565b9050919050565b5f819050919050565b6200047b8362000440565b620004936200048a8262000467565b848454620003d9565b825550505050565b5f90565b620004a96200049b565b620004b681848462000470565b505050565b5b81811015620004dd57620004d15f826200049f565b600181019050620004bc565b5050565b601f8211156200052c57620004f681620003ac565b6200050184620003be565b8101602085101562000511578190505b620005296200052085620003be565b830182620004bb565b50505b505050565b5f82821c905092915050565b5f6200054e5f198460080262000531565b1980831691505092915050565b5f6200056883836200053d565b9150826002028217905092915050565b620005838262000314565b67ffffffffffffffff8111156200059f576200059e6200031e565b5b620005ab825462000378565b620005b8828285620004e1565b5f60209050601f831160018114620005ee575f8415620005d9578287015190505b620005e585826200055b565b86555062000654565b601f198416620005fe86620003ac565b5f5b82811015620006275784890151825560018201915060208501945060208101905062000600565b8683101562000647578489015162000643601f8916826200053d565b8355505b6001600288020188555050505b505050505050565b6133d7806200066a5f395ff3fe608060405234801561000f575f80fd5b50600436106101ed575f3560e01c806355f804b31161010d57806395d89b41116100a0578063c87b56dd1161006f578063c87b56dd14610563578063d5a172f214610593578063e985e9c5146105b1578063f2fde38b146105e1576101ed565b806395d89b41146104f15780639b5b9b181461050f578063a22cb4651461052b578063b88d4fde14610547576101ed565b806370a08231116100dc57806370a082311461048f578063715018a6146104bf5780638456cb59146104c95780638da5cb5b146104d3576101ed565b806355f804b31461040957806357df110a146104255780635c975abb146104415780636352211e1461045f576101ed565b806323b872dd1161018557806340c10f191161015457806340c10f191461038557806342842e0e146103a157806342966c68146103bd5780634f6ccce7146103d9576101ed565b806323b872dd14610313578063290c292d1461032f5780632f745c591461034b5780633f4ba83a1461037b576101ed565b8063095ea7b3116101c1578063095ea7b31461028b5780630f0beece146102a7578063150b7a02146102c557806318160ddd146102f5576101ed565b8062f2a6ab146101f157806301ffc9a71461020d57806306fdde031461023d578063081812fc1461025b575b5f80fd5b61020b600480360381019061020691906125e9565b6105fd565b005b6102276004803603810190610222919061268e565b610674565b60405161023491906126d3565b60405180910390f35b6102456106ed565b6040516102529190612776565b60405180910390f35b61027560048036038101906102709190612796565b61077d565b60405161028291906127d0565b60405180910390f35b6102a560048036038101906102a091906127e9565b610798565b005b6102af6107ae565b6040516102bc9190612836565b60405180910390f35b6102df60048036038101906102da919061297b565b6107b4565b6040516102ec9190612a0a565b60405180910390f35b6102fd6107c7565b60405161030a9190612836565b60405180910390f35b61032d60048036038101906103289190612a23565b6107d0565b005b610349600480360381019061034491906127e9565b6108cf565b005b610365600480360381019061036091906127e9565b610a17565b6040516103729190612836565b60405180910390f35b610383610abb565b005b61039f600480360381019061039a91906127e9565b610acd565b005b6103bb60048036038101906103b69190612a23565b610aeb565b005b6103d760048036038101906103d29190612796565b610b0a565b005b6103f360048036038101906103ee9190612796565b610b35565b6040516104009190612836565b60405180910390f35b610423600480360381019061041e9190612b11565b610ba7565b005b61043f600480360381019061043a9190612796565b610bc2565b005b610449610be1565b60405161045691906126d3565b60405180910390f35b61047960048036038101906104749190612796565b610bf6565b60405161048691906127d0565b60405180910390f35b6104a960048036038101906104a49190612b58565b610c07565b6040516104b69190612836565b60405180910390f35b6104c7610cbd565b005b6104d1610cd0565b005b6104db610ce2565b6040516104e891906127d0565b60405180910390f35b6104f9610d09565b6040516105069190612776565b60405180910390f35b610529600480360381019061052491906127e9565b610d99565b005b61054560048036038101906105409190612bad565b610e07565b005b610561600480360381019061055c919061297b565b610e1d565b005b61057d60048036038101906105789190612796565b610e42565b60405161058a9190612776565b60405180910390f35b61059b610ef2565b6040516105a891906127d0565b60405180910390f35b6105cb60048036038101906105c69190612beb565b610f17565b6040516105d891906126d3565b60405180910390f35b6105fb60048036038101906105f69190612b58565b610fa5565b005b610605611029565b8273ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b815260040161064293929190612c29565b5f604051808303815f87803b158015610659575f80fd5b505af115801561066b573d5f803e3d5ffd5b50505050505050565b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106e657506106e5826110b0565b5b9050919050565b6060600180546106fc90612c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461072890612c8b565b80156107735780601f1061074a57610100808354040283529160200191610773565b820191905f5260205f20905b81548152906001019060200180831161075657829003601f168201915b5050505050905090565b5f61078782611191565b5061079182611217565b9050919050565b6107aa82826107a5611250565b611257565b5050565b600e5481565b5f63150b7a0260e01b9050949350505050565b5f600d54905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610840575f6040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161083791906127d0565b60405180910390fd5b5f610853838361084e611250565b611269565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108c9578382826040517f64283d7b0000000000000000000000000000000000000000000000000000000081526004016108c093929190612cbb565b60405180910390fd5b50505050565b6108d7611029565b6108df611383565b5f8111610921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091890612d3a565b60405180910390fd5b600e5481600d546109329190612d85565b1115610973576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096a90612e02565b60405180910390fd5b5f5b818110156109c4575f6001600d5461098d9190612d85565b905061099984826113c4565b600d5f8154809291906109ab90612e20565b91905055505080806109bc90612e20565b915050610975565b508173ffffffffffffffffffffffffffffffffffffffff167faa8cea5b9b55c0967a846322a639d3bc70b13695058b5c9cb34928b75b0d20fe82604051610a0b9190612836565b60405180910390a25050565b5f610a2183610c07565b8210610a665782826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610a5d929190612e67565b60405180910390fd5b60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b610ac3611029565b610acb6113e1565b565b610ad5611029565b610add611383565b610ae782826113c4565b5050565b610b0583838360405180602001604052805f815250610e1d565b505050565b610b12611029565b610b1b81611442565b600d5f815480929190610b2d90612e8e565b919050555050565b5f610b3e6107c7565b8210610b83575f826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610b7a929190612e67565b60405180910390fd5b60098281548110610b9757610b96612eb5565b5b905f5260205f2001549050919050565b610baf611029565b80600c9081610bbe919061307f565b5050565b610bca611029565b80600e54610bd89190612d85565b600e8190555050565b5f600b5f9054906101000a900460ff16905090565b5f610c0082611191565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610c78575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610c6f91906127d0565b60405180910390fd5b60045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610cc5611029565b610cce5f6114c4565b565b610cd8611029565b610ce0611585565b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060028054610d1890612c8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4490612c8b565b8015610d8f5780601f10610d6657610100808354040283529160200191610d8f565b820191905f5260205f20905b815481529060010190602001808311610d7257829003601f168201915b5050505050905090565b8173ffffffffffffffffffffffffffffffffffffffff166342842e0e3330846040518463ffffffff1660e01b8152600401610dd693929190612c29565b5f604051808303815f87803b158015610ded575f80fd5b505af1158015610dff573d5f803e3d5ffd5b505050505050565b610e19610e12611250565b83836115e7565b5050565b610e288484846107d0565b610e3c610e33611250565b85858585611750565b50505050565b60605f73ffffffffffffffffffffffffffffffffffffffff16610e64836118fc565b73ffffffffffffffffffffffffffffffffffffffff1603610eba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb1906131be565b60405180910390fd5b610ec2611935565b610ecb836119c5565b604051602001610edc929190613216565b6040516020818303038152906040529050919050565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b610fad611029565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361101d575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161101491906127d0565b60405180910390fd5b611026816114c4565b50565b611031611250565b73ffffffffffffffffffffffffffffffffffffffff1661104f610ce2565b73ffffffffffffffffffffffffffffffffffffffff16146110ae57611072611250565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016110a591906127d0565b60405180910390fd5b565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061117a57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061118a575061118982611a8f565b5b9050919050565b5f8061119c836118fc565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361120e57826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112059190612836565b60405180910390fd5b80915050919050565b5f60055f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b6112648383836001611af8565b505050565b5f80611276858585611cb7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112b9576112b484611ec2565b6112f8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146112f7576112f68185611f06565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113395761133484611fdd565b611378565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461137757611376858561209d565b5b5b809150509392505050565b61138b610be1565b156113c2576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6113dd828260405180602001604052805f815250612121565b5050565b6113e9612144565b5f600b5f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61142b611250565b60405161143891906127d0565b60405180910390a1565b5f61144e5f835f611269565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114c057816040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016114b79190612836565b60405180910390fd5b5050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61158d611383565b6001600b5f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115d0611250565b6040516115dd91906127d0565b60405180910390a1565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361165757816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161164e91906127d0565b60405180910390fd5b8060065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161174391906126d3565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156118f5578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02868685856040518563ffffffff1660e01b81526004016117ae949392919061328b565b6020604051808303815f875af19250505080156117e957506040513d601f19601f820116820180604052508101906117e691906132e9565b60015b61186a573d805f8114611817576040519150601f19603f3d011682016040523d82523d5f602084013e61181c565b606091505b505f81510361186257836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161185991906127d0565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146118f357836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016118ea91906127d0565b60405180910390fd5b505b5050505050565b5f60035f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6060600c805461194490612c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461197090612c8b565b80156119bb5780601f10611992576101008083540402835291602001916119bb565b820191905f5260205f20905b81548152906001019060200180831161199e57829003601f168201915b5050505050905090565b60605f60016119d384612184565b0190505f8167ffffffffffffffff8111156119f1576119f0612857565b5b6040519080825280601f01601f191660200182016040528015611a235781602001600182028036833780820191505090505b5090505f82602001820190505b600115611a84578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611a7957611a78613314565b5b0494505f8503611a30575b819350505050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8080611b3057505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611c62575f611b3f84611191565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611ba957508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611bbc5750611bba8184610f17565b155b15611bfe57826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401611bf591906127d0565b60405180910390fd5b8115611c6057838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360055f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f80611cc2846118fc565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611d0357611d028184866122d5565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d8e57611d425f855f80611af8565b600160045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611e0d57600160045f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460035f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b600980549050600a5f8381526020019081526020015f2081905550600981908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f611f1083610c07565b90505f60085f8481526020019081526020015f205490505f60075f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050828214611faf575f815f8581526020019081526020015f2054905080825f8581526020019081526020015f20819055508260085f8381526020019081526020015f2081905550505b60085f8581526020019081526020015f205f9055805f8481526020019081526020015f205f90555050505050565b5f6001600980549050611ff09190613341565b90505f600a5f8481526020019081526020015f205490505f6009838154811061201c5761201b612eb5565b5b905f5260205f2001549050806009838154811061203c5761203b612eb5565b5b905f5260205f20018190555081600a5f8381526020019081526020015f2081905550600a5f8581526020019081526020015f205f9055600980548061208457612083613374565b5b600190038181905f5260205f20015f9055905550505050565b5f60016120a984610c07565b6120b39190613341565b90508160075f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060085f8481526020019081526020015f2081905550505050565b61212b8383612398565b61213f612136611250565b5f858585611750565b505050565b61214c610be1565b612182576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106121e0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816121d6576121d5613314565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061221d576d04ee2d6d415b85acef8100000000838161221357612212613314565b5b0492506020810190505b662386f26fc10000831061224c57662386f26fc10000838161224257612241613314565b5b0492506010810190505b6305f5e1008310612275576305f5e100838161226b5761226a613314565b5b0492506008810190505b612710831061229a5761271083816122905761228f613314565b5b0492506004810190505b606483106122bd57606483816122b3576122b2613314565b5b0492506002810190505b600a83106122cc576001810190505b80915050919050565b6122e083838361248b565b612393575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361235457806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040161234b9190612836565b60405180910390fd5b81816040517f177e802f00000000000000000000000000000000000000000000000000000000815260040161238a929190612e67565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612408575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016123ff91906127d0565b60405180910390fd5b5f61241483835f611269565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612486575f6040517f73c6ac6e00000000000000000000000000000000000000000000000000000000815260040161247d91906127d0565b60405180910390fd5b505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561254257508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061250357506125028484610f17565b5b8061254157508273ffffffffffffffffffffffffffffffffffffffff1661252983611217565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125858261255c565b9050919050565b6125958161257b565b811461259f575f80fd5b50565b5f813590506125b08161258c565b92915050565b5f819050919050565b6125c8816125b6565b81146125d2575f80fd5b50565b5f813590506125e3816125bf565b92915050565b5f805f60608486031215612600576125ff612554565b5b5f61260d868287016125a2565b935050602061261e868287016125d5565b925050604061262f868287016125a2565b9150509250925092565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61266d81612639565b8114612677575f80fd5b50565b5f8135905061268881612664565b92915050565b5f602082840312156126a3576126a2612554565b5b5f6126b08482850161267a565b91505092915050565b5f8115159050919050565b6126cd816126b9565b82525050565b5f6020820190506126e65f8301846126c4565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612723578082015181840152602081019050612708565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612748826126ec565b61275281856126f6565b9350612762818560208601612706565b61276b8161272e565b840191505092915050565b5f6020820190508181035f83015261278e818461273e565b905092915050565b5f602082840312156127ab576127aa612554565b5b5f6127b8848285016125d5565b91505092915050565b6127ca8161257b565b82525050565b5f6020820190506127e35f8301846127c1565b92915050565b5f80604083850312156127ff576127fe612554565b5b5f61280c858286016125a2565b925050602061281d858286016125d5565b9150509250929050565b612830816125b6565b82525050565b5f6020820190506128495f830184612827565b92915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61288d8261272e565b810181811067ffffffffffffffff821117156128ac576128ab612857565b5b80604052505050565b5f6128be61254b565b90506128ca8282612884565b919050565b5f67ffffffffffffffff8211156128e9576128e8612857565b5b6128f28261272e565b9050602081019050919050565b828183375f83830152505050565b5f61291f61291a846128cf565b6128b5565b90508281526020810184848401111561293b5761293a612853565b5b6129468482856128ff565b509392505050565b5f82601f8301126129625761296161284f565b5b813561297284826020860161290d565b91505092915050565b5f805f806080858703121561299357612992612554565b5b5f6129a0878288016125a2565b94505060206129b1878288016125a2565b93505060406129c2878288016125d5565b925050606085013567ffffffffffffffff8111156129e3576129e2612558565b5b6129ef8782880161294e565b91505092959194509250565b612a0481612639565b82525050565b5f602082019050612a1d5f8301846129fb565b92915050565b5f805f60608486031215612a3a57612a39612554565b5b5f612a47868287016125a2565b9350506020612a58868287016125a2565b9250506040612a69868287016125d5565b9150509250925092565b5f67ffffffffffffffff821115612a8d57612a8c612857565b5b612a968261272e565b9050602081019050919050565b5f612ab5612ab084612a73565b6128b5565b905082815260208101848484011115612ad157612ad0612853565b5b612adc8482856128ff565b509392505050565b5f82601f830112612af857612af761284f565b5b8135612b08848260208601612aa3565b91505092915050565b5f60208284031215612b2657612b25612554565b5b5f82013567ffffffffffffffff811115612b4357612b42612558565b5b612b4f84828501612ae4565b91505092915050565b5f60208284031215612b6d57612b6c612554565b5b5f612b7a848285016125a2565b91505092915050565b612b8c816126b9565b8114612b96575f80fd5b50565b5f81359050612ba781612b83565b92915050565b5f8060408385031215612bc357612bc2612554565b5b5f612bd0858286016125a2565b9250506020612be185828601612b99565b9150509250929050565b5f8060408385031215612c0157612c00612554565b5b5f612c0e858286016125a2565b9250506020612c1f858286016125a2565b9150509250929050565b5f606082019050612c3c5f8301866127c1565b612c4960208301856127c1565b612c566040830184612827565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612ca257607f821691505b602082108103612cb557612cb4612c5e565b5b50919050565b5f606082019050612cce5f8301866127c1565b612cdb6020830185612827565b612ce860408301846127c1565b949350505050565b7f4e46543a207a65726f20636f756e7400000000000000000000000000000000005f82015250565b5f612d24600f836126f6565b9150612d2f82612cf0565b602082019050919050565b5f6020820190508181035f830152612d5181612d18565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612d8f826125b6565b9150612d9a836125b6565b9250828201905080821115612db257612db1612d58565b5b92915050565b7f4e46543a206e6f7420656e6f756768204e4654000000000000000000000000005f82015250565b5f612dec6013836126f6565b9150612df782612db8565b602082019050919050565b5f6020820190508181035f830152612e1981612de0565b9050919050565b5f612e2a826125b6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e5c57612e5b612d58565b5b600182019050919050565b5f604082019050612e7a5f8301856127c1565b612e876020830184612827565b9392505050565b5f612e98826125b6565b91505f8203612eaa57612ea9612d58565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612f3e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612f03565b612f488683612f03565b95508019841693508086168417925050509392505050565b5f819050919050565b5f612f83612f7e612f79846125b6565b612f60565b6125b6565b9050919050565b5f819050919050565b612f9c83612f69565b612fb0612fa882612f8a565b848454612f0f565b825550505050565b5f90565b612fc4612fb8565b612fcf818484612f93565b505050565b5b81811015612ff257612fe75f82612fbc565b600181019050612fd5565b5050565b601f8211156130375761300881612ee2565b61301184612ef4565b81016020851015613020578190505b61303461302c85612ef4565b830182612fd4565b50505b505050565b5f82821c905092915050565b5f6130575f198460080261303c565b1980831691505092915050565b5f61306f8383613048565b9150826002028217905092915050565b613088826126ec565b67ffffffffffffffff8111156130a1576130a0612857565b5b6130ab8254612c8b565b6130b6828285612ff6565b5f60209050601f8311600181146130e7575f84156130d5578287015190505b6130df8582613064565b865550613146565b601f1984166130f586612ee2565b5f5b8281101561311c578489015182556001820191506020850194506020810190506130f7565b868310156131395784890151613135601f891682613048565b8355505b6001600288020188555050505b505050505050565b7f4154504e46543a2055524920717565727920666f72206e6f6e6578697374656e5f8201527f7420746f6b656e00000000000000000000000000000000000000000000000000602082015250565b5f6131a86027836126f6565b91506131b38261314e565b604082019050919050565b5f6020820190508181035f8301526131d58161319c565b9050919050565b5f81905092915050565b5f6131f0826126ec565b6131fa81856131dc565b935061320a818560208601612706565b80840191505092915050565b5f61322182856131e6565b915061322d82846131e6565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f61325d82613239565b6132678185613243565b9350613277818560208601612706565b6132808161272e565b840191505092915050565b5f60808201905061329e5f8301876127c1565b6132ab60208301866127c1565b6132b86040830185612827565b81810360608301526132ca8184613253565b905095945050505050565b5f815190506132e381612664565b92915050565b5f602082840312156132fe576132fd612554565b5b5f61330b848285016132d5565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61334b826125b6565b9150613356836125b6565b925082820390508181111561336e5761336d612d58565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea26469706673582212208bda047cb690fac5297566fd6b14f63bc272b557796d62850f263509bf1445c264736f6c6343000814003368747470733a2f2f7777772e746f706d696e65722e696e666f2f6e66742f6d657461646174612f
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106101ed575f3560e01c806355f804b31161010d57806395d89b41116100a0578063c87b56dd1161006f578063c87b56dd14610563578063d5a172f214610593578063e985e9c5146105b1578063f2fde38b146105e1576101ed565b806395d89b41146104f15780639b5b9b181461050f578063a22cb4651461052b578063b88d4fde14610547576101ed565b806370a08231116100dc57806370a082311461048f578063715018a6146104bf5780638456cb59146104c95780638da5cb5b146104d3576101ed565b806355f804b31461040957806357df110a146104255780635c975abb146104415780636352211e1461045f576101ed565b806323b872dd1161018557806340c10f191161015457806340c10f191461038557806342842e0e146103a157806342966c68146103bd5780634f6ccce7146103d9576101ed565b806323b872dd14610313578063290c292d1461032f5780632f745c591461034b5780633f4ba83a1461037b576101ed565b8063095ea7b3116101c1578063095ea7b31461028b5780630f0beece146102a7578063150b7a02146102c557806318160ddd146102f5576101ed565b8062f2a6ab146101f157806301ffc9a71461020d57806306fdde031461023d578063081812fc1461025b575b5f80fd5b61020b600480360381019061020691906125e9565b6105fd565b005b6102276004803603810190610222919061268e565b610674565b60405161023491906126d3565b60405180910390f35b6102456106ed565b6040516102529190612776565b60405180910390f35b61027560048036038101906102709190612796565b61077d565b60405161028291906127d0565b60405180910390f35b6102a560048036038101906102a091906127e9565b610798565b005b6102af6107ae565b6040516102bc9190612836565b60405180910390f35b6102df60048036038101906102da919061297b565b6107b4565b6040516102ec9190612a0a565b60405180910390f35b6102fd6107c7565b60405161030a9190612836565b60405180910390f35b61032d60048036038101906103289190612a23565b6107d0565b005b610349600480360381019061034491906127e9565b6108cf565b005b610365600480360381019061036091906127e9565b610a17565b6040516103729190612836565b60405180910390f35b610383610abb565b005b61039f600480360381019061039a91906127e9565b610acd565b005b6103bb60048036038101906103b69190612a23565b610aeb565b005b6103d760048036038101906103d29190612796565b610b0a565b005b6103f360048036038101906103ee9190612796565b610b35565b6040516104009190612836565b60405180910390f35b610423600480360381019061041e9190612b11565b610ba7565b005b61043f600480360381019061043a9190612796565b610bc2565b005b610449610be1565b60405161045691906126d3565b60405180910390f35b61047960048036038101906104749190612796565b610bf6565b60405161048691906127d0565b60405180910390f35b6104a960048036038101906104a49190612b58565b610c07565b6040516104b69190612836565b60405180910390f35b6104c7610cbd565b005b6104d1610cd0565b005b6104db610ce2565b6040516104e891906127d0565b60405180910390f35b6104f9610d09565b6040516105069190612776565b60405180910390f35b610529600480360381019061052491906127e9565b610d99565b005b61054560048036038101906105409190612bad565b610e07565b005b610561600480360381019061055c919061297b565b610e1d565b005b61057d60048036038101906105789190612796565b610e42565b60405161058a9190612776565b60405180910390f35b61059b610ef2565b6040516105a891906127d0565b60405180910390f35b6105cb60048036038101906105c69190612beb565b610f17565b6040516105d891906126d3565b60405180910390f35b6105fb60048036038101906105f69190612b58565b610fa5565b005b610605611029565b8273ffffffffffffffffffffffffffffffffffffffff166342842e0e3083856040518463ffffffff1660e01b815260040161064293929190612c29565b5f604051808303815f87803b158015610659575f80fd5b505af115801561066b573d5f803e3d5ffd5b50505050505050565b5f7f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806106e657506106e5826110b0565b5b9050919050565b6060600180546106fc90612c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461072890612c8b565b80156107735780601f1061074a57610100808354040283529160200191610773565b820191905f5260205f20905b81548152906001019060200180831161075657829003601f168201915b5050505050905090565b5f61078782611191565b5061079182611217565b9050919050565b6107aa82826107a5611250565b611257565b5050565b600e5481565b5f63150b7a0260e01b9050949350505050565b5f600d54905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610840575f6040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161083791906127d0565b60405180910390fd5b5f610853838361084e611250565b611269565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108c9578382826040517f64283d7b0000000000000000000000000000000000000000000000000000000081526004016108c093929190612cbb565b60405180910390fd5b50505050565b6108d7611029565b6108df611383565b5f8111610921576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091890612d3a565b60405180910390fd5b600e5481600d546109329190612d85565b1115610973576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096a90612e02565b60405180910390fd5b5f5b818110156109c4575f6001600d5461098d9190612d85565b905061099984826113c4565b600d5f8154809291906109ab90612e20565b91905055505080806109bc90612e20565b915050610975565b508173ffffffffffffffffffffffffffffffffffffffff167faa8cea5b9b55c0967a846322a639d3bc70b13695058b5c9cb34928b75b0d20fe82604051610a0b9190612836565b60405180910390a25050565b5f610a2183610c07565b8210610a665782826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610a5d929190612e67565b60405180910390fd5b60075f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f2054905092915050565b610ac3611029565b610acb6113e1565b565b610ad5611029565b610add611383565b610ae782826113c4565b5050565b610b0583838360405180602001604052805f815250610e1d565b505050565b610b12611029565b610b1b81611442565b600d5f815480929190610b2d90612e8e565b919050555050565b5f610b3e6107c7565b8210610b83575f826040517fa57d13dc000000000000000000000000000000000000000000000000000000008152600401610b7a929190612e67565b60405180910390fd5b60098281548110610b9757610b96612eb5565b5b905f5260205f2001549050919050565b610baf611029565b80600c9081610bbe919061307f565b5050565b610bca611029565b80600e54610bd89190612d85565b600e8190555050565b5f600b5f9054906101000a900460ff16905090565b5f610c0082611191565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610c78575f6040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610c6f91906127d0565b60405180910390fd5b60045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610cc5611029565b610cce5f6114c4565b565b610cd8611029565b610ce0611585565b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060028054610d1890612c8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4490612c8b565b8015610d8f5780601f10610d6657610100808354040283529160200191610d8f565b820191905f5260205f20905b815481529060010190602001808311610d7257829003601f168201915b5050505050905090565b8173ffffffffffffffffffffffffffffffffffffffff166342842e0e3330846040518463ffffffff1660e01b8152600401610dd693929190612c29565b5f604051808303815f87803b158015610ded575f80fd5b505af1158015610dff573d5f803e3d5ffd5b505050505050565b610e19610e12611250565b83836115e7565b5050565b610e288484846107d0565b610e3c610e33611250565b85858585611750565b50505050565b60605f73ffffffffffffffffffffffffffffffffffffffff16610e64836118fc565b73ffffffffffffffffffffffffffffffffffffffff1603610eba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb1906131be565b60405180910390fd5b610ec2611935565b610ecb836119c5565b604051602001610edc929190613216565b6040516020818303038152906040529050919050565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60065f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b610fad611029565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361101d575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161101491906127d0565b60405180910390fd5b611026816114c4565b50565b611031611250565b73ffffffffffffffffffffffffffffffffffffffff1661104f610ce2565b73ffffffffffffffffffffffffffffffffffffffff16146110ae57611072611250565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016110a591906127d0565b60405180910390fd5b565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061117a57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061118a575061118982611a8f565b5b9050919050565b5f8061119c836118fc565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361120e57826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016112059190612836565b60405180910390fd5b80915050919050565b5f60055f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b6112648383836001611af8565b505050565b5f80611276858585611cb7565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112b9576112b484611ec2565b6112f8565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146112f7576112f68185611f06565b5b5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113395761133484611fdd565b611378565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461137757611376858561209d565b5b5b809150509392505050565b61138b610be1565b156113c2576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6113dd828260405180602001604052805f815250612121565b5050565b6113e9612144565b5f600b5f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61142b611250565b60405161143891906127d0565b60405180910390a1565b5f61144e5f835f611269565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114c057816040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016114b79190612836565b60405180910390fd5b5050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61158d611383565b6001600b5f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115d0611250565b6040516115dd91906127d0565b60405180910390a1565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361165757816040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161164e91906127d0565b60405180910390fd5b8060065f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161174391906126d3565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156118f5578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02868685856040518563ffffffff1660e01b81526004016117ae949392919061328b565b6020604051808303815f875af19250505080156117e957506040513d601f19601f820116820180604052508101906117e691906132e9565b60015b61186a573d805f8114611817576040519150601f19603f3d011682016040523d82523d5f602084013e61181c565b606091505b505f81510361186257836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161185991906127d0565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146118f357836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016118ea91906127d0565b60405180910390fd5b505b5050505050565b5f60035f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6060600c805461194490612c8b565b80601f016020809104026020016040519081016040528092919081815260200182805461197090612c8b565b80156119bb5780601f10611992576101008083540402835291602001916119bb565b820191905f5260205f20905b81548152906001019060200180831161199e57829003601f168201915b5050505050905090565b60605f60016119d384612184565b0190505f8167ffffffffffffffff8111156119f1576119f0612857565b5b6040519080825280601f01601f191660200182016040528015611a235781602001600182028036833780820191505090505b5090505f82602001820190505b600115611a84578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611a7957611a78613314565b5b0494505f8503611a30575b819350505050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b8080611b3057505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15611c62575f611b3f84611191565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015611ba957508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611bbc5750611bba8184610f17565b155b15611bfe57826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401611bf591906127d0565b60405180910390fd5b8115611c6057838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360055f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b5f80611cc2846118fc565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611d0357611d028184866122d5565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d8e57611d425f855f80611af8565b600160045f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611e0d57600160045f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460035f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b600980549050600a5f8381526020019081526020015f2081905550600981908060018154018082558091505060019003905f5260205f20015f909190919091505550565b5f611f1083610c07565b90505f60085f8481526020019081526020015f205490505f60075f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050828214611faf575f815f8581526020019081526020015f2054905080825f8581526020019081526020015f20819055508260085f8381526020019081526020015f2081905550505b60085f8581526020019081526020015f205f9055805f8481526020019081526020015f205f90555050505050565b5f6001600980549050611ff09190613341565b90505f600a5f8481526020019081526020015f205490505f6009838154811061201c5761201b612eb5565b5b905f5260205f2001549050806009838154811061203c5761203b612eb5565b5b905f5260205f20018190555081600a5f8381526020019081526020015f2081905550600a5f8581526020019081526020015f205f9055600980548061208457612083613374565b5b600190038181905f5260205f20015f9055905550505050565b5f60016120a984610c07565b6120b39190613341565b90508160075f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f20819055508060085f8481526020019081526020015f2081905550505050565b61212b8383612398565b61213f612136611250565b5f858585611750565b505050565b61214c610be1565b612182576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106121e0577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816121d6576121d5613314565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061221d576d04ee2d6d415b85acef8100000000838161221357612212613314565b5b0492506020810190505b662386f26fc10000831061224c57662386f26fc10000838161224257612241613314565b5b0492506010810190505b6305f5e1008310612275576305f5e100838161226b5761226a613314565b5b0492506008810190505b612710831061229a5761271083816122905761228f613314565b5b0492506004810190505b606483106122bd57606483816122b3576122b2613314565b5b0492506002810190505b600a83106122cc576001810190505b80915050919050565b6122e083838361248b565b612393575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361235457806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040161234b9190612836565b60405180910390fd5b81816040517f177e802f00000000000000000000000000000000000000000000000000000000815260040161238a929190612e67565b60405180910390fd5b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612408575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016123ff91906127d0565b60405180910390fd5b5f61241483835f611269565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612486575f6040517f73c6ac6e00000000000000000000000000000000000000000000000000000000815260040161247d91906127d0565b60405180910390fd5b505050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561254257508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061250357506125028484610f17565b5b8061254157508273ffffffffffffffffffffffffffffffffffffffff1661252983611217565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6125858261255c565b9050919050565b6125958161257b565b811461259f575f80fd5b50565b5f813590506125b08161258c565b92915050565b5f819050919050565b6125c8816125b6565b81146125d2575f80fd5b50565b5f813590506125e3816125bf565b92915050565b5f805f60608486031215612600576125ff612554565b5b5f61260d868287016125a2565b935050602061261e868287016125d5565b925050604061262f868287016125a2565b9150509250925092565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61266d81612639565b8114612677575f80fd5b50565b5f8135905061268881612664565b92915050565b5f602082840312156126a3576126a2612554565b5b5f6126b08482850161267a565b91505092915050565b5f8115159050919050565b6126cd816126b9565b82525050565b5f6020820190506126e65f8301846126c4565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612723578082015181840152602081019050612708565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612748826126ec565b61275281856126f6565b9350612762818560208601612706565b61276b8161272e565b840191505092915050565b5f6020820190508181035f83015261278e818461273e565b905092915050565b5f602082840312156127ab576127aa612554565b5b5f6127b8848285016125d5565b91505092915050565b6127ca8161257b565b82525050565b5f6020820190506127e35f8301846127c1565b92915050565b5f80604083850312156127ff576127fe612554565b5b5f61280c858286016125a2565b925050602061281d858286016125d5565b9150509250929050565b612830816125b6565b82525050565b5f6020820190506128495f830184612827565b92915050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61288d8261272e565b810181811067ffffffffffffffff821117156128ac576128ab612857565b5b80604052505050565b5f6128be61254b565b90506128ca8282612884565b919050565b5f67ffffffffffffffff8211156128e9576128e8612857565b5b6128f28261272e565b9050602081019050919050565b828183375f83830152505050565b5f61291f61291a846128cf565b6128b5565b90508281526020810184848401111561293b5761293a612853565b5b6129468482856128ff565b509392505050565b5f82601f8301126129625761296161284f565b5b813561297284826020860161290d565b91505092915050565b5f805f806080858703121561299357612992612554565b5b5f6129a0878288016125a2565b94505060206129b1878288016125a2565b93505060406129c2878288016125d5565b925050606085013567ffffffffffffffff8111156129e3576129e2612558565b5b6129ef8782880161294e565b91505092959194509250565b612a0481612639565b82525050565b5f602082019050612a1d5f8301846129fb565b92915050565b5f805f60608486031215612a3a57612a39612554565b5b5f612a47868287016125a2565b9350506020612a58868287016125a2565b9250506040612a69868287016125d5565b9150509250925092565b5f67ffffffffffffffff821115612a8d57612a8c612857565b5b612a968261272e565b9050602081019050919050565b5f612ab5612ab084612a73565b6128b5565b905082815260208101848484011115612ad157612ad0612853565b5b612adc8482856128ff565b509392505050565b5f82601f830112612af857612af761284f565b5b8135612b08848260208601612aa3565b91505092915050565b5f60208284031215612b2657612b25612554565b5b5f82013567ffffffffffffffff811115612b4357612b42612558565b5b612b4f84828501612ae4565b91505092915050565b5f60208284031215612b6d57612b6c612554565b5b5f612b7a848285016125a2565b91505092915050565b612b8c816126b9565b8114612b96575f80fd5b50565b5f81359050612ba781612b83565b92915050565b5f8060408385031215612bc357612bc2612554565b5b5f612bd0858286016125a2565b9250506020612be185828601612b99565b9150509250929050565b5f8060408385031215612c0157612c00612554565b5b5f612c0e858286016125a2565b9250506020612c1f858286016125a2565b9150509250929050565b5f606082019050612c3c5f8301866127c1565b612c4960208301856127c1565b612c566040830184612827565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680612ca257607f821691505b602082108103612cb557612cb4612c5e565b5b50919050565b5f606082019050612cce5f8301866127c1565b612cdb6020830185612827565b612ce860408301846127c1565b949350505050565b7f4e46543a207a65726f20636f756e7400000000000000000000000000000000005f82015250565b5f612d24600f836126f6565b9150612d2f82612cf0565b602082019050919050565b5f6020820190508181035f830152612d5181612d18565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612d8f826125b6565b9150612d9a836125b6565b9250828201905080821115612db257612db1612d58565b5b92915050565b7f4e46543a206e6f7420656e6f756768204e4654000000000000000000000000005f82015250565b5f612dec6013836126f6565b9150612df782612db8565b602082019050919050565b5f6020820190508181035f830152612e1981612de0565b9050919050565b5f612e2a826125b6565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e5c57612e5b612d58565b5b600182019050919050565b5f604082019050612e7a5f8301856127c1565b612e876020830184612827565b9392505050565b5f612e98826125b6565b91505f8203612eaa57612ea9612d58565b5b600182039050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302612f3e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612f03565b612f488683612f03565b95508019841693508086168417925050509392505050565b5f819050919050565b5f612f83612f7e612f79846125b6565b612f60565b6125b6565b9050919050565b5f819050919050565b612f9c83612f69565b612fb0612fa882612f8a565b848454612f0f565b825550505050565b5f90565b612fc4612fb8565b612fcf818484612f93565b505050565b5b81811015612ff257612fe75f82612fbc565b600181019050612fd5565b5050565b601f8211156130375761300881612ee2565b61301184612ef4565b81016020851015613020578190505b61303461302c85612ef4565b830182612fd4565b50505b505050565b5f82821c905092915050565b5f6130575f198460080261303c565b1980831691505092915050565b5f61306f8383613048565b9150826002028217905092915050565b613088826126ec565b67ffffffffffffffff8111156130a1576130a0612857565b5b6130ab8254612c8b565b6130b6828285612ff6565b5f60209050601f8311600181146130e7575f84156130d5578287015190505b6130df8582613064565b865550613146565b601f1984166130f586612ee2565b5f5b8281101561311c578489015182556001820191506020850194506020810190506130f7565b868310156131395784890151613135601f891682613048565b8355505b6001600288020188555050505b505050505050565b7f4154504e46543a2055524920717565727920666f72206e6f6e6578697374656e5f8201527f7420746f6b656e00000000000000000000000000000000000000000000000000602082015250565b5f6131a86027836126f6565b91506131b38261314e565b604082019050919050565b5f6020820190508181035f8301526131d58161319c565b9050919050565b5f81905092915050565b5f6131f0826126ec565b6131fa81856131dc565b935061320a818560208601612706565b80840191505092915050565b5f61322182856131e6565b915061322d82846131e6565b91508190509392505050565b5f81519050919050565b5f82825260208201905092915050565b5f61325d82613239565b6132678185613243565b9350613277818560208601612706565b6132808161272e565b840191505092915050565b5f60808201905061329e5f8301876127c1565b6132ab60208301866127c1565b6132b86040830185612827565b81810360608301526132ca8184613253565b905095945050505050565b5f815190506132e381612664565b92915050565b5f602082840312156132fe576132fd612554565b5b5f61330b848285016132d5565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61334b826125b6565b9150613356836125b6565b925082820390508181111561336e5761336d612d58565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea26469706673582212208bda047cb690fac5297566fd6b14f63bc272b557796d62850f263509bf1445c264736f6c63430008140033
Deployed Bytecode Sourcemap
122596:2518:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124792:172;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;112857:224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96094:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97266:158;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97085:115;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;122782:33;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119519:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123178:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97935:588;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124184:431;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113165:260;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;125043:65;;;:::i;:::-;;124058:116;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98594:134;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123941:107;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;113682:231;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;123421:111;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123546:109;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;121532:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95907:120;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95632:213;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3289:103;;;:::i;:::-;;124974:61;;;:::i;:::-;;2614:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96254:95;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;124625:157;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97496:146;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98799:236;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123665:266;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122829:88;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97713:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3547:220;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;124792:172;2500:13;:11;:13::i;:::-;124899:11:::1;124891:37;;;124937:4;124944:2;124948:7;124891:65;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;124792:172:::0;;;:::o;112857:224::-;112959:4;112998:35;112983:50;;;:11;:50;;;;:90;;;;113037:36;113061:11;113037:23;:36::i;:::-;112983:90;112976:97;;112857:224;;;:::o;96094:91::-;96139:13;96172:5;96165:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96094:91;:::o;97266:158::-;97333:7;97353:22;97367:7;97353:13;:22::i;:::-;;97395:21;97408:7;97395:12;:21::i;:::-;97388:28;;97266:158;;;:::o;97085:115::-;97157:35;97166:2;97170:7;97179:12;:10;:12::i;:::-;97157:8;:35::i;:::-;97085:115;;:::o;122782:33::-;;;;:::o;119519:155::-;119610:6;119636:30;;;119629:37;;119519:155;;;;;;:::o;123178:100::-;123231:7;123258:11;;123251:18;;123178:100;:::o;97935:588::-;98044:1;98030:16;;:2;:16;;;98026:89;;98100:1;98070:33;;;;;;;;;;;:::i;:::-;;;;;;;;98026:89;98336:21;98360:34;98368:2;98372:7;98381:12;:10;:12::i;:::-;98360:7;:34::i;:::-;98336:58;;98426:4;98409:21;;:13;:21;;;98405:111;;98475:4;98481:7;98490:13;98454:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;98405:111;98015:508;97935:588;;;:::o;124184:431::-;2500:13;:11;:13::i;:::-;121137:19:::1;:17;:19::i;:::-;124288:1:::2;124279:6;:10;124271:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;124352:11;;124342:6;124328:11;;:20;;;;:::i;:::-;:35;;124320:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;124405:9;124400:169;124424:6;124420:1;:10;124400:169;;;124452:15;124484:1;124470:11;;:15;;;;:::i;:::-;124452:33;;124502:22;124512:2;124516:7;124502:9;:22::i;:::-;124541:11;;:13;;;;;;;;;:::i;:::-;;;;;;124437:132;124432:3;;;;;:::i;:::-;;;;124400:169;;;;124595:2;124586:21;;;124600:6;124586:21;;;;;;:::i;:::-;;;;;;;;124184:431:::0;;:::o;113165:260::-;113253:7;113286:16;113296:5;113286:9;:16::i;:::-;113277:5;:25;113273:101;;113349:5;113356;113326:36;;;;;;;;;;;;:::i;:::-;;;;;;;;113273:101;113391:12;:19;113404:5;113391:19;;;;;;;;;;;;;;;:26;113411:5;113391:26;;;;;;;;;;;;113384:33;;113165:260;;;;:::o;125043:65::-;2500:13;:11;:13::i;:::-;125090:10:::1;:8;:10::i;:::-;125043:65::o:0;124058:116::-;2500:13;:11;:13::i;:::-;121137:19:::1;:17;:19::i;:::-;124144:22:::2;124154:2;124158:7;124144:9;:22::i;:::-;124058:116:::0;;:::o;98594:134::-;98681:39;98698:4;98704:2;98708:7;98681:39;;;;;;;;;;;;:16;:39::i;:::-;98594:134;;;:::o;123941:107::-;2500:13;:11;:13::i;:::-;124002:14:::1;124008:7;124002:5;:14::i;:::-;124027:11;;:13;;;;;;;;;:::i;:::-;;;;;;123941:107:::0;:::o;113682:231::-;113748:7;113781:13;:11;:13::i;:::-;113772:5;:22;113768:103;;113849:1;113853:5;113818:41;;;;;;;;;;;;:::i;:::-;;;;;;;;113768:103;113888:10;113899:5;113888:17;;;;;;;;:::i;:::-;;;;;;;;;;113881:24;;113682:231;;;:::o;123421:111::-;2500:13;:11;:13::i;:::-;123514:10:::1;123497:14;:27;;;;;;:::i;:::-;;123421:111:::0;:::o;123546:109::-;2500:13;:11;:13::i;:::-;123642:5:::1;123628:11;;:19;;;;:::i;:::-;123614:11;:33;;;;123546:109:::0;:::o;121532:86::-;121579:4;121603:7;;;;;;;;;;;121596:14;;121532:86;:::o;95907:120::-;95970:7;95997:22;96011:7;95997:13;:22::i;:::-;95990:29;;95907:120;;;:::o;95632:213::-;95695:7;95736:1;95719:19;;:5;:19;;;95715:89;;95789:1;95762:30;;;;;;;;;;;:::i;:::-;;;;;;;;95715:89;95821:9;:16;95831:5;95821:16;;;;;;;;;;;;;;;;95814:23;;95632:213;;;:::o;3289:103::-;2500:13;:11;:13::i;:::-;3354:30:::1;3381:1;3354:18;:30::i;:::-;3289:103::o:0;124974:61::-;2500:13;:11;:13::i;:::-;125019:8:::1;:6;:8::i;:::-;124974:61::o:0;2614:87::-;2660:7;2687:6;;;;;;;;;;;2680:13;;2614:87;:::o;96254:95::-;96301:13;96334:7;96327:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96254:95;:::o;124625:157::-;124709:11;124701:37;;;124739:10;124759:4;124766:7;124701:73;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124625:157;;:::o;97496:146::-;97582:52;97601:12;:10;:12::i;:::-;97615:8;97625;97582:18;:52::i;:::-;97496:146;;:::o;98799:236::-;98913:31;98926:4;98932:2;98936:7;98913:12;:31::i;:::-;98955:72;98989:12;:10;:12::i;:::-;99003:4;99009:2;99013:7;99022:4;98955:33;:72::i;:::-;98799:236;;;;:::o;123665:266::-;123738:13;123802:1;123773:31;;:17;123782:7;123773:8;:17::i;:::-;:31;;;123764:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;123891:10;:8;:10::i;:::-;123903:18;:7;:16;:18::i;:::-;123874:48;;;;;;;;;:::i;:::-;;;;;;;;;;;;;123860:63;;123665:266;;;:::o;122829:88::-;;;;;;;;;;;;;:::o;97713:155::-;97801:4;97825:18;:25;97844:5;97825:25;;;;;;;;;;;;;;;:35;97851:8;97825:35;;;;;;;;;;;;;;;;;;;;;;;;;97818:42;;97713:155;;;;:::o;3547:220::-;2500:13;:11;:13::i;:::-;3652:1:::1;3632:22;;:8;:22;;::::0;3628:93:::1;;3706:1;3678:31;;;;;;;;;;;:::i;:::-;;;;;;;;3628:93;3731:28;3750:8;3731:18;:28::i;:::-;3547:220:::0;:::o;2779:166::-;2850:12;:10;:12::i;:::-;2839:23;;:7;:5;:7::i;:::-;:23;;;2835:103;;2913:12;:10;:12::i;:::-;2886:40;;;;;;;;;;;:::i;:::-;;;;;;;;2835:103;2779:166::o;95263:305::-;95365:4;95417:25;95402:40;;;:11;:40;;;;:105;;;;95474:33;95459:48;;;:11;:48;;;;95402:105;:158;;;;95524:36;95548:11;95524:23;:36::i;:::-;95402:158;95382:178;;95263:305;;;:::o;110317:247::-;110380:7;110400:13;110416:17;110425:7;110416:8;:17::i;:::-;110400:33;;110465:1;110448:19;;:5;:19;;;110444:90;;110514:7;110491:31;;;;;;;;;;;:::i;:::-;;;;;;;;110444:90;110551:5;110544:12;;;110317:247;;;:::o;99798:129::-;99868:7;99895:15;:24;99911:7;99895:24;;;;;;;;;;;;;;;;;;;;;99888:31;;99798:129;;;:::o;672:98::-;725:7;752:10;745:17;;672:98;:::o;108549:122::-;108630:33;108639:2;108643:7;108652:4;108658;108630:8;:33::i;:::-;108549:122;;;:::o;113974:640::-;114069:7;114089:21;114113:32;114127:2;114131:7;114140:4;114113:13;:32::i;:::-;114089:56;;114187:1;114162:27;;:13;:27;;;114158:214;;114206:40;114238:7;114206:31;:40::i;:::-;114158:214;;;114285:2;114268:19;;:13;:19;;;114264:108;;114304:56;114337:13;114352:7;114304:32;:56::i;:::-;114264:108;114158:214;114400:1;114386:16;;:2;:16;;;114382:192;;114419:45;114456:7;114419:36;:45::i;:::-;114382:192;;;114503:2;114486:19;;:13;:19;;;114482:92;;114522:40;114550:2;114554:7;114522:27;:40::i;:::-;114482:92;114382:192;114593:13;114586:20;;;113974:640;;;;;:::o;121691:132::-;121757:8;:6;:8::i;:::-;121753:63;;;121789:15;;;;;;;;;;;;;;121753:63;121691:132::o;104617:102::-;104685:26;104695:2;104699:7;104685:26;;;;;;;;;;;;:9;:26::i;:::-;104617:102;;:::o;122433:120::-;121396:16;:14;:16::i;:::-;122502:5:::1;122492:7;;:15;;;;;;;;;;;;;;;;;;122523:22;122532:12;:10;:12::i;:::-;122523:22;;;;;;:::i;:::-;;;;;;;;122433:120::o:0;105495:232::-;105547:21;105571:40;105587:1;105591:7;105608:1;105571:7;:40::i;:::-;105547:64;;105651:1;105626:27;;:13;:27;;;105622:98;;105700:7;105677:31;;;;;;;;;;;:::i;:::-;;;;;;;;105622:98;105536:191;105495:232;:::o;3927:191::-;4001:16;4020:6;;;;;;;;;;;4001:25;;4046:8;4037:6;;:17;;;;;;;;;;;;;;;;;;4101:8;4070:40;;4091:8;4070:40;;;;;;;;;;;;3990:128;3927:191;:::o;122174:118::-;121137:19;:17;:19::i;:::-;122244:4:::1;122234:7;;:14;;;;;;;;;;;;;;;;;;122264:20;122271:12;:10;:12::i;:::-;122264:20;;;;;;:::i;:::-;;;;;;;;122174:118::o:0;109756:318::-;109884:1;109864:22;;:8;:22;;;109860:93;;109932:8;109910:31;;;;;;;;;;;:::i;:::-;;;;;;;;109860:93;110001:8;109963:18;:25;109982:5;109963:25;;;;;;;;;;;;;;;:35;109989:8;109963:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;110047:8;110025:41;;110040:5;110025:41;;;110057:8;110025:41;;;;;;:::i;:::-;;;;;;;;109756:318;;;:::o;19249:948::-;19453:1;19436:2;:14;;;:18;19432:758;;;19491:2;19475:36;;;19512:8;19522:4;19528:7;19537:4;19475:67;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;19471:708;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19855:1;19838:6;:13;:18;19834:330;;19980:2;19944:39;;;;;;;;;;;:::i;:::-;;;;;;;;19834:330;20114:6;20108:13;20099:6;20095:2;20091:15;20084:38;19471:708;19600:41;;;19590:51;;;:6;:51;;;;19586:185;;19748:2;19712:39;;;;;;;;;;;:::i;:::-;;;;;;;;19586:185;19543:243;19432:758;19249:948;;;;;:::o;99560:117::-;99626:7;99653;:16;99661:7;99653:16;;;;;;;;;;;;;;;;;;;;;99646:23;;99560:117;;;:::o;123292:115::-;123352:13;123385:14;123378:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123292:115;:::o;89818:650::-;89874:13;89925:14;89962:1;89942:17;89953:5;89942:10;:17::i;:::-;:21;89925:38;;89978:20;90012:6;90001:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89978:41;;90034:11;90131:6;90127:2;90123:15;90115:6;90111:28;90104:35;;90168:254;90175:4;90168:254;;;90200:5;;;;;;;;90306:10;90301:2;90294:5;90290:14;90285:32;90280:3;90272:46;90364:2;90355:11;;;;;;:::i;:::-;;;;;90398:1;90389:5;:10;90168:254;90385:21;90168:254;90443:6;90436:13;;;;;89818:650;;;:::o;93929:148::-;94005:4;94044:25;94029:40;;;:11;:40;;;;94022:47;;93929:148;;;:::o;108859:678::-;109021:9;:31;;;;109050:1;109034:18;;:4;:18;;;;109021:31;109017:471;;;109069:13;109085:22;109099:7;109085:13;:22::i;:::-;109069:38;;109254:1;109238:18;;:4;:18;;;;:35;;;;;109269:4;109260:13;;:5;:13;;;;109238:35;:69;;;;;109278:29;109295:5;109302:4;109278:16;:29::i;:::-;109277:30;109238:69;109234:144;;;109357:4;109335:27;;;;;;;;;;;:::i;:::-;;;;;;;;109234:144;109398:9;109394:83;;;109453:7;109449:2;109433:28;;109442:5;109433:28;;;;;;;;;;;;109394:83;109054:434;109017:471;109527:2;109500:15;:24;109516:7;109500:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;108859:678;;;;:::o;102759:824::-;102845:7;102865:12;102880:17;102889:7;102880:8;:17::i;:::-;102865:32;;102976:1;102960:18;;:4;:18;;;102956:88;;102995:37;103012:4;103018;103024:7;102995:16;:37::i;:::-;102956:88;103107:1;103091:18;;:4;:18;;;103087:263;;103209:48;103226:1;103230:7;103247:1;103251:5;103209:8;:48::i;:::-;103322:1;103303:9;:15;103313:4;103303:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;103087:263;103380:1;103366:16;;:2;:16;;;103362:111;;103445:1;103428:9;:13;103438:2;103428:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;103362:111;103504:2;103485:7;:16;103493:7;103485:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;103543:7;103539:2;103524:27;;103533:4;103524:27;;;;;;;;;;;;103571:4;103564:11;;;102759:824;;;;;:::o;115334:164::-;115438:10;:17;;;;115411:15;:24;115427:7;115411:24;;;;;;;;;;;:44;;;;115466:10;115482:7;115466:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;115334:164;:::o;116125:1075::-;116391:22;116416:15;116426:4;116416:9;:15::i;:::-;116391:40;;116442:18;116463:17;:26;116481:7;116463:26;;;;;;;;;;;;116442:47;;116502:61;116566:12;:18;116579:4;116566:18;;;;;;;;;;;;;;;116502:82;;116705:14;116691:10;:28;116687:330;;116736:19;116758;:35;116778:14;116758:35;;;;;;;;;;;;116736:57;;116844:11;116810:19;:31;116830:10;116810:31;;;;;;;;;;;:45;;;;116961:10;116928:17;:30;116946:11;116928:30;;;;;;;;;;;:43;;;;116721:296;116687:330;117113:17;:26;117131:7;117113:26;;;;;;;;;;;117106:33;;;117157:19;:35;117177:14;117157:35;;;;;;;;;;;117150:42;;;116206:994;;;116125:1075;;:::o;117495:1079::-;117748:22;117793:1;117773:10;:17;;;;:21;;;;:::i;:::-;117748:46;;117805:18;117826:15;:24;117842:7;117826:24;;;;;;;;;;;;117805:45;;118177:19;118199:10;118210:14;118199:26;;;;;;;;:::i;:::-;;;;;;;;;;118177:48;;118263:11;118238:10;118249;118238:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;118374:10;118343:15;:28;118359:11;118343:28;;;;;;;;;;;:41;;;;118515:15;:24;118531:7;118515:24;;;;;;;;;;;118508:31;;;118550:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;117566:1008;;;117495:1079;:::o;114915:218::-;115000:14;115033:1;115017:13;115027:2;115017:9;:13::i;:::-;:17;;;;:::i;:::-;115000:34;;115072:7;115045:12;:16;115058:2;115045:16;;;;;;;;;;;;;;;:24;115062:6;115045:24;;;;;;;;;;;:34;;;;115119:6;115090:17;:26;115108:7;115090:26;;;;;;;;;;;:35;;;;114989:144;114915:218;;:::o;104946:210::-;105041:18;105047:2;105051:7;105041:5;:18::i;:::-;105070:78;105104:12;:10;:12::i;:::-;105126:1;105130:2;105134:7;105143:4;105070:33;:78::i;:::-;104946:210;;;:::o;121900:130::-;121964:8;:6;:8::i;:::-;121959:64;;121996:15;;;;;;;;;;;;;;121959:64;121900:130::o;83608:948::-;83661:7;83681:14;83698:1;83681:18;;83748:8;83739:5;:17;83735:106;;83786:8;83777:17;;;;;;:::i;:::-;;;;;83823:2;83813:12;;;;83735:106;83868:8;83859:5;:17;83855:106;;83906:8;83897:17;;;;;;:::i;:::-;;;;;83943:2;83933:12;;;;83855:106;83988:8;83979:5;:17;83975:106;;84026:8;84017:17;;;;;;:::i;:::-;;;;;84063:2;84053:12;;;;83975:106;84108:7;84099:5;:16;84095:103;;84145:7;84136:16;;;;;;:::i;:::-;;;;;84181:1;84171:11;;;;84095:103;84225:7;84216:5;:16;84212:103;;84262:7;84253:16;;;;;;:::i;:::-;;;;;84298:1;84288:11;;;;84212:103;84342:7;84333:5;:16;84329:103;;84379:7;84370:16;;;;;;:::i;:::-;;;;;84415:1;84405:11;;;;84329:103;84459:7;84450:5;:16;84446:68;;84497:1;84487:11;;;;84446:68;84542:6;84535:13;;;83608:948;;;:::o;100966:376::-;101079:38;101093:5;101100:7;101109;101079:13;:38::i;:::-;101074:261;;101155:1;101138:19;;:5;:19;;;101134:190;;101208:7;101185:31;;;;;;;;;;;:::i;:::-;;;;;;;;101134:190;101291:7;101300;101264:44;;;;;;;;;;;;:::i;:::-;;;;;;;;101074:261;100966:376;;;:::o;103919:335::-;104001:1;103987:16;;:2;:16;;;103983:89;;104057:1;104027:33;;;;;;;;;;;:::i;:::-;;;;;;;;103983:89;104082:21;104106:32;104114:2;104118:7;104135:1;104106:7;:32::i;:::-;104082:56;;104178:1;104153:27;;:13;:27;;;104149:98;;104232:1;104204:31;;;;;;;;;;;:::i;:::-;;;;;;;;104149:98;103972:282;103919:335;;:::o;100247:276::-;100350:4;100406:1;100387:21;;:7;:21;;;;:128;;;;;100435:7;100426:16;;:5;:16;;;:52;;;;100446:32;100463:5;100470:7;100446:16;:32::i;:::-;100426:52;:88;;;;100507:7;100482:32;;:21;100495:7;100482:12;:21::i;:::-;:32;;;100426:88;100387:128;100367:148;;100247:276;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:77::-;878:7;907:5;896:16;;841:77;;;:::o;924:122::-;997:24;1015:5;997:24;:::i;:::-;990:5;987:35;977:63;;1036:1;1033;1026:12;977:63;924:122;:::o;1052:139::-;1098:5;1136:6;1123:20;1114:29;;1152:33;1179:5;1152:33;:::i;:::-;1052:139;;;;:::o;1197:619::-;1274:6;1282;1290;1339:2;1327:9;1318:7;1314:23;1310:32;1307:119;;;1345:79;;:::i;:::-;1307:119;1465:1;1490:53;1535:7;1526:6;1515:9;1511:22;1490:53;:::i;:::-;1480:63;;1436:117;1592:2;1618:53;1663:7;1654:6;1643:9;1639:22;1618:53;:::i;:::-;1608:63;;1563:118;1720:2;1746:53;1791:7;1782:6;1771:9;1767:22;1746:53;:::i;:::-;1736:63;;1691:118;1197:619;;;;;:::o;1822:149::-;1858:7;1898:66;1891:5;1887:78;1876:89;;1822:149;;;:::o;1977:120::-;2049:23;2066:5;2049:23;:::i;:::-;2042:5;2039:34;2029:62;;2087:1;2084;2077:12;2029:62;1977:120;:::o;2103:137::-;2148:5;2186:6;2173:20;2164:29;;2202:32;2228:5;2202:32;:::i;:::-;2103:137;;;;:::o;2246:327::-;2304:6;2353:2;2341:9;2332:7;2328:23;2324:32;2321:119;;;2359:79;;:::i;:::-;2321:119;2479:1;2504:52;2548:7;2539:6;2528:9;2524:22;2504:52;:::i;:::-;2494:62;;2450:116;2246:327;;;;:::o;2579:90::-;2613:7;2656:5;2649:13;2642:21;2631:32;;2579:90;;;:::o;2675:109::-;2756:21;2771:5;2756:21;:::i;:::-;2751:3;2744:34;2675:109;;:::o;2790:210::-;2877:4;2915:2;2904:9;2900:18;2892:26;;2928:65;2990:1;2979:9;2975:17;2966:6;2928:65;:::i;:::-;2790:210;;;;:::o;3006:99::-;3058:6;3092:5;3086:12;3076:22;;3006:99;;;:::o;3111:169::-;3195:11;3229:6;3224:3;3217:19;3269:4;3264:3;3260:14;3245:29;;3111:169;;;;:::o;3286:246::-;3367:1;3377:113;3391:6;3388:1;3385:13;3377:113;;;3476:1;3471:3;3467:11;3461:18;3457:1;3452:3;3448:11;3441:39;3413:2;3410:1;3406:10;3401:15;;3377:113;;;3524:1;3515:6;3510:3;3506:16;3499:27;3348:184;3286:246;;;:::o;3538:102::-;3579:6;3630:2;3626:7;3621:2;3614:5;3610:14;3606:28;3596:38;;3538:102;;;:::o;3646:377::-;3734:3;3762:39;3795:5;3762:39;:::i;:::-;3817:71;3881:6;3876:3;3817:71;:::i;:::-;3810:78;;3897:65;3955:6;3950:3;3943:4;3936:5;3932:16;3897:65;:::i;:::-;3987:29;4009:6;3987:29;:::i;:::-;3982:3;3978:39;3971:46;;3738:285;3646:377;;;;:::o;4029:313::-;4142:4;4180:2;4169:9;4165:18;4157:26;;4229:9;4223:4;4219:20;4215:1;4204:9;4200:17;4193:47;4257:78;4330:4;4321:6;4257:78;:::i;:::-;4249:86;;4029:313;;;;:::o;4348:329::-;4407:6;4456:2;4444:9;4435:7;4431:23;4427:32;4424:119;;;4462:79;;:::i;:::-;4424:119;4582:1;4607:53;4652:7;4643:6;4632:9;4628:22;4607:53;:::i;:::-;4597:63;;4553:117;4348:329;;;;:::o;4683:118::-;4770:24;4788:5;4770:24;:::i;:::-;4765:3;4758:37;4683:118;;:::o;4807:222::-;4900:4;4938:2;4927:9;4923:18;4915:26;;4951:71;5019:1;5008:9;5004:17;4995:6;4951:71;:::i;:::-;4807:222;;;;:::o;5035:474::-;5103:6;5111;5160:2;5148:9;5139:7;5135:23;5131:32;5128:119;;;5166:79;;:::i;:::-;5128:119;5286:1;5311:53;5356:7;5347:6;5336:9;5332:22;5311:53;:::i;:::-;5301:63;;5257:117;5413:2;5439:53;5484:7;5475:6;5464:9;5460:22;5439:53;:::i;:::-;5429:63;;5384:118;5035:474;;;;;:::o;5515:118::-;5602:24;5620:5;5602:24;:::i;:::-;5597:3;5590:37;5515:118;;:::o;5639:222::-;5732:4;5770:2;5759:9;5755:18;5747:26;;5783:71;5851:1;5840:9;5836:17;5827:6;5783:71;:::i;:::-;5639:222;;;;:::o;5867:117::-;5976:1;5973;5966:12;5990:117;6099:1;6096;6089:12;6113:180;6161:77;6158:1;6151:88;6258:4;6255:1;6248:15;6282:4;6279:1;6272:15;6299:281;6382:27;6404:4;6382:27;:::i;:::-;6374:6;6370:40;6512:6;6500:10;6497:22;6476:18;6464:10;6461:34;6458:62;6455:88;;;6523:18;;:::i;:::-;6455:88;6563:10;6559:2;6552:22;6342:238;6299:281;;:::o;6586:129::-;6620:6;6647:20;;:::i;:::-;6637:30;;6676:33;6704:4;6696:6;6676:33;:::i;:::-;6586:129;;;:::o;6721:307::-;6782:4;6872:18;6864:6;6861:30;6858:56;;;6894:18;;:::i;:::-;6858:56;6932:29;6954:6;6932:29;:::i;:::-;6924:37;;7016:4;7010;7006:15;6998:23;;6721:307;;;:::o;7034:146::-;7131:6;7126:3;7121;7108:30;7172:1;7163:6;7158:3;7154:16;7147:27;7034:146;;;:::o;7186:423::-;7263:5;7288:65;7304:48;7345:6;7304:48;:::i;:::-;7288:65;:::i;:::-;7279:74;;7376:6;7369:5;7362:21;7414:4;7407:5;7403:16;7452:3;7443:6;7438:3;7434:16;7431:25;7428:112;;;7459:79;;:::i;:::-;7428:112;7549:54;7596:6;7591:3;7586;7549:54;:::i;:::-;7269:340;7186:423;;;;;:::o;7628:338::-;7683:5;7732:3;7725:4;7717:6;7713:17;7709:27;7699:122;;7740:79;;:::i;:::-;7699:122;7857:6;7844:20;7882:78;7956:3;7948:6;7941:4;7933:6;7929:17;7882:78;:::i;:::-;7873:87;;7689:277;7628:338;;;;:::o;7972:943::-;8067:6;8075;8083;8091;8140:3;8128:9;8119:7;8115:23;8111:33;8108:120;;;8147:79;;:::i;:::-;8108:120;8267:1;8292:53;8337:7;8328:6;8317:9;8313:22;8292:53;:::i;:::-;8282:63;;8238:117;8394:2;8420:53;8465:7;8456:6;8445:9;8441:22;8420:53;:::i;:::-;8410:63;;8365:118;8522:2;8548:53;8593:7;8584:6;8573:9;8569:22;8548:53;:::i;:::-;8538:63;;8493:118;8678:2;8667:9;8663:18;8650:32;8709:18;8701:6;8698:30;8695:117;;;8731:79;;:::i;:::-;8695:117;8836:62;8890:7;8881:6;8870:9;8866:22;8836:62;:::i;:::-;8826:72;;8621:287;7972:943;;;;;;;:::o;8921:115::-;9006:23;9023:5;9006:23;:::i;:::-;9001:3;8994:36;8921:115;;:::o;9042:218::-;9133:4;9171:2;9160:9;9156:18;9148:26;;9184:69;9250:1;9239:9;9235:17;9226:6;9184:69;:::i;:::-;9042:218;;;;:::o;9266:619::-;9343:6;9351;9359;9408:2;9396:9;9387:7;9383:23;9379:32;9376:119;;;9414:79;;:::i;:::-;9376:119;9534:1;9559:53;9604:7;9595:6;9584:9;9580:22;9559:53;:::i;:::-;9549:63;;9505:117;9661:2;9687:53;9732:7;9723:6;9712:9;9708:22;9687:53;:::i;:::-;9677:63;;9632:118;9789:2;9815:53;9860:7;9851:6;9840:9;9836:22;9815:53;:::i;:::-;9805:63;;9760:118;9266:619;;;;;:::o;9891:308::-;9953:4;10043:18;10035:6;10032:30;10029:56;;;10065:18;;:::i;:::-;10029:56;10103:29;10125:6;10103:29;:::i;:::-;10095:37;;10187:4;10181;10177:15;10169:23;;9891:308;;;:::o;10205:425::-;10283:5;10308:66;10324:49;10366:6;10324:49;:::i;:::-;10308:66;:::i;:::-;10299:75;;10397:6;10390:5;10383:21;10435:4;10428:5;10424:16;10473:3;10464:6;10459:3;10455:16;10452:25;10449:112;;;10480:79;;:::i;:::-;10449:112;10570:54;10617:6;10612:3;10607;10570:54;:::i;:::-;10289:341;10205:425;;;;;:::o;10650:340::-;10706:5;10755:3;10748:4;10740:6;10736:17;10732:27;10722:122;;10763:79;;:::i;:::-;10722:122;10880:6;10867:20;10905:79;10980:3;10972:6;10965:4;10957:6;10953:17;10905:79;:::i;:::-;10896:88;;10712:278;10650:340;;;;:::o;10996:509::-;11065:6;11114:2;11102:9;11093:7;11089:23;11085:32;11082:119;;;11120:79;;:::i;:::-;11082:119;11268:1;11257:9;11253:17;11240:31;11298:18;11290:6;11287:30;11284:117;;;11320:79;;:::i;:::-;11284:117;11425:63;11480:7;11471:6;11460:9;11456:22;11425:63;:::i;:::-;11415:73;;11211:287;10996:509;;;;:::o;11511:329::-;11570:6;11619:2;11607:9;11598:7;11594:23;11590:32;11587:119;;;11625:79;;:::i;:::-;11587:119;11745:1;11770:53;11815:7;11806:6;11795:9;11791:22;11770:53;:::i;:::-;11760:63;;11716:117;11511:329;;;;:::o;11846:116::-;11916:21;11931:5;11916:21;:::i;:::-;11909:5;11906:32;11896:60;;11952:1;11949;11942:12;11896:60;11846:116;:::o;11968:133::-;12011:5;12049:6;12036:20;12027:29;;12065:30;12089:5;12065:30;:::i;:::-;11968:133;;;;:::o;12107:468::-;12172:6;12180;12229:2;12217:9;12208:7;12204:23;12200:32;12197:119;;;12235:79;;:::i;:::-;12197:119;12355:1;12380:53;12425:7;12416:6;12405:9;12401:22;12380:53;:::i;:::-;12370:63;;12326:117;12482:2;12508:50;12550:7;12541:6;12530:9;12526:22;12508:50;:::i;:::-;12498:60;;12453:115;12107:468;;;;;:::o;12581:474::-;12649:6;12657;12706:2;12694:9;12685:7;12681:23;12677:32;12674:119;;;12712:79;;:::i;:::-;12674:119;12832:1;12857:53;12902:7;12893:6;12882:9;12878:22;12857:53;:::i;:::-;12847:63;;12803:117;12959:2;12985:53;13030:7;13021:6;13010:9;13006:22;12985:53;:::i;:::-;12975:63;;12930:118;12581:474;;;;;:::o;13061:442::-;13210:4;13248:2;13237:9;13233:18;13225:26;;13261:71;13329:1;13318:9;13314:17;13305:6;13261:71;:::i;:::-;13342:72;13410:2;13399:9;13395:18;13386:6;13342:72;:::i;:::-;13424;13492:2;13481:9;13477:18;13468:6;13424:72;:::i;:::-;13061:442;;;;;;:::o;13509:180::-;13557:77;13554:1;13547:88;13654:4;13651:1;13644:15;13678:4;13675:1;13668:15;13695:320;13739:6;13776:1;13770:4;13766:12;13756:22;;13823:1;13817:4;13813:12;13844:18;13834:81;;13900:4;13892:6;13888:17;13878:27;;13834:81;13962:2;13954:6;13951:14;13931:18;13928:38;13925:84;;13981:18;;:::i;:::-;13925:84;13746:269;13695:320;;;:::o;14021:442::-;14170:4;14208:2;14197:9;14193:18;14185:26;;14221:71;14289:1;14278:9;14274:17;14265:6;14221:71;:::i;:::-;14302:72;14370:2;14359:9;14355:18;14346:6;14302:72;:::i;:::-;14384;14452:2;14441:9;14437:18;14428:6;14384:72;:::i;:::-;14021:442;;;;;;:::o;14469:165::-;14609:17;14605:1;14597:6;14593:14;14586:41;14469:165;:::o;14640:366::-;14782:3;14803:67;14867:2;14862:3;14803:67;:::i;:::-;14796:74;;14879:93;14968:3;14879:93;:::i;:::-;14997:2;14992:3;14988:12;14981:19;;14640:366;;;:::o;15012:419::-;15178:4;15216:2;15205:9;15201:18;15193:26;;15265:9;15259:4;15255:20;15251:1;15240:9;15236:17;15229:47;15293:131;15419:4;15293:131;:::i;:::-;15285:139;;15012:419;;;:::o;15437:180::-;15485:77;15482:1;15475:88;15582:4;15579:1;15572:15;15606:4;15603:1;15596:15;15623:191;15663:3;15682:20;15700:1;15682:20;:::i;:::-;15677:25;;15716:20;15734:1;15716:20;:::i;:::-;15711:25;;15759:1;15756;15752:9;15745:16;;15780:3;15777:1;15774:10;15771:36;;;15787:18;;:::i;:::-;15771:36;15623:191;;;;:::o;15820:169::-;15960:21;15956:1;15948:6;15944:14;15937:45;15820:169;:::o;15995:366::-;16137:3;16158:67;16222:2;16217:3;16158:67;:::i;:::-;16151:74;;16234:93;16323:3;16234:93;:::i;:::-;16352:2;16347:3;16343:12;16336:19;;15995:366;;;:::o;16367:419::-;16533:4;16571:2;16560:9;16556:18;16548:26;;16620:9;16614:4;16610:20;16606:1;16595:9;16591:17;16584:47;16648:131;16774:4;16648:131;:::i;:::-;16640:139;;16367:419;;;:::o;16792:233::-;16831:3;16854:24;16872:5;16854:24;:::i;:::-;16845:33;;16900:66;16893:5;16890:77;16887:103;;16970:18;;:::i;:::-;16887:103;17017:1;17010:5;17006:13;16999:20;;16792:233;;;:::o;17031:332::-;17152:4;17190:2;17179:9;17175:18;17167:26;;17203:71;17271:1;17260:9;17256:17;17247:6;17203:71;:::i;:::-;17284:72;17352:2;17341:9;17337:18;17328:6;17284:72;:::i;:::-;17031:332;;;;;:::o;17369:171::-;17408:3;17431:24;17449:5;17431:24;:::i;:::-;17422:33;;17477:4;17470:5;17467:15;17464:41;;17485:18;;:::i;:::-;17464:41;17532:1;17525:5;17521:13;17514:20;;17369:171;;;:::o;17546:180::-;17594:77;17591:1;17584:88;17691:4;17688:1;17681:15;17715:4;17712:1;17705:15;17732:141;17781:4;17804:3;17796:11;;17827:3;17824:1;17817:14;17861:4;17858:1;17848:18;17840:26;;17732:141;;;:::o;17879:93::-;17916:6;17963:2;17958;17951:5;17947:14;17943:23;17933:33;;17879:93;;;:::o;17978:107::-;18022:8;18072:5;18066:4;18062:16;18041:37;;17978:107;;;;:::o;18091:393::-;18160:6;18210:1;18198:10;18194:18;18233:97;18263:66;18252:9;18233:97;:::i;:::-;18351:39;18381:8;18370:9;18351:39;:::i;:::-;18339:51;;18423:4;18419:9;18412:5;18408:21;18399:30;;18472:4;18462:8;18458:19;18451:5;18448:30;18438:40;;18167:317;;18091:393;;;;;:::o;18490:60::-;18518:3;18539:5;18532:12;;18490:60;;;:::o;18556:142::-;18606:9;18639:53;18657:34;18666:24;18684:5;18666:24;:::i;:::-;18657:34;:::i;:::-;18639:53;:::i;:::-;18626:66;;18556:142;;;:::o;18704:75::-;18747:3;18768:5;18761:12;;18704:75;;;:::o;18785:269::-;18895:39;18926:7;18895:39;:::i;:::-;18956:91;19005:41;19029:16;19005:41;:::i;:::-;18997:6;18990:4;18984:11;18956:91;:::i;:::-;18950:4;18943:105;18861:193;18785:269;;;:::o;19060:73::-;19105:3;19060:73;:::o;19139:189::-;19216:32;;:::i;:::-;19257:65;19315:6;19307;19301:4;19257:65;:::i;:::-;19192:136;19139:189;;:::o;19334:186::-;19394:120;19411:3;19404:5;19401:14;19394:120;;;19465:39;19502:1;19495:5;19465:39;:::i;:::-;19438:1;19431:5;19427:13;19418:22;;19394:120;;;19334:186;;:::o;19526:543::-;19627:2;19622:3;19619:11;19616:446;;;19661:38;19693:5;19661:38;:::i;:::-;19745:29;19763:10;19745:29;:::i;:::-;19735:8;19731:44;19928:2;19916:10;19913:18;19910:49;;;19949:8;19934:23;;19910:49;19972:80;20028:22;20046:3;20028:22;:::i;:::-;20018:8;20014:37;20001:11;19972:80;:::i;:::-;19631:431;;19616:446;19526:543;;;:::o;20075:117::-;20129:8;20179:5;20173:4;20169:16;20148:37;;20075:117;;;;:::o;20198:169::-;20242:6;20275:51;20323:1;20319:6;20311:5;20308:1;20304:13;20275:51;:::i;:::-;20271:56;20356:4;20350;20346:15;20336:25;;20249:118;20198:169;;;;:::o;20372:295::-;20448:4;20594:29;20619:3;20613:4;20594:29;:::i;:::-;20586:37;;20656:3;20653:1;20649:11;20643:4;20640:21;20632:29;;20372:295;;;;:::o;20672:1395::-;20789:37;20822:3;20789:37;:::i;:::-;20891:18;20883:6;20880:30;20877:56;;;20913:18;;:::i;:::-;20877:56;20957:38;20989:4;20983:11;20957:38;:::i;:::-;21042:67;21102:6;21094;21088:4;21042:67;:::i;:::-;21136:1;21160:4;21147:17;;21192:2;21184:6;21181:14;21209:1;21204:618;;;;21866:1;21883:6;21880:77;;;21932:9;21927:3;21923:19;21917:26;21908:35;;21880:77;21983:67;22043:6;22036:5;21983:67;:::i;:::-;21977:4;21970:81;21839:222;21174:887;;21204:618;21256:4;21252:9;21244:6;21240:22;21290:37;21322:4;21290:37;:::i;:::-;21349:1;21363:208;21377:7;21374:1;21371:14;21363:208;;;21456:9;21451:3;21447:19;21441:26;21433:6;21426:42;21507:1;21499:6;21495:14;21485:24;;21554:2;21543:9;21539:18;21526:31;;21400:4;21397:1;21393:12;21388:17;;21363:208;;;21599:6;21590:7;21587:19;21584:179;;;21657:9;21652:3;21648:19;21642:26;21700:48;21742:4;21734:6;21730:17;21719:9;21700:48;:::i;:::-;21692:6;21685:64;21607:156;21584:179;21809:1;21805;21797:6;21793:14;21789:22;21783:4;21776:36;21211:611;;;21174:887;;20764:1303;;;20672:1395;;:::o;22073:226::-;22213:34;22209:1;22201:6;22197:14;22190:58;22282:9;22277:2;22269:6;22265:15;22258:34;22073:226;:::o;22305:366::-;22447:3;22468:67;22532:2;22527:3;22468:67;:::i;:::-;22461:74;;22544:93;22633:3;22544:93;:::i;:::-;22662:2;22657:3;22653:12;22646:19;;22305:366;;;:::o;22677:419::-;22843:4;22881:2;22870:9;22866:18;22858:26;;22930:9;22924:4;22920:20;22916:1;22905:9;22901:17;22894:47;22958:131;23084:4;22958:131;:::i;:::-;22950:139;;22677:419;;;:::o;23102:148::-;23204:11;23241:3;23226:18;;23102:148;;;;:::o;23256:390::-;23362:3;23390:39;23423:5;23390:39;:::i;:::-;23445:89;23527:6;23522:3;23445:89;:::i;:::-;23438:96;;23543:65;23601:6;23596:3;23589:4;23582:5;23578:16;23543:65;:::i;:::-;23633:6;23628:3;23624:16;23617:23;;23366:280;23256:390;;;;:::o;23652:435::-;23832:3;23854:95;23945:3;23936:6;23854:95;:::i;:::-;23847:102;;23966:95;24057:3;24048:6;23966:95;:::i;:::-;23959:102;;24078:3;24071:10;;23652:435;;;;;:::o;24093:98::-;24144:6;24178:5;24172:12;24162:22;;24093:98;;;:::o;24197:168::-;24280:11;24314:6;24309:3;24302:19;24354:4;24349:3;24345:14;24330:29;;24197:168;;;;:::o;24371:373::-;24457:3;24485:38;24517:5;24485:38;:::i;:::-;24539:70;24602:6;24597:3;24539:70;:::i;:::-;24532:77;;24618:65;24676:6;24671:3;24664:4;24657:5;24653:16;24618:65;:::i;:::-;24708:29;24730:6;24708:29;:::i;:::-;24703:3;24699:39;24692:46;;24461:283;24371:373;;;;:::o;24750:640::-;24945:4;24983:3;24972:9;24968:19;24960:27;;24997:71;25065:1;25054:9;25050:17;25041:6;24997:71;:::i;:::-;25078:72;25146:2;25135:9;25131:18;25122:6;25078:72;:::i;:::-;25160;25228:2;25217:9;25213:18;25204:6;25160:72;:::i;:::-;25279:9;25273:4;25269:20;25264:2;25253:9;25249:18;25242:48;25307:76;25378:4;25369:6;25307:76;:::i;:::-;25299:84;;24750:640;;;;;;;:::o;25396:141::-;25452:5;25483:6;25477:13;25468:22;;25499:32;25525:5;25499:32;:::i;:::-;25396:141;;;;:::o;25543:349::-;25612:6;25661:2;25649:9;25640:7;25636:23;25632:32;25629:119;;;25667:79;;:::i;:::-;25629:119;25787:1;25812:63;25867:7;25858:6;25847:9;25843:22;25812:63;:::i;:::-;25802:73;;25758:127;25543:349;;;;:::o;25898:180::-;25946:77;25943:1;25936:88;26043:4;26040:1;26033:15;26067:4;26064:1;26057:15;26084:194;26124:4;26144:20;26162:1;26144:20;:::i;:::-;26139:25;;26178:20;26196:1;26178:20;:::i;:::-;26173:25;;26222:1;26219;26215:9;26207:17;;26246:1;26240:4;26237:11;26234:37;;;26251:18;;:::i;:::-;26234:37;26084:194;;;;:::o;26284:180::-;26332:77;26329:1;26322:88;26429:4;26426:1;26419:15;26453:4;26450:1;26443:15
Swarm Source
ipfs://8bda047cb690fac5297566fd6b14f63bc272b557796d62850f263509bf1445c2
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.