ETH Price: $2,048.03 (+0.57%)

Transaction Decoder

Block:
18511297 at Nov-06-2023 06:55:59 AM +UTC
Transaction Fee:
0.004543632939062212 ETH $9.31
Gas Used:
134,231 Gas / 33.849356252 Gwei

Emitted Events:

254 SimpsPunks.Approval( owner=0x2472533e2a410c42a0275ccebee4b970698d2890, approved=0x00000000...000000000, tokenId=2913 )
255 SimpsPunks.Transfer( from=0x2472533e2a410c42a0275ccebee4b970698d2890, to=[Sender] 0xac9fa4158c0c7195bbe6bf40cbf6236e8a71c151, tokenId=2913 )
256 0xb2ecfe4e4d61f8790bbb9de2d1259b9e2410cea5.0x1d5e12b51dee5e4d34434576c3fb99714a85f57b0fd546ada4b0bddd736d12b2( 0x1d5e12b51dee5e4d34434576c3fb99714a85f57b0fd546ada4b0bddd736d12b2, b145b74fdf7da6aa8939c3d7d4d2b8d646669975e82652c2f488198861f861d1, 0000000000000000000b61012472533e2a410c42a0275ccebee4b970698d2890, 00000000004e28e2290f000098edba85dba119af60f8b7d02938c33315b9cdc1 )

Account State Difference:

  Address   Before After State Difference Code
0x2472533E...0698d2890 0.088484589631342738 Eth0.110484589631342738 Eth0.022
(Lido: Execution Layer Rewards Vault)
223.567207707964661739 Eth223.567222473374661739 Eth0.00001476541
0x98eDBa85...315b9CdC1
0xaC9Fa415...E8A71c151
0.148974941519686252 Eth
Nonce: 756
0.12243130858062404 Eth
Nonce: 757
0.026543632939062212
0xb2ecfE4E...e2410CEA5
(Blur.io: Marketplace 3)

Execution Trace

