Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 107 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Approve | 19213474 | 307 days ago | IN | 0 ETH | 0.00397932 | ||||
Approve | 19213215 | 307 days ago | IN | 0 ETH | 0.00167448 | ||||
Approve | 19208426 | 308 days ago | IN | 0 ETH | 0.00175322 | ||||
Approve | 19205598 | 308 days ago | IN | 0 ETH | 0.00140423 | ||||
Approve | 19205183 | 308 days ago | IN | 0 ETH | 0.00127294 | ||||
Approve | 19204752 | 308 days ago | IN | 0 ETH | 0.00067113 | ||||
Approve | 19204691 | 308 days ago | IN | 0 ETH | 0.00116021 | ||||
Transfer | 19204682 | 308 days ago | IN | 0 ETH | 0.00328296 | ||||
Approve | 19204678 | 308 days ago | IN | 0 ETH | 0.00122877 | ||||
Transfer | 19204678 | 308 days ago | IN | 0 ETH | 0.00337475 | ||||
Transfer | 19204676 | 308 days ago | IN | 0 ETH | 0.00150944 | ||||
Transfer | 19204673 | 308 days ago | IN | 0 ETH | 0.00138287 | ||||
Transfer | 19204671 | 308 days ago | IN | 0 ETH | 0.00267253 | ||||
Transfer | 19204669 | 308 days ago | IN | 0 ETH | 0.00482237 | ||||
Approve | 19204667 | 308 days ago | IN | 0 ETH | 0.00075824 | ||||
Transfer | 19204666 | 308 days ago | IN | 0 ETH | 0.00133266 | ||||
Transfer | 19204664 | 308 days ago | IN | 0 ETH | 0.00333706 | ||||
Transfer | 19204662 | 308 days ago | IN | 0 ETH | 0.00098351 | ||||
Transfer | 19204660 | 308 days ago | IN | 0 ETH | 0.003802 | ||||
Transfer | 19204658 | 308 days ago | IN | 0 ETH | 0.00094078 | ||||
Transfer | 19204655 | 308 days ago | IN | 0 ETH | 0.00142851 | ||||
Transfer | 19204652 | 308 days ago | IN | 0 ETH | 0.00149355 | ||||
Transfer | 19204650 | 308 days ago | IN | 0 ETH | 0.00082301 | ||||
Transfer | 19204650 | 308 days ago | IN | 0 ETH | 0.00082272 | ||||
Transfer | 19204644 | 308 days ago | IN | 0 ETH | 0.00095731 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
MEME404
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-02-10 */ //SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } interface IERC404 is IERC165 { event ERC20Approval(address owner, address spender, uint256 value); event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); event ERC721Approval( address indexed owner, address indexed spender, uint256 indexed id ); event ERC20Transfer(address indexed from, address indexed to, uint256 amount); event ERC721Transfer( address indexed from, address indexed to, uint256 indexed id ); error NotFound(); error InvalidId(); error AlreadyExists(); error InvalidRecipient(); error InvalidSender(); error InvalidSpender(); error InvalidOperator(); error UnsafeRecipient(); error NotWhitelisted(); error Unauthorized(); error InsufficientAllowance(); error DecimalsTooLow(); error CannotRemoveFromWhitelist(); error PermitDeadlineExpired(); error InvalidSigner(); error InvalidApproval(); error OwnedIndexOverflow(); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint256); function erc20TotalSupply() external view returns (uint256); function erc721TotalSupply() external view returns (uint256); function balanceOf(address owner_) external view returns (uint256); function erc721BalanceOf(address owner_) external view returns (uint256); function erc20BalanceOf(address owner_) external view returns (uint256); function whitelist(address account_) external view returns (bool); function isApprovedForAll( address owner_, address operator_ ) external view returns (bool); function allowance( address owner_, address spender_ ) external view returns (uint256); function owned(address owner_) external view returns (uint256[] memory); function ownerOf(uint256 id_) external view returns (address erc721Owner); function tokenURI(uint256 id_) external view returns (string memory); function approve( address spender_, uint256 valueOrId_ ) external returns (bool); function setApprovalForAll(address operator_, bool approved_) external; function transferFrom( address from_, address to_, uint256 valueOrId_ ) external returns (bool); function transfer(address to_, uint256 amount_) external returns (bool); function erc721TokensBankedInQueue() external view returns (uint256); function safeTransferFrom(address from_, address to_, uint256 id_) external; function safeTransferFrom( address from_, address to_, uint256 id_, bytes calldata data_ ) external; function DOMAIN_SEPARATOR() external view returns (bytes32); function permit( address owner_, address spender_, uint256 value_, uint256 deadline_, uint8 v_, bytes32 r_, bytes32 s_ ) external; } abstract contract ERC721Receiver { function onERC721Received( address, address, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC721Receiver.onERC721Received.selector; } } /** * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that * the existing queue contents are left in storage. * * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be * used in storage, and not in memory. * ```solidity * DoubleEndedQueue.Bytes32Deque queue; * ``` */ library DoubleEndedQueue { /** * @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty. */ error QueueEmpty(); /** * @dev A push operation couldn't be completed due to the queue being full. */ error QueueFull(); /** * @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds. */ error QueueOutOfBounds(); /** * @dev Indices are 128 bits so begin and end are packed in a single storage slot for efficient access. * * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and * lead to unexpected behavior. * * The first item is at data[begin] and the last item is at data[end - 1]. This range can wrap around. */ struct Uint256Deque { uint128 _begin; uint128 _end; mapping(uint128 index => uint256) _data; } /** * @dev Inserts an item at the end of the queue. * * Reverts with {QueueFull} if the queue is full. */ function pushBack(Uint256Deque storage deque, uint256 value) internal { unchecked { uint128 backIndex = deque._end; if (backIndex + 1 == deque._begin) revert QueueFull(); deque._data[backIndex] = value; deque._end = backIndex + 1; } } /** * @dev Removes the item at the end of the queue and returns it. * * Reverts with {QueueEmpty} if the queue is empty. */ function popBack( Uint256Deque storage deque ) internal returns (uint256 value) { unchecked { uint128 backIndex = deque._end; if (backIndex == deque._begin) revert QueueEmpty(); --backIndex; value = deque._data[backIndex]; delete deque._data[backIndex]; deque._end = backIndex; } } /** * @dev Inserts an item at the beginning of the queue. * * Reverts with {QueueFull} if the queue is full. */ function pushFront(Uint256Deque storage deque, uint256 value) internal { unchecked { uint128 frontIndex = deque._begin - 1; if (frontIndex == deque._end) revert QueueFull(); deque._data[frontIndex] = value; deque._begin = frontIndex; } } /** * @dev Removes the item at the beginning of the queue and returns it. * * Reverts with `QueueEmpty` if the queue is empty. */ function popFront( Uint256Deque storage deque ) internal returns (uint256 value) { unchecked { uint128 frontIndex = deque._begin; if (frontIndex == deque._end) revert QueueEmpty(); value = deque._data[frontIndex]; delete deque._data[frontIndex]; deque._begin = frontIndex + 1; } } /** * @dev Returns the item at the beginning of the queue. * * Reverts with `QueueEmpty` if the queue is empty. */ function front( Uint256Deque storage deque ) internal view returns (uint256 value) { if (empty(deque)) revert QueueEmpty(); return deque._data[deque._begin]; } /** * @dev Returns the item at the end of the queue. * * Reverts with `QueueEmpty` if the queue is empty. */ function back( Uint256Deque storage deque ) internal view returns (uint256 value) { if (empty(deque)) revert QueueEmpty(); unchecked { return deque._data[deque._end - 1]; } } /** * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at * `length(deque) - 1`. * * Reverts with `QueueOutOfBounds` if the index is out of bounds. */ function at( Uint256Deque storage deque, uint256 index ) internal view returns (uint256 value) { if (index >= length(deque)) revert QueueOutOfBounds(); // By construction, length is a uint128, so the check above ensures that index can be safely downcast to uint128 unchecked { return deque._data[deque._begin + uint128(index)]; } } /** * @dev Resets the queue back to being empty. * * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses * out on potential gas refunds. */ function clear(Uint256Deque storage deque) internal { deque._begin = 0; deque._end = 0; } /** * @dev Returns the number of items in the queue. */ function length(Uint256Deque storage deque) internal view returns (uint256) { unchecked { return uint256(deque._end - deque._begin); } } /** * @dev Returns true if the queue is empty. */ function empty(Uint256Deque storage deque) internal view returns (bool) { return deque._end == deque._begin; } } /** * @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; } } /** * @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); } } /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } } /** * @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]. */ // 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 { /// @solidity memory-safe-assembly assembly { mstore(0x00, shl(0xe0, 0x4e487b71)) mstore(0x04, code) revert(0x00, 0x24) } } } /** * @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) { /// @solidity memory-safe-assembly assembly { u := iszero(iszero(b)) } } } /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds 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 a == 0 ? 0 : (a - 1) / b + 1; } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(denominator == 0 ? Panic.DIVISION_BY_ZERO : Panic.UNDER_OVERFLOW); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @dev Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, expect 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 Ferma's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. */ 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 x < 0 ? (n - uint256(-x)) : uint256(x); // Wrap the result if it's negative. } } /** * @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) { if (m == 0) { Panic.panic(Panic.DIVISION_BY_ZERO); } else { revert Address.FailedInnerCall(); } } 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 has 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); /// @solidity memory-safe-assembly assembly { 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 Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 1); } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } } /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // 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 `bytes(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } } /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), 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 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 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. */ 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. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ 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 leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(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}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ 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. * * 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). */ 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 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 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[](totalHashes); 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 < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ 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 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 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[](totalHashes); 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 < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } } interface IERC404MerkleClaim { error AirdropAlreadyClaimed(); error NotEligibleForAirdrop(); error AirdropIsClosed(); function verifyProof( bytes32[] memory proof_, address claimer_, uint256 value_ ) external view returns (bool); function airdropMint(bytes32[] memory proof_, uint256 value_) external; } abstract contract ERC404MerkleClaim is IERC404MerkleClaim { bool public airdropIsOpen; bytes32 public airdropMerkleRoot; mapping(address => bool) public hasClaimedAirdrop; modifier whenAirdropIsOpen() { if (airdropMerkleRoot == 0 || !airdropIsOpen) { revert AirdropIsClosed(); } _; } function verifyProof( bytes32[] memory proof_, address claimer_, uint256 value_ ) public view returns (bool) { bytes32 leaf = keccak256( bytes.concat(keccak256(abi.encode(claimer_, value_))) ); if (MerkleProof.verify(proof_, airdropMerkleRoot, leaf)) { return true; } return false; } // To use, override this function in your contract, call // super.airdropMint(proof_) within your override function, then mint tokens. function airdropMint( bytes32[] memory proof_, uint256 value_ ) public virtual whenAirdropIsOpen { _validateAndRecordAirdropClaim(proof_, msg.sender, value_); } function _setAirdropMerkleRoot(bytes32 airdropMerkleRoot_) internal { airdropMerkleRoot = airdropMerkleRoot_; } function _toggleAirdropIsOpen() internal { airdropIsOpen = !airdropIsOpen; } function _validateAndRecordAirdropClaim( bytes32[] memory proof_, address claimer_, uint256 value_ ) internal { // Check that the address is eligible. if (!verifyProof(proof_, claimer_, value_)) { revert NotEligibleForAirdrop(); } // Check if address has already claimed their airdrop. if (hasClaimedAirdrop[claimer_]) { revert AirdropAlreadyClaimed(); } // Mark address as claimed. hasClaimedAirdrop[claimer_] = true; } } abstract contract ERC404 is IERC404 { using DoubleEndedQueue for DoubleEndedQueue.Uint256Deque; /// @dev The queue of ERC-721 tokens stored in the contract. DoubleEndedQueue.Uint256Deque private _storedERC721Ids; /// @dev Token name string public name; /// @dev Token symbol string public symbol; /// @dev Decimals for ERC-20 representation uint8 public immutable decimals; /// @dev Units for ERC-20 representation uint256 public immutable units; /// @dev Total supply in ERC-20 representation uint256 public totalSupply; /// @dev Current mint counter which also represents the highest /// minted id, monotonically increasing to ensure accurate ownership uint256 internal _minted; /// @dev Initial chain id for EIP-2612 support uint256 internal immutable INITIAL_CHAIN_ID; /// @dev Initial domain separator for EIP-2612 support bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; /// @dev Balance of user in ERC-20 representation mapping(address => uint256) public balanceOf; /// @dev Allowance of user in ERC-20 representation mapping(address => mapping(address => uint256)) public allowance; /// @dev Approval in ERC-721 representaion mapping(uint256 => address) public getApproved; /// @dev Approval for all in ERC-721 representation mapping(address => mapping(address => bool)) public isApprovedForAll; /// @dev Packed representation of ownerOf and owned indices mapping(uint256 => uint256) internal _ownedData; /// @dev Array of owned ids in ERC-721 representation mapping(address => uint256[]) internal _owned; /// @dev Addresses whitelisted from minting / banking for gas savings (pairs, routers, etc) mapping(address => bool) public whitelist; /// @dev EIP-2612 nonces mapping(address => uint256) public nonces; /// @dev Address bitmask for packed ownership data uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1; /// @dev Owned index bitmask for packed ownership data uint256 private constant _BITMASK_OWNED_INDEX = ((1 << 96) - 1) << 160; constructor(string memory name_, string memory symbol_, uint8 decimals_) { name = name_; symbol = symbol_; if (decimals_ < 18) { revert DecimalsTooLow(); } decimals = decimals_; units = 10 ** decimals; // EIP-2612 initialization INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = _computeDomainSeparator(); } /// @notice Function to find owner of a given ERC-721 token function ownerOf( uint256 id_ ) public view virtual returns (address erc721Owner) { erc721Owner = _getOwnerOf(id_); // If the id_ is beyond the range of minted tokens, is 0, or the token is not owned by anyone, revert. if (id_ > _minted || id_ == 0 || erc721Owner == address(0)) { revert NotFound(); } } function owned( address owner_ ) public view virtual returns (uint256[] memory) { return _owned[owner_]; } function erc721BalanceOf( address owner_ ) public view virtual returns (uint256) { return _owned[owner_].length; } function erc20BalanceOf( address owner_ ) public view virtual returns (uint256) { return balanceOf[owner_]; } function erc20TotalSupply() public view virtual returns (uint256) { return totalSupply; } function erc721TotalSupply() public view virtual returns (uint256) { return _minted; } function erc721TokensBankedInQueue() public view virtual returns (uint256) { return _storedERC721Ids.length(); } /// @notice tokenURI must be implemented by child contract function tokenURI(uint256 id_) public view virtual returns (string memory); /// @notice Function for token approvals /// @dev This function assumes the operator is attempting to approve an ERC-721 /// if valueOrId is less than the minted count. Note: Unlike setApprovalForAll, /// spender_ must be allowed to be 0x0 so that approval can be revoked. function approve( address spender_, uint256 valueOrId_ ) public virtual returns (bool) { // The ERC-721 tokens are 1-indexed, so 0 is not a valid id and indicates that // operator is attempting to set the ERC-20 allowance to 0. if (valueOrId_ <= _minted && valueOrId_ > 0) { // Intention is to approve as ERC-721 token (id). uint256 id = valueOrId_; address erc721Owner = _getOwnerOf(id); if ( msg.sender != erc721Owner && !isApprovedForAll[erc721Owner][msg.sender] ) { revert Unauthorized(); } getApproved[id] = spender_; emit ERC721Approval(erc721Owner, spender_, id); } else { // Prevent granting 0x0 an ERC-20 allowance. if (spender_ == address(0)) { revert InvalidSpender(); } // Intention is to approve as ERC-20 token (value). uint256 value = valueOrId_; allowance[msg.sender][spender_] = value; emit ERC20Approval(msg.sender, spender_, value); } return true; } /// @notice Function for ERC-721 approvals function setApprovalForAll(address operator_, bool approved_) public virtual { // Prevent approvals to 0x0. if (operator_ == address(0)) { revert InvalidOperator(); } isApprovedForAll[msg.sender][operator_] = approved_; emit ApprovalForAll(msg.sender, operator_, approved_); } /// @notice Function for mixed transfers from an operator that may be different than 'from'. /// @dev This function assumes the operator is attempting to transfer an ERC-721 /// if valueOrId is less than or equal to current max id. function transferFrom( address from_, address to_, uint256 valueOrId_ ) public virtual returns (bool) { // Prevent transferring tokens from 0x0. if (from_ == address(0)) { revert InvalidSender(); } // Prevent burning tokens to 0x0. if (to_ == address(0)) { revert InvalidRecipient(); } if (valueOrId_ <= _minted) { // Intention is to transfer as ERC-721 token (id). uint256 id = valueOrId_; if (from_ != _getOwnerOf(id)) { revert Unauthorized(); } // Check that the operator is either the sender or approved for the transfer. if ( msg.sender != from_ && !isApprovedForAll[from_][msg.sender] && msg.sender != getApproved[id] ) { revert Unauthorized(); } // Transfer 1 * units ERC-20 and 1 ERC-721 token. _transferERC20(from_, to_, units); _transferERC721(from_, to_, id); } else { // Intention is to transfer as ERC-20 token (value). uint256 value = valueOrId_; uint256 allowed = allowance[from_][msg.sender]; // Check that the operator has sufficient allowance. if (allowed != type(uint256).max) { allowance[from_][msg.sender] = allowed - value; } // Transferring ERC-20s directly requires the _transfer function. _transferERC20WithERC721(from_, to_, value); } return true; } /// @notice Function for ERC-20 transfers. /// @dev This function assumes the operator is attempting to transfer as ERC-20 /// given this function is only supported on the ERC-20 interface function transfer(address to_, uint256 value_) public virtual returns (bool) { // Prevent burning tokens to 0x0. if (to_ == address(0)) { revert InvalidRecipient(); } // Transferring ERC-20s directly requires the _transfer function. return _transferERC20WithERC721(msg.sender, to_, value_); } /// @notice Function for ERC-721 transfers with contract support. function safeTransferFrom( address from_, address to_, uint256 id_ ) public virtual { transferFrom(from_, to_, id_); if ( to_.code.length != 0 && ERC721Receiver(to_).onERC721Received(msg.sender, from_, id_, "") != ERC721Receiver.onERC721Received.selector ) { revert UnsafeRecipient(); } } /// @notice Function for ERC-721 transfers with contract support and callback data. function safeTransferFrom( address from_, address to_, uint256 id_, bytes calldata data_ ) public virtual { transferFrom(from_, to_, id_); if ( to_.code.length != 0 && ERC721Receiver(to_).onERC721Received(msg.sender, from_, id_, data_) != ERC721Receiver.onERC721Received.selector ) { revert UnsafeRecipient(); } } /// @notice Function for EIP-2612 permits function permit( address owner_, address spender_, uint256 value_, uint256 deadline_, uint8 v_, bytes32 r_, bytes32 s_ ) public virtual { if (deadline_ < block.timestamp) { revert PermitDeadlineExpired(); } if (value_ <= _minted && value_ > 0) { revert InvalidApproval(); } if (spender_ == address(0)) { revert InvalidSpender(); } unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner_, spender_, value_, nonces[owner_]++, deadline_ ) ) ) ), v_, r_, s_ ); if (recoveredAddress == address(0) || recoveredAddress != owner_) { revert InvalidSigner(); } allowance[recoveredAddress][spender_] = value_; } emit ERC20Approval(owner_, spender_, value_); } /// @notice Returns domain initial domain separator, or recomputes if chain id is not equal to initial chain id function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : _computeDomainSeparator(); } function supportsInterface( bytes4 interfaceId ) public view virtual returns (bool) { return interfaceId == type(IERC404).interfaceId || interfaceId == type(IERC165).interfaceId; } /// @notice Internal function to compute domain separator for EIP-2612 permits function _computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /// @notice This is the lowest level ERC-20 transfer function, which /// should be used for both normal ERC-20 transfers as well as minting. /// Note that this function allows transfers to and from 0x0. function _transferERC20( address from_, address to_, uint256 value_ ) internal virtual { // Minting is a special case for which we should not check the balance of // the sender, and we should increase the total supply. if (from_ == address(0)) { totalSupply += value_; } else { // Deduct value from sender's balance. balanceOf[from_] -= value_; } // Update the recipient's balance. // Can be unchecked because on mint, adding to totalSupply is checked, and on transfer balance deduction is checked. unchecked { balanceOf[to_] += value_; } emit ERC20Transfer(from_, to_, value_); } /// @notice Consolidated record keeping function for transferring ERC-721s. /// @dev Assign the token to the new owner, and remove from the old owner. /// Note that this function allows transfers to and from 0x0. function _transferERC721( address from_, address to_, uint256 id_ ) internal virtual { // If this is not a mint, handle record keeping for transfer from previous owner. if (from_ != address(0)) { // On transfer of an NFT, any previous approval is reset. delete getApproved[id_]; uint256 updatedId = _owned[from_][_owned[from_].length - 1]; if (updatedId != id_) { uint256 updatedIndex = _getOwnedIndex(id_); // update _owned for sender _owned[from_][updatedIndex] = updatedId; // update index for the moved id _setOwnedIndex(updatedId, updatedIndex); } // pop _owned[from_].pop(); } if (to_ != address(0)) { // Update owner of the token to the new owner. _setOwnerOf(id_, to_); // Push token onto the new owner's stack. _owned[to_].push(id_); // Update index for new owner's stack. _setOwnedIndex(id_, _owned[to_].length - 1); } else { delete _ownedData[id_]; } emit ERC721Transfer(from_, to_, id_); } /// @notice Internal function for ERC-20 transfers. Also handles any ERC-721 transfers that may be required. function _transferERC20WithERC721( address from_, address to_, uint256 value_ ) internal virtual returns (bool) { uint256 erc20BalanceOfSenderBefore = erc20BalanceOf(from_); uint256 erc20BalanceOfReceiverBefore = erc20BalanceOf(to_); _transferERC20(from_, to_, value_); // Preload for gas savings on branches bool isFromWhitelisted = whitelist[from_]; bool isToWhitelisted = whitelist[to_]; // Skip _withdrawAndStoreERC721 and/or _retrieveOrMintERC721 for whitelisted addresses // 1) to save gas // 2) because whitelisted addresses won't always have/need ERC-721s corresponding to their ERC20s. if (isFromWhitelisted && isToWhitelisted) { // Case 1) Both sender and recipient are whitelisted. No ERC-721s need to be transferred. // NOOP. } else if (isFromWhitelisted) { // Case 2) The sender is whitelisted, but the recipient is not. Contract should not attempt // to transfer ERC-721s from the sender, but the recipient should receive ERC-721s // from the bank/minted for any whole number increase in their balance. // Only cares about whole number increments. uint256 tokensToRetrieveOrMint = (balanceOf[to_] / units) - (erc20BalanceOfReceiverBefore / units); for (uint256 i = 0; i < tokensToRetrieveOrMint; i++) { _retrieveOrMintERC721(to_); } } else if (isToWhitelisted) { // Case 3) The sender is not whitelisted, but the recipient is. Contract should attempt // to withdraw and store ERC-721s from the sender, but the recipient should not // receive ERC-721s from the bank/minted. // Only cares about whole number increments. uint256 tokensToWithdrawAndStore = (erc20BalanceOfSenderBefore / units) - (balanceOf[from_] / units); for (uint256 i = 0; i < tokensToWithdrawAndStore; i++) { _withdrawAndStoreERC721(from_); } } else { // Case 4) Neither the sender nor the recipient are whitelisted. // Strategy: // 1. First deal with the whole tokens. These are easy and will just be transferred. // 2. Look at the fractional part of the value: // a) If it causes the sender to lose a whole token that was represented by an NFT due to a // fractional part being transferred, withdraw and store an additional NFT from the sender. // b) If it causes the receiver to gain a whole new token that should be represented by an NFT // due to receiving a fractional part that completes a whole token, retrieve or mint an NFT to the recevier. // Whole tokens worth of ERC-20s get transferred as ERC-721s without any burning/minting. uint256 nftsToTransfer = value_ / units; for (uint256 i = 0; i < nftsToTransfer; i++) { // Pop from sender's ERC-721 stack and transfer them (LIFO) uint256 indexOfLastToken = _owned[from_].length - 1; uint256 tokenId = _owned[from_][indexOfLastToken]; _transferERC721(from_, to_, tokenId); } // If the sender's transaction changes their holding from a fractional to a non-fractional // amount (or vice versa), adjust ERC-721s. // // Check if the send causes the sender to lose a whole token that was represented by an ERC-721 // due to a fractional part being transferred. // // To check this, look if subtracting the fractional amount from the balance causes the balance to // drop below the original balance % units, which represents the number of whole tokens they started with. uint256 fractionalAmount = value_ % units; if ( (erc20BalanceOfSenderBefore - fractionalAmount) / units < (erc20BalanceOfSenderBefore / units) ) { _withdrawAndStoreERC721(from_); } // Check if the receive causes the receiver to gain a whole new token that should be represented // by an NFT due to receiving a fractional part that completes a whole token. if ( (erc20BalanceOfReceiverBefore + fractionalAmount) / units > (erc20BalanceOfReceiverBefore / units) ) { _retrieveOrMintERC721(to_); } } return true; } /// @notice Internal function for ERC20 minting /// @dev This function will allow minting of new ERC20s. /// If mintCorrespondingERC721s_ is true, it will also mint the corresponding ERC721s. function _mintERC20( address to_, uint256 value_, bool mintCorrespondingERC721s_ ) internal virtual { /// You cannot mint to the zero address (you can't mint and immediately burn in the same transfer). if (to_ == address(0)) { revert InvalidRecipient(); } _transferERC20(address(0), to_, value_); // If mintCorrespondingERC721s_ is true, mint the corresponding ERC721s. if (mintCorrespondingERC721s_) { uint256 nftsToRetrieveOrMint = value_ / units; for (uint256 i = 0; i < nftsToRetrieveOrMint; i++) { _retrieveOrMintERC721(to_); } } } /// @notice Internal function for ERC-721 minting and retrieval from the bank. /// @dev This function will allow minting of new ERC-721s up to the total fractional supply. It will /// first try to pull from the bank, and if the bank is empty, it will mint a new token. function _retrieveOrMintERC721(address to_) internal virtual { if (to_ == address(0)) { revert InvalidRecipient(); } uint256 id; if (!DoubleEndedQueue.empty(_storedERC721Ids)) { // If there are any tokens in the bank, use those first. // Pop off the end of the queue (FIFO). id = _storedERC721Ids.popBack(); } else { // Otherwise, mint a new token, should not be able to go over the total fractional supply. _minted++; id = _minted; } address erc721Owner = _getOwnerOf(id); // The token should not already belong to anyone besides 0x0 or this contract. // If it does, something is wrong, as this should never happen. if (erc721Owner != address(0)) { revert AlreadyExists(); } // Transfer the token to the recipient, either transferring from the contract's bank or minting. _transferERC721(erc721Owner, to_, id); } /// @notice Internal function for ERC-721 deposits to bank (this contract). /// @dev This function will allow depositing of ERC-721s to the bank, which can be retrieved by future minters. function _withdrawAndStoreERC721(address from_) internal virtual { if (from_ == address(0)) { revert InvalidSender(); } // Retrieve the latest token added to the owner's stack (LIFO). uint256 id = _owned[from_][_owned[from_].length - 1]; // Transfer the token to the contract. _transferERC721(from_, address(0), id); // Record the token in the contract's bank queue. _storedERC721Ids.pushFront(id); } /// @notice Initialization function to set pairs / etc, saving gas by avoiding mint / burn on unnecessary targets function _setWhitelist(address target_, bool state_) internal virtual { // If the target has at least 1 full ERC-20 token, they should not be removed from the whitelist // because if they were and then they attempted to transfer, it would revert as they would not // necessarily have ehough ERC-721s to bank. if (erc20BalanceOf(target_) >= units && !state_) { revert CannotRemoveFromWhitelist(); } whitelist[target_] = state_; } function _getOwnerOf( uint256 id_ ) internal view virtual returns (address ownerOf_) { uint256 data = _ownedData[id_]; assembly { ownerOf_ := and(data, _BITMASK_ADDRESS) } } function _setOwnerOf(uint256 id_, address owner_) internal virtual { uint256 data = _ownedData[id_]; assembly { data := add( and(data, _BITMASK_OWNED_INDEX), and(owner_, _BITMASK_ADDRESS) ) } _ownedData[id_] = data; } function _getOwnedIndex( uint256 id_ ) internal view virtual returns (uint256 ownedIndex_) { uint256 data = _ownedData[id_]; assembly { ownedIndex_ := shl(data, 160) } } function _setOwnedIndex(uint256 id_, uint256 index_) internal virtual { uint256 data = _ownedData[id_]; if (index_ > _BITMASK_OWNED_INDEX >> 160) { revert OwnedIndexOverflow(); } assembly { data := add( and(data, _BITMASK_ADDRESS), and(shl(index_, 160), _BITMASK_OWNED_INDEX) ) } _ownedData[id_] = data; } } contract MEME404 is Ownable, ERC404, ERC404MerkleClaim { constructor( string memory name_, string memory symbol_, uint8 decimals_, uint256 maxTotalSupplyERC721_, address initialOwner_, address initialMintRecipient_ ) ERC404(name_, symbol_, decimals_) Ownable(initialOwner_) { // Do not mint the ERC721s to the initial owner, as it's a waste of gas. _setWhitelist(initialMintRecipient_, true); _mintERC20(initialMintRecipient_, maxTotalSupplyERC721_ * units, false); } function tokenURI(uint256 id_) public pure override returns (string memory) { return string.concat("https://silver-tropical-guanaco-683.mypinata.cloud/ipfs/QmeANZFEcHPajwDy27VnDbs7pZvZuBGFNLE3PDzWZpK66S/", Strings.toString(id_), ".json"); } function airdropMint( bytes32[] memory proof_, uint256 value_ ) public override whenAirdropIsOpen { super.airdropMint(proof_, value_); _mintERC20(msg.sender, value_, true); } function setAirdropMerkleRoot(bytes32 airdropMerkleRoot_) external onlyOwner { _setAirdropMerkleRoot(airdropMerkleRoot_); } function toggleAirdropIsOpen() external onlyOwner { _toggleAirdropIsOpen(); } function setWhitelist(address account_, bool value_) external onlyOwner { _setWhitelist(account_, value_); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint8","name":"decimals_","type":"uint8"},{"internalType":"uint256","name":"maxTotalSupplyERC721_","type":"uint256"},{"internalType":"address","name":"initialOwner_","type":"address"},{"internalType":"address","name":"initialMintRecipient_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AirdropAlreadyClaimed","type":"error"},{"inputs":[],"name":"AirdropIsClosed","type":"error"},{"inputs":[],"name":"AlreadyExists","type":"error"},{"inputs":[],"name":"CannotRemoveFromWhitelist","type":"error"},{"inputs":[],"name":"DecimalsTooLow","type":"error"},{"inputs":[],"name":"InsufficientAllowance","type":"error"},{"inputs":[],"name":"InvalidApproval","type":"error"},{"inputs":[],"name":"InvalidId","type":"error"},{"inputs":[],"name":"InvalidOperator","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidSpender","type":"error"},{"inputs":[],"name":"NotEligibleForAirdrop","type":"error"},{"inputs":[],"name":"NotFound","type":"error"},{"inputs":[],"name":"NotWhitelisted","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":"OwnedIndexOverflow","type":"error"},{"inputs":[],"name":"PermitDeadlineExpired","type":"error"},{"inputs":[],"name":"QueueEmpty","type":"error"},{"inputs":[],"name":"QueueFull","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnsafeRecipient","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"ERC20Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ERC721Approval","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":"id","type":"uint256"}],"name":"ERC721Transfer","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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airdropIsOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airdropMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"airdropMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"valueOrId_","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"erc20BalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc20TotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"erc721BalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc721TokensBankedInQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc721TotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasClaimedAirdrop","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"owned","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"erc721Owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"id_","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":"id_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"airdropMerkleRoot_","type":"bytes32"}],"name":"setAirdropMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator_","type":"address"},{"internalType":"bool","name":"approved_","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"},{"internalType":"bool","name":"value_","type":"bool"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleAirdropIsOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"valueOrId_","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"units","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"},{"internalType":"address","name":"claimer_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"verifyProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
61010060405234801562000011575f80fd5b5060405162003258380380620032588339810160408190526200003491620007fe565b858585846001600160a01b0381166200006657604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b62000071816200011a565b5060036200008084826200092b565b5060046200008f83826200092b565b5060128160ff161015620000b6576040516398790fd560e01b815260040160405180910390fd5b60ff81166080819052620000cc90600a62000b06565b60a0524660c052620000dd62000169565b60e05250620000f29150829050600162000204565b6200010e8160a0518562000107919062000b1d565b5f62000275565b50505050505062000c40565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60036040516200019c919062000b37565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60a0516001600160a01b0383165f90815260076020526040902054101580156200022c575080155b156200024b57604051633c3d8d2560e11b815260040160405180910390fd5b6001600160a01b03919091165f908152600d60205260409020805460ff1916911515919091179055565b6001600160a01b0383166200029d57604051634e46966960e11b815260040160405180910390fd5b620002aa5f8484620002eb565b8015620002e6575f60a05183620002c2919062000bb1565b90505f5b81811015620002e357620002da85620003ab565b600101620002c6565b50505b505050565b6001600160a01b03831662000319578060055f8282546200030d919062000bd1565b90915550620003489050565b6001600160a01b0383165f90815260076020526040812080548392906200034290849062000be7565b90915550505b6001600160a01b038083165f81815260076020526040908190208054850190555190918516907fe59fdd36d0d223c0c7d996db7ad796880f45e1936cb0bb7ac102e7082e031487906200039e9085815260200190565b60405180910390a3505050565b6001600160a01b038116620003d357604051634e46966960e11b815260040160405180910390fd5b5f620003f3600154600160801b81046001600160801b0390811691161490565b6200040c576200040460016200046c565b905062000428565b60068054905f6200041d8362000bfd565b919050555060065490505b5f818152600b60205260409020546001600160a01b031680156200045f5760405163119b4fd360e11b815260040160405180910390fd5b620002e6818484620004da565b80545f906001600160801b03600160801b8204811691168103620004a3576040516375e52f4f60e01b815260040160405180910390fd5b5f19016001600160801b039081165f818152600185016020526040812080549190558454909216600160801b909102179092555090565b6001600160a01b03831615620005eb575f81815260096020908152604080832080546001600160a01b03191690556001600160a01b0386168352600c909152812080546200052b9060019062000be7565b815481106200053e576200053e62000c18565b905f5260205f2001549050818114620005ad575f828152600b602052604081205460a0901b6001600160a01b0386165f908152600c60205260409020805491925083918390811062000594576200059462000c18565b5f91825260209091200155620005ab8282620006bc565b505b6001600160a01b0384165f908152600c60205260409020805480620005d657620005d662000c2c565b600190038181905f5260205f20015f90559055505b6001600160a01b0382161562000667575f818152600b6020908152604080832080546001600160a01b0319166001600160a01b038716908101909155808452600c83529083208054600181810183558286529385200185905592529054620006619183916200065b919062000be7565b620006bc565b62000676565b5f818152600b60205260408120555b80826001600160a01b0316846001600160a01b03167fe5f815dc84b8cecdfd4beedfc3f91ab5be7af100eca4e8fb11552b867995394f60405160405180910390a4505050565b5f828152600b60205260409020546001600160601b03821115620006f357604051633f2cd0e360e21b815260040160405180910390fd5b5f928352600b60205260409092206001600160a01b039290921660a090911b6001600160a01b031916019055565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011262000745575f80fd5b81516001600160401b038082111562000762576200076262000721565b604051601f8301601f19908116603f011681019082821181831017156200078d576200078d62000721565b8160405283815260209250866020858801011115620007aa575f80fd5b5f91505b83821015620007cd5785820183015181830184015290820190620007ae565b5f602085830101528094505050505092915050565b80516001600160a01b0381168114620007f9575f80fd5b919050565b5f805f805f8060c0878903121562000814575f80fd5b86516001600160401b03808211156200082b575f80fd5b620008398a838b0162000735565b975060208901519150808211156200084f575f80fd5b506200085e89828a0162000735565b955050604087015160ff8116811462000875575f80fd5b606088015190945092506200088d60808801620007e2565b91506200089d60a08801620007e2565b90509295509295509295565b600181811c90821680620008be57607f821691505b602082108103620008dd57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115620002e657805f5260205f20601f840160051c810160208510156200090a5750805b601f840160051c820191505b81811015620002e3575f815560010162000916565b81516001600160401b0381111562000947576200094762000721565b6200095f81620009588454620008a9565b84620008e3565b602080601f83116001811462000995575f84156200097d5750858301515b5f19600386901b1c1916600185901b178555620009ef565b5f85815260208120601f198616915b82811015620009c557888601518255948401946001909101908401620009a4565b5085821015620009e357878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b634e487b7160e01b5f52601160045260245ffd5b600181815b8085111562000a4b57815f190482111562000a2f5762000a2f620009f7565b8085161562000a3d57918102915b93841c939080029062000a10565b509250929050565b5f8262000a635750600162000b00565b8162000a7157505f62000b00565b816001811462000a8a576002811462000a955762000ab5565b600191505062000b00565b60ff84111562000aa95762000aa9620009f7565b50506001821b62000b00565b5060208310610133831016604e8410600b841016171562000ada575081810a62000b00565b62000ae6838362000a0b565b805f190482111562000afc5762000afc620009f7565b0290505b92915050565b5f62000b1660ff84168362000a53565b9392505050565b808202811582820484141762000b005762000b00620009f7565b5f80835462000b4681620008a9565b6001828116801562000b61576001811462000b775762000ba5565b60ff198416875282151583028701945062000ba5565b875f526020805f205f5b8581101562000b9c5781548a82015290840190820162000b81565b50505082870194505b50929695505050505050565b5f8262000bcc57634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111562000b005762000b00620009f7565b8181038181111562000b005762000b00620009f7565b5f6001820162000c115762000c11620009f7565b5060010190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b60805160a05160c05160e05161258962000ccf5f395f610a3201525f610a0201525f818161043c0152818161095501528181611461015281816114a40152818161151b0152818161154501528181611597015281816116410152818161166d01528181611694015281816116db015281816117020152818161181c015261198a01525f61032701526125895ff3fe608060405234801561000f575f80fd5b5060043610610234575f3560e01c80638b2d8dec11610135578063b88d4fde116100b4578063dd62ed3e11610079578063dd62ed3e14610540578063e985e9c51461056a578063f2fde38b14610597578063f4cdda36146105aa578063fb4bcd4f146105cc575f80fd5b8063b88d4fde146104f7578063c5ab3ba61461050a578063c87b56dd14610512578063d505accf14610525578063dc1a927314610538575f80fd5b8063a22cb465116100fa578063a22cb46514610480578063a5ce30d214610493578063a9059cbb1461049c578063b1ab9317146104af578063b3f9ea34146104cf575f80fd5b80638b2d8dec1461040c5780638da5cb5b1461041f57806395d89b411461042f578063976a8435146104375780639b19251a1461045e575f80fd5b80633644e515116101c1578063715018a611610186578063715018a6146103bd578063726d20fe146103c55780637ecebe00146103d857806383443c52146103f757806389fb4c6614610404575f80fd5b80633644e5151461035b57806342842e0e1461036357806353d6fd59146103785780636352211e1461038b57806370a082311461039e575f80fd5b8063095ea7b311610207578063095ea7b3146102eb57806309d890d5146102fe57806318160ddd1461030657806323b872dd1461030f578063313ce56714610322575f80fd5b806301ffc9a71461023857806302519da31461026057806306fdde0314610296578063081812fc146102ab575b5f80fd5b61024b610246366004611eb6565b6105df565b60405190151581526020015b60405180910390f35b61028861026e366004611ee7565b6001600160a01b03165f9081526007602052604090205490565b604051908152602001610257565b61029e610615565b6040516102579190611f22565b6102d36102b9366004611f54565b60096020525f90815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610257565b61024b6102f9366004611f6b565b6106a1565b610288610818565b61028860055481565b61024b61031d366004611f93565b610841565b6103497f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610257565b6102886109ff565b610376610371366004611f93565b610a54565b005b610376610386366004611fcc565b610b2b565b6102d3610399366004611f54565b610b41565b6102886103ac366004611ee7565b60076020525f908152604090205481565b610376610b9d565b61024b6103d33660046120b4565b610bb0565b6102886103e6366004611ee7565b600e6020525f908152604090205481565b600f5461024b9060ff1681565b600554610288565b61037661041a3660046120f7565b610c2b565b5f546001600160a01b03166102d3565b61029e610c71565b6102887f000000000000000000000000000000000000000000000000000000000000000081565b61024b61046c366004611ee7565b600d6020525f908152604090205460ff1681565b61037661048e366004611fcc565b610c7e565b61028860105481565b61024b6104aa366004611f6b565b610d10565b6104c26104bd366004611ee7565b610d43565b6040516102579190612139565b6102886104dd366004611ee7565b6001600160a01b03165f908152600c602052604090205490565b61037661050536600461217c565b610dac565b600654610288565b61029e610520366004611f54565b610e74565b61037661053336600461220f565b610ea5565b6103766110f6565b61028861054e36600461227c565b600860209081525f928352604080842090915290825290205481565b61024b61057836600461227c565b600a60209081525f928352604080842090915290825290205460ff1681565b6103766105a5366004611ee7565b611115565b61024b6105b8366004611ee7565b60116020525f908152604090205460ff1681565b6103766105da366004611f54565b611157565b5f6001600160e01b03198216632cdd2bf160e21b148061060f57506001600160e01b031982166301ffc9a760e01b145b92915050565b60038054610622906122ad565b80601f016020809104026020016040519081016040528092919081815260200182805461064e906122ad565b80156106995780601f1061067057610100808354040283529160200191610699565b820191905f5260205f20905b81548152906001019060200180831161067c57829003601f168201915b505050505081565b5f60065482111580156106b357505f82115b1561077e575f828152600b602052604090205482906001600160a01b031633811480159061070457506001600160a01b0381165f908152600a6020908152604080832033845290915290205460ff16155b15610721576040516282b42960e81b815260040160405180910390fd5b5f8281526009602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518593918516917f797365dabb18fa726ccbccbe18c6f24c34e3b0653f2e99ea873bd7b84763dde691a4505061080f565b6001600160a01b0383166107a557604051635461585f60e01b815260040160405180910390fd5b335f8181526008602090815260408083206001600160a01b03881680855290835292819020869055805193845290830191909152810183905282907f1f01303a1ce9329d9963e1937c201e23c5543a9e3536e9edead087aec7dc6d839060600160405180910390a1505b50600192915050565b5f61083c6001546001600160801b03808216600160801b9092048116919091031690565b905090565b5f6001600160a01b03841661086957604051636edaef2f60e11b815260040160405180910390fd5b6001600160a01b03831661089057604051634e46966960e11b815260040160405180910390fd5b600654821161098a575f828152600b602052604090205482906001600160a01b038681169116146108d3576040516282b42960e81b815260040160405180910390fd5b336001600160a01b0386161480159061090f57506001600160a01b0385165f908152600a6020908152604080832033845290915290205460ff16155b801561093157505f818152600960205260409020546001600160a01b03163314155b1561094e576040516282b42960e81b815260040160405180910390fd5b61097985857f0000000000000000000000000000000000000000000000000000000000000000611168565b610984858583611221565b506109f4565b6001600160a01b0384165f90815260086020908152604080832033845290915290205482905f1981146109e5576109c182826122f9565b6001600160a01b0387165f9081526008602090815260408083203384529091529020555b6109f08686846113ee565b5050505b5060015b9392505050565b5f7f00000000000000000000000000000000000000000000000000000000000000004614610a2f5761083c611755565b507f000000000000000000000000000000000000000000000000000000000000000090565b610a5f838383610841565b506001600160a01b0382163b15801590610b085750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401525f608484015290919084169063150b7a029060a4016020604051808303815f875af1158015610ad7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610afb919061230c565b6001600160e01b03191614155b15610b2657604051633da6393160e01b815260040160405180910390fd5b505050565b610b336117ee565b610b3d828261181a565b5050565b5f818152600b60205260408120546001600160a01b03169050600654821180610b68575081155b80610b7a57506001600160a01b038116155b15610b985760405163c5723b5160e01b815260040160405180910390fd5b919050565b610ba56117ee565b610bae5f6118ad565b565b604080516001600160a01b03841660208201529081018290525f90819060600160408051601f1981840301815282825280516020918201209083015201604051602081830303815290604052805190602001209050610c1285601054836118fc565b15610c215760019150506109f8565b505f949350505050565b6010541580610c3d5750600f5460ff16155b15610c5b57604051631523f31960e11b815260040160405180910390fd5b610c658282611911565b610b3d3382600161194c565b60048054610622906122ad565b6001600160a01b038216610ca55760405163ccea9e6f60e01b815260040160405180910390fd5b335f818152600a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b5f6001600160a01b038316610d3857604051634e46966960e11b815260040160405180910390fd5b6109f83384846113ee565b6001600160a01b0381165f908152600c6020908152604091829020805483518184028101840190945280845260609392830182828015610da057602002820191905f5260205f20905b815481526020019060010190808311610d8c575b50505050509050919050565b610db7858585610841565b506001600160a01b0384163b15801590610e4f5750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290610e029033908a90899089908990600401612327565b6020604051808303815f875af1158015610e1e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e42919061230c565b6001600160e01b03191614155b15610e6d57604051633da6393160e01b815260040160405180910390fd5b5050505050565b6060610e7f826119cc565b604051602001610e8f9190612379565b6040516020818303038152906040529050919050565b42841015610ec6576040516305787bdf60e01b815260040160405180910390fd5b6006548511158015610ed757505f85115b15610ef5576040516303e7c1bd60e31b815260040160405180910390fd5b6001600160a01b038616610f1c57604051635461585f60e01b815260040160405180910390fd5b5f6001610f276109ff565b6001600160a01b038a81165f818152600e602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f1981840301815282825280516020918201205f84529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa15801561102f573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615806110645750876001600160a01b0316816001600160a01b031614155b1561108257604051632057875960e21b815260040160405180910390fd5b6001600160a01b039081165f9081526008602090815260408083208a8516808552908352928190208990558051938b1684529083019190915281018690527f1f01303a1ce9329d9963e1937c201e23c5543a9e3536e9edead087aec7dc6d839060600160405180910390a150505050505050565b6110fe6117ee565b610bae600f805460ff19811660ff90911615179055565b61111d6117ee565b6001600160a01b03811661114b57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b611154816118ad565b50565b61115f6117ee565b61115481601055565b6001600160a01b038316611192578060055f8282546111879190612428565b909155506111bf9050565b6001600160a01b0383165f90815260076020526040812080548392906111b99084906122f9565b90915550505b6001600160a01b038083165f81815260076020526040908190208054850190555190918516907fe59fdd36d0d223c0c7d996db7ad796880f45e1936cb0bb7ac102e7082e031487906112149085815260200190565b60405180910390a3505050565b6001600160a01b03831615611323575f81815260096020908152604080832080546001600160a01b03191690556001600160a01b0386168352600c9091528120805461126f906001906122f9565b8154811061127f5761127f61243b565b905f5260205f20015490508181146112e8575f828152600b602052604081205460a0901b6001600160a01b0386165f908152600c6020526040902080549192508391839081106112d1576112d161243b565b5f918252602090912001556112e68282611a5c565b505b6001600160a01b0384165f908152600c6020526040902080548061130e5761130e61244f565b600190038181905f5260205f20015f90559055505b6001600160a01b03821615611399575f818152600b6020908152604080832080546001600160a01b0319166001600160a01b038716908101909155808452600c8352908320805460018181018355828652938520018590559252905461139491839161138f91906122f9565b611a5c565b6113a8565b5f818152600b60205260408120555b80826001600160a01b0316846001600160a01b03167fe5f815dc84b8cecdfd4beedfc3f91ab5be7af100eca4e8fb11552b867995394f60405160405180910390a4505050565b6001600160a01b038381165f9081526007602052604080822054928516825281205490919061141e868686611168565b6001600160a01b038087165f908152600d602052604080822054928816825290205460ff91821691168180156114515750805b6117475781156114f7575f6114867f000000000000000000000000000000000000000000000000000000000000000085612477565b6001600160a01b0389165f908152600760205260409020546114c9907f000000000000000000000000000000000000000000000000000000000000000090612477565b6114d391906122f9565b90505f5b818110156114f0576114e889611ac5565b6001016114d7565b5050611747565b8015611591576001600160a01b0388165f90815260076020526040812054611540907f000000000000000000000000000000000000000000000000000000000000000090612477565b61156a7f000000000000000000000000000000000000000000000000000000000000000087612477565b61157491906122f9565b90505f5b818110156114f0576115898a611b7b565b600101611578565b5f6115bc7f000000000000000000000000000000000000000000000000000000000000000088612477565b90505f5b8181101561163a576001600160a01b038a165f908152600c60205260408120546115ec906001906122f9565b6001600160a01b038c165f908152600c60205260408120805492935090918390811061161a5761161a61243b565b905f5260205f20015490506116308c8c83611221565b50506001016115c0565b505f6116667f00000000000000000000000000000000000000000000000000000000000000008961248a565b90506116927f000000000000000000000000000000000000000000000000000000000000000087612477565b7f00000000000000000000000000000000000000000000000000000000000000006116bd83896122f9565b6116c79190612477565b10156116d6576116d68a611b7b565b6117007f000000000000000000000000000000000000000000000000000000000000000086612477565b7f000000000000000000000000000000000000000000000000000000000000000061172b8388612428565b6117359190612477565b11156117445761174489611ac5565b50505b506001979650505050505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6003604051611786919061249d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f546001600160a01b03163314610bae5760405163118cdaa760e01b8152336004820152602401611142565b7f0000000000000000000000000000000000000000000000000000000000000000611859836001600160a01b03165f9081526007602052604090205490565b10158015611865575080155b1561188357604051633c3d8d2560e11b815260040160405180910390fd5b6001600160a01b03919091165f908152600d60205260409020805460ff1916911515919091179055565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f826119088584611bf8565b14949350505050565b60105415806119235750600f5460ff16155b1561194157604051631523f31960e11b815260040160405180910390fd5b610b3d823383611c3a565b6001600160a01b03831661197357604051634e46966960e11b815260040160405180910390fd5b61197e5f8484611168565b8015610b26575f6119af7f000000000000000000000000000000000000000000000000000000000000000084612477565b90505f5b81811015610e6d576119c485611ac5565b6001016119b3565b60605f6119d883611cc0565b60010190505f8167ffffffffffffffff8111156119f7576119f7612005565b6040519080825280601f01601f191660200182016040528015611a21576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611a2b57509392505050565b5f828152600b60205260409020546bffffffffffffffffffffffff821115611a9757604051633f2cd0e360e21b815260040160405180910390fd5b5f928352600b60205260409092206001600160a01b039290921660a090911b6001600160a01b031916019055565b6001600160a01b038116611aec57604051634e46966960e11b815260040160405180910390fd5b5f611b0b600154600160801b81046001600160801b0390811691161490565b611b2057611b196001611d97565b9050611b3a565b60068054905f611b2f8361253b565b919050555060065490505b5f818152600b60205260409020546001600160a01b03168015611b705760405163119b4fd360e11b815260040160405180910390fd5b610b26818484611221565b6001600160a01b038116611ba257604051636edaef2f60e11b815260040160405180910390fd5b6001600160a01b0381165f908152600c602052604081208054611bc7906001906122f9565b81548110611bd757611bd761243b565b905f5260205f2001549050611bed825f83611221565b610b3d600182611e04565b5f81815b8451811015611c3257611c2882868381518110611c1b57611c1b61243b565b6020026020010151611e75565b9150600101611bfc565b509392505050565b611c45838383610bb0565b611c6257604051633ba2c43760e11b815260040160405180910390fd5b6001600160a01b0382165f9081526011602052604090205460ff1615611c9b5760405163e4ca4c0b60e01b815260040160405180910390fd5b506001600160a01b03165f908152601160205260409020805460ff1916600117905550565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611cfe5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611d2a576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611d4857662386f26fc10000830492506010015b6305f5e1008310611d60576305f5e100830492506008015b6127108310611d7457612710830492506004015b60648310611d86576064830492506002015b600a831061060f5760010192915050565b80545f906001600160801b03600160801b8204811691168103611dcd576040516375e52f4f60e01b815260040160405180910390fd5b5f19016001600160801b039081165f818152600185016020526040812080549190558454909216600160801b909102179092555090565b81546001600160801b038082165f190191600160801b9004811690821603611e3f57604051638acb5f2760e01b815260040160405180910390fd5b6001600160801b03165f81815260018401602052604090209190915581546fffffffffffffffffffffffffffffffff1916179055565b5f818310611e8f575f8281526020849052604090206109f8565b5f8381526020839052604090206109f8565b6001600160e01b031981168114611154575f80fd5b5f60208284031215611ec6575f80fd5b81356109f881611ea1565b80356001600160a01b0381168114610b98575f80fd5b5f60208284031215611ef7575f80fd5b6109f882611ed1565b5f5b83811015611f1a578181015183820152602001611f02565b50505f910152565b602081525f8251806020840152611f40816040850160208701611f00565b601f01601f19169190910160400192915050565b5f60208284031215611f64575f80fd5b5035919050565b5f8060408385031215611f7c575f80fd5b611f8583611ed1565b946020939093013593505050565b5f805f60608486031215611fa5575f80fd5b611fae84611ed1565b9250611fbc60208501611ed1565b9150604084013590509250925092565b5f8060408385031215611fdd575f80fd5b611fe683611ed1565b915060208301358015158114611ffa575f80fd5b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112612028575f80fd5b8135602067ffffffffffffffff8083111561204557612045612005565b8260051b604051601f19603f8301168101818110848211171561206a5761206a612005565b6040529384526020818701810194908101925087851115612089575f80fd5b6020870191505b848210156120a957813583529183019190830190612090565b979650505050505050565b5f805f606084860312156120c6575f80fd5b833567ffffffffffffffff8111156120dc575f80fd5b6120e886828701612019565b935050611fbc60208501611ed1565b5f8060408385031215612108575f80fd5b823567ffffffffffffffff81111561211e575f80fd5b61212a85828601612019565b95602094909401359450505050565b602080825282518282018190525f9190848201906040850190845b8181101561217057835183529284019291840191600101612154565b50909695505050505050565b5f805f805f60808688031215612190575f80fd5b61219986611ed1565b94506121a760208701611ed1565b935060408601359250606086013567ffffffffffffffff808211156121ca575f80fd5b818801915088601f8301126121dd575f80fd5b8135818111156121eb575f80fd5b8960208285010111156121fc575f80fd5b9699959850939650602001949392505050565b5f805f805f805f60e0888a031215612225575f80fd5b61222e88611ed1565b965061223c60208901611ed1565b95506040880135945060608801359350608088013560ff8116811461225f575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f806040838503121561228d575f80fd5b61229683611ed1565b91506122a460208401611ed1565b90509250929050565b600181811c908216806122c157607f821691505b6020821081036122df57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561060f5761060f6122e5565b5f6020828403121561231c575f80fd5b81516109f881611ea1565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290525f828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b7f68747470733a2f2f73696c7665722d74726f706963616c2d6775616e61636f2d81527f3638332e6d7970696e6174612e636c6f75642f697066732f516d65414e5a464560208201527f634850616a7744793237566e44627337705a765a754247464e4c453350447a576040820152665a704b3636532f60c81b60608201525f825161240c816067850160208701611f00565b64173539b7b760d91b6067939091019283015250606c01919050565b8082018082111561060f5761060f6122e5565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b634e487b7160e01b5f52601260045260245ffd5b5f8261248557612485612463565b500490565b5f8261249857612498612463565b500690565b5f8083545f60018260011c915060018316806124ba57607f831692505b602080841082036124d957634e487b7160e01b5f52602260045260245ffd5b8180156124ed57600181146125025761252d565b60ff198616895284151585028901965061252d565b5f8a8152602090205f5b868110156125255781548b82015290850190830161250c565b505084890196505b509498975050505050505050565b5f6001820161254c5761254c6122e5565b506001019056fea26469706673582212206b286dd966248aaa06026b0df67e9672c40043f2b11f7036153e18c94d9608c164736f6c6343000818003300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000019400000000000000000000000077455e794993ef5c116d6bcaa9194441ce480e7c00000000000000000000000077455e794993ef5c116d6bcaa9194441ce480e7c00000000000000000000000000000000000000000000000000000000000000084d454d452034303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074d454d4534303400000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610234575f3560e01c80638b2d8dec11610135578063b88d4fde116100b4578063dd62ed3e11610079578063dd62ed3e14610540578063e985e9c51461056a578063f2fde38b14610597578063f4cdda36146105aa578063fb4bcd4f146105cc575f80fd5b8063b88d4fde146104f7578063c5ab3ba61461050a578063c87b56dd14610512578063d505accf14610525578063dc1a927314610538575f80fd5b8063a22cb465116100fa578063a22cb46514610480578063a5ce30d214610493578063a9059cbb1461049c578063b1ab9317146104af578063b3f9ea34146104cf575f80fd5b80638b2d8dec1461040c5780638da5cb5b1461041f57806395d89b411461042f578063976a8435146104375780639b19251a1461045e575f80fd5b80633644e515116101c1578063715018a611610186578063715018a6146103bd578063726d20fe146103c55780637ecebe00146103d857806383443c52146103f757806389fb4c6614610404575f80fd5b80633644e5151461035b57806342842e0e1461036357806353d6fd59146103785780636352211e1461038b57806370a082311461039e575f80fd5b8063095ea7b311610207578063095ea7b3146102eb57806309d890d5146102fe57806318160ddd1461030657806323b872dd1461030f578063313ce56714610322575f80fd5b806301ffc9a71461023857806302519da31461026057806306fdde0314610296578063081812fc146102ab575b5f80fd5b61024b610246366004611eb6565b6105df565b60405190151581526020015b60405180910390f35b61028861026e366004611ee7565b6001600160a01b03165f9081526007602052604090205490565b604051908152602001610257565b61029e610615565b6040516102579190611f22565b6102d36102b9366004611f54565b60096020525f90815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610257565b61024b6102f9366004611f6b565b6106a1565b610288610818565b61028860055481565b61024b61031d366004611f93565b610841565b6103497f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff9091168152602001610257565b6102886109ff565b610376610371366004611f93565b610a54565b005b610376610386366004611fcc565b610b2b565b6102d3610399366004611f54565b610b41565b6102886103ac366004611ee7565b60076020525f908152604090205481565b610376610b9d565b61024b6103d33660046120b4565b610bb0565b6102886103e6366004611ee7565b600e6020525f908152604090205481565b600f5461024b9060ff1681565b600554610288565b61037661041a3660046120f7565b610c2b565b5f546001600160a01b03166102d3565b61029e610c71565b6102887f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b61024b61046c366004611ee7565b600d6020525f908152604090205460ff1681565b61037661048e366004611fcc565b610c7e565b61028860105481565b61024b6104aa366004611f6b565b610d10565b6104c26104bd366004611ee7565b610d43565b6040516102579190612139565b6102886104dd366004611ee7565b6001600160a01b03165f908152600c602052604090205490565b61037661050536600461217c565b610dac565b600654610288565b61029e610520366004611f54565b610e74565b61037661053336600461220f565b610ea5565b6103766110f6565b61028861054e36600461227c565b600860209081525f928352604080842090915290825290205481565b61024b61057836600461227c565b600a60209081525f928352604080842090915290825290205460ff1681565b6103766105a5366004611ee7565b611115565b61024b6105b8366004611ee7565b60116020525f908152604090205460ff1681565b6103766105da366004611f54565b611157565b5f6001600160e01b03198216632cdd2bf160e21b148061060f57506001600160e01b031982166301ffc9a760e01b145b92915050565b60038054610622906122ad565b80601f016020809104026020016040519081016040528092919081815260200182805461064e906122ad565b80156106995780601f1061067057610100808354040283529160200191610699565b820191905f5260205f20905b81548152906001019060200180831161067c57829003601f168201915b505050505081565b5f60065482111580156106b357505f82115b1561077e575f828152600b602052604090205482906001600160a01b031633811480159061070457506001600160a01b0381165f908152600a6020908152604080832033845290915290205460ff16155b15610721576040516282b42960e81b815260040160405180910390fd5b5f8281526009602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518593918516917f797365dabb18fa726ccbccbe18c6f24c34e3b0653f2e99ea873bd7b84763dde691a4505061080f565b6001600160a01b0383166107a557604051635461585f60e01b815260040160405180910390fd5b335f8181526008602090815260408083206001600160a01b03881680855290835292819020869055805193845290830191909152810183905282907f1f01303a1ce9329d9963e1937c201e23c5543a9e3536e9edead087aec7dc6d839060600160405180910390a1505b50600192915050565b5f61083c6001546001600160801b03808216600160801b9092048116919091031690565b905090565b5f6001600160a01b03841661086957604051636edaef2f60e11b815260040160405180910390fd5b6001600160a01b03831661089057604051634e46966960e11b815260040160405180910390fd5b600654821161098a575f828152600b602052604090205482906001600160a01b038681169116146108d3576040516282b42960e81b815260040160405180910390fd5b336001600160a01b0386161480159061090f57506001600160a01b0385165f908152600a6020908152604080832033845290915290205460ff16155b801561093157505f818152600960205260409020546001600160a01b03163314155b1561094e576040516282b42960e81b815260040160405180910390fd5b61097985857f0000000000000000000000000000000000000000000000000de0b6b3a7640000611168565b610984858583611221565b506109f4565b6001600160a01b0384165f90815260086020908152604080832033845290915290205482905f1981146109e5576109c182826122f9565b6001600160a01b0387165f9081526008602090815260408083203384529091529020555b6109f08686846113ee565b5050505b5060015b9392505050565b5f7f00000000000000000000000000000000000000000000000000000000000000014614610a2f5761083c611755565b507f12dd9f2bf015824fa8fb7bd4436956ad3fbc351317b3cb9146cce4dfec388dda90565b610a5f838383610841565b506001600160a01b0382163b15801590610b085750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401525f608484015290919084169063150b7a029060a4016020604051808303815f875af1158015610ad7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610afb919061230c565b6001600160e01b03191614155b15610b2657604051633da6393160e01b815260040160405180910390fd5b505050565b610b336117ee565b610b3d828261181a565b5050565b5f818152600b60205260408120546001600160a01b03169050600654821180610b68575081155b80610b7a57506001600160a01b038116155b15610b985760405163c5723b5160e01b815260040160405180910390fd5b919050565b610ba56117ee565b610bae5f6118ad565b565b604080516001600160a01b03841660208201529081018290525f90819060600160408051601f1981840301815282825280516020918201209083015201604051602081830303815290604052805190602001209050610c1285601054836118fc565b15610c215760019150506109f8565b505f949350505050565b6010541580610c3d5750600f5460ff16155b15610c5b57604051631523f31960e11b815260040160405180910390fd5b610c658282611911565b610b3d3382600161194c565b60048054610622906122ad565b6001600160a01b038216610ca55760405163ccea9e6f60e01b815260040160405180910390fd5b335f818152600a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b5f6001600160a01b038316610d3857604051634e46966960e11b815260040160405180910390fd5b6109f83384846113ee565b6001600160a01b0381165f908152600c6020908152604091829020805483518184028101840190945280845260609392830182828015610da057602002820191905f5260205f20905b815481526020019060010190808311610d8c575b50505050509050919050565b610db7858585610841565b506001600160a01b0384163b15801590610e4f5750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290610e029033908a90899089908990600401612327565b6020604051808303815f875af1158015610e1e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e42919061230c565b6001600160e01b03191614155b15610e6d57604051633da6393160e01b815260040160405180910390fd5b5050505050565b6060610e7f826119cc565b604051602001610e8f9190612379565b6040516020818303038152906040529050919050565b42841015610ec6576040516305787bdf60e01b815260040160405180910390fd5b6006548511158015610ed757505f85115b15610ef5576040516303e7c1bd60e31b815260040160405180910390fd5b6001600160a01b038616610f1c57604051635461585f60e01b815260040160405180910390fd5b5f6001610f276109ff565b6001600160a01b038a81165f818152600e602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f1981840301815282825280516020918201205f84529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa15801561102f573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615806110645750876001600160a01b0316816001600160a01b031614155b1561108257604051632057875960e21b815260040160405180910390fd5b6001600160a01b039081165f9081526008602090815260408083208a8516808552908352928190208990558051938b1684529083019190915281018690527f1f01303a1ce9329d9963e1937c201e23c5543a9e3536e9edead087aec7dc6d839060600160405180910390a150505050505050565b6110fe6117ee565b610bae600f805460ff19811660ff90911615179055565b61111d6117ee565b6001600160a01b03811661114b57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b611154816118ad565b50565b61115f6117ee565b61115481601055565b6001600160a01b038316611192578060055f8282546111879190612428565b909155506111bf9050565b6001600160a01b0383165f90815260076020526040812080548392906111b99084906122f9565b90915550505b6001600160a01b038083165f81815260076020526040908190208054850190555190918516907fe59fdd36d0d223c0c7d996db7ad796880f45e1936cb0bb7ac102e7082e031487906112149085815260200190565b60405180910390a3505050565b6001600160a01b03831615611323575f81815260096020908152604080832080546001600160a01b03191690556001600160a01b0386168352600c9091528120805461126f906001906122f9565b8154811061127f5761127f61243b565b905f5260205f20015490508181146112e8575f828152600b602052604081205460a0901b6001600160a01b0386165f908152600c6020526040902080549192508391839081106112d1576112d161243b565b5f918252602090912001556112e68282611a5c565b505b6001600160a01b0384165f908152600c6020526040902080548061130e5761130e61244f565b600190038181905f5260205f20015f90559055505b6001600160a01b03821615611399575f818152600b6020908152604080832080546001600160a01b0319166001600160a01b038716908101909155808452600c8352908320805460018181018355828652938520018590559252905461139491839161138f91906122f9565b611a5c565b6113a8565b5f818152600b60205260408120555b80826001600160a01b0316846001600160a01b03167fe5f815dc84b8cecdfd4beedfc3f91ab5be7af100eca4e8fb11552b867995394f60405160405180910390a4505050565b6001600160a01b038381165f9081526007602052604080822054928516825281205490919061141e868686611168565b6001600160a01b038087165f908152600d602052604080822054928816825290205460ff91821691168180156114515750805b6117475781156114f7575f6114867f0000000000000000000000000000000000000000000000000de0b6b3a764000085612477565b6001600160a01b0389165f908152600760205260409020546114c9907f0000000000000000000000000000000000000000000000000de0b6b3a764000090612477565b6114d391906122f9565b90505f5b818110156114f0576114e889611ac5565b6001016114d7565b5050611747565b8015611591576001600160a01b0388165f90815260076020526040812054611540907f0000000000000000000000000000000000000000000000000de0b6b3a764000090612477565b61156a7f0000000000000000000000000000000000000000000000000de0b6b3a764000087612477565b61157491906122f9565b90505f5b818110156114f0576115898a611b7b565b600101611578565b5f6115bc7f0000000000000000000000000000000000000000000000000de0b6b3a764000088612477565b90505f5b8181101561163a576001600160a01b038a165f908152600c60205260408120546115ec906001906122f9565b6001600160a01b038c165f908152600c60205260408120805492935090918390811061161a5761161a61243b565b905f5260205f20015490506116308c8c83611221565b50506001016115c0565b505f6116667f0000000000000000000000000000000000000000000000000de0b6b3a76400008961248a565b90506116927f0000000000000000000000000000000000000000000000000de0b6b3a764000087612477565b7f0000000000000000000000000000000000000000000000000de0b6b3a76400006116bd83896122f9565b6116c79190612477565b10156116d6576116d68a611b7b565b6117007f0000000000000000000000000000000000000000000000000de0b6b3a764000086612477565b7f0000000000000000000000000000000000000000000000000de0b6b3a764000061172b8388612428565b6117359190612477565b11156117445761174489611ac5565b50505b506001979650505050505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6003604051611786919061249d565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f546001600160a01b03163314610bae5760405163118cdaa760e01b8152336004820152602401611142565b7f0000000000000000000000000000000000000000000000000de0b6b3a7640000611859836001600160a01b03165f9081526007602052604090205490565b10158015611865575080155b1561188357604051633c3d8d2560e11b815260040160405180910390fd5b6001600160a01b03919091165f908152600d60205260409020805460ff1916911515919091179055565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f826119088584611bf8565b14949350505050565b60105415806119235750600f5460ff16155b1561194157604051631523f31960e11b815260040160405180910390fd5b610b3d823383611c3a565b6001600160a01b03831661197357604051634e46966960e11b815260040160405180910390fd5b61197e5f8484611168565b8015610b26575f6119af7f0000000000000000000000000000000000000000000000000de0b6b3a764000084612477565b90505f5b81811015610e6d576119c485611ac5565b6001016119b3565b60605f6119d883611cc0565b60010190505f8167ffffffffffffffff8111156119f7576119f7612005565b6040519080825280601f01601f191660200182016040528015611a21576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084611a2b57509392505050565b5f828152600b60205260409020546bffffffffffffffffffffffff821115611a9757604051633f2cd0e360e21b815260040160405180910390fd5b5f928352600b60205260409092206001600160a01b039290921660a090911b6001600160a01b031916019055565b6001600160a01b038116611aec57604051634e46966960e11b815260040160405180910390fd5b5f611b0b600154600160801b81046001600160801b0390811691161490565b611b2057611b196001611d97565b9050611b3a565b60068054905f611b2f8361253b565b919050555060065490505b5f818152600b60205260409020546001600160a01b03168015611b705760405163119b4fd360e11b815260040160405180910390fd5b610b26818484611221565b6001600160a01b038116611ba257604051636edaef2f60e11b815260040160405180910390fd5b6001600160a01b0381165f908152600c602052604081208054611bc7906001906122f9565b81548110611bd757611bd761243b565b905f5260205f2001549050611bed825f83611221565b610b3d600182611e04565b5f81815b8451811015611c3257611c2882868381518110611c1b57611c1b61243b565b6020026020010151611e75565b9150600101611bfc565b509392505050565b611c45838383610bb0565b611c6257604051633ba2c43760e11b815260040160405180910390fd5b6001600160a01b0382165f9081526011602052604090205460ff1615611c9b5760405163e4ca4c0b60e01b815260040160405180910390fd5b506001600160a01b03165f908152601160205260409020805460ff1916600117905550565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611cfe5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611d2a576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611d4857662386f26fc10000830492506010015b6305f5e1008310611d60576305f5e100830492506008015b6127108310611d7457612710830492506004015b60648310611d86576064830492506002015b600a831061060f5760010192915050565b80545f906001600160801b03600160801b8204811691168103611dcd576040516375e52f4f60e01b815260040160405180910390fd5b5f19016001600160801b039081165f818152600185016020526040812080549190558454909216600160801b909102179092555090565b81546001600160801b038082165f190191600160801b9004811690821603611e3f57604051638acb5f2760e01b815260040160405180910390fd5b6001600160801b03165f81815260018401602052604090209190915581546fffffffffffffffffffffffffffffffff1916179055565b5f818310611e8f575f8281526020849052604090206109f8565b5f8381526020839052604090206109f8565b6001600160e01b031981168114611154575f80fd5b5f60208284031215611ec6575f80fd5b81356109f881611ea1565b80356001600160a01b0381168114610b98575f80fd5b5f60208284031215611ef7575f80fd5b6109f882611ed1565b5f5b83811015611f1a578181015183820152602001611f02565b50505f910152565b602081525f8251806020840152611f40816040850160208701611f00565b601f01601f19169190910160400192915050565b5f60208284031215611f64575f80fd5b5035919050565b5f8060408385031215611f7c575f80fd5b611f8583611ed1565b946020939093013593505050565b5f805f60608486031215611fa5575f80fd5b611fae84611ed1565b9250611fbc60208501611ed1565b9150604084013590509250925092565b5f8060408385031215611fdd575f80fd5b611fe683611ed1565b915060208301358015158114611ffa575f80fd5b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112612028575f80fd5b8135602067ffffffffffffffff8083111561204557612045612005565b8260051b604051601f19603f8301168101818110848211171561206a5761206a612005565b6040529384526020818701810194908101925087851115612089575f80fd5b6020870191505b848210156120a957813583529183019190830190612090565b979650505050505050565b5f805f606084860312156120c6575f80fd5b833567ffffffffffffffff8111156120dc575f80fd5b6120e886828701612019565b935050611fbc60208501611ed1565b5f8060408385031215612108575f80fd5b823567ffffffffffffffff81111561211e575f80fd5b61212a85828601612019565b95602094909401359450505050565b602080825282518282018190525f9190848201906040850190845b8181101561217057835183529284019291840191600101612154565b50909695505050505050565b5f805f805f60808688031215612190575f80fd5b61219986611ed1565b94506121a760208701611ed1565b935060408601359250606086013567ffffffffffffffff808211156121ca575f80fd5b818801915088601f8301126121dd575f80fd5b8135818111156121eb575f80fd5b8960208285010111156121fc575f80fd5b9699959850939650602001949392505050565b5f805f805f805f60e0888a031215612225575f80fd5b61222e88611ed1565b965061223c60208901611ed1565b95506040880135945060608801359350608088013560ff8116811461225f575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f806040838503121561228d575f80fd5b61229683611ed1565b91506122a460208401611ed1565b90509250929050565b600181811c908216806122c157607f821691505b6020821081036122df57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561060f5761060f6122e5565b5f6020828403121561231c575f80fd5b81516109f881611ea1565b6001600160a01b038681168252851660208201526040810184905260806060820181905281018290525f828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b7f68747470733a2f2f73696c7665722d74726f706963616c2d6775616e61636f2d81527f3638332e6d7970696e6174612e636c6f75642f697066732f516d65414e5a464560208201527f634850616a7744793237566e44627337705a765a754247464e4c453350447a576040820152665a704b3636532f60c81b60608201525f825161240c816067850160208701611f00565b64173539b7b760d91b6067939091019283015250606c01919050565b8082018082111561060f5761060f6122e5565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b634e487b7160e01b5f52601260045260245ffd5b5f8261248557612485612463565b500490565b5f8261249857612498612463565b500690565b5f8083545f60018260011c915060018316806124ba57607f831692505b602080841082036124d957634e487b7160e01b5f52602260045260245ffd5b8180156124ed57600181146125025761252d565b60ff198616895284151585028901965061252d565b5f8a8152602090205f5b868110156125255781548b82015290850190830161250c565b505084890196505b509498975050505050505050565b5f6001820161254c5761254c6122e5565b506001019056fea26469706673582212206b286dd966248aaa06026b0df67e9672c40043f2b11f7036153e18c94d9608c164736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000019400000000000000000000000077455e794993ef5c116d6bcaa9194441ce480e7c00000000000000000000000077455e794993ef5c116d6bcaa9194441ce480e7c00000000000000000000000000000000000000000000000000000000000000084d454d452034303400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074d454d4534303400000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name_ (string): MEME 404
Arg [1] : symbol_ (string): MEME404
Arg [2] : decimals_ (uint8): 18
Arg [3] : maxTotalSupplyERC721_ (uint256): 404
Arg [4] : initialOwner_ (address): 0x77455e794993EF5c116D6bcAa9194441CE480e7C
Arg [5] : initialMintRecipient_ (address): 0x77455e794993EF5c116D6bcAa9194441CE480e7C
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000194
Arg [4] : 00000000000000000000000077455e794993ef5c116d6bcaa9194441ce480e7c
Arg [5] : 00000000000000000000000077455e794993ef5c116d6bcaa9194441ce480e7c
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [7] : 4d454d4520343034000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [9] : 4d454d4534303400000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
118283:1334:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106476:210;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;106476:210:0;;;;;;;;99329:125;;;;;;:::i;:::-;-1:-1:-1;;;;;99431:17:0;99408:7;99431:17;;;:9;:17;;;;;;;99329:125;;;;1107:25:1;;;1095:2;1080:18;99329:125:0;961:177:1;96393:18:0;;;:::i;:::-;;;;;;;:::i;97386:46::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;97386:46:0;;;;;;-1:-1:-1;;;;;2148:32:1;;;2130:51;;2118:2;2103:18;97386:46:0;1984:203:1;100227:1058:0;;;;;;:::i;:::-;;:::i;99663:120::-;;;:::i;96686:26::-;;;;;;101900:1463;;;;;;:::i;:::-;;:::i;96517:31::-;;;;;;;;2956:4:1;2944:17;;;2926:36;;2914:2;2899:18;96517:31:0;2784:184:1;106271:199:0;;;:::i;103976:359::-;;;;;;:::i;:::-;;:::i;:::-;;119498:116;;;;;;:::i;:::-;;:::i;98716:343::-;;;;;;:::i;:::-;;:::i;97163:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;12569:103;;;:::i;94743:343::-;;;;;;:::i;:::-;;:::i;97966:41::-;;;;;;:::i;:::-;;;;;;;;;;;;;;94478:25;;;;;;;;;99460:97;99540:11;;99460:97;;119064:200;;;;;;:::i;:::-;;:::i;11894:87::-;11940:7;11967:6;-1:-1:-1;;;;;11967:6:0;11894:87;;96443:20;;;:::i;96599:30::-;;;;;97890:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;101337:311;;;;;;:::i;:::-;;:::i;94508:32::-;;;;;;103572:329;;;;;;:::i;:::-;;:::i;99065:122::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;99193:130::-;;;;;;:::i;:::-;-1:-1:-1;;;;;99296:14:0;99273:7;99296:14;;;:6;:14;;;;;:21;;99193:130;104428:389;;;;;;:::i;:::-;;:::i;99563:94::-;99644:7;;99563:94;;118810:248;;;;;;:::i;:::-;;:::i;104868:1282::-;;;;;;:::i;:::-;;:::i;119407:85::-;;;:::i;97269:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;97494:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;12827:220;;;;;;:::i;:::-;;:::i;94545:49::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;119270:131;;;;;;:::i;:::-;;:::i;106476:210::-;106562:4;-1:-1:-1;;;;;;106589:40:0;;-1:-1:-1;;;106589:40:0;;:91;;-1:-1:-1;;;;;;;106640:40:0;;-1:-1:-1;;;106640:40:0;106589:91;106575:105;106476:210;-1:-1:-1;;106476:210:0:o;96393:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;100227:1058::-;100321:4;100501:7;;100487:10;:21;;:39;;;;;100525:1;100512:10;:14;100487:39;100483:777;;;100594:10;117302:15;;;:10;:15;;;;;;;;-1:-1:-1;;;;;117356:27:0;100688:10;:25;;;;;:71;;-1:-1:-1;;;;;;100718:29:0;;;;;;:16;:29;;;;;;;;100748:10;100718:41;;;;;;;;;;100717:42;100688:71;100674:137;;;100787:14;;-1:-1:-1;;;100787:14:0;;;;;;;;;;;100674:137;100821:15;;;;:11;:15;;;;;;:26;;-1:-1:-1;;;;;;100821:26:0;-1:-1:-1;;;;;100821:26:0;;;;;;;;;100863:41;;100821:15;;100863:41;;;;;;;100528:384;;100483:777;;;-1:-1:-1;;;;;100983:22:0;;100979:72;;101025:16;;-1:-1:-1;;;101025:16:0;;;;;;;;;;;100979:72;101165:10;101120:13;101155:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;101155:31:0;;;;;;;;;;;;:39;;;101210:42;;8691:34:1;;;8741:18;;;8734:43;;;;8793:18;;8786:34;;;101155:39:0;;101210:42;;8641:2:1;8626:18;101210:42:0;;;;;;;100918:342;100483:777;-1:-1:-1;101275:4:0;100227:1058;;;;:::o;99663:120::-;99729:7;99752:25;:16;9304:12;-1:-1:-1;;;;;9304:12:0;;;-1:-1:-1;;;9291:10:0;;;;;:25;;;;9283:34;;9174:156;99752:25;99745:32;;99663:120;:::o;101900:1463::-;102014:4;-1:-1:-1;;;;;102077:19:0;;102073:64;;102114:15;;-1:-1:-1;;;102114:15:0;;;;;;;;;;;102073:64;-1:-1:-1;;;;;102188:17:0;;102184:65;;102223:18;;-1:-1:-1;;;102223:18:0;;;;;;;;;;;102184:65;102275:7;;102261:10;:21;102257:1081;;117262:16;117302:15;;;:10;:15;;;;;;;;-1:-1:-1;;;;;102389:24:0;;;117356:27;;102389:24;102385:72;;102433:14;;-1:-1:-1;;;102433:14:0;;;;;;;;;;;102385:72;102566:10;-1:-1:-1;;;;;102566:19:0;;;;;;:68;;-1:-1:-1;;;;;;102599:23:0;;;;;;:16;:23;;;;;;;;102623:10;102599:35;;;;;;;;;;102598:36;102566:68;:110;;;;-1:-1:-1;102661:15:0;;;;:11;:15;;;;;;-1:-1:-1;;;;;102661:15:0;102647:10;:29;;102566:110;102552:176;;;102704:14;;-1:-1:-1;;;102704:14:0;;;;;;;;;;;102552:176;102795:33;102810:5;102817:3;102822:5;102795:14;:33::i;:::-;102837:31;102853:5;102860:3;102865:2;102837:15;:31::i;:::-;102284:592;102257:1081;;;-1:-1:-1;;;;;103004:16:0;;102951:13;103004:16;;;:9;:16;;;;;;;;103021:10;103004:28;;;;;;;;102967:10;;-1:-1:-1;;103107:28:0;;103103:101;;103179:15;103189:5;103179:7;:15;:::i;:::-;-1:-1:-1;;;;;103148:16:0;;;;;;:9;:16;;;;;;;;103165:10;103148:28;;;;;;;:46;103103:101;103287:43;103312:5;103319:3;103324:5;103287:24;:43::i;:::-;;102882:456;;102257:1081;-1:-1:-1;103353:4:0;101900:1463;;;;;;:::o;106271:199::-;106328:7;106375:16;106358:13;:33;:106;;106439:25;:23;:25::i;106358:106::-;-1:-1:-1;106403:24:0;;106271:199::o;103976:359::-;104085:29;104098:5;104105:3;104110;104085:12;:29::i;:::-;-1:-1:-1;;;;;;104135:15:0;;;:20;;;;:146;;-1:-1:-1;104166:64:0;;-1:-1:-1;;;104166:64:0;;;104203:10;104166:64;;;9401:34:1;-1:-1:-1;;;;;9471:15:1;;;9451:18;;;9444:43;9503:18;;;9496:34;;;9566:3;9546:18;;;9539:31;-1:-1:-1;9586:19:1;;;9579:30;104241:40:0;;104166:36;;;;104241:40;;9626:19:1;;104166:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;104166:115:0;;;104135:146;104123:207;;;104305:17;;-1:-1:-1;;;104305:17:0;;;;;;;;;;;104123:207;103976:359;;;:::o;119498:116::-;11780:13;:11;:13::i;:::-;119577:31:::1;119591:8;119601:6;119577:13;:31::i;:::-;119498:116:::0;;:::o;98716:343::-;98785:19;117302:15;;;:10;:15;;;;;;-1:-1:-1;;;;;117356:27:0;98813:30;;98970:7;;98964:3;:13;:25;;;-1:-1:-1;98981:8:0;;98964:25;:54;;;-1:-1:-1;;;;;;98993:25:0;;;98964:54;98960:94;;;99036:10;;-1:-1:-1;;;99036:10:0;;;;;;;;;;;98960:94;98716:343;;;:::o;12569:103::-;11780:13;:11;:13::i;:::-;12634:30:::1;12661:1;12634:18;:30::i;:::-;12569:103::o:0;94743:343::-;94933:28;;;-1:-1:-1;;;;;10102:32:1;;94933:28:0;;;10084:51:1;10151:18;;;10144:34;;;94864:4:0;;;;10057:18:1;;94933:28:0;;;-1:-1:-1;;94933:28:0;;;;;;;;;94923:39;;94933:28;94923:39;;;;94910:53;;;10318:19:1;10353:12;94910:53:0;;;;;;;;;;;;94892:78;;;;;;94877:93;;94981:51;95000:6;95008:17;;95027:4;94981:18;:51::i;:::-;94977:85;;;95050:4;95043:11;;;;;94977:85;-1:-1:-1;95075:5:0;;94743:343;-1:-1:-1;;;;94743:343:0:o;119064:200::-;94641:17;;:22;;:40;;-1:-1:-1;94668:13:0;;;;94667:14;94641:40;94637:87;;;94699:17;;-1:-1:-1;;;94699:17:0;;;;;;;;;;;94637:87;119182:33:::1;119200:6;119208;119182:17;:33::i;:::-;119222:36;119233:10;119245:6;119253:4;119222:10;:36::i;96443:20::-:0;;;;;;;:::i;101337:311::-;-1:-1:-1;;;;;101459:23:0;;101455:70;;101500:17;;-1:-1:-1;;;101500:17:0;;;;;;;;;;;101455:70;101548:10;101531:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;101531:39:0;;;;;;;;;;;;:51;;-1:-1:-1;;101531:51:0;;;;;;;;;;101594:48;;540:41:1;;;101531:39:0;;101548:10;101594:48;;513:18:1;101594:48:0;;;;;;;101337:311;;:::o;103572:329::-;103643:4;-1:-1:-1;;;;;103699:17:0;;103695:65;;103734:18;;-1:-1:-1;;;103734:18:0;;;;;;;;;;;103695:65;103846:49;103871:10;103883:3;103888:6;103846:24;:49::i;99065:122::-;-1:-1:-1;;;;;99167:14:0;;;;;;:6;:14;;;;;;;;;99160:21;;;;;;;;;;;;;;;;;99135:16;;99160:21;;;99167:14;99160:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99065:122;;;:::o;104428:389::-;104564:29;104577:5;104584:3;104589;104564:12;:29::i;:::-;-1:-1:-1;;;;;;104614:15:0;;;:20;;;;:149;;-1:-1:-1;104645:67:0;;-1:-1:-1;;;104645:67:0;;;104723:40;-1:-1:-1;;;;;104645:36:0;;;104723:40;;104645:67;;104682:10;;104694:5;;104701:3;;104706:5;;;;104645:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;104645:118:0;;;104614:149;104602:210;;;104787:17;;-1:-1:-1;;;104787:17:0;;;;;;;;;;;104602:210;104428:389;;;;;:::o;118810:248::-;118871:13;119021:21;119038:3;119021:16;:21::i;:::-;118900:152;;;;;;;;:::i;:::-;;;;;;;;;;;;;118893:159;;118810:248;;;:::o;104868:1282::-;105065:15;105053:9;:27;105049:80;;;105098:23;;-1:-1:-1;;;105098:23:0;;;;;;;;;;;105049:80;105151:7;;105141:6;:17;;:31;;;;;105171:1;105162:6;:10;105141:31;105137:78;;;105190:17;;-1:-1:-1;;;105190:17:0;;;;;;;;;;;105137:78;-1:-1:-1;;;;;105227:22:0;;105223:68;;105267:16;;-1:-1:-1;;;105267:16:0;;;;;;;;;;;105223:68;105318:24;105345:563;105443:18;:16;:18::i;:::-;-1:-1:-1;;;;;105760:14:0;;;;;;;:6;:14;;;;;;;;;:16;;;;;;;;105502:319;;105531:133;105502:319;;;12118:25:1;12197:18;;;12190:43;;;;12269:15;;;12249:18;;;12242:43;12301:18;;;12294:34;;;12344:19;;;12337:35;;;;12388:19;;;;12381:35;;;105502:319:0;;;;;;;;;;12090:19:1;;;105502:319:0;;;105476:360;;;;;;;;-1:-1:-1;;;105387:462:0;;;12685:27:1;12728:11;;;12721:27;;;;12764:12;;;12757:28;;;;12801:12;;105387:462:0;;;-1:-1:-1;;105387:462:0;;;;;;;;;105365:495;;105387:462;105365:495;;;;105345:563;;;;;;;;;13051:25:1;13124:4;13112:17;;13092:18;;;13085:45;13146:18;;;13139:34;;;13189:18;;;13182:34;;;13023:19;;105345:563:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;105345:563:0;;-1:-1:-1;;105345:563:0;;;-1:-1:-1;;;;;;;105923:30:0;;;;:60;;;105977:6;-1:-1:-1;;;;;105957:26:0;:16;-1:-1:-1;;;;;105957:26:0;;;105923:60;105919:109;;;106003:15;;-1:-1:-1;;;106003:15:0;;;;;;;;;;;105919:109;-1:-1:-1;;;;;106038:27:0;;;;;;;:9;:27;;;;;;;;:37;;;;;;;;;;;;;:46;;;106105:39;;8709:15:1;;;8691:34;;8741:18;;;8734:43;;;;8793:18;;8786:34;;;106105:39:0;;8641:2:1;8626:18;106105:39:0;;;;;;;104868:1282;;;;;;;:::o;119407:85::-;11780:13;:11;:13::i;:::-;119464:22:::1;95610:13:::0;;;-1:-1:-1;;95593:30:0;;95610:13;;;;95609:14;95593:30;;;95545:84;12827:220;11780:13;:11;:13::i;:::-;-1:-1:-1;;;;;12912:22:0;::::1;12908:93;;12958:31;::::0;-1:-1:-1;;;12958:31:0;;12986:1:::1;12958:31;::::0;::::1;2130:51:1::0;2103:18;;12958:31:0::1;;;;;;;;12908:93;13011:28;13030:8;13011:18;:28::i;:::-;12827:220:::0;:::o;119270:131::-;11780:13;:11;:13::i;:::-;119354:41:::1;119376:18;95495:17:::0;:38;95420:119;107400:683;-1:-1:-1;;;;;107656:19:0;;107652:158;;107701:6;107686:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;107652:158:0;;-1:-1:-1;107652:158:0;;-1:-1:-1;;;;;107776:16:0;;;;;;:9;:16;;;;;:26;;107796:6;;107776:16;:26;;107796:6;;107776:26;:::i;:::-;;;;-1:-1:-1;;107652:158:0;-1:-1:-1;;;;;107999:14:0;;;;;;;:9;:14;;;;;;;:24;;;;;;108044:33;107999:14;;108044:33;;;;;;;108017:6;1107:25:1;;1095:2;1080:18;;961:177;108044:33:0;;;;;;;;107400:683;;;:::o;108311:1110::-;-1:-1:-1;;;;;108512:19:0;;;108508:518;;108614:16;;;;:11;:16;;;;;;;;108607:23;;-1:-1:-1;;;;;;108607:23:0;;;-1:-1:-1;;;;;108661:13:0;;;;:6;:13;;;;;108675:20;;:24;;108607:23;;108675:24;:::i;:::-;108661:39;;;;;;;;:::i;:::-;;;;;;;;;108641:59;;108728:3;108715:9;:16;108711:264;;108744:20;117804:15;;;:10;:15;;;;;;117871:3;117861:14;;-1:-1:-1;;;;;108834:13:0;;;;;;:6;:13;;;;;:27;;108744:42;;-1:-1:-1;108864:9:0;;108744:42;;108834:27;;;;;;:::i;:::-;;;;;;;;;;:39;108926;108941:9;108952:12;108926:14;:39::i;:::-;108733:242;108711:264;-1:-1:-1;;;;;108999:13:0;;;;;;:6;:13;;;;;:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;108533:493;108508:518;-1:-1:-1;;;;;109038:17:0;;;109034:337;;117475:12;117490:15;;;:10;:15;;;;;;;;;;-1:-1:-1;;;;;;117554:31:0;-1:-1:-1;;;;;117596:29:0;;117540:94;;;117649:22;;;109199:11;;;:6;:11;;;;;:21;;-1:-1:-1;109199:21:0;;;;;;;;;;;;;;;109295:11;;:18;;109275:43;;117490:15;;109295:22;;-1:-1:-1;109295:22:0;:::i;:::-;109275:14;:43::i;:::-;109034:337;;;109348:15;;;;:10;:15;;;;;109341:22;109034:337;109411:3;109406;-1:-1:-1;;;;;109384:31:0;109399:5;-1:-1:-1;;;;;109384:31:0;;;;;;;;;;;108311:1110;;;:::o;109539:4314::-;-1:-1:-1;;;;;99431:17:0;;;109663:4;99431:17;;;:9;:17;;;;;;;;;;;;;;;109663:4;;99431:17;109808:34;109823:5;109830:3;109835:6;109808:14;:34::i;:::-;-1:-1:-1;;;;;109920:16:0;;;109895:22;109920:16;;;:9;:16;;;;;;;109966:14;;;;;;;;109920:16;;;;;109966:14;109920:16;110212:36;;;;;110233:15;110212:36;110208:3620;;110381:17;110377:3451;;;110745:30;110815:36;110846:5;110815:28;:36;:::i;:::-;-1:-1:-1;;;;;110779:14:0;;;;;;:9;:14;;;;;;:22;;110796:5;;110779:22;:::i;:::-;110778:74;;;;:::i;:::-;110745:107;;110866:9;110861:100;110885:22;110881:1;:26;110861:100;;;110925:26;110947:3;110925:21;:26::i;:::-;110909:3;;110861:100;;;;110400:568;110377:3451;;;110978:15;110974:2854;;;-1:-1:-1;;;;;111387:16:0;;111303:32;111387:16;;;:9;:16;;;;;;:24;;111406:5;;111387:24;:::i;:::-;111339:34;111368:5;111339:26;:34;:::i;:::-;111338:74;;;;:::i;:::-;111303:109;;111426:9;111421:106;111445:24;111441:1;:28;111421:106;;;111487:30;111511:5;111487:23;:30::i;:::-;111471:3;;111421:106;;110974:2854;112317:22;112342:14;112351:5;112342:6;:14;:::i;:::-;112317:39;;112370:9;112365:293;112389:14;112385:1;:18;112365:293;;;-1:-1:-1;;;;;112517:13:0;;112490:24;112517:13;;;:6;:13;;;;;:20;:24;;112540:1;;112517:24;:::i;:::-;-1:-1:-1;;;;;112570:13:0;;112552:15;112570:13;;;:6;:13;;;;;:31;;112490:51;;-1:-1:-1;112552:15:0;;112490:51;;112570:31;;;;;;:::i;:::-;;;;;;;;;112552:49;;112612:36;112628:5;112635:3;112640:7;112612:15;:36::i;:::-;-1:-1:-1;;112405:3:0;;112365:293;;;-1:-1:-1;113214:24:0;113241:14;113250:5;113241:6;:14;:::i;:::-;113214:41;-1:-1:-1;113348:34:0;113377:5;113348:26;:34;:::i;:::-;113330:5;113281:45;113310:16;113281:26;:45;:::i;:::-;113280:55;;;;:::i;:::-;:103;113266:178;;;113404:30;113428:5;113404:23;:30::i;:::-;113727:36;113758:5;113727:28;:36;:::i;:::-;113709:5;113658:47;113689:16;113658:28;:47;:::i;:::-;113657:57;;;;:::i;:::-;:107;113643:178;;;113785:26;113807:3;113785:21;:26::i;:::-;111540:2288;;110974:2854;-1:-1:-1;113843:4:0;;109539:4314;-1:-1:-1;;;;;;;109539:4314:0:o;106774:400::-;106840:7;106913:121;107063:4;107047:22;;;;;;:::i;:::-;;;;;;;;;;106890:269;;;15513:25:1;;;;15554:18;;15547:34;;;;107082:14:0;15597:18:1;;;15590:34;107109:13:0;15640:18:1;;;15633:34;107143:4:0;15683:19:1;;;15676:61;15485:19;;106890:269:0;;;;;;;;;;;;106870:298;;;;;;106856:312;;106774:400;:::o;12059:166::-;11940:7;11967:6;-1:-1:-1;;;;;11967:6:0;10142:10;12119:23;12115:103;;12166:40;;-1:-1:-1;;;12166:40:0;;10142:10;12166:40;;;2130:51:1;2103:18;;12166:40:0;1984:203:1;116713:468:0;117073:5;117046:23;117061:7;-1:-1:-1;;;;;99431:17:0;99408:7;99431:17;;;:9;:17;;;;;;;99329:125;117046:23;:32;;:43;;;;;117083:6;117082:7;117046:43;117042:100;;;117107:27;;-1:-1:-1;;;117107:27:0;;;;;;;;;;;117042:100;-1:-1:-1;;;;;117148:18:0;;;;;;;;:9;:18;;;;;:27;;-1:-1:-1;;117148:27:0;;;;;;;;;;116713:468::o;13207:191::-;13281:16;13300:6;;-1:-1:-1;;;;;13317:17:0;;;-1:-1:-1;;;;;;13317:17:0;;;;;;13350:40;;13300:6;;;;;;;13350:40;;13281:16;13350:40;13270:128;13207:191;:::o;85372:156::-;85463:4;85516;85487:25;85500:5;85507:4;85487:12;:25::i;:::-;:33;;85372:156;-1:-1:-1;;;;85372:156:0:o;95233:181::-;94641:17;;:22;;:40;;-1:-1:-1;94668:13:0;;;;94667:14;94641:40;94637:87;;;94699:17;;-1:-1:-1;;;94699:17:0;;;;;;;;;;;94637:87;95350:58:::1;95381:6;95389:10;95401:6;95350:30;:58::i;114065:633::-:0;-1:-1:-1;;;;;114299:17:0;;114295:65;;114334:18;;-1:-1:-1;;;114334:18:0;;;;;;;;;;;114295:65;114368:39;114391:1;114395:3;114400:6;114368:14;:39::i;:::-;114498:25;114494:199;;;114534:28;114565:14;114574:5;114565:6;:14;:::i;:::-;114534:45;;114593:9;114588:98;114612:20;114608:1;:24;114588:98;;;114650:26;114672:3;114650:21;:26::i;:::-;114634:3;;114588:98;;81690:718;81746:13;81797:14;81814:17;81825:5;81814:10;:17::i;:::-;81834:1;81814:21;81797:38;;81850:20;81884:6;81873:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81873:18:0;-1:-1:-1;81850:41:0;-1:-1:-1;82015:28:0;;;82031:2;82015:28;82072:290;-1:-1:-1;;82104:5:0;-1:-1:-1;;;82241:2:0;82230:14;;82225:32;82104:5;82212:46;82304:2;82295:11;;;-1:-1:-1;82325:21:0;82072:290;82325:21;-1:-1:-1;82383:6:0;81690:718;-1:-1:-1;;;81690:718:0:o;117893:383::-;117970:12;117985:15;;;:10;:15;;;;;;118022:27;118013:36;;118009:86;;;118067:20;;-1:-1:-1;;;118067:20:0;;;;;;;;;;;118009:86;118248:15;;;;:10;:15;;;;;;-1:-1:-1;;;;;118143:27:0;;;;118197:3;118185:16;;;-1:-1:-1;;;;;;118181:43:0;118129:104;118248:22;;117893:383::o;114987:947::-;-1:-1:-1;;;;;115059:17:0;;115055:65;;115094:18;;-1:-1:-1;;;115094:18:0;;;;;;;;;;;115055:65;115128:10;115152:40;115175:16;9497:12;-1:-1:-1;;;9483:10:0;;-1:-1:-1;;;;;9483:10:0;;;9497:12;;9483:26;;9397:118;115152:40;115147:357;;115319:26;:16;:24;:26::i;:::-;115314:31;;115147:357;;;115466:7;:9;;;:7;:9;;;:::i;:::-;;;;;;115489:7;;115484:12;;115147:357;115512:19;117302:15;;;:10;:15;;;;;;-1:-1:-1;;;;;117356:27:0;115715:25;;115711:70;;115758:15;;-1:-1:-1;;;115758:15:0;;;;;;;;;;;115711:70;115891:37;115907:11;115920:3;115925:2;115891:15;:37::i;116134:456::-;-1:-1:-1;;;;;116210:19:0;;116206:64;;116247:15;;-1:-1:-1;;;116247:15:0;;;;;;;;;;;116206:64;-1:-1:-1;;;;;116360:13:0;;116347:10;116360:13;;;:6;:13;;;;;116374:20;;:24;;116397:1;;116374:24;:::i;:::-;116360:39;;;;;;;;:::i;:::-;;;;;;;;;116347:52;;116452:38;116468:5;116483:1;116487:2;116452:15;:38::i;:::-;116554:30;:16;116581:2;116554:26;:30::i;86091:296::-;86174:7;86217:4;86174:7;86232:118;86256:5;:12;86252:1;:16;86232:118;;;86305:33;86315:12;86329:5;86335:1;86329:8;;;;;;;;:::i;:::-;;;;;;;86305:9;:33::i;:::-;86290:48;-1:-1:-1;86270:3:0;;86232:118;;;-1:-1:-1;86367:12:0;86091:296;-1:-1:-1;;;86091:296:0:o;95635:499::-;95819:37;95831:6;95839:8;95849:6;95819:11;:37::i;:::-;95814:91;;95874:23;;-1:-1:-1;;;95874:23:0;;;;;;;;;;;95814:91;-1:-1:-1;;;;;95977:27:0;;;;;;:17;:27;;;;;;;;95973:80;;;96022:23;;-1:-1:-1;;;96022:23:0;;;;;;;;;;;95973:80;-1:-1:-1;;;;;;96094:27:0;;;;;:17;:27;;;;;:34;;-1:-1:-1;;96094:34:0;96124:4;96094:34;;;-1:-1:-1;95635:499:0:o;76385:948::-;76438:7;;-1:-1:-1;;;76516:17:0;;76512:106;;-1:-1:-1;;;76554:17:0;;;-1:-1:-1;76600:2:0;76590:12;76512:106;76645:8;76636:5;:17;76632:106;;76683:8;76674:17;;;-1:-1:-1;76720:2:0;76710:12;76632:106;76765:8;76756:5;:17;76752:106;;76803:8;76794:17;;;-1:-1:-1;76840:2:0;76830:12;76752:106;76885:7;76876:5;:16;76872:103;;76922:7;76913:16;;;-1:-1:-1;76958:1:0;76948:11;76872:103;77002:7;76993:5;:16;76989:103;;77039:7;77030:16;;;-1:-1:-1;77075:1:0;77065:11;76989:103;77119:7;77110:5;:16;77106:103;;77156:7;77147:16;;;-1:-1:-1;77192:1:0;77182:11;77106:103;77236:7;77227:5;:16;77223:68;;77274:1;77264:11;77319:6;76385:948;-1:-1:-1;;76385:948:0:o;6247:344::-;6381:10;;6320:13;;-1:-1:-1;;;;;;;;6381:10:0;;;;;6417:12;6404:25;;6400:50;;6438:12;;-1:-1:-1;;;6438:12:0;;;;;;;;;;;6400:50;-1:-1:-1;;6459:11:0;-1:-1:-1;;;;;6487:22:0;;;;;;;6459:11;6487;;:22;;;;;;;6518:29;;;6556:22;;;;;-1:-1:-1;;;6556:22:0;;;;;;;-1:-1:-1;6487:22:0;6247:344::o;6728:278::-;6846:12;;-1:-1:-1;;;;;6846:12:0;;;-1:-1:-1;;6846:16:0;;-1:-1:-1;;;6889:10:0;;;;6875:24;;;;6871:48;;6908:11;;-1:-1:-1;;;6908:11:0;;;;;;;;;;;6871:48;-1:-1:-1;;;;;6928:23:0;;;;;:11;;;:23;;;;;:31;;;;6968:25;;-1:-1:-1;;6968:25:0;;;;6728:278::o;93521:149::-;93584:7;93615:1;93611;:5;:51;;93863:13;93957:15;;;93993:4;93986:15;;;94040:4;94024:21;;93611:51;;;93863:13;93957:15;;;93993:4;93986:15;;;94040:4;94024:21;;93619:20;93795:268;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:173::-;660:20;;-1:-1:-1;;;;;709:31:1;;699:42;;689:70;;755:1;752;745:12;770:186;829:6;882:2;870:9;861:7;857:23;853:32;850:52;;;898:1;895;888:12;850:52;921:29;940:9;921:29;:::i;1143:250::-;1228:1;1238:113;1252:6;1249:1;1246:13;1238:113;;;1328:11;;;1322:18;1309:11;;;1302:39;1274:2;1267:10;1238:113;;;-1:-1:-1;;1385:1:1;1367:16;;1360:27;1143:250::o;1398:396::-;1547:2;1536:9;1529:21;1510:4;1579:6;1573:13;1622:6;1617:2;1606:9;1602:18;1595:34;1638:79;1710:6;1705:2;1694:9;1690:18;1685:2;1677:6;1673:15;1638:79;:::i;:::-;1778:2;1757:15;-1:-1:-1;;1753:29:1;1738:45;;;;1785:2;1734:54;;1398:396;-1:-1:-1;;1398:396:1:o;1799:180::-;1858:6;1911:2;1899:9;1890:7;1886:23;1882:32;1879:52;;;1927:1;1924;1917:12;1879:52;-1:-1:-1;1950:23:1;;1799:180;-1:-1:-1;1799:180:1:o;2192:254::-;2260:6;2268;2321:2;2309:9;2300:7;2296:23;2292:32;2289:52;;;2337:1;2334;2327:12;2289:52;2360:29;2379:9;2360:29;:::i;:::-;2350:39;2436:2;2421:18;;;;2408:32;;-1:-1:-1;;;2192:254:1:o;2451:328::-;2528:6;2536;2544;2597:2;2585:9;2576:7;2572:23;2568:32;2565:52;;;2613:1;2610;2603:12;2565:52;2636:29;2655:9;2636:29;:::i;:::-;2626:39;;2684:38;2718:2;2707:9;2703:18;2684:38;:::i;:::-;2674:48;;2769:2;2758:9;2754:18;2741:32;2731:42;;2451:328;;;;;:::o;3155:347::-;3220:6;3228;3281:2;3269:9;3260:7;3256:23;3252:32;3249:52;;;3297:1;3294;3287:12;3249:52;3320:29;3339:9;3320:29;:::i;:::-;3310:39;;3399:2;3388:9;3384:18;3371:32;3446:5;3439:13;3432:21;3425:5;3422:32;3412:60;;3468:1;3465;3458:12;3412:60;3491:5;3481:15;;;3155:347;;;;;:::o;3507:127::-;3568:10;3563:3;3559:20;3556:1;3549:31;3599:4;3596:1;3589:15;3623:4;3620:1;3613:15;3639:908;3693:5;3746:3;3739:4;3731:6;3727:17;3723:27;3713:55;;3764:1;3761;3754:12;3713:55;3800:6;3787:20;3826:4;3849:18;3886:2;3882;3879:10;3876:36;;;3892:18;;:::i;:::-;3938:2;3935:1;3931:10;3970:2;3964:9;4033:2;4029:7;4024:2;4020;4016:11;4012:25;4004:6;4000:38;4088:6;4076:10;4073:22;4068:2;4056:10;4053:18;4050:46;4047:72;;;4099:18;;:::i;:::-;4135:2;4128:22;4185:18;;;4231:4;4263:15;;;4259:26;;;4219:17;;;;-1:-1:-1;4297:15:1;;;4294:35;;;4325:1;4322;4315:12;4294:35;4361:4;4353:6;4349:17;4338:28;;4375:142;4391:6;4386:3;4383:15;4375:142;;;4457:17;;4445:30;;4495:12;;;;4408;;;;4375:142;;;4535:6;3639:908;-1:-1:-1;;;;;;;3639:908:1:o;4552:490::-;4654:6;4662;4670;4723:2;4711:9;4702:7;4698:23;4694:32;4691:52;;;4739:1;4736;4729:12;4691:52;4779:9;4766:23;4812:18;4804:6;4801:30;4798:50;;;4844:1;4841;4834:12;4798:50;4867:61;4920:7;4911:6;4900:9;4896:22;4867:61;:::i;:::-;4857:71;;;4947:38;4981:2;4970:9;4966:18;4947:38;:::i;5047:416::-;5140:6;5148;5201:2;5189:9;5180:7;5176:23;5172:32;5169:52;;;5217:1;5214;5207:12;5169:52;5257:9;5244:23;5290:18;5282:6;5279:30;5276:50;;;5322:1;5319;5312:12;5276:50;5345:61;5398:7;5389:6;5378:9;5374:22;5345:61;:::i;:::-;5335:71;5453:2;5438:18;;;;5425:32;;-1:-1:-1;;;;5047:416:1:o;5468:632::-;5639:2;5691:21;;;5761:13;;5664:18;;;5783:22;;;5610:4;;5639:2;5862:15;;;;5836:2;5821:18;;;5610:4;5905:169;5919:6;5916:1;5913:13;5905:169;;;5980:13;;5968:26;;6049:15;;;;6014:12;;;;5941:1;5934:9;5905:169;;;-1:-1:-1;6091:3:1;;5468:632;-1:-1:-1;;;;;;5468:632:1:o;6105:808::-;6202:6;6210;6218;6226;6234;6287:3;6275:9;6266:7;6262:23;6258:33;6255:53;;;6304:1;6301;6294:12;6255:53;6327:29;6346:9;6327:29;:::i;:::-;6317:39;;6375:38;6409:2;6398:9;6394:18;6375:38;:::i;:::-;6365:48;;6460:2;6449:9;6445:18;6432:32;6422:42;;6515:2;6504:9;6500:18;6487:32;6538:18;6579:2;6571:6;6568:14;6565:34;;;6595:1;6592;6585:12;6565:34;6633:6;6622:9;6618:22;6608:32;;6678:7;6671:4;6667:2;6663:13;6659:27;6649:55;;6700:1;6697;6690:12;6649:55;6740:2;6727:16;6766:2;6758:6;6755:14;6752:34;;;6782:1;6779;6772:12;6752:34;6827:7;6822:2;6813:6;6809:2;6805:15;6801:24;6798:37;6795:57;;;6848:1;6845;6838:12;6795:57;6105:808;;;;-1:-1:-1;6105:808:1;;-1:-1:-1;6879:2:1;6871:11;;6901:6;6105:808;-1:-1:-1;;;6105:808:1:o;6918:693::-;7029:6;7037;7045;7053;7061;7069;7077;7130:3;7118:9;7109:7;7105:23;7101:33;7098:53;;;7147:1;7144;7137:12;7098:53;7170:29;7189:9;7170:29;:::i;:::-;7160:39;;7218:38;7252:2;7241:9;7237:18;7218:38;:::i;:::-;7208:48;;7303:2;7292:9;7288:18;7275:32;7265:42;;7354:2;7343:9;7339:18;7326:32;7316:42;;7408:3;7397:9;7393:19;7380:33;7453:4;7446:5;7442:16;7435:5;7432:27;7422:55;;7473:1;7470;7463:12;7422:55;6918:693;;;;-1:-1:-1;6918:693:1;;;;7496:5;7548:3;7533:19;;7520:33;;-1:-1:-1;7600:3:1;7585:19;;;7572:33;;6918:693;-1:-1:-1;;6918:693:1:o;7616:260::-;7684:6;7692;7745:2;7733:9;7724:7;7720:23;7716:32;7713:52;;;7761:1;7758;7751:12;7713:52;7784:29;7803:9;7784:29;:::i;:::-;7774:39;;7832:38;7866:2;7855:9;7851:18;7832:38;:::i;:::-;7822:48;;7616:260;;;;;:::o;8066:380::-;8145:1;8141:12;;;;8188;;;8209:61;;8263:4;8255:6;8251:17;8241:27;;8209:61;8316:2;8308:6;8305:14;8285:18;8282:38;8279:161;;8362:10;8357:3;8353:20;8350:1;8343:31;8397:4;8394:1;8387:15;8425:4;8422:1;8415:15;8279:161;;8066:380;;;:::o;8831:127::-;8892:10;8887:3;8883:20;8880:1;8873:31;8923:4;8920:1;8913:15;8947:4;8944:1;8937:15;8963:128;9030:9;;;9051:11;;;9048:37;;;9065:18;;:::i;9656:249::-;9725:6;9778:2;9766:9;9757:7;9753:23;9749:32;9746:52;;;9794:1;9791;9784:12;9746:52;9826:9;9820:16;9845:30;9869:5;9845:30;:::i;10376:662::-;-1:-1:-1;;;;;10655:15:1;;;10637:34;;10707:15;;10702:2;10687:18;;10680:43;10754:2;10739:18;;10732:34;;;10802:3;10797:2;10782:18;;10775:31;;;10822:19;;10815:35;;;10580:4;10843:6;10893;10617:3;10872:19;;10859:49;10958:1;10952:3;10943:6;10932:9;10928:22;10924:32;10917:43;11028:3;11021:2;11017:7;11012:2;11004:6;11000:15;10996:29;10985:9;10981:45;10977:55;10969:63;;10376:662;;;;;;;;:::o;11043:783::-;11395:34;11390:3;11383:47;11460:34;11455:2;11450:3;11446:12;11439:56;11525:34;11520:2;11515:3;11511:12;11504:56;-1:-1:-1;;;11585:2:1;11580:3;11576:12;11569:31;11365:3;11629:6;11623:13;11645:74;11712:6;11706:3;11701;11697:13;11692:2;11684:6;11680:15;11645:74;:::i;:::-;-1:-1:-1;;;11778:3:1;11738:16;;;;11770:12;;;11763:29;-1:-1:-1;11816:3:1;11808:12;;11043:783;-1:-1:-1;11043:783:1:o;13227:125::-;13292:9;;;13313:10;;;13310:36;;;13326:18;;:::i;13357:127::-;13418:10;13413:3;13409:20;13406:1;13399:31;13449:4;13446:1;13439:15;13473:4;13470:1;13463:15;13489:127;13550:10;13545:3;13541:20;13538:1;13531:31;13581:4;13578:1;13571:15;13605:4;13602:1;13595:15;13621:127;13682:10;13677:3;13673:20;13670:1;13663:31;13713:4;13710:1;13703:15;13737:4;13734:1;13727:15;13753:120;13793:1;13819;13809:35;;13824:18;;:::i;:::-;-1:-1:-1;13858:9:1;;13753:120::o;13878:112::-;13910:1;13936;13926:35;;13941:18;;:::i;:::-;-1:-1:-1;13975:9:1;;13878:112::o;14124:1125::-;14254:3;14283:1;14316:6;14310:13;14346:1;14366;14393:9;14390:1;14386:17;14376:27;;14453:1;14442:9;14438:17;14474:18;14464:61;;14518:4;14510:6;14506:17;14496:27;;14464:61;14544:2;14592;14584:6;14581:14;14561:18;14558:38;14555:161;;14638:10;14633:3;14629:20;14626:1;14619:31;14673:4;14670:1;14663:15;14701:4;14698:1;14691:15;14555:161;14732:18;14759:133;;;;14906:1;14901:323;;;;14725:499;;14759:133;-1:-1:-1;;14792:24:1;;14780:37;;14865:14;;14858:22;14846:35;;14837:45;;;-1:-1:-1;14759:133:1;;14901:323;14071:1;14064:14;;;14108:4;14095:18;;14999:1;15013:165;15027:6;15024:1;15021:13;15013:165;;;15105:14;;15092:11;;;15085:35;15148:16;;;;15042:10;;15013:165;;;15017:3;;15207:6;15202:3;15198:16;15191:23;;14725:499;-1:-1:-1;15240:3:1;;14124:1125;-1:-1:-1;;;;;;;;14124:1125:1:o;15748:135::-;15787:3;15808:17;;;15805:43;;15828:18;;:::i;:::-;-1:-1:-1;15875:1:1;15864:13;;15748:135::o
Swarm Source
ipfs://6b286dd966248aaa06026b0df67e9672c40043f2b11f7036153e18c94d9608c1
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.