Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 891 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Approval For... | 50823990 | 23 mins ago | IN | 0 MON | 0.00814073 | ||||
| Set Approval For... | 50663529 | 18 hrs ago | IN | 0 MON | 0.00540832 | ||||
| Set Approval For... | 50638948 | 20 hrs ago | IN | 0 MON | 0.00567171 | ||||
| Set Approval For... | 50378594 | 2 days ago | IN | 0 MON | 0.0054115 | ||||
| Set Approval For... | 50333823 | 2 days ago | IN | 0 MON | 0.00595261 | ||||
| Set Approval For... | 49997563 | 3 days ago | IN | 0 MON | 0.00811726 | ||||
| Set Approval For... | 49893634 | 4 days ago | IN | 0 MON | 0.00812808 | ||||
| Set Approval For... | 49792147 | 4 days ago | IN | 0 MON | 0.01596425 | ||||
| Set Approval For... | 49604348 | 5 days ago | IN | 0 MON | 0.00540832 | ||||
| Set Approval For... | 49325636 | 6 days ago | IN | 0 MON | 0.00546456 | ||||
| Set Approval For... | 49087879 | 8 days ago | IN | 0 MON | 0.00540832 | ||||
| Safe Transfer Fr... | 49061373 | 8 days ago | IN | 0 MON | 0.00971346 | ||||
| Set Approval For... | 49030776 | 8 days ago | IN | 0 MON | 0.00540832 | ||||
| Set Approval For... | 48991649 | 8 days ago | IN | 0 MON | 0.00540832 | ||||
| Set Approval For... | 48958541 | 8 days ago | IN | 0 MON | 0.00595845 | ||||
| Set Approval For... | 48638894 | 10 days ago | IN | 0 MON | 0.00595261 | ||||
| Set Approval For... | 48586241 | 10 days ago | IN | 0 MON | 0.00566503 | ||||
| Set Approval For... | 48387358 | 11 days ago | IN | 0 MON | 0.00540832 | ||||
| Set Approval For... | 48080747 | 12 days ago | IN | 0 MON | 0.00810257 | ||||
| Set Approval For... | 48055844 | 12 days ago | IN | 0 MON | 0.00810257 | ||||
| Set Approval For... | 47679839 | 14 days ago | IN | 0 MON | 0.00543333 | ||||
| Set Approval For... | 47663403 | 14 days ago | IN | 0 MON | 0.00540832 | ||||
| Set Approval For... | 47455451 | 15 days ago | IN | 0 MON | 0.00811726 | ||||
| Set Approval For... | 47015161 | 17 days ago | IN | 0 MON | 0.00540832 | ||||
| Set Approval For... | 46861983 | 18 days ago | IN | 0 MON | 0.00566837 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 37707074 | 61 days ago | Contract Creation | 0 MON |
Loading...
Loading
Contract Name:
MonadPhasedNFT
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity)
/** *Submitted for verification at monadscan.com on 2025-11-24 */ // SPDX-License-Identifier: MIT // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity 0.8.23; /** * @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; } } // File @openzeppelin/contracts/access/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * 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); } } // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol) /** * @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); } // File @openzeppelin/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC2981.sol) /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. * * NOTE: ERC-2981 allows setting the royalty to 100% of the price. In that case all the price would be sent to the * royalty receiver and 0 tokens to the seller. Contracts dealing with royalty should consider empty transfers. */ function royaltyInfo( uint256 tokenId, uint256 salePrice ) external view returns (address receiver, uint256 royaltyAmount); } // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol) /** * @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 { /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File @openzeppelin/contracts/token/common/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/common/ERC2981.sol) /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the ERC. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 tokenId => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator); /** * @dev The default royalty receiver is invalid. */ error ERC2981InvalidDefaultRoyaltyReceiver(address receiver); /** * @dev The royalty set for a specific `tokenId` is invalid (eg. (numerator / denominator) >= 1). */ error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator); /** * @dev The royalty receiver for `tokenId` is invalid. */ error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver); /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /// @inheritdoc IERC2981 function royaltyInfo( uint256 tokenId, uint256 salePrice ) public view virtual returns (address receiver, uint256 amount) { RoyaltyInfo storage _royaltyInfo = _tokenRoyaltyInfo[tokenId]; address royaltyReceiver = _royaltyInfo.receiver; uint96 royaltyFraction = _royaltyInfo.royaltyFraction; if (royaltyReceiver == address(0)) { royaltyReceiver = _defaultRoyaltyInfo.receiver; royaltyFraction = _defaultRoyaltyInfo.royaltyFraction; } uint256 royaltyAmount = (salePrice * royaltyFraction) / _feeDenominator(); return (royaltyReceiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidDefaultRoyaltyReceiver(address(0)); } _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual { uint256 denominator = _feeDenominator(); if (feeNumerator > denominator) { // Royalty fee will exceed the sale price revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator); } if (receiver == address(0)) { revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0)); } _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } } // File @openzeppelin/contracts/interfaces/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol) /** * @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`窶冱 `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`窶冱 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`窶冱 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); } // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/IERC721.sol) /** * @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); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/extensions/IERC721Metadata.sol) /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/IERC721Receiver.sol) /** * @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); } // File @openzeppelin/contracts/token/ERC721/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/utils/ERC721Utils.sol) /** * @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 {IERC721Receiver-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(reason, 0x20), mload(reason)) } } } } } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. /** * @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)) } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) /** * @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) } } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol) /** * @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 Return the 512-bit addition of two uint256. * * The result is stored in two 256 variables such that sum = high * 2ツイ竅オ竅カ + low. */ function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) { assembly ("memory-safe") { low := add(a, b) high := lt(low, a) } } /** * @dev Return the 512-bit multiplication of two uint256. * * The result is stored in two 256 variables such that product = high * 2ツイ竅オ竅カ + low. */ function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) { // 512-bit multiply [high low] = 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 = high * 2ツイ竅オ竅カ + low. assembly ("memory-safe") { let mm := mulmod(a, b, not(0)) low := mul(a, b) high := sub(sub(mm, low), lt(mm, low)) } } /** * @dev Returns the addition of two unsigned integers, with a success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; success = c >= a; result = c * SafeCast.toUint(success); } } /** * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a - b; success = c <= a; result = c * SafeCast.toUint(success); } } /** * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a * b; assembly ("memory-safe") { // Only true when the multiplication doesn't overflow // (c / a == b) || (a == 0) success := or(eq(div(c, a), b), iszero(a)) } // equivalent to: success ? c : 0 result = c * SafeCast.toUint(success); } } /** * @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 { success = b > 0; assembly ("memory-safe") { // The `DIV` opcode returns zero when the denominator is 0. result := div(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 { success = b > 0; assembly ("memory-safe") { // The `MOD` opcode returns zero when the denominator is 0. result := mod(a, b) } } } /** * @dev Unsigned saturating addition, bounds to `2ツイ竅オ竅カ - 1` instead of overflowing. */ function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) { (bool success, uint256 result) = tryAdd(a, b); return ternary(success, result, type(uint256).max); } /** * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing. */ function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) { (, uint256 result) = trySub(a, b); return result; } /** * @dev Unsigned saturating multiplication, bounds to `2ツイ竅オ竅カ - 1` instead of overflowing. */ function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) { (bool success, uint256 result) = tryMul(a, b); return ternary(success, result, type(uint256).max); } /** * @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 { (uint256 high, uint256 low) = mul512(x, y); // Handle non-overflow cases, 256 by 256 division. if (high == 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 low / denominator; } // Make sure the result is less than 2ツイ竅オ竅カ. Also prevents denominator == 0. if (denominator <= high) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [high low]. uint256 remainder; assembly ("memory-safe") { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. high := sub(high, gt(remainder, low)) low := sub(low, 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 ("memory-safe") { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [high low] by twos. low := div(low, 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 high into low. low |= high * 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 high // is no longer required. result = low * 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 Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256. */ function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) { unchecked { (uint256 high, uint256 low) = mul512(x, y); if (high >= 1 << n) { Panic.panic(Panic.UNDER_OVERFLOW); } return (high << (256 - n)) | (low >> n); } } /** * @dev Calculates x * y >> n with full precision, following the selected rounding direction. */ function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) { return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 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 x) internal pure returns (uint256 r) { // If value has upper 128 bits set, log2 result is at least 128 r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7; // If upper 64 bits of 128-bit half set, add 64 to result r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6; // If upper 32 bits of 64-bit half set, add 32 to result r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5; // If upper 16 bits of 32-bit half set, add 16 to result r |= SafeCast.toUint((x >> r) > 0xffff) << 4; // If upper 8 bits of 16-bit half set, add 8 to result r |= SafeCast.toUint((x >> r) > 0xff) << 3; // If upper 4 bits of 8-bit half set, add 4 to result r |= SafeCast.toUint((x >> r) > 0xf) << 2; // Shifts value right by the current result and use it as an index into this lookup table: // // | x (4 bits) | index | table[index] = MSB position | // |------------|---------|-----------------------------| // | 0000 | 0 | table[0] = 0 | // | 0001 | 1 | table[1] = 0 | // | 0010 | 2 | table[2] = 1 | // | 0011 | 3 | table[3] = 1 | // | 0100 | 4 | table[4] = 2 | // | 0101 | 5 | table[5] = 2 | // | 0110 | 6 | table[6] = 2 | // | 0111 | 7 | table[7] = 2 | // | 1000 | 8 | table[8] = 3 | // | 1001 | 9 | table[9] = 3 | // | 1010 | 10 | table[10] = 3 | // | 1011 | 11 | table[11] = 3 | // | 1100 | 12 | table[12] = 3 | // | 1101 | 13 | table[13] = 3 | // | 1110 | 14 | table[14] = 3 | // | 1111 | 15 | table[15] = 3 | // // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes. assembly ("memory-safe") { r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000)) } } /** * @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 x) internal pure returns (uint256 r) { // If value has upper 128 bits set, log2 result is at least 128 r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7; // If upper 64 bits of 128-bit half set, add 64 to result r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6; // If upper 32 bits of 64-bit half set, add 32 to result r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5; // If upper 16 bits of 32-bit half set, add 16 to result r |= SafeCast.toUint((x >> r) > 0xffff) << 4; // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8 return (r >> 3) | SafeCast.toUint((x >> r) > 0xff); } /** * @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; } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) /** * @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); } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (utils/Strings.sol) /** * @dev String operations. */ library Strings { using SafeCast for *; bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; uint256 private constant SPECIAL_CHARS_LOOKUP = (1 << 0x08) | // backspace (1 << 0x09) | // tab (1 << 0x0a) | // newline (1 << 0x0c) | // form feed (1 << 0x0d) | // carriage return (1 << 0x22) | // double quote (1 << 0x5c); // backslash /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev The string being parsed contains characters that are not in scope of the given base. */ error StringsInvalidChar(); /** * @dev The string being parsed is not a properly formatted address. */ error StringsInvalidAddressFormat(); /** * @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(add(buffer, 0x20), 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)); } /** * @dev Parse a decimal string and returns the value as a `uint256`. * * Requirements: * - The string must be formatted as `[0-9]*` * - The result must fit into an `uint256` type */ function parseUint(string memory input) internal pure returns (uint256) { return parseUint(input, 0, bytes(input).length); } /** * @dev Variant of {parseUint-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `[0-9]*` * - The result must fit into an `uint256` type */ function parseUint(string memory input, uint256 begin, uint256 end) internal pure returns (uint256) { (bool success, uint256 value) = tryParseUint(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseUint-string} that returns false if the parsing fails because of an invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseUint(string memory input) internal pure returns (bool success, uint256 value) { return _tryParseUintUncheckedBounds(input, 0, bytes(input).length); } /** * @dev Variant of {parseUint-string-uint256-uint256} that returns false if the parsing fails because of an invalid * character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseUint( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, uint256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseUintUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseUint-string-uint256-uint256} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseUintUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, uint256 value) { bytes memory buffer = bytes(input); uint256 result = 0; for (uint256 i = begin; i < end; ++i) { uint8 chr = _tryParseChr(bytes1(_unsafeReadBytesOffset(buffer, i))); if (chr > 9) return (false, 0); result *= 10; result += chr; } return (true, result); } /** * @dev Parse a decimal string and returns the value as a `int256`. * * Requirements: * - The string must be formatted as `[-+]?[0-9]*` * - The result must fit in an `int256` type. */ function parseInt(string memory input) internal pure returns (int256) { return parseInt(input, 0, bytes(input).length); } /** * @dev Variant of {parseInt-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `[-+]?[0-9]*` * - The result must fit in an `int256` type. */ function parseInt(string memory input, uint256 begin, uint256 end) internal pure returns (int256) { (bool success, int256 value) = tryParseInt(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseInt-string} that returns false if the parsing fails because of an invalid character or if * the result does not fit in a `int256`. * * NOTE: This function will revert if the absolute value of the result does not fit in a `uint256`. */ function tryParseInt(string memory input) internal pure returns (bool success, int256 value) { return _tryParseIntUncheckedBounds(input, 0, bytes(input).length); } uint256 private constant ABS_MIN_INT256 = 2 ** 255; /** * @dev Variant of {parseInt-string-uint256-uint256} that returns false if the parsing fails because of an invalid * character or if the result does not fit in a `int256`. * * NOTE: This function will revert if the absolute value of the result does not fit in a `uint256`. */ function tryParseInt( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, int256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseIntUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseInt-string-uint256-uint256} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseIntUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, int256 value) { bytes memory buffer = bytes(input); // Check presence of a negative sign. bytes1 sign = begin == end ? bytes1(0) : bytes1(_unsafeReadBytesOffset(buffer, begin)); // don't do out-of-bound (possibly unsafe) read if sub-string is empty bool positiveSign = sign == bytes1("+"); bool negativeSign = sign == bytes1("-"); uint256 offset = (positiveSign || negativeSign).toUint(); (bool absSuccess, uint256 absValue) = tryParseUint(input, begin + offset, end); if (absSuccess && absValue < ABS_MIN_INT256) { return (true, negativeSign ? -int256(absValue) : int256(absValue)); } else if (absSuccess && negativeSign && absValue == ABS_MIN_INT256) { return (true, type(int256).min); } else return (false, 0); } /** * @dev Parse a hexadecimal string (with or without "0x" prefix), and returns the value as a `uint256`. * * Requirements: * - The string must be formatted as `(0x)?[0-9a-fA-F]*` * - The result must fit in an `uint256` type. */ function parseHexUint(string memory input) internal pure returns (uint256) { return parseHexUint(input, 0, bytes(input).length); } /** * @dev Variant of {parseHexUint-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `(0x)?[0-9a-fA-F]*` * - The result must fit in an `uint256` type. */ function parseHexUint(string memory input, uint256 begin, uint256 end) internal pure returns (uint256) { (bool success, uint256 value) = tryParseHexUint(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseHexUint-string} that returns false if the parsing fails because of an invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseHexUint(string memory input) internal pure returns (bool success, uint256 value) { return _tryParseHexUintUncheckedBounds(input, 0, bytes(input).length); } /** * @dev Variant of {parseHexUint-string-uint256-uint256} that returns false if the parsing fails because of an * invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseHexUint( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, uint256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseHexUintUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseHexUint-string-uint256-uint256} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseHexUintUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, uint256 value) { bytes memory buffer = bytes(input); // skip 0x prefix if present bool hasPrefix = (end > begin + 1) && bytes2(_unsafeReadBytesOffset(buffer, begin)) == bytes2("0x"); // don't do out-of-bound (possibly unsafe) read if sub-string is empty uint256 offset = hasPrefix.toUint() * 2; uint256 result = 0; for (uint256 i = begin + offset; i < end; ++i) { uint8 chr = _tryParseChr(bytes1(_unsafeReadBytesOffset(buffer, i))); if (chr > 15) return (false, 0); result *= 16; unchecked { // Multiplying by 16 is equivalent to a shift of 4 bits (with additional overflow check). // This guarantees that adding a value < 16 will not cause an overflow, hence the unchecked. result += chr; } } return (true, result); } /** * @dev Parse a hexadecimal string (with or without "0x" prefix), and returns the value as an `address`. * * Requirements: * - The string must be formatted as `(0x)?[0-9a-fA-F]{40}` */ function parseAddress(string memory input) internal pure returns (address) { return parseAddress(input, 0, bytes(input).length); } /** * @dev Variant of {parseAddress-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `(0x)?[0-9a-fA-F]{40}` */ function parseAddress(string memory input, uint256 begin, uint256 end) internal pure returns (address) { (bool success, address value) = tryParseAddress(input, begin, end); if (!success) revert StringsInvalidAddressFormat(); return value; } /** * @dev Variant of {parseAddress-string} that returns false if the parsing fails because the input is not a properly * formatted address. See {parseAddress-string} requirements. */ function tryParseAddress(string memory input) internal pure returns (bool success, address value) { return tryParseAddress(input, 0, bytes(input).length); } /** * @dev Variant of {parseAddress-string-uint256-uint256} that returns false if the parsing fails because input is not a properly * formatted address. See {parseAddress-string-uint256-uint256} requirements. */ function tryParseAddress( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, address value) { if (end > bytes(input).length || begin > end) return (false, address(0)); bool hasPrefix = (end > begin + 1) && bytes2(_unsafeReadBytesOffset(bytes(input), begin)) == bytes2("0x"); // don't do out-of-bound (possibly unsafe) read if sub-string is empty uint256 expectedLength = 40 + hasPrefix.toUint() * 2; // check that input is the correct length if (end - begin == expectedLength) { // length guarantees that this does not overflow, and value is at most type(uint160).max (bool s, uint256 v) = _tryParseHexUintUncheckedBounds(input, begin, end); return (s, address(uint160(v))); } else { return (false, address(0)); } } function _tryParseChr(bytes1 chr) private pure returns (uint8) { uint8 value = uint8(chr); // Try to parse `chr`: // - Case 1: [0-9] // - Case 2: [a-f] // - Case 3: [A-F] // - otherwise not supported unchecked { if (value > 47 && value < 58) value -= 48; else if (value > 96 && value < 103) value -= 87; else if (value > 64 && value < 71) value -= 55; else return type(uint8).max; } return value; } /** * @dev Escape special characters in JSON strings. This can be useful to prevent JSON injection in NFT metadata. * * WARNING: This function should only be used in double quoted JSON strings. Single quotes are not escaped. * * NOTE: This function escapes all unicode characters, and not just the ones in ranges defined in section 2.5 of * RFC-4627 (U+0000 to U+001F, U+0022 and U+005C). ECMAScript's `JSON.parse` does recover escaped unicode * characters that are not in this range, but other tooling may provide different results. */ function escapeJSON(string memory input) internal pure returns (string memory) { bytes memory buffer = bytes(input); bytes memory output = new bytes(2 * buffer.length); // worst case scenario uint256 outputLength = 0; for (uint256 i; i < buffer.length; ++i) { bytes1 char = bytes1(_unsafeReadBytesOffset(buffer, i)); if (((SPECIAL_CHARS_LOOKUP & (1 << uint8(char))) != 0)) { output[outputLength++] = "\\"; if (char == 0x08) output[outputLength++] = "b"; else if (char == 0x09) output[outputLength++] = "t"; else if (char == 0x0a) output[outputLength++] = "n"; else if (char == 0x0c) output[outputLength++] = "f"; else if (char == 0x0d) output[outputLength++] = "r"; else if (char == 0x5c) output[outputLength++] = "\\"; else if (char == 0x22) { // solhint-disable-next-line quotes output[outputLength++] = '"'; } } else { output[outputLength++] = char; } } // write the actual length and deallocate unused memory assembly ("memory-safe") { mstore(output, outputLength) mstore(0x40, add(output, shl(5, shr(5, add(outputLength, 63))))) } return string(output); } /** * @dev Reads a bytes32 from a bytes array without bounds checking. * * NOTE: making this function internal would mean it could be used with memory unsafe offset, and marking the * assembly block as such would prevent some optimizations. */ function _unsafeReadBytesOffset(bytes memory buffer, uint256 offset) private pure returns (bytes32 value) { // This is not memory safe in the general case, but all calls to this private function are within bounds. assembly ("memory-safe") { value := mload(add(add(buffer, 0x20), offset)) } } } // File @openzeppelin/contracts/token/ERC721/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/ERC721.sol) /** * @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_; } /// @inheritdoc IERC165 function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /// @inheritdoc IERC721 function balanceOf(address owner) public view virtual returns (uint256) { if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return _balances[owner]; } /// @inheritdoc IERC721 function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /// @inheritdoc IERC721Metadata function name() public view virtual returns (string memory) { return _name; } /// @inheritdoc IERC721Metadata function symbol() public view virtual returns (string memory) { return _symbol; } /// @inheritdoc IERC721Metadata 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 ""; } /// @inheritdoc IERC721 function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /// @inheritdoc IERC721 function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /// @inheritdoc IERC721 function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /// @inheritdoc IERC721 function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { return _operatorApprovals[owner][operator]; } /// @inheritdoc IERC721 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); } } /// @inheritdoc IERC721 function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /// @inheritdoc IERC721 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; } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.3.0) (utils/cryptography/Hashes.sol) /** * @dev Library of standard hash functions. * * _Available since v5.1._ */ library Hashes { /** * @dev Commutative Keccak256 hash of a sorted pair of bytes32. Frequently used when working with merkle proofs. * * NOTE: Equivalent to the `standardNodeHash` in our https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. */ function commutativeKeccak256(bytes32 a, bytes32 b) internal pure returns (bytes32) { return a < b ? efficientKeccak256(a, b) : efficientKeccak256(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function efficientKeccak256(bytes32 a, bytes32 b) internal pure returns (bytes32 value) { assembly ("memory-safe") { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } // File @openzeppelin/contracts/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MerkleProof.sol) // This file was procedurally generated from scripts/generate/templates/MerkleProof.js. /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. * * IMPORTANT: Consider memory side-effects when using custom hashing functions * that access memory in an unsafe way. * * NOTE: This library supports proof verification for merkle trees built using * custom _commutative_ hashing functions (i.e. `H(a, b) == H(b, a)`). Proving * leaf inclusion in trees built using non-commutative hashing functions requires * additional logic that is not supported by this library. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. * * This version handles proofs in memory with the default hashing function. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leaves & pre-images are assumed to be sorted. * * This version handles proofs in memory with the default hashing function. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. * * This version handles proofs in memory with a custom hashing function. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processProof(proof, leaf, hasher) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leaves & pre-images are assumed to be sorted. * * This version handles proofs in memory with a custom hashing function. */ function processProof( bytes32[] memory proof, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = hasher(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. * * This version handles proofs in calldata with the default hashing function. */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leaves & pre-images are assumed to be sorted. * * This version handles proofs in calldata with the default hashing function. */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. * * This version handles proofs in calldata with a custom hashing function. */ function verifyCalldata( bytes32[] calldata proof, bytes32 root, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processProofCalldata(proof, leaf, hasher) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leaves & pre-images are assumed to be sorted. * * This version handles proofs in calldata with a custom hashing function. */ function processProofCalldata( bytes32[] calldata proof, bytes32 leaf, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = hasher(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * This version handles multiproofs in memory with the default hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProof}. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * This version handles multiproofs in memory with the default hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](proofFlagsLen); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = Hashes.commutativeKeccak256(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * This version handles multiproofs in memory with a custom hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProof}. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processMultiProof(proof, proofFlags, leaves, hasher) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * This version handles multiproofs in memory with a custom hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](proofFlagsLen); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = hasher(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * This version handles multiproofs in calldata with the default hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProofCalldata}. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * This version handles multiproofs in calldata with the default hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](proofFlagsLen); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = Hashes.commutativeKeccak256(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * This version handles multiproofs in calldata with a custom hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. * * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`. * The `leaves` must be validated independently. See {processMultiProofCalldata}. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves, hasher) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * This version handles multiproofs in calldata with a custom hashing function. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op, * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not * validating the leaves elsewhere. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves, function(bytes32, bytes32) view returns (bytes32) hasher ) internal view returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofFlagsLen = proofFlags.length; // Check proof validity. if (leavesLen + proof.length != proofFlagsLen + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](proofFlagsLen); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < proofFlagsLen; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = hasher(a, b); } if (proofFlagsLen > 0) { if (proofPos != proof.length) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[proofFlagsLen - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol) /** * @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 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()); } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } } // File contracts/phasedNFT.sol // Original license: SPDX_License_Identifier: MIT /* _____ _ ______ _ _ / ____|| | | ____| (_) | | | |/ ___ | |__ __ _ _ __ ___ _| |_ _ | | / __| | __/ _` | '_ ` _ \| | | | | | | |____ \__ \ | | | (_| | | | | | | | | |_| | \_____| |___/ |_| \__,_|_| |_| |_|_|_|\__, | __/ | |___/ */ contract MonadPhasedNFT is ERC721, ERC2981, Ownable, ReentrancyGuard, Pausable { uint256 public constant MAX_SUPPLY = 1500; uint256 private _tokenIdTracker; // starts at 0 struct Phase { uint256 price; // price in MON (18 decimals) bytes32 root; // Merkle root (=0 means Public phase) uint32 cap; // phase cap uint32 minted; // cumulative minted in this phase (monotonic) uint32 maxPerTx; // per-transaction cap uint64 startTime; // active in [start, end) uint64 endTime; } Phase[3] public phases; // 0:WL 1:FCFS 2:PUB // Per-address cumulative mints per phase mapping(uint8 => mapping(address => uint256)) public mintedPerPhase; // Per-address cap for Public phase (applies when root == 0) uint256 public publicMaxPerAddress = 5; // Bypass role toggled by owner (skips per-address caps only) mapping(address => bool) public isBypass; // Payout address for withdrawals address public payout; string private _baseTokenURI; string private _contractURI; /* -------- Events -------- */ event PhaseConfigured( uint8 indexed phaseId, uint256 price, bytes32 root, uint32 cap, uint32 maxPerTx, uint64 startTime, uint64 endTime ); event PhaseTimeUpdated(uint8 indexed phaseId, uint64 startTime, uint64 endTime, uint32 maxPerTx); event BatchMinted(address indexed to, uint8 indexed phaseId, uint256 quantity, uint256 firstTokenId); event PublicMaxPerAddressUpdated(uint256 oldValue, uint256 newValue); event BypassSet(address indexed account, bool enabled); event PayoutUpdated(address indexed oldPayout, address indexed newPayout); event Withdraw(address indexed to, uint256 amount); constructor( string memory name_, string memory symbol_, string memory baseURI_, string memory contractURI_, address royaltyReceiver_, uint96 royaltyBps_, address initialOwner_ ) ERC721(name_, symbol_) Ownable(initialOwner_) { _baseTokenURI = baseURI_; _contractURI = contractURI_; _setDefaultRoyalty(royaltyReceiver_, royaltyBps_); payout = initialOwner_; } /* ---------- internal utils ---------- */ modifier validPhase(uint8 id) { require(id < 3, "bad phase"); _; } // Leaf schema: keccak256(abi.encodePacked(address, maxAllowed)) function _leaf(address a, uint256 maxAmount) internal pure returns (bytes32) { return keccak256(abi.encodePacked(a, maxAmount)); } function _isPhaseActive(uint8 id) internal view returns (bool) { Phase memory p = phases[id]; // [start, end); end is exclusive return block.timestamp >= p.startTime && block.timestamp < p.endTime; } function _min(uint256 a, uint256 b) private pure returns (uint256) { return a < b ? a : b; } // (Mainnet) No transfer pause switch here by design /* ---------- Public Mint Functions ---------- */ /** * @notice Unified mint for WL/FCFS/Public phases * @param id 0:WL, 1:FCFS, 2:PUBLIC * @param quantity quantity to mint * @param maxAllowed maximum allocation registered in Merkle (unused for Public; pass 0) * @param proof Merkle proof (empty for Public) */ function mint( uint8 id, uint256 quantity, uint256 maxAllowed, bytes32[] calldata proof ) external payable nonReentrant validPhase(id) whenNotPaused returns (uint256) { require(quantity > 0, "zero quantity"); Phase storage p = phases[id]; require(_isPhaseActive(id), "phase not active"); require(quantity <= p.maxPerTx, "exceeds max per tx"); require(p.minted + quantity <= p.cap, "phase sold out"); require(_tokenIdTracker + quantity <= MAX_SUPPLY, "exceeds max supply"); uint256 cost = p.price * quantity; require(msg.value >= cost, "insufficient payment"); // WL/FCFS (root != 0): require valid proof & per-address allocation if (p.root != bytes32(0)) { require( MerkleProof.verifyCalldata(proof, p.root, _leaf(msg.sender, maxAllowed)), "not whitelisted" ); if (!isBypass[msg.sender]) { require(mintedPerPhase[id][msg.sender] + quantity <= maxAllowed, "exceeds allowed"); } } else { // Public (root == 0): apply per-address cap (bypass excluded) if (!isBypass[msg.sender]) { require(mintedPerPhase[id][msg.sender] + quantity <= publicMaxPerAddress, "exceeds public per-address cap"); } } // Perform mint mintedPerPhase[id][msg.sender] += quantity; p.minted += uint32(quantity); uint256 firstTokenId = _tokenIdTracker; for (uint256 i = 0; i < quantity; ) { _safeMint(msg.sender, _tokenIdTracker); unchecked { _tokenIdTracker++; ++i; } } // Refund change if (msg.value > cost) { (bool rs, ) = payable(msg.sender).call{value: msg.value - cost}(""); require(rs, "refund failed"); } emit BatchMinted(msg.sender, id, quantity, firstTokenId); return firstTokenId; } /* ---------- owner ops ---------- */ /** * @notice Configure a phase (preserves existing minted count) */ function setPhase( uint8 id, uint256 price, bytes32 root, uint32 cap, uint32 maxPerTx, uint64 startTime, uint64 endTime ) external onlyOwner validPhase(id) { require(cap <= MAX_SUPPLY, "cap too big"); require(startTime < endTime, "invalid time range"); require(maxPerTx > 0 && maxPerTx <= MAX_SUPPLY, "invalid maxPerTx"); // Prevent reducing cap below already minted (safety) require(cap >= phases[id].minted, "cap < minted"); uint32 minted_ = phases[id].minted; phases[id] = Phase({ price: price, root: root, cap: cap, minted: minted_, maxPerTx: maxPerTx, startTime: startTime, endTime: endTime }); emit PhaseConfigured(id, price, root, cap, maxPerTx, startTime, endTime); } /** * @notice Update only start/end times and maxPerTx (UI convenience) */ function updatePhaseTimeAndMaxPerTx( uint8 id, uint64 startTime, uint64 endTime, uint32 maxPerTx ) external onlyOwner validPhase(id) { require(startTime < endTime, "invalid time range"); require(maxPerTx > 0 && maxPerTx <= MAX_SUPPLY, "invalid maxPerTx"); phases[id].startTime = startTime; phases[id].endTime = endTime; phases[id].maxPerTx = maxPerTx; emit PhaseTimeUpdated(id, startTime, endTime, maxPerTx); } /** Update Public per-address cap */ function setPublicMaxPerAddress(uint256 v) external onlyOwner { emit PublicMaxPerAddressUpdated(publicMaxPerAddress, v); publicMaxPerAddress = v; } /** Toggle bypass role (allows skipping per-address caps) */ function setBypass(address account, bool enabled) external onlyOwner { isBypass[account] = enabled; emit BypassSet(account, enabled); } /** Owner batch mint (ignores phases; still checks global max supply) */ function ownerBatchMint(address to, uint256 quantity) external onlyOwner nonReentrant { require(quantity > 0, "zero quantity"); require(_tokenIdTracker + quantity <= MAX_SUPPLY, "exceeds max supply"); uint256 firstTokenId = _tokenIdTracker; for (uint256 i = 0; i < quantity; ) { _safeMint(to, _tokenIdTracker); unchecked { _tokenIdTracker++; ++i; } } emit BatchMinted(to, 255, quantity, firstTokenId); // phaseId=255 indicates owner mint } function setBaseURI(string calldata u) external onlyOwner { _baseTokenURI = u; } function setContractURI(string calldata u) external onlyOwner { _contractURI = u; } /* ---------- Withdraw (supports both pull/push) ---------- */ function setPayout(address p) external onlyOwner { emit PayoutUpdated(payout, p); payout = p; } function withdrawAll() external onlyOwner nonReentrant { uint256 amount = address(this).balance; require(amount > 0, "no funds"); address to = payout == address(0) ? owner() : payout; (bool ok, ) = payable(to).call{value: amount}(""); require(ok, "withdraw failed"); emit Withdraw(to, amount); } function withdrawAmount(uint256 amount) external onlyOwner nonReentrant { require(amount > 0 && amount <= address(this).balance, "bad amount"); address to = payout == address(0) ? owner() : payout; (bool ok, ) = payable(to).call{value: amount}(""); require(ok, "withdraw failed"); emit Withdraw(to, amount); } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } /* ---------- views ---------- */ function _baseURI() internal view override returns (string memory) { return _baseTokenURI; } function contractURI() external view returns (string memory) { return _contractURI; } function totalSupply() external view returns (uint256) { return _tokenIdTracker; } function supportsInterface(bytes4 x) public view override(ERC721, ERC2981) returns (bool) { return super.supportsInterface(x); } /** Returns currently active phase IDs */ function getActivePhases() external view returns (uint8[] memory) { uint8[] memory tmp = new uint8[](3); uint8 count = 0; for (uint8 i = 0; i < 3; i++) { if (_isPhaseActive(i)) tmp[count++] = i; } uint8[] memory result = new uint8[](count); for (uint8 j = 0; j < count; j++) result[j] = tmp[j]; return result; } /** UI helper: returns remaining mintable amount considering supply/phase cap/per-address caps */ function getRemainingMints( uint8 phaseId, address user, uint256 maxAllowed ) external view validPhase(phaseId) returns (uint256) { Phase memory p = phases[phaseId]; uint256 phaseRemaining = p.cap > p.minted ? p.cap - p.minted : 0; uint256 supplyRemaining = MAX_SUPPLY > _tokenIdTracker ? MAX_SUPPLY - _tokenIdTracker : 0; uint256 hardRemaining = _min(phaseRemaining, supplyRemaining); if (p.root == bytes32(0)) { if (isBypass[user]) return hardRemaining; uint256 perAddrLeft = publicMaxPerAddress > mintedPerPhase[phaseId][user] ? publicMaxPerAddress - mintedPerPhase[phaseId][user] : 0; return _min(hardRemaining, _min(p.maxPerTx, perAddrLeft)); } else { uint256 minted_ = mintedPerPhase[phaseId][user]; uint256 allow = maxAllowed > minted_ ? maxAllowed - minted_ : 0; if (isBypass[user]) return _min(hardRemaining, p.maxPerTx); return _min(hardRemaining, _min(p.maxPerTx, allow)); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"string","name":"baseURI_","type":"string"},{"internalType":"string","name":"contractURI_","type":"string"},{"internalType":"address","name":"royaltyReceiver_","type":"address"},{"internalType":"uint96","name":"royaltyBps_","type":"uint96"},{"internalType":"address","name":"initialOwner_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","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":[],"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"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","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":"to","type":"address"},{"indexed":true,"internalType":"uint8","name":"phaseId","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"firstTokenId","type":"uint256"}],"name":"BatchMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"BypassSet","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":"oldPayout","type":"address"},{"indexed":true,"internalType":"address","name":"newPayout","type":"address"}],"name":"PayoutUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"phaseId","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"cap","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"maxPerTx","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"startTime","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"endTime","type":"uint64"}],"name":"PhaseConfigured","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"phaseId","type":"uint8"},{"indexed":false,"internalType":"uint64","name":"startTime","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"endTime","type":"uint64"},{"indexed":false,"internalType":"uint32","name":"maxPerTx","type":"uint32"}],"name":"PhaseTimeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"PublicMaxPerAddressUpdated","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","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":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getActivePhases","outputs":[{"internalType":"uint8[]","name":"","type":"uint8[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"phaseId","type":"uint8"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"maxAllowed","type":"uint256"}],"name":"getRemainingMints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBypass","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"id","type":"uint8"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"maxAllowed","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"address","name":"","type":"address"}],"name":"mintedPerPhase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"ownerBatchMint","outputs":[],"stateMutability":"nonpayable","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":[],"name":"payout","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"phases","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"uint32","name":"cap","type":"uint32"},{"internalType":"uint32","name":"minted","type":"uint32"},{"internalType":"uint32","name":"maxPerTx","type":"uint32"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicMaxPerAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","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":"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":"u","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setBypass","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"u","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"p","type":"address"}],"name":"setPayout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"id","type":"uint8"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"uint32","name":"cap","type":"uint32"},{"internalType":"uint32","name":"maxPerTx","type":"uint32"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"name":"setPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"v","type":"uint256"}],"name":"setPublicMaxPerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"x","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"id","type":"uint8"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"},{"internalType":"uint32","name":"maxPerTx","type":"uint32"}],"name":"updatePhaseTimeAndMaxPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawAmount","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405260056016553480156200001657600080fd5b50604051620037b7380380620037b78339810160408190526200003991620002ea565b80878760006200004a83826200046c565b5060016200005982826200046c565b5050506001600160a01b0381166200008c57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200009781620000f4565b5060016009556019620000ab86826200046c565b50601a620000ba85826200046c565b50620000c7838362000146565b601880546001600160a01b0319166001600160a01b03929092169190911790555062000538945050505050565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127106001600160601b0382168110156200018757604051636f483d0960e01b81526001600160601b03831660048201526024810182905260440162000083565b6001600160a01b038316620001b357604051635b6cc80560e11b81526000600482015260240162000083565b50604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600655565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200021557600080fd5b81516001600160401b0380821115620002325762000232620001ed565b604051601f8301601f19908116603f011681019082821181831017156200025d576200025d620001ed565b81604052838152602092508660208588010111156200027b57600080fd5b600091505b838210156200029f578582018301518183018401529082019062000280565b6000602085830101528094505050505092915050565b80516001600160a01b0381168114620002cd57600080fd5b919050565b80516001600160601b0381168114620002cd57600080fd5b600080600080600080600060e0888a0312156200030657600080fd5b87516001600160401b03808211156200031e57600080fd5b6200032c8b838c0162000203565b985060208a01519150808211156200034357600080fd5b620003518b838c0162000203565b975060408a01519150808211156200036857600080fd5b620003768b838c0162000203565b965060608a01519150808211156200038d57600080fd5b506200039c8a828b0162000203565b945050620003ad60808901620002b5565b9250620003bd60a08901620002d2565b9150620003cd60c08901620002b5565b905092959891949750929550565b600181811c90821680620003f057607f821691505b6020821081036200041157634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000467576000816000526020600020601f850160051c81016020861015620004425750805b601f850160051c820191505b8181101562000463578281556001016200044e565b5050505b505050565b81516001600160401b03811115620004885762000488620001ed565b620004a081620004998454620003db565b8462000417565b602080601f831160018114620004d85760008415620004bf5750858301515b600019600386901b1c1916600185901b17855562000463565b600085815260208120601f198616915b828110156200050957888601518255948401946001909101908401620004e8565b5085821015620005285787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61326f80620005486000396000f3fe6080604052600436106102465760003560e01c8063703b9a6011610139578063a3ff39b2116100b6578063d64651381161007a578063d64651381461071f578063e8a3d4851461073f578063e985e9c514610754578063eae498fe14610774578063f2fde38b14610787578063f630b9cc146107a757600080fd5b8063a3ff39b21461066f578063b88d4fde1461068f578063c87b56dd146106af578063c8dfb948146106cf578063ce00399a146106ff57600080fd5b8063853828b6116100fd578063853828b6146105e75780638da5cb5b146105fc578063938e3d7b1461061a57806395d89b411461063a578063a22cb4651461064f57600080fd5b8063703b9a601461056757806370a0823114610587578063715018a6146105a75780638456cb59146105bc57806384baa57a146105d157600080fd5b806332cb6b0c116101c757806355f804b31161018b57806355f804b3146104cd5780635c975abb146104ed5780636352211e1461050557806363bd1d4a1461052557806365d51ce01461054557600080fd5b806332cb6b0c1461044257806336f5218f146104585780633f4ba83a1461047857806341a2c4a01461048d57806342842e0e146104ad57600080fd5b8063117d58b11161020e578063117d58b11461031c57806318160ddd1461036257806323b872dd146103775780632a55205a146103975780632e37eef6146103d657600080fd5b806301ffc9a71461024b5780630562b9f71461028057806306fdde03146102a2578063081812fc146102c4578063095ea7b3146102fc575b600080fd5b34801561025757600080fd5b5061026b610266366004612a19565b6107c7565b60405190151581526020015b60405180910390f35b34801561028c57600080fd5b506102a061029b366004612a36565b6107d8565b005b3480156102ae57600080fd5b506102b7610951565b6040516102779190612a9f565b3480156102d057600080fd5b506102e46102df366004612a36565b6109e3565b6040516001600160a01b039091168152602001610277565b34801561030857600080fd5b506102a0610317366004612ace565b610a0c565b34801561032857600080fd5b50610354610337366004612b09565b601560209081526000928352604080842090915290825290205481565b604051908152602001610277565b34801561036e57600080fd5b50600b54610354565b34801561038357600080fd5b506102a0610392366004612b3c565b610a1b565b3480156103a357600080fd5b506103b76103b2366004612b78565b610aa6565b604080516001600160a01b039093168352602083019190915201610277565b3480156103e257600080fd5b506103f66103f1366004612a36565b610b2b565b60408051978852602088019690965263ffffffff94851695870195909552918316606086015290911660808401526001600160401b0390811660a08401521660c082015260e001610277565b34801561044e57600080fd5b506103546105dc81565b34801561046457600080fd5b506102a0610473366004612b9a565b610b89565b34801561048457600080fd5b506102a0610bf0565b34801561049957600080fd5b506103546104a8366004612bd6565b610c02565b3480156104b957600080fd5b506102a06104c8366004612b3c565b610e8b565b3480156104d957600080fd5b506102a06104e8366004612bf4565b610eab565b3480156104f957600080fd5b50600a5460ff1661026b565b34801561051157600080fd5b506102e4610520366004612a36565b610ec0565b34801561053157600080fd5b506018546102e4906001600160a01b031681565b34801561055157600080fd5b5061055a610ecb565b6040516102779190612c65565b34801561057357600080fd5b506102a0610582366004612a36565b610ff4565b34801561059357600080fd5b506103546105a2366004612cac565b61103d565b3480156105b357600080fd5b506102a0611085565b3480156105c857600080fd5b506102a0611097565b3480156105dd57600080fd5b5061035460165481565b3480156105f357600080fd5b506102a06110a7565b34801561060857600080fd5b506008546001600160a01b03166102e4565b34801561062657600080fd5b506102a0610635366004612bf4565b611209565b34801561064657600080fd5b506102b761121e565b34801561065b57600080fd5b506102a061066a366004612b9a565b61122d565b34801561067b57600080fd5b506102a061068a366004612cac565b611238565b34801561069b57600080fd5b506102a06106aa366004612cdd565b61129c565b3480156106bb57600080fd5b506102b76106ca366004612a36565b6112b4565b3480156106db57600080fd5b5061026b6106ea366004612cac565b60176020526000908152604090205460ff1681565b34801561070b57600080fd5b506102a061071a366004612ace565b61131c565b34801561072b57600080fd5b506102a061073a366004612de3565b61143f565b34801561074b57600080fd5b506102b76117cf565b34801561076057600080fd5b5061026b61076f366004612e5b565b6117de565b610354610782366004612e77565b61180c565b34801561079357600080fd5b506102a06107a2366004612cac565b611d9e565b3480156107b357600080fd5b506102a06107c2366004612f0d565b611dd9565b60006107d282611fd4565b92915050565b6107e0611ff9565b6107e8612026565b6000811180156107f85750478111155b6108365760405162461bcd60e51b815260206004820152600a60248201526918985908185b5bdd5b9d60b21b60448201526064015b60405180910390fd5b6018546000906001600160a01b03161561085b576018546001600160a01b0316610868565b6008546001600160a01b03165b90506000816001600160a01b03168360405160006040518083038185875af1925050503d80600081146108b7576040519150601f19603f3d011682016040523d82523d6000602084013e6108bc565b606091505b50509050806108ff5760405162461bcd60e51b815260206004820152600f60248201526e1dda5d1a191c985dc819985a5b1959608a1b604482015260640161082d565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648460405161093a91815260200190565b60405180910390a2505061094e6001600955565b50565b60606000805461096090612f61565b80601f016020809104026020016040519081016040528092919081815260200182805461098c90612f61565b80156109d95780601f106109ae576101008083540402835291602001916109d9565b820191906000526020600020905b8154815290600101906020018083116109bc57829003601f168201915b5050505050905090565b60006109ee82612050565b506000828152600460205260409020546001600160a01b03166107d2565b610a17828233612089565b5050565b6001600160a01b038216610a4557604051633250574960e11b81526000600482015260240161082d565b6000610a52838333612096565b9050836001600160a01b0316816001600160a01b031614610aa0576040516364283d7b60e01b81526001600160a01b038086166004830152602482018490528216604482015260640161082d565b50505050565b600082815260076020526040812080548291906001600160a01b03811690600160a01b90046001600160601b031681610afa5750506006546001600160a01b03811690600160a01b90046001600160601b03165b6000612710610b126001600160601b03841689612fb1565b610b1c9190612fc8565b92989297509195505050505050565b600c8160038110610b3b57600080fd5b600302018054600182015460029092015490925063ffffffff808216916401000000008104821691600160401b820416906001600160401b03600160601b8204811691600160a01b90041687565b610b91611ff9565b6001600160a01b038216600081815260176020908152604091829020805460ff191685151590811790915591519182527fd03640d98b0343d23b7e20c91b5833f853f6d53f9bbbd535ddd459c74427440e910160405180910390a25050565b610bf8611ff9565b610c0061218f565b565b60008360038160ff1610610c285760405162461bcd60e51b815260040161082d90612fea565b6000600c8660ff1660038110610c4057610c4061300d565b6040805160e0810182526003929092029290920180548252600181015460208301526002015463ffffffff8082169383018490526401000000008204811660608401819052600160401b830490911660808401526001600160401b03600160601b8304811660a0850152600160a01b90920490911660c083015290925060009111610ccc576000610ce0565b81606001518260400151610ce09190613023565b63ffffffff1690506000600b546105dc11610cfc576000610d0b565b600b54610d0b906105dc613047565b90506000610d1983836121e1565b6020850151909150610de6576001600160a01b03881660009081526017602052604090205460ff1615610d51579450610e8392505050565b60ff891660009081526015602090815260408083206001600160a01b038c16845290915281205460165411610d87576000610dbb565b60ff8a1660009081526015602090815260408083206001600160a01b038d168452909152902054601654610dbb9190613047565b9050610dda82610dd5876080015163ffffffff16846121e1565b6121e1565b96505050505050610e83565b60ff891660009081526015602090815260408083206001600160a01b038c16845290915281205490818911610e1c576000610e26565b610e26828a613047565b6001600160a01b038b1660009081526017602052604090205490915060ff1615610e6b57610e5e83876080015163ffffffff166121e1565b9750505050505050610e83565b610e5e83610dd5886080015163ffffffff16846121e1565b509392505050565b610ea68383836040518060200160405280600081525061129c565b505050565b610eb3611ff9565b6019610ea68284836130a2565b60006107d282612050565b60408051600380825260808201909252606091600091906020820184803683370190505090506000805b60038160ff161015610f4d57610f0a816121f7565b15610f4557808383610f1b81613161565b945060ff1681518110610f3057610f3061300d565b602002602001019060ff16908160ff16815250505b600101610ef5565b5060008160ff166001600160401b03811115610f6b57610f6b612cc7565b604051908082528060200260200182016040528015610f94578160200160208202803683370190505b50905060005b8260ff168160ff161015610e8357838160ff1681518110610fbd57610fbd61300d565b6020026020010151828260ff1681518110610fda57610fda61300d565b60ff90921660209283029190910190910152600101610f9a565b610ffc611ff9565b60165460408051918252602082018390527f867ac10dcee483322104736741066d7b2e045ff2cd8b5bf86a6942c68a1f097d910160405180910390a1601655565b60006001600160a01b038216611069576040516322718ad960e21b81526000600482015260240161082d565b506001600160a01b031660009081526003602052604090205490565b61108d611ff9565b610c0060006122aa565b61109f611ff9565b610c006122fc565b6110af611ff9565b6110b7612026565b47806110f05760405162461bcd60e51b81526020600482015260086024820152676e6f2066756e647360c01b604482015260640161082d565b6018546000906001600160a01b031615611115576018546001600160a01b0316611122565b6008546001600160a01b03165b90506000816001600160a01b03168360405160006040518083038185875af1925050503d8060008114611171576040519150601f19603f3d011682016040523d82523d6000602084013e611176565b606091505b50509050806111b95760405162461bcd60e51b815260206004820152600f60248201526e1dda5d1a191c985dc819985a5b1959608a1b604482015260640161082d565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364846040516111f491815260200190565b60405180910390a2505050610c006001600955565b611211611ff9565b601a610ea68284836130a2565b60606001805461096090612f61565b610a17338383612339565b611240611ff9565b6018546040516001600160a01b038084169216907f0f5e7e8f9a21dde5bc3248632fb614300e3f87c62f100f2fcb76caaedd73160390600090a3601880546001600160a01b0319166001600160a01b0392909216919091179055565b6112a7848484610a1b565b610aa033858585856123d8565b60606112bf82612050565b5060006112ca612503565b905060008151116112ea5760405180602001604052806000815250611315565b806112f484612512565b604051602001611305929190613180565b6040516020818303038152906040525b9392505050565b611324611ff9565b61132c612026565b6000811161136c5760405162461bcd60e51b815260206004820152600d60248201526c7a65726f207175616e7469747960981b604482015260640161082d565b6105dc81600b5461137d91906131af565b11156113c05760405162461bcd60e51b815260206004820152601260248201527165786365656473206d617820737570706c7960701b604482015260640161082d565b600b5460005b828110156113ec576113da84600b546125a4565b600b80546001908101909155016113c6565b50604080518381526020810183905260ff916001600160a01b038616917f5caa6bf9ed311b4e238359cf2d0c26f41c16c290725102566b24ac9e46db8c21910160405180910390a350610a176001600955565b611447611ff9565b8660038160ff161061146b5760405162461bcd60e51b815260040161082d90612fea565b6105dc8563ffffffff1611156114b15760405162461bcd60e51b815260206004820152600b60248201526a63617020746f6f2062696760a81b604482015260640161082d565b816001600160401b0316836001600160401b0316106115075760405162461bcd60e51b8152602060048201526012602482015271696e76616c69642074696d652072616e676560701b604482015260640161082d565b60008463ffffffff1611801561152557506105dc8463ffffffff1611155b6115645760405162461bcd60e51b815260206004820152601060248201526f0d2dcecc2d8d2c840dac2f0a0cae4a8f60831b604482015260640161082d565b600c8860ff166003811061157a5761157a61300d565b6003020160020160049054906101000a900463ffffffff1663ffffffff168563ffffffff1610156115dc5760405162461bcd60e51b815260206004820152600c60248201526b18d85c080f081b5a5b9d195960a21b604482015260640161082d565b6000600c8960ff16600381106115f4576115f461300d565b6003020160020160049054906101000a900463ffffffff1690506040518060e001604052808981526020018881526020018763ffffffff1681526020018263ffffffff1681526020018663ffffffff168152602001856001600160401b03168152602001846001600160401b0316815250600c8a60ff166003811061167b5761167b61300d565b82516003919091029190910190815560208201516001820155604080830151600290920180546060850151608086015160a087015160c0909701516001600160401b03908116600160a01b0267ffffffffffffffff60a01b1991909816600160601b0267ffffffffffffffff60601b1963ffffffff938416600160401b021673ffffffffffffffffffffffff0000000000000000199484166401000000000267ffffffffffffffff19909616939098169290921793909317919091169490941793909317929092169290921790555160ff8a16907fa7a14b1873603bfd03a04ac247ce96a62ea1eb7667a840e1ee7101d9892b567d906117bc908b908b908b908b908b908b90958652602086019490945263ffffffff9283166040860152911660608401526001600160401b0390811660808401521660a082015260c00190565b60405180910390a2505050505050505050565b6060601a805461096090612f61565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6000611816612026565b8560038160ff161061183a5760405162461bcd60e51b815260040161082d90612fea565b6118426125be565b600086116118825760405162461bcd60e51b815260206004820152600d60248201526c7a65726f207175616e7469747960981b604482015260640161082d565b6000600c8860ff166003811061189a5761189a61300d565b6003020190506118a9886121f7565b6118e85760405162461bcd60e51b815260206004820152601060248201526f7068617365206e6f742061637469766560801b604482015260640161082d565b6002810154600160401b900463ffffffff1687111561193e5760405162461bcd60e51b81526020600482015260126024820152710caf0c6cacac8e640dac2f040e0cae440e8f60731b604482015260640161082d565b600281015463ffffffff80821691611960918a916401000000009004166131af565b111561199f5760405162461bcd60e51b815260206004820152600e60248201526d1c1a185cd9481cdbdb19081bdd5d60921b604482015260640161082d565b6105dc87600b546119b091906131af565b11156119f35760405162461bcd60e51b815260206004820152601260248201527165786365656473206d617820737570706c7960701b604482015260640161082d565b8054600090611a03908990612fb1565b905080341015611a4c5760405162461bcd60e51b81526020600482015260146024820152731a5b9cdd59999a58da595b9d081c185e5b595b9d60621b604482015260640161082d565b600182015415611b7657611ab186868460010154611aac338c6040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b6125e2565b611aef5760405162461bcd60e51b815260206004820152600f60248201526e1b9bdd081dda1a5d195b1a5cdd1959608a1b604482015260640161082d565b3360009081526017602052604090205460ff16611b715760ff891660009081526015602090815260408083203384529091529020548790611b31908a906131af565b1115611b715760405162461bcd60e51b815260206004820152600f60248201526e195e18d959591cc8185b1b1bddd959608a1b604482015260640161082d565b611c07565b3360009081526017602052604090205460ff16611c075760165460ff8a166000908152601560209081526040808320338452909152902054611bb9908a906131af565b1115611c075760405162461bcd60e51b815260206004820152601e60248201527f65786365656473207075626c6963207065722d61646472657373206361700000604482015260640161082d565b60ff89166000908152601560209081526040808320338452909152812080548a9290611c349084906131af565b9091555050600282018054899190600490611c5e908490640100000000900463ffffffff166131c2565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000600b54905060005b89811015611cac57611c9a33600b546125a4565b600b8054600190810190915501611c86565b5081341115611d4657600033611cc28434613047565b604051600081818185875af1925050503d8060008114611cfe576040519150601f19603f3d011682016040523d82523d6000602084013e611d03565b606091505b5050905080611d445760405162461bcd60e51b815260206004820152600d60248201526c1c99599d5b990819985a5b1959609a1b604482015260640161082d565b505b604080518a81526020810183905260ff8c169133917f5caa6bf9ed311b4e238359cf2d0c26f41c16c290725102566b24ac9e46db8c21910160405180910390a39350505050611d956001600955565b95945050505050565b611da6611ff9565b6001600160a01b038116611dd057604051631e4fbdf760e01b81526000600482015260240161082d565b61094e816122aa565b611de1611ff9565b8360038160ff1610611e055760405162461bcd60e51b815260040161082d90612fea565b826001600160401b0316846001600160401b031610611e5b5760405162461bcd60e51b8152602060048201526012602482015271696e76616c69642074696d652072616e676560701b604482015260640161082d565b60008263ffffffff16118015611e7957506105dc8263ffffffff1611155b611eb85760405162461bcd60e51b815260206004820152601060248201526f0d2dcecc2d8d2c840dac2f0a0cae4a8f60831b604482015260640161082d565b83600c8660ff1660038110611ecf57611ecf61300d565b60030201600201600c6101000a8154816001600160401b0302191690836001600160401b0316021790555082600c8660ff1660038110611f1157611f1161300d565b6003020160020160146101000a8154816001600160401b0302191690836001600160401b0316021790555081600c8660ff1660038110611f5357611f5361300d565b6003020160020180546bffffffff00000000000000001916600160401b63ffffffff93841602179055604080516001600160401b038781168252861660208201529184169082015260ff8616907f5d1e2e3ecfa285af2d281f7543996b3e01182217f3d98417b3b70054b00bcfc79060600160405180910390a25050505050565b60006001600160e01b0319821663152a902d60e11b14806107d257506107d2826125fa565b6008546001600160a01b03163314610c005760405163118cdaa760e01b815233600482015260240161082d565b60026009540361204957604051633ee5aeb560e01b815260040160405180910390fd5b6002600955565b6000818152600260205260408120546001600160a01b0316806107d257604051637e27328960e01b81526004810184905260240161082d565b610ea6838383600161264a565b6000828152600260205260408120546001600160a01b03908116908316156120c3576120c3818486612750565b6001600160a01b03811615612101576120e060008560008061264a565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615612130576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6121976127b4565b600a805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60008183106121f05781611315565b5090919050565b600080600c8360ff16600381106122105761221061300d565b6040805160e0810182526003929092029290920180548252600181015460208301526002015463ffffffff80821693830193909352640100000000810483166060830152600160401b810490921660808201526001600160401b03600160601b8304811660a08301819052600160a01b9093041660c082015291504210801590611315575060c001516001600160401b0316421092915050565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6123046125be565b600a805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586121c43390565b6001600160a01b03821661236b57604051630b61174360e31b81526001600160a01b038316600482015260240161082d565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b156124fc57604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061241a9088908890879087906004016131df565b6020604051808303816000875af1925050508015612455575060408051601f3d908101601f191682019092526124529181019061321c565b60015b6124be573d808015612483576040519150601f19603f3d011682016040523d82523d6000602084013e612488565b606091505b5080516000036124b657604051633250574960e11b81526001600160a01b038516600482015260240161082d565b805160208201fd5b6001600160e01b03198116630a85bd0160e11b146124fa57604051633250574960e11b81526001600160a01b038516600482015260240161082d565b505b5050505050565b60606019805461096090612f61565b6060600061251f836127d7565b60010190506000816001600160401b0381111561253e5761253e612cc7565b6040519080825280601f01601f191660200182016040528015612568576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461257257509392505050565b610a178282604051806020016040528060008152506128af565b600a5460ff1615610c005760405163d93c066560e01b815260040160405180910390fd5b6000826125f08686856128c7565b1495945050505050565b60006001600160e01b031982166380ac58cd60e01b148061262b57506001600160e01b03198216635b5e139f60e01b145b806107d257506301ffc9a760e01b6001600160e01b03198316146107d2565b808061265e57506001600160a01b03821615155b1561272057600061266e84612050565b90506001600160a01b0383161580159061269a5750826001600160a01b0316816001600160a01b031614155b80156126ad57506126ab81846117de565b155b156126d65760405163a9fbf51f60e01b81526001600160a01b038416600482015260240161082d565b811561271e5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b61275b838383612909565b610ea6576001600160a01b03831661278957604051637e27328960e01b81526004810182905260240161082d565b60405163177e802f60e01b81526001600160a01b03831660048201526024810182905260440161082d565b600a5460ff16610c0057604051638dfc202b60e01b815260040160405180910390fd5b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106128165772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612842576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061286057662386f26fc10000830492506010015b6305f5e1008310612878576305f5e100830492506008015b612710831061288c57612710830492506004015b6064831061289e576064830492506002015b600a83106107d25760010192915050565b6128b9838361296f565b610ea63360008585856123d8565b600081815b84811015612900576128f6828787848181106128ea576128ea61300d565b905060200201356129d4565b91506001016128cc565b50949350505050565b60006001600160a01b038316158015906129675750826001600160a01b0316846001600160a01b03161480612943575061294384846117de565b8061296757506000828152600460205260409020546001600160a01b038481169116145b949350505050565b6001600160a01b03821661299957604051633250574960e11b81526000600482015260240161082d565b60006129a783836000612096565b90506001600160a01b03811615610ea6576040516339e3563760e11b81526000600482015260240161082d565b60008183106129f0576000828152602084905260409020611315565b6000838152602083905260409020611315565b6001600160e01b03198116811461094e57600080fd5b600060208284031215612a2b57600080fd5b813561131581612a03565b600060208284031215612a4857600080fd5b5035919050565b60005b83811015612a6a578181015183820152602001612a52565b50506000910152565b60008151808452612a8b816020860160208601612a4f565b601f01601f19169290920160200192915050565b6020815260006113156020830184612a73565b80356001600160a01b0381168114612ac957600080fd5b919050565b60008060408385031215612ae157600080fd5b612aea83612ab2565b946020939093013593505050565b803560ff81168114612ac957600080fd5b60008060408385031215612b1c57600080fd5b612b2583612af8565b9150612b3360208401612ab2565b90509250929050565b600080600060608486031215612b5157600080fd5b612b5a84612ab2565b9250612b6860208501612ab2565b9150604084013590509250925092565b60008060408385031215612b8b57600080fd5b50508035926020909101359150565b60008060408385031215612bad57600080fd5b612bb683612ab2565b915060208301358015158114612bcb57600080fd5b809150509250929050565b600080600060608486031215612beb57600080fd5b612b5a84612af8565b60008060208385031215612c0757600080fd5b82356001600160401b0380821115612c1e57600080fd5b818501915085601f830112612c3257600080fd5b813581811115612c4157600080fd5b866020828501011115612c5357600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b81811015612ca057835160ff1683529284019291840191600101612c81565b50909695505050505050565b600060208284031215612cbe57600080fd5b61131582612ab2565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612cf357600080fd5b612cfc85612ab2565b9350612d0a60208601612ab2565b92506040850135915060608501356001600160401b0380821115612d2d57600080fd5b818701915087601f830112612d4157600080fd5b813581811115612d5357612d53612cc7565b604051601f8201601f19908116603f01168101908382118183101715612d7b57612d7b612cc7565b816040528281528a6020848701011115612d9457600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b803563ffffffff81168114612ac957600080fd5b80356001600160401b0381168114612ac957600080fd5b600080600080600080600060e0888a031215612dfe57600080fd5b612e0788612af8565b96506020880135955060408801359450612e2360608901612db8565b9350612e3160808901612db8565b9250612e3f60a08901612dcc565b9150612e4d60c08901612dcc565b905092959891949750929550565b60008060408385031215612e6e57600080fd5b612b2583612ab2565b600080600080600060808688031215612e8f57600080fd5b612e9886612af8565b9450602086013593506040860135925060608601356001600160401b0380821115612ec257600080fd5b818801915088601f830112612ed657600080fd5b813581811115612ee557600080fd5b8960208260051b8501011115612efa57600080fd5b9699959850939650602001949392505050565b60008060008060808587031215612f2357600080fd5b612f2c85612af8565b9350612f3a60208601612dcc565b9250612f4860408601612dcc565b9150612f5660608601612db8565b905092959194509250565b600181811c90821680612f7557607f821691505b602082108103612f9557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176107d2576107d2612f9b565b600082612fe557634e487b7160e01b600052601260045260246000fd5b500490565b60208082526009908201526862616420706861736560b81b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b63ffffffff82811682821603908082111561304057613040612f9b565b5092915050565b818103818111156107d2576107d2612f9b565b601f821115610ea6576000816000526020600020601f850160051c810160208610156130835750805b601f850160051c820191505b818110156124fa5782815560010161308f565b6001600160401b038311156130b9576130b9612cc7565b6130cd836130c78354612f61565b8361305a565b6000601f84116001811461310157600085156130e95750838201355b600019600387901b1c1916600186901b1783556124fc565b600083815260209020601f19861690835b828110156131325786850135825560209485019460019092019101613112565b508682101561314f5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600060ff821660ff810361317757613177612f9b565b60010192915050565b60008351613192818460208801612a4f565b8351908301906131a6818360208801612a4f565b01949350505050565b808201808211156107d2576107d2612f9b565b63ffffffff81811683821601908082111561304057613040612f9b565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061321290830184612a73565b9695505050505050565b60006020828403121561322e57600080fd5b815161131581612a0356fea26469706673582212201d4381b6db6d68d26ac1d53ea4139973e3f66c7a3b2882fed820ecdc10f4614264736f6c6343000817003300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000ab2967a1c1bc427f08cba864a841746c8eaa6d0500000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000ab2967a1c1bc427f08cba864a841746c8eaa6d050000000000000000000000000000000000000000000000000000000000000008432046616d696c7900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044346414d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005268747470733a2f2f6261667962656964716633646a6d6c79346775726370717a757835696c6a7376706d34726663786e657164657a377569646b6a71366c32656c66712e697066732e7733732e6c696e6b2f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006568747470733a2f2f62616679626569636c616867756b32366968327561776a68777833726978686567616561747a6371716e64707767706f686678347a6a65766d34652e697066732e7733732e6c696e6b2f632d636f6e74726163742d7572692e6a736f6e000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102465760003560e01c8063703b9a6011610139578063a3ff39b2116100b6578063d64651381161007a578063d64651381461071f578063e8a3d4851461073f578063e985e9c514610754578063eae498fe14610774578063f2fde38b14610787578063f630b9cc146107a757600080fd5b8063a3ff39b21461066f578063b88d4fde1461068f578063c87b56dd146106af578063c8dfb948146106cf578063ce00399a146106ff57600080fd5b8063853828b6116100fd578063853828b6146105e75780638da5cb5b146105fc578063938e3d7b1461061a57806395d89b411461063a578063a22cb4651461064f57600080fd5b8063703b9a601461056757806370a0823114610587578063715018a6146105a75780638456cb59146105bc57806384baa57a146105d157600080fd5b806332cb6b0c116101c757806355f804b31161018b57806355f804b3146104cd5780635c975abb146104ed5780636352211e1461050557806363bd1d4a1461052557806365d51ce01461054557600080fd5b806332cb6b0c1461044257806336f5218f146104585780633f4ba83a1461047857806341a2c4a01461048d57806342842e0e146104ad57600080fd5b8063117d58b11161020e578063117d58b11461031c57806318160ddd1461036257806323b872dd146103775780632a55205a146103975780632e37eef6146103d657600080fd5b806301ffc9a71461024b5780630562b9f71461028057806306fdde03146102a2578063081812fc146102c4578063095ea7b3146102fc575b600080fd5b34801561025757600080fd5b5061026b610266366004612a19565b6107c7565b60405190151581526020015b60405180910390f35b34801561028c57600080fd5b506102a061029b366004612a36565b6107d8565b005b3480156102ae57600080fd5b506102b7610951565b6040516102779190612a9f565b3480156102d057600080fd5b506102e46102df366004612a36565b6109e3565b6040516001600160a01b039091168152602001610277565b34801561030857600080fd5b506102a0610317366004612ace565b610a0c565b34801561032857600080fd5b50610354610337366004612b09565b601560209081526000928352604080842090915290825290205481565b604051908152602001610277565b34801561036e57600080fd5b50600b54610354565b34801561038357600080fd5b506102a0610392366004612b3c565b610a1b565b3480156103a357600080fd5b506103b76103b2366004612b78565b610aa6565b604080516001600160a01b039093168352602083019190915201610277565b3480156103e257600080fd5b506103f66103f1366004612a36565b610b2b565b60408051978852602088019690965263ffffffff94851695870195909552918316606086015290911660808401526001600160401b0390811660a08401521660c082015260e001610277565b34801561044e57600080fd5b506103546105dc81565b34801561046457600080fd5b506102a0610473366004612b9a565b610b89565b34801561048457600080fd5b506102a0610bf0565b34801561049957600080fd5b506103546104a8366004612bd6565b610c02565b3480156104b957600080fd5b506102a06104c8366004612b3c565b610e8b565b3480156104d957600080fd5b506102a06104e8366004612bf4565b610eab565b3480156104f957600080fd5b50600a5460ff1661026b565b34801561051157600080fd5b506102e4610520366004612a36565b610ec0565b34801561053157600080fd5b506018546102e4906001600160a01b031681565b34801561055157600080fd5b5061055a610ecb565b6040516102779190612c65565b34801561057357600080fd5b506102a0610582366004612a36565b610ff4565b34801561059357600080fd5b506103546105a2366004612cac565b61103d565b3480156105b357600080fd5b506102a0611085565b3480156105c857600080fd5b506102a0611097565b3480156105dd57600080fd5b5061035460165481565b3480156105f357600080fd5b506102a06110a7565b34801561060857600080fd5b506008546001600160a01b03166102e4565b34801561062657600080fd5b506102a0610635366004612bf4565b611209565b34801561064657600080fd5b506102b761121e565b34801561065b57600080fd5b506102a061066a366004612b9a565b61122d565b34801561067b57600080fd5b506102a061068a366004612cac565b611238565b34801561069b57600080fd5b506102a06106aa366004612cdd565b61129c565b3480156106bb57600080fd5b506102b76106ca366004612a36565b6112b4565b3480156106db57600080fd5b5061026b6106ea366004612cac565b60176020526000908152604090205460ff1681565b34801561070b57600080fd5b506102a061071a366004612ace565b61131c565b34801561072b57600080fd5b506102a061073a366004612de3565b61143f565b34801561074b57600080fd5b506102b76117cf565b34801561076057600080fd5b5061026b61076f366004612e5b565b6117de565b610354610782366004612e77565b61180c565b34801561079357600080fd5b506102a06107a2366004612cac565b611d9e565b3480156107b357600080fd5b506102a06107c2366004612f0d565b611dd9565b60006107d282611fd4565b92915050565b6107e0611ff9565b6107e8612026565b6000811180156107f85750478111155b6108365760405162461bcd60e51b815260206004820152600a60248201526918985908185b5bdd5b9d60b21b60448201526064015b60405180910390fd5b6018546000906001600160a01b03161561085b576018546001600160a01b0316610868565b6008546001600160a01b03165b90506000816001600160a01b03168360405160006040518083038185875af1925050503d80600081146108b7576040519150601f19603f3d011682016040523d82523d6000602084013e6108bc565b606091505b50509050806108ff5760405162461bcd60e51b815260206004820152600f60248201526e1dda5d1a191c985dc819985a5b1959608a1b604482015260640161082d565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243648460405161093a91815260200190565b60405180910390a2505061094e6001600955565b50565b60606000805461096090612f61565b80601f016020809104026020016040519081016040528092919081815260200182805461098c90612f61565b80156109d95780601f106109ae576101008083540402835291602001916109d9565b820191906000526020600020905b8154815290600101906020018083116109bc57829003601f168201915b5050505050905090565b60006109ee82612050565b506000828152600460205260409020546001600160a01b03166107d2565b610a17828233612089565b5050565b6001600160a01b038216610a4557604051633250574960e11b81526000600482015260240161082d565b6000610a52838333612096565b9050836001600160a01b0316816001600160a01b031614610aa0576040516364283d7b60e01b81526001600160a01b038086166004830152602482018490528216604482015260640161082d565b50505050565b600082815260076020526040812080548291906001600160a01b03811690600160a01b90046001600160601b031681610afa5750506006546001600160a01b03811690600160a01b90046001600160601b03165b6000612710610b126001600160601b03841689612fb1565b610b1c9190612fc8565b92989297509195505050505050565b600c8160038110610b3b57600080fd5b600302018054600182015460029092015490925063ffffffff808216916401000000008104821691600160401b820416906001600160401b03600160601b8204811691600160a01b90041687565b610b91611ff9565b6001600160a01b038216600081815260176020908152604091829020805460ff191685151590811790915591519182527fd03640d98b0343d23b7e20c91b5833f853f6d53f9bbbd535ddd459c74427440e910160405180910390a25050565b610bf8611ff9565b610c0061218f565b565b60008360038160ff1610610c285760405162461bcd60e51b815260040161082d90612fea565b6000600c8660ff1660038110610c4057610c4061300d565b6040805160e0810182526003929092029290920180548252600181015460208301526002015463ffffffff8082169383018490526401000000008204811660608401819052600160401b830490911660808401526001600160401b03600160601b8304811660a0850152600160a01b90920490911660c083015290925060009111610ccc576000610ce0565b81606001518260400151610ce09190613023565b63ffffffff1690506000600b546105dc11610cfc576000610d0b565b600b54610d0b906105dc613047565b90506000610d1983836121e1565b6020850151909150610de6576001600160a01b03881660009081526017602052604090205460ff1615610d51579450610e8392505050565b60ff891660009081526015602090815260408083206001600160a01b038c16845290915281205460165411610d87576000610dbb565b60ff8a1660009081526015602090815260408083206001600160a01b038d168452909152902054601654610dbb9190613047565b9050610dda82610dd5876080015163ffffffff16846121e1565b6121e1565b96505050505050610e83565b60ff891660009081526015602090815260408083206001600160a01b038c16845290915281205490818911610e1c576000610e26565b610e26828a613047565b6001600160a01b038b1660009081526017602052604090205490915060ff1615610e6b57610e5e83876080015163ffffffff166121e1565b9750505050505050610e83565b610e5e83610dd5886080015163ffffffff16846121e1565b509392505050565b610ea68383836040518060200160405280600081525061129c565b505050565b610eb3611ff9565b6019610ea68284836130a2565b60006107d282612050565b60408051600380825260808201909252606091600091906020820184803683370190505090506000805b60038160ff161015610f4d57610f0a816121f7565b15610f4557808383610f1b81613161565b945060ff1681518110610f3057610f3061300d565b602002602001019060ff16908160ff16815250505b600101610ef5565b5060008160ff166001600160401b03811115610f6b57610f6b612cc7565b604051908082528060200260200182016040528015610f94578160200160208202803683370190505b50905060005b8260ff168160ff161015610e8357838160ff1681518110610fbd57610fbd61300d565b6020026020010151828260ff1681518110610fda57610fda61300d565b60ff90921660209283029190910190910152600101610f9a565b610ffc611ff9565b60165460408051918252602082018390527f867ac10dcee483322104736741066d7b2e045ff2cd8b5bf86a6942c68a1f097d910160405180910390a1601655565b60006001600160a01b038216611069576040516322718ad960e21b81526000600482015260240161082d565b506001600160a01b031660009081526003602052604090205490565b61108d611ff9565b610c0060006122aa565b61109f611ff9565b610c006122fc565b6110af611ff9565b6110b7612026565b47806110f05760405162461bcd60e51b81526020600482015260086024820152676e6f2066756e647360c01b604482015260640161082d565b6018546000906001600160a01b031615611115576018546001600160a01b0316611122565b6008546001600160a01b03165b90506000816001600160a01b03168360405160006040518083038185875af1925050503d8060008114611171576040519150601f19603f3d011682016040523d82523d6000602084013e611176565b606091505b50509050806111b95760405162461bcd60e51b815260206004820152600f60248201526e1dda5d1a191c985dc819985a5b1959608a1b604482015260640161082d565b816001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a9424364846040516111f491815260200190565b60405180910390a2505050610c006001600955565b611211611ff9565b601a610ea68284836130a2565b60606001805461096090612f61565b610a17338383612339565b611240611ff9565b6018546040516001600160a01b038084169216907f0f5e7e8f9a21dde5bc3248632fb614300e3f87c62f100f2fcb76caaedd73160390600090a3601880546001600160a01b0319166001600160a01b0392909216919091179055565b6112a7848484610a1b565b610aa033858585856123d8565b60606112bf82612050565b5060006112ca612503565b905060008151116112ea5760405180602001604052806000815250611315565b806112f484612512565b604051602001611305929190613180565b6040516020818303038152906040525b9392505050565b611324611ff9565b61132c612026565b6000811161136c5760405162461bcd60e51b815260206004820152600d60248201526c7a65726f207175616e7469747960981b604482015260640161082d565b6105dc81600b5461137d91906131af565b11156113c05760405162461bcd60e51b815260206004820152601260248201527165786365656473206d617820737570706c7960701b604482015260640161082d565b600b5460005b828110156113ec576113da84600b546125a4565b600b80546001908101909155016113c6565b50604080518381526020810183905260ff916001600160a01b038616917f5caa6bf9ed311b4e238359cf2d0c26f41c16c290725102566b24ac9e46db8c21910160405180910390a350610a176001600955565b611447611ff9565b8660038160ff161061146b5760405162461bcd60e51b815260040161082d90612fea565b6105dc8563ffffffff1611156114b15760405162461bcd60e51b815260206004820152600b60248201526a63617020746f6f2062696760a81b604482015260640161082d565b816001600160401b0316836001600160401b0316106115075760405162461bcd60e51b8152602060048201526012602482015271696e76616c69642074696d652072616e676560701b604482015260640161082d565b60008463ffffffff1611801561152557506105dc8463ffffffff1611155b6115645760405162461bcd60e51b815260206004820152601060248201526f0d2dcecc2d8d2c840dac2f0a0cae4a8f60831b604482015260640161082d565b600c8860ff166003811061157a5761157a61300d565b6003020160020160049054906101000a900463ffffffff1663ffffffff168563ffffffff1610156115dc5760405162461bcd60e51b815260206004820152600c60248201526b18d85c080f081b5a5b9d195960a21b604482015260640161082d565b6000600c8960ff16600381106115f4576115f461300d565b6003020160020160049054906101000a900463ffffffff1690506040518060e001604052808981526020018881526020018763ffffffff1681526020018263ffffffff1681526020018663ffffffff168152602001856001600160401b03168152602001846001600160401b0316815250600c8a60ff166003811061167b5761167b61300d565b82516003919091029190910190815560208201516001820155604080830151600290920180546060850151608086015160a087015160c0909701516001600160401b03908116600160a01b0267ffffffffffffffff60a01b1991909816600160601b0267ffffffffffffffff60601b1963ffffffff938416600160401b021673ffffffffffffffffffffffff0000000000000000199484166401000000000267ffffffffffffffff19909616939098169290921793909317919091169490941793909317929092169290921790555160ff8a16907fa7a14b1873603bfd03a04ac247ce96a62ea1eb7667a840e1ee7101d9892b567d906117bc908b908b908b908b908b908b90958652602086019490945263ffffffff9283166040860152911660608401526001600160401b0390811660808401521660a082015260c00190565b60405180910390a2505050505050505050565b6060601a805461096090612f61565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6000611816612026565b8560038160ff161061183a5760405162461bcd60e51b815260040161082d90612fea565b6118426125be565b600086116118825760405162461bcd60e51b815260206004820152600d60248201526c7a65726f207175616e7469747960981b604482015260640161082d565b6000600c8860ff166003811061189a5761189a61300d565b6003020190506118a9886121f7565b6118e85760405162461bcd60e51b815260206004820152601060248201526f7068617365206e6f742061637469766560801b604482015260640161082d565b6002810154600160401b900463ffffffff1687111561193e5760405162461bcd60e51b81526020600482015260126024820152710caf0c6cacac8e640dac2f040e0cae440e8f60731b604482015260640161082d565b600281015463ffffffff80821691611960918a916401000000009004166131af565b111561199f5760405162461bcd60e51b815260206004820152600e60248201526d1c1a185cd9481cdbdb19081bdd5d60921b604482015260640161082d565b6105dc87600b546119b091906131af565b11156119f35760405162461bcd60e51b815260206004820152601260248201527165786365656473206d617820737570706c7960701b604482015260640161082d565b8054600090611a03908990612fb1565b905080341015611a4c5760405162461bcd60e51b81526020600482015260146024820152731a5b9cdd59999a58da595b9d081c185e5b595b9d60621b604482015260640161082d565b600182015415611b7657611ab186868460010154611aac338c6040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b6125e2565b611aef5760405162461bcd60e51b815260206004820152600f60248201526e1b9bdd081dda1a5d195b1a5cdd1959608a1b604482015260640161082d565b3360009081526017602052604090205460ff16611b715760ff891660009081526015602090815260408083203384529091529020548790611b31908a906131af565b1115611b715760405162461bcd60e51b815260206004820152600f60248201526e195e18d959591cc8185b1b1bddd959608a1b604482015260640161082d565b611c07565b3360009081526017602052604090205460ff16611c075760165460ff8a166000908152601560209081526040808320338452909152902054611bb9908a906131af565b1115611c075760405162461bcd60e51b815260206004820152601e60248201527f65786365656473207075626c6963207065722d61646472657373206361700000604482015260640161082d565b60ff89166000908152601560209081526040808320338452909152812080548a9290611c349084906131af565b9091555050600282018054899190600490611c5e908490640100000000900463ffffffff166131c2565b92506101000a81548163ffffffff021916908363ffffffff1602179055506000600b54905060005b89811015611cac57611c9a33600b546125a4565b600b8054600190810190915501611c86565b5081341115611d4657600033611cc28434613047565b604051600081818185875af1925050503d8060008114611cfe576040519150601f19603f3d011682016040523d82523d6000602084013e611d03565b606091505b5050905080611d445760405162461bcd60e51b815260206004820152600d60248201526c1c99599d5b990819985a5b1959609a1b604482015260640161082d565b505b604080518a81526020810183905260ff8c169133917f5caa6bf9ed311b4e238359cf2d0c26f41c16c290725102566b24ac9e46db8c21910160405180910390a39350505050611d956001600955565b95945050505050565b611da6611ff9565b6001600160a01b038116611dd057604051631e4fbdf760e01b81526000600482015260240161082d565b61094e816122aa565b611de1611ff9565b8360038160ff1610611e055760405162461bcd60e51b815260040161082d90612fea565b826001600160401b0316846001600160401b031610611e5b5760405162461bcd60e51b8152602060048201526012602482015271696e76616c69642074696d652072616e676560701b604482015260640161082d565b60008263ffffffff16118015611e7957506105dc8263ffffffff1611155b611eb85760405162461bcd60e51b815260206004820152601060248201526f0d2dcecc2d8d2c840dac2f0a0cae4a8f60831b604482015260640161082d565b83600c8660ff1660038110611ecf57611ecf61300d565b60030201600201600c6101000a8154816001600160401b0302191690836001600160401b0316021790555082600c8660ff1660038110611f1157611f1161300d565b6003020160020160146101000a8154816001600160401b0302191690836001600160401b0316021790555081600c8660ff1660038110611f5357611f5361300d565b6003020160020180546bffffffff00000000000000001916600160401b63ffffffff93841602179055604080516001600160401b038781168252861660208201529184169082015260ff8616907f5d1e2e3ecfa285af2d281f7543996b3e01182217f3d98417b3b70054b00bcfc79060600160405180910390a25050505050565b60006001600160e01b0319821663152a902d60e11b14806107d257506107d2826125fa565b6008546001600160a01b03163314610c005760405163118cdaa760e01b815233600482015260240161082d565b60026009540361204957604051633ee5aeb560e01b815260040160405180910390fd5b6002600955565b6000818152600260205260408120546001600160a01b0316806107d257604051637e27328960e01b81526004810184905260240161082d565b610ea6838383600161264a565b6000828152600260205260408120546001600160a01b03908116908316156120c3576120c3818486612750565b6001600160a01b03811615612101576120e060008560008061264a565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615612130576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6121976127b4565b600a805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60008183106121f05781611315565b5090919050565b600080600c8360ff16600381106122105761221061300d565b6040805160e0810182526003929092029290920180548252600181015460208301526002015463ffffffff80821693830193909352640100000000810483166060830152600160401b810490921660808201526001600160401b03600160601b8304811660a08301819052600160a01b9093041660c082015291504210801590611315575060c001516001600160401b0316421092915050565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6123046125be565b600a805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586121c43390565b6001600160a01b03821661236b57604051630b61174360e31b81526001600160a01b038316600482015260240161082d565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b156124fc57604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061241a9088908890879087906004016131df565b6020604051808303816000875af1925050508015612455575060408051601f3d908101601f191682019092526124529181019061321c565b60015b6124be573d808015612483576040519150601f19603f3d011682016040523d82523d6000602084013e612488565b606091505b5080516000036124b657604051633250574960e11b81526001600160a01b038516600482015260240161082d565b805160208201fd5b6001600160e01b03198116630a85bd0160e11b146124fa57604051633250574960e11b81526001600160a01b038516600482015260240161082d565b505b5050505050565b60606019805461096090612f61565b6060600061251f836127d7565b60010190506000816001600160401b0381111561253e5761253e612cc7565b6040519080825280601f01601f191660200182016040528015612568576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461257257509392505050565b610a178282604051806020016040528060008152506128af565b600a5460ff1615610c005760405163d93c066560e01b815260040160405180910390fd5b6000826125f08686856128c7565b1495945050505050565b60006001600160e01b031982166380ac58cd60e01b148061262b57506001600160e01b03198216635b5e139f60e01b145b806107d257506301ffc9a760e01b6001600160e01b03198316146107d2565b808061265e57506001600160a01b03821615155b1561272057600061266e84612050565b90506001600160a01b0383161580159061269a5750826001600160a01b0316816001600160a01b031614155b80156126ad57506126ab81846117de565b155b156126d65760405163a9fbf51f60e01b81526001600160a01b038416600482015260240161082d565b811561271e5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b61275b838383612909565b610ea6576001600160a01b03831661278957604051637e27328960e01b81526004810182905260240161082d565b60405163177e802f60e01b81526001600160a01b03831660048201526024810182905260440161082d565b600a5460ff16610c0057604051638dfc202b60e01b815260040160405180910390fd5b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106128165772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612842576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061286057662386f26fc10000830492506010015b6305f5e1008310612878576305f5e100830492506008015b612710831061288c57612710830492506004015b6064831061289e576064830492506002015b600a83106107d25760010192915050565b6128b9838361296f565b610ea63360008585856123d8565b600081815b84811015612900576128f6828787848181106128ea576128ea61300d565b905060200201356129d4565b91506001016128cc565b50949350505050565b60006001600160a01b038316158015906129675750826001600160a01b0316846001600160a01b03161480612943575061294384846117de565b8061296757506000828152600460205260409020546001600160a01b038481169116145b949350505050565b6001600160a01b03821661299957604051633250574960e11b81526000600482015260240161082d565b60006129a783836000612096565b90506001600160a01b03811615610ea6576040516339e3563760e11b81526000600482015260240161082d565b60008183106129f0576000828152602084905260409020611315565b6000838152602083905260409020611315565b6001600160e01b03198116811461094e57600080fd5b600060208284031215612a2b57600080fd5b813561131581612a03565b600060208284031215612a4857600080fd5b5035919050565b60005b83811015612a6a578181015183820152602001612a52565b50506000910152565b60008151808452612a8b816020860160208601612a4f565b601f01601f19169290920160200192915050565b6020815260006113156020830184612a73565b80356001600160a01b0381168114612ac957600080fd5b919050565b60008060408385031215612ae157600080fd5b612aea83612ab2565b946020939093013593505050565b803560ff81168114612ac957600080fd5b60008060408385031215612b1c57600080fd5b612b2583612af8565b9150612b3360208401612ab2565b90509250929050565b600080600060608486031215612b5157600080fd5b612b5a84612ab2565b9250612b6860208501612ab2565b9150604084013590509250925092565b60008060408385031215612b8b57600080fd5b50508035926020909101359150565b60008060408385031215612bad57600080fd5b612bb683612ab2565b915060208301358015158114612bcb57600080fd5b809150509250929050565b600080600060608486031215612beb57600080fd5b612b5a84612af8565b60008060208385031215612c0757600080fd5b82356001600160401b0380821115612c1e57600080fd5b818501915085601f830112612c3257600080fd5b813581811115612c4157600080fd5b866020828501011115612c5357600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b81811015612ca057835160ff1683529284019291840191600101612c81565b50909695505050505050565b600060208284031215612cbe57600080fd5b61131582612ab2565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215612cf357600080fd5b612cfc85612ab2565b9350612d0a60208601612ab2565b92506040850135915060608501356001600160401b0380821115612d2d57600080fd5b818701915087601f830112612d4157600080fd5b813581811115612d5357612d53612cc7565b604051601f8201601f19908116603f01168101908382118183101715612d7b57612d7b612cc7565b816040528281528a6020848701011115612d9457600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b803563ffffffff81168114612ac957600080fd5b80356001600160401b0381168114612ac957600080fd5b600080600080600080600060e0888a031215612dfe57600080fd5b612e0788612af8565b96506020880135955060408801359450612e2360608901612db8565b9350612e3160808901612db8565b9250612e3f60a08901612dcc565b9150612e4d60c08901612dcc565b905092959891949750929550565b60008060408385031215612e6e57600080fd5b612b2583612ab2565b600080600080600060808688031215612e8f57600080fd5b612e9886612af8565b9450602086013593506040860135925060608601356001600160401b0380821115612ec257600080fd5b818801915088601f830112612ed657600080fd5b813581811115612ee557600080fd5b8960208260051b8501011115612efa57600080fd5b9699959850939650602001949392505050565b60008060008060808587031215612f2357600080fd5b612f2c85612af8565b9350612f3a60208601612dcc565b9250612f4860408601612dcc565b9150612f5660608601612db8565b905092959194509250565b600181811c90821680612f7557607f821691505b602082108103612f9557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176107d2576107d2612f9b565b600082612fe557634e487b7160e01b600052601260045260246000fd5b500490565b60208082526009908201526862616420706861736560b81b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b63ffffffff82811682821603908082111561304057613040612f9b565b5092915050565b818103818111156107d2576107d2612f9b565b601f821115610ea6576000816000526020600020601f850160051c810160208610156130835750805b601f850160051c820191505b818110156124fa5782815560010161308f565b6001600160401b038311156130b9576130b9612cc7565b6130cd836130c78354612f61565b8361305a565b6000601f84116001811461310157600085156130e95750838201355b600019600387901b1c1916600186901b1783556124fc565b600083815260209020601f19861690835b828110156131325786850135825560209485019460019092019101613112565b508682101561314f5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b600060ff821660ff810361317757613177612f9b565b60010192915050565b60008351613192818460208801612a4f565b8351908301906131a6818360208801612a4f565b01949350505050565b808201808211156107d2576107d2612f9b565b63ffffffff81811683821601908082111561304057613040612f9b565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061321290830184612a73565b9695505050505050565b60006020828403121561322e57600080fd5b815161131581612a0356fea26469706673582212201d4381b6db6d68d26ac1d53ea4139973e3f66c7a3b2882fed820ecdc10f4614264736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000ab2967a1c1bc427f08cba864a841746c8eaa6d0500000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000ab2967a1c1bc427f08cba864a841746c8eaa6d050000000000000000000000000000000000000000000000000000000000000008432046616d696c7900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044346414d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005268747470733a2f2f6261667962656964716633646a6d6c79346775726370717a757835696c6a7376706d34726663786e657164657a377569646b6a71366c32656c66712e697066732e7733732e6c696e6b2f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006568747470733a2f2f62616679626569636c616867756b32366968327561776a68777833726978686567616561747a6371716e64707767706f686678347a6a65766d34652e697066732e7733732e6c696e6b2f632d636f6e74726163742d7572692e6a736f6e000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name_ (string): C Family
Arg [1] : symbol_ (string): CFAM
Arg [2] : baseURI_ (string): https://bafybeidqf3djmly4gurcpqzux5iljsvpm4rfcxneqdez7uidkjq6l2elfq.ipfs.w3s.link/
Arg [3] : contractURI_ (string): https://bafybeiclahguk26ih2uawjhwx3rixhegaeatzcqqndpwgpohfx4zjevm4e.ipfs.w3s.link/c-contract-uri.json
Arg [4] : royaltyReceiver_ (address): 0xab2967A1c1Bc427f08CBA864A841746C8eaA6d05
Arg [5] : royaltyBps_ (uint96): 500
Arg [6] : initialOwner_ (address): 0xab2967A1c1Bc427f08CBA864A841746C8eaA6d05
-----Encoded View---------------
20 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [4] : 000000000000000000000000ab2967a1c1bc427f08cba864a841746c8eaa6d05
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [6] : 000000000000000000000000ab2967a1c1bc427f08cba864a841746c8eaa6d05
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [8] : 432046616d696c79000000000000000000000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [10] : 4346414d00000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000052
Arg [12] : 68747470733a2f2f6261667962656964716633646a6d6c79346775726370717a
Arg [13] : 757835696c6a7376706d34726663786e657164657a377569646b6a71366c3265
Arg [14] : 6c66712e697066732e7733732e6c696e6b2f0000000000000000000000000000
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000065
Arg [16] : 68747470733a2f2f62616679626569636c616867756b32366968327561776a68
Arg [17] : 777833726978686567616561747a6371716e64707767706f686678347a6a6576
Arg [18] : 6d34652e697066732e7733732e6c696e6b2f632d636f6e74726163742d757269
Arg [19] : 2e6a736f6e000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
171577:11652:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;181407:142;;;;;;;;;;-1:-1:-1;181407:142:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;181407:142:0;;;;;;;;180602:359;;;;;;;;;;-1:-1:-1;180602:359:0;;;;;:::i;:::-;;:::i;:::-;;124493:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;125561:158::-;;;;;;;;;;-1:-1:-1;125561:158:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:1;;;1679:51;;1667:2;1652:18;125561:158:0;1533:203:1;125409:115:0;;;;;;;;;;-1:-1:-1;125409:115:0;;;;;:::i;:::-;;:::i;172270:67::-;;;;;;;;;;-1:-1:-1;172270:67:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;2746:25:1;;;2734:2;2719:18;172270:67:0;2600:177:1;181317:82:0;;;;;;;;;;-1:-1:-1;181381:15:0;;181317:82;;126131:588;;;;;;;;;;-1:-1:-1;126131:588:0;;;;;:::i;:::-;;:::i;9669:673::-;;;;;;;;;;-1:-1:-1;9669:673:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3560:32:1;;;3542:51;;3624:2;3609:18;;3602:34;;;;3515:18;9669:673:0;3368:274:1;172171:22:0;;;;;;;;;;-1:-1:-1;172171:22:0;;;;;:::i;:::-;;:::i;:::-;;;;3952:25:1;;;4008:2;3993:18;;3986:34;;;;4039:10;4085:15;;;4065:18;;;4058:43;;;;4137:15;;;4132:2;4117:18;;4110:43;4190:15;;;4184:3;4169:19;;4162:44;-1:-1:-1;;;;;4280:15:1;;;4274:3;4259:19;;4252:44;4333:15;4327:3;4312:19;;4305:44;3939:3;3924:19;172171:22:0;3647:708:1;171663:41:0;;;;;;;;;;;;171700:4;171663:41;;179091:158;;;;;;;;;;-1:-1:-1;179091:158:0;;;;;:::i;:::-;;:::i;181026:53::-;;;;;;;;;;;;;:::i;182107:1119::-;;;;;;;;;;-1:-1:-1;182107:1119:0;;;;;:::i;:::-;;:::i;126756:134::-;;;;;;;;;;-1:-1:-1;126756:134:0;;;;;:::i;:::-;;:::i;179867:80::-;;;;;;;;;;-1:-1:-1;179867:80:0;;;;;:::i;:::-;;:::i;166514:86::-;;;;;;;;;;-1:-1:-1;166585:7:0;;;;166514:86;;124328:120;;;;;;;;;;-1:-1:-1;124328:120:0;;;;;:::i;:::-;;:::i;172614:21::-;;;;;;;;;;-1:-1:-1;172614:21:0;;;;-1:-1:-1;;;;;172614:21:0;;;181604:392;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;178847:170::-;;;;;;;;;;-1:-1:-1;178847:170:0;;;;;:::i;:::-;;:::i;124078:213::-;;;;;;;;;;-1:-1:-1;124078:213:0;;;;;:::i;:::-;;:::i;3479:103::-;;;;;;;;;;;;;:::i;180969:51::-;;;;;;;;;;;;;:::i;172412:38::-;;;;;;;;;;;;;;;;180240:354;;;;;;;;;;;;;:::i;2804:87::-;;;;;;;;;;-1:-1:-1;2877:6:0;;-1:-1:-1;;;;;2877:6:0;2804:87;;179953:83;;;;;;;;;;-1:-1:-1;179953:83:0;;;;;:::i;:::-;;:::i;124629:95::-;;;;;;;;;;;;;:::i;125756:146::-;;;;;;;;;;-1:-1:-1;125756:146:0;;;;;:::i;:::-;;:::i;180114:118::-;;;;;;;;;;-1:-1:-1;180114:118:0;;;;;:::i;:::-;;:::i;126927:236::-;;;;;;;;;;-1:-1:-1;126927:236:0;;;;;:::i;:::-;;:::i;124769:260::-;;;;;;;;;;-1:-1:-1;124769:260:0;;;;;:::i;:::-;;:::i;172526:40::-;;;;;;;;;;-1:-1:-1;172526:40:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;179335:524;;;;;;;;;;-1:-1:-1;179335:524:0;;;;;:::i;:::-;;:::i;177253:930::-;;;;;;;;;;-1:-1:-1;177253:930:0;;;;;:::i;:::-;;:::i;181224:85::-;;;;;;;;;;;;;:::i;125939:155::-;;;;;;;;;;-1:-1:-1;125939:155:0;;;;;:::i;:::-;;:::i;175069:2045::-;;;;;;:::i;:::-;;:::i;3737:220::-;;;;;;;;;;-1:-1:-1;3737:220:0;;;;;:::i;:::-;;:::i;178283:514::-;;;;;;;;;;-1:-1:-1;178283:514:0;;;;;:::i;:::-;;:::i;181407:142::-;181500:4;181520:26;181544:1;181520:23;:26::i;:::-;181513:33;181407:142;-1:-1:-1;;181407:142:0:o;180602:359::-;2690:13;:11;:13::i;:::-;170164:21:::1;:19;:21::i;:::-;180702:1:::2;180693:6;:10;:45;;;;;180717:21;180707:6;:31;;180693:45;180685:68;;;::::0;-1:-1:-1;;;180685:68:0;;10405:2:1;180685:68:0::2;::::0;::::2;10387:21:1::0;10444:2;10424:18;;;10417:30;-1:-1:-1;;;10463:18:1;;;10456:40;10513:18;;180685:68:0::2;;;;;;;;;180777:6;::::0;180764:10:::2;::::0;-1:-1:-1;;;;;180777:6:0::2;:20:::0;:39:::2;;180810:6;::::0;-1:-1:-1;;;;;180810:6:0::2;180777:39;;;2877:6:::0;;-1:-1:-1;;;;;2877:6:0;180800:7:::2;180764:52;;180828:7;180849:2;-1:-1:-1::0;;;;;180841:16:0::2;180865:6;180841:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;180827:49;;;180895:2;180887:30;;;::::0;-1:-1:-1;;;180887:30:0;;10954:2:1;180887:30:0::2;::::0;::::2;10936:21:1::0;10993:2;10973:18;;;10966:30;-1:-1:-1;;;11012:18:1;;;11005:45;11067:18;;180887:30:0::2;10752:339:1::0;180887:30:0::2;180942:2;-1:-1:-1::0;;;;;180933:20:0::2;;180946:6;180933:20;;;;2746:25:1::0;;2734:2;2719:18;;2600:177;180933:20:0::2;;;;;;;;180674:287;;170208:20:::1;169499:1:::0;170750:7;:21;170567:212;170208:20:::1;180602:359:::0;:::o;124493:91::-;124538:13;124571:5;124564:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124493:91;:::o;125561:158::-;125628:7;125648:22;125662:7;125648:13;:22::i;:::-;-1:-1:-1;127996:7:0;128023:24;;;:15;:24;;;;;;-1:-1:-1;;;;;128023:24:0;125690:21;127926:129;125409:115;125481:35;125490:2;125494:7;864:10;125481:8;:35::i;:::-;125409:115;;:::o;126131:588::-;-1:-1:-1;;;;;126226:16:0;;126222:89;;126266:33;;-1:-1:-1;;;126266:33:0;;126296:1;126266:33;;;1679:51:1;1652:18;;126266:33:0;1533:203:1;126222:89:0;126532:21;126556:34;126564:2;126568:7;864:10;126556:7;:34::i;:::-;126532:58;;126622:4;-1:-1:-1;;;;;126605:21:0;:13;-1:-1:-1;;;;;126605:21:0;;126601:111;;126650:50;;-1:-1:-1;;;126650:50:0;;-1:-1:-1;;;;;11739:15:1;;;126650:50:0;;;11721:34:1;11771:18;;;11764:34;;;11834:15;;11814:18;;;11807:43;11656:18;;126650:50:0;11481:375:1;126601:111:0;126211:508;126131:588;;;:::o;9669:673::-;9780:16;9860:26;;;:17;:26;;;;;9923:21;;9780:16;;9860:26;-1:-1:-1;;;;;9923:21:0;;;-1:-1:-1;;;9980:28:0;;-1:-1:-1;;;;;9980:28:0;9923:21;10021:176;;-1:-1:-1;;10089:19:0;:28;-1:-1:-1;;;;;10089:28:0;;;-1:-1:-1;;;10150:35:0;;-1:-1:-1;;;;;10150:35:0;10021:176;10209:21;10708:5;10234:27;-1:-1:-1;;;;;10234:27:0;;:9;:27;:::i;:::-;10233:49;;;;:::i;:::-;10303:15;;;;-1:-1:-1;9669:673:0;;-1:-1:-1;;;;;;9669:673:0:o;172171:22::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;172171:22:0;;;;;;;;;;;-1:-1:-1;;;172171:22:0;;;;-1:-1:-1;;;;;;;;172171:22:0;;;;;-1:-1:-1;;;172171:22:0;;;;:::o;179091:158::-;2690:13;:11;:13::i;:::-;-1:-1:-1;;;;;179171:17:0;::::1;;::::0;;;:8:::1;:17;::::0;;;;;;;;:27;;-1:-1:-1;;179171:27:0::1;::::0;::::1;;::::0;;::::1;::::0;;;179214;;540:41:1;;;179214:27:0::1;::::0;513:18:1;179214:27:0::1;;;;;;;179091:158:::0;;:::o;181026:53::-;2690:13;:11;:13::i;:::-;181066:10:::1;:8;:10::i;:::-;181026:53::o:0;182107:1119::-;182261:7;182243;174029:1;174024:2;:6;;;174016:28;;;;-1:-1:-1;;;174016:28:0;;;;;;;:::i;:::-;182281:14:::1;182298:6;182305:7;182298:15;;;;;;;;;:::i;:::-;182281:32;::::0;;::::1;::::0;::::1;::::0;;182298:15:::1;::::0;;;::::1;::::0;;;::::1;182281:32:::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;;::::0;::::1;::::0;;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;;;182281:32:0;::::1;::::0;;::::1;::::0;;;;-1:-1:-1;;;;;;;;182281:32:0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;182281:32:0;;::::1;::::0;;::::1;::::0;;;;;;-1:-1:-1;;;182349:16:0::1;:39;;182387:1;182349:39;;;182376:1;:8;;;182368:1;:5;;;:16;;;;:::i;:::-;182324:64;;;;182399:23;182438:15;;171700:4;182425:28;:63;;182487:1;182425:63;;;182469:15;::::0;182456:28:::1;::::0;171700:4:::1;182456:28;:::i;:::-;182399:89;;182499:21;182525:37;182530:14;182546:15;182525:4;:37::i;:::-;182579:6;::::0;::::1;::::0;182499:63;;-1:-1:-1;182575:644:0::1;;-1:-1:-1::0;;;;;182620:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;;::::1;;182616:40;;;182643:13:::0;-1:-1:-1;182636:20:0::1;::::0;-1:-1:-1;;;182636:20:0::1;182616:40;182715:23;::::0;::::1;182671:19;182715:23:::0;;;:14:::1;:23;::::0;;;;;;;-1:-1:-1;;;;;182715:29:0;::::1;::::0;;;;;;;;182693:19:::1;::::0;:51:::1;:143;;182835:1;182693:143;;;182786:23;::::0;::::1;;::::0;;;:14:::1;:23;::::0;;;;;;;-1:-1:-1;;;;;182786:29:0;::::1;::::0;;;;;;;;182764:19:::1;::::0;:51:::1;::::0;182786:29;182764:51:::1;:::i;:::-;182671:165;;182858:50;182863:13;182878:29;182883:1;:10;;;182878:29;;182895:11;182878:4;:29::i;:::-;182858:4;:50::i;:::-;182851:57;;;;;;;;;182575:644;182959:23;::::0;::::1;182941:15;182959:23:::0;;;:14:::1;:23;::::0;;;;;;;-1:-1:-1;;;;;182959:29:0;::::1;::::0;;;;;;;;;183021:20;;::::1;:47;;183067:1;183021:47;;;183044:20;183057:7:::0;183044:10;:20:::1;:::i;:::-;-1:-1:-1::0;;;;;183087:14:0;::::1;;::::0;;;:8:::1;:14;::::0;;;;;183003:65;;-1:-1:-1;183087:14:0::1;;183083:58;;;183110:31;183115:13;183130:1;:10;;;183110:31;;:4;:31::i;:::-;183103:38;;;;;;;;;;183083:58;183163:44;183168:13;183183:23;183188:1;:10;;;183183:23;;183200:5;183183:4;:23::i;174046:1::-;182107:1119:::0;;;;;;:::o;126756:134::-;126843:39;126860:4;126866:2;126870:7;126843:39;;;;;;;;;;;;:16;:39::i;:::-;126756:134;;;:::o;179867:80::-;2690:13;:11;:13::i;:::-;179927::::1;:17;179943:1:::0;;179927:13;:17:::1;:::i;124328:120::-:0;124391:7;124418:22;124432:7;124418:13;:22::i;181604:392::-;181702:14;;;181714:1;181702:14;;;;;;;;;181654;;181681:18;;181702:14;;;;181654;;181702;;;;;-1:-1:-1;181702:14:0;181681:35;;181727:11;181758:7;181753:96;181775:1;181771;:5;;;181753:96;;;181802:17;181817:1;181802:14;:17::i;:::-;181798:39;;;181836:1;181821:3;181825:7;;;;:::i;:::-;;;181821:12;;;;;;;;;;:::i;:::-;;;;;;:16;;;;;;;;;;;181798:39;181778:3;;181753:96;;;;181859:21;181895:5;181883:18;;-1:-1:-1;;;;;181883:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;181883:18:0;;181859:42;;181917:7;181912:52;181934:5;181930:9;;:1;:9;;;181912:52;;;181958:3;181962:1;181958:6;;;;;;;;;;:::i;:::-;;;;;;;181946;181953:1;181946:9;;;;;;;;;;:::i;:::-;:18;;;;:9;;;;;;;;;;;:18;181941:3;;181912:52;;178847:170;2690:13;:11;:13::i;:::-;178952:19:::1;::::0;178925:50:::1;::::0;;15712:25:1;;;15768:2;15753:18;;15746:34;;;178925:50:0::1;::::0;15685:18:1;178925:50:0::1;;;;;;;178986:19;:23:::0;178847:170::o;124078:213::-;124141:7;-1:-1:-1;;;;;124165:19:0;;124161:89;;124208:30;;-1:-1:-1;;;124208:30:0;;124235:1;124208:30;;;1679:51:1;1652:18;;124208:30:0;1533:203:1;124161:89:0;-1:-1:-1;;;;;;124267:16:0;;;;;:9;:16;;;;;;;124078:213::o;3479:103::-;2690:13;:11;:13::i;:::-;3544:30:::1;3571:1;3544:18;:30::i;180969:51::-:0;2690:13;:11;:13::i;:::-;181009:8:::1;:6;:8::i;180240:354::-:0;2690:13;:11;:13::i;:::-;170164:21:::1;:19;:21::i;:::-;180323::::2;180363:10:::0;180355:31:::2;;;::::0;-1:-1:-1;;;180355:31:0;;15993:2:1;180355:31:0::2;::::0;::::2;15975:21:1::0;16032:1;16012:18;;;16005:29;-1:-1:-1;;;16050:18:1;;;16043:38;16098:18;;180355:31:0::2;15791:331:1::0;180355:31:0::2;180410:6;::::0;180397:10:::2;::::0;-1:-1:-1;;;;;180410:6:0::2;:20:::0;:39:::2;;180443:6;::::0;-1:-1:-1;;;;;180443:6:0::2;180410:39;;;2877:6:::0;;-1:-1:-1;;;;;2877:6:0;180433:7:::2;180397:52;;180461:7;180482:2;-1:-1:-1::0;;;;;180474:16:0::2;180498:6;180474:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;180460:49;;;180528:2;180520:30;;;::::0;-1:-1:-1;;;180520:30:0;;10954:2:1;180520:30:0::2;::::0;::::2;10936:21:1::0;10993:2;10973:18;;;10966:30;-1:-1:-1;;;11012:18:1;;;11005:45;11067:18;;180520:30:0::2;10752:339:1::0;180520:30:0::2;180575:2;-1:-1:-1::0;;;;;180566:20:0::2;;180579:6;180566:20;;;;2746:25:1::0;;2734:2;2719:18;;2600:177;180566:20:0::2;;;;;;;;180295:299;;;170208:20:::1;169499:1:::0;170750:7;:21;170567:212;179953:83;2690:13;:11;:13::i;:::-;180017:12:::1;:16;180032:1:::0;;180017:12;:16:::1;:::i;124629:95::-:0;124676:13;124709:7;124702:14;;;;;:::i;125756:146::-;125842:52;864:10;125875:8;125885;125842:18;:52::i;180114:118::-;2690:13;:11;:13::i;:::-;180193:6:::1;::::0;180179:24:::1;::::0;-1:-1:-1;;;;;180179:24:0;;::::1;::::0;180193:6:::1;::::0;180179:24:::1;::::0;180193:6:::1;::::0;180179:24:::1;180214:6;:10:::0;;-1:-1:-1;;;;;;180214:10:0::1;-1:-1:-1::0;;;;;180214:10:0;;;::::1;::::0;;;::::1;::::0;;180114:118::o;126927:236::-;127041:31;127054:4;127060:2;127064:7;127041:12;:31::i;:::-;127083:72;864:10;127131:4;127137:2;127141:7;127150:4;127083:33;:72::i;124769:260::-;124833:13;124859:22;124873:7;124859:13;:22::i;:::-;;124894:21;124918:10;:8;:10::i;:::-;124894:34;;124970:1;124952:7;124946:21;:25;:75;;;;;;;;;;;;;;;;;124988:7;124997:18;:7;:16;:18::i;:::-;124974:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;124946:75;124939:82;124769:260;-1:-1:-1;;;124769:260:0:o;179335:524::-;2690:13;:11;:13::i;:::-;170164:21:::1;:19;:21::i;:::-;179451:1:::2;179440:8;:12;179432:38;;;::::0;-1:-1:-1;;;179432:38:0;;16830:2:1;179432:38:0::2;::::0;::::2;16812:21:1::0;16869:2;16849:18;;;16842:30;-1:-1:-1;;;16888:18:1;;;16881:43;16941:18;;179432:38:0::2;16628:337:1::0;179432:38:0::2;171700:4;179507:8;179489:15;;:26;;;;:::i;:::-;:40;;179481:71;;;::::0;-1:-1:-1;;;179481:71:0;;17302:2:1;179481:71:0::2;::::0;::::2;17284:21:1::0;17341:2;17321:18;;;17314:30;-1:-1:-1;;;17360:18:1;;;17353:48;17418:18;;179481:71:0::2;17100:342:1::0;179481:71:0::2;179586:15;::::0;179563:20:::2;179612:144;179636:8;179632:1;:12;179612:144;;;179663:30;179673:2;179677:15;;179663:9;:30::i;:::-;179720:15;:17:::0;;::::2;::::0;;::::2;::::0;;;179739:3:::2;179612:144;;;-1:-1:-1::0;179771:44:0::2;::::0;;15712:25:1;;;15768:2;15753:18;;15746:34;;;179787:3:0::2;::::0;-1:-1:-1;;;;;179771:44:0;::::2;::::0;::::2;::::0;15685:18:1;179771:44:0::2;;;;;;;179421:438;170208:20:::1;169499:1:::0;170750:7;:21;170567:212;177253:930;2690:13;:11;:13::i;:::-;177479:2:::1;174029:1;174024:2;:6;;;174016:28;;;;-1:-1:-1::0;;;174016:28:0::1;;;;;;;:::i;:::-;171700:4:::2;177502:3;:17;;;;177494:41;;;::::0;-1:-1:-1;;;177494:41:0;;17649:2:1;177494:41:0::2;::::0;::::2;17631:21:1::0;17688:2;17668:18;;;17661:30;-1:-1:-1;;;17707:18:1;;;17700:41;17758:18;;177494:41:0::2;17447:335:1::0;177494:41:0::2;177566:7;-1:-1:-1::0;;;;;177554:19:0::2;:9;-1:-1:-1::0;;;;;177554:19:0::2;;177546:50;;;::::0;-1:-1:-1;;;177546:50:0;;17989:2:1;177546:50:0::2;::::0;::::2;17971:21:1::0;18028:2;18008:18;;;18001:30;-1:-1:-1;;;18047:18:1;;;18040:48;18105:18;;177546:50:0::2;17787:342:1::0;177546:50:0::2;177626:1;177615:8;:12;;;:38;;;;;171700:4;177631:8;:22;;;;177615:38;177607:67;;;::::0;-1:-1:-1;;;177607:67:0;;18336:2:1;177607:67:0::2;::::0;::::2;18318:21:1::0;18375:2;18355:18;;;18348:30;-1:-1:-1;;;18394:18:1;;;18387:46;18450:18;;177607:67:0::2;18134:340:1::0;177607:67:0::2;177763:6;177770:2;177763:10;;;;;;;;;:::i;:::-;;;;:17;;;;;;;;;;;;177756:24;;:3;:24;;;;177748:49;;;::::0;-1:-1:-1;;;177748:49:0;;18681:2:1;177748:49:0::2;::::0;::::2;18663:21:1::0;18720:2;18700:18;;;18693:30;-1:-1:-1;;;18739:18:1;;;18732:42;18791:18;;177748:49:0::2;18479:336:1::0;177748:49:0::2;177810:14;177827:6;177834:2;177827:10;;;;;;;;;:::i;:::-;;;;:17;;;;;;;;;;;;177810:34;;177868:222;;;;;;;;177896:5;177868:222;;;;177922:4;177868:222;;;;177946:3;177868:222;;;;;;177972:7;177868:222;;;;;;178004:8;177868:222;;;;;;178038:9;-1:-1:-1::0;;;;;177868:222:0::2;;;;;178071:7;-1:-1:-1::0;;;;;177868:222:0::2;;;::::0;177855:6:::2;177862:2;177855:10;;;;;;;;;:::i;:::-;:235:::0;;:10:::2;::::0;;;::::2;::::0;;;::::2;:235:::0;;;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;;::::2;::::0;::::2;::::0;;::::2;::::0;;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;;::::2;::::0;-1:-1:-1;;;;;177855:235:0;;::::2;-1:-1:-1::0;;;177855:235:0::2;-1:-1:-1::0;;;;177855:235:0;;;::::2;-1:-1:-1::0;;;177855:235:0::2;-1:-1:-1::0;;;;177855:235:0::2;::::0;;::::2;-1:-1:-1::0;;;177855:235:0::2;::::0;-1:-1:-1;;177855:235:0;;::::2;::::0;::::2;-1:-1:-1::0;;177855:235:0;;;;;;::::2;::::0;;;;;;;::::2;::::0;;;;;;;;;;;::::2;::::0;;;::::2;::::0;;;::::2;::::0;;178108:67;::::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;178128:5;;178135:4;;178141:3;;178146:8;;178156:9;;178167:7;;19099:25:1;;;19155:2;19140:18;;19133:34;;;;19186:10;19232:15;;;19227:2;19212:18;;19205:43;19284:15;;19279:2;19264:18;;19257:43;-1:-1:-1;;;;;19374:15:1;;;19368:3;19353:19;;19346:44;19427:15;19421:3;19406:19;;19399:44;19086:3;19071:19;;18820:629;178108:67:0::2;;;;;;;;177483:700;2714:1:::1;177253:930:::0;;;;;;;:::o;181224:85::-;181270:13;181294:12;181287:19;;;;;:::i;125939:155::-;-1:-1:-1;;;;;126051:25:0;;;126027:4;126051:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;125939:155::o;175069:2045::-;175276:7;170164:21;:19;:21::i;:::-;175249:2:::1;174029:1;174024:2;:6;;;174016:28;;;;-1:-1:-1::0;;;174016:28:0::1;;;;;;;:::i;:::-;166119:19:::2;:17;:19::i;:::-;175315:1:::3;175304:8;:12;175296:38;;;::::0;-1:-1:-1;;;175296:38:0;;16830:2:1;175296:38:0::3;::::0;::::3;16812:21:1::0;16869:2;16849:18;;;16842:30;-1:-1:-1;;;16888:18:1;;;16881:43;16941:18;;175296:38:0::3;16628:337:1::0;175296:38:0::3;175345:15;175363:6;175370:2;175363:10;;;;;;;;;:::i;:::-;;;;175345:28;;175392:18;175407:2;175392:14;:18::i;:::-;175384:47;;;::::0;-1:-1:-1;;;175384:47:0;;19656:2:1;175384:47:0::3;::::0;::::3;19638:21:1::0;19695:2;19675:18;;;19668:30;-1:-1:-1;;;19714:18:1;;;19707:46;19770:18;;175384:47:0::3;19454:340:1::0;175384:47:0::3;175462:10;::::0;::::3;::::0;-1:-1:-1;;;175462:10:0;::::3;;;175450:22:::0;::::3;;175442:53;;;::::0;-1:-1:-1;;;175442:53:0;;20001:2:1;175442:53:0::3;::::0;::::3;19983:21:1::0;20040:2;20020:18;;;20013:30;-1:-1:-1;;;20059:18:1;;;20052:48;20117:18;;175442:53:0::3;19799:342:1::0;175442:53:0::3;175537:5;::::0;::::3;::::0;::::3;::::0;;::::3;::::0;175514:19:::3;::::0;175525:8;;175514;;::::3;;:19;:::i;:::-;:28;;175506:55;;;::::0;-1:-1:-1;;;175506:55:0;;20348:2:1;175506:55:0::3;::::0;::::3;20330:21:1::0;20387:2;20367:18;;;20360:30;-1:-1:-1;;;20406:18:1;;;20399:44;20460:18;;175506:55:0::3;20146:338:1::0;175506:55:0::3;171700:4;175598:8;175580:15;;:26;;;;:::i;:::-;:40;;175572:71;;;::::0;-1:-1:-1;;;175572:71:0;;17302:2:1;175572:71:0::3;::::0;::::3;17284:21:1::0;17341:2;17321:18;;;17314:30;-1:-1:-1;;;17360:18:1;;;17353:48;17418:18;;175572:71:0::3;17100:342:1::0;175572:71:0::3;175671:7:::0;;175656:12:::3;::::0;175671:18:::3;::::0;175681:8;;175671:18:::3;:::i;:::-;175656:33;;175721:4;175708:9;:17;;175700:50;;;::::0;-1:-1:-1;;;175700:50:0;;20691:2:1;175700:50:0::3;::::0;::::3;20673:21:1::0;20730:2;20710:18;;;20703:30;-1:-1:-1;;;20749:18:1;;;20742:50;20809:18;;175700:50:0::3;20489:344:1::0;175700:50:0::3;175845:6;::::0;::::3;::::0;:20;175841:638:::3;;175908:72;175935:5;;175942:1;:6;;;175950:29;175956:10;175968;174237:30:::0;;-1:-1:-1;;23719:2:1;23715:15;;;23711:53;174237:30:0;;;23699:66:1;23781:12;;;23774:28;;;174200:7:0;;23818:12:1;;174237:30:0;;;;;;;;;;;;174227:41;;;;;;174220:48;;174132:144;;;;;175950:29:::3;175908:26;:72::i;:::-;175882:149;;;::::0;-1:-1:-1;;;175882:149:0;;21040:2:1;175882:149:0::3;::::0;::::3;21022:21:1::0;21079:2;21059:18;;;21052:30;-1:-1:-1;;;21098:18:1;;;21091:45;21153:18;;175882:149:0::3;20838:339:1::0;175882:149:0::3;176060:10;176051:20;::::0;;;:8:::3;:20;::::0;;;;;::::3;;176046:145;;176100:18;::::0;::::3;;::::0;;;:14:::3;:18;::::0;;;;;;;176119:10:::3;176100:30:::0;;;;;;;;176145:10;;176100:41:::3;::::0;176133:8;;176100:41:::3;:::i;:::-;:55;;176092:83;;;::::0;-1:-1:-1;;;176092:83:0;;21384:2:1;176092:83:0::3;::::0;::::3;21366:21:1::0;21423:2;21403:18;;;21396:30;-1:-1:-1;;;21442:18:1;;;21435:45;21497:18;;176092:83:0::3;21182:339:1::0;176092:83:0::3;175841:638;;;176313:10;176304:20;::::0;;;:8:::3;:20;::::0;;;;;::::3;;176299:169;;176398:19;::::0;176353:18:::3;::::0;::::3;;::::0;;;:14:::3;:18;::::0;;;;;;;176372:10:::3;176353:30:::0;;;;;;;;:41:::3;::::0;176386:8;;176353:41:::3;:::i;:::-;:64;;176345:107;;;::::0;-1:-1:-1;;;176345:107:0;;21728:2:1;176345:107:0::3;::::0;::::3;21710:21:1::0;21767:2;21747:18;;;21740:30;21806:32;21786:18;;;21779:60;21856:18;;176345:107:0::3;21526:354:1::0;176345:107:0::3;176516:18;::::0;::::3;;::::0;;;:14:::3;:18;::::0;;;;;;;176535:10:::3;176516:30:::0;;;;;;;:42;;176550:8;;176516:18;:42:::3;::::0;176550:8;;176516:42:::3;:::i;:::-;::::0;;;-1:-1:-1;;176569:8:0::3;::::0;::::3;:28:::0;;176588:8;;176569;::::3;::::0;:28:::3;::::0;176588:8;;176569:28;;::::3;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;176610:20;176633:15;;176610:38;;176664:9;176659:152;176683:8;176679:1;:12;176659:152;;;176710:38;176720:10;176732:15;;176710:9;:38::i;:::-;176775:15;:17:::0;;::::3;::::0;;::::3;::::0;;;176794:3:::3;176659:152;;;;176865:4;176853:9;:16;176849:159;;;176887:7;176908:10;176932:16;176944:4:::0;176932:9:::3;:16;:::i;:::-;176900:53;::::0;::::3;::::0;;;;;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;176886:67;;;176976:2;176968:28;;;::::0;-1:-1:-1;;;176968:28:0;;22264:2:1;176968:28:0::3;::::0;::::3;22246:21:1::0;22303:2;22283:18;;;22276:30;-1:-1:-1;;;22322:18:1;;;22315:43;22375:18;;176968:28:0::3;22062:337:1::0;176968:28:0::3;176871:137;176849:159;177025:51;::::0;;15712:25:1;;;15768:2;15753:18;;15746:34;;;177025:51:0::3;::::0;::::3;::::0;177037:10:::3;::::0;177025:51:::3;::::0;15685:18:1;177025:51:0::3;;;;;;;177094:12:::0;-1:-1:-1;;;170196:1:0::1;170208:20:::0;169499:1;170750:7;:21;170567:212;170208:20;175069:2045;;;;;;;:::o;3737:220::-;2690:13;:11;:13::i;:::-;-1:-1:-1;;;;;3822:22:0;::::1;3818:93;;3868:31;::::0;-1:-1:-1;;;3868:31:0;;3896:1:::1;3868:31;::::0;::::1;1679:51:1::0;1652:18;;3868:31:0::1;1533:203:1::0;3818:93:0::1;3921:28;3940:8;3921:18;:28::i;178283:514::-:0;2690:13;:11;:13::i;:::-;178454:2:::1;174029:1;174024:2;:6;;;174016:28;;;;-1:-1:-1::0;;;174016:28:0::1;;;;;;;:::i;:::-;178489:7:::2;-1:-1:-1::0;;;;;178477:19:0::2;:9;-1:-1:-1::0;;;;;178477:19:0::2;;178469:50;;;::::0;-1:-1:-1;;;178469:50:0;;17989:2:1;178469:50:0::2;::::0;::::2;17971:21:1::0;18028:2;18008:18;;;18001:30;-1:-1:-1;;;18047:18:1;;;18040:48;18105:18;;178469:50:0::2;17787:342:1::0;178469:50:0::2;178549:1;178538:8;:12;;;:38;;;;;171700:4;178554:8;:22;;;;178538:38;178530:67;;;::::0;-1:-1:-1;;;178530:67:0;;18336:2:1;178530:67:0::2;::::0;::::2;18318:21:1::0;18375:2;18355:18;;;18348:30;-1:-1:-1;;;18394:18:1;;;18387:46;18450:18;;178530:67:0::2;18134:340:1::0;178530:67:0::2;178631:9;178608:6;178615:2;178608:10;;;;;;;;;:::i;:::-;;;;:20;;;:32;;;;;-1:-1:-1::0;;;;;178608:32:0::2;;;;;-1:-1:-1::0;;;;;178608:32:0::2;;;;;;178674:7;178651:6;178658:2;178651:10;;;;;;;;;:::i;:::-;;;;:18;;;:30;;;;;-1:-1:-1::0;;;;;178651:30:0::2;;;;;-1:-1:-1::0;;;;;178651:30:0::2;;;;;;178715:8;178692:6;178699:2;178692:10;;;;;;;;;:::i;:::-;;;;:19;;:31:::0;;-1:-1:-1;;178692:31:0::2;-1:-1:-1::0;;;178692:31:0::2;::::0;;::::2;;;::::0;;178739:50:::2;::::0;;-1:-1:-1;;;;;22655:15:1;;;22637:34;;22707:15;;22702:2;22687:18;;22680:43;22759:23;;;22739:18;;;22732:51;178739:50:0::2;::::0;::::2;::::0;::::2;::::0;22588:2:1;22573:18;178739:50:0::2;;;;;;;2714:1:::1;178283:514:::0;;;;:::o;9416:215::-;9518:4;-1:-1:-1;;;;;;9542:41:0;;-1:-1:-1;;;9542:41:0;;:81;;;9587:36;9611:11;9587:23;:36::i;2969:166::-;2877:6;;-1:-1:-1;;;;;2877:6:0;864:10;3029:23;3025:103;;3076:40;;-1:-1:-1;;;3076:40:0;;864:10;3076:40;;;1679:51:1;1652:18;;3076:40:0;1533:203:1;170244:315:0;169542:1;170373:7;;:18;170369:88;;170415:30;;-1:-1:-1;;;170415:30:0;;;;;;;;;;;170369:88;169542:1;170534:7;:17;170244:315::o;138445:247::-;138508:7;127781:16;;;:7;:16;;;;;;-1:-1:-1;;;;;127781:16:0;;138572:90;;138619:31;;-1:-1:-1;;;138619:31:0;;;;;2746:25:1;;;2719:18;;138619:31:0;2600:177:1;136677:122:0;136758:33;136767:2;136771:7;136780:4;136786;136758:8;:33::i;130887:824::-;130973:7;127781:16;;;:7;:16;;;;;;-1:-1:-1;;;;;127781:16:0;;;;131088:18;;;131084:88;;131123:37;131140:4;131146;131152:7;131123:16;:37::i;:::-;-1:-1:-1;;;;;131219:18:0;;;131215:263;;131337:48;131354:1;131358:7;131375:1;131379:5;131337:8;:48::i;:::-;-1:-1:-1;;;;;131431:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;131431:20:0;;;131215:263;-1:-1:-1;;;;;131494:16:0;;;131490:111;;-1:-1:-1;;;;;131556:13:0;;;;;;:9;:13;;;;;:18;;131573:1;131556:18;;;131490:111;131613:16;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;131613:21:0;-1:-1:-1;;;;;131613:21:0;;;;;;;;;131652:27;;131613:16;;131652:27;;;;;;;131699:4;130887:824;-1:-1:-1;;;;130887:824:0:o;167415:120::-;166378:16;:14;:16::i;:::-;167474:7:::1;:15:::0;;-1:-1:-1;;167474:15:0::1;::::0;;167505:22:::1;864:10:::0;167514:12:::1;167505:22;::::0;-1:-1:-1;;;;;1697:32:1;;;1679:51;;1667:2;1652:18;167505:22:0::1;;;;;;;167415:120::o:0;174523:106::-;174581:7;174612:1;174608;:5;:13;;174620:1;174608:13;;;-1:-1:-1;174616:1:0;;174601:20;-1:-1:-1;174523:106:0:o;174284:231::-;174341:4;174358:14;174375:6;174382:2;174375:10;;;;;;;;;:::i;:::-;174358:27;;;;;;;;174375:10;;;;;;;;;174358:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;174358:27:0;;;;;;;;;-1:-1:-1;;;;;;;;174358:27:0;;;;;;;;;;-1:-1:-1;;;174358:27:0;;;;;;;;;-1:-1:-1;174446:15:0;:30;;;;:61;;-1:-1:-1;174498:9:0;;;-1:-1:-1;;;;;174480:27:0;:15;:27;;174439:68;-1:-1:-1;;174284:231:0:o;4117:191::-;4210:6;;;-1:-1:-1;;;;;4227:17:0;;;-1:-1:-1;;;;;;4227:17:0;;;;;;;4260:40;;4210:6;;;4227:17;4210:6;;4260:40;;4191:16;;4260:40;4180:128;4117:191;:::o;167156:118::-;166119:19;:17;:19::i;:::-;167216:7:::1;:14:::0;;-1:-1:-1;;167216:14:0::1;167226:4;167216:14;::::0;;167246:20:::1;167253:12;864:10:::0;;784:98;137884:318;-1:-1:-1;;;;;137992:22:0;;137988:93;;138038:31;;-1:-1:-1;;;138038:31:0;;-1:-1:-1;;;;;1697:32:1;;138038:31:0;;;1679:51:1;1652:18;;138038:31:0;1533:203:1;137988:93:0;-1:-1:-1;;;;;138091:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;138091:46:0;;;;;;;;;;138153:41;;540::1;;;138153::0;;513:18:1;138153:41:0;;;;;;;137884:318;;;:::o;27495:950::-;-1:-1:-1;;;;;27682:14:0;;;:18;27678:760;;27721:67;;-1:-1:-1;;;27721:67:0;;-1:-1:-1;;;;;27721:36:0;;;;;:67;;27758:8;;27768:4;;27774:7;;27783:4;;27721:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27721:67:0;;;;;;;;-1:-1:-1;;27721:67:0;;;;;;;;;;;;:::i;:::-;;;27717:710;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28084:6;:13;28101:1;28084:18;28080:332;;28190:39;;-1:-1:-1;;;28190:39:0;;-1:-1:-1;;;;;1697:32:1;;28190:39:0;;;1679:51:1;1652:18;;28190:39:0;1533:203:1;28080:332:0;28362:6;28356:13;28349:4;28341:6;28337:17;28330:40;27717:710;-1:-1:-1;;;;;;27836:51:0;;-1:-1:-1;;;27836:51:0;27832:185;;27958:39;;-1:-1:-1;;;27958:39:0;;-1:-1:-1;;;;;1697:32:1;;27958:39:0;;;1679:51:1;1652:18;;27958:39:0;1533:203:1;27832:185:0;27789:243;27717:710;27495:950;;;;;:::o;181126:92::-;181178:13;181202;181195:20;;;;;:::i;104075:652::-;104131:13;104182:14;104199:17;104210:5;104199:10;:17::i;:::-;104219:1;104199:21;104182:38;;104235:20;104269:6;-1:-1:-1;;;;;104258:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;104258:18:0;-1:-1:-1;104235:41:0;-1:-1:-1;104368:30:0;;;104384:4;104368:30;104427:254;-1:-1:-1;;104459:5:0;-1:-1:-1;;;104560:2:0;104549:14;;104544:32;104459:5;104531:46;104623:2;104614:11;;;-1:-1:-1;104644:21:0;104427:254;104644:21;-1:-1:-1;104702:6:0;104075:652;-1:-1:-1;;;104075:652:0:o;132745:102::-;132813:26;132823:2;132827:7;132813:26;;;;;;;;;;;;:9;:26::i;166673:132::-;166585:7;;;;166735:63;;;166771:15;;-1:-1:-1;;;166771:15:0;;;;;;;;;;;144608:174;144709:4;144770;144733:33;144754:5;;144761:4;144733:20;:33::i;:::-;:41;;144608:174;-1:-1:-1;;;;;144608:174:0:o;123736:305::-;123838:4;-1:-1:-1;;;;;;123875:40:0;;-1:-1:-1;;;123875:40:0;;:105;;-1:-1:-1;;;;;;;123932:48:0;;-1:-1:-1;;;123932:48:0;123875:105;:158;;;-1:-1:-1;;;;;;;;;;7295:40:0;;;123997:36;7195:148;136987:678;137149:9;:31;;;-1:-1:-1;;;;;;137162:18:0;;;;137149:31;137145:471;;;137197:13;137213:22;137227:7;137213:13;:22::i;:::-;137197:38;-1:-1:-1;;;;;;137366:18:0;;;;;;:35;;;137397:4;-1:-1:-1;;;;;137388:13:0;:5;-1:-1:-1;;;;;137388:13:0;;;137366:35;:69;;;;;137406:29;137423:5;137430:4;137406:16;:29::i;:::-;137405:30;137366:69;137362:144;;;137463:27;;-1:-1:-1;;;137463:27:0;;-1:-1:-1;;;;;1697:32:1;;137463:27:0;;;1679:51:1;1652:18;;137463:27:0;1533:203:1;137362:144:0;137526:9;137522:83;;;137581:7;137577:2;-1:-1:-1;;;;;137561:28:0;137570:5;-1:-1:-1;;;;;137561:28:0;;;;;;;;;;;137522:83;137182:434;137145:471;-1:-1:-1;;137628:24:0;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;137628:29:0;-1:-1:-1;;;;;137628:29:0;;;;;;;;;;136987:678::o;129094:376::-;129207:38;129221:5;129228:7;129237;129207:13;:38::i;:::-;129202:261;;-1:-1:-1;;;;;129266:19:0;;129262:190;;129313:31;;-1:-1:-1;;;129313:31:0;;;;;2746:25:1;;;2719:18;;129313:31:0;2600:177:1;129262:190:0;129392:44;;-1:-1:-1;;;129392:44:0;;-1:-1:-1;;;;;3560:32:1;;129392:44:0;;;3542:51:1;3609:18;;;3602:34;;;3515:18;;129392:44:0;3368:274:1;166882:130:0;166585:7;;;;166941:64;;166978:15;;-1:-1:-1;;;166978:15:0;;;;;;;;;;;97028:948;97081:7;;-1:-1:-1;;;97159:17:0;;97155:106;;-1:-1:-1;;;97197:17:0;;;-1:-1:-1;97243:2:0;97233:12;97155:106;97288:8;97279:5;:17;97275:106;;97326:8;97317:17;;;-1:-1:-1;97363:2:0;97353:12;97275:106;97408:8;97399:5;:17;97395:106;;97446:8;97437:17;;;-1:-1:-1;97483:2:0;97473:12;97395:106;97528:7;97519:5;:16;97515:103;;97565:7;97556:16;;;-1:-1:-1;97601:1:0;97591:11;97515:103;97645:7;97636:5;:16;97632:103;;97682:7;97673:16;;;-1:-1:-1;97718:1:0;97708:11;97632:103;97762:7;97753:5;:16;97749:103;;97799:7;97790:16;;;-1:-1:-1;97835:1:0;97825:11;97749:103;97879:7;97870:5;:16;97866:68;;97917:1;97907:11;97962:6;97028:948;-1:-1:-1;;97028:948:0:o;133074:210::-;133169:18;133175:2;133179:7;133169:5;:18::i;:::-;133198:78;864:10;133254:1;133258:2;133262:7;133271:4;133198:33;:78::i;145195:324::-;145288:7;145331:4;145288:7;145346:136;145366:16;;;145346:136;;;145419:51;145447:12;145461:5;;145467:1;145461:8;;;;;;;:::i;:::-;;;;;;;145419:27;:51::i;:::-;145404:66;-1:-1:-1;145384:3:0;;145346:136;;;-1:-1:-1;145499:12:0;145195:324;-1:-1:-1;;;;145195:324:0:o;128375:276::-;128478:4;-1:-1:-1;;;;;128515:21:0;;;;;;:128;;;128563:7;-1:-1:-1;;;;;128554:16:0;:5;-1:-1:-1;;;;;128554:16:0;;:52;;;;128574:32;128591:5;128598:7;128574:16;:32::i;:::-;128554:88;;;-1:-1:-1;127996:7:0;128023:24;;;:15;:24;;;;;;-1:-1:-1;;;;;128610:32:0;;;128023:24;;128610:32;128554:88;128495:148;128375:276;-1:-1:-1;;;;128375:276:0:o;132047:335::-;-1:-1:-1;;;;;132115:16:0;;132111:89;;132155:33;;-1:-1:-1;;;132155:33:0;;132185:1;132155:33;;;1679:51:1;1652:18;;132155:33:0;1533:203:1;132111:89:0;132210:21;132234:32;132242:2;132246:7;132263:1;132234:7;:32::i;:::-;132210:56;-1:-1:-1;;;;;;132281:27:0;;;132277:98;;132332:31;;-1:-1:-1;;;132332:31:0;;132360:1;132332:31;;;1679:51:1;1652:18;;132332:31:0;1533:203:1;139285:169:0;139360:7;139391:1;139387;:5;:59;;139652:13;139718:15;;;139754:4;139747:15;;;139801:4;139785:21;;139387:59;;;139652:13;139718:15;;;139754:4;139747:15;;;139801:4;139785:21;;139395:24;139579:245;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:180::-;651:6;704:2;692:9;683:7;679:23;675:32;672:52;;;720:1;717;710:12;672:52;-1:-1:-1;743:23:1;;592:180;-1:-1:-1;592:180:1:o;777:250::-;862:1;872:113;886:6;883:1;880:13;872:113;;;962:11;;;956:18;943:11;;;936:39;908:2;901:10;872:113;;;-1:-1:-1;;1019:1:1;1001:16;;994:27;777:250::o;1032:271::-;1074:3;1112:5;1106:12;1139:6;1134:3;1127:19;1155:76;1224:6;1217:4;1212:3;1208:14;1201:4;1194:5;1190:16;1155:76;:::i;:::-;1285:2;1264:15;-1:-1:-1;;1260:29:1;1251:39;;;;1292:4;1247:50;;1032:271;-1:-1:-1;;1032:271:1:o;1308:220::-;1457:2;1446:9;1439:21;1420:4;1477:45;1518:2;1507:9;1503:18;1495:6;1477:45;:::i;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:1;;1848:42;;1838:70;;1904:1;1901;1894:12;1838:70;1741:173;;;:::o;1919:254::-;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:1:o;2178:156::-;2244:20;;2304:4;2293:16;;2283:27;;2273:55;;2324:1;2321;2314:12;2339:256;2405:6;2413;2466:2;2454:9;2445:7;2441:23;2437:32;2434:52;;;2482:1;2479;2472:12;2434:52;2505:27;2522:9;2505:27;:::i;:::-;2495:37;;2551:38;2585:2;2574:9;2570:18;2551:38;:::i;:::-;2541:48;;2339:256;;;;;:::o;2782:328::-;2859:6;2867;2875;2928:2;2916:9;2907:7;2903:23;2899:32;2896:52;;;2944:1;2941;2934:12;2896:52;2967:29;2986:9;2967:29;:::i;:::-;2957:39;;3015:38;3049:2;3038:9;3034:18;3015:38;:::i;:::-;3005:48;;3100:2;3089:9;3085:18;3072:32;3062:42;;2782:328;;;;;:::o;3115:248::-;3183:6;3191;3244:2;3232:9;3223:7;3219:23;3215:32;3212:52;;;3260:1;3257;3250:12;3212:52;-1:-1:-1;;3283:23:1;;;3353:2;3338:18;;;3325:32;;-1:-1:-1;3115:248:1:o;4360:347::-;4425:6;4433;4486:2;4474:9;4465:7;4461:23;4457:32;4454:52;;;4502:1;4499;4492:12;4454:52;4525:29;4544:9;4525:29;:::i;:::-;4515:39;;4604:2;4593:9;4589:18;4576:32;4651:5;4644:13;4637:21;4630:5;4627:32;4617:60;;4673:1;4670;4663:12;4617:60;4696:5;4686:15;;;4360:347;;;;;:::o;4712:324::-;4787:6;4795;4803;4856:2;4844:9;4835:7;4831:23;4827:32;4824:52;;;4872:1;4869;4862:12;4824:52;4895:27;4912:9;4895:27;:::i;5041:592::-;5112:6;5120;5173:2;5161:9;5152:7;5148:23;5144:32;5141:52;;;5189:1;5186;5179:12;5141:52;5229:9;5216:23;-1:-1:-1;;;;;5299:2:1;5291:6;5288:14;5285:34;;;5315:1;5312;5305:12;5285:34;5353:6;5342:9;5338:22;5328:32;;5398:7;5391:4;5387:2;5383:13;5379:27;5369:55;;5420:1;5417;5410:12;5369:55;5460:2;5447:16;5486:2;5478:6;5475:14;5472:34;;;5502:1;5499;5492:12;5472:34;5547:7;5542:2;5533:6;5529:2;5525:15;5521:24;5518:37;5515:57;;;5568:1;5565;5558:12;5515:57;5599:2;5591:11;;;;;5621:6;;-1:-1:-1;5041:592:1;;-1:-1:-1;;;;5041:592:1:o;5638:639::-;5805:2;5857:21;;;5927:13;;5830:18;;;5949:22;;;5776:4;;5805:2;6028:15;;;;6002:2;5987:18;;;5776:4;6071:180;6085:6;6082:1;6079:13;6071:180;;;6150:13;;6165:4;6146:24;6134:37;;6226:15;;;;6191:12;;;;6107:1;6100:9;6071:180;;;-1:-1:-1;6268:3:1;;5638:639;-1:-1:-1;;;;;;5638:639:1:o;6282:186::-;6341:6;6394:2;6382:9;6373:7;6369:23;6365:32;6362:52;;;6410:1;6407;6400:12;6362:52;6433:29;6452:9;6433:29;:::i;6473:127::-;6534:10;6529:3;6525:20;6522:1;6515:31;6565:4;6562:1;6555:15;6589:4;6586:1;6579:15;6605:1138;6700:6;6708;6716;6724;6777:3;6765:9;6756:7;6752:23;6748:33;6745:53;;;6794:1;6791;6784:12;6745:53;6817:29;6836:9;6817:29;:::i;:::-;6807:39;;6865:38;6899:2;6888:9;6884:18;6865:38;:::i;:::-;6855:48;;6950:2;6939:9;6935:18;6922:32;6912:42;;7005:2;6994:9;6990:18;6977:32;-1:-1:-1;;;;;7069:2:1;7061:6;7058:14;7055:34;;;7085:1;7082;7075:12;7055:34;7123:6;7112:9;7108:22;7098:32;;7168:7;7161:4;7157:2;7153:13;7149:27;7139:55;;7190:1;7187;7180:12;7139:55;7226:2;7213:16;7248:2;7244;7241:10;7238:36;;;7254:18;;:::i;:::-;7329:2;7323:9;7297:2;7383:13;;-1:-1:-1;;7379:22:1;;;7403:2;7375:31;7371:40;7359:53;;;7427:18;;;7447:22;;;7424:46;7421:72;;;7473:18;;:::i;:::-;7513:10;7509:2;7502:22;7548:2;7540:6;7533:18;7588:7;7583:2;7578;7574;7570:11;7566:20;7563:33;7560:53;;;7609:1;7606;7599:12;7560:53;7665:2;7660;7656;7652:11;7647:2;7639:6;7635:15;7622:46;7710:1;7705:2;7700;7692:6;7688:15;7684:24;7677:35;7731:6;7721:16;;;;;;;6605:1138;;;;;;;:::o;7748:163::-;7815:20;;7875:10;7864:22;;7854:33;;7844:61;;7901:1;7898;7891:12;7916:171;7983:20;;-1:-1:-1;;;;;8032:30:1;;8022:41;;8012:69;;8077:1;8074;8067:12;8092:610;8199:6;8207;8215;8223;8231;8239;8247;8300:3;8288:9;8279:7;8275:23;8271:33;8268:53;;;8317:1;8314;8307:12;8268:53;8340:27;8357:9;8340:27;:::i;:::-;8330:37;;8414:2;8403:9;8399:18;8386:32;8376:42;;8465:2;8454:9;8450:18;8437:32;8427:42;;8488:37;8521:2;8510:9;8506:18;8488:37;:::i;:::-;8478:47;;8544:38;8577:3;8566:9;8562:19;8544:38;:::i;:::-;8534:48;;8601:38;8634:3;8623:9;8619:19;8601:38;:::i;:::-;8591:48;;8658:38;8691:3;8680:9;8676:19;8658:38;:::i;:::-;8648:48;;8092:610;;;;;;;;;;:::o;8707:260::-;8775:6;8783;8836:2;8824:9;8815:7;8811:23;8807:32;8804:52;;;8852:1;8849;8842:12;8804:52;8875:29;8894:9;8875:29;:::i;8972:822::-;9083:6;9091;9099;9107;9115;9168:3;9156:9;9147:7;9143:23;9139:33;9136:53;;;9185:1;9182;9175:12;9136:53;9208:27;9225:9;9208:27;:::i;:::-;9198:37;;9282:2;9271:9;9267:18;9254:32;9244:42;;9333:2;9322:9;9318:18;9305:32;9295:42;;9388:2;9377:9;9373:18;9360:32;-1:-1:-1;;;;;9452:2:1;9444:6;9441:14;9438:34;;;9468:1;9465;9458:12;9438:34;9506:6;9495:9;9491:22;9481:32;;9551:7;9544:4;9540:2;9536:13;9532:27;9522:55;;9573:1;9570;9563:12;9522:55;9613:2;9600:16;9639:2;9631:6;9628:14;9625:34;;;9655:1;9652;9645:12;9625:34;9708:7;9703:2;9693:6;9690:1;9686:14;9682:2;9678:23;9674:32;9671:45;9668:65;;;9729:1;9726;9719:12;9668:65;8972:822;;;;-1:-1:-1;8972:822:1;;-1:-1:-1;9760:2:1;9752:11;;9782:6;8972:822;-1:-1:-1;;;8972:822:1:o;9799:399::-;9880:6;9888;9896;9904;9957:3;9945:9;9936:7;9932:23;9928:33;9925:53;;;9974:1;9971;9964:12;9925:53;9997:27;10014:9;9997:27;:::i;:::-;9987:37;;10043;10076:2;10065:9;10061:18;10043:37;:::i;:::-;10033:47;;10099:37;10132:2;10121:9;10117:18;10099:37;:::i;:::-;10089:47;;10155:37;10188:2;10177:9;10173:18;10155:37;:::i;:::-;10145:47;;9799:399;;;;;;;:::o;11096:380::-;11175:1;11171:12;;;;11218;;;11239:61;;11293:4;11285:6;11281:17;11271:27;;11239:61;11346:2;11338:6;11335:14;11315:18;11312:38;11309:161;;11392:10;11387:3;11383:20;11380:1;11373:31;11427:4;11424:1;11417:15;11455:4;11452:1;11445:15;11309:161;;11096:380;;;:::o;11861:127::-;11922:10;11917:3;11913:20;11910:1;11903:31;11953:4;11950:1;11943:15;11977:4;11974:1;11967:15;11993:168;12066:9;;;12097;;12114:15;;;12108:22;;12094:37;12084:71;;12135:18;;:::i;12298:217::-;12338:1;12364;12354:132;;12408:10;12403:3;12399:20;12396:1;12389:31;12443:4;12440:1;12433:15;12471:4;12468:1;12461:15;12354:132;-1:-1:-1;12500:9:1;;12298:217::o;12520:332::-;12722:2;12704:21;;;12761:1;12741:18;;;12734:29;-1:-1:-1;;;12794:2:1;12779:18;;12772:39;12843:2;12828:18;;12520:332::o;12857:127::-;12918:10;12913:3;12909:20;12906:1;12899:31;12949:4;12946:1;12939:15;12973:4;12970:1;12963:15;12989:175;13057:10;13100;;;13088;;;13084:27;;13123:12;;;13120:38;;;13138:18;;:::i;:::-;13120:38;12989:175;;;;:::o;13169:128::-;13236:9;;;13257:11;;;13254:37;;;13271:18;;:::i;13428:543::-;13530:2;13525:3;13522:11;13519:446;;;13566:1;13590:5;13587:1;13580:16;13634:4;13631:1;13621:18;13704:2;13692:10;13688:19;13685:1;13681:27;13675:4;13671:38;13740:4;13728:10;13725:20;13722:47;;;-1:-1:-1;13763:4:1;13722:47;13818:2;13813:3;13809:12;13806:1;13802:20;13796:4;13792:31;13782:41;;13873:82;13891:2;13884:5;13881:13;13873:82;;;13936:17;;;13917:1;13906:13;13873:82;;14147:1206;-1:-1:-1;;;;;14266:3:1;14263:27;14260:53;;;14293:18;;:::i;:::-;14322:94;14412:3;14372:38;14404:4;14398:11;14372:38;:::i;:::-;14366:4;14322:94;:::i;:::-;14442:1;14467:2;14462:3;14459:11;14484:1;14479:616;;;;15139:1;15156:3;15153:93;;;-1:-1:-1;15212:19:1;;;15199:33;15153:93;-1:-1:-1;;14104:1:1;14100:11;;;14096:24;14092:29;14082:40;14128:1;14124:11;;;14079:57;15259:78;;14452:895;;14479:616;13375:1;13368:14;;;13412:4;13399:18;;-1:-1:-1;;14515:17:1;;;14616:9;14638:229;14652:7;14649:1;14646:14;14638:229;;;14741:19;;;14728:33;14713:49;;14848:4;14833:20;;;;14801:1;14789:14;;;;14668:12;14638:229;;;14642:3;14895;14886:7;14883:16;14880:159;;;15019:1;15015:6;15009:3;15003;15000:1;14996:11;14992:21;14988:34;14984:39;14971:9;14966:3;14962:19;14949:33;14945:79;14937:6;14930:95;14880:159;;;15082:1;15076:3;15073:1;15069:11;15065:19;15059:4;15052:33;14452:895;;14147:1206;;;:::o;15358:175::-;15395:3;15439:4;15432:5;15428:16;15468:4;15459:7;15456:17;15453:43;;15476:18;;:::i;:::-;15525:1;15512:15;;15358:175;-1:-1:-1;;15358:175:1:o;16127:496::-;16306:3;16344:6;16338:13;16360:66;16419:6;16414:3;16407:4;16399:6;16395:17;16360:66;:::i;:::-;16489:13;;16448:16;;;;16511:70;16489:13;16448:16;16558:4;16546:17;;16511:70;:::i;:::-;16597:20;;16127:496;-1:-1:-1;;;;16127:496:1:o;16970:125::-;17035:9;;;17056:10;;;17053:36;;;17069:18;;:::i;21885:172::-;21952:10;21982;;;21994;;;21978:27;;22017:11;;;22014:37;;;22031:18;;:::i;22794:489::-;-1:-1:-1;;;;;23063:15:1;;;23045:34;;23115:15;;23110:2;23095:18;;23088:43;23162:2;23147:18;;23140:34;;;23210:3;23205:2;23190:18;;23183:31;;;22988:4;;23231:46;;23257:19;;23249:6;23231:46;:::i;:::-;23223:54;22794:489;-1:-1:-1;;;;;;22794:489:1:o;23288:249::-;23357:6;23410:2;23398:9;23389:7;23385:23;23381:32;23378:52;;;23426:1;23423;23416:12;23378:52;23458:9;23452:16;23477:30;23501:5;23477:30;:::i
Swarm Source
ipfs://1d4381b6db6d68d26ac1d53ea4139973e3f66c7a3b2882fed820ecdc10f46142
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MON
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.