ETH 0.022 Blur.io: Marketplace 3.70bce2d6( )
  • ETH 0.022 0x5fa60726e62c50af45ff2f6280c468da438a7837.70bce2d6( )
    • Null: 0x000...001.17c99154( )
    • Null: 0x000...001.8911532f( )
    • Delegate.transfer( taker=0xaC9Fa4158c0c7195bBE6bF40CBf6236E8A71c151, orderType=0, transfers=, length=1 ) => ( successful=[true] )
      • SimpsPunks.safeTransferFrom( from=0x2472533E2a410c42A0275CcEBee4B970698d2890, to=0xaC9Fa4158c0c7195bBE6bF40CBf6236E8A71c151, tokenId=2913 )
      • ETH 0.022 0x2472533e2a410c42a0275ccebee4b970698d2890.CALL( )
        File 1 of 2: SimpsPunks
        // SPDX-License-Identifier: MIT
        
        // File: @openzeppelin/contracts/security/ReentrancyGuard.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
        
        pragma solidity ^0.8.0;
        
        /**
         * @dev Contract module that helps prevent reentrant calls to a function.
         *
         * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
         * available, which can be applied to functions to make sure there are no nested
         * (reentrant) calls to them.
         *
         * Note that because there is a single `nonReentrant` guard, functions marked as
         * `nonReentrant` may not call one another. This can be worked around by making
         * those functions `private`, and then adding `external` `nonReentrant` entry
         * points to them.
         *
         * TIP: If you would like to learn more about reentrancy and alternative ways
         * to protect against it, check out our blog post
         * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
         */
        abstract contract ReentrancyGuard {
            // Booleans are more expensive than uint256 or any type that takes up a full
            // word because each write operation emits an extra SLOAD to first read the
            // slot's contents, replace the bits taken up by the boolean, and then write
            // back. This is the compiler's defense against contract upgrades and
            // pointer aliasing, and it cannot be disabled.
        
            // The values being non-zero value makes deployment a bit more expensive,
            // but in exchange the refund on every call to nonReentrant will be lower in
            // amount. Since refunds are capped to a percentage of the total
            // transaction's gas, it is best to keep them low in cases like this one, to
            // increase the likelihood of the full refund coming into effect.
            uint256 private constant _NOT_ENTERED = 1;
            uint256 private constant _ENTERED = 2;
        
            uint256 private _status;
        
            constructor() {
                _status = _NOT_ENTERED;
            }
        
            /**
             * @dev Prevents a contract from calling itself, directly or indirectly.
             * Calling a `nonReentrant` function from another `nonReentrant`
             * function is not supported. It is possible to prevent this from happening
             * by making the `nonReentrant` function external, and making it call a
             * `private` function that does the actual work.
             */
            modifier nonReentrant() {
                // On the first call to nonReentrant, _notEntered will be true
                require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
        
                // Any calls to nonReentrant after this point will fail
                _status = _ENTERED;
        
                _;
        
                // By storing the original value once again, a refund is triggered (see
                // https://eips.ethereum.org/EIPS/eip-2200)
                _status = _NOT_ENTERED;
            }
        }
        
        // File: @openzeppelin/contracts/utils/Strings.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
        
        pragma solidity ^0.8.0;
        
        /**
         * @dev String operations.
         */
        library Strings {
            bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
        
            /**
             * @dev Converts a `uint256` to its ASCII `string` decimal representation.
             */
            function toString(uint256 value) internal pure returns (string memory) {
                // Inspired by OraclizeAPI's implementation - MIT licence
                // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
        
                if (value == 0) {
                    return "0";
                }
                uint256 temp = value;
                uint256 digits;
                while (temp != 0) {
                    digits++;
                    temp /= 10;
                }
                bytes memory buffer = new bytes(digits);
                while (value != 0) {
                    digits -= 1;
                    buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
                    value /= 10;
                }
                return string(buffer);
            }
        
            /**
             * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
             */
            function toHexString(uint256 value) internal pure returns (string memory) {
                if (value == 0) {
                    return "0x00";
                }
                uint256 temp = value;
                uint256 length = 0;
                while (temp != 0) {
                    length++;
                    temp >>= 8;
                }
                return toHexString(value, length);
            }
        
            /**
             * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
             */
            function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
                bytes memory buffer = new bytes(2 * length + 2);
                buffer[0] = "0";
                buffer[1] = "x";
                for (uint256 i = 2 * length + 1; i > 1; --i) {
                    buffer[i] = _HEX_SYMBOLS[value & 0xf];
                    value >>= 4;
                }
                require(value == 0, "Strings: hex length insufficient");
                return string(buffer);
            }
        }
        
        // File: @openzeppelin/contracts/utils/Context.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
        
        pragma solidity ^0.8.0;
        
        /**
         * @dev Provides information about the current execution context, including the
         * sender of the transaction and its data. While these are generally available
         * via msg.sender and msg.data, they should not be accessed in such a direct
         * manner, since when dealing with meta-transactions the account sending and
         * paying for execution may not be the actual sender (as far as an application
         * is concerned).
         *
         * This contract is only required for intermediate, library-like contracts.
         */
        abstract contract Context {
            function _msgSender() internal view virtual returns (address) {
                return msg.sender;
            }
        
            function _msgData() internal view virtual returns (bytes calldata) {
                return msg.data;
            }
        }
        
        // File: @openzeppelin/contracts/access/Ownable.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
        
        pragma solidity ^0.8.0;
        
        
        /**
         * @dev Contract module which provides a basic access control mechanism, where
         * there is an account (an owner) that can be granted exclusive access to
         * specific functions.
         *
         * By default, the owner account will be the one that deploys the contract. This
         * can later be changed with {transferOwnership}.
         *
         * This module is used through inheritance. It will make available the modifier
         * `onlyOwner`, which can be applied to your functions to restrict their use to
         * the owner.
         */
        abstract contract Ownable is Context {
            address private _owner;
        
            event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
        
            /**
             * @dev Initializes the contract setting the deployer as the initial owner.
             */
            constructor() {
                _transferOwnership(_msgSender());
            }
        
            /**
             * @dev Returns the address of the current owner.
             */
            function owner() public view virtual returns (address) {
                return _owner;
            }
        
            /**
             * @dev Throws if called by any account other than the owner.
             */
            modifier onlyOwner() {
                require(owner() == _msgSender(), "Ownable: caller is not the owner");
                _;
            }
        
            /**
             * @dev Leaves the contract without owner. It will not be possible to call
             * `onlyOwner` functions anymore. Can only be called by the current owner.
             *
             * NOTE: Renouncing ownership will leave the contract without an owner,
             * thereby removing any functionality that is only available to the owner.
             */
            function renounceOwnership() public virtual onlyOwner {
                _transferOwnership(address(0));
            }
        
            /**
             * @dev Transfers ownership of the contract to a new account (`newOwner`).
             * Can only be called by the current owner.
             */
            function transferOwnership(address newOwner) public virtual onlyOwner {
                require(newOwner != address(0), "Ownable: new owner is the zero address");
                _transferOwnership(newOwner);
            }
        
            /**
             * @dev Transfers ownership of the contract to a new account (`newOwner`).
             * Internal function without access restriction.
             */
            function _transferOwnership(address newOwner) internal virtual {
                address oldOwner = _owner;
                _owner = newOwner;
                emit OwnershipTransferred(oldOwner, newOwner);
            }
        }
        
        // File: @openzeppelin/contracts/utils/Address.sol
        
        
        // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
        
        pragma solidity ^0.8.1;
        
        /**
         * @dev Collection of functions related to the address type
         */
        library Address {
            /**
             * @dev Returns true if `account` is a contract.
             *
             * [IMPORTANT]
             * ====
             * It is unsafe to assume that an address for which this function returns
             * false is an externally-owned account (EOA) and not a contract.
             *
             * Among others, `isContract` will return false for the following
             * types of addresses:
             *
             *  - an externally-owned account
             *  - a contract in construction
             *  - an address where a contract will be created
             *  - an address where a contract lived, but was destroyed
             * ====
             *
             * [IMPORTANT]
             * ====
             * You shouldn't rely on `isContract` to protect against flash loan attacks!
             *
             * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
             * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
             * constructor.
             * ====
             */
            function isContract(address account) internal view returns (bool) {
                // This method relies on extcodesize/address.code.length, which returns 0
                // for contracts in construction, since the code is only stored at the end
                // of the constructor execution.
        
                return account.code.length > 0;
            }
        
            /**
             * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
             * `recipient`, forwarding all available gas and reverting on errors.
             *
             * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
             * of certain opcodes, possibly making contracts go over the 2300 gas limit
             * imposed by `transfer`, making them unable to receive funds via
             * `transfer`. {sendValue} removes this limitation.
             *
             * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
             *
             * IMPORTANT: because control is transferred to `recipient`, care must be
             * taken to not create reentrancy vulnerabilities. Consider using
             * {ReentrancyGuard} or the
             * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
             */
            function sendValue(address payable recipient, uint256 amount) internal {
                require(address(this).balance >= amount, "Address: insufficient balance");
        
                (bool success, ) = recipient.call{value: amount}("");
                require(success, "Address: unable to send value, recipient may have reverted");
            }
        
            /**
             * @dev Performs a Solidity function call using a low level `call`. A
             * plain `call` is an unsafe replacement for a function call: use this
             * function instead.
             *
             * If `target` reverts with a revert reason, it is bubbled up by this
             * function (like regular Solidity function calls).
             *
             * Returns the raw returned data. To convert to the expected return value,
             * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
             *
             * Requirements:
             *
             * - `target` must be a contract.
             * - calling `target` with `data` must not revert.
             *
             * _Available since v3.1._
             */
            function functionCall(address target, bytes memory data) internal returns (bytes memory) {
                return functionCall(target, data, "Address: low-level call failed");
            }
        
            /**
             * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
             * `errorMessage` as a fallback revert reason when `target` reverts.
             *
             * _Available since v3.1._
             */
            function functionCall(
                address target,
                bytes memory data,
                string memory errorMessage
            ) internal returns (bytes memory) {
                return functionCallWithValue(target, data, 0, errorMessage);
            }
        
            /**
             * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
             * but also transferring `value` wei to `target`.
             *
             * Requirements:
             *
             * - the calling contract must have an ETH balance of at least `value`.
             * - the called Solidity function must be `payable`.
             *
             * _Available since v3.1._
             */
            function functionCallWithValue(
                address target,
                bytes memory data,
                uint256 value
            ) internal returns (bytes memory) {
                return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
            }
        
            /**
             * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
             * with `errorMessage` as a fallback revert reason when `target` reverts.
             *
             * _Available since v3.1._
             */
            function functionCallWithValue(
                address target,
                bytes memory data,
                uint256 value,
                string memory errorMessage
            ) internal returns (bytes memory) {
                require(address(this).balance >= value, "Address: insufficient balance for call");
                require(isContract(target), "Address: call to non-contract");
        
                (bool success, bytes memory returndata) = target.call{value: value}(data);
                return verifyCallResult(success, returndata, errorMessage);
            }
        
            /**
             * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
             * but performing a static call.
             *
             * _Available since v3.3._
             */
            function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
                return functionStaticCall(target, data, "Address: low-level static call failed");
            }
        
            /**
             * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
             * but performing a static call.
             *
             * _Available since v3.3._
             */
            function functionStaticCall(
                address target,
                bytes memory data,
                string memory errorMessage
            ) internal view returns (bytes memory) {
                require(isContract(target), "Address: static call to non-contract");
        
                (bool success, bytes memory returndata) = target.staticcall(data);
                return verifyCallResult(success, returndata, errorMessage);
            }
        
            /**
             * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
             * but performing a delegate call.
             *
             * _Available since v3.4._
             */
            function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
                return functionDelegateCall(target, data, "Address: low-level delegate call failed");
            }
        
            /**
             * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
             * but performing a delegate call.
             *
             * _Available since v3.4._
             */
            function functionDelegateCall(
                address target,
                bytes memory data,
                string memory errorMessage
            ) internal returns (bytes memory) {
                require(isContract(target), "Address: delegate call to non-contract");
        
                (bool success, bytes memory returndata) = target.delegatecall(data);
                return verifyCallResult(success, returndata, errorMessage);
            }
        
            /**
             * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
             * revert reason using the provided one.
             *
             * _Available since v4.3._
             */
            function verifyCallResult(
                bool success,
                bytes memory returndata,
                string memory errorMessage
            ) internal pure returns (bytes memory) {
                if (success) {
                    return returndata;
                } else {
                    // 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
        
                        assembly {
                            let returndata_size := mload(returndata)
                            revert(add(32, returndata), returndata_size)
                        }
                    } else {
                        revert(errorMessage);
                    }
                }
            }
        }
        
        // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)
        
        pragma solidity ^0.8.0;
        
        /**
         * @title ERC721 token receiver interface
         * @dev Interface for any contract that wants to support safeTransfers
         * from ERC721 asset contracts.
         */
        interface IERC721Receiver {
            /**
             * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
             * by `operator` from `from`, this function is called.
             *
             * It must return its Solidity selector to confirm the token transfer.
             * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
             *
             * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
             */
            function onERC721Received(
                address operator,
                address from,
                uint256 tokenId,
                bytes calldata data
            ) external returns (bytes4);
        }
        
        // File: @openzeppelin/contracts/utils/introspection/IERC165.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
        
        pragma solidity ^0.8.0;
        
        /**
         * @dev Interface of the ERC165 standard, as defined in the
         * https://eips.ethereum.org/EIPS/eip-165[EIP].
         *
         * Implementers can declare support of contract interfaces, which can then be
         * queried by others ({ERC165Checker}).
         *
         * For an implementation, see {ERC165}.
         */
        interface IERC165 {
            /**
             * @dev Returns true if this contract implements the interface defined by
             * `interfaceId`. See the corresponding
             * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
             * to learn more about how these ids are created.
             *
             * This function call must use less than 30 000 gas.
             */
            function supportsInterface(bytes4 interfaceId) external view returns (bool);
        }
        
        // File: @openzeppelin/contracts/utils/introspection/ERC165.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
        
        pragma solidity ^0.8.0;
        
        
        /**
         * @dev Implementation of the {IERC165} interface.
         *
         * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
         * for the additional interface id that will be supported. For example:
         *
         * ```solidity
         * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
         *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
         * }
         * ```
         *
         * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
         */
        abstract contract ERC165 is IERC165 {
            /**
             * @dev See {IERC165-supportsInterface}.
             */
            function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
                return interfaceId == type(IERC165).interfaceId;
            }
        }
        
        // File: @openzeppelin/contracts/token/ERC721/IERC721.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)
        
        pragma solidity ^0.8.0;
        
        
        /**
         * @dev Required interface of an ERC721 compliant contract.
         */
        interface IERC721 is IERC165 {
            /**
             * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
             */
            event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
        
            /**
             * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
             */
            event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
        
            /**
             * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
             */
            event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
        
            /**
             * @dev Returns the number of tokens in ``owner``'s account.
             */
            function balanceOf(address owner) external view returns (uint256 balance);
        
            /**
             * @dev Returns the owner of the `tokenId` token.
             *
             * Requirements:
             *
             * - `tokenId` must exist.
             */
            function ownerOf(uint256 tokenId) external view returns (address owner);
        
            /**
             * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
             * are aware of the ERC721 protocol to prevent tokens from being forever locked.
             *
             * Requirements:
             *
             * - `from` cannot be the zero address.
             * - `to` cannot be the zero address.
             * - `tokenId` token must exist and be owned by `from`.
             * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
             * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
             *
             * Emits a {Transfer} event.
             */
            function safeTransferFrom(
                address from,
                address to,
                uint256 tokenId
            ) external;
        
            /**
             * @dev Transfers `tokenId` token from `from` to `to`.
             *
             * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
             *
             * Requirements:
             *
             * - `from` cannot be the zero address.
             * - `to` cannot be the zero address.
             * - `tokenId` token must be owned by `from`.
             * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
             *
             * Emits a {Transfer} event.
             */
            function transferFrom(
                address from,
                address to,
                uint256 tokenId
            ) external;
        
            /**
             * @dev Gives permission to `to` to transfer `tokenId` token to another account.
             * The approval is cleared when the token is transferred.
             *
             * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
             *
             * Requirements:
             *
             * - The caller must own the token or be an approved operator.
             * - `tokenId` must exist.
             *
             * Emits an {Approval} event.
             */
            function approve(address to, uint256 tokenId) external;
        
            /**
             * @dev Returns the account approved for `tokenId` token.
             *
             * Requirements:
             *
             * - `tokenId` must exist.
             */
            function getApproved(uint256 tokenId) external view returns (address operator);
        
            /**
             * @dev Approve or remove `operator` as an operator for the caller.
             * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
             *
             * Requirements:
             *
             * - The `operator` cannot be the caller.
             *
             * Emits an {ApprovalForAll} event.
             */
            function setApprovalForAll(address operator, bool _approved) external;
        
            /**
             * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
             *
             * See {setApprovalForAll}
             */
            function isApprovedForAll(address owner, address operator) external view returns (bool);
        
            /**
             * @dev Safely transfers `tokenId` token from `from` to `to`.
             *
             * Requirements:
             *
             * - `from` cannot be the zero address.
             * - `to` cannot be the zero address.
             * - `tokenId` token must exist and be owned by `from`.
             * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
             * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
             *
             * Emits a {Transfer} event.
             */
            function safeTransferFrom(
                address from,
                address to,
                uint256 tokenId,
                bytes calldata data
            ) external;
        }
        
        // File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol
        
        
        // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
        
        pragma solidity ^0.8.0;
        
        
        /**
         * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
         * @dev See https://eips.ethereum.org/EIPS/eip-721
         */
        interface IERC721Metadata is IERC721 {
            /**
             * @dev Returns the token collection name.
             */
            function name() external view returns (string memory);
        
            /**
             * @dev Returns the token collection symbol.
             */
            function symbol() external view returns (string memory);
        
            /**
             * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
             */
            function tokenURI(uint256 tokenId) external view returns (string memory);
        }
        
        // File: erc721a/contracts/ERC721A.sol
        
        
        // Creator: Chiru Labs
        
        pragma solidity ^0.8.4;
        
        
        
        
        
        
        
        
        error ApprovalCallerNotOwnerNorApproved();
        error ApprovalQueryForNonexistentToken();
        error ApproveToCaller();
        error ApprovalToCurrentOwner();
        error BalanceQueryForZeroAddress();
        error MintToZeroAddress();
        error MintZeroQuantity();
        error OwnerQueryForNonexistentToken();
        error TransferCallerNotOwnerNorApproved();
        error TransferFromIncorrectOwner();
        error TransferToNonERC721ReceiverImplementer();
        error TransferToZeroAddress();
        error URIQueryForNonexistentToken();
        
        /**
         * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
         * the Metadata extension. Built to optimize for lower gas during batch mints.
         *
         * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
         *
         * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
         *
         * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
         */
        contract ERC721A is Context, ERC165, IERC721, IERC721Metadata {
            using Address for address;
            using Strings for uint256;
        
            // Compiler will pack this into a single 256bit word.
            struct TokenOwnership {
                // The address of the owner.
                address addr;
                // Keeps track of the start time of ownership with minimal overhead for tokenomics.
                uint64 startTimestamp;
                // Whether the token has been burned.
                bool burned;
            }
        
            // Compiler will pack this into a single 256bit word.
            struct AddressData {
                // Realistically, 2**64-1 is more than enough.
                uint64 balance;
                // Keeps track of mint count with minimal overhead for tokenomics.
                uint64 numberMinted;
                // Keeps track of burn count with minimal overhead for tokenomics.
                uint64 numberBurned;
                // For miscellaneous variable(s) pertaining to the address
                // (e.g. number of whitelist mint slots used).
                // If there are multiple variables, please pack them into a uint64.
                uint64 aux;
            }
        
            // The tokenId of the next token to be minted.
            uint256 internal _currentIndex;
        
            // The number of tokens burned.
            uint256 internal _burnCounter;
        
            // Token name
            string private _name;
        
            // Token symbol
            string private _symbol;
        
            // Mapping from token ID to ownership details
            // An empty struct value does not necessarily mean the token is unowned. See _ownershipOf implementation for details.
            mapping(uint256 => TokenOwnership) internal _ownerships;
        
            // Mapping owner address to address data
            mapping(address => AddressData) private _addressData;
        
            // Mapping from token ID to approved address
            mapping(uint256 => address) private _tokenApprovals;
        
            // Mapping from owner to operator approvals
            mapping(address => mapping(address => bool)) private _operatorApprovals;
        
            constructor(string memory name_, string memory symbol_) {
                _name = name_;
                _symbol = symbol_;
                _currentIndex = _startTokenId();
            }
        
            /**
             * To change the starting tokenId, please override this function.
             */
            function _startTokenId() internal view virtual returns (uint256) {
                return 0;
            }
        
            /**
             * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
             */
            function totalSupply() public view returns (uint256) {
                // Counter underflow is impossible as _burnCounter cannot be incremented
                // more than _currentIndex - _startTokenId() times
                unchecked {
                    return _currentIndex - _burnCounter - _startTokenId();
                }
            }
        
            /**
             * Returns the total amount of tokens minted in the contract.
             */
            function _totalMinted() internal view returns (uint256) {
                // Counter underflow is impossible as _currentIndex does not decrement,
                // and it is initialized to _startTokenId()
                unchecked {
                    return _currentIndex - _startTokenId();
                }
            }
        
            /**
             * @dev See {IERC165-supportsInterface}.
             */
            function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
                return
                    interfaceId == type(IERC721).interfaceId ||
                    interfaceId == type(IERC721Metadata).interfaceId ||
                    super.supportsInterface(interfaceId);
            }
        
            /**
             * @dev See {IERC721-balanceOf}.
             */
            function balanceOf(address owner) public view override returns (uint256) {
                if (owner == address(0)) revert BalanceQueryForZeroAddress();
                return uint256(_addressData[owner].balance);
            }
        
            /**
             * Returns the number of tokens minted by `owner`.
             */
            function _numberMinted(address owner) internal view returns (uint256) {
                return uint256(_addressData[owner].numberMinted);
            }
        
            /**
             * Returns the number of tokens burned by or on behalf of `owner`.
             */
            function _numberBurned(address owner) internal view returns (uint256) {
                return uint256(_addressData[owner].numberBurned);
            }
        
            /**
             * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
             */
            function _getAux(address owner) internal view returns (uint64) {
                return _addressData[owner].aux;
            }
        
            /**
             * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
             * If there are multiple variables, please pack them into a uint64.
             */
            function _setAux(address owner, uint64 aux) internal {
                _addressData[owner].aux = aux;
            }
        
            /**
             * Gas spent here starts off proportional to the maximum mint batch size.
             * It gradually moves to O(1) as tokens get transferred around in the collection over time.
             */
            function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
                uint256 curr = tokenId;
        
                unchecked {
                    if (_startTokenId() <= curr && curr < _currentIndex) {
                        TokenOwnership memory ownership = _ownerships[curr];
                        if (!ownership.burned) {
                            if (ownership.addr != address(0)) {
                                return ownership;
                            }
                            // Invariant:
                            // There will always be an ownership that has an address and is not burned
                            // before an ownership that does not have an address and is not burned.
                            // Hence, curr will not underflow.
                            while (true) {
                                curr--;
                                ownership = _ownerships[curr];
                                if (ownership.addr != address(0)) {
                                    return ownership;
                                }
                            }
                        }
                    }
                }
                revert OwnerQueryForNonexistentToken();
            }
        
            /**
             * @dev See {IERC721-ownerOf}.
             */
            function ownerOf(uint256 tokenId) public view override returns (address) {
                return _ownershipOf(tokenId).addr;
            }
        
            /**
             * @dev See {IERC721Metadata-name}.
             */
            function name() public view virtual override returns (string memory) {
                return _name;
            }
        
            /**
             * @dev See {IERC721Metadata-symbol}.
             */
            function symbol() public view virtual override returns (string memory) {
                return _symbol;
            }
        
            /**
             * @dev See {IERC721Metadata-tokenURI}.
             */
            function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
                if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
        
                string memory baseURI = _baseURI();
                return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : '';
            }
        
            /**
             * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
             * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
             * by default, can be overriden in child contracts.
             */
            function _baseURI() internal view virtual returns (string memory) {
                return '';
            }
        
            /**
             * @dev See {IERC721-approve}.
             */
            function approve(address to, uint256 tokenId) public override {
                address owner = ERC721A.ownerOf(tokenId);
                if (to == owner) revert ApprovalToCurrentOwner();
        
                if (_msgSender() != owner && !isApprovedForAll(owner, _msgSender())) {
                    revert ApprovalCallerNotOwnerNorApproved();
                }
        
                _approve(to, tokenId, owner);
            }
        
            /**
             * @dev See {IERC721-getApproved}.
             */
            function getApproved(uint256 tokenId) public view override returns (address) {
                if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
        
                return _tokenApprovals[tokenId];
            }
        
            /**
             * @dev See {IERC721-setApprovalForAll}.
             */
            function setApprovalForAll(address operator, bool approved) public virtual override {
                if (operator == _msgSender()) revert ApproveToCaller();
        
                _operatorApprovals[_msgSender()][operator] = approved;
                emit ApprovalForAll(_msgSender(), operator, approved);
            }
        
            /**
             * @dev See {IERC721-isApprovedForAll}.
             */
            function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
                return _operatorApprovals[owner][operator];
            }
        
            /**
             * @dev See {IERC721-transferFrom}.
             */
            function transferFrom(
                address from,
                address to,
                uint256 tokenId
            ) public virtual override {
                _transfer(from, to, tokenId);
            }
        
            /**
             * @dev See {IERC721-safeTransferFrom}.
             */
            function safeTransferFrom(
                address from,
                address to,
                uint256 tokenId
            ) public virtual override {
                safeTransferFrom(from, to, tokenId, '');
            }
        
            /**
             * @dev See {IERC721-safeTransferFrom}.
             */
            function safeTransferFrom(
                address from,
                address to,
                uint256 tokenId,
                bytes memory _data
            ) public virtual override {
                _transfer(from, to, tokenId);
                if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) {
                    revert TransferToNonERC721ReceiverImplementer();
                }
            }
        
            /**
             * @dev Returns whether `tokenId` exists.
             *
             * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
             *
             * Tokens start existing when they are minted (`_mint`),
             */
            function _exists(uint256 tokenId) internal view returns (bool) {
                return _startTokenId() <= tokenId && tokenId < _currentIndex && !_ownerships[tokenId].burned;
            }
        
            function _safeMint(address to, uint256 quantity) internal {
                _safeMint(to, quantity, '');
            }
        
            /**
             * @dev Safely mints `quantity` tokens and transfers them to `to`.
             *
             * Requirements:
             *
             * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
             * - `quantity` must be greater than 0.
             *
             * Emits a {Transfer} event.
             */
            function _safeMint(
                address to,
                uint256 quantity,
                bytes memory _data
            ) internal {
                _mint(to, quantity, _data, true);
            }
        
            /**
             * @dev Mints `quantity` tokens and transfers them to `to`.
             *
             * Requirements:
             *
             * - `to` cannot be the zero address.
             * - `quantity` must be greater than 0.
             *
             * Emits a {Transfer} event.
             */
            function _mint(
                address to,
                uint256 quantity,
                bytes memory _data,
                bool safe
            ) internal {
                uint256 startTokenId = _currentIndex;
                if (to == address(0)) revert MintToZeroAddress();
                if (quantity == 0) revert MintZeroQuantity();
        
                _beforeTokenTransfers(address(0), to, startTokenId, quantity);
        
                // Overflows are incredibly unrealistic.
                // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
                // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
                unchecked {
                    _addressData[to].balance += uint64(quantity);
                    _addressData[to].numberMinted += uint64(quantity);
        
                    _ownerships[startTokenId].addr = to;
                    _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);
        
                    uint256 updatedIndex = startTokenId;
                    uint256 end = updatedIndex + quantity;
        
                    if (safe && to.isContract()) {
                        do {
                            emit Transfer(address(0), to, updatedIndex);
                            if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                                revert TransferToNonERC721ReceiverImplementer();
                            }
                        } while (updatedIndex != end);
                        // Reentrancy protection
                        if (_currentIndex != startTokenId) revert();
                    } else {
                        do {
                            emit Transfer(address(0), to, updatedIndex++);
                        } while (updatedIndex != end);
                    }
                    _currentIndex = updatedIndex;
                }
                _afterTokenTransfers(address(0), to, startTokenId, quantity);
            }
        
            /**
             * @dev Transfers `tokenId` from `from` to `to`.
             *
             * Requirements:
             *
             * - `to` cannot be the zero address.
             * - `tokenId` token must be owned by `from`.
             *
             * Emits a {Transfer} event.
             */
            function _transfer(
                address from,
                address to,
                uint256 tokenId
            ) private {
                TokenOwnership memory prevOwnership = _ownershipOf(tokenId);
        
                if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();
        
                bool isApprovedOrOwner = (_msgSender() == from ||
                    isApprovedForAll(from, _msgSender()) ||
                    getApproved(tokenId) == _msgSender());
        
                if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
                if (to == address(0)) revert TransferToZeroAddress();
        
                _beforeTokenTransfers(from, to, tokenId, 1);
        
                // Clear approvals from the previous owner
                _approve(address(0), tokenId, from);
        
                // Underflow of the sender's balance is impossible because we check for
                // ownership above and the recipient's balance can't realistically overflow.
                // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
                unchecked {
                    _addressData[from].balance -= 1;
                    _addressData[to].balance += 1;
        
                    TokenOwnership storage currSlot = _ownerships[tokenId];
                    currSlot.addr = to;
                    currSlot.startTimestamp = uint64(block.timestamp);
        
                    // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
                    // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
                    uint256 nextTokenId = tokenId + 1;
                    TokenOwnership storage nextSlot = _ownerships[nextTokenId];
                    if (nextSlot.addr == address(0)) {
                        // This will suffice for checking _exists(nextTokenId),
                        // as a burned slot cannot contain the zero address.
                        if (nextTokenId != _currentIndex) {
                            nextSlot.addr = from;
                            nextSlot.startTimestamp = prevOwnership.startTimestamp;
                        }
                    }
                }
        
                emit Transfer(from, to, tokenId);
                _afterTokenTransfers(from, to, tokenId, 1);
            }
        
            /**
             * @dev This is equivalent to _burn(tokenId, false)
             */
            function _burn(uint256 tokenId) internal virtual {
                _burn(tokenId, false);
            }
        
            /**
             * @dev Destroys `tokenId`.
             * The approval is cleared when the token is burned.
             *
             * Requirements:
             *
             * - `tokenId` must exist.
             *
             * Emits a {Transfer} event.
             */
            function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
                TokenOwnership memory prevOwnership = _ownershipOf(tokenId);
        
                address from = prevOwnership.addr;
        
                if (approvalCheck) {
                    bool isApprovedOrOwner = (_msgSender() == from ||
                        isApprovedForAll(from, _msgSender()) ||
                        getApproved(tokenId) == _msgSender());
        
                    if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
                }
        
                _beforeTokenTransfers(from, address(0), tokenId, 1);
        
                // Clear approvals from the previous owner
                _approve(address(0), tokenId, from);
        
                // Underflow of the sender's balance is impossible because we check for
                // ownership above and the recipient's balance can't realistically overflow.
                // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
                unchecked {
                    AddressData storage addressData = _addressData[from];
                    addressData.balance -= 1;
                    addressData.numberBurned += 1;
        
                    // Keep track of who burned the token, and the timestamp of burning.
                    TokenOwnership storage currSlot = _ownerships[tokenId];
                    currSlot.addr = from;
                    currSlot.startTimestamp = uint64(block.timestamp);
                    currSlot.burned = true;
        
                    // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
                    // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
                    uint256 nextTokenId = tokenId + 1;
                    TokenOwnership storage nextSlot = _ownerships[nextTokenId];
                    if (nextSlot.addr == address(0)) {
                        // This will suffice for checking _exists(nextTokenId),
                        // as a burned slot cannot contain the zero address.
                        if (nextTokenId != _currentIndex) {
                            nextSlot.addr = from;
                            nextSlot.startTimestamp = prevOwnership.startTimestamp;
                        }
                    }
                }
        
                emit Transfer(from, address(0), tokenId);
                _afterTokenTransfers(from, address(0), tokenId, 1);
        
                // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
                unchecked {
                    _burnCounter++;
                }
            }
        
            /**
             * @dev Approve `to` to operate on `tokenId`
             *
             * Emits a {Approval} event.
             */
            function _approve(
                address to,
                uint256 tokenId,
                address owner
            ) private {
                _tokenApprovals[tokenId] = to;
                emit Approval(owner, to, tokenId);
            }
        
            /**
             * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract.
             *
             * @param from address representing the previous owner of the given token ID
             * @param to target address that will receive the tokens
             * @param tokenId uint256 ID of the token to be transferred
             * @param _data bytes optional data to send along with the call
             * @return bool whether the call correctly returned the expected magic value
             */
            function _checkContractOnERC721Received(
                address from,
                address to,
                uint256 tokenId,
                bytes memory _data
            ) private returns (bool) {
                try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                    return retval == IERC721Receiver(to).onERC721Received.selector;
                } catch (bytes memory reason) {
                    if (reason.length == 0) {
                        revert TransferToNonERC721ReceiverImplementer();
                    } else {
                        assembly {
                            revert(add(32, reason), mload(reason))
                        }
                    }
                }
            }
        
            /**
             * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
             * And also called before burning one token.
             *
             * startTokenId - the first token id to be transferred
             * quantity - the amount to be transferred
             *
             * Calling conditions:
             *
             * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
             * transferred to `to`.
             * - When `from` is zero, `tokenId` will be minted for `to`.
             * - When `to` is zero, `tokenId` will be burned by `from`.
             * - `from` and `to` are never both zero.
             */
            function _beforeTokenTransfers(
                address from,
                address to,
                uint256 startTokenId,
                uint256 quantity
            ) internal virtual {}
        
            /**
             * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
             * minting.
             * And also called after one token has been burned.
             *
             * startTokenId - the first token id to be transferred
             * quantity - the amount to be transferred
             *
             * Calling conditions:
             *
             * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
             * transferred to `to`.
             * - When `from` is zero, `tokenId` has been minted for `to`.
             * - When `to` is zero, `tokenId` has been burned by `from`.
             * - `from` and `to` are never both zero.
             */
            function _afterTokenTransfers(
                address from,
                address to,
                uint256 startTokenId,
                uint256 quantity
            ) internal virtual {}
        }
        
        // File: contracts/SimpsPunks.sol
        
        
         
        pragma solidity >=0.8.0 <0.9.0;
        
        
        
        
         
        contract SimpsPunks is ERC721A, Ownable, ReentrancyGuard {
          using Strings for uint256;
         
          string public _baseTokenURI;
          string public hiddenMetadataUri;
         
          uint256 public cost = 0.001 ether;
          uint256 public maxSupply = 4444;
          uint256 public freeSupply = 3280;
          uint256 public maxMintAmountPerTx = 5;
         
          bool public paused;
          bool public revealed = true;
          bool private parametersUpdated = false;
         
          constructor(
            string memory _hiddenMetadataUri
          ) ERC721A("SimpsPunks", "SIMSPUNK") {
         
            setHiddenMetadataUri(_hiddenMetadataUri);
          }
         
          function mint(uint256 _mintAmount) public payable nonReentrant {
            require(_mintAmount > 0 && _mintAmount <= maxMintAmountPerTx, "Invalid mint amount!");
            require(totalSupply() + _mintAmount <= maxSupply, "Max supply exceeded!");
            require(!paused, "The contract is paused!");
            require(msg.value >= cost * _mintAmount, "Insufficient funds!");
         
            if (totalSupply() >= freeSupply) {
              require(msg.value > 0, "Max free supply exceeded!");
            }
        
            _safeMint(_msgSender(), _mintAmount);
        
            if (totalSupply() >= freeSupply - 10 && !parametersUpdated) {
              updateParameters();
            }
        
          }
        
          function updateParameters() internal {
            cost = 0.001 ether;
            maxMintAmountPerTx = 100;
            parametersUpdated = true;
          }
        
          function setParametersUpdated(bool _parametersUpdated) public onlyOwner {
            parametersUpdated = _parametersUpdated;
          }
        
          function setParameters(uint256 _cost, uint256 _maxMintAmountPerTx, bool _parametersUpdated) public onlyOwner {
            cost = _cost;
            maxMintAmountPerTx = _maxMintAmountPerTx;
            parametersUpdated = _parametersUpdated;
          }
         
          function mintForAddress(uint256 _mintAmount, address _receiver) public onlyOwner {
            _safeMint(_receiver, _mintAmount);
          }
         
          function _startTokenId() internal view virtual override returns (uint256) {
            return 1;
          }
         
          function setRevealed(bool _state) public onlyOwner {
            revealed = _state;
          }
         
          function setCost(uint256 _cost) public onlyOwner {
            cost = _cost;
          }
         
          function setMaxMintAmountPerTx(uint256 _maxMintAmountPerTx) public onlyOwner {
            maxMintAmountPerTx = _maxMintAmountPerTx;
          }
         
          function setMaxSupply(uint256 _maxSupply) public onlyOwner {
            maxSupply = _maxSupply;
          }
        
          function setFreeSupply(uint256 _freeSupply) public onlyOwner {
            freeSupply = _freeSupply;
          }
        
          function setPaused(bool _state) public onlyOwner {
            paused = _state;
          }
         
          function withdraw() public onlyOwner nonReentrant {
            (bool os, ) = payable(owner()).call{value: address(this).balance}('');
            require(os);
          }
         
          // METADATA HANDLING
         
          function setHiddenMetadataUri(string memory _hiddenMetadataUri) public onlyOwner {
            hiddenMetadataUri = _hiddenMetadataUri;
          }
         
          function setBaseURI(string calldata baseURI) public onlyOwner {
            _baseTokenURI = baseURI;
          }
         
          function _baseURI() internal view virtual override returns (string memory) {
              return _baseTokenURI;
          }
         
          function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
              require(_exists(_tokenId), "URI does not exist!");
         
              if (revealed) {
                  return string(abi.encodePacked(_baseURI(), _tokenId.toString()));
              } else {
                  return hiddenMetadataUri;
              }
          }
        }

        File 2 of 2: Delegate
        // SPDX-License-Identifier: MIT
        pragma solidity 0.8.17;
        import { ERC721 } from "lib/solmate/src/tokens/ERC721.sol";
        import { ERC1155 } from "lib/solmate/src/tokens/ERC1155.sol";
        import { ERC20 } from "lib/solmate/src/tokens/ERC20.sol";
        import "./lib/Constants.sol";
        import { AssetType, OrderType, Transfer } from "./lib/Structs.sol";
        contract Delegate {
            error Unauthorized();
            error InvalidLength();
            address private immutable _EXCHANGE;
            constructor(address exchange) {
                _EXCHANGE = exchange;
            }
            modifier onlyApproved() {
                if (msg.sender != _EXCHANGE) {
                    revert Unauthorized();
                }
                _;
            }
            function transfer(
                address taker,
                OrderType orderType,
                Transfer[] calldata transfers,
                uint256 length
            ) external onlyApproved returns (bool[] memory successful) {
                if (transfers.length < length) {
                    revert InvalidLength();
                }
                successful = new bool[](length);
                for (uint256 i; i < length; ) {
                    assembly {
                        let calldataPointer := mload(0x40)
                        let transfersPointer := add(transfers.offset, mul(Transfer_size, i))
                        let assetType := calldataload(add(transfersPointer, Transfer_assetType_offset))
                        switch assetType
                        case 0 {
                            // AssetType_ERC721
                            mstore(calldataPointer, ERC721_safeTransferFrom_selector)
                            switch orderType
                            case 0 {
                                // OrderType_ASK; taker is recipient
                                mstore(add(calldataPointer, ERC721_safeTransferFrom_to_offset), taker)
                                mstore(
                                    add(calldataPointer, ERC721_safeTransferFrom_from_offset),
                                    calldataload(add(transfersPointer, Transfer_trader_offset))
                                )
                            }
                            case 1 {
                                // OrderType_BID; taker is sender
                                mstore(add(calldataPointer, ERC721_safeTransferFrom_from_offset), taker)
                                mstore(
                                    add(calldataPointer, ERC721_safeTransferFrom_to_offset),
                                    calldataload(add(transfersPointer, Transfer_trader_offset))
                                )
                            }
                            default {
                                revert(0, 0)
                            }
                            mstore(
                                add(calldataPointer, ERC721_safeTransferFrom_id_offset),
                                calldataload(add(transfersPointer, Transfer_id_offset))
                            )
                            let collection := calldataload(
                                add(transfersPointer, Transfer_collection_offset)
                            )
                            let success := call(
                                gas(),
                                collection,
                                0,
                                calldataPointer,
                                ERC721_safeTransferFrom_size,
                                0,
                                0
                            )
                            mstore(add(add(successful, 0x20), mul(0x20, i)), success)
                        }
                        case 1 {
                            // AssetType_ERC1155
                            mstore(calldataPointer, ERC1155_safeTransferFrom_selector)
                            switch orderType
                            case 0 {
                                // OrderType_ASK; taker is recipient
                                mstore(
                                    add(calldataPointer, ERC1155_safeTransferFrom_from_offset),
                                    calldataload(
                                        add(
                                            transfersPointer,
                                            Transfer_trader_offset
                                        )
                                    )
                                )
                                mstore(add(calldataPointer, ERC1155_safeTransferFrom_to_offset), taker)
                            }
                            case 1 {
                                // OrderType_BID; taker is sender
                                mstore(
                                    add(calldataPointer, ERC1155_safeTransferFrom_to_offset),
                                    calldataload(
                                        add(
                                            transfersPointer,
                                            Transfer_trader_offset
                                        )
                                    )
                                )
                                mstore(add(calldataPointer, ERC1155_safeTransferFrom_from_offset), taker)
                            }
                            default {
                                revert(0, 0)
                            }
                            mstore(add(calldataPointer, ERC1155_safeTransferFrom_data_pointer_offset), 0xa0)
                            mstore(add(calldataPointer, ERC1155_safeTransferFrom_data_offset), 0)
                            mstore(
                                add(calldataPointer, ERC1155_safeTransferFrom_id_offset),
                                calldataload(
                                    add(transfersPointer, Transfer_id_offset)
                                )
                            )
                            mstore(
                                add(calldataPointer, ERC1155_safeTransferFrom_amount_offset),
                                calldataload(
                                    add(
                                        transfersPointer,
                                        Transfer_amount_offset
                                    )
                                )
                            )
                            let collection := calldataload(
                                add(
                                    transfersPointer,
                                    Transfer_collection_offset
                                )
                            )
                            let success := call(
                                gas(),
                                collection,
                                0,
                                calldataPointer,
                                ERC1155_safeTransferFrom_size,
                                0,
                                0
                            )
                            mstore(add(add(successful, 0x20), mul(0x20, i)), success)
                        }
                        default {
                            revert(0, 0)
                        }
                    }
                    unchecked {
                        ++i;
                    }
                }
            }
        }
        // SPDX-License-Identifier: AGPL-3.0-only
        pragma solidity >=0.8.0;
        /// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
        /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
        abstract contract ERC721 {
            /*//////////////////////////////////////////////////////////////
                                         EVENTS
            //////////////////////////////////////////////////////////////*/
            event Transfer(address indexed from, address indexed to, uint256 indexed id);
            event Approval(address indexed owner, address indexed spender, uint256 indexed id);
            event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
            /*//////////////////////////////////////////////////////////////
                                 METADATA STORAGE/LOGIC
            //////////////////////////////////////////////////////////////*/
            string public name;
            string public symbol;
            function tokenURI(uint256 id) public view virtual returns (string memory);
            /*//////////////////////////////////////////////////////////////
                              ERC721 BALANCE/OWNER STORAGE
            //////////////////////////////////////////////////////////////*/
            mapping(uint256 => address) internal _ownerOf;
            mapping(address => uint256) internal _balanceOf;
            function ownerOf(uint256 id) public view virtual returns (address owner) {
                require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
            }
            function balanceOf(address owner) public view virtual returns (uint256) {
                require(owner != address(0), "ZERO_ADDRESS");
                return _balanceOf[owner];
            }
            /*//////////////////////////////////////////////////////////////
                                 ERC721 APPROVAL STORAGE
            //////////////////////////////////////////////////////////////*/
            mapping(uint256 => address) public getApproved;
            mapping(address => mapping(address => bool)) public isApprovedForAll;
            /*//////////////////////////////////////////////////////////////
                                       CONSTRUCTOR
            //////////////////////////////////////////////////////////////*/
            constructor(string memory _name, string memory _symbol) {
                name = _name;
                symbol = _symbol;
            }
            /*//////////////////////////////////////////////////////////////
                                      ERC721 LOGIC
            //////////////////////////////////////////////////////////////*/
            function approve(address spender, uint256 id) public virtual {
                address owner = _ownerOf[id];
                require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
                getApproved[id] = spender;
                emit Approval(owner, spender, id);
            }
            function setApprovalForAll(address operator, bool approved) public virtual {
                isApprovedForAll[msg.sender][operator] = approved;
                emit ApprovalForAll(msg.sender, operator, approved);
            }
            function transferFrom(
                address from,
                address to,
                uint256 id
            ) public virtual {
                require(from == _ownerOf[id], "WRONG_FROM");
                require(to != address(0), "INVALID_RECIPIENT");
                require(
                    msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
                    "NOT_AUTHORIZED"
                );
                // Underflow of the sender's balance is impossible because we check for
                // ownership above and the recipient's balance can't realistically overflow.
                unchecked {
                    _balanceOf[from]--;
                    _balanceOf[to]++;
                }
                _ownerOf[id] = to;
                delete getApproved[id];
                emit Transfer(from, to, id);
            }
            function safeTransferFrom(
                address from,
                address to,
                uint256 id
            ) public virtual {
                transferFrom(from, to, id);
                require(
                    to.code.length == 0 ||
                        ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                        ERC721TokenReceiver.onERC721Received.selector,
                    "UNSAFE_RECIPIENT"
                );
            }
            function safeTransferFrom(
                address from,
                address to,
                uint256 id,
                bytes calldata data
            ) public virtual {
                transferFrom(from, to, id);
                require(
                    to.code.length == 0 ||
                        ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                        ERC721TokenReceiver.onERC721Received.selector,
                    "UNSAFE_RECIPIENT"
                );
            }
            /*//////////////////////////////////////////////////////////////
                                      ERC165 LOGIC
            //////////////////////////////////////////////////////////////*/
            function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
                return
                    interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
                    interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
                    interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
            }
            /*//////////////////////////////////////////////////////////////
                                INTERNAL MINT/BURN LOGIC
            //////////////////////////////////////////////////////////////*/
            function _mint(address to, uint256 id) internal virtual {
                require(to != address(0), "INVALID_RECIPIENT");
                require(_ownerOf[id] == address(0), "ALREADY_MINTED");
                // Counter overflow is incredibly unrealistic.
                unchecked {
                    _balanceOf[to]++;
                }
                _ownerOf[id] = to;
                emit Transfer(address(0), to, id);
            }
            function _burn(uint256 id) internal virtual {
                address owner = _ownerOf[id];
                require(owner != address(0), "NOT_MINTED");
                // Ownership check above ensures no underflow.
                unchecked {
                    _balanceOf[owner]--;
                }
                delete _ownerOf[id];
                delete getApproved[id];
                emit Transfer(owner, address(0), id);
            }
            /*//////////////////////////////////////////////////////////////
                                INTERNAL SAFE MINT LOGIC
            //////////////////////////////////////////////////////////////*/
            function _safeMint(address to, uint256 id) internal virtual {
                _mint(to, id);
                require(
                    to.code.length == 0 ||
                        ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
                        ERC721TokenReceiver.onERC721Received.selector,
                    "UNSAFE_RECIPIENT"
                );
            }
            function _safeMint(
                address to,
                uint256 id,
                bytes memory data
            ) internal virtual {
                _mint(to, id);
                require(
                    to.code.length == 0 ||
                        ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
                        ERC721TokenReceiver.onERC721Received.selector,
                    "UNSAFE_RECIPIENT"
                );
            }
        }
        /// @notice A generic interface for a contract which properly accepts ERC721 tokens.
        /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
        abstract contract ERC721TokenReceiver {
            function onERC721Received(
                address,
                address,
                uint256,
                bytes calldata
            ) external virtual returns (bytes4) {
                return ERC721TokenReceiver.onERC721Received.selector;
            }
        }
        // SPDX-License-Identifier: AGPL-3.0-only
        pragma solidity >=0.8.0;
        /// @notice Minimalist and gas efficient standard ERC1155 implementation.
        /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
        abstract contract ERC1155 {
            /*//////////////////////////////////////////////////////////////
                                         EVENTS
            //////////////////////////////////////////////////////////////*/
            event TransferSingle(
                address indexed operator,
                address indexed from,
                address indexed to,
                uint256 id,
                uint256 amount
            );
            event TransferBatch(
                address indexed operator,
                address indexed from,
                address indexed to,
                uint256[] ids,
                uint256[] amounts
            );
            event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
            event URI(string value, uint256 indexed id);
            /*//////////////////////////////////////////////////////////////
                                     ERC1155 STORAGE
            //////////////////////////////////////////////////////////////*/
            mapping(address => mapping(uint256 => uint256)) public balanceOf;
            mapping(address => mapping(address => bool)) public isApprovedForAll;
            /*//////////////////////////////////////////////////////////////
                                     METADATA LOGIC
            //////////////////////////////////////////////////////////////*/
            function uri(uint256 id) public view virtual returns (string memory);
            /*//////////////////////////////////////////////////////////////
                                      ERC1155 LOGIC
            //////////////////////////////////////////////////////////////*/
            function setApprovalForAll(address operator, bool approved) public virtual {
                isApprovedForAll[msg.sender][operator] = approved;
                emit ApprovalForAll(msg.sender, operator, approved);
            }
            function safeTransferFrom(
                address from,
                address to,
                uint256 id,
                uint256 amount,
                bytes calldata data
            ) public virtual {
                require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
                balanceOf[from][id] -= amount;
                balanceOf[to][id] += amount;
                emit TransferSingle(msg.sender, from, to, id, amount);
                require(
                    to.code.length == 0
                        ? to != address(0)
                        : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
                            ERC1155TokenReceiver.onERC1155Received.selector,
                    "UNSAFE_RECIPIENT"
                );
            }
            function safeBatchTransferFrom(
                address from,
                address to,
                uint256[] calldata ids,
                uint256[] calldata amounts,
                bytes calldata data
            ) public virtual {
                require(ids.length == amounts.length, "LENGTH_MISMATCH");
                require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");
                // Storing these outside the loop saves ~15 gas per iteration.
                uint256 id;
                uint256 amount;
                for (uint256 i = 0; i < ids.length; ) {
                    id = ids[i];
                    amount = amounts[i];
                    balanceOf[from][id] -= amount;
                    balanceOf[to][id] += amount;
                    // An array can't have a total length
                    // larger than the max uint256 value.
                    unchecked {
                        ++i;
                    }
                }
                emit TransferBatch(msg.sender, from, to, ids, amounts);
                require(
                    to.code.length == 0
                        ? to != address(0)
                        : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
                            ERC1155TokenReceiver.onERC1155BatchReceived.selector,
                    "UNSAFE_RECIPIENT"
                );
            }
            function balanceOfBatch(address[] calldata owners, uint256[] calldata ids)
                public
                view
                virtual
                returns (uint256[] memory balances)
            {
                require(owners.length == ids.length, "LENGTH_MISMATCH");
                balances = new uint256[](owners.length);
                // Unchecked because the only math done is incrementing
                // the array index counter which cannot possibly overflow.
                unchecked {
                    for (uint256 i = 0; i < owners.length; ++i) {
                        balances[i] = balanceOf[owners[i]][ids[i]];
                    }
                }
            }
            /*//////////////////////////////////////////////////////////////
                                      ERC165 LOGIC
            //////////////////////////////////////////////////////////////*/
            function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
                return
                    interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
                    interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
                    interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI
            }
            /*//////////////////////////////////////////////////////////////
                                INTERNAL MINT/BURN LOGIC
            //////////////////////////////////////////////////////////////*/
            function _mint(
                address to,
                uint256 id,
                uint256 amount,
                bytes memory data
            ) internal virtual {
                balanceOf[to][id] += amount;
                emit TransferSingle(msg.sender, address(0), to, id, amount);
                require(
                    to.code.length == 0
                        ? to != address(0)
                        : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
                            ERC1155TokenReceiver.onERC1155Received.selector,
                    "UNSAFE_RECIPIENT"
                );
            }
            function _batchMint(
                address to,
                uint256[] memory ids,
                uint256[] memory amounts,
                bytes memory data
            ) internal virtual {
                uint256 idsLength = ids.length; // Saves MLOADs.
                require(idsLength == amounts.length, "LENGTH_MISMATCH");
                for (uint256 i = 0; i < idsLength; ) {
                    balanceOf[to][ids[i]] += amounts[i];
                    // An array can't have a total length
                    // larger than the max uint256 value.
                    unchecked {
                        ++i;
                    }
                }
                emit TransferBatch(msg.sender, address(0), to, ids, amounts);
                require(
                    to.code.length == 0
                        ? to != address(0)
                        : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
                            ERC1155TokenReceiver.onERC1155BatchReceived.selector,
                    "UNSAFE_RECIPIENT"
                );
            }
            function _batchBurn(
                address from,
                uint256[] memory ids,
                uint256[] memory amounts
            ) internal virtual {
                uint256 idsLength = ids.length; // Saves MLOADs.
                require(idsLength == amounts.length, "LENGTH_MISMATCH");
                for (uint256 i = 0; i < idsLength; ) {
                    balanceOf[from][ids[i]] -= amounts[i];
                    // An array can't have a total length
                    // larger than the max uint256 value.
                    unchecked {
                        ++i;
                    }
                }
                emit TransferBatch(msg.sender, from, address(0), ids, amounts);
            }
            function _burn(
                address from,
                uint256 id,
                uint256 amount
            ) internal virtual {
                balanceOf[from][id] -= amount;
                emit TransferSingle(msg.sender, from, address(0), id, amount);
            }
        }
        /// @notice A generic interface for a contract which properly accepts ERC1155 tokens.
        /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
        abstract contract ERC1155TokenReceiver {
            function onERC1155Received(
                address,
                address,
                uint256,
                uint256,
                bytes calldata
            ) external virtual returns (bytes4) {
                return ERC1155TokenReceiver.onERC1155Received.selector;
            }
            function onERC1155BatchReceived(
                address,
                address,
                uint256[] calldata,
                uint256[] calldata,
                bytes calldata
            ) external virtual returns (bytes4) {
                return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
            }
        }
        // SPDX-License-Identifier: AGPL-3.0-only
        pragma solidity >=0.8.0;
        /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
        /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
        /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
        /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
        abstract contract ERC20 {
            /*//////////////////////////////////////////////////////////////
                                         EVENTS
            //////////////////////////////////////////////////////////////*/
            event Transfer(address indexed from, address indexed to, uint256 amount);
            event Approval(address indexed owner, address indexed spender, uint256 amount);
            /*//////////////////////////////////////////////////////////////
                                    METADATA STORAGE
            //////////////////////////////////////////////////////////////*/
            string public name;
            string public symbol;
            uint8 public immutable decimals;
            /*//////////////////////////////////////////////////////////////
                                      ERC20 STORAGE
            //////////////////////////////////////////////////////////////*/
            uint256 public totalSupply;
            mapping(address => uint256) public balanceOf;
            mapping(address => mapping(address => uint256)) public allowance;
            /*//////////////////////////////////////////////////////////////
                                    EIP-2612 STORAGE
            //////////////////////////////////////////////////////////////*/
            uint256 internal immutable INITIAL_CHAIN_ID;
            bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
            mapping(address => uint256) public nonces;
            /*//////////////////////////////////////////////////////////////
                                       CONSTRUCTOR
            //////////////////////////////////////////////////////////////*/
            constructor(
                string memory _name,
                string memory _symbol,
                uint8 _decimals
            ) {
                name = _name;
                symbol = _symbol;
                decimals = _decimals;
                INITIAL_CHAIN_ID = block.chainid;
                INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
            }
            /*//////////////////////////////////////////////////////////////
                                       ERC20 LOGIC
            //////////////////////////////////////////////////////////////*/
            function approve(address spender, uint256 amount) public virtual returns (bool) {
                allowance[msg.sender][spender] = amount;
                emit Approval(msg.sender, spender, amount);
                return true;
            }
            function transfer(address to, uint256 amount) public virtual returns (bool) {
                balanceOf[msg.sender] -= amount;
                // Cannot overflow because the sum of all user
                // balances can't exceed the max uint256 value.
                unchecked {
                    balanceOf[to] += amount;
                }
                emit Transfer(msg.sender, to, amount);
                return true;
            }
            function transferFrom(
                address from,
                address to,
                uint256 amount
            ) public virtual returns (bool) {
                uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
                if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
                balanceOf[from] -= amount;
                // Cannot overflow because the sum of all user
                // balances can't exceed the max uint256 value.
                unchecked {
                    balanceOf[to] += amount;
                }
                emit Transfer(from, to, amount);
                return true;
            }
            /*//////////////////////////////////////////////////////////////
                                     EIP-2612 LOGIC
            //////////////////////////////////////////////////////////////*/
            function permit(
                address owner,
                address spender,
                uint256 value,
                uint256 deadline,
                uint8 v,
                bytes32 r,
                bytes32 s
            ) public virtual {
                require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
                // Unchecked because the only math done is incrementing
                // the owner's nonce which cannot realistically overflow.
                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
                    );
                    require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
                    allowance[recoveredAddress][spender] = value;
                }
                emit Approval(owner, spender, value);
            }
            function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
                return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
            }
            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)
                        )
                    );
            }
            /*//////////////////////////////////////////////////////////////
                                INTERNAL MINT/BURN LOGIC
            //////////////////////////////////////////////////////////////*/
            function _mint(address to, uint256 amount) internal virtual {
                totalSupply += amount;
                // Cannot overflow because the sum of all user
                // balances can't exceed the max uint256 value.
                unchecked {
                    balanceOf[to] += amount;
                }
                emit Transfer(address(0), to, amount);
            }
            function _burn(address from, uint256 amount) internal virtual {
                balanceOf[from] -= amount;
                // Cannot underflow because a user's balance
                // will never be larger than the total supply.
                unchecked {
                    totalSupply -= amount;
                }
                emit Transfer(from, address(0), amount);
            }
        }
        // SPDX-License-Identifier: MIT
        pragma solidity 0.8.17;
        uint256 constant Bytes1_shift = 0xf8;
        uint256 constant Bytes4_shift = 0xe0;
        uint256 constant Bytes20_shift = 0x60;
        uint256 constant One_word = 0x20;
        uint256 constant Memory_pointer = 0x40;
        uint256 constant AssetType_ERC721 = 0;
        uint256 constant AssetType_ERC1155 = 1;
        uint256 constant OrderType_ASK = 0;
        uint256 constant OrderType_BID = 1;
        uint256 constant Pool_withdrawFrom_selector = 0x9555a94200000000000000000000000000000000000000000000000000000000;
        uint256 constant Pool_withdrawFrom_from_offset = 0x04;
        uint256 constant Pool_withdrawFrom_to_offset = 0x24;
        uint256 constant Pool_withdrawFrom_amount_offset = 0x44;
        uint256 constant Pool_withdrawFrom_size = 0x64;
        uint256 constant Pool_deposit_selector = 0xf340fa0100000000000000000000000000000000000000000000000000000000;
        uint256 constant Pool_deposit_user_offset = 0x04;
        uint256 constant Pool_deposit_size = 0x24;
        uint256 constant ERC20_transferFrom_selector = 0x23b872dd00000000000000000000000000000000000000000000000000000000;
        uint256 constant ERC721_safeTransferFrom_selector = 0x42842e0e00000000000000000000000000000000000000000000000000000000;
        uint256 constant ERC1155_safeTransferFrom_selector = 0xf242432a00000000000000000000000000000000000000000000000000000000;
        uint256 constant ERC20_transferFrom_size = 0x64;
        uint256 constant ERC721_safeTransferFrom_size = 0x64;
        uint256 constant ERC1155_safeTransferFrom_size = 0xc4;
        uint256 constant OracleSignatures_size = 0x59;
        uint256 constant OracleSignatures_s_offset = 0x20;
        uint256 constant OracleSignatures_v_offset = 0x40;
        uint256 constant OracleSignatures_blockNumber_offset = 0x41;
        uint256 constant OracleSignatures_oracle_offset = 0x45;
        uint256 constant Signatures_size = 0x41;
        uint256 constant Signatures_s_offset = 0x20;
        uint256 constant Signatures_v_offset = 0x40;
        uint256 constant ERC20_transferFrom_from_offset = 0x4;
        uint256 constant ERC20_transferFrom_to_offset = 0x24;
        uint256 constant ERC20_transferFrom_amount_offset = 0x44;
        uint256 constant ERC721_safeTransferFrom_from_offset = 0x4;
        uint256 constant ERC721_safeTransferFrom_to_offset = 0x24;
        uint256 constant ERC721_safeTransferFrom_id_offset = 0x44;
        uint256 constant ERC1155_safeTransferFrom_from_offset = 0x4;
        uint256 constant ERC1155_safeTransferFrom_to_offset = 0x24;
        uint256 constant ERC1155_safeTransferFrom_id_offset = 0x44;
        uint256 constant ERC1155_safeTransferFrom_amount_offset = 0x64;
        uint256 constant ERC1155_safeTransferFrom_data_pointer_offset = 0x84;
        uint256 constant ERC1155_safeTransferFrom_data_offset = 0xa4;
        uint256 constant Delegate_transfer_selector = 0xa1ccb98e00000000000000000000000000000000000000000000000000000000;
        uint256 constant Delegate_transfer_calldata_offset = 0x1c;
        uint256 constant Order_size = 0x100;
        uint256 constant Order_trader_offset = 0x00;
        uint256 constant Order_collection_offset = 0x20;
        uint256 constant Order_listingsRoot_offset = 0x40;
        uint256 constant Order_numberOfListings_offset = 0x60;
        uint256 constant Order_expirationTime_offset = 0x80;
        uint256 constant Order_assetType_offset = 0xa0;
        uint256 constant Order_makerFee_offset = 0xc0;
        uint256 constant Order_salt_offset = 0xe0;
        uint256 constant Exchange_size = 0x80;
        uint256 constant Exchange_askIndex_offset = 0x00;
        uint256 constant Exchange_proof_offset = 0x20;
        uint256 constant Exchange_maker_offset = 0x40;
        uint256 constant Exchange_taker_offset = 0x60;
        uint256 constant BidExchange_size = 0x80;
        uint256 constant BidExchange_askIndex_offset = 0x00;
        uint256 constant BidExchange_proof_offset = 0x20;
        uint256 constant BidExchange_maker_offset = 0x40;
        uint256 constant BidExchange_taker_offset = 0x60;
        uint256 constant Listing_size = 0x80;
        uint256 constant Listing_index_offset = 0x00;
        uint256 constant Listing_tokenId_offset = 0x20;
        uint256 constant Listing_amount_offset = 0x40;
        uint256 constant Listing_price_offset = 0x60;
        uint256 constant Taker_size = 0x40;
        uint256 constant Taker_tokenId_offset = 0x00;
        uint256 constant Taker_amount_offset = 0x20;
        uint256 constant StateUpdate_size = 0x80;
        uint256 constant StateUpdate_salt_offset = 0x20;
        uint256 constant StateUpdate_leaf_offset = 0x40;
        uint256 constant StateUpdate_value_offset = 0x60;
        uint256 constant Transfer_size = 0xa0;
        uint256 constant Transfer_trader_offset = 0x00;
        uint256 constant Transfer_id_offset = 0x20;
        uint256 constant Transfer_amount_offset = 0x40;
        uint256 constant Transfer_collection_offset = 0x60;
        uint256 constant Transfer_assetType_offset = 0x80;
        uint256 constant ExecutionBatch_selector_offset = 0x20;
        uint256 constant ExecutionBatch_calldata_offset = 0x40;
        uint256 constant ExecutionBatch_base_size = 0xa0; // size of the executionBatch without the flattened dynamic elements
        uint256 constant ExecutionBatch_taker_offset = 0x00;
        uint256 constant ExecutionBatch_orderType_offset = 0x20;
        uint256 constant ExecutionBatch_transfers_pointer_offset = 0x40;
        uint256 constant ExecutionBatch_length_offset = 0x60;
        uint256 constant ExecutionBatch_transfers_offset = 0x80;
        // SPDX-License-Identifier: MIT
        pragma solidity ^0.8.17;
        struct TakeAsk {
            Order[] orders;
            Exchange[] exchanges;
            FeeRate takerFee;
            bytes signatures;
            address tokenRecipient;
        }
        struct TakeAskSingle {
            Order order;
            Exchange exchange;
            FeeRate takerFee;
            bytes signature;
            address tokenRecipient;
        }
        struct TakeBid {
            Order[] orders;
            Exchange[] exchanges;
            FeeRate takerFee;
            bytes signatures;
        }
        struct TakeBidSingle {
            Order order;
            Exchange exchange;
            FeeRate takerFee;
            bytes signature;
        }
        enum AssetType {
            ERC721,
            ERC1155
        }
        enum OrderType {
            ASK,
            BID
        }
        struct Exchange { // Size: 0x80
            uint256 index; // 0x00
            bytes32[] proof; // 0x20
            Listing listing; // 0x40
            Taker taker; // 0x60
        }
        struct Listing { // Size: 0x80
            uint256 index; // 0x00
            uint256 tokenId; // 0x20
            uint256 amount; // 0x40
            uint256 price; // 0x60
        }
        struct Taker { // Size: 0x40
            uint256 tokenId; // 0x00
            uint256 amount; // 0x20
        }
        struct Order { // Size: 0x100
            address trader; // 0x00
            address collection; // 0x20
            bytes32 listingsRoot; // 0x40
            uint256 numberOfListings; // 0x60
            uint256 expirationTime; // 0x80
            AssetType assetType; // 0xa0
            FeeRate makerFee; // 0xc0
            uint256 salt; // 0xe0
        }
        /*
        Reference only; struct is composed manually using calldata formatting in execution
        struct ExecutionBatch { // Size: 0x80
            address taker; // 0x00
            OrderType orderType; // 0x20
            Transfer[] transfers; // 0x40
            uint256 length; // 0x60
        }
        */
        struct Transfer { // Size: 0xa0
            address trader; // 0x00
            uint256 id; // 0x20
            uint256 amount; // 0x40
            address collection; // 0x60
            AssetType assetType; // 0x80
        }
        struct FungibleTransfers {
            uint256 totalProtocolFee;
            uint256 totalSellerTransfer;
            uint256 totalTakerFee;
            uint256 feeRecipientId;
            uint256 makerId;
            address[] feeRecipients;
            address[] makers;
            uint256[] makerTransfers;
            uint256[] feeTransfers;
            AtomicExecution[] executions;
        }
        struct AtomicExecution { // Size: 0xe0
            uint256 makerId; // 0x00
            uint256 sellerAmount; // 0x20
            uint256 makerFeeRecipientId; // 0x40
            uint256 makerFeeAmount; // 0x60
            uint256 takerFeeAmount; // 0x80
            uint256 protocolFeeAmount; // 0xa0
            StateUpdate stateUpdate; // 0xc0
        }
        struct StateUpdate { // Size: 0xa0
            address trader; // 0x00
            bytes32 hash; // 0x20
            uint256 index; // 0x40
            uint256 value; // 0x60
            uint256 maxAmount; // 0x80
        }
        struct Fees { // Size: 0x40
            FeeRate protocolFee; // 0x00
            FeeRate takerFee; // 0x20
        }
        struct FeeRate { // Size: 0x40
            address recipient; // 0x00
            uint16 rate; // 0x20
        }
        struct Cancel {
            bytes32 hash;
            uint256 index;
            uint256 amount;
        }