creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/modules/Storage.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.20;\n\nimport {Kernel, Module, Keycode} from \"@src/Kernel.sol\";\nimport {Proxiable} from \"@src/proxy/Proxiable.sol\";\nimport {RentalUtils} from \"@src/libraries/RentalUtils.sol\";\nimport {RentalId, RentalAssetUpdate} from \"@src/libraries/RentalStructs.sol\";\nimport {Errors} from \"@src/libraries/Errors.sol\";\n\n/**\n * @title StorageBase\n * @notice Storage exists in its own base contract to avoid storage slot mismatch during upgrades.\n */\ncontract StorageBase {\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                Rental Storage                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    // Points an order hash to whether it is active.\n    mapping(bytes32 orderHash => bool isActive) public orders;\n\n    // Points an item ID to its number of actively rented tokens. This is used to\n    // determine if an item is actively rented within the protocol. For ERC721, this\n    // value will always be 1 when actively rented. Any inactive rentals will have a\n    // value of 0.\n    mapping(RentalId itemId => uint256 amount) public rentedAssets;\n\n    // Maximum rent duration.\n    uint256 public maxRentDuration;\n\n    // Maximum offer items for a single order.\n    uint256 public maxOfferItems;\n\n    // Maximum consideration items for a single order.\n    uint256 public maxConsiderationItems;\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            Deployed Safe Storage                            //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    // Records all safes that have been deployed by the protocol.\n    mapping(address safe => uint256 nonce) public deployedSafes;\n\n    // Records the total amount of deployed safes.\n    uint256 public totalSafes;\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                 Hook Storage                                //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    // When interacting with the guard, any contracts that have hooks enabled\n    // should have the guard logic routed through them.\n    mapping(address to => address hook) internal _contractToHook;\n\n    // Mapping of a bitmap which denotes the hook functions that are enabled.\n    mapping(address hook => uint8 enabled) public hookStatus;\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            Whitelist Storage                                //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    // Allows the safe to delegate call to an approved address. For example, delegate\n    // call to a contract that would swap out an old gnosis safe module for a new one.\n    mapping(address delegate => bool isWhitelisted) public whitelistedDelegates;\n\n    // Allows for the safe registration of extensions that can be enabled on a safe.\n    mapping(address extension => uint8 enabled) public whitelistedExtensions;\n\n    // Mapping of a bitmap which denotes whether the asset is enabled for renting and\n    // whether the asset restricts gasless permit(). By default, an asset that is active\n    // in the protocol should have a value of 0x11, which allows it to be rented and\n    // prevents gasless permit() approvals.\n    mapping(address asset => uint8 assetBitmap) public whitelistedAssets;\n\n    // Allows the use of these whitelisted tokens as payments for rentals.\n    mapping(address payment => bool isWhitelisted) public whitelistedPayments;\n\n    // Allows a rental safe to upgrade to a newer guard policy if the current guard\n    // policy ever has to be deactivated due to unforseen circumstances.\n    address public guardEmergencyUpgrade;\n}\n\n/**\n * @title Storage\n * @notice Module dedicated to maintaining all the storage for the protocol. Includes\n *         storage for active rentals, deployed rental safes, hooks, and whitelists.\n */\ncontract Storage is Proxiable, Module, StorageBase {\n    using RentalUtils for address;\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                         Kernel Module Configuration                         //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Instantiate this contract as a module. When using a proxy, the kernel address\n     *      should be set to address(0).\n     *\n     * @param kernel_ Address of the kernel contract.\n     */\n    constructor(Kernel kernel_) Module(kernel_) {}\n\n    /**\n     * @notice Instantiates this contract as a module via a proxy.\n     *\n     * @param kernel_ Address of the kernel contract.\n     */\n    function MODULE_PROXY_INSTANTIATION(\n        Kernel kernel_\n    ) external onlyByProxy onlyUninitialized {\n        kernel = kernel_;\n        initialized = true;\n    }\n\n    /**\n     * @notice Specifies which version of a module is being implemented.\n     */\n    function VERSION() external pure override returns (uint8 major, uint8 minor) {\n        return (1, 0);\n    }\n\n    /**\n     * @notice Defines the keycode for this module.\n     */\n    function KEYCODE() public pure override returns (Keycode) {\n        return Keycode.wrap(\"STORE\");\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                              View Functions                                 //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @notice Determines if an asset is actively being rented by a wallet.\n     *\n     * @param recipient  Address of the wallet which rents the asset.\n     * @param token      Address of the token.\n     * @param identifier ID of the token.\n     *\n     * @return Amount of actively rented tokens for the asset.\n     */\n    function isRentedOut(\n        address recipient,\n        address token,\n        uint256 identifier\n    ) external view returns (uint256) {\n        // calculate the rental ID\n        RentalId rentalId = RentalUtils.getItemPointer(recipient, token, identifier);\n\n        // Determine if there is a positive amount\n        return rentedAssets[rentalId];\n    }\n\n    /**\n     * @notice Fetches the hook address that is pointing at the the target.\n     *\n     * @param to Address which has a hook pointing to it.\n     */\n    function contractToHook(address to) external view returns (address) {\n        // Fetch the hook that the address currently points to.\n        address hook = _contractToHook[to];\n\n        // This hook may have been disabled without setting a new hook to take its place.\n        // So if the hook is disabled, then return the 0 address.\n        return hookStatus[hook] != 0 ? hook : address(0);\n    }\n\n    /**\n     * @notice Determines whether the `onTransaction()` function is enabled for the hook.\n     *\n     * @param hook Address of the hook contract.\n     */\n    function hookOnTransaction(address hook) external view returns (bool) {\n        // 1 is 0x00000001. Determines if the masked bit is enabled.\n        return (uint8(1) & hookStatus[hook]) != 0;\n    }\n\n    /**\n     * @notice Determines whether the `onStart()` function is enabled for the hook.\n     *\n     * @param hook Address of the hook contract.\n     */\n    function hookOnStart(address hook) external view returns (bool) {\n        // 2 is 0x00000010. Determines if the masked bit is enabled.\n        return uint8(2) & hookStatus[hook] != 0;\n    }\n\n    /**\n     * @notice Determines whether the `onStop()` function is enabled for the hook.\n     *\n     * @param hook Address of the hook contract.\n     */\n    function hookOnStop(address hook) external view returns (bool) {\n        // 4 is 0x00000100. Determines if the masked bit is enabled.\n        return uint8(4) & hookStatus[hook] != 0;\n    }\n\n    /**\n     * @notice Determines whether the extension can be enabled on the rental safe.\n     *\n     * @param extension Address of the extension contract.\n     */\n    function extensionEnableAllowed(address extension) external view returns (bool) {\n        // 2 is 0x10. Determines if the masked bit is enabled.\n        return uint8(2) & whitelistedExtensions[extension] != 0;\n    }\n\n    /**\n     * @notice Determines whether the extension can be disabled on the rental safe.\n     *\n     * @param extension Address of the extension contract.\n     */\n    function extensionDisableAllowed(address extension) external view returns (bool) {\n        // 1 is 0x01. Determines if the masked bit is enabled.\n        return uint8(1) & whitelistedExtensions[extension] != 0;\n    }\n\n    /**\n     * @notice Determines whether the asset is enabled for renting in the protocol\n     *\n     * @param asset Address of the token to rent.\n     */\n    function assetEnabledForRent(address asset) external view returns (bool) {\n        // 2 is 0x10. Determines if the masked bit is enabled.\n        return uint8(2) & whitelistedAssets[asset] != 0;\n    }\n\n    /**\n     * @notice Determines whether the asset is restricted for gasless permit().\n     *\n     * @param asset Address of the token to restrict gassless permit().\n     */\n    function assetRestrictedForPermit(address asset) external view returns (bool) {\n        // 1 is 0x01. Determines if the masked bit is enabled.\n        return uint8(1) & whitelistedAssets[asset] != 0;\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            External Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @notice Adds an order hash to storage. Once an order hash is added to storage,\n     *         the assets contained within are considered actively rented. Additionally,\n     *         rental asset IDs are added to storage which creates a blocklist on those\n     *         assets. When the blocklist is active, the protocol guard becomes active on\n     *         them and prevents transfer or approval of the assets by the owner of the\n     *         safe.\n     *\n     * @param orderHash          Hash of the rental order which is added to storage.\n     * @param rentalAssetUpdates Asset update structs which are added to storage.\n     */\n    function addRentals(\n        bytes32 orderHash,\n        RentalAssetUpdate[] memory rentalAssetUpdates\n    ) external onlyByProxy permissioned {\n        // Add the order to storage.\n        orders[orderHash] = true;\n\n        // Add the rented items to storage.\n        for (uint256 i = 0; i < rentalAssetUpdates.length; ++i) {\n            RentalAssetUpdate memory asset = rentalAssetUpdates[i];\n\n            // Update the order hash for that item.\n            rentedAssets[asset.rentalId] += asset.amount;\n        }\n    }\n\n    /**\n     * @notice Removes an order hash from storage. Once an order hash is removed from\n     *         storage, it can no longer be stopped since the protocol will have no\n     *         record of the order. Addtionally, rental asset IDs are removed from\n     *         storage. Once these hashes are removed, they are no longer blocklisted\n     *         from being transferred out of the rental wallet by the owner.\n     *\n     * @param orderHash          Hash of the rental order which will be removed from\n     *                           storage.\n     * @param rentalAssetUpdates Asset update structs which will be removed from storage.\n     */\n    function removeRentals(\n        bytes32 orderHash,\n        RentalAssetUpdate[] calldata rentalAssetUpdates\n    ) external onlyByProxy permissioned {\n        // Delete the order from storage.\n        delete orders[orderHash];\n\n        // Process each rental asset.\n        for (uint256 i = 0; i < rentalAssetUpdates.length; ++i) {\n            RentalAssetUpdate memory asset = rentalAssetUpdates[i];\n\n            // Reduce the amount of tokens for the particular rental ID.\n            rentedAssets[asset.rentalId] -= asset.amount;\n        }\n    }\n\n    /**\n     * @notice Behaves the same as `removeRentals()`, except that orders are processed in\n     *          a loop.\n     *\n     * @param orderHashes        All order hashes which will be removed from storage.\n     * @param rentalAssetUpdates Asset update structs which will be removed from storage.\n     */\n    function removeRentalsBatch(\n        bytes32[] calldata orderHashes,\n        RentalAssetUpdate[] calldata rentalAssetUpdates\n    ) external onlyByProxy permissioned {\n        // Delete the orders from storage.\n        for (uint256 i = 0; i < orderHashes.length; ++i) {\n            // Delete the order from storage.\n            delete orders[orderHashes[i]];\n        }\n\n        // Process each rental asset.\n        for (uint256 i = 0; i < rentalAssetUpdates.length; ++i) {\n            RentalAssetUpdate memory asset = rentalAssetUpdates[i];\n\n            // Reduce the amount of tokens for the particular rental ID.\n            rentedAssets[asset.rentalId] -= asset.amount;\n        }\n    }\n\n    /**\n     * @notice Adds the addresss of a rental safe to storage so that protocol-deployed\n     *         rental safes can be distinguished from those deployed elsewhere.\n     *\n     * @param safe Address of the rental safe to add to storage.\n     */\n    function addRentalSafe(address safe) external onlyByProxy permissioned {\n        // Get the new safe count.\n        uint256 newSafeCount = totalSafes + 1;\n\n        // Register the safe as deployed.\n        deployedSafes[safe] = newSafeCount;\n\n        // Increment nonce.\n        totalSafes = newSafeCount;\n    }\n\n    /**\n     * @notice Connects a hook to a destination address. Once an active path is made,\n     *         any transactions originating from a rental safe to the target address\n     *         will use a hook as middleware. The hook chosen is determined by the path\n     *         set.\n     *\n     * @param to   Target address which will use a hook as middleware.\n     * @param hook Address of the hook which will act as a middleware.\n     */\n    function updateHookPath(address to, address hook) external onlyByProxy permissioned {\n        // Require that the `to` address is a contract.\n        if (to.code.length == 0) revert Errors.StorageModule_NotContract(to);\n\n        // Require that the `hook` address is a contract.\n        if (hook.code.length == 0) revert Errors.StorageModule_NotContract(hook);\n\n        // Point the `to` address to the `hook` address.\n        _contractToHook[to] = hook;\n    }\n\n    /**\n     * @notice Updates a hook with a bitmap that indicates its active functionality.\n     *         A valid bitmap is any decimal value that is less than or equal\n     *         to 7 (0x111).\n     *\n     * @param hook   Address of the hook contract.\n     * @param bitmap Decimal value that defines the active functionality on the hook.\n     */\n    function updateHookStatus(\n        address hook,\n        uint8 bitmap\n    ) external onlyByProxy permissioned {\n        // Require that the `hook` address is a contract.\n        if (hook.code.length == 0) revert Errors.StorageModule_NotContract(hook);\n\n        // 7 is 0x00000111. This ensures that only a valid bitmap can be set.\n        if (bitmap > uint8(7))\n            revert Errors.StorageModule_InvalidHookStatusBitmap(bitmap);\n\n        // Update the status of the hook.\n        hookStatus[hook] = bitmap;\n    }\n\n    /**\n     * @notice Toggles whether an address can be delegate called.\n     *\n     * @param delegate  Address which can be delegate called.\n     * @param isEnabled Boolean indicating whether the address is enabled.\n     */\n    function toggleWhitelistDelegate(\n        address delegate,\n        bool isEnabled\n    ) external onlyByProxy permissioned {\n        whitelistedDelegates[delegate] = isEnabled;\n    }\n\n    /**\n     * @notice Updates an extension with a bitmap that indicates whether the extension\n     *         can be enabled or disabled by the rental safe. A valid bitmap is any\n     *         decimal value that is less than or equal to 3 (0x11).\n     *\n     * @param extension Gnosis safe module which can be added to a rental safe.\n     * @param bitmap    Decimal value that defines the status of the extension.\n     */\n    function toggleWhitelistExtension(\n        address extension,\n        uint8 bitmap\n    ) external onlyByProxy permissioned {\n        // Require that the `extension` address is a contract.\n        if (extension.code.length == 0)\n            revert Errors.StorageModule_NotContract(extension);\n\n        // 3 is 0x11. This ensures that only a valid bitmap can be set.\n        if (bitmap > uint8(3)) revert Errors.StorageModule_InvalidWhitelistBitmap(bitmap);\n\n        // Update the extension.\n        whitelistedExtensions[extension] = bitmap;\n    }\n\n    /**\n     * @notice Toggles whether a token can be rented.\n     *\n     * @param asset  Token address which can be rented via the protocol.\n     * @param bitmap Bitmap that denotes whether an asset can be rented.\n     */\n    function toggleWhitelistAsset(\n        address asset,\n        uint8 bitmap\n    ) external onlyByProxy permissioned {\n        // 3 is 0x11. This ensures that only a valid bitmap can be set.\n        if (bitmap > uint8(3)) revert Errors.StorageModule_InvalidWhitelistBitmap(bitmap);\n\n        // Update the asset whitelist.\n        whitelistedAssets[asset] = bitmap;\n    }\n\n    /**\n     * @notice Toggles whether a batch of tokens can be rented.\n     *\n     * @param assets  Token array which can be rented via the protocol.\n     * @param bitmaps Bitmap array indicating whether those token are whitelisted.\n     */\n    function toggleWhitelistAssetBatch(\n        address[] memory assets,\n        uint8[] memory bitmaps\n    ) external onlyByProxy permissioned {\n        // Check that the arrays are the same length\n        if (assets.length != bitmaps.length) {\n            revert Errors.StorageModule_WhitelistBatchLengthMismatch(\n                assets.length,\n                bitmaps.length\n            );\n        }\n\n        // Process each whitelist entry\n        for (uint256 i; i < assets.length; ++i) {\n            // 3 is 0x11. This ensures that only a valid bitmap can be set.\n            if (bitmaps[i] > uint8(3))\n                revert Errors.StorageModule_InvalidWhitelistBitmap(bitmaps[i]);\n\n            whitelistedAssets[assets[i]] = bitmaps[i];\n        }\n    }\n\n    /**\n     * @notice Toggles whether a token can be used as a payment.\n     *\n     * @param payment   Token address which can be used as payment via the protocol.\n     * @param isEnabled Boolean indicating whether the token is whitelisted.\n     */\n    function toggleWhitelistPayment(\n        address payment,\n        bool isEnabled\n    ) external onlyByProxy permissioned {\n        whitelistedPayments[payment] = isEnabled;\n    }\n\n    /**\n     * @notice Toggles whether a batch of tokens can be used as payment.\n     *\n     * @param payments  Token array which can be used as payment via the protocol.\n     * @param isEnabled Boolean array indicating whether those token are whitelisted.\n     */\n    function toggleWhitelistPaymentBatch(\n        address[] memory payments,\n        bool[] memory isEnabled\n    ) external onlyByProxy permissioned {\n        // Check that the arrays are the same length\n        if (payments.length != isEnabled.length) {\n            revert Errors.StorageModule_WhitelistBatchLengthMismatch(\n                payments.length,\n                isEnabled.length\n            );\n        }\n\n        // Process each whitelist entry\n        for (uint256 i; i < payments.length; ++i) {\n            whitelistedPayments[payments[i]] = isEnabled[i];\n        }\n    }\n\n    /**\n     * @notice Upgrades the contract to a different implementation. This implementation\n     *         contract must be compatible with ERC-1822 or else the upgrade will fail.\n     *\n     * @param newImplementation Address of the implementation contract to upgrade to.\n     */\n    function upgrade(address newImplementation) external onlyByProxy permissioned {\n        // _upgrade is implemented in the Proxiable contract.\n        _upgrade(newImplementation);\n    }\n\n    /**\n     * @notice Freezes the contract which prevents upgrading the implementation contract.\n     *         There is no way to unfreeze once a contract has been frozen.\n     */\n    function freeze() external onlyByProxy permissioned {\n        // _freeze is implemented in the Proxiable contract.\n        _freeze();\n    }\n\n    /**\n     * @notice Sets the maximum rent duration.\n     *\n     * @param newDuration The new maximum rent duration.\n     */\n    function setMaxRentDuration(uint256 newDuration) external onlyByProxy permissioned {\n        maxRentDuration = newDuration;\n    }\n\n    /**\n     * @notice Sets the maximum offer items for a single order.\n     *\n     * @param newOfferLength The new maximum number of offer items.\n     */\n    function setMaxOfferItems(uint256 newOfferLength) external onlyByProxy permissioned {\n        maxOfferItems = newOfferLength;\n    }\n\n    /**\n     * @notice Sets the maximum consideration items for a single order.\n     *\n     * @param newConsiderationLength The new maximum number of consideration items.\n     */\n    function setMaxConsiderationItems(\n        uint256 newConsiderationLength\n    ) external onlyByProxy permissioned {\n        maxConsiderationItems = newConsiderationLength;\n    }\n\n    /**\n     * @notice Sets the guard emergency upgrade address.\n     *\n     * @param guardEmergencyUpgradeAddress The contract address which will allow rental\n     * \t\t\t\t\t\t\t\t\t   safes to upgrade their guard policy.\n     */\n    function setGuardEmergencyUpgrade(\n        address guardEmergencyUpgradeAddress\n    ) external onlyByProxy permissioned {\n        guardEmergencyUpgrade = guardEmergencyUpgradeAddress;\n    }\n}\n"
      },
      "src/Kernel.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.20;\n\nimport {\n    toRole,\n    ensureContract,\n    ensureValidKeycode,\n    ensureValidRole\n} from \"@src/libraries/KernelUtils.sol\";\nimport {Actions, Keycode, Role, Permissions} from \"@src/libraries/RentalStructs.sol\";\nimport {Errors} from \"@src/libraries/Errors.sol\";\nimport {Events} from \"src/libraries/Events.sol\";\n\n/////////////////////////////////////////////////////////////////////////////////\n//                         Module Abstract Contracts                           //\n/////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @title KernelAdapter\n * @notice A base contract to be inherited by both policies and modules. Provides common\n *         access to logic related to the kernel contract.\n */\nabstract contract KernelAdapter {\n    // The active kernel contract.\n    Kernel public kernel;\n\n    /**\n     * @dev Instantiate this contract as a a kernel adapter. When using a proxy, the kernel address\n     *      should be set to address(0).\n     *\n     * @param kernel_ Address of the kernel contract.\n     */\n    constructor(Kernel kernel_) {\n        kernel = kernel_;\n    }\n\n    /**\n     * @dev Modifier which only allows calls from the active kernel contract.\n     */\n    modifier onlyKernel() {\n        if (msg.sender != address(kernel))\n            revert Errors.KernelAdapter_OnlyKernel(msg.sender);\n        _;\n    }\n\n    /**\n     * @notice Points the adapter to reference a new kernel address. This function can\n     *         only be called by the active kernel, and is used to perform migrations by\n     *         telling all policies and modules where the new kernel is located before\n     *         actually performing the migration.\n     *\n     * @param newKernel_  Address of the new kernel contract.\n     */\n    function changeKernel(Kernel newKernel_) external onlyKernel {\n        kernel = newKernel_;\n    }\n}\n\n/**\n * @title Module\n * @notice A base contract to be inherited by all module implementations. Provides common\n *         logic related to module functionality.\n */\nabstract contract Module is KernelAdapter {\n    /**\n     * @dev Instantiate this contract as a a module. When using a proxy, the kernel address\n     *      should be set to address(0).\n     *\n     * @param kernel_ Address of the kernel contract.\n     */\n    constructor(Kernel kernel_) KernelAdapter(kernel_) {}\n\n    /**\n     * @dev Modifier which only allows calls to the module if the policy contract making the\n     *      call has been given explicit permission by the kernel first.\n     */\n    modifier permissioned() {\n        if (!kernel.modulePermissions(KEYCODE(), Policy(msg.sender), msg.sig)) {\n            revert Errors.Module_PolicyNotAuthorized(msg.sender);\n        }\n        _;\n    }\n\n    /**\n     * @notice The 5-character keycode used to uniquely represent the module. This\n     *         must be implemented by the inheriting contract.\n     *\n     * @return Keycode represented by the module.\n     */\n    function KEYCODE() public pure virtual returns (Keycode);\n\n    /**\n     * @notice Specifies the version of the module being implemented. Minor version\n     *         changes retain the interface, and major version upgrades indicated\n     *         breaking changes to the interface.\n     *\n     * @return major Major version of the module.\n     * @return minor Minor version of the module.\n     */\n    function VERSION() external pure virtual returns (uint8 major, uint8 minor) {}\n\n    /**\n     * @notice Initialization function for the module which is called when the module is\n     *         first installed or upgraded by the kernel. Can only be called by the kernel.\n     */\n    function INIT() external virtual onlyKernel {}\n}\n\n/**\n * @title Policy\n * @notice A base contract to be inherited by all policy implementations. Provides common\n *         logic related to policy functionality.\n */\nabstract contract Policy is KernelAdapter {\n    // Whether the policy is active or not.\n    bool public isActive;\n\n    /**\n     * @dev Instantiate this contract as a a policy. When using a proxy, the kernel address\n     *      should be set to address(0).\n     *\n     * @param kernel_ Address of the kernel contract.\n     */\n    constructor(Kernel kernel_) KernelAdapter(kernel_) {}\n\n    /**\n     * @dev Modifier which only allows calls from addresses which have explicitly been\n     *      granted a role by the kernel.\n     */\n    modifier onlyRole(bytes32 role_) {\n        Role role = toRole(role_);\n        if (!kernel.hasRole(msg.sender, role)) {\n            revert Errors.Policy_OnlyRole(role);\n        }\n        _;\n    }\n\n    /**\n     * @notice When a policy is activated, it must respond with all of the module\n     *         keycodes that it depends on. The kernel stores these dependencies as a\n     *         mapping from module keycode to an array of policies that depend on it.\n     *         This is useful because when a module is upgraded, it can know exactly\n     *         the policies that depend upon it and call out to each policy to\n     *         reconfigure its dependencies to use the upgraded module contract address.\n     *\n     * @param dependencies Keycodes of all the modules that the policy depends on.\n     */\n    function configureDependencies()\n        external\n        virtual\n        onlyKernel\n        returns (Keycode[] memory dependencies)\n    {}\n\n    /**\n     * @notice When a policy is activated, it must respond with a series of\n     *         keycode <> function selector pairs which represent a request for the\n     *         policy to call a specific function selector at a specific module.\n     *         These requests are stored as a mapping in the kernel while the policy\n     *         is active, and the kernel will reject any call from a policy to a module\n     *         which has not first requested permission.\n     *\n     * @param requests Keycode <> function selector pairs which define the module access\n     *                 requested by a policy.\n     */\n    function requestPermissions()\n        external\n        view\n        virtual\n        onlyKernel\n        returns (Permissions[] memory requests)\n    {}\n\n    /**\n     * @dev Used by a policy to get the current address of a module\n     *      at a specific keycode.\n     *\n     * @param keycode_ Keycode used to get the address of the module.\n     */\n    function getModuleAddress(Keycode keycode_) internal view returns (address) {\n        address moduleForKeycode = address(kernel.getModuleForKeycode(keycode_));\n        if (moduleForKeycode == address(0))\n            revert Errors.Policy_ModuleDoesNotExist(keycode_);\n        return moduleForKeycode;\n    }\n\n    /**\n     * @notice Allows the kernel to grant or revoke the active status of the policy.\n     *\n     * @param activate_ Whether to activate or deactivate the policy.\n     */\n    function setActiveStatus(bool activate_) external onlyKernel {\n        isActive = activate_;\n    }\n}\n\n/////////////////////////////////////////////////////////////////////////////////\n//                               Kernel Contract                               //\n/////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @title Kernel\n * @notice A registry contract that manages a set of policy and module contracts, as well\n *         as the permissions to interact with those contracts.\n */\ncontract Kernel {\n    // Admin addresses.\n    address public executor;\n    address public admin;\n\n    // Module Management.\n    Keycode[] public allKeycodes;\n    mapping(Keycode => Module) public getModuleForKeycode; // get contract for module keycode.\n    mapping(Module => Keycode) public getKeycodeForModule; // get module keycode for contract.\n\n    // Module dependents data. Manages module dependencies for policies.\n    mapping(Keycode => Policy[]) public moduleDependents;\n    mapping(Keycode => mapping(Policy => uint256)) public getDependentIndex;\n\n    // Module <> Policy Permissions. Keycode -> Policy -> Function Selector -> Permission.\n    mapping(Keycode => mapping(Policy => mapping(bytes4 => bool)))\n        public modulePermissions; // for policy addr, check if they have permission to call the function in the module.\n\n    // List of all active policies.\n    Policy[] public activePolicies;\n    mapping(Policy => uint256) public getPolicyIndex;\n\n    // Policy roles data.\n    mapping(address => mapping(Role => bool)) public hasRole;\n    mapping(Role => bool) public isRole;\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                Constructor                                  //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Instantiate the kernel with executor and admin addresses.\n     *\n     * @param _executor Address in charge of handling kernel executions.\n     * @param _admin    Address in charge of granting and revoking roles.\n     */\n    constructor(address _executor, address _admin) {\n        executor = _executor;\n        admin = _admin;\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                Modifiers                                    //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Modifier which only allows calls by an executing address.\n     */\n    modifier onlyExecutor() {\n        if (msg.sender != executor) revert Errors.Kernel_OnlyExecutor(msg.sender);\n        _;\n    }\n\n    /**\n     * @dev modifier which only allows calls by an admin address.\n     */\n    modifier onlyAdmin() {\n        if (msg.sender != admin) revert Errors.Kernel_OnlyAdmin(msg.sender);\n        _;\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            External Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Executes an action on a target address.\n     *\n     * @param action_ Action which will be performed.\n     * @param target_ Address upon which the action will operate.\n     */\n    function executeAction(Actions action_, address target_) external onlyExecutor {\n        if (action_ == Actions.InstallModule) {\n            ensureContract(target_);\n            ensureValidKeycode(Module(target_).KEYCODE());\n            _installModule(Module(target_));\n        } else if (action_ == Actions.UpgradeModule) {\n            ensureContract(target_);\n            ensureValidKeycode(Module(target_).KEYCODE());\n            _upgradeModule(Module(target_));\n        } else if (action_ == Actions.ActivatePolicy) {\n            ensureContract(target_);\n            _activatePolicy(Policy(target_));\n        } else if (action_ == Actions.DeactivatePolicy) {\n            ensureContract(target_);\n            _deactivatePolicy(Policy(target_));\n        } else if (action_ == Actions.MigrateKernel) {\n            ensureContract(target_);\n            _migrateKernel(Kernel(target_));\n        } else if (action_ == Actions.ChangeExecutor) {\n            executor = target_;\n        } else if (action_ == Actions.ChangeAdmin) {\n            admin = target_;\n        }\n\n        emit Events.ActionExecuted(action_, target_);\n    }\n\n    /**\n     * @dev Grants a role to the target address.\n     *\n     * @param role_ Role to grant to the target.\n     * @param addr_ Address that will receive the role.\n     */\n    function grantRole(Role role_, address addr_) public onlyAdmin {\n        // Check that the address does not already have the role.\n        if (hasRole[addr_][role_])\n            revert Errors.Kernel_AddressAlreadyHasRole(addr_, role_);\n\n        // Ensure the role is properly formatted.\n        ensureValidRole(role_);\n\n        // Mark this role as having been granted.\n        if (!isRole[role_]) isRole[role_] = true;\n\n        // Grant the role to the target.\n        hasRole[addr_][role_] = true;\n\n        emit Events.RoleGranted(role_, addr_);\n    }\n\n    /**\n     * @dev Revokes a role from the target address.\n     *\n     * @param role_ Role to revoke from the target.\n     * @param addr_ Address that will have the role removed.\n     */\n    function revokeRole(Role role_, address addr_) public onlyAdmin {\n        // Check if the role has been granted before.\n        if (!isRole[role_]) revert Errors.Kernel_RoleDoesNotExist(role_);\n\n        // Check if the target address currently has the role.\n        if (!hasRole[addr_][role_])\n            revert Errors.Kernel_AddressDoesNotHaveRole(addr_, role_);\n\n        // Revoke the role.\n        hasRole[addr_][role_] = false;\n\n        emit Events.RoleRevoked(role_, addr_);\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            Internal Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Installs a new module into the kernel.\n     *\n     * @param newModule_ Address of the new module.\n     */\n    function _installModule(Module newModule_) internal {\n        // Fetch the module keycode.\n        Keycode keycode = newModule_.KEYCODE();\n\n        // Make sure the keycode isnt in use already.\n        if (address(getModuleForKeycode[keycode]) != address(0)) {\n            revert Errors.Kernel_ModuleAlreadyInstalled(keycode);\n        }\n\n        // Connect the keycode to the module address.\n        getModuleForKeycode[keycode] = newModule_;\n\n        // Connect the module address to the keycode.\n        getKeycodeForModule[newModule_] = keycode;\n\n        // Keep a running array of all module keycodes.\n        allKeycodes.push(keycode);\n\n        // Initialize the module contract.\n        newModule_.INIT();\n    }\n\n    /**\n     * @dev Upgrades a module by changing the address that the keycode points to.\n     *\n     * @param newModule_ Address of the new module.\n     */\n    function _upgradeModule(Module newModule_) internal {\n        // Get the keycode of the new module\n        Keycode keycode = newModule_.KEYCODE();\n\n        // Get the address of the old module\n        Module oldModule = getModuleForKeycode[keycode];\n\n        // Check that the old module contract exists, and that the old module\n        // address is not the same as the new module\n        if (address(oldModule) == address(0) || oldModule == newModule_) {\n            revert Errors.Kernel_InvalidModuleUpgrade(keycode);\n        }\n\n        // The old module no longer points to the keycode.\n        getKeycodeForModule[oldModule] = Keycode.wrap(bytes5(0));\n\n        // The new module points to the keycode.\n        getKeycodeForModule[newModule_] = keycode;\n\n        // The keycode points to the new module.\n        getModuleForKeycode[keycode] = newModule_;\n\n        // Initialize the new module contract.\n        newModule_.INIT();\n\n        // Reconfigure policies so that all policies that depended on the old\n        // module will refetch the new module address from the kernel.\n        _reconfigurePolicies(keycode);\n    }\n\n    /**\n     * @dev Activates a new policy into the kernel.\n     *\n     * @param policy_ Address of the policy to activate.\n     */\n    function _activatePolicy(Policy policy_) internal {\n        // Ensure that the policy is not already active.\n        if (policy_.isActive())\n            revert Errors.Kernel_PolicyAlreadyApproved(address(policy_));\n\n        // Grant permissions for policy to access restricted module functions.\n        Permissions[] memory requests = policy_.requestPermissions();\n        _setPolicyPermissions(policy_, requests, true);\n\n        // Add policy to list of active policies.\n        activePolicies.push(policy_);\n\n        // Set the index of the policy in the array of active policies.\n        getPolicyIndex[policy_] = activePolicies.length - 1;\n\n        // Fetch module dependencies.\n        Keycode[] memory dependencies = policy_.configureDependencies();\n        uint256 depLength = dependencies.length;\n\n        // Loop through each keycode the policy depends on.\n        for (uint256 i; i < depLength; ++i) {\n            Keycode keycode = dependencies[i];\n\n            // Push the policy to the array of dependents for the keycode\n            moduleDependents[keycode].push(policy_);\n\n            // Set the index of the policy in the array of dependents.\n            getDependentIndex[keycode][policy_] = moduleDependents[keycode].length - 1;\n        }\n\n        // Set policy status to active.\n        policy_.setActiveStatus(true);\n    }\n\n    /**\n     * @dev Deactivates an active policy from the kernel\n     *\n     * @param policy_ Address of the policy to deactivate.\n     */\n    function _deactivatePolicy(Policy policy_) internal {\n        if (!policy_.isActive()) revert Errors.Kernel_PolicyNotApproved(address(policy_));\n\n        // Fetch originally granted permissions from the policy\n        // and then revoke them.\n        Permissions[] memory requests = policy_.requestPermissions();\n        _setPolicyPermissions(policy_, requests, false);\n\n        // Get the index of the policy in the active policies array.\n        uint256 idx = getPolicyIndex[policy_];\n\n        // Get the index of the last policy in the active policy array.\n        Policy lastPolicy = activePolicies[activePolicies.length - 1];\n\n        // Set the last policy at the index of the policy to deactivate.\n        activePolicies[idx] = lastPolicy;\n\n        // Pop the last policy from the array.\n        activePolicies.pop();\n\n        // Set the last policy's index to the index of the policy\n        // that was removed.\n        getPolicyIndex[lastPolicy] = idx;\n\n        // Delete the index of the policy being deactivated.\n        delete getPolicyIndex[policy_];\n\n        // Remove policy from array of dependents for each keycode\n        // that the policy depends upon.\n        _pruneFromDependents(policy_);\n\n        // Set policy status to inactive.\n        policy_.setActiveStatus(false);\n    }\n\n    /**\n     * @dev Migrates the kernel to a new contract.\n     *\n     *      WARNING: THIS ACTION WILL BRICK THIS KERNEL.\n     *\n     *      By performing a migration, this kernel will no longer have any authority\n     *      over the current policies and modules.\n     *\n     *      All functionality will move to the new kernel. The new kernel will need\n     *      to add all of the modules and policies again via `executeAction`. Until\n     *      all policies and modules are re-activated on the new kernel, policies will\n     *      not be able to access permissioned functions on modules, and privileged\n     *      addresses will not be able to access role-gated functions on policies.\n     *\n     * @param newKernel_ Address of the new kernel.\n     */\n    function _migrateKernel(Kernel newKernel_) internal {\n        uint256 keycodeLen = allKeycodes.length;\n\n        // For each keycode stored in the kernel.\n        for (uint256 i; i < keycodeLen; ++i) {\n            // get the module represented by the keycode.\n            Module module = Module(getModuleForKeycode[allKeycodes[i]]);\n            // Instruct the module to change the kernel.\n            module.changeKernel(newKernel_);\n        }\n\n        // For each active policy stored in the kernel\n        uint256 policiesLen = activePolicies.length;\n        for (uint256 j; j < policiesLen; ++j) {\n            // Get the policy.\n            Policy policy = activePolicies[j];\n\n            // Deactivate the policy before changing kernel.\n            policy.setActiveStatus(false);\n\n            // Instruct the policy to change the kernel.\n            policy.changeKernel(newKernel_);\n        }\n    }\n\n    /**\n     * @dev All policies that are dependent on the module represented by the keycode\n     *      must be reconfigured so that the policies can request the current\n     *      address of the module from the kernel.\n     *\n     * @param keycode_ Keycode representing the module.\n     */\n    function _reconfigurePolicies(Keycode keycode_) internal {\n        // Get an array of all policies that depend on the keycode.\n        Policy[] memory dependents = moduleDependents[keycode_];\n        uint256 depLength = dependents.length;\n\n        // Loop through each policy.\n        for (uint256 i; i < depLength; ++i) {\n            // Reconfigure its dependencies.\n            dependents[i].configureDependencies();\n        }\n    }\n\n    /**\n     * @dev Sets the permissions for a policy to interact with a module. Once the policy has\n     *      been activated, these permissions do not change until the policy is deactivated.\n     *\n     * @param policy_   Address of the policy.\n     * @param requests_ Permission requests comprised of keycode and function selector pairs.\n     * @param grant_    Whether to grant these permissions or revoke them.\n     */\n    function _setPolicyPermissions(\n        Policy policy_,\n        Permissions[] memory requests_,\n        bool grant_\n    ) internal {\n        uint256 reqLength = requests_.length;\n        for (uint256 i = 0; i < reqLength; ++i) {\n            // Set the permission for the keycode -> policy -> function selector.\n            Permissions memory request = requests_[i];\n            modulePermissions[request.keycode][policy_][request.funcSelector] = grant_;\n\n            emit Events.PermissionsUpdated(\n                request.keycode,\n                policy_,\n                request.funcSelector,\n                grant_\n            );\n        }\n    }\n\n    /**\n     * @dev All keycodes store an array of the policies that depend upon them,\n     *      so a policy must be pruned from this array when it is deactivated.\n     *\n     * @param policy_ Address of the policy to prune from the dependency array.\n     */\n    function _pruneFromDependents(Policy policy_) internal {\n        // Retrieve all keycodes that the policy is dependent upon.\n        Keycode[] memory dependencies = policy_.configureDependencies();\n        uint256 depcLength = dependencies.length;\n\n        // Loop through each keycode.\n        for (uint256 i; i < depcLength; ++i) {\n            // Get the stored array of policies that depend on the keycode.\n            Keycode keycode = dependencies[i];\n            Policy[] storage dependents = moduleDependents[keycode];\n\n            // Get the index of the policy to prune in the array.\n            uint256 origIndex = getDependentIndex[keycode][policy_];\n\n            // Get the address of the last policy in the array.\n            Policy lastPolicy = dependents[dependents.length - 1];\n\n            // Overwrite the last policy with the policy being pruned.\n            dependents[origIndex] = lastPolicy;\n\n            // Since the last policy exists twice now in the array, pop it\n            // from the end of the array.\n            dependents.pop();\n\n            // Set the index of the swapped policy to its correct spot.\n            getDependentIndex[keycode][lastPolicy] = origIndex;\n\n            // Delete the index of the of the pruned policy.\n            delete getDependentIndex[keycode][policy_];\n        }\n    }\n}\n"
      },
      "src/proxy/Proxiable.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.20;\n\nimport {Errors} from \"@src/libraries/Errors.sol\";\n\n/**\n * @title Proxiable\n * @notice Adheres to the Universal Upgradeable Proxy Standard (ERC-1822). This contract\n *         is meant to be inherited by the logic implementation. Proxiable is in charge\n *         of implementations for upgrading the proxy, and freezing the proxy so that it\n *         can no longer be upgraded.\n */\ncontract Proxiable {\n    // Whether this proxy has been initialized.\n    bool public initialized;\n\n    // Store the implementation contract address on deployment.\n    address private immutable _self = address(this);\n\n    // This is keccak256(\"eip1967.proxy.implementation\") subtracted by 1.\n    bytes32 internal constant IMPLEMENTATION_SLOT =\n        0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    // This is keccak256(\"proxiable.freeze.slot\") subtracted by 1.\n    bytes32 internal constant FREEZE_SLOT =\n        0xb1c430d6858c7d4aa68247671513746f811bc8a08b57cb1afc031d4c886174dc;\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                  Modifiers                                  //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Modifier which only allows a call to be made if it is via the proxy.\n     */\n    modifier onlyByProxy() {\n        // Makes sure the contract storage is not from address(this), and that the\n        // implementation address stored in the proxy is the same as the original\n        // stored address from the implementation contract.\n        if (address(this) == _self || _getImplementation() != _self) {\n            revert Errors.Proxy_OnlyCallByProxy();\n        }\n\n        _;\n    }\n\n    /**\n     * @dev Modifier which only allows a call if the proxy is uninitialized.\n     */\n    modifier onlyUninitialized() {\n        if (initialized) revert Errors.Proxy_AlreadyInitialized();\n        _;\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            Internal Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Checks if the proxy contract is frozen.\n     *\n     * @return isFrozen Whether the proxy is frozen.\n     */\n    function _isFrozen() internal view returns (bool isFrozen) {\n        assembly {\n            // Load the implementation contract.\n            isFrozen := sload(FREEZE_SLOT)\n        }\n    }\n\n    /**\n     * @dev Gets the implementation address.\n     *\n     * @return implementation Address of the implementation.\n     */\n    function _getImplementation() internal view returns (address implementation) {\n        assembly {\n            // Load the implementation contract.\n            implementation := sload(IMPLEMENTATION_SLOT)\n        }\n    }\n\n    /**\n     * @dev Upgrades the implementation contract.\n     *\n     * @param newImplementation Address of the new implementation.\n     */\n    function _upgrade(address newImplementation) internal {\n        // Assert that the contract has not been frozen.\n        if (_isFrozen()) {\n            revert Errors.Proxy_Frozen();\n        }\n\n        // Assert that the contract to upgrade to is also a `Proxiable`.\n        try Proxiable(newImplementation).proxiableUUID() returns (bytes32 uuid) {\n            if (IMPLEMENTATION_SLOT != uuid)\n                revert Errors.Proxy_NotCompatible(newImplementation);\n        } catch {\n            revert Errors.Proxy_NotCompatible(newImplementation);\n        }\n\n        // Update the implementation address.\n        assembly {\n            sstore(IMPLEMENTATION_SLOT, newImplementation)\n        }\n    }\n\n    /**\n     * @dev Freezes the contract. Warning: This permanently prevents future upgrades.\n     */\n    function _freeze() internal {\n        // Update the freeze slot address.\n        assembly {\n            sstore(FREEZE_SLOT, 1)\n        }\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            External Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @notice Returns the ID of this `Proxiable` contract.\n     *\n     * @return ID of the proxiable contract.\n     */\n    function proxiableUUID() public pure returns (bytes32) {\n        return IMPLEMENTATION_SLOT;\n    }\n}\n"
      },
      "src/libraries/RentalUtils.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {\n    ReceivedItem,\n    SpentItem,\n    ItemType as SeaportItemType\n} from \"@seaport-types/lib/ConsiderationStructs.sol\";\n\nimport {\n    RentalOrder,\n    RentalId,\n    RentalAssetUpdate,\n    Item,\n    ItemType,\n    OrderType\n} from \"@src/libraries/RentalStructs.sol\";\n\n/**\n * @title RentalUtils\n * @notice Contains logic for working with rental IDs and various assertion\n *         helper functions.\n */\nlibrary RentalUtils {\n    /////////////////////////////////////////////////////////////////////////////////\n    //                               Rental ID Utils                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Generates a hashed `RentalId` type out of a recipient, token, and identifier.\n     *\n     * @param recipient  Address which will receive the rental asset.\n     * @param token      Address of the rental asset.\n     * @param identifier Identifier for the rental asset.\n     *\n     * @return id Rental ID generated from the input values.\n     */\n    function getItemPointer(\n        address recipient,\n        address token,\n        uint256 identifier\n    ) internal pure returns (RentalId id) {\n        id = RentalId.wrap(keccak256(abi.encodePacked(recipient, token, identifier)));\n    }\n\n    /**\n     * @dev Converts an `Item` and a recipient address into a `RentalId`.\n     *\n     * @param rentalItem The item to convert into a `RentalId`.\n     * @param recipient  Address which will receive the rental asset.\n     *\n     * @return rentalId Rental ID generated from the input values.\n     *\n     */\n    function toRentalId(\n        Item memory rentalItem,\n        address recipient\n    ) internal pure returns (RentalId rentalId) {\n        // Convert the rental item into a rental ID.\n        return getItemPointer(recipient, rentalItem.token, rentalItem.identifier);\n    }\n\n    /**\n     * @dev Converts an array of `Item` and a recipient address into an array of\n     *      `RentalId`.\n     *\n     * @param rentalItems The items to convert into a `RentalId` array.\n     * @param recipient   Address which will receive the rental asset.\n     *\n     * @return rentalIds Rental IDs generated from the input values.\n     */\n    function toRentalIds(\n        Item[] memory rentalItems,\n        address recipient\n    ) internal pure returns (RentalId[] memory rentalIds) {\n        rentalIds = new RentalId[](rentalItems.length);\n\n        for (uint256 i; i < rentalIds.length; ++i) {\n            // Convert the rental item into a rental ID.\n            rentalIds[i] = getItemPointer(\n                recipient,\n                rentalItems[i].token,\n                rentalItems[i].identifier\n            );\n        }\n    }\n\n    /**\n     * @dev Converts an `Item` and a recipient address into a `RentalAssetUpdate`.\n     *\n     * @param item      The item to convert into a `RentalAssetupdate`.\n     * @param recipient Address which will receive the rental asset.\n     */\n    function toRentalAssetUpdate(\n        Item memory item,\n        address recipient\n    ) internal pure returns (RentalAssetUpdate memory rentalAssetupdate) {\n        return RentalAssetUpdate(toRentalId(item, recipient), item.amount);\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                               Item Assertions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Asserts whether an `Item` represents an ERC721 token.\n     *\n     * @return Whether the item is an ERC721 token.\n     */\n    function isERC721(Item memory item) internal pure returns (bool) {\n        return item.itemType == ItemType.ERC721;\n    }\n\n    /**\n     * @dev Asserts whether a `SpentItem` represents an ERC721 token.\n     *\n     * @return Whether the item is an ERC721 token.\n     */\n    function isERC721(SpentItem memory item) internal pure returns (bool) {\n        return item.itemType == SeaportItemType.ERC721;\n    }\n\n    /**\n     * @dev Asserts whether a `ReceivedItem` represents an ERC721 token.\n     *\n     * @return Whether the item is an ERC721 token.\n     */\n    function isERC721(ReceivedItem memory item) internal pure returns (bool) {\n        return item.itemType == SeaportItemType.ERC721;\n    }\n\n    /**\n     * @dev Asserts whether an `Item` represents an ERC1155 token.\n     *\n     * @return Whether the item is an ERC1155 token.\n     */\n    function isERC1155(Item memory item) internal pure returns (bool) {\n        return item.itemType == ItemType.ERC1155;\n    }\n\n    /**\n     * @dev Asserts whether a `SpentItem` represents an ERC1155 token.\n     *\n     * @return Whether the item is an ERC1155 token.\n     */\n    function isERC1155(SpentItem memory item) internal pure returns (bool) {\n        return item.itemType == SeaportItemType.ERC1155;\n    }\n\n    /**\n     * @dev Asserts whether a `ReceivedItem` represents an ERC1155 token.\n     *\n     * @return Whether the item is an ERC1155 token.\n     */\n    function isERC1155(ReceivedItem memory item) internal pure returns (bool) {\n        return item.itemType == SeaportItemType.ERC1155;\n    }\n\n    /**\n     * @dev Asserts whether an `Item` represents an ERC20 token.\n     *\n     * @return Whether the item is an ERC20 token.\n     */\n    function isERC20(Item memory item) internal pure returns (bool) {\n        return item.itemType == ItemType.ERC20;\n    }\n\n    /**\n     * @dev Asserts whether a `SpentItem` represents an ERC20 token.\n     *\n     * @return Whether the item is an ERC20 token.\n     */\n    function isERC20(SpentItem memory item) internal pure returns (bool) {\n        return item.itemType == SeaportItemType.ERC20;\n    }\n\n    /**\n     * @dev Asserts whether a `ReceivedItem` represents an ERC20 token.\n     *\n     * @return Whether the item is an ERC20 token.\n     */\n    function isERC20(ReceivedItem memory item) internal pure returns (bool) {\n        return item.itemType == SeaportItemType.ERC20;\n    }\n\n    /**\n     * @dev Asserts whether an `Item` represents a rented asset.\n     *\n     * @return Whether the item is a rented asset.\n     */\n    function isRental(Item memory item) internal pure returns (bool) {\n        return isERC721(item) || isERC1155(item);\n    }\n\n    /**\n     * @dev Asserts whether a `SpentItem` represents a rented asset.\n     *\n     * @return Whether the item is a rented asset.\n     */\n    function isRental(SpentItem memory item) internal pure returns (bool) {\n        return isERC721(item) || isERC1155(item);\n    }\n\n    /**\n     * @dev Asserts whether a `ReceivedItem` represents a rented asset.\n     *\n     * @return Whether the item is a rented asset.\n     */\n    function isRental(ReceivedItem memory item) internal pure returns (bool) {\n        return isERC721(item) || isERC1155(item);\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                              Order Assertions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Asserts whether the order is a Base order.\n     *\n     * @return Whether the order is a Base order.\n     */\n    function isBaseOrder(OrderType orderType) internal pure returns (bool) {\n        return orderType == OrderType.BASE;\n    }\n\n    /**\n     * @dev Asserts whether the order is a Pay order.\n     *\n     * @return Whether the order is a Pay order.\n     */\n    function isPayOrder(OrderType orderType) internal pure returns (bool) {\n        return orderType == OrderType.PAY;\n    }\n\n    /**\n     * @dev Asserts whether the order is a Payee order.\n     *\n     * @return Whether the order is a Payee order.\n     */\n    function isPayeeOrder(OrderType orderType) internal pure returns (bool) {\n        return orderType == OrderType.PAYEE;\n    }\n}\n"
      },
      "src/libraries/RentalStructs.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {\n    ReceivedItem,\n    SpentItem,\n    OrderType as SeaportOrderType\n} from \"@seaport-types/lib/ConsiderationStructs.sol\";\n\n/////////////////////////////////////////////////////////////////////////////////\n//                           Order Creation Structs                            //\n/////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @dev Defines the supported order types in a rental. BASE orders require that rental\n *      assets are offered up in exchange for some ERC20 payment. PAY orders must contain\n *      only offer items where at least one is a rental asset and at least one is a\n *      payment. These orders are paired with PAYEE orders only contain consideration\n *      items where at least one is a rental asset and at least one is a payment.\n */\nenum OrderType {\n    // Offer items: all must be ERC721/ERC1155.\n    // Consideration items: all must be ERC20.\n    BASE,\n    // Offer items: at least one ERC721/ERC1155, at least one ERC20.\n    // Consideration items: none.\n    PAY,\n    // Offer items: none.\n    // Consideration items: at least one ERC721/ERC1155, at least one ERC20.\n    PAYEE\n}\n\n/**\n * @dev A hook contains three components: an address of the hook which will activate if a\n *      path is present to the hook, the index of the item associated with this hook in\n *      the order (it will always be an offer item), and any arbitrary data that the\n *      offerer deems important to pass along to the call with the hook on rental start.\n */\nstruct Hook {\n    // The hook contract.\n    address target;\n    // Index of the item in the order to apply the hook to.\n    uint256 itemIndex;\n    // Any extra data that the hook will need.\n    bytes extraData;\n}\n\n/**\n * @dev Order metadata contains all the details supplied by the offerer when they sign an\n *      order. These items include the type of rental order, how long the rental will be\n *      active, any hooks associated with the order, and any data that should be emitted\n *      when the rental starts.\n */\nstruct OrderMetadata {\n    // Type of order being created.\n    OrderType orderType;\n    // Duration of the rental in seconds.\n    uint256 rentDuration;\n    // Hooks that will act as middleware for the items in the order.\n    Hook[] hooks;\n    // Any extra data to be emitted upon order fulfillment.\n    bytes emittedExtraData;\n}\n\n/**\n * @dev Order fulfillment data contains details supplied by the fulfiller of the order.\n *      Currently, the only data needed is the expected rental wallet address which will\n *      receive the rented assets. This address is used to check against the fulfiller of\n *      the order to make sure they are the owner of the rental safe recipient address.\n */\nstruct OrderFulfillment {\n    // Rental wallet address.\n    address recipient;\n}\n\n/////////////////////////////////////////////////////////////////////////////////\n//                             Rental Order Structs                            //\n/////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @dev Defines the different types of assets that a rental order supports.\n */\nenum ItemType {\n    // ERC721 assets.\n    ERC721,\n    // ERC1155 assets.\n    ERC1155,\n    // ERC20 assets.\n    ERC20\n}\n\n/**\n * @dev Defines which party will receive an asset after a rental is settled.\n */\nenum SettleTo {\n    // Lender of the rental order.\n    LENDER,\n    // Renter of the rental order.\n    RENTER\n}\n\n/**\n * @dev Defines a rental ID which is a hash of unique markers on an asset. Namely, the\n *      recipient of the asset, the asset address, and the asset identifier.\n */\ntype RentalId is bytes32;\n\n/**\n * @dev Used to transport rental asset update information. Contains data for a\n *      single rental asset: a rental ID and the amount of tokens rented.\n */\nstruct RentalAssetUpdate {\n    RentalId rentalId;\n    uint256 amount;\n}\n\n/**\n * @dev Defines an item which is part of a rental order. Contains item type, EOA to\n *      settle the asset to, address of the token, amount of the token rented, and\n *      identifier of the token.\n */\nstruct Item {\n    ItemType itemType;\n    SettleTo settleTo;\n    address token;\n    uint256 amount;\n    uint256 identifier;\n}\n\n/**\n * @dev Defines a rental order. This order is contructed from a single seaport order when\n *      a rental is created. To stop a rental, this order will need to be provided back\n *      to the protocol. Since it is not stored in long form, an event is emitted when\n *      the rental is started to provide all the data necessary to reconstruct the rental\n *      order.\n */\nstruct RentalOrder {\n    bytes32 seaportOrderHash;\n    Item[] items;\n    Hook[] hooks;\n    OrderType orderType;\n    address lender;\n    address renter;\n    address rentalWallet;\n    uint256 startTimestamp;\n    uint256 endTimestamp;\n}\n\n/////////////////////////////////////////////////////////////////////////////////\n//                               Payload Structs                               //\n/////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @dev Used as a vehicle for extra data that is needed for the rental, which is provided to\n *      the seaport order during fulfillment. The hash of the metadata is checked against\n *      the hash stored in the signed seaport order to make sure the data matches.\n */\nstruct RentPayload {\n    bytes32 orderHash;\n    OrderFulfillment fulfillment;\n    OrderMetadata metadata;\n    uint256 expiration;\n    address intendedFulfiller;\n}\n\n/**\n * @dev Converts data received from the seaport zone contract into a single struct that\n *      is easier to work with during rental creation.\n */\nstruct SeaportPayload {\n    bytes32 orderHash;\n    bytes32 zoneHash;\n    SpentItem[] offer;\n    ReceivedItem[] consideration;\n    ReceivedItem[] totalExecutions;\n    address fulfiller;\n    address offerer;\n    SeaportOrderType orderType;\n}\n\n/////////////////////////////////////////////////////////////////////////////////\n//                              Kernel Structs                                 //\n/////////////////////////////////////////////////////////////////////////////////\n\n/**\n * @dev Defines the actions which can be carried out by the executor of the kernel.\n */\nenum Actions {\n    // Installs a new module.\n    InstallModule,\n    // Changes the 5-character keycode from one module to point to a new module.\n    UpgradeModule,\n    // Grants a policy's access to module permissioned module functionality.\n    ActivatePolicy,\n    // Revokes a policy's access to permissioned module functionality.\n    DeactivatePolicy,\n    // Changes the address of the executor role.\n    ChangeExecutor,\n    // Changes the address of the admin role.\n    ChangeAdmin,\n    // Migrates the kernel to a new contract. This can only be done once per contract.\n    MigrateKernel\n}\n\n/**\n * @dev Defines permission for a policy to have access to the `funcSelector` at a\n *      specific module contract via its keycode.\n */\nstruct Permissions {\n    Keycode keycode;\n    bytes4 funcSelector;\n}\n\n/**\n * @dev A 5-character keycode that references a module contract.\n */\ntype Keycode is bytes5;\n\n/**\n * @dev A unique role which can be granted or revoked by the admin.\n */\ntype Role is bytes32;\n"
      },
      "src/libraries/Errors.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {ItemType, Role, Keycode} from \"@src/libraries/RentalStructs.sol\";\n\nimport {\n    ItemType as SeaportItemType,\n    OrderType as SeaportOrderType\n} from \"@seaport-types/lib/ConsiderationStructs.sol\";\n\n/**\n * @title Errors\n * @notice Contains errors defined for the protocol.\n */\nlibrary Errors {\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                     Shared                                  //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when an order is assigned an invalid OrderType.\n     *\n     * @param orderType The invalid order type enum value.\n     */\n    error Shared_OrderTypeNotSupported(uint8 orderType);\n\n    /**\n     * @dev Thrown when trying to interact with a hook that is disabled.\n     *\n     * @param hook The hook addess on which an interaction was attempted.\n     */\n    error Shared_DisabledHook(address hook);\n\n    /**\n     * @dev Thrown when a hook is specified for a non-ERC721 or non-ERC1155 item.\n     *\n     * @param itemIndex The index of the invalid item.\n     */\n    error Shared_NonRentalHookItem(uint256 itemIndex);\n\n    /**\n     * @dev Thrown when execution flow reverts during a call to a hook.\n     *\n     * @param revertReason The reason the execution reverted, as a string.\n     */\n    error Shared_HookFailString(string revertReason);\n\n    /**\n     * @dev Thrown when execution flow reverts during a call to a hook.\n     *\n     * @param revertData The reason the execution reverted, as bytes.\n     */\n    error Shared_HookFailBytes(bytes revertData);\n\n    /**\n     * @dev Thrown when an ERC20 transfer failed.\n     *\n     * @param token Address of the token being transferred.\n     * @param from  Address that the token was sent from.\n     * @param to    Address that the token was sent to.\n     * @param value Amount of the token sent.\n     */\n    error Shared_ERC20TransferFailed(\n        address token,\n        address from,\n        address to,\n        uint256 value\n    );\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                 Create Policy                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when an order contains a Seaport item type that is not supported.\n     *\n     * @param itemType The seaport item type that is not supported.\n     */\n    error CreatePolicy_SeaportItemTypeNotSupported(SeaportItemType itemType);\n\n    /**\n     * @dev Thrown when an order contains a Seaport order type that is not supported.\n     *\n     * @param orderType The seaport order type that is not supported.\n     */\n    error CreatePolicy_SeaportOrderTypeNotSupported(SeaportOrderType orderType);\n\n    /**\n     * @dev Thrown when a `RentPayload` was signed with an expected order hash that was\n     *      not used when fulfilling the order.\n     *\n     * @param payloadOrderHash Order hash that the payload expects.\n     * @param seaportOrderHash Order hash of the order being fulfilled.\n     */\n    error CreatePolicy_InvalidPayloadForOrderHash(\n        bytes32 payloadOrderHash,\n        bytes32 seaportOrderHash\n    );\n\n    /**\n     * @dev Thrown when the total number of offer items in an order is zero.\n     */\n    error CreatePolicy_OfferCountZero();\n\n    /**\n     * @dev Thrown when the total number of offer items in an order exceeds the maximum\n     * \t\tamount allowed.\n     *\n     * @param offerCount Number of offer items in the order.\n     */\n    error CreatePolicy_OfferCountExceedsMax(uint256 offerCount);\n\n    /**\n     * @dev Thrown when the total number of offer items in an order is greater than zero.\n     *\n     * @param offerCount Number of offer items in the order.\n     */\n    error CreatePolicy_OfferCountNonZero(uint256 offerCount);\n\n    /**\n     * @dev Thrown when the total number of consideration items in an order is zero.\n     */\n    error CreatePolicy_ConsiderationCountZero();\n\n    /**\n     * @dev Thrown when the total number of consideration items in an order exceeds\n     * \t\tthe maximum\tamount allowed.\n     *\n     * @param considerationCount Number of consideration items in the order.\n     */\n    error CreatePolicy_ConsiderationCountExceedsMax(uint256 considerationCount);\n\n    /**\n     * @dev Thrown when the total number of consideration items in an order is greater\n     * \t\tthan zero.\n     *\n     * @param considerationCount Number of consideration items in the order.\n     */\n    error CreatePolicy_ConsiderationCountNonZero(uint256 considerationCount);\n\n    /**\n     * @dev Thrown when the recipient of a token is unexpected.\n     *\n     * @param itemType      The seaport item type of the token.\n     * @param token         Address of the token.\n     * @param identifier    ID of the token.\n     * @param amount        Amount of the token sent.\n     * @param currentOwner  Address the token was actually sent to.\n     * @param expectedOwner Address the token was expected to be sent to.\n     */\n    error CreatePolicy_UnexpectedTokenRecipient(\n        SeaportItemType itemType,\n        address token,\n        uint256 identifier,\n        uint256 amount,\n        address currentOwner,\n        address expectedOwner\n    );\n\n    /**\n     * @dev Thrown when the count of either rental or payment items are zero.\n     *\n     * @param totalRentals  Total items in the orde which are rented assets.\n     * @param totalPayments Total items in the order which are payments.\n     */\n    error CreatePolicy_ItemCountZero(uint256 totalRentals, uint256 totalPayments);\n\n    /**\n     * @dev Thrown when the recipient of a consideration payment is not set to the proper\n     *      payment escrow contract.\n     *\n     * @param paymentRecipient Recipient address of the payment tokens.\n     */\n    error CreatePolicy_UnexpectedPaymentEscrowRecipient(address paymentRecipient);\n\n    /**\n     * @dev Thrown when a rent duration that is too long is specified.\n     */\n    error CreatePolicy_RentDurationTooLong(uint256 rentDuration);\n\n    /**\n     * @dev Thrown when a rent duration of zero is specified.\n     */\n    error CreatePolicy_RentDurationZero();\n\n    /**\n     * @dev Thrown when order metadata does not match zone hash.\n     */\n    error CreatePolicy_InvalidOrderMetadataHash();\n\n    /**\n     * @dev Thrown when the recipient is not a protocol-deployed safe.\n     *\n     * @param safe Address of the non-protocol safe.\n     */\n    error CreatePolicy_InvalidRentalSafe(address safe);\n\n    /**\n     * @dev Thrown when the fulfiller is not the owner of the recipient rental safe.\n     *\n     * @param unauthorizedOwner Address which is not an owner of the rental safe.\n     * @param safe              Address of the rental safe.\n     */\n    error CreatePolicy_InvalidSafeOwner(address unauthorizedOwner, address safe);\n\n    /**\n     * @dev Thrown when a consideration item has the offerer selected as a recipient.\n     */\n    error CreatePolicy_OffererCannotBeRecipient();\n\n    /**\n     * @dev Thrown when an unauthorized address signs a create policy payloads.\n     *\n     * @param signer Address that signed the rent payload.\n     */\n    error CreatePolicy_UnauthorizedCreatePolicySigner(address signer);\n\n    /**\n     * @dev Thrown when creating a rental with an asset that does not exist\n     *      in the whitelist.\n     */\n    error CreatePolicy_AssetNotWhitelisted(address token);\n\n    /**\n     * @dev Thrown when creating a rental with a payment that does not exist\n     *      in the whitelist.\n     */\n    error CreatePolicy_PaymentNotWhitelisted(address token);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                  Stop Policy                                //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when an order hash does not exist.\n     *\n     * @param orderHash Hash of the rental order.\n     */\n    error StopPolicy_OrderDoesNotExist(bytes32 orderHash);\n\n    /**\n     * @dev Thrown when an order is stopped in the same transaction that it was started.\n     *\n     */\n    error StopPolicy_StoppedTooSoon();\n\n    /**\n     * @dev Thrown when either the timestamp or the stopper address is invalid when\n     *      stopping an order.\n     *\n     * @param timestamp Current timestamp of the attempted rental stop.\n     * @param stopper   Address that initiated the rental stop.\n     */\n    error StopPolicy_CannotStopOrder(uint256 timestamp, address stopper);\n\n    /**\n     * @dev Thrown when the call to reclaim assets from a rental wallet fails.\n     */\n    error StopPolicy_ReclaimFailed();\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                Factory Policy                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when attempting to deploy a safe with an incompatible threshhold and\n     *      number of owners.\n     *\n     * @param threshold Minimum number of owners needed to sign a transaction.\n     * @param owners    Maximum number of owners for the safe.\n     */\n    error FactoryPolicy_InvalidSafeThreshold(uint256 threshold, uint256 owners);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                 Guard Policy                                //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when attempting to call a restricted function selector on a rented\n     *      item.\n     *\n     * @param selector Four byte selector of the call.\n     */\n    error GuardPolicy_UnauthorizedSelector(bytes4 selector);\n\n    /**\n     * @dev Thrown when attempting to call a restricted function selector with an amount\n     *      that would result in less tokens being left in the safe than are actively\n     *      rented out.\n     *\n     * @param selector Four byte selector of the call.\n     * @param rentedAmount Amount that is actively rented.\n     * @param remainingBalance Invalid remaining balance if the call had succeeded.\n     */\n    error GuardPolicy_UnauthorizedAssetAmount(\n        bytes4 selector,\n        uint256 rentedAmount,\n        uint256 remainingBalance\n    );\n\n    /**\n     * @dev Thrown when an unauthorized call to change the enabled/disabled status\n     *      of an extension is made.\n     *\n     * @param extension An extension contract for the rental safe to add as a module.\n     */\n    error GuardPolicy_UnauthorizedExtension(address extension);\n\n    /**\n     * @dev Thrown when a target delegate call address is not whitelisted.\n     *\n     * @param to Address to direct a delegate call.\n     */\n    error GuardPolicy_UnauthorizedDelegateCall(address to);\n\n    /**\n     * @dev Thrown when attempting to execute a transaction throught a Guard Policy that\n     *      is no longer active.\n     */\n    error GuardPolicy_Deactivated();\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                               Fallback Policy                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when attempting to validate a message hash that was not signed\n     *      by any owners of the rental safe.\n     *\n     * @param messageHash Message digest that was signed.\n     */\n    error FallbackPolicy_HashNotSigned(bytes32 messageHash);\n\n    /**\n     * @dev Thrown when a signature is attempting to be validated from a token\n     *      contract that has been whitelisted for renting on the protocol. This\n     *      error is thrown to protect the assets from token approvals being gaslessly\n     *      signed to transfer the asset from the rental safe.abi\n     *\n     * @param sender Address that requested the signature validation.\n     */\n    error FallbackPolicy_UnauthorizedSender(address sender);\n\n    /**\n     * @dev Thrown when attempting to validate a contract signature through the Fallback\n     *      Policy that is no longer active.\n     */\n    error FallbackPolicy_Deactivated();\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                             Payment Escrow Module                           //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when attempting to make a payment of 0.\n     */\n    error PaymentEscrow_ZeroPayment();\n\n    /**\n     * @dev Thrown when attempting to see a fee numerator too high.\n     */\n    error PaymentEscrow_InvalidFeeNumerator();\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                 Storage Module                              //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when attempting to enable a hook using a non-contract address.\n     *\n     * @param addr Address of the hook.\n     */\n    error StorageModule_NotContract(address addr);\n\n    /**\n     * @dev Thrown when an invalid bitmap is provided to the hook status.\n     *\n     * @param bitmap Used to identify what functions the hook supports.\n     */\n    error StorageModule_InvalidHookStatusBitmap(uint8 bitmap);\n\n    /**\n     * @dev Thrown when an invalid bitmap is provided to a whitelist.\n     *\n     * @param bitmap Used to identify the value of the whitelist.\n     */\n    error StorageModule_InvalidWhitelistBitmap(uint8 bitmap);\n\n    /**\n     * @dev Thrown when making a batch update to a token whitelist and the array of\n     *  \ttokens is not the same length as the array of booleans that distinguish\n     * \t\twhether the asset is whitelisted or not.\n     *\n     * @param assetLength Length of the asset array.\n     * @param boolLength Length of the bool array.\n     */\n    error StorageModule_WhitelistBatchLengthMismatch(\n        uint256 assetLength,\n        uint256 boolLength\n    );\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                               Create2 Deployer                              //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when deployment has already been made at the address.\n     *\n     * @param deployed Address of the already deployed contract.\n     * @param salt     Salt used to generated the address.\n     */\n    error Create2Deployer_AlreadyDeployed(address deployed, bytes32 salt);\n\n    /**\n     * @dev Thrown when deployment address and actual deployment address did not match.\n     *\n     * @param expected Expected deployment address based on the salt provided.\n     * @param actual   Actual deployment address of the contract.\n     */\n    error Create2Deployer_MismatchedDeploymentAddress(address expected, address actual);\n\n    /**\n     * @dev Thrown when the salt does not begin with the sender.\n     *\n     * @param sender Address of the account initiating the deployment.\n     * @param salt   Salt used to create the deployment.\n     */\n    error Create2Deployer_UnauthorizedSender(address sender, bytes32 salt);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                              Reclaimer Package                              //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when interacting with the reclaimer without a delegate call.\n     */\n    error ReclaimerPackage_OnlyDelegateCallAllowed();\n\n    /**\n     * @dev Thrown when the initiator of the reclaim is not the rental wallet.\n     *\n     * @param reclaimer Address that attempted the reclaim.\n     */\n    error ReclaimerPackage_OnlyRentalSafeAllowed(address reclaimer);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                Signer Package                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when an unauthorized address attempts to fulfill an order.\n     *\n     * @param unauthorized Address that attempted the fulfillment.\n     * @param expected     Address that was expected to be the fulfiller.\n     */\n    error SignerPackage_UnauthorizedFulfiller(address unauthorized, address expected);\n\n    /**\n     * @dev Thrown when a rental payload signature has expired.\n     *\n     * @param currentTimestamp Current timestamp when the signature was checked.\n     * @param expiredAt        Timestamp that the signature expired.\n     */\n    error SignerPackage_SignatureExpired(uint256 currentTimestamp, uint256 expiredAt);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                    Proxy                                    //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when attempting to upgrade to a non-compatible proxy contract.\n     *\n     * @param newImplementation Address of the new proxy implementation contract.\n     */\n    error Proxy_NotCompatible(address newImplementation);\n\n    /**\n     * @dev Thrown when attempting to upgrade a frozen contract.\n     */\n    error Proxy_Frozen();\n\n    /**\n     * @dev Thrown when making a non-proxy call.\n     */\n    error Proxy_OnlyCallByProxy();\n\n    /**\n     * @dev Thrown when trying to initialize a proxy twice.\n     */\n    error Proxy_AlreadyInitialized();\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                              Kernel Adapter                                 //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when attempting to call a function that is only callable by the Kernel.\n     *      The kernel is the only address authorized to migrate the kernel contract,\n     *      initialize modules, and configure dependencies and permissions on policies.\n     *\n     * @param caller_ Address that attempted the call.\n     */\n    error KernelAdapter_OnlyKernel(address caller_);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                   Module                                    //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when a policy contract attempts to interact with a function on a\n     *      module contract that it has not explicitly been given permission to access.\n     *\n     * @param policy_ Address of the policy contract attempting to make the call.\n     */\n    error Module_PolicyNotAuthorized(address policy_);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                   Policy                                    //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when an address attempts to call a function on a policy contract,\n     *      but has not been authorized with the proper role first.\n     *\n     * @param role_ The role the caller must have to access the function.\n     */\n    error Policy_OnlyRole(Role role_);\n\n    /**\n     * @dev Thrown when a policy attempts to interact with module via a keycode that does\n     *      not point to a module.\n     *\n     * @param keycode_ The keycode used to point to a module.\n     */\n    error Policy_ModuleDoesNotExist(Keycode keycode_);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                   Kernel                                    //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Thrown when attempting to access a function that is only reserved for the\n     *      kernel executor role.\n     *\n     * @param caller_ Address that attempted a call to an executor-only function.\n     */\n    error Kernel_OnlyExecutor(address caller_);\n\n    /**\n     * @dev Thrown when attempting to access a function that is only reserved for the\n     *      kernel admin role.\n     *\n     * @param caller_ Address that attemped a call to an admin-only function.\n     */\n    error Kernel_OnlyAdmin(address caller_);\n\n    /**\n     * @dev Thrown when attempting to install a module with a 5-character keycode\n     *      that is already in use by another module.\n     *\n     * @param module_ Keycode for the module that is already in use.\n     */\n    error Kernel_ModuleAlreadyInstalled(Keycode module_);\n\n    /**\n     * @dev Thrown when an upgrade for a module is invalid. This can occur for two\n     *      reasons: either the keycode to upgrade never had a module installed using it\n     *      in the first place, or the module address to upgrade to is the same address\n     *      as the previous module.\n     *\n     * @param module_ keycode for the module to upgrade.\n     */\n    error Kernel_InvalidModuleUpgrade(Keycode module_);\n\n    /**\n     * @dev Thrown when attempting to activate a policy that has already been activated.\n     *      This action cannot be done more than once on a single policy, unless it is\n     *      deactivated first.\n     *\n     * @param policy_ Address of the policy contract attempting the activation.\n     */\n    error Kernel_PolicyAlreadyApproved(address policy_);\n\n    /**\n     * @dev Thrown when attempting to deactivate a policy that has either already been\n     *      deactivated or was never activated in the first place.\n     *\n     * @param policy_ Address of the policy contract attempting the deactivation.\n     */\n    error Kernel_PolicyNotApproved(address policy_);\n\n    /**\n     * @dev Thrown when attempting to grant a role to an address that has already been\n     *      granted that role.\n     *\n     * @param addr_ Address receiving the role.\n     * @param role_ Role to grant to the target address.\n     */\n    error Kernel_AddressAlreadyHasRole(address addr_, Role role_);\n\n    /**\n     * @dev Thrown when attempting to revoke a role from an address that has either\n     *      already had the role revoked or was never granted the role in the first place.\n     *\n     * @param addr_ Address giving up the role.\n     * @param role_ Role to revoke from the target address.\n     */\n    error Kernel_AddressDoesNotHaveRole(address addr_, Role role_);\n\n    /**\n     * @dev Thrown when attempting to revoke a role that has never been granted to\n     *      any address.\n     *\n     * @param role_ Role which has never been granted.\n     */\n    error Kernel_RoleDoesNotExist(Role role_);\n\n    /**\n     * @dev Thrown when the target is not a contract\n     *\n     * @param target_ The address to check if it is a contract.\n     */\n    error Kernel_TargetNotAContract(address target_);\n\n    /**\n     * @dev Thrown when the keycode provided is invalid.\n     *\n     * @param keycode_ The five character keycode to check.\n     */\n    error Kernel_InvalidKeycode(Keycode keycode_);\n\n    /**\n     *\n     * @dev Thrown when the role provided is invalid.\n     *\n     * @param role_ The role to check.\n     */\n    error Kernel_InvalidRole(Role role_);\n}\n"
      },
      "src/libraries/KernelUtils.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {Errors} from \"@src/libraries/Errors.sol\";\nimport {Keycode, Role} from \"@src/libraries/RentalStructs.sol\";\n\n/**\n * @dev Converts a bytes5 value into a `Keycode` type.\n *\n * @param keycode_ The value to convert into a `Keycode`.\n */\nfunction toKeycode(bytes5 keycode_) pure returns (Keycode) {\n    return Keycode.wrap(keycode_);\n}\n\n/**\n * @dev Converts a `Keycode` into a bytes5 type.\n *\n * @param keycode_ The value to convert into a bytes5.\n */\nfunction fromKeycode(Keycode keycode_) pure returns (bytes5) {\n    return Keycode.unwrap(keycode_);\n}\n\n/**\n * @dev Converts a bytes32 value into a `Role` type.\n *\n * @param role_ The value to convert into a `Role`.\n */\nfunction toRole(bytes32 role_) pure returns (Role) {\n    return Role.wrap(role_);\n}\n\n/**\n * @dev Converts a `Role` into a bytes32 value.\n *\n * @param role_ The value to convert into a bytes32.\n */\nfunction fromRole(Role role_) pure returns (bytes32) {\n    return Role.unwrap(role_);\n}\n\n/**\n * @dev Ensures the target address is a contract. This is done by checking the length\n *      of the bytecode stored at that address. Note: This function will be used to set\n *      official protocol contracts so it is a highly unlikely situation where the code\n *      size check is performed while the `target_` address is inside its constructor.\n *\n * @param target_ Address to check the bytecode size.\n */\nfunction ensureContract(address target_) view {\n    uint256 size;\n    assembly (\"memory-safe\") {\n        size := extcodesize(target_)\n    }\n    if (size == 0) revert Errors.Kernel_TargetNotAContract(target_);\n}\n\n/**\n * @dev Ensures a `Keycode` is properly formatted. Keycodes can only be made up of\n *      letters A-Z, must be capitalized, and can only be 5 letters long.\n *\n * @param keycode_ The keycode to check the validity of.\n */\nfunction ensureValidKeycode(Keycode keycode_) pure {\n    bytes5 unwrapped = Keycode.unwrap(keycode_);\n\n    for (uint256 i = 0; i < 5; ++i) {\n        bytes1 char = unwrapped[i];\n\n        if (char < 0x41 || char > 0x5A) revert Errors.Kernel_InvalidKeycode(keycode_);\n    }\n}\n\n/**\n * @dev Ensures a `Role` is properly formatted. Roles can only be made up of\n *      letters A-Z, must be capitalized, but with the exception that underscores\n *      are allowed.\n *\n * @param role_ The role to check the validity of.\n */\nfunction ensureValidRole(Role role_) pure {\n    bytes32 unwrapped = Role.unwrap(role_);\n\n    for (uint256 i = 0; i < 32; ++i) {\n        bytes1 char = unwrapped[i];\n        if ((char < 0x41 || char > 0x5A) && char != 0x5F && char != 0x00) {\n            revert Errors.Kernel_InvalidRole(role_); // A-Z only, allow underscores\n        }\n    }\n}\n"
      },
      "src/libraries/Events.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {\n    Hook,\n    Item,\n    OrderType,\n    Role,\n    Keycode,\n    Actions\n} from \"@src/libraries/RentalStructs.sol\";\nimport {Policy} from \"@src/Kernel.sol\";\n\n/**\n * @title Events\n * @notice Contains events defined for the protocol.\n */\nlibrary Events {\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                 Create Policy                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Emitted when a new rental order is started. PAYEE orders are excluded from\n     *      emitting this event.\n     *\n     * @param orderHash        Hash of the rental order struct.\n     * @param emittedExtraData Data passed to the order to be emitted as an event.\n     * @param seaportOrderHash Order hash of the seaport order struct.\n     * @param items            Items in the rental order.\n     * @param hooks            Hooks defined for the rental order.\n     * @param orderType        Order type of the rental.\n     * @param lender           Lender EOA of the assets in the order.\n     * @param renter           Renter EOA of the assets in the order.\n     * @param rentalWallet     Wallet contract which holds the rented assets.\n     * @param startTimestamp   Timestamp which marks the start of the rental.\n     * @param endTimestamp     Timestamp which marks the end of the rental.\n     */\n    event RentalOrderStarted(\n        bytes32 orderHash,\n        bytes emittedExtraData,\n        bytes32 seaportOrderHash,\n        Item[] items,\n        Hook[] hooks,\n        OrderType orderType,\n        address indexed lender,\n        address indexed renter,\n        address rentalWallet,\n        uint256 startTimestamp,\n        uint256 endTimestamp\n    );\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                  Stop Policy                                //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Emitted when a rental order is stopped.\n     *\n     * @param seaportOrderHash Order hash of the seaport order struct.\n     * @param stopper          Address which initated the stopping of the rental.\n     */\n    event RentalOrderStopped(bytes32 seaportOrderHash, address stopper);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                Factory Policy                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Emitted when a rental safe is deployed.\n     *\n     * @param safe      Address of the newly deployed rental safe contract.\n     * @param owners    Owner addresses of the rental safe.\n     * @param threshold Number of owners required to sign a transaction to execute it.\n     */\n    event RentalSafeDeployment(address safe, address[] owners, uint256 threshold);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            Payment Escrow Module                            //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Emitted when a fee is taken.\n     *\n     * @param token     Token address that the fee is denominated in.\n     * @param amount    Amount of the fee taken.\n     */\n    event FeeTaken(address token, uint256 amount);\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                                  Kernel                                     //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Emitted when the permissions change for a policy. This occurs either when\n     *      the policy has been activated or when it has been deactivated.\n     *\n     * @param keycode_      Keycode representing a module.\n     * @param policy_       Address of the policy contract.\n     * @param funcSelector_ Function selector of the module.\n     * @param granted_      Whether permission to access has been granted or revoked.\n     */\n    event PermissionsUpdated(\n        Keycode indexed keycode_,\n        Policy indexed policy_,\n        bytes4 funcSelector_,\n        bool granted_\n    );\n\n    /**\n     * @dev Emitted when an address has been granted a role.\n     *\n     * @param role_ The role being granted.\n     * @param addr_ The address receiving the role.\n     */\n    event RoleGranted(Role indexed role_, address indexed addr_);\n\n    /**\n     * @dev Emitted when an address has a role revoked from it.\n     *\n     * @param role_ The role being revoked.\n     * @param addr_ The address which has its role revoked.\n     */\n    event RoleRevoked(Role indexed role_, address indexed addr_);\n\n    /**\n     * @dev Emitted when an action has been executed on the kernel.\n     *\n     * @param action_ The action which was executed.\n     * @param target_ The target address for the action.\n     */\n    event ActionExecuted(Actions indexed action_, address indexed target_);\n}\n"
      },
      "lib/seaport-types/src/lib/ConsiderationStructs.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {\n    BasicOrderType,\n    ItemType,\n    OrderType,\n    Side\n} from \"./ConsiderationEnums.sol\";\n\nimport {\n    CalldataPointer,\n    MemoryPointer\n} from \"../helpers/PointerLibraries.sol\";\n\n/**\n * @dev An order contains eleven components: an offerer, a zone (or account that\n *      can cancel the order or restrict who can fulfill the order depending on\n *      the type), the order type (specifying partial fill support as well as\n *      restricted order status), the start and end time, a hash that will be\n *      provided to the zone when validating restricted orders, a salt, a key\n *      corresponding to a given conduit, a counter, and an arbitrary number of\n *      offer items that can be spent along with consideration items that must\n *      be received by their respective recipient.\n */\nstruct OrderComponents {\n    address offerer;\n    address zone;\n    OfferItem[] offer;\n    ConsiderationItem[] consideration;\n    OrderType orderType;\n    uint256 startTime;\n    uint256 endTime;\n    bytes32 zoneHash;\n    uint256 salt;\n    bytes32 conduitKey;\n    uint256 counter;\n}\n\n/**\n * @dev An offer item has five components: an item type (ETH or other native\n *      tokens, ERC20, ERC721, and ERC1155, as well as criteria-based ERC721 and\n *      ERC1155), a token address, a dual-purpose \"identifierOrCriteria\"\n *      component that will either represent a tokenId or a merkle root\n *      depending on the item type, and a start and end amount that support\n *      increasing or decreasing amounts over the duration of the respective\n *      order.\n */\nstruct OfferItem {\n    ItemType itemType;\n    address token;\n    uint256 identifierOrCriteria;\n    uint256 startAmount;\n    uint256 endAmount;\n}\n\n/**\n * @dev A consideration item has the same five components as an offer item and\n *      an additional sixth component designating the required recipient of the\n *      item.\n */\nstruct ConsiderationItem {\n    ItemType itemType;\n    address token;\n    uint256 identifierOrCriteria;\n    uint256 startAmount;\n    uint256 endAmount;\n    address payable recipient;\n}\n\n/**\n * @dev A spent item is translated from a utilized offer item and has four\n *      components: an item type (ETH or other native tokens, ERC20, ERC721, and\n *      ERC1155), a token address, a tokenId, and an amount.\n */\nstruct SpentItem {\n    ItemType itemType;\n    address token;\n    uint256 identifier;\n    uint256 amount;\n}\n\n/**\n * @dev A received item is translated from a utilized consideration item and has\n *      the same four components as a spent item, as well as an additional fifth\n *      component designating the required recipient of the item.\n */\nstruct ReceivedItem {\n    ItemType itemType;\n    address token;\n    uint256 identifier;\n    uint256 amount;\n    address payable recipient;\n}\n\n/**\n * @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155\n *      matching, a group of six functions may be called that only requires a\n *      subset of the usual order arguments. Note the use of a \"basicOrderType\"\n *      enum; this represents both the usual order type as well as the \"route\"\n *      of the basic order (a simple derivation function for the basic order\n *      type is `basicOrderType = orderType + (4 * basicOrderRoute)`.)\n */\nstruct BasicOrderParameters {\n    // calldata offset\n    address considerationToken; // 0x24\n    uint256 considerationIdentifier; // 0x44\n    uint256 considerationAmount; // 0x64\n    address payable offerer; // 0x84\n    address zone; // 0xa4\n    address offerToken; // 0xc4\n    uint256 offerIdentifier; // 0xe4\n    uint256 offerAmount; // 0x104\n    BasicOrderType basicOrderType; // 0x124\n    uint256 startTime; // 0x144\n    uint256 endTime; // 0x164\n    bytes32 zoneHash; // 0x184\n    uint256 salt; // 0x1a4\n    bytes32 offererConduitKey; // 0x1c4\n    bytes32 fulfillerConduitKey; // 0x1e4\n    uint256 totalOriginalAdditionalRecipients; // 0x204\n    AdditionalRecipient[] additionalRecipients; // 0x224\n    bytes signature; // 0x244\n    // Total length, excluding dynamic array data: 0x264 (580)\n}\n\n/**\n * @dev Basic orders can supply any number of additional recipients, with the\n *      implied assumption that they are supplied from the offered ETH (or other\n *      native token) or ERC20 token for the order.\n */\nstruct AdditionalRecipient {\n    uint256 amount;\n    address payable recipient;\n}\n\n/**\n * @dev The full set of order components, with the exception of the counter,\n *      must be supplied when fulfilling more sophisticated orders or groups of\n *      orders. The total number of original consideration items must also be\n *      supplied, as the caller may specify additional consideration items.\n */\nstruct OrderParameters {\n    address offerer; // 0x00\n    address zone; // 0x20\n    OfferItem[] offer; // 0x40\n    ConsiderationItem[] consideration; // 0x60\n    OrderType orderType; // 0x80\n    uint256 startTime; // 0xa0\n    uint256 endTime; // 0xc0\n    bytes32 zoneHash; // 0xe0\n    uint256 salt; // 0x100\n    bytes32 conduitKey; // 0x120\n    uint256 totalOriginalConsiderationItems; // 0x140\n    // offer.length                          // 0x160\n}\n\n/**\n * @dev Orders require a signature in addition to the other order parameters.\n */\nstruct Order {\n    OrderParameters parameters;\n    bytes signature;\n}\n\n/**\n * @dev Advanced orders include a numerator (i.e. a fraction to attempt to fill)\n *      and a denominator (the total size of the order) in addition to the\n *      signature and other order parameters. It also supports an optional field\n *      for supplying extra data; this data will be provided to the zone if the\n *      order type is restricted and the zone is not the caller, or will be\n *      provided to the offerer as context for contract order types.\n */\nstruct AdvancedOrder {\n    OrderParameters parameters;\n    uint120 numerator;\n    uint120 denominator;\n    bytes signature;\n    bytes extraData;\n}\n\n/**\n * @dev Orders can be validated (either explicitly via `validate`, or as a\n *      consequence of a full or partial fill), specifically cancelled (they can\n *      also be cancelled in bulk via incrementing a per-zone counter), and\n *      partially or fully filled (with the fraction filled represented by a\n *      numerator and denominator).\n */\nstruct OrderStatus {\n    bool isValidated;\n    bool isCancelled;\n    uint120 numerator;\n    uint120 denominator;\n}\n\n/**\n * @dev A criteria resolver specifies an order, side (offer vs. consideration),\n *      and item index. It then provides a chosen identifier (i.e. tokenId)\n *      alongside a merkle proof demonstrating the identifier meets the required\n *      criteria.\n */\nstruct CriteriaResolver {\n    uint256 orderIndex;\n    Side side;\n    uint256 index;\n    uint256 identifier;\n    bytes32[] criteriaProof;\n}\n\n/**\n * @dev A fulfillment is applied to a group of orders. It decrements a series of\n *      offer and consideration items, then generates a single execution\n *      element. A given fulfillment can be applied to as many offer and\n *      consideration items as desired, but must contain at least one offer and\n *      at least one consideration that match. The fulfillment must also remain\n *      consistent on all key parameters across all offer items (same offerer,\n *      token, type, tokenId, and conduit preference) as well as across all\n *      consideration items (token, type, tokenId, and recipient).\n */\nstruct Fulfillment {\n    FulfillmentComponent[] offerComponents;\n    FulfillmentComponent[] considerationComponents;\n}\n\n/**\n * @dev Each fulfillment component contains one index referencing a specific\n *      order and another referencing a specific offer or consideration item.\n */\nstruct FulfillmentComponent {\n    uint256 orderIndex;\n    uint256 itemIndex;\n}\n\n/**\n * @dev An execution is triggered once all consideration items have been zeroed\n *      out. It sends the item in question from the offerer to the item's\n *      recipient, optionally sourcing approvals from either this contract\n *      directly or from the offerer's chosen conduit if one is specified. An\n *      execution is not provided as an argument, but rather is derived via\n *      orders, criteria resolvers, and fulfillments (where the total number of\n *      executions will be less than or equal to the total number of indicated\n *      fulfillments) and returned as part of `matchOrders`.\n */\nstruct Execution {\n    ReceivedItem item;\n    address offerer;\n    bytes32 conduitKey;\n}\n\n/**\n * @dev Restricted orders are validated post-execution by calling validateOrder\n *      on the zone. This struct provides context about the order fulfillment\n *      and any supplied extraData, as well as all order hashes fulfilled in a\n *      call to a match or fulfillAvailable method.\n */\nstruct ZoneParameters {\n    bytes32 orderHash;\n    address fulfiller;\n    address offerer;\n    SpentItem[] offer;\n    ReceivedItem[] consideration;\n    bytes extraData;\n    bytes32[] orderHashes;\n    uint256 startTime;\n    uint256 endTime;\n    bytes32 zoneHash;\n}\n\n/**\n * @dev Zones and contract offerers can communicate which schemas they implement\n *      along with any associated metadata related to each schema.\n */\nstruct Schema {\n    uint256 id;\n    bytes metadata;\n}\n\nusing StructPointers for OrderComponents global;\nusing StructPointers for OfferItem global;\nusing StructPointers for ConsiderationItem global;\nusing StructPointers for SpentItem global;\nusing StructPointers for ReceivedItem global;\nusing StructPointers for BasicOrderParameters global;\nusing StructPointers for AdditionalRecipient global;\nusing StructPointers for OrderParameters global;\nusing StructPointers for Order global;\nusing StructPointers for AdvancedOrder global;\nusing StructPointers for OrderStatus global;\nusing StructPointers for CriteriaResolver global;\nusing StructPointers for Fulfillment global;\nusing StructPointers for FulfillmentComponent global;\nusing StructPointers for Execution global;\nusing StructPointers for ZoneParameters global;\n\n/**\n * @dev This library provides a set of functions for converting structs to\n *      pointers.\n */\nlibrary StructPointers {\n    /**\n     * @dev Get a MemoryPointer from OrderComponents.\n     *\n     * @param obj The OrderComponents object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        OrderComponents memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from OrderComponents.\n     *\n     * @param obj The OrderComponents object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        OrderComponents calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from OfferItem.\n     *\n     * @param obj The OfferItem object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        OfferItem memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from OfferItem.\n     *\n     * @param obj The OfferItem object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        OfferItem calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from ConsiderationItem.\n     *\n     * @param obj The ConsiderationItem object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        ConsiderationItem memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from ConsiderationItem.\n     *\n     * @param obj The ConsiderationItem object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        ConsiderationItem calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from SpentItem.\n     *\n     * @param obj The SpentItem object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        SpentItem memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from SpentItem.\n     *\n     * @param obj The SpentItem object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        SpentItem calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from ReceivedItem.\n     *\n     * @param obj The ReceivedItem object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        ReceivedItem memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from ReceivedItem.\n     *\n     * @param obj The ReceivedItem object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        ReceivedItem calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from BasicOrderParameters.\n     *\n     * @param obj The BasicOrderParameters object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        BasicOrderParameters memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from BasicOrderParameters.\n     *\n     * @param obj The BasicOrderParameters object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        BasicOrderParameters calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from AdditionalRecipient.\n     *\n     * @param obj The AdditionalRecipient object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        AdditionalRecipient memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from AdditionalRecipient.\n     *\n     * @param obj The AdditionalRecipient object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        AdditionalRecipient calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from OrderParameters.\n     *\n     * @param obj The OrderParameters object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        OrderParameters memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from OrderParameters.\n     *\n     * @param obj The OrderParameters object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        OrderParameters calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from Order.\n     *\n     * @param obj The Order object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        Order memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from Order.\n     *\n     * @param obj The Order object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        Order calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from AdvancedOrder.\n     *\n     * @param obj The AdvancedOrder object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        AdvancedOrder memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from AdvancedOrder.\n     *\n     * @param obj The AdvancedOrder object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        AdvancedOrder calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from OrderStatus.\n     *\n     * @param obj The OrderStatus object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        OrderStatus memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from OrderStatus.\n     *\n     * @param obj The OrderStatus object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        OrderStatus calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from CriteriaResolver.\n     *\n     * @param obj The CriteriaResolver object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        CriteriaResolver memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from CriteriaResolver.\n     *\n     * @param obj The CriteriaResolver object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        CriteriaResolver calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from Fulfillment.\n     *\n     * @param obj The Fulfillment object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        Fulfillment memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from Fulfillment.\n     *\n     * @param obj The Fulfillment object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        Fulfillment calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from FulfillmentComponent.\n     *\n     * @param obj The FulfillmentComponent object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        FulfillmentComponent memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from FulfillmentComponent.\n     *\n     * @param obj The FulfillmentComponent object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        FulfillmentComponent calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from Execution.\n     *\n     * @param obj The Execution object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        Execution memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from Execution.\n     *\n     * @param obj The Execution object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        Execution calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a MemoryPointer from ZoneParameters.\n     *\n     * @param obj The ZoneParameters object.\n     *\n     * @return ptr The MemoryPointer.\n     */\n    function toMemoryPointer(\n        ZoneParameters memory obj\n    ) internal pure returns (MemoryPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n\n    /**\n     * @dev Get a CalldataPointer from ZoneParameters.\n     *\n     * @param obj The ZoneParameters object.\n     *\n     * @return ptr The CalldataPointer.\n     */\n    function toCalldataPointer(\n        ZoneParameters calldata obj\n    ) internal pure returns (CalldataPointer ptr) {\n        assembly {\n            ptr := obj\n        }\n    }\n}\n"
      },
      "lib/seaport-types/src/lib/ConsiderationEnums.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nenum OrderType {\n    // 0: no partial fills, anyone can execute\n    FULL_OPEN,\n\n    // 1: partial fills supported, anyone can execute\n    PARTIAL_OPEN,\n\n    // 2: no partial fills, only offerer or zone can execute\n    FULL_RESTRICTED,\n\n    // 3: partial fills supported, only offerer or zone can execute\n    PARTIAL_RESTRICTED,\n\n    // 4: contract order type\n    CONTRACT\n}\n\nenum BasicOrderType {\n    // 0: no partial fills, anyone can execute\n    ETH_TO_ERC721_FULL_OPEN,\n\n    // 1: partial fills supported, anyone can execute\n    ETH_TO_ERC721_PARTIAL_OPEN,\n\n    // 2: no partial fills, only offerer or zone can execute\n    ETH_TO_ERC721_FULL_RESTRICTED,\n\n    // 3: partial fills supported, only offerer or zone can execute\n    ETH_TO_ERC721_PARTIAL_RESTRICTED,\n\n    // 4: no partial fills, anyone can execute\n    ETH_TO_ERC1155_FULL_OPEN,\n\n    // 5: partial fills supported, anyone can execute\n    ETH_TO_ERC1155_PARTIAL_OPEN,\n\n    // 6: no partial fills, only offerer or zone can execute\n    ETH_TO_ERC1155_FULL_RESTRICTED,\n\n    // 7: partial fills supported, only offerer or zone can execute\n    ETH_TO_ERC1155_PARTIAL_RESTRICTED,\n\n    // 8: no partial fills, anyone can execute\n    ERC20_TO_ERC721_FULL_OPEN,\n\n    // 9: partial fills supported, anyone can execute\n    ERC20_TO_ERC721_PARTIAL_OPEN,\n\n    // 10: no partial fills, only offerer or zone can execute\n    ERC20_TO_ERC721_FULL_RESTRICTED,\n\n    // 11: partial fills supported, only offerer or zone can execute\n    ERC20_TO_ERC721_PARTIAL_RESTRICTED,\n\n    // 12: no partial fills, anyone can execute\n    ERC20_TO_ERC1155_FULL_OPEN,\n\n    // 13: partial fills supported, anyone can execute\n    ERC20_TO_ERC1155_PARTIAL_OPEN,\n\n    // 14: no partial fills, only offerer or zone can execute\n    ERC20_TO_ERC1155_FULL_RESTRICTED,\n\n    // 15: partial fills supported, only offerer or zone can execute\n    ERC20_TO_ERC1155_PARTIAL_RESTRICTED,\n\n    // 16: no partial fills, anyone can execute\n    ERC721_TO_ERC20_FULL_OPEN,\n\n    // 17: partial fills supported, anyone can execute\n    ERC721_TO_ERC20_PARTIAL_OPEN,\n\n    // 18: no partial fills, only offerer or zone can execute\n    ERC721_TO_ERC20_FULL_RESTRICTED,\n\n    // 19: partial fills supported, only offerer or zone can execute\n    ERC721_TO_ERC20_PARTIAL_RESTRICTED,\n\n    // 20: no partial fills, anyone can execute\n    ERC1155_TO_ERC20_FULL_OPEN,\n\n    // 21: partial fills supported, anyone can execute\n    ERC1155_TO_ERC20_PARTIAL_OPEN,\n\n    // 22: no partial fills, only offerer or zone can execute\n    ERC1155_TO_ERC20_FULL_RESTRICTED,\n\n    // 23: partial fills supported, only offerer or zone can execute\n    ERC1155_TO_ERC20_PARTIAL_RESTRICTED\n}\n\nenum BasicOrderRouteType {\n    // 0: provide Ether (or other native token) to receive offered ERC721 item.\n    ETH_TO_ERC721,\n\n    // 1: provide Ether (or other native token) to receive offered ERC1155 item.\n    ETH_TO_ERC1155,\n\n    // 2: provide ERC20 item to receive offered ERC721 item.\n    ERC20_TO_ERC721,\n\n    // 3: provide ERC20 item to receive offered ERC1155 item.\n    ERC20_TO_ERC1155,\n\n    // 4: provide ERC721 item to receive offered ERC20 item.\n    ERC721_TO_ERC20,\n\n    // 5: provide ERC1155 item to receive offered ERC20 item.\n    ERC1155_TO_ERC20\n}\n\nenum ItemType {\n    // 0: ETH on mainnet, MATIC on polygon, etc.\n    NATIVE,\n\n    // 1: ERC20 items (ERC777 and ERC20 analogues could also technically work)\n    ERC20,\n\n    // 2: ERC721 items\n    ERC721,\n\n    // 3: ERC1155 items\n    ERC1155,\n\n    // 4: ERC721 items where a number of tokenIds are supported\n    ERC721_WITH_CRITERIA,\n\n    // 5: ERC1155 items where a number of ids are supported\n    ERC1155_WITH_CRITERIA\n}\n\nenum Side {\n    // 0: Items that can be spent\n    OFFER,\n\n    // 1: Items that must be received\n    CONSIDERATION\n}\n"
      },
      "lib/seaport-types/src/helpers/PointerLibraries.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\ntype CalldataPointer is uint256;\n\ntype ReturndataPointer is uint256;\n\ntype MemoryPointer is uint256;\n\nusing CalldataPointerLib for CalldataPointer global;\nusing MemoryPointerLib for MemoryPointer global;\nusing ReturndataPointerLib for ReturndataPointer global;\n\nusing CalldataReaders for CalldataPointer global;\nusing ReturndataReaders for ReturndataPointer global;\nusing MemoryReaders for MemoryPointer global;\nusing MemoryWriters for MemoryPointer global;\n\nCalldataPointer constant CalldataStart = CalldataPointer.wrap(0x04);\nMemoryPointer constant FreeMemoryPPtr = MemoryPointer.wrap(0x40);\nuint256 constant IdentityPrecompileAddress = 0x4;\nuint256 constant OffsetOrLengthMask = 0xffffffff;\nuint256 constant _OneWord = 0x20;\nuint256 constant _FreeMemoryPointerSlot = 0x40;\n\n/// @dev Allocates `size` bytes in memory by increasing the free memory pointer\n///    and returns the memory pointer to the first byte of the allocated region.\n// (Free functions cannot have visibility.)\n// solhint-disable-next-line func-visibility\nfunction malloc(uint256 size) pure returns (MemoryPointer mPtr) {\n    assembly {\n        mPtr := mload(_FreeMemoryPointerSlot)\n        mstore(_FreeMemoryPointerSlot, add(mPtr, size))\n    }\n}\n\n// (Free functions cannot have visibility.)\n// solhint-disable-next-line func-visibility\nfunction getFreeMemoryPointer() pure returns (MemoryPointer mPtr) {\n    mPtr = FreeMemoryPPtr.readMemoryPointer();\n}\n\n// (Free functions cannot have visibility.)\n// solhint-disable-next-line func-visibility\nfunction setFreeMemoryPointer(MemoryPointer mPtr) pure {\n    FreeMemoryPPtr.write(mPtr);\n}\n\nlibrary CalldataPointerLib {\n    function lt(\n        CalldataPointer a,\n        CalldataPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := lt(a, b)\n        }\n    }\n\n    function gt(\n        CalldataPointer a,\n        CalldataPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := gt(a, b)\n        }\n    }\n\n    function eq(\n        CalldataPointer a,\n        CalldataPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := eq(a, b)\n        }\n    }\n\n    function isNull(CalldataPointer a) internal pure returns (bool b) {\n        assembly {\n            b := iszero(a)\n        }\n    }\n\n    /// @dev Resolves an offset stored at `cdPtr + headOffset` to a calldata.\n    ///      pointer `cdPtr` must point to some parent object with a dynamic\n    ///      type's head stored at `cdPtr + headOffset`.\n    function pptr(\n        CalldataPointer cdPtr,\n        uint256 headOffset\n    ) internal pure returns (CalldataPointer cdPtrChild) {\n        cdPtrChild = cdPtr.offset(\n            cdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask\n        );\n    }\n\n    /// @dev Resolves an offset stored at `cdPtr` to a calldata pointer.\n    ///      `cdPtr` must point to some parent object with a dynamic type as its\n    ///      first member, e.g. `struct { bytes data; }`\n    function pptr(\n        CalldataPointer cdPtr\n    ) internal pure returns (CalldataPointer cdPtrChild) {\n        cdPtrChild = cdPtr.offset(cdPtr.readUint256() & OffsetOrLengthMask);\n    }\n\n    /// @dev Returns the calldata pointer one word after `cdPtr`.\n    function next(\n        CalldataPointer cdPtr\n    ) internal pure returns (CalldataPointer cdPtrNext) {\n        assembly {\n            cdPtrNext := add(cdPtr, _OneWord)\n        }\n    }\n\n    /// @dev Returns the calldata pointer `_offset` bytes after `cdPtr`.\n    function offset(\n        CalldataPointer cdPtr,\n        uint256 _offset\n    ) internal pure returns (CalldataPointer cdPtrNext) {\n        assembly {\n            cdPtrNext := add(cdPtr, _offset)\n        }\n    }\n\n    /// @dev Copies `size` bytes from calldata starting at `src` to memory at\n    ///      `dst`.\n    function copy(\n        CalldataPointer src,\n        MemoryPointer dst,\n        uint256 size\n    ) internal pure {\n        assembly {\n            calldatacopy(dst, src, size)\n        }\n    }\n}\n\nlibrary ReturndataPointerLib {\n    function lt(\n        ReturndataPointer a,\n        ReturndataPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := lt(a, b)\n        }\n    }\n\n    function gt(\n        ReturndataPointer a,\n        ReturndataPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := gt(a, b)\n        }\n    }\n\n    function eq(\n        ReturndataPointer a,\n        ReturndataPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := eq(a, b)\n        }\n    }\n\n    function isNull(ReturndataPointer a) internal pure returns (bool b) {\n        assembly {\n            b := iszero(a)\n        }\n    }\n\n    /// @dev Resolves an offset stored at `rdPtr + headOffset` to a returndata\n    ///      pointer. `rdPtr` must point to some parent object with a dynamic\n    ///      type's head stored at `rdPtr + headOffset`.\n    function pptr(\n        ReturndataPointer rdPtr,\n        uint256 headOffset\n    ) internal pure returns (ReturndataPointer rdPtrChild) {\n        rdPtrChild = rdPtr.offset(\n            rdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask\n        );\n    }\n\n    /// @dev Resolves an offset stored at `rdPtr` to a returndata pointer.\n    ///    `rdPtr` must point to some parent object with a dynamic type as its\n    ///    first member, e.g. `struct { bytes data; }`\n    function pptr(\n        ReturndataPointer rdPtr\n    ) internal pure returns (ReturndataPointer rdPtrChild) {\n        rdPtrChild = rdPtr.offset(rdPtr.readUint256() & OffsetOrLengthMask);\n    }\n\n    /// @dev Returns the returndata pointer one word after `cdPtr`.\n    function next(\n        ReturndataPointer rdPtr\n    ) internal pure returns (ReturndataPointer rdPtrNext) {\n        assembly {\n            rdPtrNext := add(rdPtr, _OneWord)\n        }\n    }\n\n    /// @dev Returns the returndata pointer `_offset` bytes after `cdPtr`.\n    function offset(\n        ReturndataPointer rdPtr,\n        uint256 _offset\n    ) internal pure returns (ReturndataPointer rdPtrNext) {\n        assembly {\n            rdPtrNext := add(rdPtr, _offset)\n        }\n    }\n\n    /// @dev Copies `size` bytes from returndata starting at `src` to memory at\n    /// `dst`.\n    function copy(\n        ReturndataPointer src,\n        MemoryPointer dst,\n        uint256 size\n    ) internal pure {\n        assembly {\n            returndatacopy(dst, src, size)\n        }\n    }\n}\n\nlibrary MemoryPointerLib {\n    function copy(\n        MemoryPointer src,\n        MemoryPointer dst,\n        uint256 size\n    ) internal view {\n        assembly {\n            let success := staticcall(\n                gas(),\n                IdentityPrecompileAddress,\n                src,\n                size,\n                dst,\n                size\n            )\n            if or(iszero(returndatasize()), iszero(success)) {\n                revert(0, 0)\n            }\n        }\n    }\n\n    function lt(\n        MemoryPointer a,\n        MemoryPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := lt(a, b)\n        }\n    }\n\n    function gt(\n        MemoryPointer a,\n        MemoryPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := gt(a, b)\n        }\n    }\n\n    function eq(\n        MemoryPointer a,\n        MemoryPointer b\n    ) internal pure returns (bool c) {\n        assembly {\n            c := eq(a, b)\n        }\n    }\n\n    function isNull(MemoryPointer a) internal pure returns (bool b) {\n        assembly {\n            b := iszero(a)\n        }\n    }\n\n    function hash(\n        MemoryPointer ptr,\n        uint256 length\n    ) internal pure returns (bytes32 _hash) {\n        assembly {\n            _hash := keccak256(ptr, length)\n        }\n    }\n\n    /// @dev Returns the memory pointer one word after `mPtr`.\n    function next(\n        MemoryPointer mPtr\n    ) internal pure returns (MemoryPointer mPtrNext) {\n        assembly {\n            mPtrNext := add(mPtr, _OneWord)\n        }\n    }\n\n    /// @dev Returns the memory pointer `_offset` bytes after `mPtr`.\n    function offset(\n        MemoryPointer mPtr,\n        uint256 _offset\n    ) internal pure returns (MemoryPointer mPtrNext) {\n        assembly {\n            mPtrNext := add(mPtr, _offset)\n        }\n    }\n\n    /// @dev Resolves a pointer at `mPtr + headOffset` to a memory\n    ///    pointer. `mPtr` must point to some parent object with a dynamic\n    ///    type's pointer stored at `mPtr + headOffset`.\n    function pptr(\n        MemoryPointer mPtr,\n        uint256 headOffset\n    ) internal pure returns (MemoryPointer mPtrChild) {\n        mPtrChild = mPtr.offset(headOffset).readMemoryPointer();\n    }\n\n    /// @dev Resolves a pointer stored at `mPtr` to a memory pointer.\n    ///    `mPtr` must point to some parent object with a dynamic type as its\n    ///    first member, e.g. `struct { bytes data; }`\n    function pptr(\n        MemoryPointer mPtr\n    ) internal pure returns (MemoryPointer mPtrChild) {\n        mPtrChild = mPtr.readMemoryPointer();\n    }\n}\n\nlibrary CalldataReaders {\n    /// @dev Reads the value at `cdPtr` and applies a mask to return only the\n    ///    last 4 bytes.\n    function readMaskedUint256(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint256 value) {\n        value = cdPtr.readUint256() & OffsetOrLengthMask;\n    }\n\n    /// @dev Reads the bool at `cdPtr` in calldata.\n    function readBool(\n        CalldataPointer cdPtr\n    ) internal pure returns (bool value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the address at `cdPtr` in calldata.\n    function readAddress(\n        CalldataPointer cdPtr\n    ) internal pure returns (address value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes1 at `cdPtr` in calldata.\n    function readBytes1(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes1 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes2 at `cdPtr` in calldata.\n    function readBytes2(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes2 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes3 at `cdPtr` in calldata.\n    function readBytes3(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes3 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes4 at `cdPtr` in calldata.\n    function readBytes4(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes4 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes5 at `cdPtr` in calldata.\n    function readBytes5(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes5 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes6 at `cdPtr` in calldata.\n    function readBytes6(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes6 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes7 at `cdPtr` in calldata.\n    function readBytes7(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes7 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes8 at `cdPtr` in calldata.\n    function readBytes8(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes8 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes9 at `cdPtr` in calldata.\n    function readBytes9(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes9 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes10 at `cdPtr` in calldata.\n    function readBytes10(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes10 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes11 at `cdPtr` in calldata.\n    function readBytes11(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes11 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes12 at `cdPtr` in calldata.\n    function readBytes12(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes12 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes13 at `cdPtr` in calldata.\n    function readBytes13(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes13 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes14 at `cdPtr` in calldata.\n    function readBytes14(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes14 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes15 at `cdPtr` in calldata.\n    function readBytes15(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes15 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes16 at `cdPtr` in calldata.\n    function readBytes16(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes16 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes17 at `cdPtr` in calldata.\n    function readBytes17(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes17 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes18 at `cdPtr` in calldata.\n    function readBytes18(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes18 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes19 at `cdPtr` in calldata.\n    function readBytes19(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes19 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes20 at `cdPtr` in calldata.\n    function readBytes20(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes20 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes21 at `cdPtr` in calldata.\n    function readBytes21(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes21 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes22 at `cdPtr` in calldata.\n    function readBytes22(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes22 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes23 at `cdPtr` in calldata.\n    function readBytes23(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes23 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes24 at `cdPtr` in calldata.\n    function readBytes24(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes24 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes25 at `cdPtr` in calldata.\n    function readBytes25(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes25 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes26 at `cdPtr` in calldata.\n    function readBytes26(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes26 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes27 at `cdPtr` in calldata.\n    function readBytes27(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes27 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes28 at `cdPtr` in calldata.\n    function readBytes28(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes28 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes29 at `cdPtr` in calldata.\n    function readBytes29(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes29 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes30 at `cdPtr` in calldata.\n    function readBytes30(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes30 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes31 at `cdPtr` in calldata.\n    function readBytes31(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes31 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the bytes32 at `cdPtr` in calldata.\n    function readBytes32(\n        CalldataPointer cdPtr\n    ) internal pure returns (bytes32 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint8 at `cdPtr` in calldata.\n    function readUint8(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint8 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint16 at `cdPtr` in calldata.\n    function readUint16(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint16 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint24 at `cdPtr` in calldata.\n    function readUint24(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint24 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint32 at `cdPtr` in calldata.\n    function readUint32(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint32 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint40 at `cdPtr` in calldata.\n    function readUint40(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint40 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint48 at `cdPtr` in calldata.\n    function readUint48(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint48 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint56 at `cdPtr` in calldata.\n    function readUint56(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint56 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint64 at `cdPtr` in calldata.\n    function readUint64(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint64 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint72 at `cdPtr` in calldata.\n    function readUint72(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint72 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint80 at `cdPtr` in calldata.\n    function readUint80(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint80 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint88 at `cdPtr` in calldata.\n    function readUint88(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint88 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint96 at `cdPtr` in calldata.\n    function readUint96(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint96 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint104 at `cdPtr` in calldata.\n    function readUint104(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint104 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint112 at `cdPtr` in calldata.\n    function readUint112(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint112 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint120 at `cdPtr` in calldata.\n    function readUint120(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint120 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint128 at `cdPtr` in calldata.\n    function readUint128(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint128 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint136 at `cdPtr` in calldata.\n    function readUint136(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint136 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint144 at `cdPtr` in calldata.\n    function readUint144(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint144 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint152 at `cdPtr` in calldata.\n    function readUint152(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint152 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint160 at `cdPtr` in calldata.\n    function readUint160(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint160 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint168 at `cdPtr` in calldata.\n    function readUint168(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint168 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint176 at `cdPtr` in calldata.\n    function readUint176(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint176 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint184 at `cdPtr` in calldata.\n    function readUint184(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint184 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint192 at `cdPtr` in calldata.\n    function readUint192(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint192 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint200 at `cdPtr` in calldata.\n    function readUint200(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint200 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint208 at `cdPtr` in calldata.\n    function readUint208(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint208 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint216 at `cdPtr` in calldata.\n    function readUint216(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint216 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint224 at `cdPtr` in calldata.\n    function readUint224(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint224 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint232 at `cdPtr` in calldata.\n    function readUint232(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint232 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint240 at `cdPtr` in calldata.\n    function readUint240(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint240 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint248 at `cdPtr` in calldata.\n    function readUint248(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint248 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the uint256 at `cdPtr` in calldata.\n    function readUint256(\n        CalldataPointer cdPtr\n    ) internal pure returns (uint256 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int8 at `cdPtr` in calldata.\n    function readInt8(\n        CalldataPointer cdPtr\n    ) internal pure returns (int8 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int16 at `cdPtr` in calldata.\n    function readInt16(\n        CalldataPointer cdPtr\n    ) internal pure returns (int16 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int24 at `cdPtr` in calldata.\n    function readInt24(\n        CalldataPointer cdPtr\n    ) internal pure returns (int24 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int32 at `cdPtr` in calldata.\n    function readInt32(\n        CalldataPointer cdPtr\n    ) internal pure returns (int32 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int40 at `cdPtr` in calldata.\n    function readInt40(\n        CalldataPointer cdPtr\n    ) internal pure returns (int40 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int48 at `cdPtr` in calldata.\n    function readInt48(\n        CalldataPointer cdPtr\n    ) internal pure returns (int48 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int56 at `cdPtr` in calldata.\n    function readInt56(\n        CalldataPointer cdPtr\n    ) internal pure returns (int56 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int64 at `cdPtr` in calldata.\n    function readInt64(\n        CalldataPointer cdPtr\n    ) internal pure returns (int64 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int72 at `cdPtr` in calldata.\n    function readInt72(\n        CalldataPointer cdPtr\n    ) internal pure returns (int72 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int80 at `cdPtr` in calldata.\n    function readInt80(\n        CalldataPointer cdPtr\n    ) internal pure returns (int80 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int88 at `cdPtr` in calldata.\n    function readInt88(\n        CalldataPointer cdPtr\n    ) internal pure returns (int88 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int96 at `cdPtr` in calldata.\n    function readInt96(\n        CalldataPointer cdPtr\n    ) internal pure returns (int96 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int104 at `cdPtr` in calldata.\n    function readInt104(\n        CalldataPointer cdPtr\n    ) internal pure returns (int104 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int112 at `cdPtr` in calldata.\n    function readInt112(\n        CalldataPointer cdPtr\n    ) internal pure returns (int112 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int120 at `cdPtr` in calldata.\n    function readInt120(\n        CalldataPointer cdPtr\n    ) internal pure returns (int120 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int128 at `cdPtr` in calldata.\n    function readInt128(\n        CalldataPointer cdPtr\n    ) internal pure returns (int128 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int136 at `cdPtr` in calldata.\n    function readInt136(\n        CalldataPointer cdPtr\n    ) internal pure returns (int136 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int144 at `cdPtr` in calldata.\n    function readInt144(\n        CalldataPointer cdPtr\n    ) internal pure returns (int144 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int152 at `cdPtr` in calldata.\n    function readInt152(\n        CalldataPointer cdPtr\n    ) internal pure returns (int152 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int160 at `cdPtr` in calldata.\n    function readInt160(\n        CalldataPointer cdPtr\n    ) internal pure returns (int160 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int168 at `cdPtr` in calldata.\n    function readInt168(\n        CalldataPointer cdPtr\n    ) internal pure returns (int168 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int176 at `cdPtr` in calldata.\n    function readInt176(\n        CalldataPointer cdPtr\n    ) internal pure returns (int176 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int184 at `cdPtr` in calldata.\n    function readInt184(\n        CalldataPointer cdPtr\n    ) internal pure returns (int184 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int192 at `cdPtr` in calldata.\n    function readInt192(\n        CalldataPointer cdPtr\n    ) internal pure returns (int192 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int200 at `cdPtr` in calldata.\n    function readInt200(\n        CalldataPointer cdPtr\n    ) internal pure returns (int200 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int208 at `cdPtr` in calldata.\n    function readInt208(\n        CalldataPointer cdPtr\n    ) internal pure returns (int208 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int216 at `cdPtr` in calldata.\n    function readInt216(\n        CalldataPointer cdPtr\n    ) internal pure returns (int216 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int224 at `cdPtr` in calldata.\n    function readInt224(\n        CalldataPointer cdPtr\n    ) internal pure returns (int224 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int232 at `cdPtr` in calldata.\n    function readInt232(\n        CalldataPointer cdPtr\n    ) internal pure returns (int232 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int240 at `cdPtr` in calldata.\n    function readInt240(\n        CalldataPointer cdPtr\n    ) internal pure returns (int240 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int248 at `cdPtr` in calldata.\n    function readInt248(\n        CalldataPointer cdPtr\n    ) internal pure returns (int248 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n\n    /// @dev Reads the int256 at `cdPtr` in calldata.\n    function readInt256(\n        CalldataPointer cdPtr\n    ) internal pure returns (int256 value) {\n        assembly {\n            value := calldataload(cdPtr)\n        }\n    }\n}\n\nlibrary ReturndataReaders {\n    /// @dev Reads value at `rdPtr` & applies a mask to return only last 4 bytes\n    function readMaskedUint256(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint256 value) {\n        value = rdPtr.readUint256() & OffsetOrLengthMask;\n    }\n\n    /// @dev Reads the bool at `rdPtr` in returndata.\n    function readBool(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bool value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the address at `rdPtr` in returndata.\n    function readAddress(\n        ReturndataPointer rdPtr\n    ) internal pure returns (address value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes1 at `rdPtr` in returndata.\n    function readBytes1(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes1 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes2 at `rdPtr` in returndata.\n    function readBytes2(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes2 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes3 at `rdPtr` in returndata.\n    function readBytes3(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes3 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes4 at `rdPtr` in returndata.\n    function readBytes4(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes4 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes5 at `rdPtr` in returndata.\n    function readBytes5(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes5 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes6 at `rdPtr` in returndata.\n    function readBytes6(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes6 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes7 at `rdPtr` in returndata.\n    function readBytes7(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes7 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes8 at `rdPtr` in returndata.\n    function readBytes8(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes8 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes9 at `rdPtr` in returndata.\n    function readBytes9(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes9 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes10 at `rdPtr` in returndata.\n    function readBytes10(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes10 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes11 at `rdPtr` in returndata.\n    function readBytes11(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes11 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes12 at `rdPtr` in returndata.\n    function readBytes12(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes12 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes13 at `rdPtr` in returndata.\n    function readBytes13(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes13 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes14 at `rdPtr` in returndata.\n    function readBytes14(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes14 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes15 at `rdPtr` in returndata.\n    function readBytes15(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes15 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes16 at `rdPtr` in returndata.\n    function readBytes16(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes16 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes17 at `rdPtr` in returndata.\n    function readBytes17(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes17 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes18 at `rdPtr` in returndata.\n    function readBytes18(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes18 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes19 at `rdPtr` in returndata.\n    function readBytes19(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes19 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes20 at `rdPtr` in returndata.\n    function readBytes20(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes20 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes21 at `rdPtr` in returndata.\n    function readBytes21(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes21 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes22 at `rdPtr` in returndata.\n    function readBytes22(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes22 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes23 at `rdPtr` in returndata.\n    function readBytes23(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes23 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes24 at `rdPtr` in returndata.\n    function readBytes24(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes24 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes25 at `rdPtr` in returndata.\n    function readBytes25(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes25 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes26 at `rdPtr` in returndata.\n    function readBytes26(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes26 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes27 at `rdPtr` in returndata.\n    function readBytes27(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes27 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes28 at `rdPtr` in returndata.\n    function readBytes28(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes28 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes29 at `rdPtr` in returndata.\n    function readBytes29(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes29 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes30 at `rdPtr` in returndata.\n    function readBytes30(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes30 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes31 at `rdPtr` in returndata.\n    function readBytes31(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes31 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the bytes32 at `rdPtr` in returndata.\n    function readBytes32(\n        ReturndataPointer rdPtr\n    ) internal pure returns (bytes32 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint8 at `rdPtr` in returndata.\n    function readUint8(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint8 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint16 at `rdPtr` in returndata.\n    function readUint16(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint16 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint24 at `rdPtr` in returndata.\n    function readUint24(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint24 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint32 at `rdPtr` in returndata.\n    function readUint32(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint32 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint40 at `rdPtr` in returndata.\n    function readUint40(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint40 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint48 at `rdPtr` in returndata.\n    function readUint48(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint48 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint56 at `rdPtr` in returndata.\n    function readUint56(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint56 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint64 at `rdPtr` in returndata.\n    function readUint64(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint64 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint72 at `rdPtr` in returndata.\n    function readUint72(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint72 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint80 at `rdPtr` in returndata.\n    function readUint80(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint80 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint88 at `rdPtr` in returndata.\n    function readUint88(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint88 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint96 at `rdPtr` in returndata.\n    function readUint96(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint96 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint104 at `rdPtr` in returndata.\n    function readUint104(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint104 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint112 at `rdPtr` in returndata.\n    function readUint112(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint112 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint120 at `rdPtr` in returndata.\n    function readUint120(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint120 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint128 at `rdPtr` in returndata.\n    function readUint128(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint128 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint136 at `rdPtr` in returndata.\n    function readUint136(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint136 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint144 at `rdPtr` in returndata.\n    function readUint144(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint144 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint152 at `rdPtr` in returndata.\n    function readUint152(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint152 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint160 at `rdPtr` in returndata.\n    function readUint160(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint160 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint168 at `rdPtr` in returndata.\n    function readUint168(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint168 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint176 at `rdPtr` in returndata.\n    function readUint176(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint176 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint184 at `rdPtr` in returndata.\n    function readUint184(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint184 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint192 at `rdPtr` in returndata.\n    function readUint192(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint192 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint200 at `rdPtr` in returndata.\n    function readUint200(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint200 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint208 at `rdPtr` in returndata.\n    function readUint208(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint208 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint216 at `rdPtr` in returndata.\n    function readUint216(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint216 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint224 at `rdPtr` in returndata.\n    function readUint224(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint224 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint232 at `rdPtr` in returndata.\n    function readUint232(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint232 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint240 at `rdPtr` in returndata.\n    function readUint240(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint240 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint248 at `rdPtr` in returndata.\n    function readUint248(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint248 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the uint256 at `rdPtr` in returndata.\n    function readUint256(\n        ReturndataPointer rdPtr\n    ) internal pure returns (uint256 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int8 at `rdPtr` in returndata.\n    function readInt8(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int8 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int16 at `rdPtr` in returndata.\n    function readInt16(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int16 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int24 at `rdPtr` in returndata.\n    function readInt24(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int24 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int32 at `rdPtr` in returndata.\n    function readInt32(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int32 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int40 at `rdPtr` in returndata.\n    function readInt40(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int40 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int48 at `rdPtr` in returndata.\n    function readInt48(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int48 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int56 at `rdPtr` in returndata.\n    function readInt56(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int56 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int64 at `rdPtr` in returndata.\n    function readInt64(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int64 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int72 at `rdPtr` in returndata.\n    function readInt72(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int72 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int80 at `rdPtr` in returndata.\n    function readInt80(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int80 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int88 at `rdPtr` in returndata.\n    function readInt88(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int88 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int96 at `rdPtr` in returndata.\n    function readInt96(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int96 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int104 at `rdPtr` in returndata.\n    function readInt104(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int104 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int112 at `rdPtr` in returndata.\n    function readInt112(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int112 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int120 at `rdPtr` in returndata.\n    function readInt120(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int120 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int128 at `rdPtr` in returndata.\n    function readInt128(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int128 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int136 at `rdPtr` in returndata.\n    function readInt136(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int136 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int144 at `rdPtr` in returndata.\n    function readInt144(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int144 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int152 at `rdPtr` in returndata.\n    function readInt152(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int152 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int160 at `rdPtr` in returndata.\n    function readInt160(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int160 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int168 at `rdPtr` in returndata.\n    function readInt168(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int168 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int176 at `rdPtr` in returndata.\n    function readInt176(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int176 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int184 at `rdPtr` in returndata.\n    function readInt184(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int184 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int192 at `rdPtr` in returndata.\n    function readInt192(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int192 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int200 at `rdPtr` in returndata.\n    function readInt200(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int200 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int208 at `rdPtr` in returndata.\n    function readInt208(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int208 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int216 at `rdPtr` in returndata.\n    function readInt216(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int216 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int224 at `rdPtr` in returndata.\n    function readInt224(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int224 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int232 at `rdPtr` in returndata.\n    function readInt232(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int232 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int240 at `rdPtr` in returndata.\n    function readInt240(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int240 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int248 at `rdPtr` in returndata.\n    function readInt248(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int248 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n\n    /// @dev Reads the int256 at `rdPtr` in returndata.\n    function readInt256(\n        ReturndataPointer rdPtr\n    ) internal pure returns (int256 value) {\n        assembly {\n            returndatacopy(0, rdPtr, _OneWord)\n            value := mload(0)\n        }\n    }\n}\n\nlibrary MemoryReaders {\n    /// @dev Reads the memory pointer at `mPtr` in memory.\n    function readMemoryPointer(\n        MemoryPointer mPtr\n    ) internal pure returns (MemoryPointer value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads value at `mPtr` & applies a mask to return only last 4 bytes\n    function readMaskedUint256(\n        MemoryPointer mPtr\n    ) internal pure returns (uint256 value) {\n        value = mPtr.readUint256() & OffsetOrLengthMask;\n    }\n\n    /// @dev Reads the bool at `mPtr` in memory.\n    function readBool(MemoryPointer mPtr) internal pure returns (bool value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the address at `mPtr` in memory.\n    function readAddress(\n        MemoryPointer mPtr\n    ) internal pure returns (address value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes1 at `mPtr` in memory.\n    function readBytes1(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes1 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes2 at `mPtr` in memory.\n    function readBytes2(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes2 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes3 at `mPtr` in memory.\n    function readBytes3(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes3 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes4 at `mPtr` in memory.\n    function readBytes4(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes4 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes5 at `mPtr` in memory.\n    function readBytes5(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes5 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes6 at `mPtr` in memory.\n    function readBytes6(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes6 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes7 at `mPtr` in memory.\n    function readBytes7(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes7 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes8 at `mPtr` in memory.\n    function readBytes8(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes8 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes9 at `mPtr` in memory.\n    function readBytes9(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes9 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes10 at `mPtr` in memory.\n    function readBytes10(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes10 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes11 at `mPtr` in memory.\n    function readBytes11(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes11 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes12 at `mPtr` in memory.\n    function readBytes12(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes12 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes13 at `mPtr` in memory.\n    function readBytes13(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes13 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes14 at `mPtr` in memory.\n    function readBytes14(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes14 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes15 at `mPtr` in memory.\n    function readBytes15(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes15 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes16 at `mPtr` in memory.\n    function readBytes16(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes16 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes17 at `mPtr` in memory.\n    function readBytes17(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes17 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes18 at `mPtr` in memory.\n    function readBytes18(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes18 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes19 at `mPtr` in memory.\n    function readBytes19(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes19 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes20 at `mPtr` in memory.\n    function readBytes20(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes20 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes21 at `mPtr` in memory.\n    function readBytes21(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes21 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes22 at `mPtr` in memory.\n    function readBytes22(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes22 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes23 at `mPtr` in memory.\n    function readBytes23(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes23 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes24 at `mPtr` in memory.\n    function readBytes24(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes24 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes25 at `mPtr` in memory.\n    function readBytes25(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes25 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes26 at `mPtr` in memory.\n    function readBytes26(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes26 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes27 at `mPtr` in memory.\n    function readBytes27(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes27 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes28 at `mPtr` in memory.\n    function readBytes28(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes28 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes29 at `mPtr` in memory.\n    function readBytes29(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes29 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes30 at `mPtr` in memory.\n    function readBytes30(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes30 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes31 at `mPtr` in memory.\n    function readBytes31(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes31 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the bytes32 at `mPtr` in memory.\n    function readBytes32(\n        MemoryPointer mPtr\n    ) internal pure returns (bytes32 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint8 at `mPtr` in memory.\n    function readUint8(MemoryPointer mPtr) internal pure returns (uint8 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint16 at `mPtr` in memory.\n    function readUint16(\n        MemoryPointer mPtr\n    ) internal pure returns (uint16 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint24 at `mPtr` in memory.\n    function readUint24(\n        MemoryPointer mPtr\n    ) internal pure returns (uint24 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint32 at `mPtr` in memory.\n    function readUint32(\n        MemoryPointer mPtr\n    ) internal pure returns (uint32 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint40 at `mPtr` in memory.\n    function readUint40(\n        MemoryPointer mPtr\n    ) internal pure returns (uint40 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint48 at `mPtr` in memory.\n    function readUint48(\n        MemoryPointer mPtr\n    ) internal pure returns (uint48 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint56 at `mPtr` in memory.\n    function readUint56(\n        MemoryPointer mPtr\n    ) internal pure returns (uint56 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint64 at `mPtr` in memory.\n    function readUint64(\n        MemoryPointer mPtr\n    ) internal pure returns (uint64 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint72 at `mPtr` in memory.\n    function readUint72(\n        MemoryPointer mPtr\n    ) internal pure returns (uint72 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint80 at `mPtr` in memory.\n    function readUint80(\n        MemoryPointer mPtr\n    ) internal pure returns (uint80 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint88 at `mPtr` in memory.\n    function readUint88(\n        MemoryPointer mPtr\n    ) internal pure returns (uint88 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint96 at `mPtr` in memory.\n    function readUint96(\n        MemoryPointer mPtr\n    ) internal pure returns (uint96 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint104 at `mPtr` in memory.\n    function readUint104(\n        MemoryPointer mPtr\n    ) internal pure returns (uint104 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint112 at `mPtr` in memory.\n    function readUint112(\n        MemoryPointer mPtr\n    ) internal pure returns (uint112 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint120 at `mPtr` in memory.\n    function readUint120(\n        MemoryPointer mPtr\n    ) internal pure returns (uint120 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint128 at `mPtr` in memory.\n    function readUint128(\n        MemoryPointer mPtr\n    ) internal pure returns (uint128 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint136 at `mPtr` in memory.\n    function readUint136(\n        MemoryPointer mPtr\n    ) internal pure returns (uint136 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint144 at `mPtr` in memory.\n    function readUint144(\n        MemoryPointer mPtr\n    ) internal pure returns (uint144 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint152 at `mPtr` in memory.\n    function readUint152(\n        MemoryPointer mPtr\n    ) internal pure returns (uint152 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint160 at `mPtr` in memory.\n    function readUint160(\n        MemoryPointer mPtr\n    ) internal pure returns (uint160 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint168 at `mPtr` in memory.\n    function readUint168(\n        MemoryPointer mPtr\n    ) internal pure returns (uint168 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint176 at `mPtr` in memory.\n    function readUint176(\n        MemoryPointer mPtr\n    ) internal pure returns (uint176 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint184 at `mPtr` in memory.\n    function readUint184(\n        MemoryPointer mPtr\n    ) internal pure returns (uint184 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint192 at `mPtr` in memory.\n    function readUint192(\n        MemoryPointer mPtr\n    ) internal pure returns (uint192 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint200 at `mPtr` in memory.\n    function readUint200(\n        MemoryPointer mPtr\n    ) internal pure returns (uint200 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint208 at `mPtr` in memory.\n    function readUint208(\n        MemoryPointer mPtr\n    ) internal pure returns (uint208 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint216 at `mPtr` in memory.\n    function readUint216(\n        MemoryPointer mPtr\n    ) internal pure returns (uint216 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint224 at `mPtr` in memory.\n    function readUint224(\n        MemoryPointer mPtr\n    ) internal pure returns (uint224 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint232 at `mPtr` in memory.\n    function readUint232(\n        MemoryPointer mPtr\n    ) internal pure returns (uint232 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint240 at `mPtr` in memory.\n    function readUint240(\n        MemoryPointer mPtr\n    ) internal pure returns (uint240 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint248 at `mPtr` in memory.\n    function readUint248(\n        MemoryPointer mPtr\n    ) internal pure returns (uint248 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the uint256 at `mPtr` in memory.\n    function readUint256(\n        MemoryPointer mPtr\n    ) internal pure returns (uint256 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int8 at `mPtr` in memory.\n    function readInt8(MemoryPointer mPtr) internal pure returns (int8 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int16 at `mPtr` in memory.\n    function readInt16(MemoryPointer mPtr) internal pure returns (int16 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int24 at `mPtr` in memory.\n    function readInt24(MemoryPointer mPtr) internal pure returns (int24 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int32 at `mPtr` in memory.\n    function readInt32(MemoryPointer mPtr) internal pure returns (int32 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int40 at `mPtr` in memory.\n    function readInt40(MemoryPointer mPtr) internal pure returns (int40 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int48 at `mPtr` in memory.\n    function readInt48(MemoryPointer mPtr) internal pure returns (int48 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int56 at `mPtr` in memory.\n    function readInt56(MemoryPointer mPtr) internal pure returns (int56 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int64 at `mPtr` in memory.\n    function readInt64(MemoryPointer mPtr) internal pure returns (int64 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int72 at `mPtr` in memory.\n    function readInt72(MemoryPointer mPtr) internal pure returns (int72 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int80 at `mPtr` in memory.\n    function readInt80(MemoryPointer mPtr) internal pure returns (int80 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int88 at `mPtr` in memory.\n    function readInt88(MemoryPointer mPtr) internal pure returns (int88 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int96 at `mPtr` in memory.\n    function readInt96(MemoryPointer mPtr) internal pure returns (int96 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int104 at `mPtr` in memory.\n    function readInt104(\n        MemoryPointer mPtr\n    ) internal pure returns (int104 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int112 at `mPtr` in memory.\n    function readInt112(\n        MemoryPointer mPtr\n    ) internal pure returns (int112 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int120 at `mPtr` in memory.\n    function readInt120(\n        MemoryPointer mPtr\n    ) internal pure returns (int120 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int128 at `mPtr` in memory.\n    function readInt128(\n        MemoryPointer mPtr\n    ) internal pure returns (int128 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int136 at `mPtr` in memory.\n    function readInt136(\n        MemoryPointer mPtr\n    ) internal pure returns (int136 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int144 at `mPtr` in memory.\n    function readInt144(\n        MemoryPointer mPtr\n    ) internal pure returns (int144 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int152 at `mPtr` in memory.\n    function readInt152(\n        MemoryPointer mPtr\n    ) internal pure returns (int152 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int160 at `mPtr` in memory.\n    function readInt160(\n        MemoryPointer mPtr\n    ) internal pure returns (int160 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int168 at `mPtr` in memory.\n    function readInt168(\n        MemoryPointer mPtr\n    ) internal pure returns (int168 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int176 at `mPtr` in memory.\n    function readInt176(\n        MemoryPointer mPtr\n    ) internal pure returns (int176 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int184 at `mPtr` in memory.\n    function readInt184(\n        MemoryPointer mPtr\n    ) internal pure returns (int184 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int192 at `mPtr` in memory.\n    function readInt192(\n        MemoryPointer mPtr\n    ) internal pure returns (int192 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int200 at `mPtr` in memory.\n    function readInt200(\n        MemoryPointer mPtr\n    ) internal pure returns (int200 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int208 at `mPtr` in memory.\n    function readInt208(\n        MemoryPointer mPtr\n    ) internal pure returns (int208 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int216 at `mPtr` in memory.\n    function readInt216(\n        MemoryPointer mPtr\n    ) internal pure returns (int216 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int224 at `mPtr` in memory.\n    function readInt224(\n        MemoryPointer mPtr\n    ) internal pure returns (int224 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int232 at `mPtr` in memory.\n    function readInt232(\n        MemoryPointer mPtr\n    ) internal pure returns (int232 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int240 at `mPtr` in memory.\n    function readInt240(\n        MemoryPointer mPtr\n    ) internal pure returns (int240 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int248 at `mPtr` in memory.\n    function readInt248(\n        MemoryPointer mPtr\n    ) internal pure returns (int248 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n\n    /// @dev Reads the int256 at `mPtr` in memory.\n    function readInt256(\n        MemoryPointer mPtr\n    ) internal pure returns (int256 value) {\n        assembly {\n            value := mload(mPtr)\n        }\n    }\n}\n\nlibrary MemoryWriters {\n    /// @dev Writes `valuePtr` to memory at `mPtr`.\n    function write(MemoryPointer mPtr, MemoryPointer valuePtr) internal pure {\n        assembly {\n            mstore(mPtr, valuePtr)\n        }\n    }\n\n    /// @dev Writes a boolean `value` to `mPtr` in memory.\n    function write(MemoryPointer mPtr, bool value) internal pure {\n        assembly {\n            mstore(mPtr, value)\n        }\n    }\n\n    /// @dev Writes an address `value` to `mPtr` in memory.\n    function write(MemoryPointer mPtr, address value) internal pure {\n        assembly {\n            mstore(mPtr, value)\n        }\n    }\n\n    /// @dev Writes a bytes32 `value` to `mPtr` in memory.\n    /// Separate name to disambiguate literal write parameters.\n    function writeBytes32(MemoryPointer mPtr, bytes32 value) internal pure {\n        assembly {\n            mstore(mPtr, value)\n        }\n    }\n\n    /// @dev Writes a uint256 `value` to `mPtr` in memory.\n    function write(MemoryPointer mPtr, uint256 value) internal pure {\n        assembly {\n            mstore(mPtr, value)\n        }\n    }\n\n    /// @dev Writes an int256 `value` to `mPtr` in memory.\n    /// Separate name to disambiguate literal write parameters.\n    function writeInt(MemoryPointer mPtr, int256 value) internal pure {\n        assembly {\n            mstore(mPtr, value)\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "@ds-test/=lib/forge-std/lib/ds-test/src/",
        "@forge-std/=lib/forge-std/src/",
        "@openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
        "@safe-contracts/=lib/safe-contracts/contracts/",
        "@src/=src/",
        "@test/=test/",
        "@merkle-generator/=lib/merkle-proof-generator/src/",
        "@scripts/=scripts/",
        "@seaport-types/=lib/seaport-types/src/",
        "@seaport-core/=lib/seaport-core/src/",
        "seaport-types/=lib/seaport-types/",
        "seaport-core/=lib/seaport-core/",
        "@solady/=lib/Solady/src/",
        "@seaport-sol/=lib/seaport-sol/src/",
        "@rari-capital/solmate/=lib/seaport-sol/lib/seaport/lib/solmate/",
        "Solady/=lib/Solady/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "forge-std/=lib/forge-std/src/",
        "murky/=lib/seaport-sol/lib/murky/src/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "openzeppelin/=lib/openzeppelin-contracts/contracts/",
        "safe-contracts/=lib/safe-contracts/",
        "seaport-sol/=lib/seaport-sol/src/",
        "seaport/=lib/seaport-sol/lib/seaport/contracts/",
        "solady/=lib/seaport-sol/lib/solady/",
        "solarray/=lib/seaport-sol/lib/solarray/src/",
        "solmate/=lib/seaport-sol/lib/seaport/lib/solmate/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "viaIR": false,
      "libraries": {}
    }
  }}