creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/policies/Stop.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.20;\n\nimport {Enum} from \"@safe-contracts/common/Enum.sol\";\nimport {LibString} from \"@solady/utils/LibString.sol\";\n\nimport {ISafe} from \"@src/interfaces/ISafe.sol\";\nimport {IHook} from \"@src/interfaces/IHook.sol\";\n\nimport {Kernel, Policy, Permissions, Keycode} from \"@src/Kernel.sol\";\nimport {toKeycode} from \"@src/libraries/KernelUtils.sol\";\nimport {RentalUtils} from \"@src/libraries/RentalUtils.sol\";\nimport {Signer} from \"@src/packages/Signer.sol\";\nimport {Reclaimer} from \"@src/packages/Reclaimer.sol\";\nimport {Accumulator} from \"@src/packages/Accumulator.sol\";\nimport {Storage} from \"@src/modules/Storage.sol\";\nimport {PaymentEscrow} from \"@src/modules/PaymentEscrow.sol\";\nimport {Errors} from \"@src/libraries/Errors.sol\";\nimport {Events} from \"@src/libraries/Events.sol\";\nimport {\n    Item,\n    RentalOrder,\n    Hook,\n    OrderType,\n    ItemType,\n    RentalId,\n    RentalAssetUpdate\n} from \"@src/libraries/RentalStructs.sol\";\n\n/**\n * @title Stop\n * @notice Acts as an interface for all behavior related to stoping a rental.\n */\ncontract Stop is Policy, Signer, Reclaimer, Accumulator {\n    using RentalUtils for Item;\n    using RentalUtils for Item[];\n    using RentalUtils for OrderType;\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                         Kernel Policy Configuration                         //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    // Modules that the policy depends on.\n    Storage public STORE;\n    PaymentEscrow public ESCRW;\n\n    /**\n     * @dev Instantiate this contract as a policy.\n     *\n     * @param kernel_ Address of the kernel contract.\n     */\n    constructor(Kernel kernel_) Policy(kernel_) Signer() Reclaimer() {}\n\n    /**\n     * @notice Upon policy activation, configures the modules that the policy depends on.\n     *         If a module is ever upgraded that this policy depends on, the kernel will\n     *         call this function again to ensure this policy has the current address\n     *         of the module.\n     *\n     * @return dependencies Array of keycodes which represent modules that\n     *                      this policy depends on.\n     */\n    function configureDependencies()\n        external\n        override\n        onlyKernel\n        returns (Keycode[] memory dependencies)\n    {\n        dependencies = new Keycode[](2);\n\n        dependencies[0] = toKeycode(\"STORE\");\n        STORE = Storage(getModuleAddress(toKeycode(\"STORE\")));\n\n        dependencies[1] = toKeycode(\"ESCRW\");\n        ESCRW = PaymentEscrow(getModuleAddress(toKeycode(\"ESCRW\")));\n    }\n\n    /**\n     * @notice Upon policy activation, permissions are requested from the kernel to access\n     *         particular keycode <> function selector pairs. Once these permissions are\n     *         granted, they do not change and can only be revoked when the policy is\n     *         deactivated by the kernel.\n     *\n     * @return requests Array of keycode <> function selector pairs which represent\n     *                  permissions for the policy.\n     */\n    function requestPermissions()\n        external\n        view\n        override\n        onlyKernel\n        returns (Permissions[] memory requests)\n    {\n        requests = new Permissions[](4);\n        requests[0] = Permissions(toKeycode(\"STORE\"), STORE.removeRentals.selector);\n        requests[1] = Permissions(toKeycode(\"STORE\"), STORE.removeRentalsBatch.selector);\n        requests[2] = Permissions(toKeycode(\"ESCRW\"), ESCRW.settlePayment.selector);\n        requests[3] = Permissions(toKeycode(\"ESCRW\"), ESCRW.settlePaymentBatch.selector);\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            Internal Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Helper function to emit an event which signals a rental order has stopped.\n     *\n     * @param seaportOrderHash Order hash of the seaport order.\n     * @param stopper Address which stopped the rental order.\n     */\n    function _emitRentalOrderStopped(bytes32 seaportOrderHash, address stopper) internal {\n        // Wmit the event.\n        emit Events.RentalOrderStopped(seaportOrderHash, stopper);\n    }\n\n    /**\n     * @dev Validates that a rental order can be stopped. Whether an order\n     *      can be stopped is dependent on the type of order. BASE orders can\n     *      be stopped only when the rental has expired. PAY orders can be stopped\n     *      by the lender at any point in the time.\n     *\n     * @param orderType Order type of the rental order to stop.\n     * @param endTimestamp Timestamp that the rental will end.\n     * @param expectedLender Address of the initial lender in the order.\n     */\n    function _validateRentalCanBeStopped(\n        OrderType orderType,\n        uint256 startTimestamp,\n        uint256 endTimestamp,\n        address expectedLender\n    ) internal view {\n        // Determine if the order has expired.\n        bool hasExpired = endTimestamp <= block.timestamp;\n\n        // Determine if the fulfiller is the lender of the order.\n        bool isLender = expectedLender == msg.sender;\n\n        // Order cannot be stopped in the same transaction it was created.\n        if (startTimestamp == block.timestamp) {\n            revert Errors.StopPolicy_StoppedTooSoon();\n        }\n\n        // BASE orders processing.\n        if (orderType.isBaseOrder()) {\n            // check that the period for the rental order has expired.\n            if (!hasExpired) {\n                revert Errors.StopPolicy_CannotStopOrder(block.timestamp, msg.sender);\n            }\n        }\n        // PAY order processing.\n        else if (orderType.isPayOrder()) {\n            // If the stopper is the lender, then it doesnt matter whether the rental\n            // has expired. But if the stopper is not the lender, then the rental must have expired.\n            if (!isLender && (!hasExpired)) {\n                revert Errors.StopPolicy_CannotStopOrder(block.timestamp, msg.sender);\n            }\n        }\n        // Revert if given an invalid order type.\n        else {\n            revert Errors.Shared_OrderTypeNotSupported(uint8(orderType));\n        }\n    }\n\n    /**\n     * @dev Since the stop policy is an enabled Gnosis Safe module on all rental safes, it\n     *      can be used to execute a transaction directly from the rental safe which retrieves\n     *      the rented assets. This call bypasses the guard that prevents the assets from being\n     *      transferred.\n     *\n     * @param order Rental order to reclaim the items for.\n     */\n    function _reclaimRentedItems(RentalOrder memory order) internal {\n        // Transfer ERC721s from the renter back to lender.\n        bool success = ISafe(order.rentalWallet).execTransactionFromModule(\n            // Stop policy inherits the reclaimer package.\n            address(this),\n            // value.\n            0,\n            // The encoded call to the `reclaimRentalOrder` function.\n            abi.encodeWithSelector(this.reclaimRentalOrder.selector, order),\n            // Safe must delegate call to the stop policy so that it is the msg.sender.\n            Enum.Operation.DelegateCall\n        );\n\n        // Assert that the transfer back to the lender was successful.\n        if (!success) {\n            revert Errors.StopPolicy_ReclaimFailed();\n        }\n    }\n\n    /**\n     * @dev When a rental order is stopped, process each hook one by one but only if\n     *      the hook's status is set to execute on a rental stop.\n     *\n     * @param hooks        Array of hooks to process for the order.\n     * @param rentalItems  Array of rental items which are referenced by the hooks\n     * @param rentalWallet Address of the rental wallet which is the current owner\n     *                     of the rented assets.\n     */\n    function _removeHooks(\n        Hook[] calldata hooks,\n        Item[] calldata rentalItems,\n        address rentalWallet\n    ) internal {\n        // Define hook target, item index, and item.\n        address target;\n        uint256 itemIndex;\n        Item memory item;\n\n        // Loop through each hook in the payload.\n        for (uint256 i = 0; i < hooks.length; ++i) {\n            // Get the hook address.\n            target = hooks[i].target;\n\n            // Check that the hook is reNFT-approved to execute on rental stop.\n            if (STORE.hookOnStop(target)) {\n                // Get the rental item index for this hook.\n                itemIndex = hooks[i].itemIndex;\n\n                // Get the rental item for this hook.\n                item = rentalItems[itemIndex];\n\n                // Make sure the item is a rented item.\n                if (!item.isRental()) {\n                    revert Errors.Shared_NonRentalHookItem(itemIndex);\n                }\n\n                // Call the hook with data about the rented item.\n                try\n                    IHook(target).onStop(\n                        rentalWallet,\n                        item.token,\n                        item.identifier,\n                        item.amount,\n                        hooks[i].extraData\n                    )\n                {} catch Error(string memory revertReason) {\n                    // Revert with reason given.\n                    revert Errors.Shared_HookFailString(revertReason);\n                } catch Panic(uint256 errorCode) {\n                    // Convert solidity panic code to string.\n                    string memory stringErrorCode = LibString.toString(errorCode);\n\n                    // Revert with panic code.\n                    revert Errors.Shared_HookFailString(\n                        string.concat(\"Hook reverted: Panic code \", stringErrorCode)\n                    );\n                } catch (bytes memory revertData) {\n                    // Fallback to an error that returns the byte data.\n                    revert Errors.Shared_HookFailBytes(revertData);\n                }\n            }\n        }\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            External Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @notice Stops a rental by providing a `RentalOrder` struct. This data does not\n     *         exist in protocol storage, only the hash of the rental order. However,\n     *         during rental creation, all data needed to construct the rental order\n     *         is emitted as an event. A check is then made to ensure that the passed\n     *         in rental order matches the hash of a rental order in storage.\n     *\n     * @param order Rental order to stop.\n     */\n    function stopRent(RentalOrder calldata order) external {\n        // Compute the order hash.\n        bytes32 orderHash = _deriveRentalOrderHash(order);\n\n        // The order must exist to be deleted.\n        if (!STORE.orders(orderHash)) {\n            revert Errors.StopPolicy_OrderDoesNotExist(orderHash);\n        }\n\n        // Check that the rental can be stopped.\n        _validateRentalCanBeStopped(\n            order.orderType,\n            order.startTimestamp,\n            order.endTimestamp,\n            order.lender\n        );\n\n        // Create an accumulator which will hold all of the rental asset updates, consisting of IDs and\n        // the rented amount. From this point on, new memory cannot be safely allocated until the\n        // accumulator no longer needs to include elements.\n        bytes memory rentalAssetUpdates = new bytes(0);\n\n        // Check if each item in the order is a rental. If so, then generate the rental asset update.\n        // Memory will become safe again after this block.\n        for (uint256 i; i < order.items.length; ++i) {\n            if (order.items[i].isRental()) {\n                // Insert the rental asset update into the dynamic array.\n                _insert(\n                    rentalAssetUpdates,\n                    order.items[i].toRentalId(order.rentalWallet),\n                    order.items[i].amount\n                );\n            }\n        }\n\n        // Interaction: Transfer rentals from the renter back to lender.\n        _reclaimRentedItems(order);\n\n        // Interaction: Transfer ERC20 payments from the escrow contract to the respective recipients.\n        ESCRW.settlePayment(order);\n\n        // Interaction: process hooks so they no longer exist for the renter.\n        if (order.hooks.length > 0) {\n            _removeHooks(order.hooks, order.items, order.rentalWallet);\n        }\n\n        // Invariant: Remove rentals from storage by using the order hash only after all\n        // processing for the order has been completed\n        STORE.removeRentals(orderHash, _convertToStatic(rentalAssetUpdates));\n\n        // Emit rental order stopped.\n        _emitRentalOrderStopped(order.seaportOrderHash, msg.sender);\n    }\n\n    /**\n     * @notice Stops a batch of rentals by providing an array of `RentalOrder` structs.\n     *\n     * @param orders Array of rental orders to stop.\n     */\n    function stopRentBatch(RentalOrder[] calldata orders) external {\n        // Process each rental order.\n        // Memory will become safe after this block.\n        for (uint256 i = 0; i < orders.length; ++i) {\n            // Compute the order hash.\n            bytes32 orderHash = _deriveRentalOrderHash(orders[i]);\n\n            // The order must exist to be deleted.\n            if (!STORE.orders(orderHash)) {\n                revert Errors.StopPolicy_OrderDoesNotExist(orderHash);\n            }\n\n            // Check that the rental can be stopped.\n            _validateRentalCanBeStopped(\n                orders[i].orderType,\n                orders[i].startTimestamp,\n                orders[i].endTimestamp,\n                orders[i].lender\n            );\n\n            // Create an accumulator which will hold all of the rental asset updates, consisting of IDs and\n            // the rented amount. From this point on, new memory cannot be safely allocated until the\n            // accumulator no longer needs to include elements.\n            bytes memory rentalAssetUpdates = new bytes(0);\n\n            // Check if each item in the order is a rental. If so, then generate the rental asset update.\n            for (uint256 j = 0; j < orders[i].items.length; ++j) {\n                // Insert the rental asset update into the dynamic array.\n                if (orders[i].items[j].isRental()) {\n                    _insert(\n                        rentalAssetUpdates,\n                        orders[i].items[j].toRentalId(orders[i].rentalWallet),\n                        orders[i].items[j].amount\n                    );\n                }\n            }\n\n            // Interaction: Transfer rentals from the renter back to lender.\n            _reclaimRentedItems(orders[i]);\n\n            // Interaction: Transfer ERC20 payments from the escrow contract to the respective recipients.\n            ESCRW.settlePayment(orders[i]);\n\n            // Interaction: Process hooks so they no longer exist for the renter.\n            if (orders[i].hooks.length > 0) {\n                _removeHooks(orders[i].hooks, orders[i].items, orders[i].rentalWallet);\n            }\n\n            // Invariant: Remove rentals from storage by using the order hash only after\n            // processing for the order has been completed\n            STORE.removeRentals(orderHash, _convertToStatic(rentalAssetUpdates));\n\n            // Emit rental order stopped.\n            _emitRentalOrderStopped(orderHash, msg.sender);\n        }\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/common/Enum.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title Enum - Collection of enums used in Safe contracts.\n * @author Richard Meissner - @rmeissner\n */\nabstract contract Enum {\n    enum Operation {\n        Call,\n        DelegateCall\n    }\n}\n"
      },
      "lib/Solady/src/utils/LibString.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/// @notice Library for converting numbers into strings and other string operations.\n/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)\n/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol)\nlibrary LibString {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        CUSTOM ERRORS                       */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The `length` of the output is too small to contain all the hex digits.\n    error HexLengthInsufficient();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                         CONSTANTS                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The constant returned when the `search` is not found in the string.\n    uint256 internal constant NOT_FOUND = type(uint256).max;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                     DECIMAL OPERATIONS                     */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the base 10 decimal representation of `value`.\n    function toString(uint256 value) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but\n            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.\n            // We will need 1 word for the trailing zeros padding, 1 word for the length,\n            // and 3 words for a maximum of 78 digits.\n            str := add(mload(0x40), 0x80)\n            // Update the free memory pointer to allocate.\n            mstore(0x40, add(str, 0x20))\n            // Zeroize the slot after the string.\n            mstore(str, 0)\n\n            // Cache the end of the memory to calculate the length later.\n            let end := str\n\n            let w := not(0) // Tsk.\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let temp := value } 1 {} {\n                str := add(str, w) // `sub(str, 1)`.\n                // Write the character to the pointer.\n                // The ASCII index of the '0' character is 48.\n                mstore8(str, add(48, mod(temp, 10)))\n                // Keep dividing `temp` until zero.\n                temp := div(temp, 10)\n                if iszero(temp) { break }\n            }\n\n            let length := sub(end, str)\n            // Move the pointer 32 bytes leftwards to make room for the length.\n            str := sub(str, 0x20)\n            // Store the length.\n            mstore(str, length)\n        }\n    }\n\n    /// @dev Returns the base 10 decimal representation of `value`.\n    function toString(int256 value) internal pure returns (string memory str) {\n        if (value >= 0) {\n            return toString(uint256(value));\n        }\n        unchecked {\n            str = toString(uint256(-value));\n        }\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We still have some spare memory space on the left,\n            // as we have allocated 3 words (96 bytes) for up to 78 digits.\n            let length := mload(str) // Load the string length.\n            mstore(str, 0x2d) // Store the '-' character.\n            str := sub(str, 1) // Move back the string pointer by a byte.\n            mstore(str, add(length, 1)) // Update the string length.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   HEXADECIMAL OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the hexadecimal representation of `value`,\n    /// left-padded to an input length of `length` bytes.\n    /// The output is prefixed with \"0x\" encoded using 2 hexadecimal digits per byte,\n    /// giving a total length of `length * 2 + 2` bytes.\n    /// Reverts if `length` is too small for the output to contain all the digits.\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value, length);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`,\n    /// left-padded to an input length of `length` bytes.\n    /// The output is prefixed with \"0x\" encoded using 2 hexadecimal digits per byte,\n    /// giving a total length of `length * 2` bytes.\n    /// Reverts if `length` is too small for the output to contain all the digits.\n    function toHexStringNoPrefix(uint256 value, uint256 length)\n        internal\n        pure\n        returns (string memory str)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes\n            // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.\n            // We add 0x20 to the total and round down to a multiple of 0x20.\n            // (0x20 + 0x20 + 0x02 + 0x20) = 0x62.\n            str := add(mload(0x40), and(add(shl(1, length), 0x42), not(0x1f)))\n            // Allocate the memory.\n            mstore(0x40, add(str, 0x20))\n            // Zeroize the slot after the string.\n            mstore(str, 0)\n\n            // Cache the end to calculate the length later.\n            let end := str\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let start := sub(str, add(length, length))\n            let w := not(1) // Tsk.\n            let temp := value\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for {} 1 {} {\n                str := add(str, w) // `sub(str, 2)`.\n                mstore8(add(str, 1), mload(and(temp, 15)))\n                mstore8(str, mload(and(shr(4, temp), 15)))\n                temp := shr(8, temp)\n                if iszero(xor(str, start)) { break }\n            }\n\n            if temp {\n                // Store the function selector of `HexLengthInsufficient()`.\n                mstore(0x00, 0x2194895a)\n                // Revert with (offset, size).\n                revert(0x1c, 0x04)\n            }\n\n            // Compute the string's length.\n            let strLength := sub(end, str)\n            // Move the pointer and write the length.\n            str := sub(str, 0x20)\n            mstore(str, strLength)\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    /// As address are 20 bytes long, the output will left-padded to have\n    /// a length of `20 * 2 + 2` bytes.\n    function toHexString(uint256 value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\".\n    /// The output excludes leading \"0\" from the `toHexString` output.\n    /// `0x00: \"0x0\", 0x01: \"0x1\", 0x12: \"0x12\", 0x123: \"0x123\"`.\n    function toMinimalHexString(uint256 value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let o := eq(byte(0, mload(add(str, 0x20))), 0x30) // Whether leading zero is present.\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(add(str, o), 0x3078) // Write the \"0x\" prefix, accounting for leading zero.\n            str := sub(add(str, o), 2) // Move the pointer, accounting for leading zero.\n            mstore(str, sub(strLength, o)) // Write the length, accounting for leading zero.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output excludes leading \"0\" from the `toHexStringNoPrefix` output.\n    /// `0x00: \"0\", 0x01: \"1\", 0x12: \"12\", 0x123: \"123\"`.\n    function toMinimalHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let o := eq(byte(0, mload(add(str, 0x20))), 0x30) // Whether leading zero is present.\n            let strLength := mload(str) // Get the length.\n            str := add(str, o) // Move the pointer, accounting for leading zero.\n            mstore(str, sub(strLength, o)) // Write the length, accounting for leading zero.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    /// As address are 20 bytes long, the output will left-padded to have\n    /// a length of `20 * 2` bytes.\n    function toHexStringNoPrefix(uint256 value) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x40 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.\n            str := add(mload(0x40), 0x80)\n            // Allocate the memory.\n            mstore(0x40, add(str, 0x20))\n            // Zeroize the slot after the string.\n            mstore(str, 0)\n\n            // Cache the end to calculate the length later.\n            let end := str\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let w := not(1) // Tsk.\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let temp := value } 1 {} {\n                str := add(str, w) // `sub(str, 2)`.\n                mstore8(add(str, 1), mload(and(temp, 15)))\n                mstore8(str, mload(and(shr(4, temp), 15)))\n                temp := shr(8, temp)\n                if iszero(temp) { break }\n            }\n\n            // Compute the string's length.\n            let strLength := sub(end, str)\n            // Move the pointer and write the length.\n            str := sub(str, 0x20)\n            mstore(str, strLength)\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\", encoded using 2 hexadecimal digits per byte,\n    /// and the alphabets are capitalized conditionally according to\n    /// https://eips.ethereum.org/EIPS/eip-55\n    function toHexStringChecksummed(address value) internal pure returns (string memory str) {\n        str = toHexString(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`\n            let o := add(str, 0x22)\n            let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `\n            let t := shl(240, 136) // `0b10001000 << 240`\n            for { let i := 0 } 1 {} {\n                mstore(add(i, i), mul(t, byte(i, hashed)))\n                i := add(i, 1)\n                if eq(i, 20) { break }\n            }\n            mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))\n            o := add(o, 0x20)\n            mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    function toHexString(address value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(address value) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            str := mload(0x40)\n\n            // Allocate the memory.\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x28 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.\n            mstore(0x40, add(str, 0x80))\n\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            str := add(str, 2)\n            mstore(str, 40)\n\n            let o := add(str, 0x20)\n            mstore(add(o, 40), 0)\n\n            value := shl(96, value)\n\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for { let i := 0 } 1 {} {\n                let p := add(o, add(i, i))\n                let temp := byte(i, value)\n                mstore8(add(p, 1), mload(and(temp, 15)))\n                mstore8(p, mload(shr(4, temp)))\n                i := add(i, 1)\n                if eq(i, 20) { break }\n            }\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexString(bytes memory raw) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(raw);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let length := mload(raw)\n            str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.\n            mstore(str, add(length, length)) // Store the length of the output.\n\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let o := add(str, 0x20)\n            let end := add(raw, length)\n\n            for {} iszero(eq(raw, end)) {} {\n                raw := add(raw, 1)\n                mstore8(add(o, 1), mload(and(mload(raw), 15)))\n                mstore8(o, mload(and(shr(4, mload(raw)), 15)))\n                o := add(o, 2)\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(0x40, add(o, 0x20)) // Allocate the memory.\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   RUNE STRING OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Returns the number of UTF characters in the string.\n    function runeCount(string memory s) internal pure returns (uint256 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if mload(s) {\n                mstore(0x00, div(not(0), 255))\n                mstore(0x20, 0x0202020202020202020202020202020202020202020202020303030304040506)\n                let o := add(s, 0x20)\n                let end := add(o, mload(s))\n                for { result := 1 } 1 { result := add(result, 1) } {\n                    o := add(o, byte(0, mload(shr(250, mload(o)))))\n                    if iszero(lt(o, end)) { break }\n                }\n            }\n        }\n    }\n\n    /// @dev Returns if this string is a 7-bit ASCII string.\n    /// (i.e. all characters codes are in [0..127])\n    function is7BitASCII(string memory s) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let mask := shl(7, div(not(0), 255))\n            result := 1\n            let n := mload(s)\n            if n {\n                let o := add(s, 0x20)\n                let end := add(o, n)\n                let last := mload(end)\n                mstore(end, 0)\n                for {} 1 {} {\n                    if and(mask, mload(o)) {\n                        result := 0\n                        break\n                    }\n                    o := add(o, 0x20)\n                    if iszero(lt(o, end)) { break }\n                }\n                mstore(end, last)\n            }\n        }\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                   BYTE STRING OPERATIONS                   */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // For performance and bytecode compactness, all indices of the following operations\n    // are byte (ASCII) offsets, not UTF character offsets.\n\n    /// @dev Returns `subject` all occurrences of `search` replaced with `replacement`.\n    function replace(string memory subject, string memory search, string memory replacement)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let subjectLength := mload(subject)\n            let searchLength := mload(search)\n            let replacementLength := mload(replacement)\n\n            subject := add(subject, 0x20)\n            search := add(search, 0x20)\n            replacement := add(replacement, 0x20)\n            result := add(mload(0x40), 0x20)\n\n            let subjectEnd := add(subject, subjectLength)\n            if iszero(gt(searchLength, subjectLength)) {\n                let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1)\n                let h := 0\n                if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }\n                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))\n                let s := mload(search)\n                for {} 1 {} {\n                    let t := mload(subject)\n                    // Whether the first `searchLength % 32` bytes of\n                    // `subject` and `search` matches.\n                    if iszero(shr(m, xor(t, s))) {\n                        if h {\n                            if iszero(eq(keccak256(subject, searchLength), h)) {\n                                mstore(result, t)\n                                result := add(result, 1)\n                                subject := add(subject, 1)\n                                if iszero(lt(subject, subjectSearchEnd)) { break }\n                                continue\n                            }\n                        }\n                        // Copy the `replacement` one word at a time.\n                        for { let o := 0 } 1 {} {\n                            mstore(add(result, o), mload(add(replacement, o)))\n                            o := add(o, 0x20)\n                            if iszero(lt(o, replacementLength)) { break }\n                        }\n                        result := add(result, replacementLength)\n                        subject := add(subject, searchLength)\n                        if searchLength {\n                            if iszero(lt(subject, subjectSearchEnd)) { break }\n                            continue\n                        }\n                    }\n                    mstore(result, t)\n                    result := add(result, 1)\n                    subject := add(subject, 1)\n                    if iszero(lt(subject, subjectSearchEnd)) { break }\n                }\n            }\n\n            let resultRemainder := result\n            result := add(mload(0x40), 0x20)\n            let k := add(sub(resultRemainder, result), sub(subjectEnd, subject))\n            // Copy the rest of the string one word at a time.\n            for {} lt(subject, subjectEnd) {} {\n                mstore(resultRemainder, mload(subject))\n                resultRemainder := add(resultRemainder, 0x20)\n                subject := add(subject, 0x20)\n            }\n            result := sub(result, 0x20)\n            let last := add(add(result, 0x20), k) // Zeroize the slot after the string.\n            mstore(last, 0)\n            mstore(0x40, add(last, 0x20)) // Allocate the memory.\n            mstore(result, k) // Store the length.\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `search` in `subject`,\n    /// searching from left to right, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.\n    function indexOf(string memory subject, string memory search, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for { let subjectLength := mload(subject) } 1 {} {\n                if iszero(mload(search)) {\n                    if iszero(gt(from, subjectLength)) {\n                        result := from\n                        break\n                    }\n                    result := subjectLength\n                    break\n                }\n                let searchLength := mload(search)\n                let subjectStart := add(subject, 0x20)\n\n                result := not(0) // Initialize to `NOT_FOUND`.\n\n                subject := add(subjectStart, from)\n                let end := add(sub(add(subjectStart, subjectLength), searchLength), 1)\n\n                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))\n                let s := mload(add(search, 0x20))\n\n                if iszero(and(lt(subject, end), lt(from, subjectLength))) { break }\n\n                if iszero(lt(searchLength, 0x20)) {\n                    for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {\n                        if iszero(shr(m, xor(mload(subject), s))) {\n                            if eq(keccak256(subject, searchLength), h) {\n                                result := sub(subject, subjectStart)\n                                break\n                            }\n                        }\n                        subject := add(subject, 1)\n                        if iszero(lt(subject, end)) { break }\n                    }\n                    break\n                }\n                for {} 1 {} {\n                    if iszero(shr(m, xor(mload(subject), s))) {\n                        result := sub(subject, subjectStart)\n                        break\n                    }\n                    subject := add(subject, 1)\n                    if iszero(lt(subject, end)) { break }\n                }\n                break\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `search` in `subject`,\n    /// searching from left to right.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.\n    function indexOf(string memory subject, string memory search)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        result = indexOf(subject, search, 0);\n    }\n\n    /// @dev Returns the byte index of the first location of `search` in `subject`,\n    /// searching from right to left, starting from `from`.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.\n    function lastIndexOf(string memory subject, string memory search, uint256 from)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            for {} 1 {} {\n                result := not(0) // Initialize to `NOT_FOUND`.\n                let searchLength := mload(search)\n                if gt(searchLength, mload(subject)) { break }\n                let w := result\n\n                let fromMax := sub(mload(subject), searchLength)\n                if iszero(gt(fromMax, from)) { from := fromMax }\n\n                let end := add(add(subject, 0x20), w)\n                subject := add(add(subject, 0x20), from)\n                if iszero(gt(subject, end)) { break }\n                // As this function is not too often used,\n                // we shall simply use keccak256 for smaller bytecode size.\n                for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {\n                    if eq(keccak256(subject, searchLength), h) {\n                        result := sub(subject, add(end, 1))\n                        break\n                    }\n                    subject := add(subject, w) // `sub(subject, 1)`.\n                    if iszero(gt(subject, end)) { break }\n                }\n                break\n            }\n        }\n    }\n\n    /// @dev Returns the byte index of the first location of `search` in `subject`,\n    /// searching from right to left.\n    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.\n    function lastIndexOf(string memory subject, string memory search)\n        internal\n        pure\n        returns (uint256 result)\n    {\n        result = lastIndexOf(subject, search, uint256(int256(-1)));\n    }\n\n    /// @dev Returns whether `subject` starts with `search`.\n    function startsWith(string memory subject, string memory search)\n        internal\n        pure\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let searchLength := mload(search)\n            // Just using keccak256 directly is actually cheaper.\n            // forgefmt: disable-next-item\n            result := and(\n                iszero(gt(searchLength, mload(subject))),\n                eq(\n                    keccak256(add(subject, 0x20), searchLength),\n                    keccak256(add(search, 0x20), searchLength)\n                )\n            )\n        }\n    }\n\n    /// @dev Returns whether `subject` ends with `search`.\n    function endsWith(string memory subject, string memory search)\n        internal\n        pure\n        returns (bool result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let searchLength := mload(search)\n            let subjectLength := mload(subject)\n            // Whether `search` is not longer than `subject`.\n            let withinRange := iszero(gt(searchLength, subjectLength))\n            // Just using keccak256 directly is actually cheaper.\n            // forgefmt: disable-next-item\n            result := and(\n                withinRange,\n                eq(\n                    keccak256(\n                        // `subject + 0x20 + max(subjectLength - searchLength, 0)`.\n                        add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))),\n                        searchLength\n                    ),\n                    keccak256(add(search, 0x20), searchLength)\n                )\n            )\n        }\n    }\n\n    /// @dev Returns `subject` repeated `times`.\n    function repeat(string memory subject, uint256 times)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let subjectLength := mload(subject)\n            if iszero(or(iszero(times), iszero(subjectLength))) {\n                subject := add(subject, 0x20)\n                result := mload(0x40)\n                let output := add(result, 0x20)\n                for {} 1 {} {\n                    // Copy the `subject` one word at a time.\n                    for { let o := 0 } 1 {} {\n                        mstore(add(output, o), mload(add(subject, o)))\n                        o := add(o, 0x20)\n                        if iszero(lt(o, subjectLength)) { break }\n                    }\n                    output := add(output, subjectLength)\n                    times := sub(times, 1)\n                    if iszero(times) { break }\n                }\n                mstore(output, 0) // Zeroize the slot after the string.\n                let resultLength := sub(output, add(result, 0x20))\n                mstore(result, resultLength) // Store the length.\n                // Allocate the memory.\n                mstore(0x40, add(result, add(resultLength, 0x20)))\n            }\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).\n    /// `start` and `end` are byte offsets.\n    function slice(string memory subject, uint256 start, uint256 end)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let subjectLength := mload(subject)\n            if iszero(gt(subjectLength, end)) { end := subjectLength }\n            if iszero(gt(subjectLength, start)) { start := subjectLength }\n            if lt(start, end) {\n                result := mload(0x40)\n                let resultLength := sub(end, start)\n                mstore(result, resultLength)\n                subject := add(subject, start)\n                let w := not(0x1f)\n                // Copy the `subject` one word at a time, backwards.\n                for { let o := and(add(resultLength, 0x1f), w) } 1 {} {\n                    mstore(add(result, o), mload(add(subject, o)))\n                    o := add(o, w) // `sub(o, 0x20)`.\n                    if iszero(o) { break }\n                }\n                // Zeroize the slot after the string.\n                mstore(add(add(result, 0x20), resultLength), 0)\n                // Allocate memory for the length and the bytes,\n                // rounded up to a multiple of 32.\n                mstore(0x40, add(result, and(add(resultLength, 0x3f), w)))\n            }\n        }\n    }\n\n    /// @dev Returns a copy of `subject` sliced from `start` to the end of the string.\n    /// `start` is a byte offset.\n    function slice(string memory subject, uint256 start)\n        internal\n        pure\n        returns (string memory result)\n    {\n        result = slice(subject, start, uint256(int256(-1)));\n    }\n\n    /// @dev Returns all the indices of `search` in `subject`.\n    /// The indices are byte offsets.\n    function indicesOf(string memory subject, string memory search)\n        internal\n        pure\n        returns (uint256[] memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let subjectLength := mload(subject)\n            let searchLength := mload(search)\n\n            if iszero(gt(searchLength, subjectLength)) {\n                subject := add(subject, 0x20)\n                search := add(search, 0x20)\n                result := add(mload(0x40), 0x20)\n\n                let subjectStart := subject\n                let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1)\n                let h := 0\n                if iszero(lt(searchLength, 0x20)) { h := keccak256(search, searchLength) }\n                let m := shl(3, sub(0x20, and(searchLength, 0x1f)))\n                let s := mload(search)\n                for {} 1 {} {\n                    let t := mload(subject)\n                    // Whether the first `searchLength % 32` bytes of\n                    // `subject` and `search` matches.\n                    if iszero(shr(m, xor(t, s))) {\n                        if h {\n                            if iszero(eq(keccak256(subject, searchLength), h)) {\n                                subject := add(subject, 1)\n                                if iszero(lt(subject, subjectSearchEnd)) { break }\n                                continue\n                            }\n                        }\n                        // Append to `result`.\n                        mstore(result, sub(subject, subjectStart))\n                        result := add(result, 0x20)\n                        // Advance `subject` by `searchLength`.\n                        subject := add(subject, searchLength)\n                        if searchLength {\n                            if iszero(lt(subject, subjectSearchEnd)) { break }\n                            continue\n                        }\n                    }\n                    subject := add(subject, 1)\n                    if iszero(lt(subject, subjectSearchEnd)) { break }\n                }\n                let resultEnd := result\n                // Assign `result` to the free memory pointer.\n                result := mload(0x40)\n                // Store the length of `result`.\n                mstore(result, shr(5, sub(resultEnd, add(result, 0x20))))\n                // Allocate memory for result.\n                // We allocate one more word, so this array can be recycled for {split}.\n                mstore(0x40, add(resultEnd, 0x20))\n            }\n        }\n    }\n\n    /// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string.\n    function split(string memory subject, string memory delimiter)\n        internal\n        pure\n        returns (string[] memory result)\n    {\n        uint256[] memory indices = indicesOf(subject, delimiter);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let w := not(0x1f)\n            let indexPtr := add(indices, 0x20)\n            let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))\n            mstore(add(indicesEnd, w), mload(subject))\n            mstore(indices, add(mload(indices), 1))\n            let prevIndex := 0\n            for {} 1 {} {\n                let index := mload(indexPtr)\n                mstore(indexPtr, 0x60)\n                if iszero(eq(index, prevIndex)) {\n                    let element := mload(0x40)\n                    let elementLength := sub(index, prevIndex)\n                    mstore(element, elementLength)\n                    // Copy the `subject` one word at a time, backwards.\n                    for { let o := and(add(elementLength, 0x1f), w) } 1 {} {\n                        mstore(add(element, o), mload(add(add(subject, prevIndex), o)))\n                        o := add(o, w) // `sub(o, 0x20)`.\n                        if iszero(o) { break }\n                    }\n                    // Zeroize the slot after the string.\n                    mstore(add(add(element, 0x20), elementLength), 0)\n                    // Allocate memory for the length and the bytes,\n                    // rounded up to a multiple of 32.\n                    mstore(0x40, add(element, and(add(elementLength, 0x3f), w)))\n                    // Store the `element` into the array.\n                    mstore(indexPtr, element)\n                }\n                prevIndex := add(index, mload(delimiter))\n                indexPtr := add(indexPtr, 0x20)\n                if iszero(lt(indexPtr, indicesEnd)) { break }\n            }\n            result := indices\n            if iszero(mload(delimiter)) {\n                result := add(indices, 0x20)\n                mstore(result, sub(mload(indices), 2))\n            }\n        }\n    }\n\n    /// @dev Returns a concatenated string of `a` and `b`.\n    /// Cheaper than `string.concat()` and does not de-align the free memory pointer.\n    function concat(string memory a, string memory b)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let w := not(0x1f)\n            result := mload(0x40)\n            let aLength := mload(a)\n            // Copy `a` one word at a time, backwards.\n            for { let o := and(add(aLength, 0x20), w) } 1 {} {\n                mstore(add(result, o), mload(add(a, o)))\n                o := add(o, w) // `sub(o, 0x20)`.\n                if iszero(o) { break }\n            }\n            let bLength := mload(b)\n            let output := add(result, aLength)\n            // Copy `b` one word at a time, backwards.\n            for { let o := and(add(bLength, 0x20), w) } 1 {} {\n                mstore(add(output, o), mload(add(b, o)))\n                o := add(o, w) // `sub(o, 0x20)`.\n                if iszero(o) { break }\n            }\n            let totalLength := add(aLength, bLength)\n            let last := add(add(result, 0x20), totalLength)\n            // Zeroize the slot after the string.\n            mstore(last, 0)\n            // Stores the length.\n            mstore(result, totalLength)\n            // Allocate memory for the length and the bytes,\n            // rounded up to a multiple of 32.\n            mstore(0x40, and(add(last, 0x1f), w))\n        }\n    }\n\n    /// @dev Returns a copy of the string in either lowercase or UPPERCASE.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function toCase(string memory subject, bool toUpper)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let length := mload(subject)\n            if length {\n                result := add(mload(0x40), 0x20)\n                subject := add(subject, 1)\n                let flags := shl(add(70, shl(5, toUpper)), 0x3ffffff)\n                let w := not(0)\n                for { let o := length } 1 {} {\n                    o := add(o, w)\n                    let b := and(0xff, mload(add(subject, o)))\n                    mstore8(add(result, o), xor(b, and(shr(b, flags), 0x20)))\n                    if iszero(o) { break }\n                }\n                result := mload(0x40)\n                mstore(result, length) // Store the length.\n                let last := add(add(result, 0x20), length)\n                mstore(last, 0) // Zeroize the slot after the string.\n                mstore(0x40, add(last, 0x20)) // Allocate the memory.\n            }\n        }\n    }\n\n    /// @dev Returns a lowercased copy of the string.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function lower(string memory subject) internal pure returns (string memory result) {\n        result = toCase(subject, false);\n    }\n\n    /// @dev Returns an UPPERCASED copy of the string.\n    /// WARNING! This function is only compatible with 7-bit ASCII strings.\n    function upper(string memory subject) internal pure returns (string memory result) {\n        result = toCase(subject, true);\n    }\n\n    /// @dev Escapes the string to be used within HTML tags.\n    function escapeHTML(string memory s) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let end := add(s, mload(s))\n            result := add(mload(0x40), 0x20)\n            // Store the bytes of the packed offsets and strides into the scratch space.\n            // `packed = (stride << 5) | offset`. Max offset is 20. Max stride is 6.\n            mstore(0x1f, 0x900094)\n            mstore(0x08, 0xc0000000a6ab)\n            // Store \"&quot;&amp;&#39;&lt;&gt;\" into the scratch space.\n            mstore(0x00, shl(64, 0x2671756f743b26616d703b262333393b266c743b2667743b))\n            for {} iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                // Not in `[\"\\\"\",\"'\",\"&\",\"<\",\">\"]`.\n                if iszero(and(shl(c, 1), 0x500000c400000000)) {\n                    mstore8(result, c)\n                    result := add(result, 1)\n                    continue\n                }\n                let t := shr(248, mload(c))\n                mstore(result, mload(and(t, 0x1f)))\n                result := add(result, shr(5, t))\n            }\n            let last := result\n            mstore(last, 0) // Zeroize the slot after the string.\n            result := mload(0x40)\n            mstore(result, sub(last, add(result, 0x20))) // Store the length.\n            mstore(0x40, add(last, 0x20)) // Allocate the memory.\n        }\n    }\n\n    /// @dev Escapes the string to be used within double-quotes in a JSON.\n    /// If `addDoubleQuotes` is true, the result will be enclosed in double-quotes.\n    function escapeJSON(string memory s, bool addDoubleQuotes)\n        internal\n        pure\n        returns (string memory result)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let end := add(s, mload(s))\n            result := add(mload(0x40), 0x20)\n            if addDoubleQuotes {\n                mstore8(result, 34)\n                result := add(1, result)\n            }\n            // Store \"\\\\u0000\" in scratch space.\n            // Store \"0123456789abcdef\" in scratch space.\n            // Also, store `{0x08:\"b\", 0x09:\"t\", 0x0a:\"n\", 0x0c:\"f\", 0x0d:\"r\"}`.\n            // into the scratch space.\n            mstore(0x15, 0x5c75303030303031323334353637383961626364656662746e006672)\n            // Bitmask for detecting `[\"\\\"\",\"\\\\\"]`.\n            let e := or(shl(0x22, 1), shl(0x5c, 1))\n            for {} iszero(eq(s, end)) {} {\n                s := add(s, 1)\n                let c := and(mload(s), 0xff)\n                if iszero(lt(c, 0x20)) {\n                    if iszero(and(shl(c, 1), e)) {\n                        // Not in `[\"\\\"\",\"\\\\\"]`.\n                        mstore8(result, c)\n                        result := add(result, 1)\n                        continue\n                    }\n                    mstore8(result, 0x5c) // \"\\\\\".\n                    mstore8(add(result, 1), c)\n                    result := add(result, 2)\n                    continue\n                }\n                if iszero(and(shl(c, 1), 0x3700)) {\n                    // Not in `[\"\\b\",\"\\t\",\"\\n\",\"\\f\",\"\\d\"]`.\n                    mstore8(0x1d, mload(shr(4, c))) // Hex value.\n                    mstore8(0x1e, mload(and(c, 15))) // Hex value.\n                    mstore(result, mload(0x19)) // \"\\\\u00XX\".\n                    result := add(result, 6)\n                    continue\n                }\n                mstore8(result, 0x5c) // \"\\\\\".\n                mstore8(add(result, 1), mload(add(c, 8)))\n                result := add(result, 2)\n            }\n            if addDoubleQuotes {\n                mstore8(result, 34)\n                result := add(1, result)\n            }\n            let last := result\n            mstore(last, 0) // Zeroize the slot after the string.\n            result := mload(0x40)\n            mstore(result, sub(last, add(result, 0x20))) // Store the length.\n            mstore(0x40, add(last, 0x20)) // Allocate the memory.\n        }\n    }\n\n    /// @dev Escapes the string to be used within double-quotes in a JSON.\n    function escapeJSON(string memory s) internal pure returns (string memory result) {\n        result = escapeJSON(s, false);\n    }\n\n    /// @dev Returns whether `a` equals `b`.\n    function eq(string memory a, string memory b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := eq(keccak256(add(a, 0x20), mload(a)), keccak256(add(b, 0x20), mload(b)))\n        }\n    }\n\n    /// @dev Returns whether `a` equals `b`. For short strings up to 32 bytes.\n    function eqs(string memory a, bytes32 b) internal pure returns (bool result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // These should be evaluated on compile time, as far as possible.\n            let x := and(b, add(not(b), 1))\n            let r := or(shl(8, iszero(b)), shl(7, iszero(iszero(shr(128, x)))))\n            r := or(r, shl(6, iszero(iszero(shr(64, shr(r, x))))))\n            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))\n            r := or(r, shl(4, lt(0xffff, shr(r, x))))\n            r := or(r, shl(3, lt(0xff, shr(r, x))))\n            result := gt(eq(mload(a), sub(32, shr(3, r))), shr(r, xor(b, mload(add(a, 0x20)))))\n        }\n    }\n\n    /// @dev Packs a single string with its length into a single word.\n    /// Returns `bytes32(0)` if the length is zero or greater than 31.\n    function packOne(string memory a) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // We don't need to zero right pad the string,\n            // since this is our own custom non-standard packing scheme.\n            result :=\n                mul(\n                    // Load the length and the bytes.\n                    mload(add(a, 0x1f)),\n                    // `length != 0 && length < 32`. Abuses underflow.\n                    // Assumes that the length is valid and within the block gas limit.\n                    lt(sub(mload(a), 1), 0x1f)\n                )\n        }\n    }\n\n    /// @dev Unpacks a string packed using {packOne}.\n    /// Returns the empty string if `packed` is `bytes32(0)`.\n    /// If `packed` is not an output of {packOne}, the output behaviour is undefined.\n    function unpackOne(bytes32 packed) internal pure returns (string memory result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Grab the free memory pointer.\n            result := mload(0x40)\n            // Allocate 2 words (1 for the length, 1 for the bytes).\n            mstore(0x40, add(result, 0x40))\n            // Zeroize the length slot.\n            mstore(result, 0)\n            // Store the length and bytes.\n            mstore(add(result, 0x1f), packed)\n            // Right pad with zeroes.\n            mstore(add(add(result, 0x20), mload(result)), 0)\n        }\n    }\n\n    /// @dev Packs two strings with their lengths into a single word.\n    /// Returns `bytes32(0)` if combined length is zero or greater than 30.\n    function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let aLength := mload(a)\n            // We don't need to zero right pad the strings,\n            // since this is our own custom non-standard packing scheme.\n            result :=\n                mul(\n                    // Load the length and the bytes of `a` and `b`.\n                    or(\n                        shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))),\n                        mload(sub(add(b, 0x1e), aLength))\n                    ),\n                    // `totalLength != 0 && totalLength < 31`. Abuses underflow.\n                    // Assumes that the lengths are valid and within the block gas limit.\n                    lt(sub(add(aLength, mload(b)), 1), 0x1e)\n                )\n        }\n    }\n\n    /// @dev Unpacks strings packed using {packTwo}.\n    /// Returns the empty strings if `packed` is `bytes32(0)`.\n    /// If `packed` is not an output of {packTwo}, the output behaviour is undefined.\n    function unpackTwo(bytes32 packed)\n        internal\n        pure\n        returns (string memory resultA, string memory resultB)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Grab the free memory pointer.\n            resultA := mload(0x40)\n            resultB := add(resultA, 0x40)\n            // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.\n            mstore(0x40, add(resultB, 0x40))\n            // Zeroize the length slots.\n            mstore(resultA, 0)\n            mstore(resultB, 0)\n            // Store the lengths and bytes.\n            mstore(add(resultA, 0x1f), packed)\n            mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))\n            // Right pad with zeroes.\n            mstore(add(add(resultA, 0x20), mload(resultA)), 0)\n            mstore(add(add(resultB, 0x20), mload(resultB)), 0)\n        }\n    }\n\n    /// @dev Directly returns `a` without copying.\n    function directReturn(string memory a) internal pure {\n        assembly {\n            // Assumes that the string does not start from the scratch space.\n            let retStart := sub(a, 0x20)\n            let retSize := add(mload(a), 0x40)\n            // Right pad with zeroes. Just in case the string is produced\n            // by a method that doesn't zero right pad.\n            mstore(add(retStart, retSize), 0)\n            // Store the return offset.\n            mstore(retStart, 0x20)\n            // End the transaction, returning the string.\n            return(retStart, retSize)\n        }\n    }\n}\n"
      },
      "src/interfaces/ISafe.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {Safe} from \"@safe-contracts/Safe.sol\";\nimport {Enum} from \"@safe-contracts/common/Enum.sol\";\n\n/**\n * @title ISafe\n * @notice Interface for a multisignature wallet with support for confirmations using\n *         signed messages based on EIP-712.\n */\ninterface ISafe {\n    /** @notice Executes a `operation` {0: Call, 1: DelegateCall}} transaction to `to`\n     *          with `value` (Native Currency) and pays `gasPrice` * `gasLimit` in\n     *          `gasToken` token to `refundReceiver`.\n     *\n     * @dev The fees are always transferred, even if the user transaction fails.\n     *      This method doesn't perform any sanity check of the transaction, such as:\n     *      - if the contract at `to` address has code or not\n     *      - if the `gasToken` is a contract or not\n     *      It is the responsibility of the caller to perform such checks.\n     *\n     * @param to             Destination address of Safe transaction.\n     * @param value          Ether value of Safe transaction.\n     * @param data           Data payload of Safe transaction.\n     * @param operation      Operation type of Safe transaction.\n     * @param safeTxGas      Gas that should be used for the Safe transaction.\n     * @param baseGas        Gas costs that are independent of the transaction\n     *                       execution(e.g. base transaction fee, signature check,\n     *                       payment of the refund).\n     * @param gasPrice       Gas price that should be used for the payment calculation.\n     * @param gasToken       Token address (or 0 if ETH) that is used for the payment.\n     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n     * @param signatures     Signature data that should be verified. Can be packed ECDSA\n     *                       signature ({bytes32 r}{bytes32 s}{uint8 v}), contract\n     *                       signature (EIP-1271) or approved hash.\n     *\n     * @return success Boolean indicating transaction's success.\n     */\n    function execTransaction(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address payable refundReceiver,\n        bytes memory signatures\n    ) external payable returns (bool success);\n\n    /**\n     * @notice Execute `operation` (0: Call, 1: DelegateCall) to `to` with `value`\n     *         (Native Token).\n     *\n     * @dev Function is virtual to allow overriding for L2 singleton to emit an event for\n     *      indexing.\n     *\n     * @param to        Destination address of module transaction.\n     * @param value     Ether value of module transaction.\n     * @param data      Data payload of module transaction.\n     * @param operation Operation type of module transaction.\n     *\n     * @return success  Boolean flag indicating if the call succeeded.\n     */\n    function execTransactionFromModule(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation\n    ) external returns (bool success);\n\n    /**\n     * @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n     *\n     * @dev This can only be done via a Safe transaction.\n     *\n     * @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n     * @param oldOwner  Owner address to be replaced.\n     * @param newOwner  New owner address.\n     */\n    function swapOwner(address prevOwner, address oldOwner, address newOwner) external;\n\n    /**\n     * @notice Enables the module `module` for the Safe.\n     *\n     * @dev This can only be done via a Safe transaction.\n     *\n     * @param module Module to be whitelisted.\n     */\n    function enableModule(address module) external;\n\n    /**\n     * @notice Disables the module `module` for the Safe.\n     *\n     * @dev This can only be done via a Safe transaction.\n     *\n     * @param prevModule Previous module in the modules linked list.\n     * @param module     Module to be removed.\n     */\n    function disableModule(address prevModule, address module) external;\n\n    /**\n     * @notice Set Transaction Guard `guard` for the Safe. Make sure you trust the guard.\n     *\n     * @dev Set a guard that checks transactions before execution\n     *      This can only be done via a Safe transaction.\n     *      ⚠️ IMPORTANT: Since a guard has full power to block Safe transaction execution,\n     *        a broken guard can cause a denial of service for the Safe. Make sure to\n     *        carefully audit the guard code and design recovery mechanisms.\n     *\n     * @param guard The address of the guard to be used or the 0 address to disable the\n     *              guard.\n     */\n    function setGuard(address guard) external;\n\n    /**\n     * @notice Set Fallback Handler to `handler` for the Safe.\n     *\n     * @dev Only fallback calls without value and with data will be forwarded.\n     *      This can only be done via a Safe transaction.\n     *      Cannot be set to the Safe itself.\n     *\n     * @param handler Contract to handle fallback calls.\n     */\n    function setFallbackHandler(address handler) external;\n\n    /**\n     * @notice Sets an initial storage of the Safe contract.\n     *\n     * @dev This method can only be called once. If a proxy was created without setting\n     *      up, anyone can call setup and claim the proxy.\n     *\n     * @param _owners         List of Safe owners.\n     * @param _threshold      Number of required confirmations for a Safe transaction.\n     * @param to              Contract address for optional delegate call.\n     * @param data            Data payload for optional delegate call.\n     * @param fallbackHandler Handler for fallback calls to this contract.\n     * @param paymentToken    Token that should be used for the payment (0 is ETH).\n     * @param payment         Value that should be paid.\n     * @param paymentReceiver Address that should receive the payment (or 0 if tx.origin).\n     */\n    function setup(\n        address[] calldata _owners,\n        uint256 _threshold,\n        address to,\n        bytes calldata data,\n        address fallbackHandler,\n        address paymentToken,\n        uint256 payment,\n        address payable paymentReceiver\n    ) external;\n\n    /**\n     * @notice Returns if `owner` is an owner of the Safe.\n     *\n     * @return Boolean if owner is an owner of the Safe.\n     */\n    function isOwner(address owner) external view returns (bool);\n\n    /**\n     * @notice Returns transaction hash to be signed by owners.\n     *\n     * @param to             Destination address.\n     * @param value          Ether value.\n     * @param data           Data payload.\n     * @param operation      Operation type.\n     * @param safeTxGas      Fas that should be used for the safe transaction.\n     * @param baseGas        Gas costs for data used to trigger the safe transaction.\n     * @param gasPrice       Maximum gas price that should be used for this transaction.\n     * @param gasToken       Token address (or 0 if ETH) that is used for the payment.\n     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n     * @param _nonce         Transaction nonce.\n     *\n     * @return transactionHash Transaction hash to be signed by owners.\n     */\n    function getTransactionHash(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address refundReceiver,\n        uint256 _nonce\n    ) external view returns (bytes32 transactionHash);\n\n    /**\n     * @notice Returns the nonce of the current transaction\n     *\n     * @return nonce The nonce of the current transaction\n     */\n    function nonce() external view returns (uint256 nonce);\n\n    /**\n     * @notice Returns the hash of a message that can be signed by safe owners.\n     *\n     * @param safe    Safe which the message is targeted for.\n     * @param message Message which will be signed.\n     */\n    function getMessageHashForSafe(\n        Safe safe,\n        bytes memory message\n    ) external view returns (bytes32 messageHash);\n}\n"
      },
      "src/interfaces/IHook.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\n/**\n * @title IHook\n * @notice Interface for hook contracts which are capable of being called when a rental\n *         begins, ends, or during a transaction that involves a rented asset.\n */\ninterface IHook {\n    /**\n     * @notice Triggers this hook call during a transaction involving a rented asset with\n     *         an active hook address attached to its metadata.\n     *\n     * @param safe  Rental wallet that initiated the call.\n     * @param to    Recipient of the call.\n     * @param value Value of ether sent with the call.\n     * @param data  Any extra data sent along with the hook.\n     */\n    function onTransaction(\n        address safe,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) external;\n\n    /**\n     * @notice Triggers this hook call when a rental has been started.\n     *\n     * @param safe       Rental wallet which will receive the rented asset associated\n     *                   with this hook.\n     * @param token      Address of the rented asset.\n     * @param identifier ID of the rented asset.\n     * @param amount     Amount of the rented asset being transferred.\n     * @param extraData  Any extra data sent along with the hook.\n     */\n    function onStart(\n        address safe,\n        address token,\n        uint256 identifier,\n        uint256 amount,\n        bytes memory extraData\n    ) external;\n\n    /**\n     * @notice Triggers this hook call when a rental has been stopped.\n     *\n     * @param safe       Rental wallet currently owning the rented asset associated with\n     *                   this hook.\n     * @param token      Address of the rented asset.\n     * @param identifier ID of the rented asset.\n     * @param amount     Amount of the rented asset being transferred.\n     * @param extraData  Any extra data sent along with the hook.\n     */\n    function onStop(\n        address safe,\n        address token,\n        uint256 identifier,\n        uint256 amount,\n        bytes memory extraData\n    ) external;\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/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/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/packages/Signer.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.20;\n\nimport {ECDSA} from \"@openzeppelin-contracts/utils/cryptography/ECDSA.sol\";\n\nimport {\n    RentPayload,\n    Hook,\n    RentalOrder,\n    OrderFulfillment,\n    OrderMetadata,\n    Item\n} from \"@src/libraries/RentalStructs.sol\";\nimport {Errors} from \"@src/libraries/Errors.sol\";\n\n/**\n * @title Signer\n * @notice Contains logic related to signed payloads and signature verification when\n *         creating rentals.\n */\nabstract contract Signer {\n    using ECDSA for bytes32;\n\n    // Declare constants for name and version.\n    string internal constant _NAME = \"ReNFT-Rentals\";\n    string internal constant _VERSION = \"1.0.0\";\n\n    // Precompute hashes, original chainId, and domain separator on deployment.\n    bytes32 internal immutable _NAME_HASH;\n    bytes32 internal immutable _VERSION_HASH;\n    bytes32 internal immutable _EIP_712_DOMAIN_TYPEHASH;\n    uint256 internal immutable _CHAIN_ID;\n    bytes32 internal immutable _DOMAIN_SEPARATOR;\n    bytes32 internal immutable _ITEM_TYPEHASH;\n    bytes32 internal immutable _HOOK_TYPEHASH;\n    bytes32 internal immutable _RENTAL_ORDER_TYPEHASH;\n    bytes32 internal immutable _ORDER_FULFILLMENT_TYPEHASH;\n    bytes32 internal immutable _ORDER_METADATA_TYPEHASH;\n    bytes32 internal immutable _RENT_PAYLOAD_TYPEHASH;\n\n    /**\n     * @dev Sets up the type hashes and sets the chain ID.\n     */\n    constructor() {\n        // Derive name, version, and EIP-712 typehashes.\n        (\n            _NAME_HASH,\n            _VERSION_HASH,\n            _EIP_712_DOMAIN_TYPEHASH,\n            _DOMAIN_SEPARATOR\n        ) = _deriveTypehashes();\n\n        // Derive name and version hashes alongside required EIP-712 typehashes.\n        (\n            _ITEM_TYPEHASH,\n            _HOOK_TYPEHASH,\n            _RENTAL_ORDER_TYPEHASH,\n            _ORDER_FULFILLMENT_TYPEHASH,\n            _ORDER_METADATA_TYPEHASH,\n            _RENT_PAYLOAD_TYPEHASH\n        ) = _deriveRentalTypehashes();\n\n        // Store the current chainId and derive the current domain separator.\n        _CHAIN_ID = block.chainid;\n    }\n\n    /**\n     * @dev Validates that the expected fulfiller of the order is the same as the address\n     *      executed the order. This check is meant to prevent order sniping where one\n     *      party receives a server-side signature but another party intercepts the\n     *      signature and uses it.\n     *\n     * @param intendedFulfiller Address that was expected to execute the order.\n     * @param actualFulfiller   Address that actually executed the order.\n     */\n    function _validateFulfiller(\n        address intendedFulfiller,\n        address actualFulfiller\n    ) internal pure {\n        // Check actual fulfiller against the intended fulfiller.\n        if (intendedFulfiller != actualFulfiller) {\n            revert Errors.SignerPackage_UnauthorizedFulfiller(\n                actualFulfiller,\n                intendedFulfiller\n            );\n        }\n    }\n\n    /**\n     * @dev Validates that the server-side signature has not expired.\n     *\n     * @param expiration Expiration time of the signature.\n     */\n    function _validateProtocolSignatureExpiration(uint256 expiration) internal view {\n        // Check that the signature provided by the protocol signer has not expired.\n        if (block.timestamp > expiration) {\n            revert Errors.SignerPackage_SignatureExpired(block.timestamp, expiration);\n        }\n    }\n\n    /**\n     * @dev Recovers the signer of the payload hash.\n     *\n     * @param payloadHash The payload hash which was signed.\n     * @param signature   The signature data for the payload hash.\n     */\n    function _recoverSignerFromPayload(\n        bytes32 payloadHash,\n        bytes memory signature\n    ) internal view returns (address) {\n        // Derive original EIP-712 digest using domain separator and order hash.\n        bytes32 digest = _DOMAIN_SEPARATOR.toTypedDataHash(payloadHash);\n\n        // Recover the signer address of the signature.\n        return digest.recover(signature);\n    }\n\n    /**\n     * @dev Derives the hash of a given item using a type hash.\n     *\n     * @param item Item to hash.\n     *\n     * @return The hash of the item.\n     */\n    function _deriveItemHash(Item memory item) internal view returns (bytes32) {\n        // Derive and return the item as specified by EIP-712.\n        return\n            keccak256(\n                abi.encode(\n                    _ITEM_TYPEHASH,\n                    item.itemType,\n                    item.settleTo,\n                    item.token,\n                    item.amount,\n                    item.identifier\n                )\n            );\n    }\n\n    /**\n     * @dev Derives the hash of a given hook using a type hash.\n     *\n     * @param hook Hook to hash.\n     *\n     * @return The hash of the hook.\n     */\n    function _deriveHookHash(Hook memory hook) internal view returns (bytes32) {\n        // Derive and return the hook as specified by EIP-712.\n        return\n            keccak256(\n                abi.encode(\n                    _HOOK_TYPEHASH,\n                    hook.target,\n                    hook.itemIndex,\n                    keccak256(hook.extraData)\n                )\n            );\n    }\n\n    /**\n     * @dev Derives the hash of a given rental order using a type hash.\n     *\n     * @param order Rental order to hash.\n     *\n     * @return The hash of the rental order.\n     */\n    function _deriveRentalOrderHash(\n        RentalOrder memory order\n    ) internal view returns (bytes32) {\n        // Create arrays for items and hooks.\n        bytes32[] memory itemHashes = new bytes32[](order.items.length);\n        bytes32[] memory hookHashes = new bytes32[](order.hooks.length);\n\n        // Iterate over each item.\n        for (uint256 i = 0; i < order.items.length; ++i) {\n            // Hash the item.\n            itemHashes[i] = _deriveItemHash(order.items[i]);\n        }\n\n        // Iterate over each hook.\n        for (uint256 i = 0; i < order.hooks.length; ++i) {\n            // Hash the hook.\n            hookHashes[i] = _deriveHookHash(order.hooks[i]);\n        }\n\n        return\n            keccak256(\n                abi.encode(\n                    _RENTAL_ORDER_TYPEHASH,\n                    order.seaportOrderHash,\n                    keccak256(abi.encodePacked(itemHashes)),\n                    keccak256(abi.encodePacked(hookHashes)),\n                    order.orderType,\n                    order.lender,\n                    order.renter,\n                    order.rentalWallet,\n                    order.startTimestamp,\n                    order.endTimestamp\n                )\n            );\n    }\n\n    /**\n     * @dev Derives the hash of a given fulfillment using a type hash.\n     *\n     * @param fulfillment Order fulfillment to hash.\n     *\n     * @return The hash of the order fulfillment.\n     */\n    function _deriveOrderFulfillmentHash(\n        OrderFulfillment memory fulfillment\n    ) internal view returns (bytes32) {\n        // Derive and return the fulfilmment hash as specified by EIP-712\n        return keccak256(abi.encode(_ORDER_FULFILLMENT_TYPEHASH, fulfillment.recipient));\n    }\n\n    /**\n     * @dev Derives the hash of a given order metadata using a type hash.\n     *\n     * @param metadata Order metadata to hash.\n     *\n     * @return The hash of the order metadata.\n     */\n    function _deriveOrderMetadataHash(\n        OrderMetadata memory metadata\n    ) internal view returns (bytes32) {\n        // Create array for hooks.\n        bytes32[] memory hookHashes = new bytes32[](metadata.hooks.length);\n\n        // Iterate over each hook.\n        for (uint256 i = 0; i < metadata.hooks.length; ++i) {\n            // Hash the hook\n            hookHashes[i] = _deriveHookHash(metadata.hooks[i]);\n        }\n\n        // Derive and return the metadata hash as specified by EIP-712.\n        return\n            keccak256(\n                abi.encode(\n                    _ORDER_METADATA_TYPEHASH,\n                    metadata.orderType,\n                    metadata.rentDuration,\n                    keccak256(abi.encodePacked(hookHashes)),\n                    keccak256(metadata.emittedExtraData)\n                )\n            );\n    }\n\n    /**\n     * @dev Derives the hash of a given payload using a type hash.\n     *\n     * @param payload Rent payload to hash.\n     *\n     * @return The hash of the rent payload.\n     */\n    function _deriveRentPayloadHash(\n        RentPayload memory payload\n    ) internal view returns (bytes32) {\n        // Derive and return the rent payload hash as specified by EIP-712.\n        return\n            keccak256(\n                abi.encode(\n                    _RENT_PAYLOAD_TYPEHASH,\n                    payload.orderHash,\n                    _deriveOrderFulfillmentHash(payload.fulfillment),\n                    _deriveOrderMetadataHash(payload.metadata),\n                    payload.expiration,\n                    payload.intendedFulfiller\n                )\n            );\n    }\n\n    /**\n     * @dev Derives the hash of the domain separator.\n     *\n     * @param _eip712DomainTypeHash The standard EIP-712 domain type string.\n     * @param _nameHash             Hash of the contract name.\n     * @param _versionHash          Hash of the contract version.\n     *\n     * @return The hash of the domain separator.\n     */\n    function _deriveDomainSeparator(\n        bytes32 _eip712DomainTypeHash,\n        bytes32 _nameHash,\n        bytes32 _versionHash\n    ) internal view virtual returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    _eip712DomainTypeHash,\n                    _nameHash,\n                    _versionHash,\n                    block.chainid,\n                    address(this)\n                )\n            );\n    }\n\n    /**\n     * @dev Derives the standard EIP-712 type hashes.\n     *\n     * @return nameHash             Hash of the contract name.\n     * @return versionHash          Hash of the contract version.\n     * @return eip712DomainTypehash Hash of the EIP-712 Domain.\n     * @return domainSeparator      The constructed domain separator.\n     */\n    function _deriveTypehashes()\n        internal\n        view\n        returns (\n            bytes32 nameHash,\n            bytes32 versionHash,\n            bytes32 eip712DomainTypehash,\n            bytes32 domainSeparator\n        )\n    {\n        // Derive the name type hash.\n        nameHash = keccak256(bytes(_NAME));\n\n        // Derive the version type hash.\n        versionHash = keccak256(bytes(_VERSION));\n\n        // Construct the primary EIP-712 domain type string.\n        eip712DomainTypehash = keccak256(\n            abi.encodePacked(\n                \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n            )\n        );\n\n        // Construct the domain separator.\n        domainSeparator = _deriveDomainSeparator(\n            eip712DomainTypehash,\n            nameHash,\n            versionHash\n        );\n    }\n\n    /**\n     * @dev Derives the protocol-specific type hashes.\n     *\n     * @return itemTypeHash             Type hash of the item.\n     * @return hookTypeHash             Type hash of the hook.\n     * @return rentalOrderTypeHash      Type hash of the rental order.\n     * @return orderFulfillmentTypeHash Type hash of the order fulfillment.\n     * @return orderMetadataTypeHash    Type hash of the order metadata.\n     * @return rentPayloadTypeHash      Type hash of the rent payload.\n     */\n    function _deriveRentalTypehashes()\n        internal\n        pure\n        returns (\n            bytes32 itemTypeHash,\n            bytes32 hookTypeHash,\n            bytes32 rentalOrderTypeHash,\n            bytes32 orderFulfillmentTypeHash,\n            bytes32 orderMetadataTypeHash,\n            bytes32 rentPayloadTypeHash\n        )\n    {\n        // Construct the Item type string.\n        bytes memory itemTypeString = abi.encodePacked(\n            \"Item(uint8 itemType,uint8 settleTo,address token,uint256 amount,uint256 identifier)\"\n        );\n\n        // Construct the Hook type string.\n        bytes memory hookTypeString = abi.encodePacked(\n            \"Hook(address target,uint256 itemIndex,bytes extraData)\"\n        );\n\n        // Construct the RentalOrder type string.\n        bytes memory rentalOrderTypeString = abi.encodePacked(\n            \"RentalOrder(bytes32 seaportOrderHash,Item[] items,Hook[] hooks,uint8 orderType,address lender,address renter,address rentalWallet,uint256 startTimestamp,uint256 endTimestamp)\"\n        );\n\n        // Derive the Item type hash using the corresponding type string.\n        itemTypeHash = keccak256(itemTypeString);\n\n        // Derive the Hook type hash using the corresponding type string.\n        hookTypeHash = keccak256(hookTypeString);\n\n        // Derive the RentalOrder type hash using the corresponding type string.\n        rentalOrderTypeHash = keccak256(\n            abi.encodePacked(rentalOrderTypeString, hookTypeString, itemTypeString)\n        );\n\n        {\n            // Construct the OrderFulfillment type string.\n            bytes memory orderFulfillmentTypeString = abi.encodePacked(\n                \"OrderFulfillment(address recipient)\"\n            );\n\n            // Construct the OrderMetadata type string.\n            bytes memory orderMetadataTypeString = abi.encodePacked(\n                \"OrderMetadata(uint8 orderType,uint256 rentDuration,Hook[] hooks,bytes emittedExtraData)\"\n            );\n\n            // Construct the RentPayload type string.\n            bytes memory rentPayloadTypeString = abi.encodePacked(\n                \"RentPayload(bytes32 orderHash,OrderFulfillment fulfillment,OrderMetadata metadata,uint256 expiration,address intendedFulfiller)\"\n            );\n\n            // Derive RentPayload type hash via combination of relevant type strings.\n            rentPayloadTypeHash = keccak256(\n                abi.encodePacked(\n                    rentPayloadTypeString,\n                    orderFulfillmentTypeString,\n                    orderMetadataTypeString\n                )\n            );\n\n            // Derive the OrderFulfillment type hash using the corresponding type string.\n            orderFulfillmentTypeHash = keccak256(orderFulfillmentTypeString);\n\n            // Derive the OrderMetadata type hash using the corresponding type string.\n            orderMetadataTypeHash = keccak256(orderMetadataTypeString);\n        }\n    }\n}\n"
      },
      "src/packages/Reclaimer.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.20;\n\nimport {IERC721} from \"@openzeppelin-contracts/token/ERC721/IERC721.sol\";\nimport {IERC1155} from \"@openzeppelin-contracts/token/ERC1155/IERC1155.sol\";\n\nimport {RentalOrder, Item, ItemType} from \"@src/libraries/RentalStructs.sol\";\nimport {Errors} from \"@src/libraries/Errors.sol\";\nimport {Transferer} from \"@src/libraries/Transferer.sol\";\n\n/**\n * @title Reclaimer\n * @notice Retrieves rented assets from a wallet contract once a rental has been\n *         stopped, and transfers them to the proper recipient.\n */\nabstract contract Reclaimer {\n    using Transferer for Item;\n\n    // The original address that this contract was deployed with\n    address private immutable original;\n\n    /**\n     * @dev Use the constructor to store the original deployment address.\n     */\n    constructor() {\n        original = address(this);\n    }\n\n    /**\n     * @notice Reclaims the assets that are currently owned by a rental safe.\n     *         This function is intended to be delegate called by the safe.\n     *\n     *         NOTE: At first, it may seem that this function can be used to exploit\n     *         the safe, since this is an external function that can transfer tokens\n     *         out of a rental safe, so long as the caller is:\n     *             1) Using delegate call to extract the assets\n     *             2) The rental safe that holds those assets\n     *\n     *         This exploit is prevented because delegate calls from the rental safe can\n     *         only be made to addresses which have been explicitly whitelisted by the\n     *         Admin policy. Further, since the Stop policy is a whitelisted module on\n     *         the safe, `reclaimRentalOrder()` can only be called via the context of the\n     *         Stop policy contract, which prevents unauthorized reclaiming.\n     *\n     * @param rentalOrder Order which will have its contained items reclaimed by the\n     *                    recipient parties.\n     */\n    function reclaimRentalOrder(RentalOrder calldata rentalOrder) external {\n        // This contract address must be in the context of another address.\n        if (address(this) == original) {\n            revert Errors.ReclaimerPackage_OnlyDelegateCallAllowed();\n        }\n\n        // Only the rental wallet specified in the order can be the address that\n        // initates the reclaim. In the context of a delegate call, address(this)\n        // will be the safe.\n        if (address(this) != rentalOrder.rentalWallet) {\n            revert Errors.ReclaimerPackage_OnlyRentalSafeAllowed(\n                rentalOrder.rentalWallet\n            );\n        }\n\n        // Get a count for the number of items.\n        uint256 itemCount = rentalOrder.items.length;\n\n        // Transfer each item if it is a rented asset.\n        for (uint256 i = 0; i < itemCount; ++i) {\n            Item memory item = rentalOrder.items[i];\n\n            // Check if the item is an ERC721.\n            if (item.itemType == ItemType.ERC721) item.transferERC721(rentalOrder.lender);\n\n            // check if the item is an ERC1155.\n            if (item.itemType == ItemType.ERC1155)\n                item.transferERC1155(rentalOrder.lender);\n        }\n    }\n}\n"
      },
      "src/packages/Accumulator.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.20;\n\nimport {RentalId, RentalAssetUpdate} from \"@src/libraries/RentalStructs.sol\";\n\n/**\n * @title Accumulator\n * @notice Package that implements functionality for managing dynamically allocated data\n *         struct arrays directly in memory. The rationale for this was the need for an\n *         array of structs where the total size is not known at instantiation.\n */\nabstract contract Accumulator {\n    /**\n     * @dev Accumulates an intermediary representation of a dynamic array of\n     *      `RentalAssetUpdate` structs.\n     *\n     * In memory, the format of `rentalAssets` will be as follows:\n     *\n     * 0x00: Length of the intermediary representation bytes data\n     * 0x20: Number of `RentalAssetUpdate` elements stored\n     * 0x40: `rentalId` of the first element\n     * 0x60: `amount` of the first element\n     * 0x80: `rentalId` of the second element\n     * 0xa0: `amount` of the second element\n     * 0xc0: ...\n     *\n     * @param rentalAssets      Bytes value which will accumulate `RentalAssetUpdate`\n     *                          structs.\n     * @param rentalId          Rental ID to include in the next `RentalAssetUpdate`.\n     * @param rentalAssetAmount Amount to include in the next `RentalAssetUpdate`.\n     */\n    function _insert(\n        bytes memory rentalAssets,\n        RentalId rentalId,\n        uint256 rentalAssetAmount\n    ) internal pure {\n        // Place the rental ID on the stack.\n        bytes32 _rentalId = RentalId.unwrap(rentalId);\n\n        assembly {\n            // This is the first time inserting into this bytes data.\n            if eq(mload(rentalAssets), 0) {\n                // Create some space for the initial element length word.\n                mstore(rentalAssets, 0x20)\n\n                // Zero out the number of elements.\n                mstore(add(0x20, rentalAssets), 0x00)\n            }\n\n            // Calculate the new size of the bytes data by adding\n            // the size of a `RentalAssetUpdate` struct.\n            let newByteDataSize := add(mload(rentalAssets), 0x40)\n\n            // Get the pointer for where the element data begins.\n            let rentalAssetElementPtr := add(rentalAssets, 0x20)\n\n            // Increase the number of rental elements by one.\n            let elements := add(mload(rentalAssetElementPtr), 1)\n\n            // Calculate the position for the new rental ID.\n            // To do this, calculate the total length of the element portion, then\n            // subtract by the initial offset. In this case, the offset is the 32-byte\n            // word (0x20) which contains the length of the array.\n            let newItemPosition := add(\n                rentalAssetElementPtr,\n                sub(mul(elements, 0x40), 0x20)\n            )\n\n            // Store the new byte data size\n            mstore(rentalAssets, newByteDataSize)\n\n            // Store the new number of elements\n            mstore(rentalAssetElementPtr, elements)\n\n            // Store the rental ID\n            mstore(newItemPosition, _rentalId)\n\n            // Store the amount in the adjacent 32-byte word\n            mstore(add(newItemPosition, 0x20), rentalAssetAmount)\n\n            // Update the free memory pointer so that memory is safe\n            // once we stop doing dynamic memory array inserts\n            mstore(0x40, add(newItemPosition, 0x40))\n        }\n    }\n\n    /**\n     * @dev Converts an intermediary dynamic array of `RentalAssetUpdate` into a\n     *      conventional Solidity array.\n     *\n     * @param rentalAssetUpdates Bytes data that represents an array of\n     *                           `RentalAssetUpdate` structs.\n     *\n     * @return updates Solidity representation of a `RentalAssetUpdate` array.\n     */\n    function _convertToStatic(\n        bytes memory rentalAssetUpdates\n    ) internal pure returns (RentalAssetUpdate[] memory updates) {\n        // Pointer to the rental asset update data.\n        bytes32 rentalAssetUpdatePointer;\n\n        // Load the length of the rental asset update items.\n        uint256 rentalAssetUpdateLength;\n        assembly {\n            // Get a pointer to the number of elements in the bytes data.\n            // With the 0x20 offset, we would be loading the length of the entire\n            // byte string, but we want the element length which starts one\n            // word to the right.\n            rentalAssetUpdatePointer := add(0x20, rentalAssetUpdates)\n\n            // Load the number of elements.\n            rentalAssetUpdateLength := mload(rentalAssetUpdatePointer)\n        }\n\n        // Instantiate the update array.\n        updates = new RentalAssetUpdate[](rentalAssetUpdateLength);\n\n        // Iterate through each item in the byte data, and add it as\n        // an entry to the array.\n        for (uint256 i = 0; i < rentalAssetUpdateLength; ++i) {\n            // Define the placeholders.\n            RentalId rentalId;\n            uint256 amount;\n\n            // Extract the current element from the byte data.\n            assembly {\n                // Determine element offset by multiplying the length of a\n                // RentalAssetUpdate struct (0x40) by the current index, then\n                // add a word to make sure the next word is accessed because the\n                // offset defaults to being set to the length pointer.\n                let currentElementOffset := add(0x20, mul(i, 0x40))\n\n                // Load the rental ID starting at the data pointer.\n                rentalId := mload(add(rentalAssetUpdatePointer, currentElementOffset))\n\n                // Load the amount at the data pointer adjacent to it.\n                amount := mload(\n                    add(0x20, add(rentalAssetUpdatePointer, currentElementOffset))\n                )\n            }\n\n            // Set the items\n            updates[i] = RentalAssetUpdate(rentalId, amount);\n        }\n    }\n}\n"
      },
      "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/modules/PaymentEscrow.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"@openzeppelin-contracts/token/ERC20/IERC20.sol\";\n\nimport {Kernel, Module, Keycode} from \"@src/Kernel.sol\";\nimport {Proxiable} from \"@src/proxy/Proxiable.sol\";\nimport {\n    RentalOrder,\n    Item,\n    ItemType,\n    SettleTo,\n    OrderType\n} from \"@src/libraries/RentalStructs.sol\";\nimport {Errors} from \"@src/libraries/Errors.sol\";\nimport {Events} from \"@src/libraries/Events.sol\";\nimport {RentalUtils} from \"@src/libraries/RentalUtils.sol\";\nimport {Transferer} from \"@src/libraries/Transferer.sol\";\n\n/**\n * @title PaymentEscrowBase\n * @notice Storage exists in its own base contract to avoid storage slot mismatch during upgrades.\n */\ncontract PaymentEscrowBase {\n    // Keeps a record of the current token balances in the escrow.\n    mapping(address token => uint256 amount) public balanceOf;\n\n    // Fee percentage taken from payments.\n    uint256 public fee;\n}\n\n/**\n * @title PaymentEscrow\n * @notice Module dedicated to escrowing rental payments while rentals are active. When\n *         rentals are stopped, this module will determine payouts to all parties and a\n *         fee will be reserved to be withdrawn later by a protocol admin.\n */\ncontract PaymentEscrow is Proxiable, Module, PaymentEscrowBase {\n    using Transferer for address;\n    using RentalUtils for Item;\n    using RentalUtils for OrderType;\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(\"ESCRW\");\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            Internal Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @dev Calculates the fee based on the fee numerator set by an admin.\n     *\n     * @param amount Amount for which to calculate the fee.\n     */\n    function _calculateFee(uint256 amount) internal view returns (uint256) {\n        // Uses 10,000 as a denominator for the fee.\n        return (amount * fee) / 10000;\n    }\n\n    /**\n     * @dev Calculates the pro-rata split based on the amount of time that has elapsed in\n     *      a rental order. If there are not enough funds to split perfectly, rounding is\n     *      done to make the split as fair as possible.\n     *\n     * @param amount      Amount of tokens for which to calculate the split.\n     * @param elapsedTime Elapsed time since the rental started.\n     * @param totalTime   Total time window of the rental from start to end.\n     *\n     * @return renterAmount Payment amount to send to the renter.\n     * @return lenderAmount Payment amoutn to send to the lender.\n     */\n    function _calculatePaymentProRata(\n        uint256 amount,\n        uint256 elapsedTime,\n        uint256 totalTime\n    ) internal pure returns (uint256 renterAmount, uint256 lenderAmount) {\n        // Calculate the numerator and adjust by a multiple of 1000.\n        uint256 numerator = (amount * elapsedTime) * 1000;\n\n        // Calculate the result, but bump by 500 to add a rounding adjustment. Then,\n        // reduce by a multiple of 1000.\n        renterAmount = ((numerator / totalTime) + 500) / 1000;\n\n        // Calculate lender amount from renter amount so no tokens are left behind.\n        lenderAmount = amount - renterAmount;\n    }\n\n    /**\n     * @dev Settles a payment via a pro-rata split. After payments are calculated, they\n     *      are transferred to their respective recipients.\n     *\n     * @param token       Token address for which to settle a payment.\n     * @param amount      Amount of the token to settle.\n     * @param lender      Lender account.\n     * @param renter      Renter accoutn.\n     * @param elapsedTime Elapsed time since the rental started.\n     * @param totalTime   Total time window of the rental from start to end.\n     */\n    function _settlePaymentProRata(\n        address token,\n        uint256 amount,\n        address lender,\n        address renter,\n        uint256 elapsedTime,\n        uint256 totalTime\n    ) internal {\n        // Calculate the pro-rata payment for renter and lender.\n        (uint256 renterAmount, uint256 lenderAmount) = _calculatePaymentProRata(\n            amount,\n            elapsedTime,\n            totalTime\n        );\n\n        // Send the lender portion of the payment.\n        token.transferERC20(lender, lenderAmount);\n\n        // Send the renter portion of the payment.\n        token.transferERC20(renter, renterAmount);\n    }\n\n    /**\n     * @dev Settles a payment by sending the full amount to one address.\n     *\n     * @param token    Token address for which to settle a payment.\n     * @param amount   Amount of the token to settle.\n     * @param settleTo Specifies whether to settle to the lender or the renter.\n     * @param lender   Lender account.\n     * @param renter   Renter account.\n     */\n    function _settlePaymentInFull(\n        address token,\n        uint256 amount,\n        SettleTo settleTo,\n        address lender,\n        address renter\n    ) internal {\n        // Determine the address that this payment will settle to.\n        address settleToAddress = settleTo == SettleTo.LENDER ? lender : renter;\n\n        // Send the payment.\n        token.transferERC20(settleToAddress, amount);\n    }\n\n    /**\n     * @dev Settles alls payments contained in the given item. Uses a pro-rata or in full\n     *      scheme depending on the order type and when the order was stopped.\n     *\n     * @param items     Items present in the order.\n     * @param orderType Type of the order.\n     * @param lender    Lender account.\n     * @param renter    Renter account.\n     * @param start     Timestamp that the rental began.\n     * @param end       Timestamp that the rental expires at.\n     */\n    function _settlePayment(\n        Item[] calldata items,\n        OrderType orderType,\n        address lender,\n        address renter,\n        uint256 start,\n        uint256 end\n    ) internal {\n        // Calculate the time values.\n        uint256 elapsedTime = block.timestamp - start;\n        uint256 totalTime = end - start;\n\n        // Determine whether the rental order has ended.\n        bool isRentalOver = elapsedTime >= totalTime;\n\n        // Loop through each item in the order.\n        for (uint256 i = 0; i < items.length; ++i) {\n            // Get the item.\n            Item memory item = items[i];\n\n            // Check that the item is a payment.\n            if (item.isERC20()) {\n                // Set a placeholder payment amount which can be reduced in the\n                // presence of a fee.\n                uint256 paymentAmount = item.amount;\n\n                // Take a fee on the payment amount if the fee is on.\n                if (fee != 0) {\n                    // Calculate the new fee.\n                    uint256 paymentFee = _calculateFee(paymentAmount);\n\n                    // Adjust the payment amount by the fee.\n                    paymentAmount -= paymentFee;\n                }\n\n                // Effect: Decrease the token balance. Use the payment amount pre-fee\n                // so that fees can be taken.\n                _decreaseDeposit(item.token, item.amount);\n\n                // If its a PAY order but the rental hasn't ended yet.\n                if (orderType.isPayOrder() && !isRentalOver) {\n                    // Interaction: a PAY order which hasnt ended yet. Payout is pro-rata.\n                    _settlePaymentProRata(\n                        item.token,\n                        paymentAmount,\n                        lender,\n                        renter,\n                        elapsedTime,\n                        totalTime\n                    );\n                }\n                // If its a PAY order and the rental is over, or, if its a BASE order.\n                else if (\n                    (orderType.isPayOrder() && isRentalOver) || orderType.isBaseOrder()\n                ) {\n                    // Interaction: a pay order or base order which has ended. Payout is in full.\n                    _settlePaymentInFull(\n                        item.token,\n                        paymentAmount,\n                        item.settleTo,\n                        lender,\n                        renter\n                    );\n                } else {\n                    revert Errors.Shared_OrderTypeNotSupported(uint8(orderType));\n                }\n            }\n        }\n    }\n\n    /**\n     * @dev Decreases the tracked token balance of a particular token on the payment\n     *      escrow contract.\n     *\n     * @param token  Token address.\n     * @param amount Amount to decrease the balance by.\n     */\n    function _decreaseDeposit(address token, uint256 amount) internal {\n        // Directly decrease the synced balance.\n        balanceOf[token] -= amount;\n    }\n\n    /**\n     * @dev Increases the tracked token balance of a particular token on the payment\n     *      escrow contract.\n     *\n     * @param token  Token address.\n     * @param amount Amount to increase the balance by.\n     */\n    function _increaseDeposit(address token, uint256 amount) internal {\n        // Directly increase the synced balance.\n        balanceOf[token] += amount;\n    }\n\n    /////////////////////////////////////////////////////////////////////////////////\n    //                            External Functions                               //\n    /////////////////////////////////////////////////////////////////////////////////\n\n    /**\n     * @notice Settles the payment for a rental order by transferring all items marked as\n     *         payments to their destination accounts. During the settlement process, if\n     *         active, a fee is taken on the payment.\n     *\n     * @param order Rental order for which to settle a payment.\n     */\n    function settlePayment(RentalOrder calldata order) external onlyByProxy permissioned {\n        // Settle all payments for the order.\n        _settlePayment(\n            order.items,\n            order.orderType,\n            order.lender,\n            order.renter,\n            order.startTimestamp,\n            order.endTimestamp\n        );\n    }\n\n    /**\n     * @notice Settles the payments for multiple orders by looping through each one.\n     *\n     * @param orders Rental ordesr for which to settle payments.\n     */\n    function settlePaymentBatch(\n        RentalOrder[] calldata orders\n    ) external onlyByProxy permissioned {\n        // Loop through each order.\n        for (uint256 i = 0; i < orders.length; ++i) {\n            // Settle all payments for the order.\n            _settlePayment(\n                orders[i].items,\n                orders[i].orderType,\n                orders[i].lender,\n                orders[i].renter,\n                orders[i].startTimestamp,\n                orders[i].endTimestamp\n            );\n        }\n    }\n\n    /**\n     * @notice When fungible tokens are transferred to the payment escrow contract,\n     *         their balances should be increased.\n     *\n     * @param token  Token address for the asset.\n     * @param amount Amount of the token transferred to the escrow\n     */\n    function increaseDeposit(\n        address token,\n        uint256 amount\n    ) external onlyByProxy permissioned {\n        // Check: Cannot accept a payment of zero.\n        if (amount == 0) {\n            revert Errors.PaymentEscrow_ZeroPayment();\n        }\n\n        // Effect: Increase the deposit\n        _increaseDeposit(token, amount);\n    }\n\n    /**\n     * @notice Sets the numerator for the fee. The denominator will always be set at\n     *         10,000.\n     *\n     * @param feeNumerator Numerator of the fee.\n     */\n    function setFee(uint256 feeNumerator) external onlyByProxy permissioned {\n        // Cannot accept a fee numerator greater than 10000.\n        if (feeNumerator > 10000) {\n            revert Errors.PaymentEscrow_InvalidFeeNumerator();\n        }\n\n        // Set the fee.\n        fee = feeNumerator;\n    }\n\n    /**\n     * @notice Used to collect protocol fees. In addition, if funds are accidentally sent\n     *         to the payment escrow contract, this function can be used to skim them off.\n     *\n     * @param token Address of the token to skim.\n     * @param to    Address to send the collected tokens.\n     */\n    function skim(address token, address to) external onlyByProxy permissioned {\n        // Fetch the currently synced balance of the escrow.\n        uint256 syncedBalance = balanceOf[token];\n\n        // Fetch the true token balance of the escrow.\n        uint256 trueBalance = IERC20(token).balanceOf(address(this));\n\n        // Calculate the amount to skim.\n        uint256 skimmedBalance = trueBalance - syncedBalance;\n\n        // Send the difference to the specified address.\n        token.transferERC20(to, skimmedBalance);\n\n        // Emit event with fees taken.\n        emit Events.FeeTaken(token, skimmedBalance);\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"
      },
      "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/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"
      },
      "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"
      },
      "lib/safe-contracts/contracts/Safe.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/NativeCurrencyPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/SafeMath.sol\";\n\n/**\n * @title Safe - A multisignature wallet with support for confirmations using signed messages based on EIP-712.\n * @dev Most important concepts:\n *      - Threshold: Number of required confirmations for a Safe transaction.\n *      - Owners: List of addresses that control the Safe. They are the only ones that can add/remove owners, change the threshold and\n *        approve transactions. Managed in `OwnerManager`.\n *      - Transaction Hash: Hash of a transaction is calculated using the EIP-712 typed structured data hashing scheme.\n *      - Nonce: Each transaction should have a different nonce to prevent replay attacks.\n *      - Signature: A valid signature of an owner of the Safe for a transaction hash.\n *      - Guard: Guard is a contract that can execute pre- and post- transaction checks. Managed in `GuardManager`.\n *      - Modules: Modules are contracts that can be used to extend the write functionality of a Safe. Managed in `ModuleManager`.\n *      - Fallback: Fallback handler is a contract that can provide additional read-only functional for Safe. Managed in `FallbackManager`.\n *      Note: This version of the implementation contract doesn't emit events for the sake of gas efficiency and therefore requires a tracing node for indexing/\n *      For the events-based implementation see `SafeL2.sol`.\n * @author Stefan George - @Georgi87\n * @author Richard Meissner - @rmeissner\n */\ncontract Safe is\n    Singleton,\n    NativeCurrencyPaymentFallback,\n    ModuleManager,\n    OwnerManager,\n    SignatureDecoder,\n    SecuredTokenTransfer,\n    ISignatureValidatorConstants,\n    FallbackManager,\n    StorageAccessible,\n    GuardManager\n{\n    using SafeMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    // keccak256(\n    //     \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n    // );\n    bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n    // keccak256(\n    //     \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n    // );\n    bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n    event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n    event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n    event SignMsg(bytes32 indexed msgHash);\n    event ExecutionFailure(bytes32 indexed txHash, uint256 payment);\n    event ExecutionSuccess(bytes32 indexed txHash, uint256 payment);\n\n    uint256 public nonce;\n    bytes32 private _deprecatedDomainSeparator;\n    // Mapping to keep track of all message hashes that have been approved by ALL REQUIRED owners\n    mapping(bytes32 => uint256) public signedMessages;\n    // Mapping to keep track of all hashes (message or transaction) that have been approved by ANY owners\n    mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n    // This constructor ensures that this contract can only be used as a singleton for Proxy contracts\n    constructor() {\n        /**\n         * By setting the threshold it is not possible to call setup anymore,\n         * so we create a Safe with 0 owners and threshold 1.\n         * This is an unusable Safe, perfect for the singleton\n         */\n        threshold = 1;\n    }\n\n    /**\n     * @notice Sets an initial storage of the Safe contract.\n     * @dev This method can only be called once.\n     *      If a proxy was created without setting up, anyone can call setup and claim the proxy.\n     * @param _owners List of Safe owners.\n     * @param _threshold Number of required confirmations for a Safe transaction.\n     * @param to Contract address for optional delegate call.\n     * @param data Data payload for optional delegate call.\n     * @param fallbackHandler Handler for fallback calls to this contract\n     * @param paymentToken Token that should be used for the payment (0 is ETH)\n     * @param payment Value that should be paid\n     * @param paymentReceiver Address that should receive the payment (or 0 if tx.origin)\n     */\n    function setup(\n        address[] calldata _owners,\n        uint256 _threshold,\n        address to,\n        bytes calldata data,\n        address fallbackHandler,\n        address paymentToken,\n        uint256 payment,\n        address payable paymentReceiver\n    ) external {\n        // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n        setupOwners(_owners, _threshold);\n        if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n        // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n        setupModules(to, data);\n\n        if (payment > 0) {\n            // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n            // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n            handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n        }\n        emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n    }\n\n    /** @notice Executes a `operation` {0: Call, 1: DelegateCall}} transaction to `to` with `value` (Native Currency)\n     *          and pays `gasPrice` * `gasLimit` in `gasToken` token to `refundReceiver`.\n     * @dev The fees are always transferred, even if the user transaction fails.\n     *      This method doesn't perform any sanity check of the transaction, such as:\n     *      - if the contract at `to` address has code or not\n     *      - if the `gasToken` is a contract or not\n     *      It is the responsibility of the caller to perform such checks.\n     * @param to Destination address of Safe transaction.\n     * @param value Ether value of Safe transaction.\n     * @param data Data payload of Safe transaction.\n     * @param operation Operation type of Safe transaction.\n     * @param safeTxGas Gas that should be used for the Safe transaction.\n     * @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n     * @param gasPrice Gas price that should be used for the payment calculation.\n     * @param gasToken Token address (or 0 if ETH) that is used for the payment.\n     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n     * @param signatures Signature data that should be verified.\n     *                   Can be packed ECDSA signature ({bytes32 r}{bytes32 s}{uint8 v}), contract signature (EIP-1271) or approved hash.\n     * @return success Boolean indicating transaction's success.\n     */\n    function execTransaction(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address payable refundReceiver,\n        bytes memory signatures\n    ) public payable virtual returns (bool success) {\n        bytes32 txHash;\n        // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n        {\n            bytes memory txHashData = encodeTransactionData(\n                // Transaction info\n                to,\n                value,\n                data,\n                operation,\n                safeTxGas,\n                // Payment info\n                baseGas,\n                gasPrice,\n                gasToken,\n                refundReceiver,\n                // Signature info\n                nonce\n            );\n            // Increase nonce and execute transaction.\n            nonce++;\n            txHash = keccak256(txHashData);\n            checkSignatures(txHash, txHashData, signatures);\n        }\n        address guard = getGuard();\n        {\n            if (guard != address(0)) {\n                Guard(guard).checkTransaction(\n                    // Transaction info\n                    to,\n                    value,\n                    data,\n                    operation,\n                    safeTxGas,\n                    // Payment info\n                    baseGas,\n                    gasPrice,\n                    gasToken,\n                    refundReceiver,\n                    // Signature info\n                    signatures,\n                    msg.sender\n                );\n            }\n        }\n        // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n        // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n        require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n        // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n        {\n            uint256 gasUsed = gasleft();\n            // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n            // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n            success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n            gasUsed = gasUsed.sub(gasleft());\n            // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n            // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n            require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n            // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n            uint256 payment = 0;\n            if (gasPrice > 0) {\n                payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n            }\n            if (success) emit ExecutionSuccess(txHash, payment);\n            else emit ExecutionFailure(txHash, payment);\n        }\n        {\n            if (guard != address(0)) {\n                Guard(guard).checkAfterExecution(txHash, success);\n            }\n        }\n    }\n\n    /**\n     * @notice Handles the payment for a Safe transaction.\n     * @param gasUsed Gas used by the Safe transaction.\n     * @param baseGas Gas costs that are independent of the transaction execution (e.g. base transaction fee, signature check, payment of the refund).\n     * @param gasPrice Gas price that should be used for the payment calculation.\n     * @param gasToken Token address (or 0 if ETH) that is used for the payment.\n     * @return payment The amount of payment made in the specified token.\n     */\n    function handlePayment(\n        uint256 gasUsed,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address payable refundReceiver\n    ) private returns (uint256 payment) {\n        // solhint-disable-next-line avoid-tx-origin\n        address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n        if (gasToken == address(0)) {\n            // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n            payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n            require(receiver.send(payment), \"GS011\");\n        } else {\n            payment = gasUsed.add(baseGas).mul(gasPrice);\n            require(transferToken(gasToken, receiver, payment), \"GS012\");\n        }\n    }\n\n    /**\n     * @notice Checks whether the signature provided is valid for the provided data and hash. Reverts otherwise.\n     * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n     * @param data That should be signed (this is passed to an external validator contract)\n     * @param signatures Signature data that should be verified.\n     *                   Can be packed ECDSA signature ({bytes32 r}{bytes32 s}{uint8 v}), contract signature (EIP-1271) or approved hash.\n     */\n    function checkSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures) public view {\n        // Load threshold to avoid multiple storage loads\n        uint256 _threshold = threshold;\n        // Check that a threshold is set\n        require(_threshold > 0, \"GS001\");\n        checkNSignatures(dataHash, data, signatures, _threshold);\n    }\n\n    /**\n     * @notice Checks whether the signature provided is valid for the provided data and hash. Reverts otherwise.\n     * @dev Since the EIP-1271 does an external call, be mindful of reentrancy attacks.\n     * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n     * @param data That should be signed (this is passed to an external validator contract)\n     * @param signatures Signature data that should be verified.\n     *                   Can be packed ECDSA signature ({bytes32 r}{bytes32 s}{uint8 v}), contract signature (EIP-1271) or approved hash.\n     * @param requiredSignatures Amount of required valid signatures.\n     */\n    function checkNSignatures(bytes32 dataHash, bytes memory data, bytes memory signatures, uint256 requiredSignatures) public view {\n        // Check that the provided signature data is not too short\n        require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n        // There cannot be an owner with address 0.\n        address lastOwner = address(0);\n        address currentOwner;\n        uint8 v;\n        bytes32 r;\n        bytes32 s;\n        uint256 i;\n        for (i = 0; i < requiredSignatures; i++) {\n            (v, r, s) = signatureSplit(signatures, i);\n            if (v == 0) {\n                require(keccak256(data) == dataHash, \"GS027\");\n                // If v is 0 then it is a contract signature\n                // When handling contract signatures the address of the contract is encoded into r\n                currentOwner = address(uint160(uint256(r)));\n\n                // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n                // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n                // Here we only check that the pointer is not pointing inside the part that is being processed\n                require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n                // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n                require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n                // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n                uint256 contractSignatureLen;\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    contractSignatureLen := mload(add(add(signatures, s), 0x20))\n                }\n                require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n                // Check signature\n                bytes memory contractSignature;\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n                    contractSignature := add(add(signatures, s), 0x20)\n                }\n                require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n            } else if (v == 1) {\n                // If v is 1 then it is an approved hash\n                // When handling approved hashes the address of the approver is encoded into r\n                currentOwner = address(uint160(uint256(r)));\n                // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n                require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n            } else if (v > 30) {\n                // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n                // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n                currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n            } else {\n                // Default is the ecrecover flow with the provided data hash\n                // Use ecrecover with the messageHash for EOA signatures\n                currentOwner = ecrecover(dataHash, v, r, s);\n            }\n            require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n            lastOwner = currentOwner;\n        }\n    }\n\n    /**\n     * @notice Marks hash `hashToApprove` as approved.\n     * @dev This can be used with a pre-approved hash transaction signature.\n     *      IMPORTANT: The approved hash stays approved forever. There's no revocation mechanism, so it behaves similarly to ECDSA signatures\n     * @param hashToApprove The hash to mark as approved for signatures that are verified by this contract.\n     */\n    function approveHash(bytes32 hashToApprove) external {\n        require(owners[msg.sender] != address(0), \"GS030\");\n        approvedHashes[msg.sender][hashToApprove] = 1;\n        emit ApproveHash(hashToApprove, msg.sender);\n    }\n\n    /**\n     * @notice Returns the ID of the chain the contract is currently deployed on.\n     * @return The ID of the current chain as a uint256.\n     */\n    function getChainId() public view returns (uint256) {\n        uint256 id;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            id := chainid()\n        }\n        return id;\n    }\n\n    /**\n     * @dev Returns the domain separator for this contract, as defined in the EIP-712 standard.\n     * @return bytes32 The domain separator hash.\n     */\n    function domainSeparator() public view returns (bytes32) {\n        return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n    }\n\n    /**\n     * @notice Returns the pre-image of the transaction hash (see getTransactionHash).\n     * @param to Destination address.\n     * @param value Ether value.\n     * @param data Data payload.\n     * @param operation Operation type.\n     * @param safeTxGas Gas that should be used for the safe transaction.\n     * @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n     * @param gasPrice Maximum gas price that should be used for this transaction.\n     * @param gasToken Token address (or 0 if ETH) that is used for the payment.\n     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n     * @param _nonce Transaction nonce.\n     * @return Transaction hash bytes.\n     */\n    function encodeTransactionData(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address refundReceiver,\n        uint256 _nonce\n    ) public view returns (bytes memory) {\n        bytes32 safeTxHash = keccak256(\n            abi.encode(\n                SAFE_TX_TYPEHASH,\n                to,\n                value,\n                keccak256(data),\n                operation,\n                safeTxGas,\n                baseGas,\n                gasPrice,\n                gasToken,\n                refundReceiver,\n                _nonce\n            )\n        );\n        return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n    }\n\n    /**\n     * @notice Returns transaction hash to be signed by owners.\n     * @param to Destination address.\n     * @param value Ether value.\n     * @param data Data payload.\n     * @param operation Operation type.\n     * @param safeTxGas Fas that should be used for the safe transaction.\n     * @param baseGas Gas costs for data used to trigger the safe transaction.\n     * @param gasPrice Maximum gas price that should be used for this transaction.\n     * @param gasToken Token address (or 0 if ETH) that is used for the payment.\n     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n     * @param _nonce Transaction nonce.\n     * @return Transaction hash.\n     */\n    function getTransactionHash(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address refundReceiver,\n        uint256 _nonce\n    ) public view returns (bytes32) {\n        return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n    }\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/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.19;\n\nimport {Strings} from \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS\n    }\n\n    /**\n     * @dev The signature derives the `address(0)`.\n     */\n    error ECDSAInvalidSignature();\n\n    /**\n     * @dev The signature has an invalid length.\n     */\n    error ECDSAInvalidSignatureLength(uint256 length);\n\n    /**\n     * @dev The signature has an S value that is in the upper half order.\n     */\n    error ECDSAInvalidSignatureS(bytes32 s);\n\n    function _throwError(RecoverError error, bytes32 errorArg) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert ECDSAInvalidSignature();\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert ECDSAInvalidSignatureLength(uint256(errorArg));\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert ECDSAInvalidSignatureS(errorArg);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {\n        unchecked {\n            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n            // We do not check for an overflow here since the shift operation results in 0 or 1.\n            uint8 v = uint8((uint256(vs) >> 255) + 27);\n            return tryRecover(hash, v, r, s);\n        }\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError, bytes32) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS, s);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature, bytes32(0));\n        }\n\n        return (signer, RecoverError.NoError, bytes32(0));\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n            mstore(0x1c, hash)\n            message := keccak256(0x00, 0x3c)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, hex\"19_01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            data := keccak256(ptr, 0x42)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\n     * `validator` and `data` according to the version 0 of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(hex\"19_00\", validator, data));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.19;\n\nimport {IERC165} from \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n     * understand this adds an external call which potentially creates a reentrancy vulnerability.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.19;\n\nimport {IERC165} from \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n    /**\n     * @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`.\n     */\n    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n    /**\n     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n     * transfers.\n     */\n    event TransferBatch(\n        address indexed operator,\n        address indexed from,\n        address indexed to,\n        uint256[] ids,\n        uint256[] values\n    );\n\n    /**\n     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n     * `approved`.\n     */\n    event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n    /**\n     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n     *\n     * If an {URI} event was emitted for `id`, the standard\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n     * returned by {IERC1155MetadataURI-uri}.\n     */\n    event URI(string value, uint256 indexed id);\n\n    /**\n     * @dev Returns the value of tokens of token type `id` owned by `account`.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) external view returns (uint256);\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(\n        address[] calldata accounts,\n        uint256[] calldata ids\n    ) external view returns (uint256[] memory);\n\n    /**\n     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n     *\n     * Emits an {ApprovalForAll} event.\n     *\n     * Requirements:\n     *\n     * - `operator` cannot be the caller.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n     *\n     * See {setApprovalForAll}.\n     */\n    function isApprovedForAll(address account, address operator) external view returns (bool);\n\n    /**\n     * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.\n     *\n     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens\n     * to an untrusted contract, when invoking {onERC1155Received} on the receiver.\n     * Ensure to follow the checks-effects-interactions pattern and consider employing\n     * reentrancy guards when interacting with untrusted contracts.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n     * - `from` must have a balance of tokens of type `id` of at least `value` amount.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n     *\n     *\n     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens\n     * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver.\n     * Ensure to follow the checks-effects-interactions pattern and consider employing\n     * reentrancy guards when interacting with untrusted contracts.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `values` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] calldata ids,\n        uint256[] calldata values,\n        bytes calldata data\n    ) external;\n}\n"
      },
      "src/libraries/Transferer.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\n\nimport {IERC721} from \"@openzeppelin-contracts/token/ERC721/IERC721.sol\";\nimport {IERC1155} from \"@openzeppelin-contracts/token/ERC1155/IERC1155.sol\";\nimport {IERC20} from \"@openzeppelin-contracts/token/ERC20/IERC20.sol\";\n\nimport {Item} from \"@src/libraries/RentalStructs.sol\";\nimport {Errors} from \"@src/libraries/Errors.sol\";\n\n/**\n * @title Transferer\n * @notice Contains logic for for transferring tokens.\n */\nlibrary Transferer {\n    /**\n     * @dev Helper function to transfer an ERC721 token.\n     *\n     * @param item      Item which will be transferred.\n     * @param recipient Address which will receive the token.\n     */\n    function transferERC721(Item memory item, address recipient) internal {\n        IERC721(item.token).safeTransferFrom(address(this), recipient, item.identifier);\n    }\n\n    /**\n     * @dev Helper function to transfer an ERC1155 token.\n     *\n     * @param item      Item which will be transferred.\n     * @param recipient Address which will receive the token.\n     */\n    function transferERC1155(Item memory item, address recipient) internal {\n        IERC1155(item.token).safeTransferFrom(\n            address(this),\n            recipient,\n            item.identifier,\n            item.amount,\n            \"\"\n        );\n    }\n\n    /**\n     * @dev Safe transfer for ERC20 tokens that do not consistently renturn true/false.\n     *\n     * @param token Asset address which is being sent.\n     * @param to    Destination address for the transfer.\n     * @param value Amount of the asset being transferred.\n     */\n    function transferERC20(address token, address to, uint256 value) internal {\n        // Call transfer() on the token.\n        (bool success, bytes memory data) = token.call(\n            abi.encodeWithSelector(IERC20.transfer.selector, to, value)\n        );\n\n        // Because both reverting and returning false are allowed by the ERC20 standard\n        // to indicate a failed transfer, we must handle both cases.\n        //\n        // If success is false, the ERC20 contract reverted.\n        //\n        // If success is true, we must check if return data was provided. If no return\n        // data is provided, then no revert occurred. But, if return data is provided,\n        // then it must be decoded into a bool which will indicate the success of the\n        // transfer.\n        if (!success || (data.length != 0 && !abi.decode(data, (bool)))) {\n            revert Errors.Shared_ERC20TransferFailed(token, address(this), to, value);\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"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.19;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "lib/safe-contracts/contracts/base/ModuleManager.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/**\n * @title Module Manager - A contract managing Safe modules\n * @notice Modules are extensions with unlimited access to a Safe that can be added to a Safe by its owners.\n           ⚠️ WARNING: Modules are a security risk since they can execute arbitrary transactions, \n           so only trusted and audited modules should be added to a Safe. A malicious module can\n           completely takeover a Safe.\n * @author Stefan George - @Georgi87\n * @author Richard Meissner - @rmeissner\n */\nabstract contract ModuleManager is SelfAuthorized, Executor {\n    event EnabledModule(address indexed module);\n    event DisabledModule(address indexed module);\n    event ExecutionFromModuleSuccess(address indexed module);\n    event ExecutionFromModuleFailure(address indexed module);\n\n    address internal constant SENTINEL_MODULES = address(0x1);\n\n    mapping(address => address) internal modules;\n\n    /**\n     * @notice Setup function sets the initial storage of the contract.\n     *         Optionally executes a delegate call to another contract to setup the modules.\n     * @param to Optional destination address of call to execute.\n     * @param data Optional data of call to execute.\n     */\n    function setupModules(address to, bytes memory data) internal {\n        require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n        modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n        if (to != address(0)) {\n            require(isContract(to), \"GS002\");\n            // Setup has to complete successfully or transaction fails.\n            require(execute(to, 0, data, Enum.Operation.DelegateCall, type(uint256).max), \"GS000\");\n        }\n    }\n\n    /**\n     * @notice Enables the module `module` for the Safe.\n     * @dev This can only be done via a Safe transaction.\n     * @param module Module to be whitelisted.\n     */\n    function enableModule(address module) public authorized {\n        // Module address cannot be null or sentinel.\n        require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n        // Module cannot be added twice.\n        require(modules[module] == address(0), \"GS102\");\n        modules[module] = modules[SENTINEL_MODULES];\n        modules[SENTINEL_MODULES] = module;\n        emit EnabledModule(module);\n    }\n\n    /**\n     * @notice Disables the module `module` for the Safe.\n     * @dev This can only be done via a Safe transaction.\n     * @param prevModule Previous module in the modules linked list.\n     * @param module Module to be removed.\n     */\n    function disableModule(address prevModule, address module) public authorized {\n        // Validate module address and check that it corresponds to module index.\n        require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n        require(modules[prevModule] == module, \"GS103\");\n        modules[prevModule] = modules[module];\n        modules[module] = address(0);\n        emit DisabledModule(module);\n    }\n\n    /**\n     * @notice Execute `operation` (0: Call, 1: DelegateCall) to `to` with `value` (Native Token)\n     * @dev Function is virtual to allow overriding for L2 singleton to emit an event for indexing.\n     * @param to Destination address of module transaction.\n     * @param value Ether value of module transaction.\n     * @param data Data payload of module transaction.\n     * @param operation Operation type of module transaction.\n     * @return success Boolean flag indicating if the call succeeded.\n     */\n    function execTransactionFromModule(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation\n    ) public virtual returns (bool success) {\n        // Only whitelisted modules are allowed.\n        require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n        // Execute transaction without further confirmations.\n        success = execute(to, value, data, operation, type(uint256).max);\n        if (success) emit ExecutionFromModuleSuccess(msg.sender);\n        else emit ExecutionFromModuleFailure(msg.sender);\n    }\n\n    /**\n     * @notice Execute `operation` (0: Call, 1: DelegateCall) to `to` with `value` (Native Token) and return data\n     * @param to Destination address of module transaction.\n     * @param value Ether value of module transaction.\n     * @param data Data payload of module transaction.\n     * @param operation Operation type of module transaction.\n     * @return success Boolean flag indicating if the call succeeded.\n     * @return returnData Data returned by the call.\n     */\n    function execTransactionFromModuleReturnData(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation\n    ) public returns (bool success, bytes memory returnData) {\n        success = execTransactionFromModule(to, value, data, operation);\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            // Load free memory location\n            let ptr := mload(0x40)\n            // We allocate memory for the return data by setting the free memory location to\n            // current free memory location + data size + 32 bytes for data size value\n            mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n            // Store the size\n            mstore(ptr, returndatasize())\n            // Store the data\n            returndatacopy(add(ptr, 0x20), 0, returndatasize())\n            // Point the return data to the correct memory location\n            returnData := ptr\n        }\n    }\n\n    /**\n     * @notice Returns if an module is enabled\n     * @return True if the module is enabled\n     */\n    function isModuleEnabled(address module) public view returns (bool) {\n        return SENTINEL_MODULES != module && modules[module] != address(0);\n    }\n\n    /**\n     * @notice Returns an array of modules.\n     *         If all entries fit into a single page, the next pointer will be 0x1.\n     *         If another page is present, next will be the last element of the returned array.\n     * @param start Start of the page. Has to be a module or start pointer (0x1 address)\n     * @param pageSize Maximum number of modules that should be returned. Has to be > 0\n     * @return array Array of modules.\n     * @return next Start of the next page.\n     */\n    function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n        require(start == SENTINEL_MODULES || isModuleEnabled(start), \"GS105\");\n        require(pageSize > 0, \"GS106\");\n        // Init array with max page size\n        array = new address[](pageSize);\n\n        // Populate return array\n        uint256 moduleCount = 0;\n        next = modules[start];\n        while (next != address(0) && next != SENTINEL_MODULES && moduleCount < pageSize) {\n            array[moduleCount] = next;\n            next = modules[next];\n            moduleCount++;\n        }\n\n        /**\n          Because of the argument validation, we can assume that the loop will always iterate over the valid module list values\n          and the `next` variable will either be an enabled module or a sentinel address (signalling the end). \n          \n          If we haven't reached the end inside the loop, we need to set the next pointer to the last element of the modules array\n          because the `next` variable (which is a module by itself) acting as a pointer to the start of the next page is neither \n          included to the current page, nor will it be included in the next one if you pass it as a start.\n        */\n        if (next != SENTINEL_MODULES) {\n            next = array[moduleCount - 1];\n        }\n        // Set correct size of returned array\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            mstore(array, moduleCount)\n        }\n    }\n\n    /**\n     * @notice Returns true if `account` is a contract.\n     * @dev This function will return false if invoked during the constructor of a contract,\n     *      as the code is not actually created until after the constructor finishes.\n     * @param account The address being queried\n     */\n    function isContract(address account) internal view returns (bool) {\n        uint256 size;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            size := extcodesize(account)\n        }\n        return size > 0;\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/base/OwnerManager.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/**\n * @title OwnerManager - Manages Safe owners and a threshold to authorize transactions.\n * @dev Uses a linked list to store the owners because the code generate by the solidity compiler\n *      is more efficient than using a dynamic array.\n * @author Stefan George - @Georgi87\n * @author Richard Meissner - @rmeissner\n */\nabstract contract OwnerManager is SelfAuthorized {\n    event AddedOwner(address indexed owner);\n    event RemovedOwner(address indexed owner);\n    event ChangedThreshold(uint256 threshold);\n\n    address internal constant SENTINEL_OWNERS = address(0x1);\n\n    mapping(address => address) internal owners;\n    uint256 internal ownerCount;\n    uint256 internal threshold;\n\n    /**\n     * @notice Sets the initial storage of the contract.\n     * @param _owners List of Safe owners.\n     * @param _threshold Number of required confirmations for a Safe transaction.\n     */\n    function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n        // Threshold can only be 0 at initialization.\n        // Check ensures that setup function can only be called once.\n        require(threshold == 0, \"GS200\");\n        // Validate that threshold is smaller than number of added owners.\n        require(_threshold <= _owners.length, \"GS201\");\n        // There has to be at least one Safe owner.\n        require(_threshold >= 1, \"GS202\");\n        // Initializing Safe owners.\n        address currentOwner = SENTINEL_OWNERS;\n        for (uint256 i = 0; i < _owners.length; i++) {\n            // Owner address cannot be null.\n            address owner = _owners[i];\n            require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n            // No duplicate owners allowed.\n            require(owners[owner] == address(0), \"GS204\");\n            owners[currentOwner] = owner;\n            currentOwner = owner;\n        }\n        owners[currentOwner] = SENTINEL_OWNERS;\n        ownerCount = _owners.length;\n        threshold = _threshold;\n    }\n\n    /**\n     * @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n     * @dev This can only be done via a Safe transaction.\n     * @param owner New owner address.\n     * @param _threshold New threshold.\n     */\n    function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n        // Owner address cannot be null, the sentinel or the Safe itself.\n        require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n        // No duplicate owners allowed.\n        require(owners[owner] == address(0), \"GS204\");\n        owners[owner] = owners[SENTINEL_OWNERS];\n        owners[SENTINEL_OWNERS] = owner;\n        ownerCount++;\n        emit AddedOwner(owner);\n        // Change threshold if threshold was changed.\n        if (threshold != _threshold) changeThreshold(_threshold);\n    }\n\n    /**\n     * @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n     * @dev This can only be done via a Safe transaction.\n     * @param prevOwner Owner that pointed to the owner to be removed in the linked list\n     * @param owner Owner address to be removed.\n     * @param _threshold New threshold.\n     */\n    function removeOwner(address prevOwner, address owner, uint256 _threshold) public authorized {\n        // Only allow to remove an owner, if threshold can still be reached.\n        require(ownerCount - 1 >= _threshold, \"GS201\");\n        // Validate owner address and check that it corresponds to owner index.\n        require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n        require(owners[prevOwner] == owner, \"GS205\");\n        owners[prevOwner] = owners[owner];\n        owners[owner] = address(0);\n        ownerCount--;\n        emit RemovedOwner(owner);\n        // Change threshold if threshold was changed.\n        if (threshold != _threshold) changeThreshold(_threshold);\n    }\n\n    /**\n     * @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n     * @dev This can only be done via a Safe transaction.\n     * @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n     * @param oldOwner Owner address to be replaced.\n     * @param newOwner New owner address.\n     */\n    function swapOwner(address prevOwner, address oldOwner, address newOwner) public authorized {\n        // Owner address cannot be null, the sentinel or the Safe itself.\n        require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n        // No duplicate owners allowed.\n        require(owners[newOwner] == address(0), \"GS204\");\n        // Validate oldOwner address and check that it corresponds to owner index.\n        require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n        require(owners[prevOwner] == oldOwner, \"GS205\");\n        owners[newOwner] = owners[oldOwner];\n        owners[prevOwner] = newOwner;\n        owners[oldOwner] = address(0);\n        emit RemovedOwner(oldOwner);\n        emit AddedOwner(newOwner);\n    }\n\n    /**\n     * @notice Changes the threshold of the Safe to `_threshold`.\n     * @dev This can only be done via a Safe transaction.\n     * @param _threshold New threshold.\n     */\n    function changeThreshold(uint256 _threshold) public authorized {\n        // Validate that threshold is smaller than number of owners.\n        require(_threshold <= ownerCount, \"GS201\");\n        // There has to be at least one Safe owner.\n        require(_threshold >= 1, \"GS202\");\n        threshold = _threshold;\n        emit ChangedThreshold(threshold);\n    }\n\n    /**\n     * @notice Returns the number of required confirmations for a Safe transaction aka the threshold.\n     * @return Threshold number.\n     */\n    function getThreshold() public view returns (uint256) {\n        return threshold;\n    }\n\n    /**\n     * @notice Returns if `owner` is an owner of the Safe.\n     * @return Boolean if owner is an owner of the Safe.\n     */\n    function isOwner(address owner) public view returns (bool) {\n        return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n    }\n\n    /**\n     * @notice Returns a list of Safe owners.\n     * @return Array of Safe owners.\n     */\n    function getOwners() public view returns (address[] memory) {\n        address[] memory array = new address[](ownerCount);\n\n        // populate return array\n        uint256 index = 0;\n        address currentOwner = owners[SENTINEL_OWNERS];\n        while (currentOwner != SENTINEL_OWNERS) {\n            array[index] = currentOwner;\n            currentOwner = owners[currentOwner];\n            index++;\n        }\n        return array;\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/base/FallbackManager.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/**\n * @title Fallback Manager - A contract managing fallback calls made to this contract\n * @author Richard Meissner - @rmeissner\n */\nabstract contract FallbackManager is SelfAuthorized {\n    event ChangedFallbackHandler(address indexed handler);\n\n    // keccak256(\"fallback_manager.handler.address\")\n    bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n    /**\n     *  @notice Internal function to set the fallback handler.\n     *  @param handler contract to handle fallback calls.\n     */\n    function internalSetFallbackHandler(address handler) internal {\n        /*\n            If a fallback handler is set to self, then the following attack vector is opened:\n            Imagine we have a function like this:\n            function withdraw() internal authorized {\n                withdrawalAddress.call.value(address(this).balance)(\"\");\n            }\n\n            If the fallback method is triggered, the fallback handler appends the msg.sender address to the calldata and calls the fallback handler.\n            A potential attacker could call a Safe with the 3 bytes signature of a withdraw function. Since 3 bytes do not create a valid signature,\n            the call would end in a fallback handler. Since it appends the msg.sender address to the calldata, the attacker could craft an address \n            where the first 3 bytes of the previous calldata + the first byte of the address make up a valid function signature. The subsequent call would result in unsanctioned access to Safe's internal protected methods.\n            For some reason, solidity matches the first 4 bytes of the calldata to a function signature, regardless if more data follow these 4 bytes.\n        */\n        require(handler != address(this), \"GS400\");\n\n        bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(slot, handler)\n        }\n    }\n\n    /**\n     * @notice Set Fallback Handler to `handler` for the Safe.\n     * @dev Only fallback calls without value and with data will be forwarded.\n     *      This can only be done via a Safe transaction.\n     *      Cannot be set to the Safe itself.\n     * @param handler contract to handle fallback calls.\n     */\n    function setFallbackHandler(address handler) public authorized {\n        internalSetFallbackHandler(handler);\n        emit ChangedFallbackHandler(handler);\n    }\n\n    // @notice Forwards all calls to the fallback handler if set. Returns 0 if no handler is set.\n    // @dev Appends the non-padded caller address to the calldata to be optionally used in the handler\n    //      The handler can make us of `HandlerContext.sol` to extract the address.\n    //      This is done because in the next call frame the `msg.sender` will be FallbackManager's address\n    //      and having the original caller address may enable additional verification scenarios.\n    // solhint-disable-next-line payable-fallback,no-complex-fallback\n    fallback() external {\n        bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let handler := sload(slot)\n            if iszero(handler) {\n                return(0, 0)\n            }\n            calldatacopy(0, 0, calldatasize())\n            // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n            // Then the address without padding is stored right after the calldata\n            mstore(calldatasize(), shl(96, caller()))\n            // Add 20 bytes for the address appended add the end\n            let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n            returndatacopy(0, 0, returndatasize())\n            if iszero(success) {\n                revert(0, returndatasize())\n            }\n            return(0, returndatasize())\n        }\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/base/GuardManager.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"../interfaces/IERC165.sol\";\n\ninterface Guard is IERC165 {\n    function checkTransaction(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address payable refundReceiver,\n        bytes memory signatures,\n        address msgSender\n    ) external;\n\n    function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\nabstract contract BaseGuard is Guard {\n    function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {\n        return\n            interfaceId == type(Guard).interfaceId || // 0xe6d7a83a\n            interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n    }\n}\n\n/**\n * @title Guard Manager - A contract managing transaction guards which perform pre and post-checks on Safe transactions.\n * @author Richard Meissner - @rmeissner\n */\nabstract contract GuardManager is SelfAuthorized {\n    event ChangedGuard(address indexed guard);\n\n    // keccak256(\"guard_manager.guard.address\")\n    bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n    /**\n     * @dev Set a guard that checks transactions before execution\n     *      This can only be done via a Safe transaction.\n     *      ⚠️ IMPORTANT: Since a guard has full power to block Safe transaction execution,\n     *        a broken guard can cause a denial of service for the Safe. Make sure to carefully\n     *        audit the guard code and design recovery mechanisms.\n     * @notice Set Transaction Guard `guard` for the Safe. Make sure you trust the guard.\n     * @param guard The address of the guard to be used or the 0 address to disable the guard\n     */\n    function setGuard(address guard) external authorized {\n        if (guard != address(0)) {\n            require(Guard(guard).supportsInterface(type(Guard).interfaceId), \"GS300\");\n        }\n        bytes32 slot = GUARD_STORAGE_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(slot, guard)\n        }\n        emit ChangedGuard(guard);\n    }\n\n    /**\n     * @dev Internal method to retrieve the current guard\n     *      We do not have a public method because we're short on bytecode size limit,\n     *      to retrieve the guard address, one can use `getStorageAt` from `StorageAccessible` contract\n     *      with the slot `GUARD_STORAGE_SLOT`\n     * @return guard The address of the guard\n     */\n    function getGuard() internal view returns (address guard) {\n        bytes32 slot = GUARD_STORAGE_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            guard := sload(slot)\n        }\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/common/NativeCurrencyPaymentFallback.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title NativeCurrencyPaymentFallback - A contract that has a fallback to accept native currency payments.\n * @author Richard Meissner - @rmeissner\n */\nabstract contract NativeCurrencyPaymentFallback {\n    event SafeReceived(address indexed sender, uint256 value);\n\n    /**\n     * @notice Receive function accepts native currency transactions.\n     * @dev Emits an event with sender and received value.\n     */\n    receive() external payable {\n        emit SafeReceived(msg.sender, msg.value);\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/common/Singleton.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title Singleton - Base for singleton contracts (should always be the first super contract)\n *        This contract is tightly coupled to our proxy contract (see `proxies/SafeProxy.sol`)\n * @author Richard Meissner - @rmeissner\n */\nabstract contract Singleton {\n    // singleton always has to be the first declared variable to ensure the same location as in the Proxy contract.\n    // It should also always be ensured the address is stored alone (uses a full word)\n    address private singleton;\n}\n"
      },
      "lib/safe-contracts/contracts/common/SignatureDecoder.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title SignatureDecoder - Decodes signatures encoded as bytes\n * @author Richard Meissner - @rmeissner\n */\nabstract contract SignatureDecoder {\n    /**\n     * @notice Splits signature bytes into `uint8 v, bytes32 r, bytes32 s`.\n     * @dev Make sure to perform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n     *      The signature format is a compact form of {bytes32 r}{bytes32 s}{uint8 v}\n     *      Compact means uint8 is not padded to 32 bytes.\n     * @param pos Which signature to read.\n     *            A prior bounds check of this parameter should be performed, to avoid out of bounds access.\n     * @param signatures Concatenated {r, s, v} signatures.\n     * @return v Recovery ID or Safe signature type.\n     * @return r Output value r of the signature.\n     * @return s Output value s of the signature.\n     */\n    function signatureSplit(bytes memory signatures, uint256 pos) internal pure returns (uint8 v, bytes32 r, bytes32 s) {\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let signaturePos := mul(0x41, pos)\n            r := mload(add(signatures, add(signaturePos, 0x20)))\n            s := mload(add(signatures, add(signaturePos, 0x40)))\n            /**\n             * Here we are loading the last 32 bytes, including 31 bytes\n             * of 's'. There is no 'mload8' to do this.\n             * 'byte' is not working due to the Solidity parser, so lets\n             * use the second best option, 'and'\n             */\n            v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n        }\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/common/SecuredTokenTransfer.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title SecuredTokenTransfer - Secure token transfer.\n * @author Richard Meissner - @rmeissner\n */\nabstract contract SecuredTokenTransfer {\n    /**\n     * @notice Transfers a token and returns a boolean if it was a success\n     * @dev It checks the return data of the transfer call and returns true if the transfer was successful.\n     *      It doesn't check if the `token` address is a contract or not.\n     * @param token Token that should be transferred\n     * @param receiver Receiver to whom the token should be transferred\n     * @param amount The amount of tokens that should be transferred\n     * @return transferred Returns true if the transfer was successful\n     */\n    function transferToken(address token, address receiver, uint256 amount) internal returns (bool transferred) {\n        // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n        bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            // We write the return value to scratch space.\n            // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n            let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            switch returndatasize()\n            case 0 {\n                transferred := success\n            }\n            case 0x20 {\n                transferred := iszero(or(iszero(success), iszero(mload(0))))\n            }\n            default {\n                transferred := 0\n            }\n        }\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/common/StorageAccessible.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title StorageAccessible - A generic base contract that allows callers to access all internal storage.\n * @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\n *         It removes a method from the original contract not needed for the Safe contracts.\n * @author Gnosis Developers\n */\nabstract contract StorageAccessible {\n    /**\n     * @notice Reads `length` bytes of storage in the currents contract\n     * @param offset - the offset in the current contract's storage in words to start reading from\n     * @param length - the number of words (32 bytes) of data to read\n     * @return the bytes that were read.\n     */\n    function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n        bytes memory result = new bytes(length * 32);\n        for (uint256 index = 0; index < length; index++) {\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                let word := sload(add(offset, index))\n                mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Performs a delegatecall on a targetContract in the context of self.\n     * Internally reverts execution to avoid side effects (making it static).\n     *\n     * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n     * Specifically, the `returndata` after a call to this method will be:\n     * `success:bool || response.length:uint256 || response:bytes`.\n     *\n     * @param targetContract Address of the contract containing the code to execute.\n     * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n     */\n    function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n            mstore(0x00, success)\n            mstore(0x20, returndatasize())\n            returndatacopy(0x40, 0, returndatasize())\n            revert(0, add(returndatasize(), 0x40))\n        }\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/interfaces/ISignatureValidator.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n    // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n    bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n    /**\n     * @notice Legacy EIP1271 method to validate a signature.\n     * @param _data Arbitrary length data signed on the behalf of address(this).\n     * @param _signature Signature byte array associated with _data.\n     *\n     * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n     * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n     * MUST allow external calls\n     */\n    function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n"
      },
      "lib/safe-contracts/contracts/external/SafeMath.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title SafeMath\n * @notice Math operations with safety checks that revert on error (overflow/underflow)\n */\nlibrary SafeMath {\n    /**\n     * @notice Multiplies two numbers, reverts on overflow.\n     * @param a First number\n     * @param b Second number\n     * @return Product of a and b\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b);\n\n        return c;\n    }\n\n    /**\n     * @notice Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n     * @param a First number\n     * @param b Second number\n     * @return Difference of a and b\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b <= a);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @notice Adds two numbers, reverts on overflow.\n     * @param a First number\n     * @param b Second number\n     * @return Sum of a and b\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a);\n\n        return c;\n    }\n\n    /**\n     * @notice Returns the largest of two numbers.\n     * @param a First number\n     * @param b Second number\n     * @return Largest of a and b\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a >= b ? a : b;\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"
      },
      "lib/openzeppelin-contracts/contracts/utils/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.19;\n\nimport {Math} from \"./math/Math.sol\";\nimport {SignedMath} from \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev The `value` string doesn't fit in the specified `length`.\n     */\n    error StringsInsufficientHexLength(uint256 value, uint256 length);\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toStringSigned(int256 value) internal pure returns (string memory) {\n        return string.concat(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value)));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        uint256 localValue = value;\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[localValue & 0xf];\n            localValue >>= 4;\n        }\n        if (localValue != 0) {\n            revert StringsInsufficientHexLength(value, length);\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.19;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "lib/safe-contracts/contracts/common/SelfAuthorized.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title SelfAuthorized - Authorizes current contract to perform actions to itself.\n * @author Richard Meissner - @rmeissner\n */\nabstract contract SelfAuthorized {\n    function requireSelfCall() private view {\n        require(msg.sender == address(this), \"GS031\");\n    }\n\n    modifier authorized() {\n        // Modifiers are copied around during compilation. This is a function call as it minimized the bytecode size\n        requireSelfCall();\n        _;\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/base/Executor.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/**\n * @title Executor - A contract that can execute transactions\n * @author Richard Meissner - @rmeissner\n */\nabstract contract Executor {\n    /**\n     * @notice Executes either a delegatecall or a call with provided parameters.\n     * @dev This method doesn't perform any sanity check of the transaction, such as:\n     *      - if the contract at `to` address has code or not\n     *      It is the responsibility of the caller to perform such checks.\n     * @param to Destination address.\n     * @param value Ether value.\n     * @param data Data payload.\n     * @param operation Operation type.\n     * @return success boolean flag indicating if the call succeeded.\n     */\n    function execute(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation,\n        uint256 txGas\n    ) internal returns (bool success) {\n        if (operation == Enum.Operation.DelegateCall) {\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n            }\n        } else {\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n            }\n        }\n    }\n}\n"
      },
      "lib/safe-contracts/contracts/interfaces/IERC165.sol": {
        "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @notice More details at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by `interfaceId`.\n     * See the corresponding EIP section\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.19;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    /**\n     * @dev Muldiv operation overflow.\n     */\n    error MathOverflowedMulDiv();\n\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v5.0._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v5.0._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v5.0._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v5.0._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v5.0._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            return a / b;\n        }\n\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            if (denominator <= prod1) {\n                revert MathOverflowedMulDiv();\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/math/SignedMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.19;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\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": {}
    }
  }}