creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "lib/rain.orderbook/src/concrete/parser/OrderBookSubParser.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity =0.8.19;\n\nimport {\n    LibParseOperand,\n    BaseRainterpreterSubParserNPE2,\n    Operand\n} from \"rain.interpreter/abstract/BaseRainterpreterSubParserNPE2.sol\";\nimport {LibConvert} from \"rain.lib.typecast/LibConvert.sol\";\nimport {BadDynamicLength} from \"rain.interpreter/error/ErrOpList.sol\";\nimport {LibExternOpContextSenderNPE2} from \"rain.interpreter/lib/extern/reference/op/LibExternOpContextSenderNPE2.sol\";\nimport {LibExternOpContextCallingContractNPE2} from\n    \"rain.interpreter/lib/extern/reference/op/LibExternOpContextCallingContractNPE2.sol\";\nimport {LibUint256Matrix} from \"rain.solmem/lib/LibUint256Matrix.sol\";\n\nimport {LibOrderBookSubParser, SUB_PARSER_WORD_PARSERS_LENGTH} from \"../../lib/LibOrderBookSubParser.sol\";\nimport {\n    CONTEXT_COLUMNS,\n    CONTEXT_BASE_ROWS,\n    CONTEXT_BASE_ROW_SENDER,\n    CONTEXT_BASE_ROW_CALLING_CONTRACT,\n    CONTEXT_BASE_COLUMN,\n    CONTEXT_VAULT_OUTPUTS_COLUMN,\n    CONTEXT_VAULT_INPUTS_COLUMN,\n    CONTEXT_CALCULATIONS_COLUMN,\n    CONTEXT_VAULT_IO_BALANCE_DIFF,\n    CONTEXT_VAULT_IO_BALANCE_BEFORE,\n    CONTEXT_VAULT_IO_VAULT_ID,\n    CONTEXT_VAULT_IO_TOKEN_DECIMALS,\n    CONTEXT_VAULT_IO_TOKEN,\n    CONTEXT_VAULT_IO_ROWS,\n    CONTEXT_CALCULATIONS_ROW_IO_RATIO,\n    CONTEXT_CALCULATIONS_ROW_MAX_OUTPUT,\n    CONTEXT_CALCULATIONS_ROWS,\n    CONTEXT_CALLING_CONTEXT_ROW_ORDER_COUNTERPARTY,\n    CONTEXT_CALLING_CONTEXT_ROW_ORDER_OWNER,\n    CONTEXT_CALLING_CONTEXT_ROW_ORDER_HASH,\n    CONTEXT_CALLING_CONTEXT_ROWS,\n    CONTEXT_CALLING_CONTEXT_COLUMN,\n    CONTEXT_SIGNED_CONTEXT_START_COLUMN,\n    CONTEXT_SIGNED_CONTEXT_START_ROW,\n    CONTEXT_SIGNED_CONTEXT_START_ROWS,\n    CONTEXT_SIGNED_CONTEXT_SIGNERS_COLUMN,\n    CONTEXT_SIGNED_CONTEXT_SIGNERS_ROW,\n    CONTEXT_SIGNED_CONTEXT_SIGNERS_ROWS\n} from \"../../lib/LibOrderBook.sol\";\n\nbytes constant SUB_PARSER_PARSE_META =\n    hex\"01004800040040020200110000000000001006102008000020040000000100000090088de69a0b015d8302c9be1f116682f50584c8d406bbcde60fb5f425102ce8cf1283156f0109ac300398cd200ab1aeaf0ea9bcef075e0bc300d3b4e80de78f2e0c9fc5d509a7e6560427db4a\";\nbytes constant SUB_PARSER_WORD_PARSERS =\n    hex\"0fc70fe60ff7100810181029103a104b105c106d107e108e109f10b010c110d210e310f31103\";\nbytes constant SUB_PARSER_OPERAND_HANDLERS =\n    hex\"12481248124812481248124812481248124812481248124812481248124812481248128d134c\";\n\ncontract OrderBookSubParser is BaseRainterpreterSubParserNPE2 {\n    using LibUint256Matrix for uint256[][];\n\n    function subParserParseMeta() internal pure virtual override returns (bytes memory) {\n        return SUB_PARSER_PARSE_META;\n    }\n\n    function subParserWordParsers() internal pure virtual override returns (bytes memory) {\n        return SUB_PARSER_WORD_PARSERS;\n    }\n\n    function subParserOperandHandlers() internal pure virtual override returns (bytes memory) {\n        return SUB_PARSER_OPERAND_HANDLERS;\n    }\n\n    function buildSubParserOperandHandlers() external pure returns (bytes memory) {\n        // Add 2 columns for signers and signed context start.\n        function(uint256[] memory) internal pure returns (Operand)[][] memory handlers =\n            new function(uint256[] memory) internal pure returns (Operand)[][](CONTEXT_COLUMNS + 2);\n\n        function(uint256[] memory) internal pure returns (Operand)[] memory contextBaseHandlers =\n            new function(uint256[] memory) internal pure returns (Operand)[](CONTEXT_BASE_ROWS);\n        contextBaseHandlers[CONTEXT_BASE_ROW_SENDER] = LibParseOperand.handleOperandDisallowed;\n        contextBaseHandlers[CONTEXT_BASE_ROW_CALLING_CONTRACT] = LibParseOperand.handleOperandDisallowed;\n\n        function(uint256[] memory) internal pure returns (Operand)[] memory contextCallingContextHandlers =\n            new function(uint256[] memory) internal pure returns (Operand)[](CONTEXT_CALLING_CONTEXT_ROWS);\n        contextCallingContextHandlers[CONTEXT_CALLING_CONTEXT_ROW_ORDER_HASH] = LibParseOperand.handleOperandDisallowed;\n        contextCallingContextHandlers[CONTEXT_CALLING_CONTEXT_ROW_ORDER_OWNER] = LibParseOperand.handleOperandDisallowed;\n        contextCallingContextHandlers[CONTEXT_CALLING_CONTEXT_ROW_ORDER_COUNTERPARTY] =\n            LibParseOperand.handleOperandDisallowed;\n\n        function(uint256[] memory) internal pure returns (Operand)[] memory contextCalculationsHandlers =\n            new function(uint256[] memory) internal pure returns (Operand)[](CONTEXT_CALCULATIONS_ROWS);\n        contextCalculationsHandlers[CONTEXT_CALCULATIONS_ROW_MAX_OUTPUT] = LibParseOperand.handleOperandDisallowed;\n        contextCalculationsHandlers[CONTEXT_CALCULATIONS_ROW_IO_RATIO] = LibParseOperand.handleOperandDisallowed;\n\n        function(uint256[] memory) internal pure returns (Operand)[] memory contextVaultInputsHandlers =\n            new function(uint256[] memory) internal pure returns (Operand)[](CONTEXT_VAULT_IO_ROWS);\n        contextVaultInputsHandlers[CONTEXT_VAULT_IO_TOKEN] = LibParseOperand.handleOperandDisallowed;\n        contextVaultInputsHandlers[CONTEXT_VAULT_IO_TOKEN_DECIMALS] = LibParseOperand.handleOperandDisallowed;\n        contextVaultInputsHandlers[CONTEXT_VAULT_IO_VAULT_ID] = LibParseOperand.handleOperandDisallowed;\n        contextVaultInputsHandlers[CONTEXT_VAULT_IO_BALANCE_BEFORE] = LibParseOperand.handleOperandDisallowed;\n        contextVaultInputsHandlers[CONTEXT_VAULT_IO_BALANCE_DIFF] = LibParseOperand.handleOperandDisallowed;\n\n        function(uint256[] memory) internal pure returns (Operand)[] memory contextVaultOutputsHandlers =\n            new function(uint256[] memory) internal pure returns (Operand)[](CONTEXT_VAULT_IO_ROWS);\n        contextVaultOutputsHandlers[CONTEXT_VAULT_IO_TOKEN] = LibParseOperand.handleOperandDisallowed;\n        contextVaultOutputsHandlers[CONTEXT_VAULT_IO_TOKEN_DECIMALS] = LibParseOperand.handleOperandDisallowed;\n        contextVaultOutputsHandlers[CONTEXT_VAULT_IO_VAULT_ID] = LibParseOperand.handleOperandDisallowed;\n        contextVaultOutputsHandlers[CONTEXT_VAULT_IO_BALANCE_BEFORE] = LibParseOperand.handleOperandDisallowed;\n        contextVaultOutputsHandlers[CONTEXT_VAULT_IO_BALANCE_DIFF] = LibParseOperand.handleOperandDisallowed;\n\n        function(uint256[] memory) internal pure returns (Operand)[] memory contextSignersHandlers =\n            new function(uint256[] memory) internal pure returns (Operand)[](CONTEXT_SIGNED_CONTEXT_SIGNERS_ROWS);\n        contextSignersHandlers[CONTEXT_SIGNED_CONTEXT_SIGNERS_ROW] = LibParseOperand.handleOperandSingleFullNoDefault;\n\n        function(uint256[] memory) internal pure returns (Operand)[] memory contextSignedContextHandlers =\n            new function(uint256[] memory) internal pure returns (Operand)[](CONTEXT_SIGNED_CONTEXT_START_ROWS);\n        contextSignedContextHandlers[CONTEXT_SIGNED_CONTEXT_START_ROW] =\n            LibParseOperand.handleOperandDoublePerByteNoDefault;\n\n        handlers[CONTEXT_BASE_COLUMN] = contextBaseHandlers;\n        handlers[CONTEXT_CALLING_CONTEXT_COLUMN] = contextCallingContextHandlers;\n        handlers[CONTEXT_CALCULATIONS_COLUMN] = contextCalculationsHandlers;\n        handlers[CONTEXT_VAULT_INPUTS_COLUMN] = contextVaultInputsHandlers;\n        handlers[CONTEXT_VAULT_OUTPUTS_COLUMN] = contextVaultOutputsHandlers;\n        handlers[CONTEXT_SIGNED_CONTEXT_SIGNERS_COLUMN] = contextSignersHandlers;\n        handlers[CONTEXT_SIGNED_CONTEXT_START_COLUMN] = contextSignedContextHandlers;\n\n        uint256[][] memory handlersUint256;\n        assembly (\"memory-safe\") {\n            handlersUint256 := handlers\n        }\n\n        return LibConvert.unsafeTo16BitBytes(handlersUint256.flatten());\n    }\n\n    function buildSubParserWordParsers() external pure returns (bytes memory) {\n        // Add 2 columns for signers and signed context start.\n        function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[][] memory\n            parsers = new function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[][](\n                CONTEXT_COLUMNS + 2\n            );\n\n        function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[] memory\n            contextBaseParsers = new function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[](\n                CONTEXT_BASE_ROWS\n            );\n        contextBaseParsers[CONTEXT_BASE_ROW_SENDER] = LibOrderBookSubParser.subParserSender;\n        contextBaseParsers[CONTEXT_BASE_ROW_CALLING_CONTRACT] = LibOrderBookSubParser.subParserCallingContract;\n\n        function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[] memory\n            contextCallingContextParsers = new function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[](\n                CONTEXT_CALLING_CONTEXT_ROWS\n            );\n        contextCallingContextParsers[CONTEXT_CALLING_CONTEXT_ROW_ORDER_HASH] = LibOrderBookSubParser.subParserOrderHash;\n        contextCallingContextParsers[CONTEXT_CALLING_CONTEXT_ROW_ORDER_OWNER] =\n            LibOrderBookSubParser.subParserOrderOwner;\n        contextCallingContextParsers[CONTEXT_CALLING_CONTEXT_ROW_ORDER_COUNTERPARTY] =\n            LibOrderBookSubParser.subParserOrderCounterparty;\n\n        function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[] memory\n            contextCalculationsParsers = new function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[](\n                CONTEXT_CALCULATIONS_ROWS\n            );\n        contextCalculationsParsers[CONTEXT_CALCULATIONS_ROW_MAX_OUTPUT] = LibOrderBookSubParser.subParserMaxOutput;\n        contextCalculationsParsers[CONTEXT_CALCULATIONS_ROW_IO_RATIO] = LibOrderBookSubParser.subParserIORatio;\n\n        function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[] memory\n            contextVaultInputsParsers = new function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[](\n                CONTEXT_VAULT_IO_ROWS\n            );\n        contextVaultInputsParsers[CONTEXT_VAULT_IO_TOKEN] = LibOrderBookSubParser.subParserInputToken;\n        contextVaultInputsParsers[CONTEXT_VAULT_IO_TOKEN_DECIMALS] = LibOrderBookSubParser.subParserInputTokenDecimals;\n        contextVaultInputsParsers[CONTEXT_VAULT_IO_VAULT_ID] = LibOrderBookSubParser.subParserInputVaultId;\n        contextVaultInputsParsers[CONTEXT_VAULT_IO_BALANCE_BEFORE] = LibOrderBookSubParser.subParserInputBalanceBefore;\n        contextVaultInputsParsers[CONTEXT_VAULT_IO_BALANCE_DIFF] = LibOrderBookSubParser.subParserInputBalanceDiff;\n\n        function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[] memory\n            contextVaultOutputsParsers = new function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[](\n                CONTEXT_VAULT_IO_ROWS\n            );\n        contextVaultOutputsParsers[CONTEXT_VAULT_IO_TOKEN] = LibOrderBookSubParser.subParserOutputToken;\n        contextVaultOutputsParsers[CONTEXT_VAULT_IO_TOKEN_DECIMALS] = LibOrderBookSubParser.subParserOutputTokenDecimals;\n        contextVaultOutputsParsers[CONTEXT_VAULT_IO_VAULT_ID] = LibOrderBookSubParser.subParserOutputVaultId;\n        contextVaultOutputsParsers[CONTEXT_VAULT_IO_BALANCE_BEFORE] = LibOrderBookSubParser.subParserOutputBalanceBefore;\n        contextVaultOutputsParsers[CONTEXT_VAULT_IO_BALANCE_DIFF] = LibOrderBookSubParser.subParserOutputBalanceDiff;\n\n        function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[] memory\n            contextSignersParsers = new function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[](\n                CONTEXT_SIGNED_CONTEXT_SIGNERS_ROWS\n            );\n        contextSignersParsers[CONTEXT_SIGNED_CONTEXT_SIGNERS_ROW] = LibOrderBookSubParser.subParserSigners;\n\n        function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[] memory\n            contextSignedContextParsers = new function(uint256, uint256, Operand) internal view returns (bool, bytes memory, uint256[] memory)[](\n                CONTEXT_SIGNED_CONTEXT_START_ROWS\n            );\n        contextSignedContextParsers[CONTEXT_SIGNED_CONTEXT_START_ROW] = LibOrderBookSubParser.subParserSignedContext;\n\n        parsers[CONTEXT_BASE_COLUMN] = contextBaseParsers;\n        parsers[CONTEXT_CALLING_CONTEXT_COLUMN] = contextCallingContextParsers;\n        parsers[CONTEXT_CALCULATIONS_COLUMN] = contextCalculationsParsers;\n        parsers[CONTEXT_VAULT_INPUTS_COLUMN] = contextVaultInputsParsers;\n        parsers[CONTEXT_VAULT_OUTPUTS_COLUMN] = contextVaultOutputsParsers;\n        parsers[CONTEXT_SIGNED_CONTEXT_SIGNERS_COLUMN] = contextSignersParsers;\n        parsers[CONTEXT_SIGNED_CONTEXT_START_COLUMN] = contextSignedContextParsers;\n\n        uint256[][] memory parsersUint256;\n        assembly (\"memory-safe\") {\n            parsersUint256 := parsers\n        }\n\n        return LibConvert.unsafeTo16BitBytes(parsersUint256.flatten());\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/abstract/BaseRainterpreterSubParserNPE2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity =0.8.19;\n\nimport {ERC165} from \"openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\";\nimport {LibBytes, Pointer} from \"rain.solmem/lib/LibBytes.sol\";\n\nimport {ISubParserV2, COMPATIBLITY_V3} from \"rain.interpreter.interface/interface/ISubParserV2.sol\";\nimport {IncompatibleSubParser} from \"../error/ErrSubParse.sol\";\nimport {LibSubParse, ParseState} from \"../lib/parse/LibSubParse.sol\";\nimport {CMASK_RHS_WORD_TAIL} from \"../lib/parse/LibParseCMask.sol\";\nimport {LibParse, Operand} from \"../lib/parse/LibParse.sol\";\nimport {LibParseMeta} from \"../lib/parse/LibParseMeta.sol\";\nimport {LibParseOperand} from \"../lib/parse/LibParseOperand.sol\";\n\n/// @dev This is a placeholder for the subparser function pointers.\n/// The subparser function pointers are a list of 16 bit function pointers,\n/// where each subparser function is responsible for parsing a particular\n/// word into a an opcode that will be used by the main parser to build the\n/// final bytecode.\nbytes constant SUB_PARSER_WORD_PARSERS = hex\"\";\n\n/// @dev This is a placeholder for the subparser meta bytes.\n/// The subparser meta bytes are the same structure as the main parser meta\n/// bytes. The exact same process of hashing, blooming, fingeprinting and index\n/// lookup applies to the subparser meta bytes as the main parser meta bytes.\nbytes constant SUB_PARSER_PARSE_META = hex\"\";\n\n/// @dev This is a placeholder for the int that encodes pointers to operand\n/// parsers.\nbytes constant SUB_PARSER_OPERAND_HANDLERS = hex\"\";\n\n/// @dev This is a placeholder for the int that encodes pointers to literal\n/// parsers.\nbytes constant SUB_PARSER_LITERAL_PARSERS = hex\"\";\n\n/// Base implementation of `ISubParserV2`. Inherit from this contract and\n/// override the virtual functions to align all the relevant pointers and\n/// metadata bytes so that it can actually run.\n/// The basic workflow for subparsing via this contract is:\n/// - The main parser will call `subParse` with the subparser's compatibility\n///   version and the data to parse.\n/// - The subparser will check the compatibility is an exact match and revert if\n///   not. This is the simplest and most conservative approach, if there's a new\n///   compatibility version, a new version of the subparser will need to be\n///   deployed even if the upstream changes are backwards compatible.\n/// - The subparser will then parse the data, using the `subParserParseMeta`\n///   function to get the metadata bytes, which must be overridden by the child\n///   contract in order to be useful. The sub parser meta bytes are constructed\n///   exactly the same as the main parser meta bytes, so the same types and libs\n///   can be used to build them. The key difference is that the index of each\n///   word in the authoring meta maps to a _parser_ function pointer, rather\n///   than a _handler_ function pointer. What this means is that the function\n///   at index N of `subParserFunctionPointers` is responsible for parsing\n///   whatever data the main parser has passed to `subParse` into whatever the\n///   final output of the subparser is. For example, the 5th parser function\n///   might convert some word string `\"foo\"` into the bytecode that represents\n///   an extern call on the main interpreter into the contract that provides\n///   that extern logic. This decoupling allows any subparser function to\n///   generate any runtime behaviour at all, provided it knows how to construct\n///   the opcode for it.\n/// - Currently the subparse handles literals and operands in the same way as\n///   the main parser, but this may change in future. Likely that there will be\n///   dedicated \"sub literal\" and \"sub word\" concepts, that should be more\n///   composable than the current approach.\n/// - The final result of the subparser is returned as a tuple of success,\n///   bytecode and constants. The success flag is used to indicate whether the\n///   subparser was able to parse the data, and the bytecode and constants are\n///   the same as the main parser, and are used to construct the final bytecode\n///   of the main parser. The expectation on failure is that there may be some\n///   other subparser that can parse the data, so the main parser will handle\n///   fallback logic.\nabstract contract BaseRainterpreterSubParserNPE2 is ERC165, ISubParserV2 {\n    using LibBytes for bytes;\n    using LibParse for ParseState;\n    using LibParseMeta for ParseState;\n    using LibParseOperand for ParseState;\n\n    /// Overrideable function to allow implementations to define their parse\n    /// meta bytes.\n    //slither-disable-next-line dead-code\n    function subParserParseMeta() internal pure virtual returns (bytes memory) {\n        return SUB_PARSER_PARSE_META;\n    }\n\n    /// Overrideable function to allow implementations to define their function\n    /// pointers to each sub parser.\n    //slither-disable-next-line dead-code\n    function subParserWordParsers() internal pure virtual returns (bytes memory) {\n        return SUB_PARSER_WORD_PARSERS;\n    }\n\n    /// Overrideable function to allow implementations to define their operand\n    /// handlers.\n    //slither-disable-next-line dead-code\n    function subParserOperandHandlers() internal pure virtual returns (bytes memory) {\n        return SUB_PARSER_OPERAND_HANDLERS;\n    }\n\n    /// Overrideable function to allow implementations to define their literal\n    /// parsers.\n    //slither-disable-next-line dead-code\n    function subParserLiteralParsers() internal pure virtual returns (bytes memory) {\n        return SUB_PARSER_LITERAL_PARSERS;\n    }\n\n    /// Overrideable function to allow implementations to define their\n    /// compatibility version. Most implementations should leave this as the\n    /// default as it matches the main parser's compatibility version as at the\n    /// same commit the abstract sub parser is pulled from.\n    //slither-disable-next-line dead-code\n    function subParserCompatibility() internal pure virtual returns (bytes32) {\n        return COMPATIBLITY_V3;\n    }\n\n    /// Overrideable function to allow implementations to define their\n    /// literal dispatch matching. This is optional, and if not overridden\n    /// simply won't attempt to parse any literals. This is usually what you\n    /// want, as the main parser will handle common literals and the subparser\n    /// can focus on words, which is the more common case.\n    /// @param cursor The cursor to the memory location of the start of the\n    /// dispatch data.\n    /// @param end The cursor to the memory location of the end of the dispatch\n    /// data.\n    /// @return success Whether the dispatch was successfully matched. If the\n    /// sub parser does not recognise the dispatch data, it should return false.\n    /// The main parser MAY fallback to other sub parsers, so this is not\n    /// necessarily a failure condition.\n    /// @return index The index of the sub parser literal parser to use. If\n    /// success is true, this MUST match the position of the function pointer in\n    /// the bytes returned by `subParserLiteralParsers`.\n    /// @return value The value of the dispatch data, which is passed to the\n    /// sub parser literal parser. This MAY be zero if the sub parser does not\n    /// need to use the dispatch data. The interpretation of this value is\n    /// entirely up to the sub parser.\n    //slither-disable-next-line dead-code\n    function matchSubParseLiteralDispatch(uint256 cursor, uint256 end)\n        internal\n        pure\n        virtual\n        returns (bool success, uint256 index, uint256 value)\n    {\n        (cursor, end);\n        success = false;\n        index = 0;\n        value = 0;\n    }\n\n    modifier onlyCompatible(bytes32 compatibility) {\n        if (compatibility != subParserCompatibility()) {\n            revert IncompatibleSubParser();\n        }\n        _;\n    }\n\n    /// A basic implementation of sub parsing literals that uses encoded\n    /// function pointers to dispatch everything necessary in O(1) and allows\n    /// for the child contract to override all relevant functions with some\n    /// modest boilerplate.\n    /// This is virtual but the expectation is that it generally DOES NOT need\n    /// to be overridden, as the function pointers and metadata bytes are all\n    /// that need to be changed to implement a new subparser.\n    /// @inheritdoc ISubParserV2\n    function subParseLiteral(bytes32 compatibility, bytes memory data)\n        external\n        pure\n        virtual\n        onlyCompatible(compatibility)\n        returns (bool, uint256)\n    {\n        (uint256 dispatchStart, uint256 bodyStart, uint256 bodyEnd) = LibSubParse.consumeSubParseLiteralInputData(data);\n\n        (bool success, uint256 index, uint256 dispatchValue) = matchSubParseLiteralDispatch(dispatchStart, bodyStart);\n\n        if (success) {\n            function (uint256, uint256, uint256) internal pure returns (uint256) subParser;\n            bytes memory localSubParserLiteralParsers = subParserLiteralParsers();\n            assembly (\"memory-safe\") {\n                subParser := and(mload(add(localSubParserLiteralParsers, mul(add(index, 1), 2))), 0xFFFF)\n            }\n            return (true, subParser(dispatchValue, bodyStart, bodyEnd));\n        } else {\n            return (false, 0);\n        }\n    }\n\n    /// A basic implementation of sub parsing words that uses encoded function\n    /// pointers to dispatch everything necessary in O(1) and allows for the\n    /// child contract to override all relevant functions with some modest\n    /// boilerplate.\n    /// This is virtual but the expectation is that it generally DOES NOT need\n    /// to be overridden, as the function pointers and metadata bytes are all\n    /// that need to be changed to implement a new subparser.\n    /// @inheritdoc ISubParserV2\n    function subParseWord(bytes32 compatibility, bytes memory data)\n        external\n        pure\n        virtual\n        onlyCompatible(compatibility)\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        (uint256 constantsHeight, uint256 ioByte, ParseState memory state) =\n            LibSubParse.consumeSubParseWordInputData(data, subParserParseMeta(), subParserOperandHandlers());\n        uint256 cursor = Pointer.unwrap(state.data.dataPointer());\n        uint256 end = cursor + state.data.length;\n\n        bytes32 word;\n        (cursor, word) = LibParse.parseWord(cursor, end, CMASK_RHS_WORD_TAIL);\n        (bool exists, uint256 index) = state.lookupWord(word);\n        if (exists) {\n            Operand operand = state.handleOperand(index);\n            function (uint256, uint256, Operand) internal pure returns (bool, bytes memory, uint256[] memory) subParser;\n            bytes memory localSubParserWordParsers = subParserWordParsers();\n            assembly (\"memory-safe\") {\n                subParser := and(mload(add(localSubParserWordParsers, mul(add(index, 1), 2))), 0xFFFF)\n            }\n            return subParser(constantsHeight, ioByte, operand);\n        } else {\n            return (false, \"\", new uint256[](0));\n        }\n    }\n\n    /// @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(ISubParserV2).interfaceId || super.supportsInterface(interfaceId);\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/lib/rain.lib.typecast/src/LibConvert.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @title LibConvert\n/// @notice Type conversions that require additional structural changes to\n/// complete safely. These are NOT mere type casts and involve additional\n/// reads and writes to complete, such as recalculating the length of an array.\n/// The convention \"toX\" is adopted from Rust to imply the additional costs and\n/// consumption of the source to produce the target.\nlibrary LibConvert {\n    /// Convert an array of integers to `bytes` data. This requires modifying\n    /// the length in situ as the integer array length is measured in 32 byte\n    /// increments while the length of `bytes` is the literal number of bytes.\n    ///\n    /// It is unsafe for the caller to use `us_` after it has been converted to\n    /// bytes because there is now two pointers to the same mutable data\n    /// structure AND the length prefix for the `uint256[]` version is corrupt.\n    ///\n    /// @param us_ The integer array to convert to `bytes`.\n    /// @return bytes_ The integer array converted to `bytes` data.\n    function unsafeToBytes(uint256[] memory us_) internal pure returns (bytes memory bytes_) {\n        assembly (\"memory-safe\") {\n            bytes_ := us_\n            // Length in bytes is 32x the length in uint256\n            mstore(bytes_, mul(0x20, mload(bytes_)))\n        }\n    }\n\n    /// Truncate `uint256[]` values down to `uint16[]` then pack this to `bytes`\n    /// without padding or length prefix. Unsafe because the starting `uint256`\n    /// values are not checked for overflow due to the truncation. The caller\n    /// MUST ensure that all values fit in `type(uint16).max` or that silent\n    /// overflow is safe.\n    /// @param us_ The `uint256[]` to truncate and concatenate to 16 bit `bytes`.\n    /// @return The concatenated 2-byte chunks.\n    function unsafeTo16BitBytes(uint256[] memory us_) internal pure returns (bytes memory) {\n        unchecked {\n            // We will keep 2 bytes (16 bits) from each integer.\n            bytes memory bytes_ = new bytes(us_.length * 2);\n            assembly (\"memory-safe\") {\n                let replaceMask_ := 0xFFFF\n                let preserveMask_ := not(replaceMask_)\n                for {\n                    let cursor_ := add(us_, 0x20)\n                    let end_ := add(cursor_, mul(mload(us_), 0x20))\n                    let bytesCursor_ := add(bytes_, 0x02)\n                } lt(cursor_, end_) {\n                    cursor_ := add(cursor_, 0x20)\n                    bytesCursor_ := add(bytesCursor_, 0x02)\n                } {\n                    let data_ := mload(bytesCursor_)\n                    mstore(bytesCursor_, or(and(preserveMask_, data_), and(replaceMask_, mload(cursor_))))\n                }\n            }\n            return bytes_;\n        }\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/error/ErrOpList.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.19;\n\n/// @dev Workaround for https://github.com/foundry-rs/foundry/issues/6572\ncontract ErrOpList {}\n\n/// Thrown when a dynamic length array is NOT 1 more than a fixed length array.\n/// Should never happen outside a major breaking change to memory layouts.\nerror BadDynamicLength(uint256 dynamicLength, uint256 standardOpsLength);\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/extern/reference/op/LibExternOpContextSenderNPE2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity =0.8.19;\n\nimport {Operand} from \"rain.interpreter.interface/interface/IInterpreterV2.sol\";\nimport {LibSubParse} from \"../../../parse/LibSubParse.sol\";\nimport {IInterpreterExternV3} from \"rain.interpreter.interface/interface/IInterpreterExternV3.sol\";\nimport {CONTEXT_BASE_COLUMN, CONTEXT_BASE_ROW_SENDER} from \"rain.interpreter.interface/lib/caller/LibContext.sol\";\n\n/// @title LibExternOpContextSenderNPE2\n/// This op is a simple reference to the sender of the transaction that called\n/// the interpreter. It is used to demonstrate how to implement context\n/// references.\nlibrary LibExternOpContextSenderNPE2 {\n    /// The sub parser for the extern increment opcode. It has no special logic\n    /// so uses the default sub parser from `LibSubParse`.\n    //slither-disable-next-line dead-code\n    function subParser(uint256, uint256, Operand) internal pure returns (bool, bytes memory, uint256[] memory) {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_BASE_COLUMN, CONTEXT_BASE_ROW_SENDER);\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/extern/reference/op/LibExternOpContextCallingContractNPE2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity =0.8.19;\n\nimport {Operand} from \"rain.interpreter.interface/interface/IInterpreterV2.sol\";\nimport {LibSubParse} from \"../../../parse/LibSubParse.sol\";\nimport {IInterpreterExternV3} from \"rain.interpreter.interface/interface/IInterpreterExternV3.sol\";\nimport {\n    CONTEXT_BASE_COLUMN,\n    CONTEXT_BASE_ROW_CALLING_CONTRACT\n} from \"rain.interpreter.interface/lib/caller/LibContext.sol\";\n\n/// @title LibExternOpContextCallingContractNPE2\n/// This op is a simple reference to the contract that called the interpreter.\n/// It is used to demonstrate how to implement context references.\nlibrary LibExternOpContextCallingContractNPE2 {\n    /// The sub parser for the extern increment opcode. It has no special logic\n    /// so uses the default sub parser from `LibSubParse`.\n    //slither-disable-next-line dead-code\n    function subParser(uint256, uint256, Operand) internal pure returns (bool, bytes memory, uint256[] memory) {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_BASE_COLUMN, CONTEXT_BASE_ROW_CALLING_CONTRACT);\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Matrix.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibPointer.sol\";\n\nlibrary LibUint256Matrix {\n    /// Pointer to the start (length prefix) of a `uint256[][]`.\n    /// @param matrix The matrix to get the start pointer of.\n    /// @return pointer The pointer to the start of `matrix`.\n    function startPointer(uint256[][] memory matrix) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := matrix\n        }\n    }\n\n    /// Pointer to the data of a `uint256[][]` NOT the length prefix.\n    /// Note that the data of a `uint256[][]` is _references_ to the `uint256[]`\n    /// start pointers and does NOT include the arrays themselves.\n    /// @param matrix The matrix to get the data pointer of.\n    /// @return pointer The pointer to the data of `matrix`.\n    function dataPointer(uint256[][] memory matrix) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(matrix, 0x20)\n        }\n    }\n\n    /// Pointer to the end of the allocated memory of a matrix.\n    /// Note that the data of a `uint256[][]` is _references_ to the `uint256[]`\n    /// start pointers and does NOT include the arrays themselves.\n    /// @param matrix The matrix to get the end pointer of.\n    /// @return pointer The pointer to the end of `matrix`.\n    function endPointer(uint256[][] memory matrix) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(matrix, add(0x20, mul(0x20, mload(matrix))))\n        }\n    }\n\n    /// Cast a `Pointer` to `uint256[][]` without modification or safety checks.\n    /// The caller MUST ensure the pointer is to a valid region of memory for\n    /// some `uint256[][]`.\n    /// @param pointer The pointer to cast to `uint256[][]`.\n    /// @return matrix The cast `uint256[][]`.\n    function unsafeAsUint256Matrix(Pointer pointer) internal pure returns (uint256[][] memory matrix) {\n        assembly (\"memory-safe\") {\n            matrix := pointer\n        }\n    }\n\n    /// 2-dimensional analogue of `arrayFrom`. Takes a 1-dimensional array and\n    /// coerces it to a 2-dimensional matrix where the first and only item in the\n    /// matrix is the 1-dimensional array.\n    /// @param a The 1-dimensional array to include in the matrix.\n    /// @return matrix The 2-dimensional matrix containing `a`.\n    function matrixFrom(uint256[] memory a) internal pure returns (uint256[][] memory matrix) {\n        assembly (\"memory-safe\") {\n            matrix := mload(0x40)\n            mstore(matrix, 1)\n            mstore(add(matrix, 0x20), a)\n            mstore(0x40, add(matrix, 0x40))\n        }\n    }\n\n    /// 2-dimensional analogue of `arrayFrom`. Takes 1-dimensional arrays and\n    /// coerces them to a 2-dimensional matrix where items in the matrix are the\n    /// 1-dimensional arrays.\n    /// @param a The 1-dimensional array to include in the matrix.\n    /// @param b Second 1-dimensional array to include in the matrix.\n    /// @return matrix The 2-dimensional matrix containing `a` and `b`.\n    function matrixFrom(uint256[] memory a, uint256[] memory b) internal pure returns (uint256[][] memory matrix) {\n        assembly (\"memory-safe\") {\n            matrix := mload(0x40)\n            mstore(matrix, 2)\n            mstore(add(matrix, 0x20), a)\n            mstore(add(matrix, 0x40), b)\n            mstore(0x40, add(matrix, 0x60))\n        }\n    }\n\n    /// 2-dimensional analogue of `arrayFrom`. Takes 1-dimensional arrays and\n    /// coerces them to a 2-dimensional matrix where items in the matrix are the\n    /// 1-dimensional arrays.\n    /// @param a The 1-dimensional array to include in the matrix.\n    /// @param b Second 1-dimensional array to include in the matrix.\n    /// @param c Third 1-dimensional array to include in the matrix.\n    /// @return matrix The 2-dimensional matrix containing `a`, `b` and `c`.\n    function matrixFrom(uint256[] memory a, uint256[] memory b, uint256[] memory c)\n        internal\n        pure\n        returns (uint256[][] memory matrix)\n    {\n        assembly (\"memory-safe\") {\n            matrix := mload(0x40)\n            mstore(matrix, 3)\n            mstore(add(matrix, 0x20), a)\n            mstore(add(matrix, 0x40), b)\n            mstore(add(matrix, 0x60), c)\n            mstore(0x40, add(matrix, 0x80))\n        }\n    }\n\n    /// Counts the total number of items in the matrix across all internal\n    /// arrays. Normally `matrix.length` only returns the number of internal\n    /// arrays, not the total number of items in the matrix.\n    function itemCount(uint256[][] memory matrix) internal pure returns (uint256 count) {\n        assembly (\"memory-safe\") {\n            let cursor := add(matrix, 0x20)\n            let end := add(cursor, mul(mload(matrix), 0x20))\n\n            for {} lt(cursor, end) {} {\n                count := add(count, mload(mload(cursor)))\n                cursor := add(cursor, 0x20)\n            }\n        }\n    }\n\n    /// Allocates and builds a new `uint256[]` from a `uint256[][]`. This is\n    /// potentially memory intensive and expensive, but there's no way around\n    /// the allocation if a flat array is needed. This is because 2-dimensional\n    /// arrays are stored as a length-prefixed array of pointers to 1-dimensional\n    /// arrays, not as a contiguous block of memory.\n    /// @param matrix The matrix to flatten.\n    /// @return array The flattened array.\n    function flatten(uint256[][] memory matrix) internal pure returns (uint256[] memory) {\n        uint256 length = itemCount(matrix);\n        uint256[] memory array;\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(0x40, add(array, add(0x20, mul(length, 0x20))))\n            mstore(array, length)\n\n            let cursor := add(matrix, 0x20)\n            let end := add(cursor, mul(mload(matrix), 0x20))\n\n            let arrayCursor := add(array, 0x20)\n            for {} lt(cursor, end) {} {\n                let itemCursor := add(mload(cursor), 0x20)\n                let itemEnd := add(itemCursor, mul(mload(mload(cursor)), 0x20))\n                for {} lt(itemCursor, itemEnd) {} {\n                    mstore(arrayCursor, mload(itemCursor))\n                    arrayCursor := add(arrayCursor, 0x20)\n                    itemCursor := add(itemCursor, 0x20)\n                }\n                cursor := add(cursor, 0x20)\n            }\n        }\n        return array;\n    }\n}\n"
      },
      "lib/rain.orderbook/src/lib/LibOrderBookSubParser.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.19;\n\nimport {AuthoringMetaV2, Operand} from \"rain.interpreter.interface/interface/ISubParserV2.sol\";\nimport {LibUint256Matrix} from \"rain.solmem/lib/LibUint256Matrix.sol\";\nimport {LibSubParse} from \"rain.interpreter/lib/parse/LibSubParse.sol\";\nimport {\n    CONTEXT_BASE_COLUMN,\n    CONTEXT_BASE_ROW_SENDER,\n    CONTEXT_BASE_ROW_CALLING_CONTRACT,\n    CONTEXT_BASE_ROWS,\n    CONTEXT_COLUMNS,\n    CONTEXT_VAULT_OUTPUTS_COLUMN,\n    CONTEXT_VAULT_INPUTS_COLUMN,\n    CONTEXT_CALCULATIONS_COLUMN,\n    CONTEXT_CALLING_CONTEXT_COLUMN,\n    CONTEXT_VAULT_IO_BALANCE_DIFF,\n    CONTEXT_VAULT_IO_BALANCE_BEFORE,\n    CONTEXT_VAULT_IO_VAULT_ID,\n    CONTEXT_VAULT_IO_TOKEN_DECIMALS,\n    CONTEXT_VAULT_IO_TOKEN,\n    CONTEXT_VAULT_IO_ROWS,\n    CONTEXT_CALCULATIONS_ROW_IO_RATIO,\n    CONTEXT_CALCULATIONS_ROW_MAX_OUTPUT,\n    CONTEXT_CALCULATIONS_ROWS,\n    CONTEXT_CALLING_CONTEXT_ROW_ORDER_COUNTERPARTY,\n    CONTEXT_CALLING_CONTEXT_ROW_ORDER_OWNER,\n    CONTEXT_CALLING_CONTEXT_ROW_ORDER_HASH,\n    CONTEXT_CALLING_CONTEXT_ROWS,\n    CONTEXT_SIGNED_CONTEXT_SIGNERS_COLUMN,\n    CONTEXT_SIGNED_CONTEXT_SIGNERS_ROW,\n    CONTEXT_SIGNED_CONTEXT_SIGNERS_ROWS,\n    CONTEXT_SIGNED_CONTEXT_START_COLUMN,\n    CONTEXT_SIGNED_CONTEXT_START_ROW,\n    CONTEXT_SIGNED_CONTEXT_START_ROWS\n} from \"./LibOrderBook.sol\";\n\nuint256 constant SUB_PARSER_WORD_PARSERS_LENGTH = 2;\n\nbytes constant WORD_ORDER_CLEARER = \"order-clearer\";\nbytes constant WORD_ORDERBOOK = \"orderbook\";\nbytes constant WORD_ORDER_HASH = \"order-hash\";\nbytes constant WORD_ORDER_OWNER = \"order-owner\";\nbytes constant WORD_ORDER_COUNTERPARTY = \"order-counterparty\";\nbytes constant WORD_CALCULATED_MAX_OUTPUT = \"calculated-max-output\";\nbytes constant WORD_CALCULATED_IO_RATIO = \"calculated-io-ratio\";\nbytes constant WORD_INPUT_TOKEN = \"input-token\";\nbytes constant WORD_INPUT_TOKEN_DECIMALS = \"input-token-decimals\";\nbytes constant WORD_INPUT_VAULT_ID = \"input-vault-id\";\nbytes constant WORD_INPUT_VAULT_BALANCE_BEFORE = \"input-vault-balance-before\";\nbytes constant WORD_INPUT_VAULT_BALANCE_INCREASE = \"input-vault-balance-increase\";\nbytes constant WORD_OUTPUT_TOKEN = \"output-token\";\nbytes constant WORD_OUTPUT_TOKEN_DECIMALS = \"output-token-decimals\";\nbytes constant WORD_OUTPUT_VAULT_ID = \"output-vault-id\";\nbytes constant WORD_OUTPUT_VAULT_BALANCE_BEFORE = \"output-vault-balance-before\";\nbytes constant WORD_OUTPUT_VAULT_BALANCE_DECREASE = \"output-vault-balance-decrease\";\n\n/// @title LibOrderBookSubParser\nlibrary LibOrderBookSubParser {\n    using LibUint256Matrix for uint256[][];\n\n    function subParserSender(uint256, uint256, Operand) internal pure returns (bool, bytes memory, uint256[] memory) {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_BASE_COLUMN, CONTEXT_BASE_ROW_SENDER);\n    }\n\n    function subParserCallingContract(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_BASE_COLUMN, CONTEXT_BASE_ROW_CALLING_CONTRACT);\n    }\n\n    function subParserOrderHash(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_CALLING_CONTEXT_COLUMN, CONTEXT_CALLING_CONTEXT_ROW_ORDER_HASH);\n    }\n\n    function subParserOrderOwner(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_CALLING_CONTEXT_COLUMN, CONTEXT_CALLING_CONTEXT_ROW_ORDER_OWNER);\n    }\n\n    function subParserOrderCounterparty(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return\n            LibSubParse.subParserContext(CONTEXT_CALLING_CONTEXT_COLUMN, CONTEXT_CALLING_CONTEXT_ROW_ORDER_COUNTERPARTY);\n    }\n\n    function subParserMaxOutput(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_CALCULATIONS_COLUMN, CONTEXT_CALCULATIONS_ROW_MAX_OUTPUT);\n    }\n\n    function subParserIORatio(uint256, uint256, Operand) internal pure returns (bool, bytes memory, uint256[] memory) {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_CALCULATIONS_COLUMN, CONTEXT_CALCULATIONS_ROW_IO_RATIO);\n    }\n\n    function subParserInputToken(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_INPUTS_COLUMN, CONTEXT_VAULT_IO_TOKEN);\n    }\n\n    function subParserInputTokenDecimals(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_INPUTS_COLUMN, CONTEXT_VAULT_IO_TOKEN_DECIMALS);\n    }\n\n    function subParserInputVaultId(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_INPUTS_COLUMN, CONTEXT_VAULT_IO_VAULT_ID);\n    }\n\n    function subParserInputBalanceBefore(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_INPUTS_COLUMN, CONTEXT_VAULT_IO_BALANCE_BEFORE);\n    }\n\n    function subParserInputBalanceDiff(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_INPUTS_COLUMN, CONTEXT_VAULT_IO_BALANCE_DIFF);\n    }\n\n    function subParserOutputToken(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_OUTPUTS_COLUMN, CONTEXT_VAULT_IO_TOKEN);\n    }\n\n    function subParserOutputTokenDecimals(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_OUTPUTS_COLUMN, CONTEXT_VAULT_IO_TOKEN_DECIMALS);\n    }\n\n    function subParserOutputVaultId(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_OUTPUTS_COLUMN, CONTEXT_VAULT_IO_VAULT_ID);\n    }\n\n    function subParserOutputBalanceBefore(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_OUTPUTS_COLUMN, CONTEXT_VAULT_IO_BALANCE_BEFORE);\n    }\n\n    function subParserOutputBalanceDiff(uint256, uint256, Operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_VAULT_OUTPUTS_COLUMN, CONTEXT_VAULT_IO_BALANCE_DIFF);\n    }\n\n    function subParserSigners(uint256, uint256, Operand operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_SIGNED_CONTEXT_SIGNERS_COLUMN, Operand.unwrap(operand));\n    }\n\n    function subParserSignedContext(uint256, uint256, Operand operand)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        uint256 column = Operand.unwrap(operand) & 0xFF;\n        uint256 row = (Operand.unwrap(operand) >> 8) & 0xFF;\n        //slither-disable-next-line unused-return\n        return LibSubParse.subParserContext(CONTEXT_SIGNED_CONTEXT_START_COLUMN + column, row);\n    }\n\n    //slither-disable-next-line dead-code\n    function authoringMetaV2() internal pure returns (bytes memory) {\n        // Add 2 for the signed context signers and signed context start columns.\n        AuthoringMetaV2[][] memory meta = new AuthoringMetaV2[][](CONTEXT_COLUMNS + 2);\n\n        AuthoringMetaV2[] memory contextBaseMeta = new AuthoringMetaV2[](CONTEXT_BASE_ROWS);\n        contextBaseMeta[CONTEXT_BASE_ROW_SENDER] = AuthoringMetaV2(\n            bytes32(WORD_ORDER_CLEARER),\n            \"The order clearer is the address that submitted the transaction that is causing the order to execute. This MAY be the counterparty, e.g. when an order is being taken directly, but it MAY NOT be the counterparty if a third party is clearing two orders against each other.\"\n        );\n        contextBaseMeta[CONTEXT_BASE_ROW_CALLING_CONTRACT] =\n            AuthoringMetaV2(bytes32(WORD_ORDERBOOK), \"The address of the orderbook that the order is being run on.\");\n\n        AuthoringMetaV2[] memory contextCallingContextMeta = new AuthoringMetaV2[](CONTEXT_CALLING_CONTEXT_ROWS);\n        contextCallingContextMeta[CONTEXT_CALLING_CONTEXT_ROW_ORDER_HASH] =\n            AuthoringMetaV2(bytes32(WORD_ORDER_HASH), \"The hash of the order that is being cleared.\");\n        contextCallingContextMeta[CONTEXT_CALLING_CONTEXT_ROW_ORDER_OWNER] =\n            AuthoringMetaV2(bytes32(WORD_ORDER_OWNER), \"The address of the order owner.\");\n        contextCallingContextMeta[CONTEXT_CALLING_CONTEXT_ROW_ORDER_COUNTERPARTY] = AuthoringMetaV2(\n            bytes32(WORD_ORDER_COUNTERPARTY),\n            \"The address of the owner of the counterparty order. Will be the order taker if there is no counterparty order.\"\n        );\n\n        AuthoringMetaV2[] memory contextCalculationsMeta = new AuthoringMetaV2[](CONTEXT_CALCULATIONS_ROWS);\n        contextCalculationsMeta[CONTEXT_CALCULATIONS_ROW_MAX_OUTPUT] = AuthoringMetaV2(\n            bytes32(WORD_CALCULATED_MAX_OUTPUT),\n            \"The maximum output of the order, i.e. the maximum amount of the output token that the order will send. This is normalized to 18 decimal fixed point regardless of the decimals of the underlying token. This is 0 before calculations have been run.\"\n        );\n        contextCalculationsMeta[CONTEXT_CALCULATIONS_ROW_IO_RATIO] = AuthoringMetaV2(\n            bytes32(WORD_CALCULATED_IO_RATIO),\n            \"The ratio of the input to output token, i.e. the amount of the input token that the order will receive for each unit of the output token that it sends. This is normalized to 18 decimal fixed point regardless of the decimals of the underlying tokens. This is 0 before calculations have been run.\"\n        );\n\n        AuthoringMetaV2[] memory contextVaultInputsMeta = new AuthoringMetaV2[](CONTEXT_VAULT_IO_ROWS);\n        contextVaultInputsMeta[CONTEXT_VAULT_IO_TOKEN] =\n            AuthoringMetaV2(bytes32(WORD_INPUT_TOKEN), \"The address of the input token for the vault input.\");\n        contextVaultInputsMeta[CONTEXT_VAULT_IO_TOKEN_DECIMALS] =\n            AuthoringMetaV2(bytes32(WORD_INPUT_TOKEN_DECIMALS), \"The decimals of the input token for the vault input.\");\n        contextVaultInputsMeta[CONTEXT_VAULT_IO_VAULT_ID] = AuthoringMetaV2(\n            bytes32(WORD_INPUT_VAULT_ID), \"The ID of the input vault that incoming tokens are received into.\"\n        );\n        contextVaultInputsMeta[CONTEXT_VAULT_IO_BALANCE_BEFORE] = AuthoringMetaV2(\n            bytes32(WORD_INPUT_VAULT_BALANCE_BEFORE), \"The balance of the input vault before the order is cleared.\"\n        );\n        contextVaultInputsMeta[CONTEXT_VAULT_IO_BALANCE_DIFF] = AuthoringMetaV2(\n            bytes32(WORD_INPUT_VAULT_BALANCE_INCREASE),\n            \"The difference in the balance of the input vault after the order is cleared. This is always positive so it must be added to the input balance before to get the final vault balance. This is 0 before calculations have been run.\"\n        );\n\n        AuthoringMetaV2[] memory contextVaultOutputsMeta = new AuthoringMetaV2[](CONTEXT_VAULT_IO_ROWS);\n        contextVaultOutputsMeta[CONTEXT_VAULT_IO_TOKEN] =\n            AuthoringMetaV2(bytes32(WORD_OUTPUT_TOKEN), \"The address of the output token for the vault output.\");\n        contextVaultOutputsMeta[CONTEXT_VAULT_IO_TOKEN_DECIMALS] = AuthoringMetaV2(\n            bytes32(WORD_OUTPUT_TOKEN_DECIMALS), \"The decimals of the output token for the vault output.\"\n        );\n        contextVaultOutputsMeta[CONTEXT_VAULT_IO_VAULT_ID] = AuthoringMetaV2(\n            bytes32(WORD_OUTPUT_VAULT_ID), \"The ID of the output vault that outgoing tokens are sent from.\"\n        );\n        contextVaultOutputsMeta[CONTEXT_VAULT_IO_BALANCE_BEFORE] = AuthoringMetaV2(\n            bytes32(WORD_OUTPUT_VAULT_BALANCE_BEFORE), \"The balance of the output vault before the order is cleared.\"\n        );\n        contextVaultOutputsMeta[CONTEXT_VAULT_IO_BALANCE_DIFF] = AuthoringMetaV2(\n            bytes32(WORD_OUTPUT_VAULT_BALANCE_DECREASE),\n            \"The difference in the balance of the output vault after the order is cleared. This is always positive so it must be subtracted from the output balance before to get the final vault balance. This is 0 before calculations have been run.\"\n        );\n\n        AuthoringMetaV2[] memory contextSignersMeta = new AuthoringMetaV2[](CONTEXT_SIGNED_CONTEXT_SIGNERS_ROWS);\n        contextSignersMeta[CONTEXT_SIGNED_CONTEXT_SIGNERS_ROW] = AuthoringMetaV2(\n            bytes32(\"signer\"),\n            \"The addresses of the signers of the signed context. The indexes of the signers matches the column they signed in the signed context grid.\"\n        );\n\n        AuthoringMetaV2[] memory contextSignedMeta = new AuthoringMetaV2[](CONTEXT_SIGNED_CONTEXT_START_ROWS);\n        contextSignedMeta[CONTEXT_SIGNED_CONTEXT_START_ROW] = AuthoringMetaV2(\n            bytes32(\"signed-context\"),\n            \"Signed context is provided by the order clearer/taker and can be signed by anyone. Orderbook will check the signature, but the expression author much authorize the signer's public key.\"\n        );\n\n        meta[CONTEXT_BASE_COLUMN] = contextBaseMeta;\n        meta[CONTEXT_CALLING_CONTEXT_COLUMN] = contextCallingContextMeta;\n        meta[CONTEXT_CALCULATIONS_COLUMN] = contextCalculationsMeta;\n        meta[CONTEXT_VAULT_INPUTS_COLUMN] = contextVaultInputsMeta;\n        meta[CONTEXT_VAULT_OUTPUTS_COLUMN] = contextVaultOutputsMeta;\n        meta[CONTEXT_SIGNED_CONTEXT_SIGNERS_COLUMN] = contextSignersMeta;\n        meta[CONTEXT_SIGNED_CONTEXT_START_COLUMN] = contextSignedMeta;\n\n        uint256[][] memory metaUint256;\n        assembly {\n            metaUint256 := meta\n        }\n        uint256[] memory metaUint256Flattened = metaUint256.flatten();\n        AuthoringMetaV2[] memory metaFlattened;\n        assembly {\n            metaFlattened := metaUint256Flattened\n        }\n\n        return abi.encode(metaFlattened);\n    }\n}\n"
      },
      "lib/rain.orderbook/src/lib/LibOrderBook.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.19;\n\nimport {\n    CONTEXT_BASE_ROWS,\n    CONTEXT_BASE_ROW_SENDER,\n    CONTEXT_BASE_ROW_CALLING_CONTRACT,\n    CONTEXT_BASE_COLUMN\n} from \"rain.interpreter.interface/lib/caller/LibContext.sol\";\n\n/// @dev Orderbook context is actually fairly complex. The calling context column\n/// is populated before calculate order, but the remaining columns are only\n/// available to handle IO as they depend on the full evaluation of calculuate\n/// order, and cross referencing against the same from the counterparty, as well\n/// as accounting limits such as current vault balances, etc.\n/// The token address and decimals for vault inputs and outputs IS available to\n/// the calculate order entrypoint, but not the final vault balances/diff.\nuint256 constant CALLING_CONTEXT_COLUMNS = 4;\n\nuint256 constant CONTEXT_COLUMNS = CALLING_CONTEXT_COLUMNS + 1;\n\n/// @dev Contextual data available to both calculate order and handle IO. The\n/// order hash, order owner and order counterparty. IMPORTANT NOTE that the\n/// typical base context of an order with the caller will often be an unrelated\n/// clearer of the order rather than the owner or counterparty.\nuint256 constant CONTEXT_CALLING_CONTEXT_COLUMN = 1;\nuint256 constant CONTEXT_CALLING_CONTEXT_ROWS = 3;\n\nuint256 constant CONTEXT_CALLING_CONTEXT_ROW_ORDER_HASH = 0;\nuint256 constant CONTEXT_CALLING_CONTEXT_ROW_ORDER_OWNER = 1;\nuint256 constant CONTEXT_CALLING_CONTEXT_ROW_ORDER_COUNTERPARTY = 2;\n\n/// @dev Calculations column contains the DECIMAL RESCALED calculations but\n/// otherwise provided as-is according to calculate order entrypoint\nuint256 constant CONTEXT_CALCULATIONS_COLUMN = 2;\nuint256 constant CONTEXT_CALCULATIONS_ROWS = 2;\n\nuint256 constant CONTEXT_CALCULATIONS_ROW_MAX_OUTPUT = 0;\nuint256 constant CONTEXT_CALCULATIONS_ROW_IO_RATIO = 1;\n\n/// @dev Vault inputs are the literal token amounts and vault balances before and\n/// after for the input token from the perspective of the order. MAY be\n/// significantly different to the calculated amount due to insufficient vault\n/// balances from either the owner or counterparty, etc.\nuint256 constant CONTEXT_VAULT_INPUTS_COLUMN = 3;\n/// @dev Vault outputs are the same as vault inputs but for the output token from\n/// the perspective of the order.\nuint256 constant CONTEXT_VAULT_OUTPUTS_COLUMN = 4;\n\n/// @dev Row of the token address for vault inputs and outputs columns.\nuint256 constant CONTEXT_VAULT_IO_TOKEN = 0;\n/// @dev Row of the token decimals for vault inputs and outputs columns.\nuint256 constant CONTEXT_VAULT_IO_TOKEN_DECIMALS = 1;\n/// @dev Row of the vault ID for vault inputs and outputs columns.\nuint256 constant CONTEXT_VAULT_IO_VAULT_ID = 2;\n/// @dev Row of the vault balance before the order was cleared for vault inputs\n/// and outputs columns.\nuint256 constant CONTEXT_VAULT_IO_BALANCE_BEFORE = 3;\n/// @dev Row of the vault balance difference after the order was cleared for\n/// vault inputs and outputs columns. The diff is ALWAYS POSITIVE as it is a\n/// `uint256` so it must be added to input balances and subtraced from output\n/// balances.\nuint256 constant CONTEXT_VAULT_IO_BALANCE_DIFF = 4;\n/// @dev Length of a vault IO column.\nuint256 constant CONTEXT_VAULT_IO_ROWS = 5;\n\nuint256 constant CONTEXT_SIGNED_CONTEXT_SIGNERS_COLUMN = 5;\nuint256 constant CONTEXT_SIGNED_CONTEXT_SIGNERS_ROWS = 1;\nuint256 constant CONTEXT_SIGNED_CONTEXT_SIGNERS_ROW = 0;\n\nuint256 constant CONTEXT_SIGNED_CONTEXT_START_COLUMN = 6;\nuint256 constant CONTEXT_SIGNED_CONTEXT_START_ROWS = 1;\nuint256 constant CONTEXT_SIGNED_CONTEXT_START_ROW = 0;\n"
      },
      "lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibBytes.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibPointer.sol\";\n\n/// Thrown when asked to truncate data to a longer length.\n/// @param length Actual bytes length.\n/// @param truncate Attempted truncation length.\nerror TruncateError(uint256 length, uint256 truncate);\n\n/// @title LibBytes\n/// @notice Tools for working directly with memory in a Solidity compatible way.\nlibrary LibBytes {\n    /// Truncates bytes of data by mutating its length directly.\n    /// Any excess bytes are leaked\n    function truncate(bytes memory data, uint256 length) internal pure {\n        if (data.length < length) {\n            revert TruncateError(data.length, length);\n        }\n        assembly (\"memory-safe\") {\n            mstore(data, length)\n        }\n    }\n\n    /// Pointer to the data of a bytes array NOT the length prefix.\n    /// @param data Bytes to get the data pointer for.\n    /// @return pointer Pointer to the data of the bytes in memory.\n    function dataPointer(bytes memory data) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(data, 0x20)\n        }\n    }\n\n    /// Pointer to the start of a bytes array (the length prefix).\n    /// @param data Bytes to get the pointer to.\n    /// @return pointer Pointer to the start of the bytes data structure.\n    function startPointer(bytes memory data) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := data\n        }\n    }\n\n    /// Pointer to the end of some bytes.\n    ///\n    /// Note that this pointer MAY NOT BE ALIGNED, i.e. it MAY NOT point to the\n    /// start of a multiple of 32, UNLIKE the free memory pointer at 0x40.\n    ///\n    /// @param data Bytes to get the pointer to the end of.\n    /// @return pointer Pointer to the end of the bytes data structure.\n    function endDataPointer(bytes memory data) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(data, add(0x20, mload(data)))\n        }\n    }\n\n    /// Pointer to the end of the memory allocated for bytes.\n    ///\n    /// The allocator is ALWAYS aligned to whole words, i.e. 32 byte multiples,\n    /// for data structures allocated by Solidity. This includes `bytes` which\n    /// means that any time the length of some `bytes` is NOT a multiple of 32\n    /// the alloation will point past the end of the `bytes` data.\n    ///\n    /// There is no guarantee that the memory region between `endDataPointer`\n    /// and `endAllocatedPointer` is zeroed out. It is best to think of that\n    /// space as leaked garbage.\n    ///\n    /// Almost always, e.g. for the purpose of copying data between regions, you\n    /// will want `endDataPointer` rather than this function.\n    /// @param data Bytes to get the end of the allocated data region for.\n    /// @return pointer Pointer to the end of the allocated data region.\n    function endAllocatedPointer(bytes memory data) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(data, and(add(add(mload(data), 0x20), 0x1f), not(0x1f)))\n        }\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/ISubParserV2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n// Reexports for implementations to use.\nimport {AuthoringMetaV2} from \"./IParserV1.sol\";\nimport {Operand} from \"./IInterpreterV2.sol\";\n\n/// @dev A compatibility version for the subparser interface.\n///\n/// ## Literal parsing\n///\n/// The structure of data for this version is:\n/// - bytes [0,1]: The length of the dispatch data as 2 bytes.\n/// - bytes [2,N-1+2]: The dispatch data, where N is the length of the dispatch\n///   data as defined by the first 2 bytes. This is used by the sub parser to\n///   decide which literal parser to use. If there are no matches the sub parser\n///   MUST return false and MUST NOT revert.\n/// - bytes [N+2,...]: The literal data that the sub parser is being asked to\n///   parse. The sub parser MUST revert if it cannot parse the literal, once it\n///   has determined that it is the correct sub parser to handle the literal.\n///\n/// ## Word parsing\n///\n/// The structure of data for this version is:\n/// - bytes [0,1]: The current height of the constants array on the main parser.\n/// - bytes [2,2]: The IO byte, that at the time of writing represents the\n///   number of inputs to the word.\n/// - bytes [3,4]; Two bytes that encodes N where N is the length in bytes of the\n///   rainlang word that could not be parsed in bytes.\n/// - bytes [5, N+5]: A string slice that the parser could not parse. For well\n///   formed rainlang it will be a word WITHOUT any associated operands. The\n///   parsing of operands is handled by the main parser, and the subparser is\n///   only expected to parse the word itself and handle the pre-parsed operand\n///   values.\n/// - bytes [N+5,...]: The operands that the main parser has already parsed as\n///   a standard `uint256[]` array. The subparser is expected to handle these\n///   operands as-is, and return bytecode that is compatible with the operand\n///   values. The first word of the array is the array length.\nbytes32 constant COMPATIBLITY_V2 = keccak256(\"2023.12.28 Rainlang ISubParserV2\");\n\n/// @dev A compatibility version for the subparser interface.\n///\n/// Identical to COMPATIBLITY_V2, except the IO byte in word parsing now encodes\n/// both the inputs and outputs. The IO byte is [2,2] in the word parsing data.\n/// The high/leftmost 4 bits of the IO byte encode the number of outputs, and the\n/// low/rightmost 4 bits of the IO byte encode the number of inputs. This implies\n/// that the number of inputs and outputs must each be less than 16.\nbytes32 constant COMPATIBLITY_V3 = keccak256(\"2024.02.15 Rainlang ISubParserV3\");\n\ninterface ISubParserV2 {\n    /// The sub parser is being asked to attempt to parse a literal that the main\n    /// parser has failed to parse. The sub parser MUST ONLY attempt to parse a\n    /// literal that matches both the compatibility version and that the data\n    /// represents a literal that the sub parser is capable of parsing. It is\n    /// expected that the main parser will attempt multiple sub parsers in order\n    /// to parse a literal, so the sub parser MUST NOT revert if it does not know\n    /// how to parse the literal, as some other sub parser may be able to parse\n    /// it. The sub parser MUST return false if it does not know how to parse the\n    /// literal, and MUST return true if it does know how to parse the literal,\n    /// as well as the value of the literal.\n    /// If the sub parser knows how to parse some literal, but the data is\n    /// malformed, the sub parser MUST revert.\n    /// If the compatibility version is not supported, the sub parser MUST\n    /// revert.\n    ///\n    /// Literal parsing is the process of taking a sequence of bytes and\n    /// converting it into a value that is known at compile time.\n    ///\n    /// @param compatibility The compatibility version of the parser that the\n    /// sub parser must support in order to parse the literal.\n    /// @param data The data that represents the literal. The structure of this\n    /// is defined by the conventions for the compatibility version.\n    /// @return success Whether the sub parser knows how to parse the literal.\n    /// If the sub parser does know how to handle the literal but cannot due to\n    /// malformed data, or some other reason, it MUST revert.\n    /// @return value The value of the literal.\n    function subParseLiteral(bytes32 compatibility, bytes calldata data)\n        external\n        pure\n        returns (bool success, uint256 value);\n\n    /// The sub parser is being asked to attempt to parse a word that the main\n    /// parser has failed to parse. The sub parser MUST ONLY attempt to parse a\n    /// word that matches both the compatibility version and that the data\n    /// represents a word that the sub parser is capable of parsing. It is\n    /// expected that the main parser will attempt multiple sub parsers in order\n    /// to parse a word, so the sub parser MUST NOT revert if it does not know\n    /// how to parse the word, as some other sub parser may be able to parse\n    /// it. The sub parser MUST return false if it does not know how to parse the\n    /// word, and MUST return true if it does know how to parse the word,\n    /// as well as the bytecode and constants of the word.\n    /// If the sub parser knows how to parse some word, but the data is\n    /// malformed, the sub parser MUST revert.\n    ///\n    /// Word parsing is the process of taking a sequence of bytes and\n    /// converting it into a sequence of bytecode and constants that is known at\n    /// compile time, and will be executed at runtime. As the bytecode executes\n    /// on the interpreter, not the (sub)parser, the sub parser relies on\n    /// convention to ensure that it is producing valid bytecode and constants.\n    /// These conventions are defined by the compatibility versions.\n    ///\n    /// @param compatibility The compatibility version of the parser that the\n    /// sub parser must support in order to parse the word.\n    /// @param data The data that represents the word.\n    /// @return success Whether the sub parser knows how to parse the word.\n    /// If the sub parser does know how to handle the word but cannot due to\n    /// malformed data, or some other reason, it MUST revert.\n    /// @return bytecode The bytecode of the word.\n    /// @return constants The constants of the word. This MAY be empty if the\n    /// bytecode does not require any new constants. These constants will be\n    /// merged into the constants of the main parser.\n    function subParseWord(bytes32 compatibility, bytes calldata data)\n        external\n        pure\n        returns (bool success, bytes memory bytecode, uint256[] memory constants);\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/error/ErrSubParse.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @dev When a subparser is not compatible with the main parser it MUST error\n/// on `subParse` calls rather than simply return false.\nerror IncompatibleSubParser();\n\n/// @dev Thrown when a subparser is asked to build an extern dispatch when the\n/// constants height is outside the range a single byte can represent.\nerror ExternDispatchConstantsHeightOverflow(uint256 constantsHeight);\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibSubParse.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibParseState, ParseState} from \"./LibParseState.sol\";\nimport {\n    OPCODE_UNKNOWN,\n    OPCODE_EXTERN,\n    OPCODE_CONSTANT,\n    OPCODE_CONTEXT,\n    Operand\n} from \"rain.interpreter.interface/interface/IInterpreterV2.sol\";\nimport {LibBytecode, Pointer} from \"rain.interpreter.interface/lib/bytecode/LibBytecode.sol\";\nimport {ISubParserV2, COMPATIBLITY_V3} from \"rain.interpreter.interface/interface/ISubParserV2.sol\";\nimport {BadSubParserResult, UnknownWord, UnsupportedLiteralType} from \"../../error/ErrParse.sol\";\nimport {LibExtern, EncodedExternDispatch} from \"../extern/LibExtern.sol\";\nimport {IInterpreterExternV3} from \"rain.interpreter.interface/interface/IInterpreterExternV3.sol\";\nimport {ExternDispatchConstantsHeightOverflow} from \"../../error/ErrSubParse.sol\";\nimport {LibMemCpy} from \"rain.solmem/lib/LibMemCpy.sol\";\nimport {LibParseError} from \"./LibParseError.sol\";\n\nlibrary LibSubParse {\n    using LibParseState for ParseState;\n    using LibParseError for ParseState;\n\n    /// Sub parse a word into a context grid position.\n    function subParserContext(uint256 column, uint256 row)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        bytes memory bytecode;\n        uint256 opIndex = OPCODE_CONTEXT;\n        assembly (\"memory-safe\") {\n            // Allocate the bytecode.\n            // This is an UNALIGNED allocation.\n            bytecode := mload(0x40)\n            mstore(0x40, add(bytecode, 0x24))\n\n            // The caller is responsible for ensuring the column and row are\n            // within `uint8`.\n            mstore8(add(bytecode, 0x23), column)\n            mstore8(add(bytecode, 0x22), row)\n\n            // 0 inputs 1 output.\n            mstore8(add(bytecode, 0x21), 0x10)\n\n            mstore8(add(bytecode, 0x20), opIndex)\n\n            // Write the length of the bytes.\n            mstore(bytecode, 4)\n        }\n\n        uint256[] memory constants;\n        assembly (\"memory-safe\") {\n            constants := mload(0x40)\n            mstore(0x40, add(constants, 0x20))\n            mstore(constants, 0)\n        }\n\n        return (true, bytecode, constants);\n    }\n\n    /// Sub parse a value into the bytecode that will run on the interpreter to\n    /// push the given value onto the stack, using the constant opcode at eval.\n    function subParserConstant(uint256 constantsHeight, uint256 value)\n        internal\n        pure\n        returns (bool, bytes memory, uint256[] memory)\n    {\n        // Build a constant opcode that the interpreter will run itself.\n        bytes memory bytecode;\n        uint256 opIndex = OPCODE_CONSTANT;\n        assembly (\"memory-safe\") {\n            // Allocate the bytecode.\n            // This is an UNALIGNED allocation.\n            bytecode := mload(0x40)\n            mstore(0x40, add(bytecode, 0x24))\n\n            // It's most efficient to store the constants height first, as it\n            // is in theory multibyte (although it's not expected to be).\n            // This also has the effect of zeroing out the inputs, which is what\n            // we want, as long as the main parser respects the constants height\n            // never being more than 2 bytes.\n            mstore(add(bytecode, 4), constantsHeight)\n\n            // 0 inputs 1 output.\n            mstore8(add(bytecode, 0x21), 0x10)\n\n            // Main opcode is constant.\n            mstore8(add(bytecode, 0x20), opIndex)\n\n            // Write the length of the bytes.\n            mstore(bytecode, 4)\n        }\n\n        uint256[] memory constants;\n        assembly (\"memory-safe\") {\n            constants := mload(0x40)\n            mstore(0x40, add(constants, 0x40))\n            mstore(constants, 1)\n            mstore(add(constants, 0x20), value)\n        }\n\n        return (true, bytecode, constants);\n    }\n\n    /// Sub parse a known extern opcode index into the bytecode that will run\n    /// on the interpreter to call the given extern contract. This requires the\n    /// parsing has already matched a word to the extern opcode index, so it\n    /// implies the parse meta has been traversed and the parse index has been\n    /// mapped to an extern opcode index somehow.\n    function subParserExtern(\n        IInterpreterExternV3 extern,\n        uint256 constantsHeight,\n        uint256 ioByte,\n        Operand operand,\n        uint256 opcodeIndex\n    ) internal pure returns (bool, bytes memory, uint256[] memory) {\n        // The constants height is an error check because the main parser can\n        // provide two bytes for it. Everything else is expected to be more\n        // directly controlled by the subparser itself.\n        if (constantsHeight > 0xFFFF) {\n            revert ExternDispatchConstantsHeightOverflow(constantsHeight);\n        }\n        // Build an extern call that dials back into the current contract at eval\n        // time with the current opcode index.\n        bytes memory bytecode;\n        uint256 opIndex = OPCODE_EXTERN;\n        assembly (\"memory-safe\") {\n            // Allocate the bytecode.\n            // This is an UNALIGNED allocation.\n            bytecode := mload(0x40)\n            mstore(0x40, add(bytecode, 0x24))\n            mstore(add(bytecode, 4), constantsHeight)\n            // The IO byte is inputs merged with outputs.\n            mstore8(add(bytecode, 0x21), ioByte)\n            // Main opcode is extern, to call back into current contract.\n            mstore8(add(bytecode, 0x20), opIndex)\n            // The bytes length is 4.\n            mstore(bytecode, 4)\n        }\n\n        uint256 externDispatch = EncodedExternDispatch.unwrap(\n            LibExtern.encodeExternCall(extern, LibExtern.encodeExternDispatch(opcodeIndex, operand))\n        );\n\n        uint256[] memory constants;\n        assembly (\"memory-safe\") {\n            constants := mload(0x40)\n            mstore(0x40, add(constants, 0x40))\n            mstore(constants, 1)\n            mstore(add(constants, 0x20), externDispatch)\n        }\n\n        return (true, bytecode, constants);\n    }\n\n    function subParseWordSlice(ParseState memory state, uint256 cursor, uint256 end) internal pure {\n        unchecked {\n            for (; cursor < end; cursor += 4) {\n                uint256 memoryAtCursor;\n                assembly (\"memory-safe\") {\n                    memoryAtCursor := mload(cursor)\n                }\n                if (memoryAtCursor >> 0xf8 == OPCODE_UNKNOWN) {\n                    uint256 deref = state.subParsers;\n                    while (deref != 0) {\n                        ISubParserV2 subParser = ISubParserV2(address(uint160(deref)));\n                        assembly (\"memory-safe\") {\n                            deref := mload(shr(0xf0, deref))\n                        }\n\n                        // Subparse data is a fixed length header that provides the\n                        // subparser some minimal additional contextual information\n                        // then the rest of the data is the original string that the\n                        // main parser could not understand.\n                        // The header is:\n                        // - 2 bytes: The current constant builder height. MAY be\n                        //   used by the subparser to calculate indexes for the\n                        //   constants it pushes.\n                        // - 1 byte: The IO byte from the unknown op. MAY be used\n                        //   by the subparser to calculate the IO byte for the op\n                        //   it builds.\n                        bytes memory data;\n                        // The operand of the unknown opcode directly points at the\n                        // data that we need to subparse.\n                        assembly (\"memory-safe\") {\n                            data := and(shr(0xe0, memoryAtCursor), 0xFFFF)\n                        }\n                        // We just need to fill in the header.\n                        {\n                            uint256 constantsBuilder = state.constantsBuilder;\n                            assembly (\"memory-safe\") {\n                                let header :=\n                                    shl(\n                                        0xe8,\n                                        or(\n                                            // IO byte is the second byte of the unknown op.\n                                            byte(1, memoryAtCursor),\n                                            // Constants builder height is the low 16 bits.\n                                            shl(8, and(constantsBuilder, 0xFFFF))\n                                        )\n                                    )\n\n                                let headerPtr := add(data, 0x20)\n                                mstore(headerPtr, or(header, and(mload(headerPtr), not(shl(0xe8, 0xFFFFFF)))))\n                            }\n                        }\n\n                        (bool success, bytes memory subBytecode, uint256[] memory subConstants) =\n                            subParser.subParseWord(COMPATIBLITY_V3, data);\n                        if (success) {\n                            // The sub bytecode must be exactly 4 bytes to\n                            // represent an op.\n                            if (subBytecode.length != 4) {\n                                revert BadSubParserResult(subBytecode);\n                            }\n\n                            {\n                                // Copy the sub bytecode over the unknown op.\n                                uint256 mask = 0xFFFFFFFF << 0xe0;\n                                assembly (\"memory-safe\") {\n                                    mstore(\n                                        cursor,\n                                        or(and(memoryAtCursor, not(mask)), and(mload(add(subBytecode, 0x20)), mask))\n                                    )\n                                }\n                            }\n\n                            for (uint256 i; i < subConstants.length; ++i) {\n                                state.pushConstantValue(subConstants[i]);\n                            }\n\n                            // Stop looping over sub parsers now.\n                            break;\n                        }\n                    }\n                }\n\n                // If the op was not replaced, then we need to error because we have\n                // no idea what it is.\n                assembly (\"memory-safe\") {\n                    memoryAtCursor := mload(cursor)\n                }\n                if (memoryAtCursor >> 0xf8 == OPCODE_UNKNOWN) {\n                    revert UnknownWord();\n                }\n            }\n        }\n    }\n\n    function subParseWords(ParseState memory state, bytes memory bytecode)\n        internal\n        pure\n        returns (bytes memory, uint256[] memory)\n    {\n        unchecked {\n            uint256 sourceCount = LibBytecode.sourceCount(bytecode);\n            for (uint256 sourceIndex; sourceIndex < sourceCount; ++sourceIndex) {\n                // Start cursor at the pointer to the source.\n                uint256 cursor = Pointer.unwrap(LibBytecode.sourcePointer(bytecode, sourceIndex)) + 4;\n                uint256 end = cursor + (LibBytecode.sourceOpsCount(bytecode, sourceIndex) * 4);\n                subParseWordSlice(state, cursor, end);\n            }\n            return (bytecode, state.buildConstants());\n        }\n    }\n\n    function subParseLiteral(\n        ParseState memory state,\n        uint256 dispatchStart,\n        uint256 dispatchEnd,\n        uint256 bodyStart,\n        uint256 bodyEnd\n    ) internal pure returns (uint256) {\n        unchecked {\n            // Build the data for the subparser.\n            bytes memory data;\n            {\n                uint256 copyPointer;\n                uint256 dispatchLength = dispatchEnd - dispatchStart;\n                uint256 bodyLength = bodyEnd - bodyStart;\n                {\n                    uint256 dataLength = 2 + dispatchLength + bodyLength;\n                    assembly (\"memory-safe\") {\n                        data := mload(0x40)\n                        mstore(0x40, add(data, add(dataLength, 0x20)))\n                        mstore(add(data, 2), dispatchLength)\n                        mstore(data, dataLength)\n                        copyPointer := add(data, 0x22)\n                    }\n                }\n                LibMemCpy.unsafeCopyBytesTo(Pointer.wrap(dispatchStart), Pointer.wrap(copyPointer), dispatchLength);\n                LibMemCpy.unsafeCopyBytesTo(\n                    Pointer.wrap(bodyStart), Pointer.wrap(copyPointer + dispatchLength), bodyLength\n                );\n            }\n\n            uint256 deref = state.subParsers;\n            while (deref != 0) {\n                ISubParserV2 subParser = ISubParserV2(address(uint160(deref)));\n                assembly (\"memory-safe\") {\n                    deref := mload(shr(0xf0, deref))\n                }\n\n                (bool success, uint256 value) = subParser.subParseLiteral(COMPATIBLITY_V3, data);\n                if (success) {\n                    return value;\n                }\n            }\n\n            revert UnsupportedLiteralType(state.parseErrorOffset(dispatchStart));\n        }\n    }\n\n    function consumeSubParseWordInputData(bytes memory data, bytes memory meta, bytes memory operandHandlers)\n        internal\n        pure\n        returns (uint256 constantsHeight, uint256 ioByte, ParseState memory state)\n    {\n        uint256[] memory operandValues;\n        assembly (\"memory-safe\") {\n            // Pull the header out into EVM stack items.\n            constantsHeight := and(mload(add(data, 2)), 0xFFFF)\n            ioByte := and(mload(add(data, 3)), 0xFF)\n\n            // Mutate the data to no longer have a header.\n            let newLength := and(mload(add(data, 5)), 0xFFFF)\n            data := add(data, 5)\n            mstore(data, newLength)\n            operandValues := add(data, add(newLength, 0x20))\n        }\n        // Literal parsers are empty for the sub parser as the main parser should\n        // be handling all literals in operands. The sub parser handles literal\n        // parsing as a dedicated interface seperately.\n        state = LibParseState.newState(data, meta, operandHandlers, \"\");\n        state.operandValues = operandValues;\n    }\n\n    function consumeSubParseLiteralInputData(bytes memory data)\n        internal\n        pure\n        returns (uint256 dispatchStart, uint256 bodyStart, uint256 bodyEnd)\n    {\n        assembly (\"memory-safe\") {\n            let dispatchLength := and(mload(add(data, 2)), 0xFFFF)\n            dispatchStart := add(data, 0x22)\n            bodyStart := add(dispatchStart, dispatchLength)\n            bodyEnd := add(data, add(0x20, mload(data)))\n        }\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParseCMask.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @dev Workaround for https://github.com/foundry-rs/foundry/issues/6572\ncontract LibParseCMask {}\n\n/// @dev ASCII null\nuint128 constant CMASK_NULL = uint128(1) << uint128(uint8(bytes1(\"\\x00\")));\n\n/// @dev ASCII start of heading\nuint128 constant CMASK_START_OF_HEADING = uint128(1) << uint128(uint8(bytes1(\"\\x01\")));\n\n/// @dev ASCII start of text\nuint128 constant CMASK_START_OF_TEXT = uint128(1) << uint128(uint8(bytes1(\"\\x02\")));\n\n/// @dev ASCII end of text\nuint128 constant CMASK_END_OF_TEXT = uint128(1) << uint128(uint8(bytes1(\"\\x03\")));\n\n/// @dev ASCII end of transmission\nuint128 constant CMASK_END_OF_TRANSMISSION = uint128(1) << uint128(uint8(bytes1(\"\\x04\")));\n\n/// @dev ASCII enquiry\nuint128 constant CMASK_ENQUIRY = uint128(1) << uint128(uint8(bytes1(\"\\x05\")));\n\n/// @dev ASCII acknowledge\nuint128 constant CMASK_ACKNOWLEDGE = uint128(1) << uint128(uint8(bytes1(\"\\x06\")));\n\n/// @dev ASCII bell\nuint128 constant CMASK_BELL = uint128(1) << uint128(uint8(bytes1(\"\\x07\")));\n\n/// @dev ASCII backspace\nuint128 constant CMASK_BACKSPACE = uint128(1) << uint128(uint8(bytes1(\"\\x08\")));\n\n/// @dev ASCII horizontal tab\nuint128 constant CMASK_HORIZONTAL_TAB = uint128(1) << uint128(uint8(bytes1(\"\\t\")));\n\n/// @dev ASCII line feed\nuint128 constant CMASK_LINE_FEED = uint128(1) << uint128(uint8(bytes1(\"\\n\")));\n\n/// @dev ASCII vertical tab\nuint128 constant CMASK_VERTICAL_TAB = uint128(1) << uint128(uint8(bytes1(\"\\x0B\")));\n\n/// @dev ASCII form feed\nuint128 constant CMASK_FORM_FEED = uint128(1) << uint128(uint8(bytes1(\"\\x0C\")));\n\n/// @dev ASCII carriage return\nuint128 constant CMASK_CARRIAGE_RETURN = uint128(1) << uint128(uint8(bytes1(\"\\r\")));\n\n/// @dev ASCII shift out\nuint128 constant CMASK_SHIFT_OUT = uint128(1) << uint128(uint8(bytes1(\"\\x0E\")));\n\n/// @dev ASCII shift in\nuint128 constant CMASK_SHIFT_IN = uint128(1) << uint128(uint8(bytes1(\"\\x0F\")));\n\n/// @dev ASCII data link escape\nuint128 constant CMASK_DATA_LINK_ESCAPE = uint128(1) << uint128(uint8(bytes1(\"\\x10\")));\n\n/// @dev ASCII device control 1\nuint128 constant CMASK_DEVICE_CONTROL_1 = uint128(1) << uint128(uint8(bytes1(\"\\x11\")));\n\n/// @dev ASCII device control 2\nuint128 constant CMASK_DEVICE_CONTROL_2 = uint128(1) << uint128(uint8(bytes1(\"\\x12\")));\n\n/// @dev ASCII device control 3\nuint128 constant CMASK_DEVICE_CONTROL_3 = uint128(1) << uint128(uint8(bytes1(\"\\x13\")));\n\n/// @dev ASCII device control 4\nuint128 constant CMASK_DEVICE_CONTROL_4 = uint128(1) << uint128(uint8(bytes1(\"\\x14\")));\n\n/// @dev ASCII negative acknowledge\nuint128 constant CMASK_NEGATIVE_ACKNOWLEDGE = uint128(1) << uint128(uint8(bytes1(\"\\x15\")));\n\n/// @dev ASCII synchronous idle\nuint128 constant CMASK_SYNCHRONOUS_IDLE = uint128(1) << uint128(uint8(bytes1(\"\\x16\")));\n\n/// @dev ASCII end of transmission block\nuint128 constant CMASK_END_OF_TRANSMISSION_BLOCK = uint128(1) << uint128(uint8(bytes1(\"\\x17\")));\n\n/// @dev ASCII cancel\nuint128 constant CMASK_CANCEL = uint128(1) << uint128(uint8(bytes1(\"\\x18\")));\n\n/// @dev ASCII end of medium\nuint128 constant CMASK_END_OF_MEDIUM = uint128(1) << uint128(uint8(bytes1(\"\\x19\")));\n\n/// @dev ASCII substitute\nuint128 constant CMASK_SUBSTITUTE = uint128(1) << uint128(uint8(bytes1(\"\\x1A\")));\n\n/// @dev ASCII escape\nuint128 constant CMASK_ESCAPE = uint128(1) << uint128(uint8(bytes1(\"\\x1B\")));\n\n/// @dev ASCII file separator\nuint128 constant CMASK_FILE_SEPARATOR = uint128(1) << uint128(uint8(bytes1(\"\\x1C\")));\n\n/// @dev ASCII group separator\nuint128 constant CMASK_GROUP_SEPARATOR = uint128(1) << uint128(uint8(bytes1(\"\\x1D\")));\n\n/// @dev ASCII record separator\nuint128 constant CMASK_RECORD_SEPARATOR = uint128(1) << uint128(uint8(bytes1(\"\\x1E\")));\n\n/// @dev ASCII unit separator\nuint128 constant CMASK_UNIT_SEPARATOR = uint128(1) << uint128(uint8(bytes1(\"\\x1F\")));\n\n/// @dev ASCII space\nuint128 constant CMASK_SPACE = uint128(1) << uint128(uint8(bytes1(\" \")));\n\n/// @dev ASCII !\nuint128 constant CMASK_EXCLAMATION_MARK = uint128(1) << uint128(uint8(bytes1(\"!\")));\n\n/// @dev ASCII \"\nuint128 constant CMASK_QUOTATION_MARK = uint128(1) << uint128(uint8(bytes1(\"\\\"\")));\n\n/// @dev ASCII #\nuint128 constant CMASK_NUMBER_SIGN = uint128(1) << uint128(uint8(bytes1(\"#\")));\n\n/// @dev ASCII $\nuint128 constant CMASK_DOLLAR_SIGN = uint128(1) << uint128(uint8(bytes1(\"$\")));\n\n/// @dev ASCII %\nuint128 constant CMASK_PERCENT_SIGN = uint128(1) << uint128(uint8(bytes1(\"%\")));\n\n/// @dev ASCII &\nuint128 constant CMASK_AMPERSAND = uint128(1) << uint128(uint8(bytes1(\"&\")));\n\n/// @dev ASCII '\nuint128 constant CMASK_APOSTROPHE = uint128(1) << uint128(uint8(bytes1(\"'\")));\n\n/// @dev ASCII (\nuint128 constant CMASK_LEFT_PAREN = uint128(1) << uint128(uint8(bytes1(\"(\")));\n\n/// @dev ASCII )\nuint128 constant CMASK_RIGHT_PAREN = uint128(1) << uint128(uint8(bytes1(\")\")));\n\n/// @dev ASCII *\nuint128 constant CMASK_ASTERISK = uint128(1) << uint128(uint8(bytes1(\"*\")));\n\n/// @dev ASCII +\nuint128 constant CMASK_PLUS_SIGN = uint128(1) << uint128(uint8(bytes1(\"+\")));\n\n/// @dev ASCII ,\nuint128 constant CMASK_COMMA = uint128(1) << uint128(uint8(bytes1(\",\")));\n\n/// @dev ASCII -\nuint128 constant CMASK_DASH = uint128(1) << uint128(uint8(bytes1(\"-\")));\n\n/// @dev ASCII .\nuint128 constant CMASK_FULL_STOP = uint128(1) << uint128(uint8(bytes1(\".\")));\n\n/// @dev ASCII /\nuint128 constant CMASK_SLASH = uint128(1) << uint128(uint8(bytes1(\"/\")));\n\n/// @dev ASCII 0\nuint128 constant CMASK_ZERO = uint128(1) << uint128(uint8(bytes1(\"0\")));\n\n/// @dev ASCII 1\nuint128 constant CMASK_ONE = uint128(1) << uint128(uint8(bytes1(\"1\")));\n\n/// @dev ASCII 2\nuint128 constant CMASK_TWO = uint128(1) << uint128(uint8(bytes1(\"2\")));\n\n/// @dev ASCII 3\nuint128 constant CMASK_THREE = uint128(1) << uint128(uint8(bytes1(\"3\")));\n\n/// @dev ASCII 4\nuint128 constant CMASK_FOUR = uint128(1) << uint128(uint8(bytes1(\"4\")));\n\n/// @dev ASCII 5\nuint128 constant CMASK_FIVE = uint128(1) << uint128(uint8(bytes1(\"5\")));\n\n/// @dev ASCII 6\nuint128 constant CMASK_SIX = uint128(1) << uint128(uint8(bytes1(\"6\")));\n\n/// @dev ASCII 7\nuint128 constant CMASK_SEVEN = uint128(1) << uint128(uint8(bytes1(\"7\")));\n\n/// @dev ASCII 8\nuint128 constant CMASK_EIGHT = uint128(1) << uint128(uint8(bytes1(\"8\")));\n\n/// @dev ASCII 9\nuint128 constant CMASK_NINE = uint128(1) << uint128(uint8(bytes1(\"9\")));\n\n/// @dev ASCII :\nuint128 constant CMASK_COLON = uint128(1) << uint128(uint8(bytes1(\":\")));\n\n/// @dev ASCII ;\nuint128 constant CMASK_SEMICOLON = uint128(1) << uint128(uint8(bytes1(\";\")));\n\n/// @dev ASCII <\nuint128 constant CMASK_LESS_THAN_SIGN = uint128(1) << uint128(uint8(bytes1(\"<\")));\n\n/// @dev ASCII =\nuint128 constant CMASK_EQUALS_SIGN = uint128(1) << uint128(uint8(bytes1(\"=\")));\n\n/// @dev ASCII >\nuint128 constant CMASK_GREATER_THAN_SIGN = uint128(1) << uint128(uint8(bytes1(\">\")));\n\n/// @dev ASCII ?\nuint128 constant CMASK_QUESTION_MARK = uint128(1) << uint128(uint8(bytes1(\"?\")));\n\n/// @dev ASCII @\nuint128 constant CMASK_AT_SIGN = uint128(1) << uint128(uint8(bytes1(\"@\")));\n\n/// @dev ASCII A\nuint128 constant CMASK_UPPER_A = uint128(1) << uint128(uint8(bytes1(\"A\")));\n\n/// @dev ASCII B\nuint128 constant CMASK_UPPER_B = uint128(1) << uint128(uint8(bytes1(\"B\")));\n\n/// @dev ASCII C\nuint128 constant CMASK_UPPER_C = uint128(1) << uint128(uint8(bytes1(\"C\")));\n\n/// @dev ASCII D\nuint128 constant CMASK_UPPER_D = uint128(1) << uint128(uint8(bytes1(\"D\")));\n\n/// @dev ASCII E\nuint128 constant CMASK_UPPER_E = uint128(1) << uint128(uint8(bytes1(\"E\")));\n\n/// @dev ASCII F\nuint128 constant CMASK_UPPER_F = uint128(1) << uint128(uint8(bytes1(\"F\")));\n\n/// @dev ASCII G\nuint128 constant CMASK_UPPER_G = uint128(1) << uint128(uint8(bytes1(\"G\")));\n\n/// @dev ASCII H\nuint128 constant CMASK_UPPER_H = uint128(1) << uint128(uint8(bytes1(\"H\")));\n\n/// @dev ASCII I\nuint128 constant CMASK_UPPER_I = uint128(1) << uint128(uint8(bytes1(\"I\")));\n\n/// @dev ASCII J\nuint128 constant CMASK_UPPER_J = uint128(1) << uint128(uint8(bytes1(\"J\")));\n\n/// @dev ASCII K\nuint128 constant CMASK_UPPER_K = uint128(1) << uint128(uint8(bytes1(\"K\")));\n\n/// @dev ASCII L\nuint128 constant CMASK_UPPER_L = uint128(1) << uint128(uint8(bytes1(\"L\")));\n\n/// @dev ASCII M\nuint128 constant CMASK_UPPER_M = uint128(1) << uint128(uint8(bytes1(\"M\")));\n\n/// @dev ASCII N\nuint128 constant CMASK_UPPER_N = uint128(1) << uint128(uint8(bytes1(\"N\")));\n\n/// @dev ASCII O\nuint128 constant CMASK_UPPER_O = uint128(1) << uint128(uint8(bytes1(\"O\")));\n\n/// @dev ASCII P\nuint128 constant CMASK_UPPER_P = uint128(1) << uint128(uint8(bytes1(\"P\")));\n\n/// @dev ASCII Q\nuint128 constant CMASK_UPPER_Q = uint128(1) << uint128(uint8(bytes1(\"Q\")));\n\n/// @dev ASCII R\nuint128 constant CMASK_UPPER_R = uint128(1) << uint128(uint8(bytes1(\"R\")));\n\n/// @dev ASCII S\nuint128 constant CMASK_UPPER_S = uint128(1) << uint128(uint8(bytes1(\"S\")));\n\n/// @dev ASCII T\nuint128 constant CMASK_UPPER_T = uint128(1) << uint128(uint8(bytes1(\"T\")));\n\n/// @dev ASCII U\nuint128 constant CMASK_UPPER_U = uint128(1) << uint128(uint8(bytes1(\"U\")));\n\n/// @dev ASCII V\nuint128 constant CMASK_UPPER_V = uint128(1) << uint128(uint8(bytes1(\"V\")));\n\n/// @dev ASCII W\nuint128 constant CMASK_UPPER_W = uint128(1) << uint128(uint8(bytes1(\"W\")));\n\n/// @dev ASCII X\nuint128 constant CMASK_UPPER_X = uint128(1) << uint128(uint8(bytes1(\"X\")));\n\n/// @dev ASCII Y\nuint128 constant CMASK_UPPER_Y = uint128(1) << uint128(uint8(bytes1(\"Y\")));\n\n/// @dev ASCII Z\nuint128 constant CMASK_UPPER_Z = uint128(1) << uint128(uint8(bytes1(\"Z\")));\n\n/// @dev ASCII [\nuint128 constant CMASK_LEFT_SQUARE_BRACKET = uint128(1) << uint128(uint8(bytes1(\"[\")));\n\n/// @dev ASCII \\\nuint128 constant CMASK_BACKSLASH = uint128(1) << uint128(uint8(bytes1(\"\\\\\")));\n\n/// @dev ASCII ]\nuint128 constant CMASK_RIGHT_SQUARE_BRACKET = uint128(1) << uint128(uint8(bytes1(\"]\")));\n\n/// @dev ASCII ^\nuint128 constant CMASK_CIRCUMFLEX_ACCENT = uint128(1) << uint128(uint8(bytes1(\"^\")));\n\n/// @dev ASCII _\nuint128 constant CMASK_UNDERSCORE = uint128(1) << uint128(uint8(bytes1(\"_\")));\n\n/// @dev ASCII `\nuint128 constant CMASK_GRAVE_ACCENT = uint128(1) << uint128(uint8(bytes1(\"`\")));\n\n/// @dev ASCII a\nuint128 constant CMASK_LOWER_A = uint128(1) << uint128(uint8(bytes1(\"a\")));\n\n/// @dev ASCII b\nuint128 constant CMASK_LOWER_B = uint128(1) << uint128(uint8(bytes1(\"b\")));\n\n/// @dev ASCII c\nuint128 constant CMASK_LOWER_C = uint128(1) << uint128(uint8(bytes1(\"c\")));\n\n/// @dev ASCII d\nuint128 constant CMASK_LOWER_D = uint128(1) << uint128(uint8(bytes1(\"d\")));\n\n/// @dev ASCII e\nuint128 constant CMASK_LOWER_E = uint128(1) << uint128(uint8(bytes1(\"e\")));\n\n/// @dev ASCII f\nuint128 constant CMASK_LOWER_F = uint128(1) << uint128(uint8(bytes1(\"f\")));\n\n/// @dev ASCII g\nuint128 constant CMASK_LOWER_G = uint128(1) << uint128(uint8(bytes1(\"g\")));\n\n/// @dev ASCII h\nuint128 constant CMASK_LOWER_H = uint128(1) << uint128(uint8(bytes1(\"h\")));\n\n/// @dev ASCII i\nuint128 constant CMASK_LOWER_I = uint128(1) << uint128(uint8(bytes1(\"i\")));\n\n/// @dev ASCII j\nuint128 constant CMASK_LOWER_J = uint128(1) << uint128(uint8(bytes1(\"j\")));\n\n/// @dev ASCII k\nuint128 constant CMASK_LOWER_K = uint128(1) << uint128(uint8(bytes1(\"k\")));\n\n/// @dev ASCII l\nuint128 constant CMASK_LOWER_L = uint128(1) << uint128(uint8(bytes1(\"l\")));\n\n/// @dev ASCII m\nuint128 constant CMASK_LOWER_M = uint128(1) << uint128(uint8(bytes1(\"m\")));\n\n/// @dev ASCII n\nuint128 constant CMASK_LOWER_N = uint128(1) << uint128(uint8(bytes1(\"n\")));\n\n/// @dev ASCII o\nuint128 constant CMASK_LOWER_O = uint128(1) << uint128(uint8(bytes1(\"o\")));\n\n/// @dev ASCII p\nuint128 constant CMASK_LOWER_P = uint128(1) << uint128(uint8(bytes1(\"p\")));\n\n/// @dev ASCII q\nuint128 constant CMASK_LOWER_Q = uint128(1) << uint128(uint8(bytes1(\"q\")));\n\n/// @dev ASCII r\nuint128 constant CMASK_LOWER_R = uint128(1) << uint128(uint8(bytes1(\"r\")));\n\n/// @dev ASCII s\nuint128 constant CMASK_LOWER_S = uint128(1) << uint128(uint8(bytes1(\"s\")));\n\n/// @dev ASCII t\nuint128 constant CMASK_LOWER_T = uint128(1) << uint128(uint8(bytes1(\"t\")));\n\n/// @dev ASCII u\nuint128 constant CMASK_LOWER_U = uint128(1) << uint128(uint8(bytes1(\"u\")));\n\n/// @dev ASCII v\nuint128 constant CMASK_LOWER_V = uint128(1) << uint128(uint8(bytes1(\"v\")));\n\n/// @dev ASCII w\nuint128 constant CMASK_LOWER_W = uint128(1) << uint128(uint8(bytes1(\"w\")));\n\n/// @dev ASCII x\nuint128 constant CMASK_LOWER_X = uint128(1) << uint128(uint8(bytes1(\"x\")));\n\n/// @dev ASCII y\nuint128 constant CMASK_LOWER_Y = uint128(1) << uint128(uint8(bytes1(\"y\")));\n\n/// @dev ASCII z\nuint128 constant CMASK_LOWER_Z = uint128(1) << uint128(uint8(bytes1(\"z\")));\n\n/// @dev ASCII {\nuint128 constant CMASK_LEFT_CURLY_BRACKET = uint128(1) << uint128(uint8(bytes1(\"{\")));\n\n/// @dev ASCII |\nuint128 constant CMASK_VERTICAL_BAR = uint128(1) << uint128(uint8(bytes1(\"|\")));\n\n/// @dev ASCII }\nuint128 constant CMASK_RIGHT_CURLY_BRACKET = uint128(1) << uint128(uint8(bytes1(\"}\")));\n\n/// @dev ASCII ~\nuint128 constant CMASK_TILDE = uint128(1) << uint128(uint8(bytes1(\"~\")));\n\n/// @dev ASCII delete\nuint128 constant CMASK_DELETE = uint128(1) << uint128(uint8(bytes1(\"\\x7F\")));\n\n/// @dev ASCII printable characters is everything 0x20 and above, except 0x7F\nuint128 constant CMASK_PRINTABLE = ~(\n    CMASK_NULL | CMASK_START_OF_HEADING | CMASK_START_OF_TEXT | CMASK_END_OF_TEXT | CMASK_END_OF_TRANSMISSION\n        | CMASK_ENQUIRY | CMASK_ACKNOWLEDGE | CMASK_BELL | CMASK_BACKSPACE | CMASK_HORIZONTAL_TAB | CMASK_LINE_FEED\n        | CMASK_VERTICAL_TAB | CMASK_FORM_FEED | CMASK_CARRIAGE_RETURN | CMASK_SHIFT_OUT | CMASK_SHIFT_IN\n        | CMASK_DATA_LINK_ESCAPE | CMASK_DEVICE_CONTROL_1 | CMASK_DEVICE_CONTROL_2 | CMASK_DEVICE_CONTROL_3\n        | CMASK_DEVICE_CONTROL_4 | CMASK_NEGATIVE_ACKNOWLEDGE | CMASK_SYNCHRONOUS_IDLE | CMASK_END_OF_TRANSMISSION_BLOCK\n        | CMASK_CANCEL | CMASK_END_OF_MEDIUM | CMASK_SUBSTITUTE | CMASK_ESCAPE | CMASK_FILE_SEPARATOR\n        | CMASK_GROUP_SEPARATOR | CMASK_RECORD_SEPARATOR | CMASK_UNIT_SEPARATOR | CMASK_DELETE\n);\n\n/// @dev numeric 0-9\nuint128 constant CMASK_NUMERIC_0_9 = CMASK_ZERO | CMASK_ONE | CMASK_TWO | CMASK_THREE | CMASK_FOUR | CMASK_FIVE\n    | CMASK_SIX | CMASK_SEVEN | CMASK_EIGHT | CMASK_NINE;\n\n/// @dev e notation eE\nuint128 constant CMASK_E_NOTATION = CMASK_LOWER_E | CMASK_UPPER_E;\n\n/// @dev lower alpha a-z\nuint128 constant CMASK_LOWER_ALPHA_A_Z = CMASK_LOWER_A | CMASK_LOWER_B | CMASK_LOWER_C | CMASK_LOWER_D | CMASK_LOWER_E\n    | CMASK_LOWER_F | CMASK_LOWER_G | CMASK_LOWER_H | CMASK_LOWER_I | CMASK_LOWER_J | CMASK_LOWER_K | CMASK_LOWER_L\n    | CMASK_LOWER_M | CMASK_LOWER_N | CMASK_LOWER_O | CMASK_LOWER_P | CMASK_LOWER_Q | CMASK_LOWER_R | CMASK_LOWER_S\n    | CMASK_LOWER_T | CMASK_LOWER_U | CMASK_LOWER_V | CMASK_LOWER_W | CMASK_LOWER_X | CMASK_LOWER_Y | CMASK_LOWER_Z;\n\n/// @dev upper alpha A-Z\nuint128 constant CMASK_UPPER_ALPHA_A_Z = CMASK_UPPER_A | CMASK_UPPER_B | CMASK_UPPER_C | CMASK_UPPER_D | CMASK_UPPER_E\n    | CMASK_UPPER_F | CMASK_UPPER_G | CMASK_UPPER_H | CMASK_UPPER_I | CMASK_UPPER_J | CMASK_UPPER_K | CMASK_UPPER_L\n    | CMASK_UPPER_M | CMASK_UPPER_N | CMASK_UPPER_O | CMASK_UPPER_P | CMASK_UPPER_Q | CMASK_UPPER_R | CMASK_UPPER_S\n    | CMASK_UPPER_T | CMASK_UPPER_U | CMASK_UPPER_V | CMASK_UPPER_W | CMASK_UPPER_X | CMASK_UPPER_Y | CMASK_UPPER_Z;\n\n/// @dev lower alpha a-f (hex)\nuint128 constant CMASK_LOWER_ALPHA_A_F =\n    CMASK_LOWER_A | CMASK_LOWER_B | CMASK_LOWER_C | CMASK_LOWER_D | CMASK_LOWER_E | CMASK_LOWER_F;\n\n/// @dev upper alpha A-F (hex)\nuint128 constant CMASK_UPPER_ALPHA_A_F =\n    CMASK_UPPER_A | CMASK_UPPER_B | CMASK_UPPER_C | CMASK_UPPER_D | CMASK_UPPER_E | CMASK_UPPER_F;\n\n/// @dev hex 0-9 a-f A-F\nuint128 constant CMASK_HEX = CMASK_NUMERIC_0_9 | CMASK_LOWER_ALPHA_A_F | CMASK_UPPER_ALPHA_A_F;\n\n/// @dev Rainlang end of line is ,\nuint128 constant CMASK_EOL = CMASK_COMMA;\n\n/// @dev Rainlang LHS/RHS delimiter is :\nuint128 constant CMASK_LHS_RHS_DELIMITER = CMASK_COLON;\n\n/// @dev Rainlang end of source is ;\nuint128 constant CMASK_EOS = CMASK_SEMICOLON;\n\n/// @dev Rainlang stack head is lower alpha and underscore a-z _\nuint128 constant CMASK_LHS_STACK_HEAD = CMASK_LOWER_ALPHA_A_Z | CMASK_UNDERSCORE;\n\n/// @dev Rainlang identifier head is lower alpha a-z\nuint128 constant CMASK_IDENTIFIER_HEAD = CMASK_LOWER_ALPHA_A_Z;\nuint128 constant CMASK_RHS_WORD_HEAD = CMASK_IDENTIFIER_HEAD;\n\n/// @dev Rainlang stack/identifier tail is lower alphanumeric kebab a-z 0-9 -\nuint128 constant CMASK_IDENTIFIER_TAIL = CMASK_IDENTIFIER_HEAD | CMASK_NUMERIC_0_9 | CMASK_DASH;\nuint128 constant CMASK_LHS_STACK_TAIL = CMASK_IDENTIFIER_TAIL;\nuint128 constant CMASK_RHS_WORD_TAIL = CMASK_IDENTIFIER_TAIL;\n\n/// @dev Rainlang operand start is <\nuint128 constant CMASK_OPERAND_START = CMASK_LESS_THAN_SIGN;\n\n/// @dev Rainlang operand end is >\nuint128 constant CMASK_OPERAND_END = CMASK_GREATER_THAN_SIGN;\n\n/// @dev NOT lower alphanumeric kebab\nuint128 constant CMASK_NOT_IDENTIFIER_TAIL = ~CMASK_IDENTIFIER_TAIL;\n\n/// @dev Rainlang whitespace is \\n \\r \\t space\nuint128 constant CMASK_WHITESPACE = CMASK_LINE_FEED | CMASK_CARRIAGE_RETURN | CMASK_HORIZONTAL_TAB | CMASK_SPACE;\n\n/// @dev Rainlang stack item delimiter is whitespace\nuint128 constant CMASK_LHS_STACK_DELIMITER = CMASK_WHITESPACE;\n\n/// @dev Rainlang supports numeric literals as anything starting with 0-9\nuint128 constant CMASK_NUMERIC_LITERAL_HEAD = CMASK_NUMERIC_0_9;\n\n/// @dev Rainlang supports string literals as anything starting with \"\nuint128 constant CMASK_STRING_LITERAL_HEAD = CMASK_QUOTATION_MARK;\n\n/// @dev Rainlang supports sub parseable literals as anything starting with [\nuint128 constant CMASK_SUB_PARSEABLE_LITERAL_HEAD = CMASK_LEFT_SQUARE_BRACKET;\n\n/// @dev Rainlang ends a sub parseable literal with ]\nuint128 constant CMASK_SUB_PARSEABLE_LITERAL_END = CMASK_RIGHT_SQUARE_BRACKET;\n\n/// @dev Rainlang string end is \"\nuint128 constant CMASK_STRING_LITERAL_END = CMASK_QUOTATION_MARK;\n\n/// @dev Rainlang string tail is any printable ASCII except \" which ends it.\nuint128 constant CMASK_STRING_LITERAL_TAIL = ~CMASK_STRING_LITERAL_END & CMASK_PRINTABLE;\n\n/// @dev Rainlang literal head\nuint128 constant CMASK_LITERAL_HEAD =\n    CMASK_NUMERIC_LITERAL_HEAD | CMASK_STRING_LITERAL_HEAD | CMASK_SUB_PARSEABLE_LITERAL_HEAD;\n\n/// @dev Rainlang comment head is /\nuint128 constant CMASK_COMMENT_HEAD = CMASK_SLASH;\n\n/// @dev Rainlang interstitial head could be some whitespace or a comment head.\nuint128 constant CMASK_INTERSTITIAL_HEAD = CMASK_WHITESPACE | CMASK_COMMENT_HEAD;\n\n/// @dev Rainlang comment starting sequence is /*\nuint256 constant COMMENT_START_SEQUENCE = uint256(uint16(bytes2(\"/*\")));\n\n/// @dev Rainlang comment ending sequence is */\nuint256 constant COMMENT_END_SEQUENCE = uint256(uint16(bytes2(\"*/\")));\n\n/// @dev Rainlang comment end sequence end byte is / */\nuint256 constant CMASK_COMMENT_END_SEQUENCE_END = COMMENT_END_SEQUENCE & 0xFF;\n\n/// @dev Rainlang literal hexadecimal dispatch is 0x\n/// We compare the head and dispatch together to avoid a second comparison.\n/// This is safe because the head is prefiltered to be 0-9 due to the numeric\n/// literal head, therefore the only possible match is 0x (not x0).\nuint128 constant CMASK_LITERAL_HEX_DISPATCH = CMASK_ZERO | CMASK_LOWER_X;\n\n/// @dev We may want to match the exact start of a hex literal.\nuint256 constant CMASK_LITERAL_HEX_DISPATCH_START = uint256(uint16(bytes2(\"0x\")));\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParse.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibPointer, Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {LibMemCpy} from \"rain.solmem/lib/LibMemCpy.sol\";\nimport {\n    CMASK_COMMENT_HEAD,\n    CMASK_EOS,\n    CMASK_EOL,\n    CMASK_LITERAL_HEAD,\n    CMASK_WHITESPACE,\n    CMASK_RIGHT_PAREN,\n    CMASK_LEFT_PAREN,\n    CMASK_RHS_WORD_TAIL,\n    CMASK_RHS_WORD_HEAD,\n    CMASK_LHS_RHS_DELIMITER,\n    CMASK_LHS_STACK_TAIL,\n    CMASK_LHS_STACK_HEAD,\n    COMMENT_START_SEQUENCE,\n    COMMENT_END_SEQUENCE,\n    CMASK_IDENTIFIER_HEAD\n} from \"./LibParseCMask.sol\";\nimport {LibCtPop} from \"../bitwise/LibCtPop.sol\";\nimport {LibParseMeta} from \"./LibParseMeta.sol\";\nimport {LibParseLiteral} from \"./literal/LibParseLiteral.sol\";\nimport {LibParseOperand} from \"./LibParseOperand.sol\";\nimport {Operand, OPCODE_STACK, OPCODE_UNKNOWN} from \"rain.interpreter.interface/interface/IInterpreterV2.sol\";\nimport {LibParseStackName} from \"./LibParseStackName.sol\";\nimport {\n    ExcessLHSItems,\n    ExcessRHSItems,\n    NotAcceptingInputs,\n    ParseStackUnderflow,\n    ParseStackOverflow,\n    UnexpectedRHSChar,\n    UnexpectedRightParen,\n    WordSize,\n    DuplicateLHSItem,\n    ParserOutOfBounds,\n    ExpectedLeftParen,\n    UnexpectedLHSChar,\n    DanglingSource,\n    MaxSources,\n    UnclosedLeftParen,\n    MissingFinalSemi,\n    UnexpectedComment,\n    ParenOverflow,\n    UnknownWord,\n    MalformedCommentStart\n} from \"../../error/ErrParse.sol\";\nimport {\n    LibParseState,\n    ParseState,\n    FSM_YANG_MASK,\n    FSM_DEFAULT,\n    FSM_ACTIVE_SOURCE_MASK,\n    FSM_WORD_END_MASK\n} from \"./LibParseState.sol\";\nimport {LibParsePragma} from \"./LibParsePragma.sol\";\nimport {LibParseInterstitial} from \"./LibParseInterstitial.sol\";\nimport {LibParseError} from \"./LibParseError.sol\";\nimport {LibSubParse} from \"./LibSubParse.sol\";\nimport {LibBytes} from \"rain.solmem/lib/LibBytes.sol\";\nimport {LibUint256Array} from \"rain.solmem/lib/LibUint256Array.sol\";\n\nuint256 constant NOT_LOW_16_BIT_MASK = ~uint256(0xFFFF);\nuint256 constant ACTIVE_SOURCE_MASK = NOT_LOW_16_BIT_MASK;\nuint256 constant SUB_PARSER_BYTECODE_HEADER_SIZE = 5;\n\nlibrary LibParse {\n    using LibPointer for Pointer;\n    using LibParseStackName for ParseState;\n    using LibParseState for ParseState;\n    using LibParseInterstitial for ParseState;\n    using LibParseError for ParseState;\n    using LibParseMeta for ParseState;\n    using LibParsePragma for ParseState;\n    using LibParse for ParseState;\n    using LibParseOperand for ParseState;\n    using LibSubParse for ParseState;\n    using LibBytes for bytes;\n    using LibUint256Array for uint256[];\n\n    /// Parses a word that matches a tail mask between cursor and end. The caller\n    /// has several responsibilities while safely using this word.\n    /// - The caller MUST ensure that the word is not zero length.\n    ///   I.e. `end - cursor > 0`.\n    /// - The caller MUST ensure the head of the word (the first character) is\n    ///   valid according to some head mask. Generally it is expected that the\n    ///   valid chars for a head and tail may be different.\n    /// This function will extract every other character from the word, starting\n    /// with the second character, and check that it is valid according to the\n    /// tail mask. If any invalid characters are found, the parsing will stop\n    /// looping as it is assumed the remaining data is valid as something else,\n    /// just not a word.\n    function parseWord(uint256 cursor, uint256 end, uint256 mask) internal pure returns (uint256, bytes32) {\n        unchecked {\n            bytes32 word;\n            uint256 i = 1;\n            uint256 iEnd;\n            {\n                uint256 remaining = end - cursor;\n                iEnd = remaining > 0x20 ? 0x20 : remaining;\n            }\n            assembly (\"memory-safe\") {\n                // word is head + tail\n                word := mload(cursor)\n                // loop over the tail\n                //slither-disable-next-line incorrect-shift\n                for {} and(lt(i, iEnd), iszero(and(shl(byte(i, word), 1), not(mask)))) { i := add(i, 1) } {}\n\n                // zero out the rightmost part of the mload that is not the word.\n                let scrub := mul(sub(0x20, i), 8)\n                word := shl(scrub, shr(scrub, word))\n                cursor := add(cursor, i)\n            }\n            if (i == 0x20) {\n                revert WordSize(string(abi.encodePacked(word)));\n            }\n            return (cursor, word);\n        }\n    }\n\n    /// Skip an unlimited number of chars until we find one that is not in the\n    /// mask.\n    function skipMask(uint256 cursor, uint256 end, uint256 mask) internal pure returns (uint256) {\n        assembly (\"memory-safe\") {\n            //slither-disable-next-line incorrect-shift\n            for {} and(lt(cursor, end), gt(and(shl(byte(0, mload(cursor)), 1), mask), 0)) { cursor := add(cursor, 1) } {}\n        }\n        return cursor;\n    }\n\n    function parseLHS(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) {\n        unchecked {\n            while (cursor < end) {\n                bytes32 word;\n                uint256 char;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n\n                if (char & CMASK_LHS_STACK_HEAD > 0) {\n                    // if yang we can't start new stack item\n                    if (state.fsm & FSM_YANG_MASK > 0) {\n                        revert UnexpectedLHSChar(state.parseErrorOffset(cursor));\n                    }\n\n                    // Named stack item.\n                    if (char & CMASK_IDENTIFIER_HEAD > 0) {\n                        (cursor, word) = parseWord(cursor, end, CMASK_LHS_STACK_TAIL);\n                        (bool exists, uint256 index) = state.pushStackName(word);\n                        (index);\n                        // If the stack name already exists, then we\n                        // revert as shadowing is not allowed.\n                        if (exists) {\n                            revert DuplicateLHSItem(state.parseErrorOffset(cursor));\n                        }\n                    }\n                    // Anon stack item.\n                    else {\n                        cursor = skipMask(cursor + 1, end, CMASK_LHS_STACK_TAIL);\n                    }\n                    // Bump the index regardless of whether the stack\n                    // item is named or not.\n                    state.topLevel1++;\n                    state.lineTracker++;\n\n                    // Set yang as we are now building a stack item.\n                    state.fsm |= FSM_YANG_MASK | FSM_ACTIVE_SOURCE_MASK;\n                } else if (char & CMASK_WHITESPACE != 0) {\n                    cursor = skipMask(cursor + 1, end, CMASK_WHITESPACE);\n                    // Set ying as we now open to possibilities.\n                    state.fsm &= ~FSM_YANG_MASK;\n                } else if (char & CMASK_LHS_RHS_DELIMITER != 0) {\n                    // Set RHS and yin.\n                    state.fsm = (state.fsm | FSM_ACTIVE_SOURCE_MASK) & ~FSM_YANG_MASK;\n                    cursor++;\n                    break;\n                } else {\n                    if (char & CMASK_COMMENT_HEAD != 0) {\n                        revert UnexpectedComment(state.parseErrorOffset(cursor));\n                    } else {\n                        revert UnexpectedLHSChar(state.parseErrorOffset(cursor));\n                    }\n                }\n            }\n            return cursor;\n        }\n    }\n\n    //slither-disable-next-line cyclomatic-complexity\n    function parseRHS(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) {\n        unchecked {\n            while (cursor < end) {\n                bytes32 word;\n                uint256 char;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n\n                if (char & CMASK_RHS_WORD_HEAD > 0) {\n                    // If yang we can't start a new word.\n                    if (state.fsm & FSM_YANG_MASK > 0) {\n                        revert UnexpectedRHSChar(state.parseErrorOffset(cursor));\n                    }\n\n                    // If the word is unknown we need the cursor at the start\n                    // so that we can copy it into the subparser bytecode.\n                    uint256 cursorForUnknownWord = cursor;\n                    (cursor, word) = parseWord(cursor, end, CMASK_RHS_WORD_TAIL);\n\n                    // First check if this word is in meta.\n                    (bool exists, uint256 opcodeIndex) = state.lookupWord(word);\n                    if (exists) {\n                        cursor = state.parseOperand(cursor, end);\n                        Operand operand = state.handleOperand(opcodeIndex);\n                        state.pushOpToSource(opcodeIndex, operand);\n                        // This is a real word so we expect to see parens\n                        // after it.\n                        state.fsm |= FSM_WORD_END_MASK;\n                    }\n                    // Fallback to LHS items.\n                    else {\n                        (exists, opcodeIndex) = state.stackNameIndex(word);\n                        if (exists) {\n                            state.pushOpToSource(OPCODE_STACK, Operand.wrap(opcodeIndex));\n                            // Need to process highwater here because we\n                            // don't have any parens to open or close.\n                            state.highwater();\n                        }\n                        // Fallback to sub parsing.\n                        else {\n                            Operand operand;\n                            bytes memory subParserBytecode;\n\n                            {\n                                // Need to capture the word length up here before\n                                // we move the cursor past the operand that might\n                                // exist.\n                                uint256 wordLength = cursor - cursorForUnknownWord;\n                                uint256 subParserBytecodeLength = SUB_PARSER_BYTECODE_HEADER_SIZE + wordLength;\n                                // We store the final parsed values in the sub parser\n                                // bytecode so they can be handled as operand values,\n                                // rather than needing to be parsed as literals.\n                                // We have to move the cursor to keep the main parser\n                                // moving, but the sub parser bytecode will be\n                                // populated with the values in the state array.\n                                cursor = state.parseOperand(cursor, end);\n                                // The operand values length is only known after\n                                // parsing the operand.\n                                subParserBytecodeLength += state.operandValues.length * 0x20 + 0x20;\n\n                                // Build the bytecode that we will be sending to the\n                                // subparser. We can't yet build the byte header but\n                                // we can allocate the memory for it and move the string\n                                // tail and operand values into place.\n                                uint256 subParserBytecodeBytesLengthOffset = SUB_PARSER_BYTECODE_HEADER_SIZE;\n                                assembly (\"memory-safe\") {\n                                    subParserBytecode := mload(0x40)\n                                    // Move allocated memory past the bytes and their\n                                    // length. This is NOT an aligned allocation.\n                                    mstore(0x40, add(subParserBytecode, add(subParserBytecodeLength, 0x20)))\n                                    // Need to record the length of the unparsed\n                                    // bytes or the structure will be ambiguous to\n                                    // the sub parser.\n                                    mstore(add(subParserBytecode, subParserBytecodeBytesLengthOffset), wordLength)\n                                    mstore(subParserBytecode, subParserBytecodeLength)\n                                    // The operand of an unknown word is a pointer to\n                                    // the bytecode that needs to be sub parsed.\n                                    operand := subParserBytecode\n                                }\n                                // Copy the unknown word into the subparser bytecode\n                                // after the header bytes.\n                                LibMemCpy.unsafeCopyBytesTo(\n                                    Pointer.wrap(cursorForUnknownWord),\n                                    Pointer.wrap(\n                                        Pointer.unwrap(subParserBytecode.dataPointer())\n                                            + SUB_PARSER_BYTECODE_HEADER_SIZE\n                                    ),\n                                    wordLength\n                                );\n                            }\n                            // Copy the operand values into place for sub\n                            // parsing.\n                            {\n                                uint256 wordsToCopy = state.operandValues.length + 1;\n                                LibMemCpy.unsafeCopyWordsTo(\n                                    state.operandValues.startPointer(),\n                                    subParserBytecode.endDataPointer().unsafeSubWords(wordsToCopy),\n                                    wordsToCopy\n                                );\n                            }\n\n                            state.pushOpToSource(OPCODE_UNKNOWN, operand);\n                            // We only support words with parens for unknown words\n                            // that are sent off to the sub parsers.\n                            state.fsm |= FSM_WORD_END_MASK;\n                        }\n                    }\n\n                    state.fsm |= FSM_YANG_MASK;\n                }\n                // If this is the end of a word we MUST start a paren.\n                else if (state.fsm & FSM_WORD_END_MASK > 0) {\n                    if (char & CMASK_LEFT_PAREN == 0) {\n                        revert ExpectedLeftParen(state.parseErrorOffset(cursor));\n                    }\n                    // Increase the paren depth by 1.\n                    // i.e. move the byte offset by 3\n                    // There MAY be garbage at this new offset due to\n                    // a previous paren group being deallocated. The\n                    // deallocation process writes the input counter\n                    // to zero but leaves a garbage word in place, with\n                    // the expectation that it will be overwritten by\n                    // the next paren group.\n                    uint256 newParenOffset;\n                    assembly (\"memory-safe\") {\n                        newParenOffset := add(byte(0, mload(add(state, 0x60))), 3)\n                        mstore8(add(state, 0x60), newParenOffset)\n                    }\n                    // first 2 bytes are reserved, then remaining 62\n                    // bytes are for paren groups, so the offset MUST NOT\n                    // imply writing to the 63rd byte.\n                    if (newParenOffset > 59) {\n                        revert ParenOverflow();\n                    }\n                    cursor++;\n\n                    // We've moved past the paren, so we are no longer at\n                    // the end of a word and are yin.\n                    state.fsm &= ~(FSM_WORD_END_MASK | FSM_YANG_MASK);\n                } else if (char & CMASK_RIGHT_PAREN > 0) {\n                    uint256 parenOffset;\n                    assembly (\"memory-safe\") {\n                        parenOffset := byte(0, mload(add(state, 0x60)))\n                    }\n                    if (parenOffset == 0) {\n                        revert UnexpectedRightParen(state.parseErrorOffset(cursor));\n                    }\n                    // Decrease the paren depth by 1.\n                    // i.e. move the byte offset by -3.\n                    // This effectively deallocates the paren group, so\n                    // write the input counter out to the operand pointed\n                    // to by the pointer we deallocated.\n                    assembly (\"memory-safe\") {\n                        // State field offset.\n                        let stateOffset := add(state, 0x60)\n                        parenOffset := sub(parenOffset, 3)\n                        mstore8(stateOffset, parenOffset)\n                        mstore8(\n                            // Add 2 for the reserved bytes to the offset\n                            // then read top 16 bits from the pointer.\n                            // Add 1 to sandwitch the inputs byte between\n                            // the opcode index byte and the operand low\n                            // bytes.\n                            add(1, shr(0xf0, mload(add(add(stateOffset, 2), parenOffset)))),\n                            // Store the input counter, which is 2 bytes\n                            // after the operand write pointer.\n                            byte(0, mload(add(add(stateOffset, 4), parenOffset)))\n                        )\n                    }\n                    state.highwater();\n                    cursor++;\n                } else if (char & CMASK_WHITESPACE > 0) {\n                    cursor = skipMask(cursor + 1, end, CMASK_WHITESPACE);\n                    // Set yin as we now open to possibilities.\n                    state.fsm &= ~FSM_YANG_MASK;\n                }\n                // Handle all literals.\n                else if (char & CMASK_LITERAL_HEAD > 0) {\n                    cursor = state.pushLiteral(cursor, end);\n                    state.highwater();\n                    // We are yang now. Need the next char to release to\n                    // yin.\n                    state.fsm |= FSM_YANG_MASK;\n                } else if (char & CMASK_EOL > 0) {\n                    state.endLine(cursor);\n                    cursor++;\n                    break;\n                }\n                // End of source.\n                else if (char & CMASK_EOS > 0) {\n                    state.endLine(cursor);\n                    state.endSource();\n                    cursor++;\n\n                    state.fsm = FSM_DEFAULT;\n                    break;\n                }\n                // Comments aren't allowed in the RHS but we can give a\n                // nicer error message than the default.\n                else if (char & CMASK_COMMENT_HEAD != 0) {\n                    revert UnexpectedComment(state.parseErrorOffset(cursor));\n                } else {\n                    revert UnexpectedRHSChar(state.parseErrorOffset(cursor));\n                }\n            }\n            return cursor;\n        }\n    }\n\n    function parse(ParseState memory state) internal pure returns (bytes memory bytecode, uint256[] memory) {\n        unchecked {\n            if (state.data.length > 0) {\n                uint256 cursor;\n                uint256 end;\n                {\n                    bytes memory data = state.data;\n                    assembly (\"memory-safe\") {\n                        cursor := add(data, 0x20)\n                        end := add(cursor, mload(data))\n                    }\n                }\n                cursor = state.parseInterstitial(cursor, end);\n                cursor = state.parsePragma(cursor, end);\n                while (cursor < end) {\n                    cursor = state.parseInterstitial(cursor, end);\n                    cursor = state.parseLHS(cursor, end);\n                    cursor = state.parseRHS(cursor, end);\n                }\n                if (cursor != end) {\n                    revert ParserOutOfBounds();\n                }\n                if (state.fsm & FSM_ACTIVE_SOURCE_MASK != 0) {\n                    revert MissingFinalSemi(state.parseErrorOffset(cursor));\n                }\n            }\n            //slither-disable-next-line unused-return\n            return state.subParseWords(state.buildBytecode());\n        }\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParseMeta.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibCtPop} from \"../bitwise/LibCtPop.sol\";\nimport {Operand} from \"rain.interpreter.interface/interface/IInterpreterV2.sol\";\nimport {LibParseOperand} from \"./LibParseOperand.sol\";\nimport {ParseState} from \"./LibParseState.sol\";\nimport {AuthoringMetaV2} from \"rain.interpreter.interface/interface/IParserV1.sol\";\n\n/// @dev For metadata builder.\nerror DuplicateFingerprint();\n\n/// @dev Words and io fn pointers aren't the same length.\nerror WordIOFnPointerMismatch(uint256 wordsLength, uint256 ioFnPointersLength);\n\n/// @dev 0xFFFFFF = 3 byte fingerprint\n/// The fingerprint is 3 bytes because we're targetting the same collision\n/// resistance on words as solidity functions. As we already use a fully byte to\n/// map words across the expander, we only need 3 bytes for the fingerprint to\n/// achieve 4 bytes of collision resistance, which is the same as a solidity\n/// selector. This assumes that the byte selected to expand is uncorrelated with\n/// the fingerprint bytes, which is a reasonable assumption as long as we use\n/// different bytes from a keccak256 hash for each.\n/// This assumes a single expander, if there are multiple expanders, then the\n/// collision resistance only improves, so this is still safe.\nuint256 constant FINGERPRINT_MASK = 0xFFFFFF;\n/// @dev 4 = 1 byte opcode index + 3 byte fingerprint\nuint256 constant META_ITEM_SIZE = 4;\nuint256 constant META_ITEM_MASK = (1 << META_ITEM_SIZE) - 1;\n/// @dev 33 = 32 bytes for expansion + 1 byte for seed\nuint256 constant META_EXPANSION_SIZE = 0x21;\n/// @dev 1 = 1 byte for depth\nuint256 constant META_PREFIX_SIZE = 1;\n\nlibrary LibParseMeta {\n    function wordBitmapped(uint256 seed, bytes32 word) internal pure returns (uint256 bitmap, uint256 hashed) {\n        assembly (\"memory-safe\") {\n            mstore(0, word)\n            mstore8(0x20, seed)\n            hashed := keccak256(0, 0x21)\n            // We have to be careful here to avoid using the same byte for both\n            // the expansion and the fingerprint. This is because we are relying\n            // on the combined effect of both for collision resistance. We do\n            // this by using the high byte of the hash for the bitmap, and the\n            // low 3 bytes for the fingerprint.\n            //slither-disable-next-line incorrect-shift\n            bitmap := shl(byte(0, hashed), 1)\n        }\n    }\n\n    function copyWordsFromAuthoringMeta(AuthoringMetaV2[] memory authoringMeta)\n        internal\n        pure\n        returns (bytes32[] memory)\n    {\n        bytes32[] memory words = new bytes32[](authoringMeta.length);\n        for (uint256 i = 0; i < authoringMeta.length; i++) {\n            words[i] = authoringMeta[i].word;\n        }\n        return words;\n    }\n\n    function findBestExpander(AuthoringMetaV2[] memory metas)\n        internal\n        pure\n        returns (uint8 bestSeed, uint256 bestExpansion, AuthoringMetaV2[] memory remaining)\n    {\n        unchecked {\n            {\n                uint256 bestCt = 0;\n                for (uint256 seed = 0; seed < type(uint8).max; seed++) {\n                    uint256 expansion = 0;\n                    for (uint256 i = 0; i < metas.length; i++) {\n                        (uint256 shifted, uint256 hashed) = wordBitmapped(seed, metas[i].word);\n                        (hashed);\n                        expansion = shifted | expansion;\n                    }\n                    uint256 ct = LibCtPop.ctpop(expansion);\n                    if (ct > bestCt) {\n                        bestCt = ct;\n                        bestSeed = uint8(seed);\n                        bestExpansion = expansion;\n                    }\n                    // perfect expansion.\n                    if (ct == metas.length) {\n                        break;\n                    }\n                }\n\n                uint256 remainingLength = metas.length - bestCt;\n                assembly (\"memory-safe\") {\n                    remaining := mload(0x40)\n                    mstore(remaining, remainingLength)\n                    mstore(0x40, add(remaining, mul(0x20, add(1, remainingLength))))\n                }\n            }\n            uint256 usedExpansion = 0;\n            uint256 j = 0;\n            for (uint256 i = 0; i < metas.length; i++) {\n                (uint256 shifted, uint256 hashed) = wordBitmapped(bestSeed, metas[i].word);\n                (hashed);\n                if ((shifted & usedExpansion) == 0) {\n                    usedExpansion = shifted | usedExpansion;\n                } else {\n                    remaining[j] = metas[i];\n                    j++;\n                }\n            }\n        }\n    }\n\n    function buildParseMetaV2(AuthoringMetaV2[] memory authoringMeta, uint8 maxDepth)\n        internal\n        pure\n        returns (bytes memory parseMeta)\n    {\n        unchecked {\n            // Write out expansions.\n            uint8[] memory seeds;\n            uint256[] memory expansions;\n            uint256 dataStart;\n            {\n                uint256 depth = 0;\n                seeds = new uint8[](maxDepth);\n                expansions = new uint256[](maxDepth);\n                {\n                    AuthoringMetaV2[] memory remainingAuthoringMeta = authoringMeta;\n                    while (remainingAuthoringMeta.length > 0) {\n                        uint8 seed;\n                        uint256 expansion;\n                        (seed, expansion, remainingAuthoringMeta) = findBestExpander(remainingAuthoringMeta);\n                        seeds[depth] = seed;\n                        expansions[depth] = expansion;\n                        depth++;\n                    }\n                }\n\n                uint256 parseMetaLength =\n                    META_PREFIX_SIZE + depth * META_EXPANSION_SIZE + authoringMeta.length * META_ITEM_SIZE;\n                parseMeta = new bytes(parseMetaLength);\n                assembly (\"memory-safe\") {\n                    mstore8(add(parseMeta, 0x20), depth)\n                }\n                for (uint256 j = 0; j < depth; j++) {\n                    assembly (\"memory-safe\") {\n                        // Write each seed immediately before its expansion.\n                        let seedWriteAt := add(add(parseMeta, 0x21), mul(0x21, j))\n                        mstore8(seedWriteAt, mload(add(seeds, add(0x20, mul(0x20, j)))))\n                        mstore(add(seedWriteAt, 1), mload(add(expansions, add(0x20, mul(0x20, j)))))\n                    }\n                }\n\n                {\n                    uint256 dataOffset = META_PREFIX_SIZE + META_ITEM_SIZE + depth * META_EXPANSION_SIZE;\n                    assembly (\"memory-safe\") {\n                        dataStart := add(parseMeta, dataOffset)\n                    }\n                }\n            }\n\n            // Write words.\n            for (uint256 k = 0; k < authoringMeta.length; k++) {\n                uint256 s = 0;\n                uint256 cumulativePos = 0;\n                while (true) {\n                    uint256 toWrite;\n                    uint256 writeAt;\n\n                    // Need some careful scoping here to avoid stack too deep.\n                    {\n                        uint256 expansion = expansions[s];\n\n                        uint256 hashed;\n                        {\n                            uint256 shifted;\n                            (shifted, hashed) = wordBitmapped(seeds[s], authoringMeta[k].word);\n\n                            uint256 metaItemSize = META_ITEM_SIZE;\n                            uint256 pos = LibCtPop.ctpop(expansion & (shifted - 1)) + cumulativePos;\n                            assembly (\"memory-safe\") {\n                                writeAt := add(dataStart, mul(pos, metaItemSize))\n                            }\n                        }\n\n                        {\n                            uint256 wordFingerprint = hashed & FINGERPRINT_MASK;\n                            uint256 posFingerprint;\n                            assembly (\"memory-safe\") {\n                                posFingerprint := mload(writeAt)\n                            }\n                            posFingerprint &= FINGERPRINT_MASK;\n                            if (posFingerprint != 0) {\n                                if (posFingerprint == wordFingerprint) {\n                                    revert DuplicateFingerprint();\n                                }\n                                // Collision, try next expansion.\n                                s++;\n                                cumulativePos = cumulativePos + LibCtPop.ctpop(expansion);\n                                continue;\n                            }\n                            // Not collision, prepare the write with the\n                            // fingerprint and index.\n                            toWrite = wordFingerprint | (k << 0x18);\n                        }\n                    }\n\n                    uint256 mask = ~META_ITEM_MASK;\n                    assembly (\"memory-safe\") {\n                        mstore(writeAt, or(and(mload(writeAt), mask), toWrite))\n                    }\n                    // We're done with this word.\n                    break;\n                }\n            }\n        }\n    }\n\n    /// Given the parse meta and a word, return the index and io fn pointer for\n    /// the word. If the word is not found, then `exists` will be false. The\n    /// caller MUST check `exists` before using the other return values.\n    /// @param state The parser state.\n    /// @param word The word to lookup.\n    /// @return True if the word exists in the parse meta.\n    /// @return The index of the word in the parse meta.\n    function lookupWord(ParseState memory state, bytes32 word) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 dataStart;\n            uint256 cursor;\n            uint256 end;\n            {\n                uint256 metaExpansionSize = META_EXPANSION_SIZE;\n                uint256 metaItemSize = META_ITEM_SIZE;\n                bytes memory meta = state.meta;\n                assembly (\"memory-safe\") {\n                    // Read depth from first meta byte.\n                    cursor := add(meta, 1)\n                    let depth := and(mload(cursor), 0xFF)\n                    // 33 bytes per depth\n                    end := add(cursor, mul(depth, metaExpansionSize))\n                    dataStart := add(end, metaItemSize)\n                }\n            }\n\n            uint256 cumulativeCt = 0;\n            while (cursor < end) {\n                uint256 expansion;\n                uint256 posData;\n                uint256 wordFingerprint;\n                // Lookup the data at pos.\n                {\n                    uint256 seed;\n                    assembly (\"memory-safe\") {\n                        cursor := add(cursor, 1)\n                        seed := and(mload(cursor), 0xFF)\n                        cursor := add(cursor, 0x20)\n                        expansion := mload(cursor)\n                    }\n\n                    (uint256 shifted, uint256 hashed) = wordBitmapped(seed, word);\n                    uint256 pos = LibCtPop.ctpop(expansion & (shifted - 1)) + cumulativeCt;\n                    wordFingerprint = hashed & FINGERPRINT_MASK;\n                    uint256 metaItemSize = META_ITEM_SIZE;\n                    assembly (\"memory-safe\") {\n                        posData := mload(add(dataStart, mul(pos, metaItemSize)))\n                    }\n                }\n\n                // Match\n                if (wordFingerprint == posData & FINGERPRINT_MASK) {\n                    uint256 index;\n                    assembly (\"memory-safe\") {\n                        index := byte(28, posData)\n                    }\n                    return (true, index);\n                } else {\n                    cumulativeCt += LibCtPop.ctpop(expansion);\n                }\n            }\n            return (false, 0);\n        }\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParseOperand.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {\n    ExpectedOperand,\n    UnclosedOperand,\n    OperandOverflow,\n    OperandValuesOverflow,\n    UnexpectedOperand,\n    UnexpectedOperandValue\n} from \"../../error/ErrParse.sol\";\nimport {Operand} from \"rain.interpreter.interface/interface/IInterpreterV2.sol\";\nimport {LibParse} from \"./LibParse.sol\";\nimport {LibParseLiteral} from \"./literal/LibParseLiteral.sol\";\nimport {CMASK_OPERAND_END, CMASK_WHITESPACE, CMASK_OPERAND_START} from \"./LibParseCMask.sol\";\nimport {ParseState, OPERAND_VALUES_LENGTH, FSM_YANG_MASK} from \"./LibParseState.sol\";\nimport {LibParseError} from \"./LibParseError.sol\";\nimport {LibParseInterstitial} from \"./LibParseInterstitial.sol\";\n\nlibrary LibParseOperand {\n    using LibParseError for ParseState;\n    using LibParseLiteral for ParseState;\n    using LibParseOperand for ParseState;\n    using LibParseInterstitial for ParseState;\n\n    function parseOperand(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) {\n        uint256 char;\n        assembly (\"memory-safe\") {\n            //slither-disable-next-line incorrect-shift\n            char := shl(byte(0, mload(cursor)), 1)\n        }\n\n        // Reset operand values to length 0 to avoid any previous values bleeding\n        // into processing this operand.\n        uint256[] memory operandValues = state.operandValues;\n        assembly (\"memory-safe\") {\n            mstore(operandValues, 0)\n        }\n\n        // There may not be an operand. Only process if there is.\n        if (char == CMASK_OPERAND_START) {\n            // Move past the opening character.\n            ++cursor;\n            // Let the state be yin so we can parse literals.\n            state.fsm &= ~FSM_YANG_MASK;\n\n            // Load the next char.\n            assembly (\"memory-safe\") {\n                //slither-disable-next-line incorrect-shift\n                char := shl(byte(0, mload(cursor)), 1)\n            }\n            uint256 i = 0;\n            bool success = false;\n            while (cursor < end) {\n                // Load the next char.\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n\n                // Handle any whitespace.\n                // We DO NOT currently support full interstitial parsing here.\n                if (char & CMASK_WHITESPACE != 0) {\n                    // Move past the whitespace.\n                    cursor = state.skipWhitespace(cursor, end);\n                }\n                // If the operand has ended break.\n                else if (char & CMASK_OPERAND_END != 0) {\n                    // Move past the operand end.\n                    ++cursor;\n                    success = true;\n                    break;\n                }\n                // Attempt to parse literals if we're not yang.\n                else if (state.fsm & FSM_YANG_MASK == 0) {\n                    // We can't exceed the initial length of the operand values\n                    // that was allocated when the parse state was created.\n                    if (i == OPERAND_VALUES_LENGTH) {\n                        revert OperandValuesOverflow(state.parseErrorOffset(cursor));\n                    }\n                    uint256 value;\n                    (cursor, value) = state.parseLiteral(cursor, end);\n                    // We manipulate the operand values array directly in\n                    // assembly because if we used the Solidity indexing syntax\n                    // it would bounds check against the _current_ length of the\n                    // operand values array, not the length it was when the\n                    // parse state was created. The current length is just\n                    // whatever it happened to be for the last operand that was\n                    // parsed, so it's not useful for us here.\n                    assembly (\"memory-safe\") {\n                        mstore(add(operandValues, add(0x20, mul(i, 0x20))), value)\n                    }\n                    // Set yang so we don't attempt to parse a literal straight\n                    // off the back of this literal without some whitespace.\n                    state.fsm |= FSM_YANG_MASK;\n                    ++i;\n                }\n                // Something failed here so let's say the author forgot to close\n                // the operand, which is a little arbitrary but at least it's\n                // a consistent error.\n                else {\n                    revert UnclosedOperand(state.parseErrorOffset(cursor));\n                }\n            }\n            if (!success) {\n                revert UnclosedOperand(state.parseErrorOffset(cursor));\n            }\n            assembly (\"memory-safe\") {\n                mstore(operandValues, i)\n            }\n        }\n\n        return cursor;\n    }\n\n    /// Standard dispatch for handling an operand after it is parsed, using the\n    /// encoded function pointers on the current parse state. Requires that the\n    /// word index has been looked up by the parser, exists, and the literal\n    /// values have all been parsed out of the operand string. In the case of\n    /// the main parser this will all be done inline, but in the case of a sub\n    /// parser the literal extraction will be done first, then the word lookup\n    /// will have to be done by the sub parser, alongside the values provided\n    /// by the main parser.\n    function handleOperand(ParseState memory state, uint256 wordIndex) internal pure returns (Operand) {\n        function (uint256[] memory) internal pure returns (Operand) handler;\n        bytes memory handlers = state.operandHandlers;\n        assembly (\"memory-safe\") {\n            // There is no bounds check here because the indexes are calcualted\n            // by the parser itself, NOT provided by the user. Therefore the\n            // scope of corrupt data is limited to a bug in the parser itself,\n            // which can and should have direct test coverage.\n            handler := and(mload(add(handlers, add(2, mul(wordIndex, 2)))), 0xFFFF)\n        }\n        return handler(state.operandValues);\n    }\n\n    function handleOperandDisallowed(uint256[] memory values) internal pure returns (Operand) {\n        if (values.length != 0) {\n            revert UnexpectedOperand();\n        }\n        return Operand.wrap(0);\n    }\n\n    function handleOperandDisallowedAlwaysOne(uint256[] memory values) internal pure returns (Operand) {\n        if (values.length != 0) {\n            revert UnexpectedOperand();\n        }\n        return Operand.wrap(1);\n    }\n\n    /// There must be one or zero values. The fallback is 0 if nothing is\n    /// provided, else the provided value MUST fit in two bytes and is used as\n    /// is.\n    function handleOperandSingleFull(uint256[] memory values) internal pure returns (Operand operand) {\n        // Happy path at the top for efficiency.\n        if (values.length == 1) {\n            assembly (\"memory-safe\") {\n                operand := mload(add(values, 0x20))\n            }\n            if (Operand.unwrap(operand) > uint256(type(uint16).max)) {\n                revert OperandOverflow();\n            }\n        } else if (values.length == 0) {\n            operand = Operand.wrap(0);\n        } else {\n            revert UnexpectedOperandValue();\n        }\n    }\n\n    /// There must be exactly one value. There is no default fallback.\n    function handleOperandSingleFullNoDefault(uint256[] memory values) internal pure returns (Operand operand) {\n        // Happy path at the top for efficiency.\n        if (values.length == 1) {\n            assembly (\"memory-safe\") {\n                operand := mload(add(values, 0x20))\n            }\n            if (Operand.unwrap(operand) > uint256(type(uint16).max)) {\n                revert OperandOverflow();\n            }\n        } else if (values.length == 0) {\n            revert ExpectedOperand();\n        } else {\n            revert UnexpectedOperandValue();\n        }\n    }\n\n    /// There must be exactly two values. There is no default fallback. Each\n    /// value MUST fit in one byte and is used as is.\n    function handleOperandDoublePerByteNoDefault(uint256[] memory values) internal pure returns (Operand operand) {\n        // Happy path at the top for efficiency.\n        if (values.length == 2) {\n            uint256 a;\n            uint256 b;\n            assembly (\"memory-safe\") {\n                a := mload(add(values, 0x20))\n                b := mload(add(values, 0x40))\n            }\n            if (a > type(uint8).max || b > type(uint8).max) {\n                revert OperandOverflow();\n            }\n            operand = Operand.wrap(a | (b << 8));\n        } else if (values.length < 2) {\n            revert ExpectedOperand();\n        } else {\n            revert UnexpectedOperandValue();\n        }\n    }\n\n    /// 8 bit value then maybe 1 bit flag then maybe 1 bit flag. Fallback to 0\n    /// for both flags if not provided.\n    function handleOperand8M1M1(uint256[] memory values) internal pure returns (Operand operand) {\n        // Happy path at the top for efficiency.\n        uint256 length = values.length;\n        if (length >= 1 && length <= 3) {\n            uint256 a;\n            uint256 b;\n            uint256 c;\n            assembly (\"memory-safe\") {\n                a := mload(add(values, 0x20))\n            }\n\n            if (length >= 2) {\n                assembly (\"memory-safe\") {\n                    b := mload(add(values, 0x40))\n                }\n            } else {\n                b = 0;\n            }\n\n            if (length == 3) {\n                assembly (\"memory-safe\") {\n                    c := mload(add(values, 0x60))\n                }\n            } else {\n                c = 0;\n            }\n\n            if (a > type(uint8).max || b > 1 || c > 1) {\n                revert OperandOverflow();\n            }\n\n            operand = Operand.wrap(a | (b << 8) | (c << 9));\n        } else if (length == 0) {\n            revert ExpectedOperand();\n        } else {\n            revert UnexpectedOperandValue();\n        }\n    }\n\n    /// 2x maybe 1 bit flags. Fallback to 0 for both flags if not provided.\n    function handleOperandM1M1(uint256[] memory values) internal pure returns (Operand operand) {\n        // Happy path at the top for efficiency.\n        uint256 length = values.length;\n        if (length < 3) {\n            uint256 a;\n            uint256 b;\n\n            if (length >= 1) {\n                assembly (\"memory-safe\") {\n                    a := mload(add(values, 0x20))\n                }\n            } else {\n                a = 0;\n            }\n\n            if (length == 2) {\n                assembly (\"memory-safe\") {\n                    b := mload(add(values, 0x40))\n                }\n            } else {\n                b = 0;\n            }\n\n            if (a > 1 || b > 1) {\n                revert OperandOverflow();\n            }\n\n            operand = Operand.wrap(a | (b << 1));\n        } else {\n            revert UnexpectedOperandValue();\n        }\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/IInterpreterV2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {EncodedDispatch, StateNamespace, Operand, DEFAULT_STATE_NAMESPACE} from \"./deprecated/IInterpreterV1.sol\";\nimport {FullyQualifiedNamespace, IInterpreterStoreV2} from \"./IInterpreterStoreV2.sol\";\n\n/// @dev For maximum compatibility with external contracts, the `IInterpreterV2`\n/// should implement an opcode that reads from the stack by index as opcode `0`.\nuint256 constant OPCODE_STACK = 0;\n\n/// @dev For maximum compatibility with external contracts, the `IInterpreterV2`\n/// should implement an opcode that reads constants by index as opcode `1`.\nuint256 constant OPCODE_CONSTANT = 1;\n\n/// @dev For maximum compatibility with external contracts, the `IInterpreterV2`\n/// should implement an opcode that calls externs by index as opcode `2`.\nuint256 constant OPCODE_EXTERN = 2;\n\n/// @dev For maximum compatibility with external contracts, the `IInterpreterV2`\n/// should implement an opcode that reads from the context grid as <column row>\n/// as opcode `3`.\nuint256 constant OPCODE_CONTEXT = 3;\n\n/// @dev For maximum compatibility with opcode lists, the `IInterpreterV2`\n/// should implement the opcode for locally unknown words that need sub parsing\n/// as opcode `255`.\nuint256 constant OPCODE_UNKNOWN = 0xFF;\n\n/// @dev The index of a source within a deployed expression that can be evaluated\n/// by an `IInterpreterV2`. MAY be an entrypoint or the index of a source called\n/// internally such as by the `call` opcode.\ntype SourceIndexV2 is uint256;\n\n/// @title IInterpreterV2\n/// Interface into a standard interpreter that supports:\n///\n/// - evaluating `view` logic deployed onchain by an `IExpressionDeployerV1`\n/// - receiving arbitrary `uint256[][]` supporting context to be made available\n///   to the evaluated logic\n/// - handling subsequent state changes in bulk in response to evaluated logic\n/// - namespacing state changes according to the caller's preferences to avoid\n///   unwanted key collisions\n/// - exposing its internal function pointers to support external precompilation\n///   of logic for more gas efficient runtime evaluation by the interpreter\n///\n/// The interface is designed to be stable across many versions and\n/// implementations of an interpreter, balancing minimalism with features\n/// required for a general purpose onchain interpreted compute environment.\n///\n/// The security model of an interpreter is that it MUST be resilient to\n/// malicious expressions even if they dispatch arbitrary internal function\n/// pointers during an eval. The interpreter MAY return garbage or exhibit\n/// undefined behaviour or error during an eval, _provided that no state changes\n/// are persisted_ e.g. in storage, such that only the caller that specifies the\n/// malicious expression can be negatively impacted by the result. In turn, the\n/// caller must guard itself against arbitrarily corrupt/malicious reverts and\n/// return values from any interpreter that it requests an expression from. And\n/// so on and so forth up to the externally owned account (EOA) who signs the\n/// transaction and agrees to a specific combination of contracts, expressions\n/// and interpreters, who can presumably make an informed decision about which\n/// ones to trust to get the job done.\n///\n/// The state changes for an interpreter are expected to be produced by an\n/// `eval2` and passed to the `IInterpreterStoreV1` returned by the eval, as-is\n/// by the caller, after the caller has had an opportunity to apply their own\n/// intermediate logic such as reentrancy defenses against malicious\n/// interpreters. The interpreter is free to structure the state changes however\n/// it wants but MUST guard against the calling contract corrupting the changes\n/// between `eval2` and `set`. For example a store could sandbox storage writes\n/// per-caller so that a malicious caller can only damage their own state\n/// changes, while honest callers respect, benefit from and are protected by the\n/// interpreter store's state change handling.\n///\n/// The two step eval-state model allows evaluation to be read-only which\n/// provides security guarantees for the caller such as no stateful reentrancy,\n/// either from the interpreter or some contract interface used by some word,\n/// while still allowing for storage writes. As the storage writes happen on the\n/// interpreter rather than the caller (c.f. delegate call) the caller DOES NOT\n/// need to trust the interpreter, which allows for permissionless selection of\n/// interpreters by end users. Delegate call always implies an admin key on the\n/// caller because the delegatee contract can write arbitrarily to the state of\n/// the delegator, which severely limits the generality of contract composition.\ninterface IInterpreterV2 {\n    /// Exposes the function pointers as `uint16` values packed into a single\n    /// `bytes` in the same order as they would be indexed into by opcodes. For\n    /// example, if opcode `2` should dispatch function at position `0x1234` then\n    /// the start of the returned bytes would be `0xXXXXXXXX1234` where `X` is\n    /// a placeholder for the function pointers of opcodes `0` and `1`.\n    ///\n    /// `IExpressionDeployerV3` contracts use these function pointers to\n    /// \"compile\" the expression into something that an interpreter can dispatch\n    /// directly without paying gas to lookup the same at runtime. As the\n    /// validity of any integrity check and subsequent dispatch is highly\n    /// sensitive to both the function pointers and overall bytecode of the\n    /// interpreter, `IExpressionDeployerV3` contracts SHOULD implement guards\n    /// against accidentally being deployed onchain paired against an unknown\n    /// interpreter. It is very easy for an apparent compatible pairing to be\n    /// subtly and critically incompatible due to addition/removal/reordering of\n    /// opcodes and compiler optimisations on the interpreter bytecode.\n    ///\n    /// This MAY return different values during construction vs. all other times\n    /// after the interpreter has been successfully deployed onchain. DO NOT rely\n    /// on function pointers reported during contract construction.\n    function functionPointers() external view returns (bytes calldata);\n\n    /// The raison d'etre for an interpreter. Given some expression and per-call\n    /// additional contextual data, produce a stack of results and a set of state\n    /// changes that the caller MAY OPTIONALLY pass back to be persisted by a\n    /// call to `IInterpreterStoreV1.set`.\n    ///\n    /// There are two key differences between `eval` and `eval2`:\n    /// - `eval` was ambiguous about whether the top value of the final stack is\n    /// the first or last item of the array. `eval2` is unambiguous in that the\n    /// top of the stack MUST be the first item in the array.\n    /// - `eval2` allows the caller to specify inputs to the entrypoint stack of\n    /// the expression. This allows the `eval` and `offchainDebugEval` functions\n    /// to be merged into a single function that can be used for both onchain and\n    /// offchain evaluation. For example, the caller can simulate \"internal\"\n    /// calls by specifying the inputs to the entrypoint stack of the expression\n    /// as the outputs of some other expression. Legacy behaviour can be achieved\n    /// by passing an empty array for `inputs`.\n    ///\n    /// @param store The storage contract that the returned key/value pairs\n    /// MUST be passed to IF the calling contract is in a non-static calling\n    /// context. Static calling contexts MUST pass `address(0)`.\n    /// @param namespace The fully qualified namespace that will be used by the\n    /// interpreter at runtime in order to perform gets on the underlying store.\n    /// @param dispatch All the information required for the interpreter to load\n    /// an expression, select an entrypoint and return the values expected by the\n    /// caller. The interpreter MAY encode dispatches differently to\n    /// `LibEncodedDispatch` but this WILL negatively impact compatibility for\n    /// calling contracts that hardcode the encoding logic.\n    /// @param context A 2-dimensional array of data that can be indexed into at\n    /// runtime by the interpreter. The calling contract is responsible for\n    /// ensuring the authenticity and completeness of context data. The\n    /// interpreter MUST revert at runtime if an expression attempts to index\n    /// into some context value that is not provided by the caller. This implies\n    /// that context reads cannot be checked for out of bounds reads at deploy\n    /// time, as the runtime context MAY be provided in a different shape to what\n    /// the expression is expecting.\n    /// @param inputs The inputs to the entrypoint stack of the expression. MAY\n    /// be empty if the caller prefers to specify all inputs via. context.\n    /// @return stack The list of values produced by evaluating the expression.\n    /// MUST NOT be longer than the maximum length specified by `dispatch`, if\n    /// applicable. MUST be ordered such that the top of the stack is the FIRST\n    /// item in the array.\n    /// @return writes A list of values to be processed by a store. Most likely\n    /// will be pairwise key/value items but this is not strictly required if\n    /// some store expects some other format.\n    function eval2(\n        IInterpreterStoreV2 store,\n        FullyQualifiedNamespace namespace,\n        EncodedDispatch dispatch,\n        uint256[][] calldata context,\n        uint256[] calldata inputs\n    ) external view returns (uint256[] calldata stack, uint256[] calldata writes);\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/IInterpreterExternV3.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {EncodedExternDispatch, ExternDispatch} from \"./deprecated/IInterpreterExternV2.sol\";\n\n/// @title IInterpreterExternV3\n/// Handle a single dispatch from some calling contract with an array of\n/// inputs and array of outputs. Ostensibly useful to build \"word packs\" for\n/// `IInterpreterV2` so that less frequently used words can be provided in\n/// a less efficient format, but without bloating the base interpreter in\n/// terms of code size. Effectively allows unlimited words to exist as externs\n/// alongside interpreters.\n///\n/// The difference between V2 and V3 is that V3 integrates with integrity checks.\ninterface IInterpreterExternV3 {\n    /// Checks the integrity of some extern call.\n    /// @param dispatch Encoded information about the extern to dispatch.\n    /// Analogous to the opcode/operand in the interpreter.\n    /// @param expectedInputs The number of inputs expected for the dispatched\n    /// logic.\n    /// @param expectedOutputs The number of outputs expected for the dispatched\n    /// logic.\n    /// @return actualInputs The actual number of inputs for the dispatched\n    /// logic.\n    /// @return actualOutputs The actual number of outputs for the dispatched\n    /// logic.\n    function externIntegrity(ExternDispatch dispatch, uint256 expectedInputs, uint256 expectedOutputs)\n        external\n        view\n        returns (uint256 actualInputs, uint256 actualOutputs);\n\n    /// Handles a single dispatch.\n    /// @param dispatch Encoded information about the extern to dispatch.\n    /// Analogous to the opcode/operand in the interpreter.\n    /// @param inputs The array of inputs for the dispatched logic.\n    /// @return outputs The result of the dispatched logic.\n    function extern(ExternDispatch dispatch, uint256[] calldata inputs)\n        external\n        view\n        returns (uint256[] calldata outputs);\n}\n"
      },
      "lib/rain.interpreter.interface/src/lib/caller/LibContext.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibUint256Array} from \"rain.solmem/lib/LibUint256Array.sol\";\nimport {LibHashNoAlloc, HASH_NIL} from \"rain.lib.hash/LibHashNoAlloc.sol\";\n\nimport {SignatureChecker} from \"openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol\";\nimport {ECDSA} from \"openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol\";\n\nimport {\n    IInterpreterCallerV2,\n    SignedContextV1,\n    SIGNED_CONTEXT_SIGNER_OFFSET,\n    SIGNED_CONTEXT_SIGNATURE_OFFSET,\n    SIGNED_CONTEXT_CONTEXT_OFFSET\n} from \"../../interface/IInterpreterCallerV2.sol\";\n\n/// Thrown when the ith signature from a list of signed contexts is invalid.\nerror InvalidSignature(uint256 i);\n\nuint256 constant CONTEXT_BASE_COLUMN = 0;\nuint256 constant CONTEXT_BASE_ROWS = 2;\n\nuint256 constant CONTEXT_BASE_ROW_SENDER = 0;\nuint256 constant CONTEXT_BASE_ROW_CALLING_CONTRACT = 1;\n\n/// @title LibContext\n/// @notice Conventions for working with context as a calling contract. All of\n/// this functionality is OPTIONAL but probably useful for the majority of use\n/// cases. By building and authenticating onchain, caller provided and signed\n/// contexts all in a standard way the overall usability of context is greatly\n/// improved for expression authors and readers. Any calling contract that can\n/// match the context expectations of an existing expression is one large step\n/// closer to compatibility and portability, inheriting network effects of what\n/// has already been authored elsewhere.\nlibrary LibContext {\n    using LibUint256Array for uint256[];\n\n    /// The base context is the `msg.sender` and address of the calling contract.\n    /// As the interpreter itself is called via an external interface and may be\n    /// statically calling itself, it MAY NOT have any ability to inspect either\n    /// of these values. Even if this were not the case the calling contract\n    /// cannot assume the existence of some opcode(s) in the interpreter that\n    /// inspect the caller, so providing these two values as context is\n    /// sufficient to decouple the calling contract from the interpreter. It is\n    /// STRONGLY RECOMMENDED that even if the calling contract has \"no context\"\n    /// that it still provides this base to every `eval`.\n    ///\n    /// Calling contracts DO NOT need to call this directly. It is built and\n    /// merged automatically into the standard context built by `build`.\n    ///\n    /// @return The `msg.sender` and address of the calling contract using this\n    /// library, as a context-compatible array.\n    function base() internal view returns (uint256[] memory) {\n        return LibUint256Array.arrayFrom(uint256(uint160(msg.sender)), uint256(uint160(address(this))));\n    }\n\n    /// Standard hashing process over a single `SignedContextV1`. Notably used\n    /// to hash a list as `SignedContextV1[]` but could also be used to hash a\n    /// single `SignedContextV1` in isolation. Avoids allocating memory by\n    /// hashing each struct field in sequence within the memory scratch space.\n    /// @param signedContext The signed context to hash.\n    /// @param hashed The hashed signed context.\n    function hash(SignedContextV1 memory signedContext) internal pure returns (bytes32 hashed) {\n        uint256 signerOffset = SIGNED_CONTEXT_SIGNER_OFFSET;\n        uint256 contextOffset = SIGNED_CONTEXT_CONTEXT_OFFSET;\n        uint256 signatureOffset = SIGNED_CONTEXT_SIGNATURE_OFFSET;\n\n        assembly (\"memory-safe\") {\n            mstore(0, keccak256(add(signedContext, signerOffset), 0x20))\n\n            let context_ := mload(add(signedContext, contextOffset))\n            mstore(0x20, keccak256(add(context_, 0x20), mul(mload(context_), 0x20)))\n\n            mstore(0, keccak256(0, 0x40))\n\n            let signature_ := mload(add(signedContext, signatureOffset))\n            mstore(0x20, keccak256(add(signature_, 0x20), mload(signature_)))\n\n            hashed := keccak256(0, 0x40)\n        }\n    }\n\n    /// Standard hashing process over a list of signed contexts. Situationally\n    /// useful if the calling contract wants to record that it has seen a set of\n    /// signed data then later compare it against some input (e.g. to ensure that\n    /// many calls of some function all share the same input values). Note that\n    /// unlike the internals of `build`, this hashes over the signer and the\n    /// signature, to ensure that some data cannot be re-signed and used under\n    /// a different provenance later.\n    /// @param signedContexts The list of signed contexts to hash over.\n    /// @return hashed The hash of the signed contexts.\n    function hash(SignedContextV1[] memory signedContexts) internal pure returns (bytes32 hashed) {\n        uint256 cursor;\n        uint256 end;\n        bytes32 hashNil = HASH_NIL;\n        assembly (\"memory-safe\") {\n            cursor := add(signedContexts, 0x20)\n            end := add(cursor, mul(mload(signedContexts), 0x20))\n            mstore(0, hashNil)\n        }\n\n        SignedContextV1 memory signedContext;\n        bytes32 mem0;\n        while (cursor < end) {\n            assembly (\"memory-safe\") {\n                signedContext := mload(cursor)\n                // Subhash will write to 0 for its own hashing so keep a copy\n                // before it gets overwritten.\n                mem0 := mload(0)\n            }\n            bytes32 subHash = hash(signedContext);\n            assembly (\"memory-safe\") {\n                mstore(0, mem0)\n                mstore(0x20, subHash)\n                mstore(0, keccak256(0, 0x40))\n                cursor := add(cursor, 0x20)\n            }\n        }\n        assembly (\"memory-safe\") {\n            hashed := mload(0)\n        }\n    }\n\n    /// Builds a standard 2-dimensional context array from base, calling and\n    /// signed contexts. Note that \"columns\" of a context array refer to each\n    /// `uint256[]` and each item within a `uint256[]` is a \"row\".\n    ///\n    /// @param baseContext Anything the calling contract can provide which MAY\n    /// include input from the `msg.sender` of the calling contract. The default\n    /// base context from `LibContext.base()` DOES NOT need to be provided by the\n    /// caller, this matrix MAY be empty and will be simply merged into the final\n    /// context. The base context matrix MUST contain a consistent number of\n    /// columns from the calling contract so that the expression can always\n    /// predict how many unsigned columns there will be when it runs.\n    /// @param signedContexts Signed contexts are provided by the `msg.sender`\n    /// but signed by a third party. The expression (author) defines _who_ may\n    /// sign and the calling contract authenticates the signature over the\n    /// signed data. Technically `build` handles all the authentication inline\n    /// for the calling contract so if some context builds it can be treated as\n    /// authentic. The builder WILL REVERT if any of the signatures are invalid.\n    /// Note two things about the structure of the final built context re: signed\n    /// contexts:\n    /// - The first column is a list of the signers in order of what they signed\n    /// - The `msg.sender` can provide an arbitrary number of signed contexts so\n    ///   expressions DO NOT know exactly how many columns there are.\n    /// The expression is responsible for defining e.g. a domain separator in a\n    /// position that would force signed context to be provided in the \"correct\"\n    /// order, rather than relying on the `msg.sender` to honestly present data\n    /// in any particular structure/order.\n    function build(uint256[][] memory baseContext, SignedContextV1[] memory signedContexts)\n        internal\n        view\n        returns (uint256[][] memory)\n    {\n        unchecked {\n            uint256[] memory signers = new uint256[](signedContexts.length);\n\n            // - LibContext.base() + whatever we are provided.\n            // - signed contexts + signers if they exist else nothing.\n            uint256 contextLength = 1 + baseContext.length + (signedContexts.length > 0 ? signedContexts.length + 1 : 0);\n\n            uint256[][] memory context = new uint256[][](contextLength);\n            uint256 offset = 0;\n            context[offset] = LibContext.base();\n\n            for (uint256 i = 0; i < baseContext.length; i++) {\n                offset++;\n                context[offset] = baseContext[i];\n            }\n\n            if (signedContexts.length > 0) {\n                offset++;\n                context[offset] = signers;\n\n                for (uint256 i = 0; i < signedContexts.length; i++) {\n                    if (\n                        // Unlike `LibContext.hash` we can only hash over\n                        // the context as it's impossible for a signature\n                        // to sign itself.\n                        // Note the use of encodePacked here over a\n                        // single array, not including the length. This\n                        // would be a security issue if multiple dynamic\n                        // length values were hashed over together as\n                        // then many possible inputs could collide with\n                        // a single encoded output.\n                        !SignatureChecker.isValidSignatureNow(\n                            signedContexts[i].signer,\n                            ECDSA.toEthSignedMessageHash(LibHashNoAlloc.hashWords(signedContexts[i].context)),\n                            signedContexts[i].signature\n                        )\n                    ) {\n                        revert InvalidSignature(i);\n                    }\n\n                    signers[i] = uint256(uint160(signedContexts[i].signer));\n                    offset++;\n                    context[offset] = signedContexts[i].context;\n                }\n            }\n\n            return context;\n        }\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibPointer.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// A pointer to a location in memory. This is a `uint256` to save gas on low\n/// level operations on the evm stack. These same low level operations typically\n/// WILL NOT check for overflow or underflow, so all pointer logic MUST ensure\n/// that reads, writes and movements are not out of bounds.\ntype Pointer is uint256;\n\n/// @title LibPointer\n/// Ergonomic wrappers around common pointer movements, reading and writing. As\n/// wrappers on such low level operations often introduce too much jump gas\n/// overhead, these functions MAY find themselves used in reference\n/// implementations that more optimised code can be fuzzed against. MAY also be\n/// situationally useful on cooler performance paths.\nlibrary LibPointer {\n    /// Cast a `Pointer` to `bytes` without modification or any safety checks.\n    /// The caller MUST ensure the pointer is to a valid region of memory for\n    /// some `bytes`.\n    /// @param pointer The pointer to cast to `bytes`.\n    /// @return data The cast `bytes`.\n    function unsafeAsBytes(Pointer pointer) internal pure returns (bytes memory data) {\n        assembly (\"memory-safe\") {\n            data := pointer\n        }\n    }\n\n    /// Increase some pointer by a number of bytes.\n    ///\n    /// This is UNSAFE because it can silently overflow or point beyond some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// Note that moving a pointer by some bytes offset is likely to unalign it\n    /// with the 32 byte increments of the Solidity allocator.\n    ///\n    /// @param pointer The pointer to increase by `length`.\n    /// @param length The number of bytes to increase the pointer by.\n    /// @return The increased pointer.\n    function unsafeAddBytes(Pointer pointer, uint256 length) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(pointer, length)\n        }\n        return pointer;\n    }\n\n    /// Increase some pointer by a single 32 byte word.\n    ///\n    /// This is UNSAFE because it can silently overflow or point beyond some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// If the original pointer is aligned to the Solidity allocator it will be\n    /// aligned after the movement.\n    ///\n    /// @param pointer The pointer to increase by a single word.\n    /// @return The increased pointer.\n    function unsafeAddWord(Pointer pointer) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(pointer, 0x20)\n        }\n        return pointer;\n    }\n\n    /// Increase some pointer by multiple 32 byte words.\n    ///\n    /// This is UNSAFE because it can silently overflow or point beyond some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// If the original pointer is aligned to the Solidity allocator it will be\n    /// aligned after the movement.\n    ///\n    /// @param pointer The pointer to increase.\n    /// @param words The number of words to increase the pointer by.\n    /// @return The increased pointer.\n    function unsafeAddWords(Pointer pointer, uint256 words) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(pointer, mul(0x20, words))\n        }\n        return pointer;\n    }\n\n    /// Decrease some pointer by a single 32 byte word.\n    ///\n    /// This is UNSAFE because it can silently underflow or point below some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// If the original pointer is aligned to the Solidity allocator it will be\n    /// aligned after the movement.\n    ///\n    /// @param pointer The pointer to decrease by a single word.\n    /// @return The decreased pointer.\n    function unsafeSubWord(Pointer pointer) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := sub(pointer, 0x20)\n        }\n        return pointer;\n    }\n\n    /// Decrease some pointer by multiple 32 byte words.\n    ///\n    /// This is UNSAFE because it can silently underflow or point below some\n    /// data structure. The caller MUST ensure that this is a safe operation.\n    ///\n    /// If the original pointer is aligned to the Solidity allocator it will be\n    /// aligned after the movement.\n    ///\n    /// @param pointer The pointer to decrease.\n    /// @param words The number of words to decrease the pointer by.\n    /// @return The decreased pointer.\n    function unsafeSubWords(Pointer pointer, uint256 words) internal pure returns (Pointer) {\n        assembly (\"memory-safe\") {\n            pointer := sub(pointer, mul(0x20, words))\n        }\n        return pointer;\n    }\n\n    /// Read the word at the pointer.\n    ///\n    /// This is UNSAFE because it can read outside any particular data stucture\n    /// or even beyond allocated memory. The caller MUST ensure that this is a\n    /// safe operation.\n    ///\n    /// @param pointer Pointer to read the word at.\n    /// @return word The word read from the pointer.\n    function unsafeReadWord(Pointer pointer) internal pure returns (uint256 word) {\n        assembly (\"memory-safe\") {\n            word := mload(pointer)\n        }\n    }\n\n    /// Write a word at the pointer.\n    ///\n    /// This is UNSAFE because it can write outside any particular data stucture\n    /// or even beyond allocated memory. The caller MUST ensure that this is a\n    /// safe operation.\n    ///\n    /// @param pointer Pointer to write the word at.\n    /// @param word The word to write.\n    function unsafeWriteWord(Pointer pointer, uint256 word) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(pointer, word)\n        }\n    }\n\n    /// Get the pointer to the end of all allocated memory.\n    /// As per Solidity docs, there is no guarantee that the region of memory\n    /// beyond this pointer is zeroed out, as assembly MAY write beyond allocated\n    /// memory for temporary use if the scratch space is insufficient.\n    /// @return pointer The pointer to the end of all allocated memory.\n    function allocatedMemoryPointer() internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := mload(0x40)\n        }\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/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.0;\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/rain.interpreter.interface/src/interface/IParserV1.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nstruct AuthoringMeta {\n    // `word` is referenced directly in assembly so don't move the field.\n    bytes32 word;\n    uint8 operandParserOffset;\n    string description;\n}\n\n/// Identical to AuthoringMeta but without operandParserOffset.\nstruct AuthoringMetaV2 {\n    // `word` is referenced directly in assembly so don't move the field. It MUST\n    // be the first item.\n    bytes32 word;\n    string description;\n}\n\ninterface IParserV1 {\n    /// Parses a Rainlang string into an evaluable expression. MUST be\n    /// deterministic and MUST NOT have side effects. The only inputs are the\n    /// Rainlang string and the parse meta. MAY revert if the Rainlang string\n    /// is invalid. This function takes `bytes` instead of `string` to allow\n    /// for definitions of \"string\" other than UTF-8.\n    /// @param data The Rainlang bytes to parse.\n    /// @return bytecode The expressions that can be evaluated.\n    /// @return constants The constants that can be referenced by sources.\n    function parse(bytes calldata data) external pure returns (bytes calldata bytecode, uint256[] calldata constants);\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParseState.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Operand, OPCODE_CONSTANT} from \"rain.interpreter.interface/interface/IInterpreterV2.sol\";\nimport {LibParseStackTracker, ParseStackTracker} from \"./LibParseStackTracker.sol\";\nimport {Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {LibMemCpy} from \"rain.solmem/lib/LibMemCpy.sol\";\nimport {\n    DanglingSource,\n    MaxSources,\n    ParseStackOverflow,\n    UnclosedLeftParen,\n    ExcessRHSItems,\n    ExcessLHSItems,\n    NotAcceptingInputs,\n    UnsupportedLiteralType,\n    InvalidSubParser,\n    OpcodeIOOverflow\n} from \"../../error/ErrParse.sol\";\nimport {LibParseLiteral} from \"./literal/LibParseLiteral.sol\";\nimport {LibParse} from \"./LibParse.sol\";\nimport {LibParseOperand} from \"./LibParseOperand.sol\";\nimport {LibParseError} from \"./LibParseError.sol\";\n\n/// @dev Initial state of an active source is just the starting offset which is\n/// 0x20.\nuint256 constant EMPTY_ACTIVE_SOURCE = 0x20;\n\nuint256 constant FSM_YANG_MASK = 1;\nuint256 constant FSM_WORD_END_MASK = 1 << 1;\nuint256 constant FSM_ACCEPTING_INPUTS_MASK = 1 << 2;\n\n/// @dev If a source is active we cannot finish parsing without a semi to trigger\n/// finalisation.\nuint256 constant FSM_ACTIVE_SOURCE_MASK = 1 << 3;\n\n/// @dev fsm default state is:\n/// - yin\n/// - not word end\n/// - accepting inputs\nuint256 constant FSM_DEFAULT = FSM_ACCEPTING_INPUTS_MASK;\n\n/// @dev The operand values array is 4 words long. In the future we could have\n/// some kind of logic that reallocates and expands this if we discover that\n/// we need more than 4 operands for a single opcode. Currently there are no\n/// opcodes in the main parser that require more than 4 operands. Of course some\n/// sub parser could implement something that expects more than 4, in which case\n/// we will have to revisit this, but it won't be a breaking change. Consider\n/// that operands in the output are only 2 bytes, so a 4 value operand array is\n/// already only allowing for 4 bits per value on average, which is pretty tight\n/// for anything other than bit flags.\nuint256 constant OPERAND_VALUES_LENGTH = 4;\n\n/// The parser is stateful. This struct keeps track of the entire state.\n/// @param activeSourcePtr The pointer to the current source being built.\n/// The active source being pointed to is:\n/// - low 16 bits: bitwise offset into the source for the next word to be\n///   written. Starts at 0x20. Once a source is no longer the active source, i.e.\n///   it is full and a member of the LL tail, the offset is replaced with a\n///   pointer to the next source (towards the head) to build a doubly linked\n///   list.\n/// - mid 16 bits: pointer to the previous active source (towards the tail). This\n///   is a linked list of sources that are built RTL and then reversed to LTR to\n///   eval.\n/// - high bits: 4 byte opcodes and operand pairs.\n/// @param sourcesBuilder A builder for the sources array. This is a 256 bit\n/// integer where each 16 bits is a literal memory pointer to a source.\n/// @param fsm The finite state machine representation of the parser.\n/// - bit 0: LHS/RHS => 0 = LHS, 1 = RHS\n/// - bit 1: yang/yin => 0 = yin, 1 = yang\n/// - bit 2: word end => 0 = not end, 1 = end\n/// - bit 3: accepting inputs => 0 = not accepting, 1 = accepting\n/// - bit 4: interstitial => 0 = not interstitial, 1 = interstitial\n/// @param topLevel0 Memory region for stack word counters. The first byte is a\n/// counter/offset into the region, which increments for every top level item\n/// parsed on the RHS. The remaining 31 bytes are the word counters for each\n/// stack item, which are incremented for every op pushed to the source. This is\n/// reset to 0 for every new source.\n/// @param topLevel1 31 additional bytes of stack words, allowing for 62 top\n/// level stack items total per source. The final byte is used to count the\n/// stack height according to the LHS for the current source. This is reset to 0\n/// for every new source.\n/// @param parenTracker0 Memory region for tracking pointers to words in the\n/// source, and counters for the number of words in each paren group. The first\n/// byte is a counter/offset into the region. The second byte is a phantom\n/// counter for the root level, the remaining 30 bytes are the paren group words.\n/// @param parenTracker1 32 additional bytes of paren group words.\n/// @param lineTracker A 32 byte memory region for tracking the current line.\n/// Will be partially reset for each line when `endLine` is called. Fully\n/// reset when a new source is started.\n/// Bytes from low to high:\n/// - byte 0: Lowest byte is the number of LHS items parsed. This is the low\n/// byte so that a simple ++ is a valid operation on the line tracker while\n/// parsing the LHS. This is reset to 0 for each new line.\n/// - byte 1: A snapshot of the first high byte of `topLevel0`, i.e. the offset\n/// of top level items as at the beginning of the line. This is reset to the high\n/// byte of `topLevel0` on each new line.\n/// - bytes 2+: A sequence of 2 byte pointers to before the start of each top\n/// level item, which is implictly after the end of the previous top level item.\n/// Allows us to quickly find the start of the RHS source for each top level\n/// item.\n/// @param stackNames A linked list of stack names. As the parser encounters\n/// named stack items it pushes them onto this linked list. The linked list is\n/// in FILO order, so the first item on the stack is the last item in the list.\n/// This makes it more efficient to reference more recent stack names on the RHS.\n/// @param literalBloom A bloom filter of all the literals that have been\n/// encountered so far. This is used to quickly dedupe literals.\n/// @param constantsBuilder A builder for the constants array.\n/// - low 16 bits: the height (length) of the constants array.\n/// - high 240 bits: a linked list of constant values. Each constant value is\n///   stored as a 256 bit key/value pair. The key is the fingerprint of the\n///   constant value, and the value is the constant value itself.\n/// @param literalParsers A 256 bit integer where each 16 bits is a function\n/// pointer to a literal parser.\nstruct ParseState {\n    /// @dev START things that are referenced directly in assembly by hardcoded\n    /// offsets. E.g.\n    /// - `pushOpToSource`\n    /// - `snapshotSourceHeadToLineTracker`\n    /// - `newSource`\n    uint256 activeSourcePtr;\n    uint256 topLevel0;\n    uint256 topLevel1;\n    uint256 parenTracker0;\n    uint256 parenTracker1;\n    uint256 lineTracker;\n    /// - `pushSubParser`\n    uint256 subParsers;\n    /// @dev END things that are referenced directly in assembly by hardcoded\n    /// offsets.\n    uint256 sourcesBuilder;\n    uint256 fsm;\n    uint256 stackNames;\n    uint256 stackNameBloom;\n    uint256 constantsBuilder;\n    uint256 constantsBloom;\n    bytes literalParsers;\n    bytes operandHandlers;\n    uint256[] operandValues;\n    ParseStackTracker stackTracker;\n    bytes data;\n    bytes meta;\n}\n\nlibrary LibParseState {\n    using LibParseState for ParseState;\n    using LibParseStackTracker for ParseStackTracker;\n    using LibParseError for ParseState;\n    using LibParseLiteral for ParseState;\n\n    function newActiveSourcePointer(uint256 oldActiveSourcePointer) internal pure returns (uint256) {\n        uint256 activeSourcePtr;\n        uint256 emptyActiveSource = EMPTY_ACTIVE_SOURCE;\n        assembly (\"memory-safe\") {\n            // The active source pointer MUST be aligned to 32 bytes because we\n            // rely on alignment to know when we have filled a source and need\n            // to create a new one, or need to jump through the linked list.\n            activeSourcePtr := and(add(mload(0x40), 0x1F), not(0x1F))\n            mstore(activeSourcePtr, or(emptyActiveSource, shl(0x10, oldActiveSourcePointer)))\n            mstore(0x40, add(activeSourcePtr, 0x20))\n\n            // The old tail head must now point back to the new tail head.\n            mstore(oldActiveSourcePointer, or(and(mload(oldActiveSourcePointer), not(0xFFFF)), activeSourcePtr))\n        }\n        return activeSourcePtr;\n    }\n\n    function resetSource(ParseState memory state) internal pure {\n        state.activeSourcePtr = newActiveSourcePointer(0);\n        state.topLevel0 = 0;\n        state.topLevel1 = 0;\n        state.parenTracker0 = 0;\n        state.parenTracker1 = 0;\n        state.lineTracker = 0;\n\n        // We don't reset sub parsers because they are global and immutable to\n        // the parsing process.\n\n        state.stackNames = 0;\n        state.stackNameBloom = 0;\n        state.stackTracker = ParseStackTracker.wrap(0);\n    }\n\n    function newState(bytes memory data, bytes memory meta, bytes memory operandHandlers, bytes memory literalParsers)\n        internal\n        pure\n        returns (ParseState memory)\n    {\n        ParseState memory state = ParseState(\n            // activeSource\n            // (will be built in `newActiveSource`)\n            0,\n            // topLevel0\n            0,\n            // topLevel1\n            0,\n            // parenTracker0\n            0,\n            // parenTracker1\n            0,\n            // lineTracker\n            // (will be built in `resetSource`)\n            0,\n            // sub parsers\n            0,\n            // sourcesBuilder\n            0,\n            // fsm\n            FSM_DEFAULT,\n            // stackNames\n            0,\n            // stackNameBloom\n            0,\n            // literalBloom\n            0,\n            // constantsBuilder\n            0,\n            // literalParsers\n            literalParsers,\n            // operandHandlers\n            operandHandlers,\n            // operandValues\n            new uint256[](OPERAND_VALUES_LENGTH),\n            // stackTracker\n            ParseStackTracker.wrap(0),\n            // data bytes\n            data,\n            // meta bytes\n            meta\n        );\n        state.resetSource();\n        return state;\n    }\n\n    function pushSubParser(ParseState memory state, uint256 cursor, uint256 subParser) internal pure {\n        if (subParser > uint256(type(uint160).max)) {\n            revert InvalidSubParser(state.parseErrorOffset(cursor));\n        }\n\n        uint256 tail = state.subParsers;\n        // Move the tail off to a new allocation.\n        uint256 tailPointer;\n        assembly (\"memory-safe\") {\n            tailPointer := mload(0x40)\n            mstore(0x40, add(tailPointer, 0x20))\n            mstore(tailPointer, tail)\n        }\n        // Put the tail pointer in the high bits of the new head.\n        state.subParsers = subParser | tailPointer << 0xF0;\n    }\n\n    // Find the pointer to the first opcode in the source LL. Put it in the line\n    // tracker at the appropriate offset.\n    function snapshotSourceHeadToLineTracker(ParseState memory state) internal pure {\n        uint256 activeSourcePtr = state.activeSourcePtr;\n        assembly (\"memory-safe\") {\n            let topLevel0Pointer := add(state, 0x20)\n            let totalRHSTopLevel := byte(0, mload(topLevel0Pointer))\n            // Only do stuff if the current word counter is zero.\n            if iszero(byte(0, mload(add(topLevel0Pointer, add(totalRHSTopLevel, 1))))) {\n                let byteOffset := div(and(mload(activeSourcePtr), 0xFFFF), 8)\n                let sourceHead := add(activeSourcePtr, sub(0x20, byteOffset))\n\n                let lineTracker := mload(add(state, 0xa0))\n                let lineRHSTopLevel := sub(totalRHSTopLevel, byte(30, lineTracker))\n                let offset := mul(0x10, add(lineRHSTopLevel, 1))\n                lineTracker := or(lineTracker, shl(offset, sourceHead))\n                mstore(add(state, 0xa0), lineTracker)\n            }\n        }\n    }\n\n    //slither-disable-next-line cyclomatic-complexity\n    function endLine(ParseState memory state, uint256 cursor) internal pure {\n        unchecked {\n            {\n                uint256 parenOffset;\n                assembly (\"memory-safe\") {\n                    parenOffset := byte(0, mload(add(state, 0x60)))\n                }\n                if (parenOffset > 0) {\n                    revert UnclosedLeftParen(state.parseErrorOffset(cursor));\n                }\n            }\n\n            // This will snapshot the current head of the source, which will be\n            // the start of where we want to read for the final line RHS item,\n            // if it exists.\n            state.snapshotSourceHeadToLineTracker();\n\n            // Preserve the accepting inputs flag but set\n            // everything else back to defaults. Also set that\n            // there is an active source.\n            state.fsm = (FSM_DEFAULT & ~FSM_ACCEPTING_INPUTS_MASK) | (state.fsm & FSM_ACCEPTING_INPUTS_MASK)\n                | FSM_ACTIVE_SOURCE_MASK;\n\n            uint256 lineLHSItems = state.lineTracker & 0xFF;\n            // Total number of RHS at top level is the top byte of topLevel0.\n            uint256 totalRHSTopLevel = state.topLevel0 >> 0xf8;\n            // Snapshot for RHS from start of line is second low byte of\n            // lineTracker.\n            uint256 lineRHSTopLevel = totalRHSTopLevel - ((state.lineTracker >> 8) & 0xFF);\n\n            // If:\n            // - we are accepting inputs\n            // - the RHS on this line is empty\n            // Then we treat the LHS items as inputs to the source. This means that\n            // we need to move the RHS offset to the end of the LHS items. There MAY\n            // be 0 LHS items, e.g. if the entire source is empty. This can only\n            // happen at the start of the source, as any RHS item immediately flips\n            // the FSM to not accepting inputs.\n            if (lineRHSTopLevel == 0) {\n                if (state.fsm & FSM_ACCEPTING_INPUTS_MASK == 0) {\n                    revert NotAcceptingInputs(state.parseErrorOffset(cursor));\n                } else {\n                    // As there are no RHS opcodes yet we can simply set topLevel0 directly.\n                    // This is the only case where we defer to the LHS to tell\n                    // us how many top level items there are.\n                    totalRHSTopLevel += lineLHSItems;\n                    state.topLevel0 = totalRHSTopLevel << 0xf8;\n\n                    // Push the inputs onto the stack tracker.\n                    state.stackTracker = state.stackTracker.pushInputs(lineLHSItems);\n                }\n            }\n            // If:\n            // - there are multiple RHS items on this line\n            // Then there must be the same number of LHS items. Multi or zero output\n            // RHS top level items are NOT supported unless they are the only RHS\n            // item on that line.\n            else if (lineRHSTopLevel > 1) {\n                if (lineLHSItems < lineRHSTopLevel) {\n                    revert ExcessRHSItems(state.parseErrorOffset(cursor));\n                } else if (lineLHSItems > lineRHSTopLevel) {\n                    revert ExcessLHSItems(state.parseErrorOffset(cursor));\n                }\n            }\n\n            // Follow pointers to the start of the RHS item.\n            uint256 topLevelOffset = 1 + totalRHSTopLevel - lineRHSTopLevel;\n            uint256 end = (0x10 * lineRHSTopLevel) + 0x20;\n            for (uint256 offset = 0x20; offset < end; offset += 0x10) {\n                uint256 itemSourceHead = (state.lineTracker >> offset) & 0xFFFF;\n                uint256 opsDepth;\n                assembly (\"memory-safe\") {\n                    opsDepth := byte(0, mload(add(state, add(0x20, topLevelOffset))))\n                }\n                for (uint256 i = 1; i <= opsDepth; i++) {\n                    {\n                        // We've hit the end of a LL item so have to jump towards the\n                        // tail to keep going. This makes the assumption that\n                        // the relevant pointers are aligned to 32 bytes, which\n                        // is handled on allocation in `newActiveSourcePointer`.\n                        if (itemSourceHead % 0x20 == 0x1c) {\n                            assembly (\"memory-safe\") {\n                                itemSourceHead := shr(0xf0, mload(itemSourceHead))\n                            }\n                        }\n                        uint256 opInputs;\n                        assembly (\"memory-safe\") {\n                            opInputs := byte(1, mload(itemSourceHead))\n                        }\n                        state.stackTracker = state.stackTracker.pop(opInputs);\n                        // Nested multi or zero output RHS items are NOT\n                        // supported. If the top level RHS item is the ONLY RHS\n                        // item on the line then it MAY have multiple or zero\n                        // outputs. In this case we defer to the LHS to tell us\n                        // how many outputs there are. If the LHS is wrong then\n                        // later integrity checks will need to flag it.\n                        uint256 opOutputs = i == opsDepth && lineRHSTopLevel == 1 ? lineLHSItems : 1;\n                        state.stackTracker = state.stackTracker.push(opOutputs);\n\n                        // Merge the op outputs and inputs into a single byte.\n                        if (opOutputs > 0x0F || opInputs > 0x0F) {\n                            revert OpcodeIOOverflow(state.parseErrorOffset(cursor));\n                        }\n                        assembly (\"memory-safe\") {\n                            mstore8(add(itemSourceHead, 1), or(shl(4, opOutputs), opInputs))\n                        }\n                    }\n                    itemSourceHead += 4;\n                }\n                topLevelOffset++;\n            }\n\n            state.lineTracker = totalRHSTopLevel << 8;\n        }\n    }\n\n    /// We potentially just closed out some group of arbitrarily nested parens\n    /// OR a lone literal value at the top level. IF we are at the top level we\n    /// move the immutable stack highwater mark forward 1 item, which moves the\n    /// RHS offset forward 1 byte to start a new word counter.\n    function highwater(ParseState memory state) internal pure {\n        uint256 parenOffset;\n        assembly (\"memory-safe\") {\n            parenOffset := byte(0, mload(add(state, 0x60)))\n        }\n        if (parenOffset == 0) {\n            uint256 newStackRHSOffset;\n            assembly (\"memory-safe\") {\n                let stackRHSOffsetPtr := add(state, 0x20)\n                newStackRHSOffset := add(byte(0, mload(stackRHSOffsetPtr)), 1)\n                mstore8(stackRHSOffsetPtr, newStackRHSOffset)\n            }\n            if (newStackRHSOffset == 0x3f) {\n                revert ParseStackOverflow();\n            }\n        }\n    }\n\n    function constantValueBloom(uint256 value) internal pure returns (uint256 bloom) {\n        return uint256(1) << (value % 256);\n    }\n\n    /// Includes a constant value in the constants linked list so that it will\n    /// appear in the final constants array.\n    function pushConstantValue(ParseState memory state, uint256 value) internal pure {\n        unchecked {\n            uint256 headPtr;\n            uint256 tailPtr = state.constantsBuilder >> 0x10;\n            assembly (\"memory-safe\") {\n                // Allocate two words.\n                headPtr := mload(0x40)\n                mstore(0x40, add(headPtr, 0x40))\n\n                // First word is the pointer to the tail of the LL.\n                mstore(headPtr, tailPtr)\n                // Second word is the value.\n                mstore(add(headPtr, 0x20), value)\n            }\n\n            // Inc the constants height by 1 and set the new head pointer.\n            state.constantsBuilder = ((state.constantsBuilder & 0xFFFF) + 1) | (headPtr << 0x10);\n\n            // Merge in the value bloom.\n            state.constantsBloom |= constantValueBloom(value);\n        }\n    }\n\n    function pushLiteral(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) {\n        unchecked {\n            uint256 constantValue;\n            bool success;\n            (success, cursor, constantValue) = state.tryParseLiteral(cursor, end);\n            // Don't continue trying to push something that we can't parse.\n            if (!success) {\n                revert UnsupportedLiteralType(state.parseErrorOffset(cursor));\n            }\n\n            // Whether the constant is a duplicate.\n            bool exists = false;\n\n            // The index of the constant in the constants builder LL. This is\n            // starting from the top of the linked list, so the final index is\n            // the height of the linked list minus this value.\n            uint256 t = 0;\n\n            // If the constant is in the bloom filter, then it MAY be a\n            // duplicate. Try to find the constant value in the linked list of\n            // constants.\n            //\n            // If the constant is NOT in the bloom filter, then it is definitely\n            // NOT a duplicate, so avoid traversing the linked list.\n            //\n            // Worst case is a false positive in the bloom filter, which means\n            // we traverse the linked list and find no match. This is O(1) for\n            // the bloom filter and O(n) for the linked list traversal.\n            if (state.constantsBloom & constantValueBloom(constantValue) != 0) {\n                uint256 tailPtr = state.constantsBuilder >> 0x10;\n                while (tailPtr != 0 && !exists) {\n                    ++t;\n                    uint256 tailValue;\n                    assembly (\"memory-safe\") {\n                        tailValue := mload(add(tailPtr, 0x20))\n                        tailPtr := mload(tailPtr)\n                    }\n                    exists = constantValue == tailValue;\n                }\n            }\n\n            // Push the constant opcode to the source.\n            // The index is either the height of the constants, if the constant\n            // is NOT a duplicate, or the height minus the index of the\n            // duplicate. This is because the final constants array is built\n            // 0 indexed from the bottom of the linked list to the top.\n            {\n                uint256 constantsHeight = state.constantsBuilder & 0xFFFF;\n                state.pushOpToSource(OPCODE_CONSTANT, Operand.wrap(exists ? constantsHeight - t : constantsHeight));\n            }\n\n            // If the literal is not a duplicate, then we need to add it to the\n            // linked list of literals so that `t` can point to it, and we can\n            // build the constants array from the values in the linked list\n            // later.\n            if (!exists) {\n                state.pushConstantValue(constantValue);\n            }\n\n            return cursor;\n        }\n    }\n\n    function pushOpToSource(ParseState memory state, uint256 opcode, Operand operand) internal pure {\n        unchecked {\n            // This might be a top level item so try to snapshot its pointer to\n            // the line tracker before writing the stack counter.\n            state.snapshotSourceHeadToLineTracker();\n\n            // As soon as we push an op to source we can no longer accept inputs.\n            state.fsm &= ~FSM_ACCEPTING_INPUTS_MASK;\n            // We also have an active source;\n            state.fsm |= FSM_ACTIVE_SOURCE_MASK;\n\n            // Increment the top level stack counter for the current top level\n            // word. MAY be setting 0 to 1 if this is the top level.\n            assembly (\"memory-safe\") {\n                // Hardcoded offset into the state struct.\n                let counterOffset := add(state, 0x20)\n                let counterPointer := add(counterOffset, add(byte(0, mload(counterOffset)), 1))\n                // Increment the counter.\n                mstore8(counterPointer, add(byte(0, mload(counterPointer)), 1))\n            }\n\n            uint256 activeSource;\n            uint256 offset;\n            uint256 activeSourcePointer = state.activeSourcePtr;\n            assembly (\"memory-safe\") {\n                activeSource := mload(activeSourcePointer)\n                // The low 16 bits of the active source is the current offset.\n                offset := and(activeSource, 0xFFFF)\n\n                // The offset is in bits so for a byte pointer we need to divide\n                // by 8, then add 4 to move to the operand low byte.\n                let inputsBytePointer := sub(add(activeSourcePointer, 0x20), add(div(offset, 8), 4))\n\n                // Increment the paren input counter. The input counter is for the paren\n                // group that is currently being built. This means the counter is for\n                // the paren group that is one level above the current paren offset.\n                // Assumes that every word has exactly 1 output, therefore the input\n                // counter always increases by 1.\n                // Hardcoded offset into the state struct.\n                let inputCounterPos := add(state, 0x60)\n                inputCounterPos :=\n                    add(\n                        add(\n                            inputCounterPos,\n                            // the offset\n                            byte(0, mload(inputCounterPos))\n                        ),\n                        // +2 for the reserved bytes -1 to move back to the counter\n                        // for the previous paren group.\n                        1\n                    )\n                // Increment the parent counter.\n                mstore8(inputCounterPos, add(byte(0, mload(inputCounterPos)), 1))\n                // Zero out the current counter.\n                mstore8(add(inputCounterPos, 3), 0)\n\n                // Write the operand low byte pointer into the paren tracker.\n                // Move 3 bytes after the input counter pos, then shift down 32\n                // bytes to accomodate the full mload.\n                let parenTrackerPointer := sub(inputCounterPos, 29)\n                mstore(parenTrackerPointer, or(and(mload(parenTrackerPointer), not(0xFFFF)), inputsBytePointer))\n            }\n\n            // We write sources RTL so they can run LTR.\n            activeSource =\n            // increment offset. We have 16 bits allocated to the offset and stop\n            // processing at 0x100 so this never overflows into the actual source\n            // data.\n            activeSource + 0x20\n            // include the operand. The operand is assumed to be 16 bits, so we shift\n            // it into the correct position.\n            | Operand.unwrap(operand) << offset\n            // include new op. The opcode is assumed to be 8 bits, so we shift it\n            // into the correct position, beyond the operand.\n            | opcode << (offset + 0x18);\n            assembly (\"memory-safe\") {\n                mstore(activeSourcePointer, activeSource)\n            }\n\n            // We have filled the current source slot. Need to create a new active\n            // source and fulfill the doubly linked list.\n            if (offset == 0xe0) {\n                state.activeSourcePtr = newActiveSourcePointer(activeSourcePointer);\n            }\n        }\n    }\n\n    function endSource(ParseState memory state) internal pure {\n        uint256 sourcesBuilder = state.sourcesBuilder;\n        uint256 offset = sourcesBuilder >> 0xf0;\n\n        // End is the number of top level words in the source, which is the\n        // byte offset index + 1.\n        uint256 end;\n        assembly (\"memory-safe\") {\n            end := add(byte(0, mload(add(state, 0x20))), 1)\n        }\n\n        if (offset == 0xf0) {\n            revert MaxSources();\n        }\n        // Follow the word counters to build the source with the correct\n        // combination of LTR and RTL words. The stack needs to be built\n        // LTR at the top level, so that as the evaluation proceeds LTR it\n        // can reference previous items in subsequent items. However, the\n        // stack is built RTL within each item, so that nested parens are\n        // evaluated correctly similar to reverse polish notation.\n        else {\n            uint256 source;\n            ParseStackTracker stackTracker = state.stackTracker;\n            uint256 cursor = state.activeSourcePtr;\n            assembly (\"memory-safe\") {\n                // find the end of the LL tail.\n                let tailPointer := and(shr(0x10, mload(cursor)), 0xFFFF)\n                for {} iszero(iszero(tailPointer)) {} {\n                    cursor := tailPointer\n                    tailPointer := and(shr(0x10, mload(cursor)), 0xFFFF)\n                }\n\n                // Move cursor to the end of the end of the LL tail item.\n                // This is 4 bytes from the end of the EVM word, to compensate\n                // for the offset and pointer positions.\n                tailPointer := cursor\n                cursor := add(cursor, 0x1C)\n                // leave space for the source prefix in the bytecode output.\n                let length := 4\n                source := mload(0x40)\n                // Move over the source 32 byte length and the 4 byte prefix.\n                let writeCursor := add(source, 0x20)\n                writeCursor := add(writeCursor, 4)\n\n                let counterCursor := add(state, 0x21)\n                for {\n                    let i := 0\n                    let wordsTotal := byte(0, mload(counterCursor))\n                    let wordsRemaining := wordsTotal\n                } lt(i, end) {\n                    i := add(i, 1)\n                    counterCursor := add(counterCursor, 1)\n                    wordsTotal := byte(0, mload(counterCursor))\n                    wordsRemaining := wordsTotal\n                } {\n                    length := add(length, mul(wordsTotal, 4))\n                    {\n                        // 4 bytes per source word.\n                        let tailItemWordsRemaining := div(sub(cursor, tailPointer), 4)\n                        // loop to the tail item that contains the start of the words\n                        // that we need to copy.\n                        for {} gt(wordsRemaining, tailItemWordsRemaining) {} {\n                            wordsRemaining := sub(wordsRemaining, tailItemWordsRemaining)\n                            tailPointer := and(mload(tailPointer), 0xFFFF)\n                            tailItemWordsRemaining := 7\n                            cursor := add(tailPointer, 0x1C)\n                        }\n                    }\n\n                    // Now the words remaining is lte the words remaining in the\n                    // tail item. Move the cursor back to the start of the words\n                    // and copy the passed over bytes to the write cursor.\n                    {\n                        let forwardTailPointer := tailPointer\n                        let size := mul(wordsRemaining, 4)\n                        cursor := sub(cursor, size)\n                        mstore(writeCursor, mload(cursor))\n                        writeCursor := add(writeCursor, size)\n\n                        // Redefine wordsRemaining to be the number of words\n                        // left to copy.\n                        wordsRemaining := sub(wordsTotal, wordsRemaining)\n                        // Move over whole tail items.\n                        for {} gt(wordsRemaining, 7) {} {\n                            wordsRemaining := sub(wordsRemaining, 7)\n                            // Follow the forward tail pointer.\n                            forwardTailPointer := and(shr(0x10, mload(forwardTailPointer)), 0xFFFF)\n                            mstore(writeCursor, mload(forwardTailPointer))\n                            writeCursor := add(writeCursor, 0x1c)\n                        }\n                        // Move over the remaining words in the tail item.\n                        if gt(wordsRemaining, 0) {\n                            forwardTailPointer := and(shr(0x10, mload(forwardTailPointer)), 0xFFFF)\n                            mstore(writeCursor, mload(forwardTailPointer))\n                            writeCursor := add(writeCursor, mul(wordsRemaining, 4))\n                        }\n                    }\n                }\n                // Store the bytes length in the source.\n                mstore(source, length)\n                // Store the opcodes length and stack tracker in the source\n                // prefix.\n                let prefixWritePointer := add(source, 4)\n                mstore(\n                    prefixWritePointer,\n                    or(\n                        and(mload(prefixWritePointer), not(0xFFFFFFFF)),\n                        or(shl(0x18, sub(div(length, 4), 1)), stackTracker)\n                    )\n                )\n\n                // Round up to the nearest 32 bytes to realign memory.\n                mstore(0x40, and(add(writeCursor, 0x1f), not(0x1f)))\n            }\n\n            //slither-disable-next-line incorrect-shift\n            state.sourcesBuilder =\n                ((offset + 0x10) << 0xf0) | (source << offset) | (sourcesBuilder & ((1 << offset) - 1));\n\n            // Reset source as we're done with this one.\n            state.fsm &= ~FSM_ACTIVE_SOURCE_MASK;\n            state.resetSource();\n        }\n    }\n\n    function buildBytecode(ParseState memory state) internal pure returns (bytes memory bytecode) {\n        unchecked {\n            uint256 sourcesBuilder = state.sourcesBuilder;\n            uint256 offsetEnd = (sourcesBuilder >> 0xf0);\n\n            // Somehow the parser state for the active source was not reset\n            // correctly, or the finalised offset is dangling. This implies that\n            // we are building the overall sources array while still trying to\n            // build one of the individual sources. This is a bug in the parser.\n            uint256 activeSource;\n            {\n                uint256 activeSourcePointer = state.activeSourcePtr;\n                assembly (\"memory-safe\") {\n                    activeSource := mload(activeSourcePointer)\n                }\n            }\n\n            if (activeSource != EMPTY_ACTIVE_SOURCE) {\n                revert DanglingSource();\n            }\n\n            uint256 cursor;\n            uint256 sourcesCount;\n            uint256 sourcesStart;\n            assembly (\"memory-safe\") {\n                cursor := mload(0x40)\n                bytecode := cursor\n                // Move past the bytecode length, we will write this at the end.\n                cursor := add(cursor, 0x20)\n\n                // First byte is the number of sources.\n                sourcesCount := div(offsetEnd, 0x10)\n                mstore8(cursor, sourcesCount)\n                cursor := add(cursor, 1)\n\n                let pointersCursor := cursor\n\n                // Skip past the pointer space. We'll back fill it.\n                // Divide offsetEnd to convert from a bit to a byte shift.\n                cursor := add(cursor, div(offsetEnd, 8))\n                sourcesStart := cursor\n\n                // Write total bytes length into bytecode. We do ths and handle\n                // the allocation in this same assembly block for memory safety\n                // for the compiler optimiser.\n                let sourcesLength := 0\n                let sourcePointers := 0\n                for { let offset := 0 } lt(offset, offsetEnd) { offset := add(offset, 0x10) } {\n                    let currentSourcePointer := and(shr(offset, sourcesBuilder), 0xFFFF)\n                    // add 4 byte prefix to the length of the sources, all as\n                    // bytes.\n                    sourcePointers := or(sourcePointers, shl(sub(0xf0, offset), sourcesLength))\n                    let currentSourceLength := mload(currentSourcePointer)\n\n                    // Put the reference source pointer and length into the\n                    // prefix so that we can use them to copy the actual data\n                    // into the bytecode.\n                    let tmpPrefix := shl(0xe0, or(shl(0x10, currentSourcePointer), currentSourceLength))\n                    mstore(add(sourcesStart, sourcesLength), tmpPrefix)\n                    sourcesLength := add(sourcesLength, currentSourceLength)\n                }\n                mstore(pointersCursor, or(mload(pointersCursor), sourcePointers))\n                mstore(bytecode, add(sourcesLength, sub(sub(sourcesStart, 0x20), bytecode)))\n\n                // Round up to the nearest 32 bytes past cursor to realign and\n                // allocate memory.\n                mstore(0x40, and(add(add(add(0x20, mload(bytecode)), bytecode), 0x1f), not(0x1f)))\n            }\n\n            // Loop over the sources and write them into the bytecode. Perhaps\n            // there is a more efficient way to do this in the future that won't\n            // cause each source to be written twice in memory.\n            for (uint256 i = 0; i < sourcesCount; i++) {\n                Pointer sourcePointer;\n                uint256 length;\n                Pointer targetPointer;\n                assembly (\"memory-safe\") {\n                    let relativePointer := and(mload(add(bytecode, add(3, mul(i, 2)))), 0xFFFF)\n                    targetPointer := add(sourcesStart, relativePointer)\n                    let tmpPrefix := mload(targetPointer)\n                    sourcePointer := add(0x20, shr(0xf0, tmpPrefix))\n                    length := and(shr(0xe0, tmpPrefix), 0xFFFF)\n                }\n                LibMemCpy.unsafeCopyBytesTo(sourcePointer, targetPointer, length);\n            }\n        }\n    }\n\n    function buildConstants(ParseState memory state) internal pure returns (uint256[] memory constants) {\n        uint256 constantsHeight = state.constantsBuilder & 0xFFFF;\n        uint256 tailPtr = state.constantsBuilder >> 0x10;\n\n        assembly (\"memory-safe\") {\n            let cursor := mload(0x40)\n            constants := cursor\n            mstore(cursor, constantsHeight)\n            let end := cursor\n            // Move the cursor to the end of the array. Write in reverse order\n            // of the linked list traversal so that the constants are built\n            // according to the stable indexes in the source from the linked\n            // list base.\n            cursor := add(cursor, mul(constantsHeight, 0x20))\n            // Allocate one word past the cursor. This will be just after the\n            // length if the constants array is empty. Otherwise it will be\n            // just after the last constant.\n            mstore(0x40, add(cursor, 0x20))\n            // It MUST be equivalent to say that the cursor is above the end,\n            // and that we are following tail pointers until they point to 0,\n            // and that the cursor is moving as far as the constants height.\n            // This is ensured by the fact that the constants height is only\n            // incremented when a new constant is added to the linked list.\n            for {} gt(cursor, end) {\n                // Next item in the linked list.\n                cursor := sub(cursor, 0x20)\n                // tail pointer in tail keys is the low 16 bits under the\n                // fingerprint, which is different from the tail pointer in\n                // the constants builder, where it sits above the constants\n                // height.\n                tailPtr := and(mload(tailPtr), 0xFFFF)\n            } {\n                // Store the values not the keys.\n                mstore(cursor, mload(add(tailPtr, 0x20)))\n            }\n        }\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/src/lib/bytecode/LibBytecode.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.19;\n\nimport {LibPointer, Pointer} from \"rain.solmem/lib/LibPointer.sol\";\nimport {LibBytes} from \"rain.solmem/lib/LibBytes.sol\";\nimport {LibMemCpy} from \"rain.solmem/lib/LibMemCpy.sol\";\nimport {\n    StackSizingsNotMonotonic,\n    TruncatedSource,\n    UnexpectedTrailingOffsetBytes,\n    TruncatedHeader,\n    TruncatedHeaderOffsets,\n    UnexpectedSources,\n    SourceIndexOutOfBounds\n} from \"../../error/ErrBytecode.sol\";\n\n/// @title LibBytecode\n/// @notice A library for inspecting the bytecode of an expression. Largely\n/// focused on reading the source headers rather than the opcodes themselves.\n/// Designed to be efficient enough to be used in the interpreter directly.\n/// As such, it is not particularly safe, notably it always assumes that the\n/// headers are not lying about the structure and runtime behaviour of the\n/// bytecode. This is by design as it allows much more simple, efficient and\n/// decoupled implementation of authoring/parsing logic, which makes the author\n/// of an expression responsible for producing well formed bytecode, such as\n/// balanced LHS/RHS stacks. The deployment integrity checks are responsible for\n/// checking that the headers match the structure and behaviour of the bytecode.\nlibrary LibBytecode {\n    using LibPointer for Pointer;\n    using LibBytes for bytes;\n    using LibMemCpy for Pointer;\n\n    /// The number of sources in the bytecode.\n    /// If the bytecode is empty, returns 0.\n    /// Otherwise, returns the first byte of the bytecode, which is the number\n    /// of sources.\n    /// Implies that 0x and 0x00 are equivalent, both having 0 sources. For this\n    /// reason, contracts that handle bytecode MUST NOT rely on simple data\n    /// length checks to determine if the bytecode is empty or not.\n    /// DOES NOT check the integrity or even existence of the sources.\n    /// @param bytecode The bytecode to inspect.\n    /// @return count The number of sources in the bytecode.\n    function sourceCount(bytes memory bytecode) internal pure returns (uint256 count) {\n        if (bytecode.length == 0) {\n            return 0;\n        }\n        assembly (\"memory-safe\") {\n            // The first byte of rain bytecode is the count of how many sources\n            // there are.\n            count := byte(0, mload(add(bytecode, 0x20)))\n        }\n    }\n\n    /// Checks the structural integrity of the bytecode from the perspective of\n    /// potential out of bounds reads. Will revert if the bytecode is not\n    /// well-formed. This check MUST be done BEFORE any attempts at per-opcode\n    /// integrity checks, as the per-opcode checks assume that the headers define\n    /// valid regions in memory to iterate over.\n    ///\n    /// Checks:\n    /// - The offsets are populated according to the source count.\n    /// - The offsets point to positions within the bytecode `bytes`.\n    /// - There exists at least the 4 byte header for each source at the offset,\n    ///   within the bounds of the bytecode `bytes`.\n    /// - The number of opcodes specified in the header of each source locates\n    ///   the end of the source exactly at either the offset of the next source\n    ///   or the end of the bytecode `bytes`.\n    function checkNoOOBPointers(bytes memory bytecode) internal pure {\n        unchecked {\n            uint256 count = sourceCount(bytecode);\n            // The common case is that there are more than 0 sources.\n            if (count > 0) {\n                uint256 sourcesRelativeStart = 1 + count * 2;\n                if (sourcesRelativeStart > bytecode.length) {\n                    revert TruncatedHeaderOffsets(bytecode);\n                }\n                uint256 sourcesStart;\n                assembly (\"memory-safe\") {\n                    sourcesStart := add(bytecode, add(0x20, sourcesRelativeStart))\n                }\n\n                // Start at the end of the bytecode and work backwards. Find the\n                // last unchecked relative offset, follow it, read the opcode\n                // count from the header, and check that ends at the end cursor.\n                // Set the end cursor to the relative offset then repeat until\n                // there are no more unchecked relative offsets. The endCursor\n                // as a relative offset must be 0 at the end of this process\n                // (i.e. the first relative offset is always 0).\n                uint256 endCursor;\n                assembly (\"memory-safe\") {\n                    endCursor := add(bytecode, add(0x20, mload(bytecode)))\n                }\n                // This cursor points at the 2 byte relative offset that we need\n                // to check next.\n                uint256 uncheckedOffsetCursor;\n                uint256 end;\n                assembly (\"memory-safe\") {\n                    uncheckedOffsetCursor := add(bytecode, add(0x21, mul(sub(count, 1), 2)))\n                    end := add(bytecode, 0x21)\n                }\n\n                while (uncheckedOffsetCursor >= end) {\n                    // Read the relative offset from the bytecode.\n                    uint256 relativeOffset;\n                    assembly (\"memory-safe\") {\n                        relativeOffset := shr(0xF0, mload(uncheckedOffsetCursor))\n                    }\n                    uint256 absoluteOffset = sourcesStart + relativeOffset;\n\n                    // Check that the 4 byte header is within the upper bound\n                    // established by the end cursor before attempting to read\n                    // from it.\n                    uint256 headerEnd = absoluteOffset + 4;\n                    if (headerEnd > endCursor) {\n                        revert TruncatedHeader(bytecode);\n                    }\n\n                    // The ops count is the first byte of the header.\n                    uint256 opsCount;\n                    {\n                        // The stack allocation, inputs, and outputs are the next\n                        // 3 bytes of the header. We can't know exactly what they\n                        // need to be according to the opcodes without checking\n                        // every opcode implementation, but we can check that\n                        // they satisfy the invariant\n                        // `inputs <= outputs <= stackAllocation`.\n                        // Note that the outputs may include the inputs, as the\n                        // outputs is merely the final stack size.\n                        uint256 stackAllocation;\n                        uint256 inputs;\n                        uint256 outputs;\n                        assembly (\"memory-safe\") {\n                            let data := mload(absoluteOffset)\n                            opsCount := byte(0, data)\n                            stackAllocation := byte(1, data)\n                            inputs := byte(2, data)\n                            outputs := byte(3, data)\n                        }\n\n                        if (inputs > outputs || outputs > stackAllocation) {\n                            revert StackSizingsNotMonotonic(bytecode, relativeOffset);\n                        }\n                    }\n\n                    // The ops count is the number of 4 byte opcodes in the\n                    // source. Check that the end of the source is at the end\n                    // cursor.\n                    uint256 sourceEnd = headerEnd + opsCount * 4;\n                    if (sourceEnd != endCursor) {\n                        revert TruncatedSource(bytecode);\n                    }\n\n                    // Move the end cursor to the start of the header.\n                    endCursor = absoluteOffset;\n                    // Move the unchecked offset cursor to the previous offset.\n                    uncheckedOffsetCursor -= 2;\n                }\n\n                // If the end cursor is not pointing at the absolute start of the\n                // sources, then somehow the bytecode has malformed data between\n                // the offsets and the sources.\n                if (endCursor != sourcesStart) {\n                    revert UnexpectedTrailingOffsetBytes(bytecode);\n                }\n            } else {\n                // If there are no sources the bytecode is either 0 length or a\n                // single 0 byte, which we already implicity checked by reaching\n                // this code path. Ensure the bytecode has no trailing bytes.\n                if (bytecode.length > 1) {\n                    revert UnexpectedSources(bytecode);\n                }\n            }\n        }\n    }\n\n    /// The relative byte offset of a source in the bytecode.\n    /// This is the offset from the start of the first source header, which is\n    /// after the source count byte and the source offsets.\n    /// This function DOES NOT check that the relative offset is within the\n    /// bounds of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE\n    /// attempting to traverse the bytecode, otherwise the relative offset MAY\n    /// point to memory outside the bytecode `bytes`.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return offset The relative byte offset of the source in the bytecode.\n    function sourceRelativeOffset(bytes memory bytecode, uint256 sourceIndex) internal pure returns (uint256 offset) {\n        // If the source index requested is out of bounds, revert.\n        if (sourceIndex >= sourceCount(bytecode)) {\n            revert SourceIndexOutOfBounds(bytecode, sourceIndex);\n        }\n        assembly (\"memory-safe\") {\n            // After the first byte, all the relative offset pointers are\n            // stored sequentially as 16 bit values.\n            offset := and(mload(add(add(bytecode, 3), mul(sourceIndex, 2))), 0xFFFF)\n        }\n    }\n\n    /// The absolute byte pointer of a source in the bytecode. Points to the\n    /// header of the source, NOT the first opcode.\n    /// This function DOES NOT check that the source index is within the bounds\n    /// of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE attempting to\n    /// traverse the bytecode, otherwise the relative offset MAY point to memory\n    /// outside the bytecode `bytes`.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return pointer The absolute byte pointer of the source in the bytecode.\n    function sourcePointer(bytes memory bytecode, uint256 sourceIndex) internal pure returns (Pointer pointer) {\n        unchecked {\n            uint256 sourcesStartOffset = 1 + sourceCount(bytecode) * 2;\n            uint256 offset = sourceRelativeOffset(bytecode, sourceIndex);\n            assembly (\"memory-safe\") {\n                pointer := add(add(add(bytecode, 0x20), sourcesStartOffset), offset)\n            }\n        }\n    }\n\n    /// The number of opcodes in a source.\n    /// This function DOES NOT check that the source index is within the bounds\n    /// of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE attempting to\n    /// traverse the bytecode, otherwise the relative offset MAY point to memory\n    /// outside the bytecode `bytes`.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return opsCount The number of opcodes in the source.\n    function sourceOpsCount(bytes memory bytecode, uint256 sourceIndex) internal pure returns (uint256 opsCount) {\n        unchecked {\n            Pointer pointer = sourcePointer(bytecode, sourceIndex);\n            assembly (\"memory-safe\") {\n                opsCount := byte(0, mload(pointer))\n            }\n        }\n    }\n\n    /// The number of stack slots allocated by a source. This is the number of\n    /// 32 byte words that MUST be allocated for the stack for the given source\n    /// index to avoid memory corruption when executing the source.\n    /// This function DOES NOT check that the source index is within the bounds\n    /// of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE attempting to\n    /// traverse the bytecode, otherwise the relative offset MAY point to memory\n    /// outside the bytecode `bytes`.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return allocation The number of stack slots allocated by the source.\n    function sourceStackAllocation(bytes memory bytecode, uint256 sourceIndex)\n        internal\n        pure\n        returns (uint256 allocation)\n    {\n        unchecked {\n            Pointer pointer = sourcePointer(bytecode, sourceIndex);\n            assembly (\"memory-safe\") {\n                allocation := byte(1, mload(pointer))\n            }\n        }\n    }\n\n    /// The number of inputs and outputs of a source.\n    /// This function DOES NOT check that the source index is within the bounds\n    /// of the bytecode. Callers MUST `checkNoOOBPointers` BEFORE attempting to\n    /// traverse the bytecode, otherwise the relative offset MAY point to memory\n    /// outside the bytecode `bytes`.\n    /// Note that both the inputs and outputs are always returned togther, this\n    /// is because the caller SHOULD be checking both together whenever using\n    /// some bytecode. Returning two values is more efficient than two separate\n    /// function calls.\n    /// @param bytecode The bytecode to inspect.\n    /// @param sourceIndex The index of the source to inspect.\n    /// @return inputs The number of inputs of the source.\n    /// @return outputs The number of outputs of the source.\n    function sourceInputsOutputsLength(bytes memory bytecode, uint256 sourceIndex)\n        internal\n        pure\n        returns (uint256 inputs, uint256 outputs)\n    {\n        unchecked {\n            Pointer pointer = sourcePointer(bytecode, sourceIndex);\n            assembly (\"memory-safe\") {\n                let data := mload(pointer)\n                inputs := byte(2, data)\n                outputs := byte(3, data)\n            }\n        }\n    }\n\n    /// Backwards compatibility with the old way of representing sources.\n    /// Requires allocation and copying so it isn't particularly efficient, but\n    /// allows us to use the new bytecode format with old interpreter code. Not\n    /// recommended for production code but useful for testing.\n    function bytecodeToSources(bytes memory bytecode) internal pure returns (bytes[] memory) {\n        unchecked {\n            uint256 count = sourceCount(bytecode);\n            bytes[] memory sources = new bytes[](count);\n            for (uint256 i = 0; i < count; i++) {\n                // Skip over the prefix 4 bytes.\n                Pointer pointer = sourcePointer(bytecode, i).unsafeAddBytes(4);\n                uint256 length = sourceOpsCount(bytecode, i) * 4;\n                bytes memory source = new bytes(length);\n                pointer.unsafeCopyBytesTo(source.dataPointer(), length);\n                // Move the opcode index one byte for each opcode, into the input\n                // position, as legacly sources did not have input bytes.\n                assembly (\"memory-safe\") {\n                    for {\n                        let cursor := add(source, 0x20)\n                        let end := add(cursor, length)\n                    } lt(cursor, end) { cursor := add(cursor, 4) } {\n                        mstore8(add(cursor, 1), byte(0, mload(cursor)))\n                        mstore8(cursor, 0)\n                    }\n                }\n                sources[i] = source;\n            }\n            return sources;\n        }\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/error/ErrParse.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @dev Workaround for https://github.com/foundry-rs/foundry/issues/6572\ncontract ErrParse {}\n\n/// Thrown when parsing a source string and an operand opening `<` paren is found\n/// somewhere that we don't expect it or can't handle it.\nerror UnexpectedOperand();\n\n/// Thrown when there are more operand values in the operand than the handler\n/// is expecting.\nerror UnexpectedOperandValue();\n\n/// Thrown when parsing an operand and some required component of the operand is\n/// not found in the source string.\nerror ExpectedOperand();\n\n/// Thrown when parsing an operand and the literal in the source string is too\n/// large to fit in the bits allocated for it in the operand.\nerror OperandOverflow();\n\n/// Thrown when the number of values encountered in a single operand parsing is\n/// longer than the memory allocated to hold them.\n/// @param offset The offset in the source string where the error occurred.\nerror OperandValuesOverflow(uint256 offset);\n\n/// Thrown when parsing an operand and the closing `>` paren is not found.\n/// @param offset The offset in the source string where the error occurred.\nerror UnclosedOperand(uint256 offset);\n\n/// The parser tried to bound an unsupported literal that we have no type for.\nerror UnsupportedLiteralType(uint256 offset);\n\n/// Encountered a string literal that is larger than supported.\nerror StringTooLong(uint256 offset);\n\n/// Encountered a string that does not have a valid end, e.g. we found some char\n/// that was not printable ASCII and had to stop.\nerror UnclosedStringLiteral(uint256 offset);\n\n/// Encountered a literal that is larger than supported.\nerror HexLiteralOverflow(uint256 offset);\n\n/// Encountered a zero length hex literal.\nerror ZeroLengthHexLiteral(uint256 offset);\n\n/// Encountered an odd sized hex literal.\nerror OddLengthHexLiteral(uint256 offset);\n\n/// Encountered a hex literal with an invalid character.\nerror MalformedHexLiteral(uint256 offset);\n\n/// Encountered a decimal literal that is larger than supported.\nerror DecimalLiteralOverflow(uint256 offset);\n\n/// Encountered a decimal literal with an exponent that has too many or no\n/// digits.\nerror MalformedExponentDigits(uint256 offset);\n\n/// Encountered a zero length decimal literal.\nerror ZeroLengthDecimal(uint256 offset);\n\n/// The expression does not finish with a semicolon (EOF).\nerror MissingFinalSemi(uint256 offset);\n\n/// Enountered an unexpected character on the LHS.\nerror UnexpectedLHSChar(uint256 offset);\n\n/// Encountered an unexpected character on the RHS.\nerror UnexpectedRHSChar(uint256 offset);\n\n/// More specific version of UnexpectedRHSChar where we specifically expected\n/// a left paren but got some other char.\nerror ExpectedLeftParen(uint256 offset);\n\n/// Encountered a right paren without a matching left paren.\nerror UnexpectedRightParen(uint256 offset);\n\n/// Encountered an unclosed left paren.\nerror UnclosedLeftParen(uint256 offset);\n\n/// Encountered a comment outside the interstitial space between lines.\nerror UnexpectedComment(uint256 offset);\n\n/// Encountered a comment that never ends.\nerror UnclosedComment(uint256 offset);\n\n/// Encountered a comment start sequence that is malformed.\nerror MalformedCommentStart(uint256 offset);\n\n/// @dev Thrown when a stack name is duplicated. Shadowing in all forms is\n/// disallowed in Rainlang.\nerror DuplicateLHSItem(uint256 errorOffset);\n\n/// Encountered too many LHS items.\nerror ExcessLHSItems(uint256 offset);\n\n/// Encountered inputs where they can't be handled.\nerror NotAcceptingInputs(uint256 offset);\n\n/// Encountered too many RHS items.\nerror ExcessRHSItems(uint256 offset);\n\n/// Encountered a word that is longer than 32 bytes.\nerror WordSize(string word);\n\n/// Parsed a word that is not in the meta.\nerror UnknownWord();\n\n/// The parser exceeded the maximum number of sources that it can build.\nerror MaxSources();\n\n/// The parser encountered a dangling source. This is a bug in the parser.\nerror DanglingSource();\n\n/// The parser moved past the end of the data.\nerror ParserOutOfBounds();\n\n/// The parser encountered a stack deeper than it can process in the memory\n/// region allocated for stack names.\nerror ParseStackOverflow();\n\n/// The parser encountered a stack underflow.\nerror ParseStackUnderflow();\n\n/// The parser encountered a paren group deeper than it can process in the\n/// memory region allocated for paren tracking.\nerror ParenOverflow();\n\n/// The parser did not find any whitespace after the pragma keyword.\nerror NoWhitespaceAfterUsingWordsFrom(uint256 offset);\n\n/// The parser encountered a literal that it cannot use as a sub parser.\nerror InvalidSubParser(uint256 offset);\n\n/// The parser encountered an unclosed sub parsed literal.\nerror UnclosedSubParseableLiteral(uint256 offset);\n\n/// The parser encountered a sub parseable literal with a missing dispatch.\nerror SubParseableMissingDispatch(uint256 offset);\n\n/// The sub parser returned some bytecode that the main parser could not\n/// understand.\nerror BadSubParserResult(bytes bytecode);\n\n/// Thrown when there are more than 16 inputs or outputs for a given opcode.\nerror OpcodeIOOverflow(uint256 offset);\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/extern/LibExtern.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IInterpreterV2, Operand} from \"rain.interpreter.interface/interface/IInterpreterV2.sol\";\nimport {\n    IInterpreterExternV3,\n    ExternDispatch,\n    EncodedExternDispatch\n} from \"rain.interpreter.interface/interface/IInterpreterExternV3.sol\";\n\n/// @title LibExtern\n/// Defines and implements an encoding and decoding scheme for the data that\n/// controls the behaviour of externs.\nlibrary LibExtern {\n    /// Converts an opcode and operand pair into a single 32-byte word.\n    /// The encoding scheme is:\n    /// - bits [0,16): the operand\n    /// - bits [16,32): the opcode\n    /// IMPORTANT: The encoding process does not check that either the opcode or\n    /// operand fit within 16 bits. This is the responsibility of the caller.\n    function encodeExternDispatch(uint256 opcode, Operand operand) internal pure returns (ExternDispatch) {\n        return ExternDispatch.wrap(opcode << 0x10 | Operand.unwrap(operand));\n    }\n\n    /// Inverse of `encodeExternDispatch`.\n    function decodeExternDispatch(ExternDispatch dispatch) internal pure returns (uint256, Operand) {\n        return (ExternDispatch.unwrap(dispatch) >> 0x10, Operand.wrap(uint16(ExternDispatch.unwrap(dispatch))));\n    }\n\n    /// Encodes an extern address and dispatch pair into a single 32-byte word.\n    /// This is the full data required to actually call an extern contract.\n    /// The encoding scheme is:\n    /// - bits [0,160): the address of the extern contract\n    /// - bits [160,176): the dispatch operand\n    /// - bits [176,192): the dispatch opcode\n    /// Note that the high bits are implied by a correctly encoded\n    /// `ExternDispatch`. Use `encodeExternDispatch` to ensure this.\n    /// IMPORTANT: The encoding process does not check that any of the values\n    /// fit within their respective bit ranges. This is the responsibility of\n    /// the caller.\n    function encodeExternCall(IInterpreterExternV3 extern, ExternDispatch dispatch)\n        internal\n        pure\n        returns (EncodedExternDispatch)\n    {\n        return EncodedExternDispatch.wrap(uint256(uint160(address(extern))) | ExternDispatch.unwrap(dispatch) << 160);\n    }\n\n    /// Inverse of `encodeExternCall`.\n    function decodeExternCall(EncodedExternDispatch dispatch)\n        internal\n        pure\n        returns (IInterpreterExternV3, ExternDispatch)\n    {\n        return (\n            IInterpreterExternV3(address(uint160(EncodedExternDispatch.unwrap(dispatch)))),\n            ExternDispatch.wrap(EncodedExternDispatch.unwrap(dispatch) >> 160)\n        );\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibMemCpy.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./LibPointer.sol\";\n\nlibrary LibMemCpy {\n    /// Copy an arbitrary number of bytes from one location in memory to another.\n    /// As we can only read/write bytes in 32 byte chunks we first have to loop\n    /// over 32 byte values to copy then handle any unaligned remaining data. The\n    /// remaining data will be appropriately masked with the existing data in the\n    /// final chunk so as to not write past the desired length. Note that the\n    /// final unaligned write will be more gas intensive than the prior aligned\n    /// writes. The writes are completely unsafe, the caller MUST ensure that\n    /// sufficient memory is allocated and reading/writing the requested number\n    /// of bytes from/to the requested locations WILL NOT corrupt memory in the\n    /// opinion of solidity or other subsequent read/write operations.\n    /// @param sourceCursor The starting pointer to read from.\n    /// @param targetCursor The starting pointer to write to.\n    /// @param length The number of bytes to read/write.\n    function unsafeCopyBytesTo(Pointer sourceCursor, Pointer targetCursor, uint256 length) internal pure {\n        assembly (\"memory-safe\") {\n            // Precalculating the end here, rather than tracking the remaining\n            // length each iteration uses relatively more gas for less data, but\n            // scales better for more data. Copying 1-2 words is ~30 gas more\n            // expensive but copying 3+ words favours a precalculated end point\n            // increasingly for more data.\n            let m := mod(length, 0x20)\n            let end := add(sourceCursor, sub(length, m))\n            for {} lt(sourceCursor, end) {\n                sourceCursor := add(sourceCursor, 0x20)\n                targetCursor := add(targetCursor, 0x20)\n            } { mstore(targetCursor, mload(sourceCursor)) }\n\n            if iszero(iszero(m)) {\n                //slither-disable-next-line incorrect-shift\n                let mask_ := shr(mul(m, 8), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)\n                // preserve existing bytes\n                mstore(\n                    targetCursor,\n                    or(\n                        // input\n                        and(mload(sourceCursor), not(mask_)),\n                        and(mload(targetCursor), mask_)\n                    )\n                )\n            }\n        }\n    }\n\n    /// Copies `length` `uint256` values starting from `source` to `target`\n    /// with NO attempt to check that this is safe to do so. The caller MUST\n    /// ensure that there exists allocated memory at `target` in which it is\n    /// safe and appropriate to copy `length * 32` bytes to. Anything that was\n    /// already written to memory at `[target:target+(length * 32 bytes)]`\n    /// will be overwritten.\n    /// There is no return value as memory is modified directly.\n    /// @param source The starting position in memory that data will be copied\n    /// from.\n    /// @param target The starting position in memory that data will be copied\n    /// to.\n    /// @param length The number of 32 byte (i.e. `uint256`) words that will\n    /// be copied.\n    function unsafeCopyWordsTo(Pointer source, Pointer target, uint256 length) internal pure {\n        assembly (\"memory-safe\") {\n            for { let end_ := add(source, mul(0x20, length)) } lt(source, end_) {\n                source := add(source, 0x20)\n                target := add(target, 0x20)\n            } { mstore(target, mload(source)) }\n        }\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParseError.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {ParseState} from \"./LibParseState.sol\";\n\nlibrary LibParseError {\n    function parseErrorOffset(ParseState memory state, uint256 cursor) internal pure returns (uint256 offset) {\n        bytes memory data = state.data;\n        assembly (\"memory-safe\") {\n            offset := sub(cursor, add(data, 0x20))\n        }\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/bitwise/LibCtPop.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// @dev 010101... for ctpop\nuint256 constant CTPOP_M1 = 0x5555555555555555555555555555555555555555555555555555555555555555;\n/// @dev 00110011.. for ctpop\nuint256 constant CTPOP_M2 = 0x3333333333333333333333333333333333333333333333333333333333333333;\n/// @dev 4 bits alternating for ctpop\nuint256 constant CTPOP_M4 = 0x0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F;\n/// @dev 8 bits alternating for ctpop\nuint256 constant CTPOP_M8 = 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF;\n/// @dev 16 bits alternating for ctpop\nuint256 constant CTPOP_M16 = 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF;\n/// @dev 32 bits alternating for ctpop\nuint256 constant CTPOP_M32 = 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF;\n/// @dev 64 bits alternating for ctpop\nuint256 constant CTPOP_M64 = 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF;\n/// @dev 128 bits alternating for ctpop\nuint256 constant CTPOP_M128 = 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;\n/// @dev 1 bytes for ctpop\nuint256 constant CTPOP_H01 = 0x0101010101010101010101010101010101010101010101010101010101010101;\n\nlibrary LibCtPop {\n    /// Optimised version of ctpop.\n    /// https://en.wikipedia.org/wiki/Hamming_weight\n    function ctpop(uint256 x) internal pure returns (uint256) {\n        // This edge case is not handled by the algorithm below.\n        if (x == type(uint256).max) {\n            return 256;\n        }\n        unchecked {\n            x -= (x >> 1) & CTPOP_M1;\n            x = (x & CTPOP_M2) + ((x >> 2) & CTPOP_M2);\n            x = (x + (x >> 4)) & CTPOP_M4;\n            x = (x * CTPOP_H01) >> 248;\n        }\n        return x;\n    }\n\n    /// This is the slowest possible implementation of ctpop. It is used to\n    /// verify the correctness of the optimized implementation in LibCtPop.\n    /// It should be obviously correct by visual inspection, referencing the\n    /// wikipedia article.\n    /// https://en.wikipedia.org/wiki/Hamming_weight\n    function ctpopSlow(uint256 x) internal pure returns (uint256) {\n        unchecked {\n            x = (x & CTPOP_M1) + ((x >> 1) & CTPOP_M1);\n            x = (x & CTPOP_M2) + ((x >> 2) & CTPOP_M2);\n            x = (x & CTPOP_M4) + ((x >> 4) & CTPOP_M4);\n            x = (x & CTPOP_M8) + ((x >> 8) & CTPOP_M8);\n            x = (x & CTPOP_M16) + ((x >> 16) & CTPOP_M16);\n            x = (x & CTPOP_M32) + ((x >> 32) & CTPOP_M32);\n            x = (x & CTPOP_M64) + ((x >> 64) & CTPOP_M64);\n            x = (x & CTPOP_M128) + ((x >> 128) & CTPOP_M128);\n        }\n        return x;\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/literal/LibParseLiteral.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {\n    CMASK_E_NOTATION,\n    CMASK_HEX,\n    CMASK_LOWER_ALPHA_A_F,\n    CMASK_NUMERIC_0_9,\n    CMASK_STRING_LITERAL_HEAD,\n    CMASK_UPPER_ALPHA_A_F,\n    CMASK_LITERAL_HEX_DISPATCH,\n    CMASK_NUMERIC_LITERAL_HEAD,\n    CMASK_SUB_PARSEABLE_LITERAL_HEAD,\n    CMASK_SUB_PARSEABLE_LITERAL_END,\n    CMASK_WHITESPACE\n} from \"../LibParseCMask.sol\";\nimport {LibParse} from \"../LibParse.sol\";\n\nimport {\n    DecimalLiteralOverflow,\n    HexLiteralOverflow,\n    MalformedExponentDigits,\n    MalformedHexLiteral,\n    OddLengthHexLiteral,\n    ZeroLengthDecimal,\n    ZeroLengthHexLiteral,\n    UnsupportedLiteralType,\n    UnclosedSubParseableLiteral\n} from \"../../../error/ErrParse.sol\";\nimport {ParseState} from \"../LibParseState.sol\";\nimport {LibParseError} from \"../LibParseError.sol\";\nimport {LibParseInterstitial} from \"../LibParseInterstitial.sol\";\nimport {LibSubParse} from \"../LibSubParse.sol\";\n\nuint256 constant LITERAL_PARSERS_LENGTH = 4;\n\nuint256 constant LITERAL_PARSER_INDEX_HEX = 0;\nuint256 constant LITERAL_PARSER_INDEX_DECIMAL = 1;\nuint256 constant LITERAL_PARSER_INDEX_STRING = 2;\nuint256 constant LITERAL_PARSER_INDEX_SUB_PARSE = 3;\n\nlibrary LibParseLiteral {\n    using LibParseLiteral for ParseState;\n    using LibParseError for ParseState;\n    using LibParseLiteral for ParseState;\n    using LibParseInterstitial for ParseState;\n    using LibSubParse for ParseState;\n\n    function selectLiteralParserByIndex(ParseState memory state, uint256 index)\n        internal\n        pure\n        returns (function(ParseState memory, uint256, uint256) pure returns (uint256, uint256))\n    {\n        bytes memory literalParsers = state.literalParsers;\n        function(ParseState memory, uint256, uint256) pure returns (uint256, uint256) parser;\n        // This is NOT bounds checked because the indexes are all expected to\n        // be provided by the parser itself and not user input.\n        assembly (\"memory-safe\") {\n            parser := and(mload(add(literalParsers, add(2, mul(index, 2)))), 0xFFFF)\n        }\n        return parser;\n    }\n\n    function parseLiteral(ParseState memory state, uint256 cursor, uint256 end)\n        internal\n        pure\n        returns (uint256, uint256)\n    {\n        (bool success, uint256 newCursor, uint256 value) = tryParseLiteral(state, cursor, end);\n        if (success) {\n            return (newCursor, value);\n        } else {\n            revert UnsupportedLiteralType(state.parseErrorOffset(cursor));\n        }\n    }\n\n    function tryParseLiteral(ParseState memory state, uint256 cursor, uint256 end)\n        internal\n        pure\n        returns (bool, uint256, uint256)\n    {\n        uint256 index;\n        {\n            uint256 word;\n            uint256 head;\n            assembly (\"memory-safe\") {\n                word := mload(cursor)\n                //slither-disable-next-line incorrect-shift\n                head := shl(byte(0, word), 1)\n            }\n\n            // Figure out the literal type and dispatch to the correct parser.\n            // Probably a numeric, most things are.\n            if ((head & CMASK_NUMERIC_LITERAL_HEAD) != 0) {\n                uint256 disambiguate;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    disambiguate := shl(byte(1, word), 1)\n                }\n                // Hexadecimal literal dispatch is 0x. We can't accidentally\n                // match x0 because we already checked that the head is 0-9.\n                if ((head | disambiguate) == CMASK_LITERAL_HEX_DISPATCH) {\n                    index = LITERAL_PARSER_INDEX_HEX;\n                } else {\n                    index = LITERAL_PARSER_INDEX_DECIMAL;\n                }\n            }\n            // Could be a lil' string.\n            else if ((head & CMASK_STRING_LITERAL_HEAD) != 0) {\n                index = LITERAL_PARSER_INDEX_STRING;\n            }\n            // Or a sub parseable something.\n            else if ((head & CMASK_SUB_PARSEABLE_LITERAL_HEAD) != 0) {\n                index = LITERAL_PARSER_INDEX_SUB_PARSE;\n            }\n            // We don't know what this is.\n            else {\n                return (false, cursor, 0);\n            }\n        }\n        uint256 value;\n        (cursor, value) = state.selectLiteralParserByIndex(index)(state, cursor, end);\n        return (true, cursor, value);\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParseStackName.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {ParseState} from \"./LibParseState.sol\";\n\nlibrary LibParseStackName {\n    /// Push a word onto the stack name stack.\n    /// @return exists Whether the word already existed.\n    /// @return index The new index after the word was pushed. Will be unchanged\n    /// if the word already existed.\n    function pushStackName(ParseState memory state, bytes32 word) internal pure returns (bool exists, uint256 index) {\n        unchecked {\n            (exists, index) = stackNameIndex(state, word);\n            if (!exists) {\n                uint256 fingerprint;\n                uint256 ptr;\n                uint256 oldStackNames = state.stackNames;\n                assembly (\"memory-safe\") {\n                    ptr := mload(0x40)\n                    mstore(ptr, word)\n                    fingerprint := and(keccak256(ptr, 0x20), not(0xFFFFFFFF))\n                    mstore(ptr, oldStackNames)\n                    mstore(0x40, add(ptr, 0x20))\n                }\n                // Add the start of line height to the LHS line parse count.\n                uint256 stackLHSIndex = state.topLevel1 & 0xFF;\n                state.stackNames = fingerprint | (stackLHSIndex << 0x10) | ptr;\n                index = stackLHSIndex + 1;\n            }\n        }\n    }\n\n    /// Retrieve the index of a previously pushed stack name.\n    function stackNameIndex(ParseState memory state, bytes32 word) internal pure returns (bool exists, uint256 index) {\n        uint256 fingerprint;\n        uint256 stackNames = state.stackNames;\n        uint256 stackNameBloom = state.stackNameBloom;\n        uint256 bloom;\n        assembly (\"memory-safe\") {\n            mstore(0, word)\n            fingerprint := shr(0x20, keccak256(0, 0x20))\n            //slither-disable-next-line incorrect-shift\n            bloom := shl(and(fingerprint, 0xFF), 1)\n\n            // If the bloom matches then maybe the stack name is in the stack.\n            if and(bloom, stackNameBloom) {\n                for { let ptr := and(stackNames, 0xFFFF) } iszero(iszero(ptr)) {\n                    stackNames := mload(ptr)\n                    ptr := and(stackNames, 0xFFFF)\n                } {\n                    if eq(fingerprint, shr(0x20, stackNames)) {\n                        exists := true\n                        index := and(shr(0x10, stackNames), 0xFFFF)\n                        break\n                    }\n                }\n            }\n        }\n        state.stackNameBloom = bloom | stackNameBloom;\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParsePragma.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {LibParseState, ParseState} from \"./LibParseState.sol\";\nimport {CMASK_WHITESPACE, CMASK_LITERAL_HEX_DISPATCH_START} from \"./LibParseCMask.sol\";\nimport {NoWhitespaceAfterUsingWordsFrom} from \"../../error/ErrParse.sol\";\nimport {LibParseError} from \"./LibParseError.sol\";\nimport {LibParseInterstitial} from \"./LibParseInterstitial.sol\";\nimport {LibParseLiteral} from \"./literal/LibParseLiteral.sol\";\n\nbytes constant PRAGMA_KEYWORD_BYTES = bytes(\"using-words-from\");\nbytes32 constant PRAGMA_KEYWORD_BYTES32 = bytes32(PRAGMA_KEYWORD_BYTES);\nuint256 constant PRAGMA_KEYWORD_BYTES_LENGTH = 16;\nbytes32 constant PRAGMA_KEYWORD_MASK = bytes32(~((1 << (32 - PRAGMA_KEYWORD_BYTES_LENGTH) * 8) - 1));\n\nlibrary LibParsePragma {\n    using LibParseError for ParseState;\n    using LibParseInterstitial for ParseState;\n    using LibParseLiteral for ParseState;\n    using LibParseState for ParseState;\n\n    function parsePragma(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) {\n        unchecked {\n            // Not-pragma guard.\n            {\n                // There is a pragma if the cursor is pointing exactly at the bytes of\n                // the pragma.\n                bytes32 maybePragma;\n                assembly (\"memory-safe\") {\n                    maybePragma := mload(cursor)\n                }\n                // Bail without modifying the cursor if there's no pragma.\n                if (maybePragma & PRAGMA_KEYWORD_MASK != PRAGMA_KEYWORD_BYTES32) {\n                    return cursor;\n                }\n            }\n\n            {\n                // Move past the pragma keyword.\n                cursor += PRAGMA_KEYWORD_BYTES_LENGTH;\n\n                // Need at least one whitespace char after the pragma keyword.\n                uint256 char;\n                assembly (\"memory-safe\") {\n                    //slither-disable-next-line incorrect-shift\n                    char := shl(byte(0, mload(cursor)), 1)\n                }\n                if (char & CMASK_WHITESPACE == 0) {\n                    revert NoWhitespaceAfterUsingWordsFrom(state.parseErrorOffset(cursor));\n                }\n                ++cursor;\n            }\n\n            while (cursor < end) {\n                // It's fine to add comments for each pragma address.\n                // This also has the effect of moving past the interstitial after\n                // the last address as we don't break til just below.\n                cursor = state.parseInterstitial(cursor, end);\n\n                // Try to parse a literal and treat it as an address.\n                bool success;\n                uint256 value;\n                (success, cursor, value) = state.tryParseLiteral(cursor, end);\n                // If we didn't parse a literal, we're done with the pragma.\n                if (!success) {\n                    break;\n                } else {\n                    state.pushSubParser(cursor, value);\n                }\n            }\n\n            return cursor;\n        }\n    }\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParseInterstitial.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {FSM_YANG_MASK, ParseState} from \"./LibParseState.sol\";\nimport {\n    CMASK_COMMENT_HEAD,\n    CMASK_WHITESPACE,\n    COMMENT_END_SEQUENCE,\n    COMMENT_START_SEQUENCE,\n    CMASK_COMMENT_END_SEQUENCE_END\n} from \"./LibParseCMask.sol\";\nimport {ParserOutOfBounds, MalformedCommentStart, UnclosedComment} from \"../../error/ErrParse.sol\";\nimport {LibParseError} from \"./LibParseError.sol\";\nimport {LibParse} from \"./LibParse.sol\";\n\nlibrary LibParseInterstitial {\n    using LibParse for ParseState;\n    using LibParseError for ParseState;\n    using LibParseInterstitial for ParseState;\n\n    /// The cursor currently points at the head of a comment. We need to skip\n    /// over all data until we find the end of the comment. This MAY REVERT if\n    /// the comment is malformed, e.g. if the comment doesn't start with `/*`.\n    /// @param state The parser state.\n    /// @param cursor The current cursor position.\n    /// @return The new cursor position.\n    function skipComment(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) {\n        // Set yang for comments to force a little breathing room between\n        // comments and the next item.\n        state.fsm |= FSM_YANG_MASK;\n\n        // We're going to ignore overflow here because if either cursor or\n        // end is anywhere near uint256 max something went very wrong\n        // elsewhere already.\n        unchecked {\n            // It's an error if we can't fit the comment sequences in the\n            // remaining data to parse.\n            if (cursor + 4 > end) {\n                revert UnclosedComment(state.parseErrorOffset(cursor));\n            }\n\n            // First check the comment opening sequence is not malformed.\n            uint256 startSequence;\n            assembly (\"memory-safe\") {\n                startSequence := shr(0xf0, mload(cursor))\n            }\n            if (startSequence != COMMENT_START_SEQUENCE) {\n                revert MalformedCommentStart(state.parseErrorOffset(cursor));\n            }\n\n            // Move past the start sequence.\n            // The 3rd character can never be the end of the comment.\n            // Consider the string /*/ which is not a valid comment.\n            cursor += 3;\n\n            bool foundEnd = false;\n            while (cursor < end) {\n                uint256 charByte;\n                assembly (\"memory-safe\") {\n                    charByte := byte(0, mload(cursor))\n                }\n                if (charByte == CMASK_COMMENT_END_SEQUENCE_END) {\n                    // Maybe this is the end of the comment.\n                    // Check the sequence.\n                    uint256 endSequence;\n                    assembly (\"memory-safe\") {\n                        endSequence := shr(0xf0, mload(sub(cursor, 1)))\n                    }\n                    if (endSequence == COMMENT_END_SEQUENCE) {\n                        // We found the end of the comment.\n                        // Move past the end sequence and stop looping.\n                        ++cursor;\n                        foundEnd = true;\n                        break;\n                    }\n                }\n                ++cursor;\n            }\n\n            // If we didn't find the end of the comment, it's an error.\n            if (!foundEnd) {\n                revert UnclosedComment(state.parseErrorOffset(cursor));\n            }\n\n            return cursor;\n        }\n    }\n\n    function skipWhitespace(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) {\n        unchecked {\n            // Set ying as we now open to possibilities.\n            state.fsm &= ~FSM_YANG_MASK;\n            return LibParse.skipMask(cursor, end, CMASK_WHITESPACE);\n        }\n    }\n\n    function parseInterstitial(ParseState memory state, uint256 cursor, uint256 end) internal pure returns (uint256) {\n        while (cursor < end) {\n            uint256 char;\n            assembly (\"memory-safe\") {\n                //slither-disable-next-line incorrect-shift\n                char := shl(byte(0, mload(cursor)), 1)\n            }\n            if (char & CMASK_WHITESPACE > 0) {\n                cursor = state.skipWhitespace(cursor, end);\n            } else if (char & CMASK_COMMENT_HEAD > 0) {\n                cursor = state.skipComment(cursor, end);\n            } else {\n                break;\n            }\n        }\n        return cursor;\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/lib/rain.solmem/src/lib/LibUint256Array.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {Pointer} from \"./LibPointer.sol\";\nimport {LibMemCpy} from \"./LibMemCpy.sol\";\nimport {OutOfBoundsTruncate} from \"../error/ErrUint256Array.sol\";\n\n/// @title Uint256Array\n/// @notice Things we want to do carefully and efficiently with uint256 arrays\n/// that Solidity doesn't give us native tools for.\nlibrary LibUint256Array {\n    using LibUint256Array for uint256[];\n\n    /// Pointer to the start (length prefix) of a `uint256[]`.\n    /// @param array The array to get the start pointer of.\n    /// @return pointer The pointer to the start of `array`.\n    function startPointer(uint256[] memory array) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := array\n        }\n    }\n\n    /// Pointer to the data of a `uint256[]` NOT the length prefix.\n    /// @param array The array to get the data pointer of.\n    /// @return pointer The pointer to the data of `array`.\n    function dataPointer(uint256[] memory array) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(array, 0x20)\n        }\n    }\n\n    /// Pointer to the end of the allocated memory of an array.\n    /// @param array The array to get the end pointer of.\n    /// @return pointer The pointer to the end of `array`.\n    function endPointer(uint256[] memory array) internal pure returns (Pointer pointer) {\n        assembly (\"memory-safe\") {\n            pointer := add(array, add(0x20, mul(0x20, mload(array))))\n        }\n    }\n\n    /// Cast a `Pointer` to `uint256[]` without modification or safety checks.\n    /// The caller MUST ensure the pointer is to a valid region of memory for\n    /// some `uint256[]`.\n    /// @param pointer The pointer to cast to `uint256[]`.\n    /// @return array The cast `uint256[]`.\n    function unsafeAsUint256Array(Pointer pointer) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := pointer\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a A single integer to build an array around.\n    /// @return array The newly allocated array including `a` as a single item.\n    function arrayFrom(uint256 a) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 1)\n            mstore(add(array, 0x20), a)\n            mstore(0x40, add(array, 0x40))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @return array The newly allocated array including `a` and `b` as the only\n    /// items.\n    function arrayFrom(uint256 a, uint256 b) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 2)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(0x40, add(array, 0x60))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @param c The third integer to build an array around.\n    /// @return array The newly allocated array including `a`, `b` and `c` as the\n    /// only items.\n    function arrayFrom(uint256 a, uint256 b, uint256 c) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 3)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(add(array, 0x60), c)\n            mstore(0x40, add(array, 0x80))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @param c The third integer to build an array around.\n    /// @param d The fourth integer to build an array around.\n    /// @return array The newly allocated array including `a`, `b`, `c` and `d` as the\n    /// only items.\n    function arrayFrom(uint256 a, uint256 b, uint256 c, uint256 d) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 4)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(add(array, 0x60), c)\n            mstore(add(array, 0x80), d)\n            mstore(0x40, add(array, 0xA0))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @param c The third integer to build an array around.\n    /// @param d The fourth integer to build an array around.\n    /// @param e The fifth integer to build an array around.\n    /// @return array The newly allocated array including `a`, `b`, `c`, `d` and\n    /// `e` as the only items.\n    function arrayFrom(uint256 a, uint256 b, uint256 c, uint256 d, uint256 e)\n        internal\n        pure\n        returns (uint256[] memory array)\n    {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 5)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(add(array, 0x60), c)\n            mstore(add(array, 0x80), d)\n            mstore(add(array, 0xA0), e)\n            mstore(0x40, add(array, 0xC0))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first integer to build an array around.\n    /// @param b The second integer to build an array around.\n    /// @param c The third integer to build an array around.\n    /// @param d The fourth integer to build an array around.\n    /// @param e The fifth integer to build an array around.\n    /// @param f The sixth integer to build an array around.\n    /// @return array The newly allocated array including `a`, `b`, `c`, `d`, `e`\n    /// and `f` as the only items.\n    function arrayFrom(uint256 a, uint256 b, uint256 c, uint256 d, uint256 e, uint256 f)\n        internal\n        pure\n        returns (uint256[] memory array)\n    {\n        assembly (\"memory-safe\") {\n            array := mload(0x40)\n            mstore(array, 6)\n            mstore(add(array, 0x20), a)\n            mstore(add(array, 0x40), b)\n            mstore(add(array, 0x60), c)\n            mstore(add(array, 0x80), d)\n            mstore(add(array, 0xA0), e)\n            mstore(add(array, 0xC0), f)\n            mstore(0x40, add(array, 0xE0))\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The head of the new array.\n    /// @param tail The tail of the new array.\n    /// @return array The new array.\n    function arrayFrom(uint256 a, uint256[] memory tail) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            let length := add(mload(tail), 1)\n            let outputCursor := mload(0x40)\n            array := outputCursor\n            let outputEnd := add(outputCursor, add(0x20, mul(length, 0x20)))\n            mstore(0x40, outputEnd)\n\n            mstore(outputCursor, length)\n            mstore(add(outputCursor, 0x20), a)\n\n            for {\n                outputCursor := add(outputCursor, 0x40)\n                let inputCursor := add(tail, 0x20)\n            } lt(outputCursor, outputEnd) {\n                outputCursor := add(outputCursor, 0x20)\n                inputCursor := add(inputCursor, 0x20)\n            } { mstore(outputCursor, mload(inputCursor)) }\n        }\n    }\n\n    /// Building arrays from literal components is a common task that introduces\n    /// boilerplate that is either inefficient or error prone.\n    /// @param a The first item of the new array.\n    /// @param b The second item of the new array.\n    /// @param tail The tail of the new array.\n    /// @return array The new array.\n    function arrayFrom(uint256 a, uint256 b, uint256[] memory tail) internal pure returns (uint256[] memory array) {\n        assembly (\"memory-safe\") {\n            let length := add(mload(tail), 2)\n            let outputCursor := mload(0x40)\n            array := outputCursor\n            let outputEnd := add(outputCursor, add(0x20, mul(length, 0x20)))\n            mstore(0x40, outputEnd)\n\n            mstore(outputCursor, length)\n            mstore(add(outputCursor, 0x20), a)\n            mstore(add(outputCursor, 0x40), b)\n\n            for {\n                outputCursor := add(outputCursor, 0x60)\n                let inputCursor := add(tail, 0x20)\n            } lt(outputCursor, outputEnd) {\n                outputCursor := add(outputCursor, 0x20)\n                inputCursor := add(inputCursor, 0x20)\n            } { mstore(outputCursor, mload(inputCursor)) }\n        }\n    }\n\n    /// Solidity provides no way to change the length of in-memory arrays but\n    /// it also does not deallocate memory ever. It is always safe to shrink an\n    /// array that has already been allocated, with the caveat that the\n    /// truncated items will effectively become inaccessible regions of memory.\n    /// That is to say, we deliberately \"leak\" the truncated items, but that is\n    /// no worse than Solidity's native behaviour of leaking everything always.\n    /// The array is MUTATED in place so there is no return value and there is\n    /// no new allocation or copying of data either.\n    /// @param array The array to truncate.\n    /// @param newLength The new length of the array after truncation.\n    function truncate(uint256[] memory array, uint256 newLength) internal pure {\n        if (newLength > array.length) {\n            revert OutOfBoundsTruncate(array.length, newLength);\n        }\n        assembly (\"memory-safe\") {\n            mstore(array, newLength)\n        }\n    }\n\n    /// Extends `base_` with `extend_` by allocating only an additional\n    /// `extend_.length` words onto `base_` and copying only `extend_` if\n    /// possible. If `base_` is large this MAY be significantly more efficient\n    /// than allocating `base_.length + extend_.length` for an entirely new array\n    /// and copying both `base_` and `extend_` into the new array one item at a\n    /// time in Solidity.\n    ///\n    /// The efficient version of extension is only possible if the free memory\n    /// pointer sits at the end of the base array at the moment of extension. If\n    /// there is allocated memory after the end of base then extension will\n    /// require copying both the base and extend arays to a new region of memory.\n    /// The caller is responsible for optimising code paths to avoid additional\n    /// allocations.\n    ///\n    /// This function is UNSAFE because the base array IS MUTATED DIRECTLY by\n    /// some code paths AND THE FINAL RETURN ARRAY MAY POINT TO THE SAME REGION\n    /// OF MEMORY. It is NOT POSSIBLE to reliably see this behaviour from the\n    /// caller in all cases as the Solidity compiler optimisations may switch the\n    /// caller between the allocating and non-allocating logic due to subtle\n    /// optimisation reasons. To use this function safely THE CALLER MUST NOT USE\n    /// THE BASE ARRAY AND MUST USE THE RETURNED ARRAY ONLY. It is safe to use\n    /// the extend array after calling this function as it is never mutated, it\n    /// is only copied from.\n    ///\n    /// @param b The base integer array that will be extended by `e`.\n    /// @param e The extend integer array that extends `b`.\n    /// @return extended The extended array of `b` extended by `e`.\n    function unsafeExtend(uint256[] memory b, uint256[] memory e) internal pure returns (uint256[] memory extended) {\n        assembly (\"memory-safe\") {\n            // Slither doesn't recognise assembly function names as mixed case\n            // even if they are.\n            // https://github.com/crytic/slither/issues/1815\n            //slither-disable-next-line naming-convention\n            function extendInline(base, extend) -> baseAfter {\n                let outputCursor := mload(0x40)\n                let baseLength := mload(base)\n                let baseEnd := add(base, add(0x20, mul(baseLength, 0x20)))\n\n                // If base is NOT the last thing in allocated memory, allocate,\n                // copy and recurse.\n                switch eq(outputCursor, baseEnd)\n                case 0 {\n                    let newBase := outputCursor\n                    let newBaseEnd := add(newBase, sub(baseEnd, base))\n                    mstore(0x40, newBaseEnd)\n                    for { let inputCursor := base } lt(outputCursor, newBaseEnd) {\n                        inputCursor := add(inputCursor, 0x20)\n                        outputCursor := add(outputCursor, 0x20)\n                    } { mstore(outputCursor, mload(inputCursor)) }\n\n                    baseAfter := extendInline(newBase, extend)\n                }\n                case 1 {\n                    let totalLength_ := add(baseLength, mload(extend))\n                    let outputEnd_ := add(base, add(0x20, mul(totalLength_, 0x20)))\n                    mstore(base, totalLength_)\n                    mstore(0x40, outputEnd_)\n                    for { let inputCursor := add(extend, 0x20) } lt(outputCursor, outputEnd_) {\n                        inputCursor := add(inputCursor, 0x20)\n                        outputCursor := add(outputCursor, 0x20)\n                    } { mstore(outputCursor, mload(inputCursor)) }\n\n                    baseAfter := base\n                }\n            }\n\n            extended := extendInline(b, e)\n        }\n    }\n\n    /// Reverse an array in place. This is a destructive operation that MUTATES\n    /// the array in place. There is no return value.\n    /// @param array The array to reverse.\n    function reverse(uint256[] memory array) internal pure {\n        assembly (\"memory-safe\") {\n            for {\n                let left := add(array, 0x20)\n                // Right points at the last item in the array. Which is the\n                // length number of items from the length.\n                let right := add(array, mul(mload(array), 0x20))\n            } lt(left, right) {\n                left := add(left, 0x20)\n                right := sub(right, 0x20)\n            } {\n                let leftValue := mload(left)\n                mstore(left, mload(right))\n                mstore(right, leftValue)\n            }\n        }\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterV1.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IInterpreterStoreV1} from \"./IInterpreterStoreV1.sol\";\n\n/// @dev The index of a source within a deployed expression that can be evaluated\n/// by an `IInterpreterV1`. MAY be an entrypoint or the index of a source called\n/// internally such as by the `call` opcode.\ntype SourceIndex is uint16;\n\n/// @dev Encoded information about a specific evaluation including the expression\n/// address onchain, entrypoint and expected return values.\ntype EncodedDispatch is uint256;\n\n/// @dev The namespace for state changes as requested by the calling contract.\n/// The interpreter MUST apply this namespace IN ADDITION to namespacing by\n/// caller etc.\ntype StateNamespace is uint256;\n\n/// @dev Additional bytes that can be used to configure a single opcode dispatch.\n/// Commonly used to specify the number of inputs to a variadic function such\n/// as addition or multiplication.\ntype Operand is uint256;\n\n/// @dev The default state namespace MUST be used when a calling contract has no\n/// particular opinion on or need for dynamic namespaces.\nStateNamespace constant DEFAULT_STATE_NAMESPACE = StateNamespace.wrap(0);\n\n/// @title IInterpreterV1\n/// Interface into a standard interpreter that supports:\n///\n/// - evaluating `view` logic deployed onchain by an `IExpressionDeployerV1`\n/// - receiving arbitrary `uint256[][]` supporting context to be made available\n///   to the evaluated logic\n/// - handling subsequent state changes in bulk in response to evaluated logic\n/// - namespacing state changes according to the caller's preferences to avoid\n///   unwanted key collisions\n/// - exposing its internal function pointers to support external precompilation\n///   of logic for more gas efficient runtime evaluation by the interpreter\n///\n/// The interface is designed to be stable across many versions and\n/// implementations of an interpreter, balancing minimalism with features\n/// required for a general purpose onchain interpreted compute environment.\n///\n/// The security model of an interpreter is that it MUST be resilient to\n/// malicious expressions even if they dispatch arbitrary internal function\n/// pointers during an eval. The interpreter MAY return garbage or exhibit\n/// undefined behaviour or error during an eval, _provided that no state changes\n/// are persisted_ e.g. in storage, such that only the caller that specifies the\n/// malicious expression can be negatively impacted by the result. In turn, the\n/// caller must guard itself against arbitrarily corrupt/malicious reverts and\n/// return values from any interpreter that it requests an expression from. And\n/// so on and so forth up to the externally owned account (EOA) who signs the\n/// transaction and agrees to a specific combination of contracts, expressions\n/// and interpreters, who can presumably make an informed decision about which\n/// ones to trust to get the job done.\n///\n/// The state changes for an interpreter are expected to be produces by an `eval`\n/// and passed to the `IInterpreterStoreV1` returned by the eval, as-is by the\n/// caller, after the caller has had an opportunity to apply their own\n/// intermediate logic such as reentrancy defenses against malicious\n/// interpreters. The interpreter is free to structure the state changes however\n/// it wants but MUST guard against the calling contract corrupting the changes\n/// between `eval` and `set`. For example a store could sandbox storage writes\n/// per-caller so that a malicious caller can only damage their own state\n/// changes, while honest callers respect, benefit from and are protected by the\n/// interpreter store's state change handling.\n///\n/// The two step eval-state model allows eval to be read-only which provides\n/// security guarantees for the caller such as no stateful reentrancy, either\n/// from the interpreter or some contract interface used by some word, while\n/// still allowing for storage writes. As the storage writes happen on the\n/// interpreter rather than the caller (c.f. delegate call) the caller DOES NOT\n/// need to trust the interpreter, which allows for permissionless selection of\n/// interpreters by end users. Delegate call always implies an admin key on the\n/// caller because the delegatee contract can write arbitrarily to the state of\n/// the delegator, which severely limits the generality of contract composition.\ninterface IInterpreterV1 {\n    /// Exposes the function pointers as `uint16` values packed into a single\n    /// `bytes` in the same order as they would be indexed into by opcodes. For\n    /// example, if opcode `2` should dispatch function at position `0x1234` then\n    /// the start of the returned bytes would be `0xXXXXXXXX1234` where `X` is\n    /// a placeholder for the function pointers of opcodes `0` and `1`.\n    ///\n    /// `IExpressionDeployerV1` contracts use these function pointers to\n    /// \"compile\" the expression into something that an interpreter can dispatch\n    /// directly without paying gas to lookup the same at runtime. As the\n    /// validity of any integrity check and subsequent dispatch is highly\n    /// sensitive to both the function pointers and overall bytecode of the\n    /// interpreter, `IExpressionDeployerV1` contracts SHOULD implement guards\n    /// against accidentally being deployed onchain paired against an unknown\n    /// interpreter. It is very easy for an apparent compatible pairing to be\n    /// subtly and critically incompatible due to addition/removal/reordering of\n    /// opcodes and compiler optimisations on the interpreter bytecode.\n    ///\n    /// This MAY return different values during construction vs. all other times\n    /// after the interpreter has been successfully deployed onchain. DO NOT rely\n    /// on function pointers reported during contract construction.\n    function functionPointers() external view returns (bytes memory);\n\n    /// The raison d'etre for an interpreter. Given some expression and per-call\n    /// additional contextual data, produce a stack of results and a set of state\n    /// changes that the caller MAY OPTIONALLY pass back to be persisted by a\n    /// call to `IInterpreterStoreV1.set`.\n    /// @param store The storage contract that the returned key/value pairs\n    /// MUST be passed to IF the calling contract is in a non-static calling\n    /// context. Static calling contexts MUST pass `address(0)`.\n    /// @param namespace The state namespace that will be fully qualified by the\n    /// interpreter at runtime in order to perform gets on the underlying store.\n    /// MUST be the same namespace passed to the store by the calling contract\n    /// when sending the resulting key/value items to storage.\n    /// @param dispatch All the information required for the interpreter to load\n    /// an expression, select an entrypoint and return the values expected by the\n    /// caller. The interpreter MAY encode dispatches differently to\n    /// `LibEncodedDispatch` but this WILL negatively impact compatibility for\n    /// calling contracts that hardcode the encoding logic.\n    /// @param context A 2-dimensional array of data that can be indexed into at\n    /// runtime by the interpreter. The calling contract is responsible for\n    /// ensuring the authenticity and completeness of context data. The\n    /// interpreter MUST revert at runtime if an expression attempts to index\n    /// into some context value that is not provided by the caller. This implies\n    /// that context reads cannot be checked for out of bounds reads at deploy\n    /// time, as the runtime context MAY be provided in a different shape to what\n    /// the expression is expecting.\n    /// Same as `eval` but allowing the caller to specify a namespace under which\n    /// the state changes will be applied. The interpeter MUST ensure that keys\n    /// will never collide across namespaces, even if, for example:\n    ///\n    /// - The calling contract is malicious and attempts to craft a collision\n    ///   with state changes from another contract\n    /// - The expression is malicious and attempts to craft a collision with\n    ///   other expressions evaluated by the same calling contract\n    ///\n    /// A malicious entity MAY have access to significant offchain resources to\n    /// attempt to precompute key collisions through brute force. The collision\n    /// resistance of namespaces should be comparable or equivalent to the\n    /// collision resistance of the hashing algorithms employed by the blockchain\n    /// itself, such as the design of `mapping` in Solidity that hashes each\n    /// nested key to produce a collision resistant compound key.\n    /// @return stack The list of values produced by evaluating the expression.\n    /// MUST NOT be longer than the maximum length specified by `dispatch`, if\n    /// applicable.\n    /// @return kvs A list of pairwise key/value items to be saved in the store.\n    function eval(\n        IInterpreterStoreV1 store,\n        StateNamespace namespace,\n        EncodedDispatch dispatch,\n        uint256[][] calldata context\n    ) external view returns (uint256[] memory stack, uint256[] memory kvs);\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/IInterpreterStoreV2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {StateNamespace, FullyQualifiedNamespace, NO_STORE} from \"./deprecated/IInterpreterStoreV1.sol\";\n\n/// @title IInterpreterStoreV2\n/// @notice Tracks state changes on behalf of an interpreter. A single store can\n/// handle state changes for many calling contracts, many interpreters and many\n/// expressions. The store is responsible for ensuring that applying these state\n/// changes is safe from key collisions with calls to `set` from different\n/// `msg.sender` callers. I.e. it MUST NOT be possible for a caller to modify the\n/// state changes associated with some other caller.\n///\n/// The store defines the shape of its own state changes, which is opaque to the\n/// calling contract. For example, some store may treat the list of state changes\n/// as a pairwise key/value set, and some other store may treat it as a literal\n/// list to be stored as-is.\n///\n/// Each interpreter decides for itself which store to use based on the\n/// compatibility of its own opcodes.\n///\n/// The store MUST assume the state changes have been corrupted by the calling\n/// contract due to bugs or malicious intent, and enforce state isolation between\n/// callers despite arbitrarily invalid state changes. The store MUST revert if\n/// it can detect invalid state changes, such as a key/value list having an odd\n/// number of items, but this MAY NOT be possible if the corruption is\n/// undetectable.\ninterface IInterpreterStoreV2 {\n    /// MUST be emitted by the store on `set` to its internal storage.\n    /// @param namespace The fully qualified namespace that the store is setting.\n    /// @param key The key that the store is setting.\n    /// @param value The value that the store is setting.\n    event Set(FullyQualifiedNamespace namespace, uint256 key, uint256 value);\n\n    /// Mutates the interpreter store in bulk. The bulk values are provided in\n    /// the form of a `uint256[]` which can be treated e.g. as pairwise keys and\n    /// values to be stored in a Solidity mapping. The `IInterpreterStoreV2`\n    /// defines the meaning of the `uint256[]` for its own storage logic.\n    ///\n    /// @param namespace The unqualified namespace for the set that MUST be\n    /// fully qualified by the `IInterpreterStoreV2` to prevent key collisions\n    /// between callers. The fully qualified namespace forms a compound key with\n    /// the keys for each value to set.\n    /// @param kvs The list of changes to apply to the store's internal state.\n    function set(StateNamespace namespace, uint256[] calldata kvs) external;\n\n    /// Given a fully qualified namespace and key, return the associated value.\n    /// Ostensibly the interpreter can use this to implement opcodes that read\n    /// previously set values. The interpreter MUST apply the same qualification\n    /// logic as the store that it uses to guarantee consistent round tripping of\n    /// data and prevent malicious behaviours. Technically also allows onchain\n    /// reads of any set value from any contract, not just interpreters, but in\n    /// this case readers MUST be aware and handle inconsistencies between get\n    /// and set while the state changes are still in memory in the calling\n    /// context and haven't yet been persisted to the store.\n    ///\n    /// `IInterpreterStoreV2` uses the same fallback behaviour for unset keys as\n    /// Solidity. Specifically, any UNSET VALUES SILENTLY FALLBACK TO `0`.\n    /// @param namespace The fully qualified namespace to get a single value for.\n    /// @param key The key to get the value for within the namespace.\n    /// @return The value OR ZERO IF NOT SET.\n    function get(FullyQualifiedNamespace namespace, uint256 key) external view returns (uint256);\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterExternV2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {EncodedExternDispatch, ExternDispatch} from \"./IInterpreterExternV1.sol\";\n\n/// @title IInterpreterExternV2\n/// Handle a single dispatch from some calling contract with an array of\n/// inputs and array of outputs. Ostensibly useful to build \"word packs\" for\n/// `IInterpreterV1` so that less frequently used words can be provided in\n/// a less efficient format, but without bloating the base interpreter in\n/// terms of code size. Effectively allows unlimited words to exist as externs\n/// alongside interpreters.\n///\n/// The only difference between V2 and V1 is that V2 allows for the inputs and\n/// outputs to be in calldata rather than memory.\ninterface IInterpreterExternV2 {\n    /// Handles a single dispatch.\n    /// @param dispatch Encoded information about the extern to dispatch.\n    /// Analogous to the opcode/operand in the interpreter.\n    /// @param inputs The array of inputs for the dispatched logic.\n    /// @return outputs The result of the dispatched logic.\n    function extern(ExternDispatch dispatch, uint256[] calldata inputs)\n        external\n        view\n        returns (uint256[] calldata outputs);\n}\n"
      },
      "lib/rain.interpreter.interface/lib/rain.lib.hash/src/LibHashNoAlloc.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nbytes32 constant HASH_NIL = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n\n/// @title LibHashNoAlloc\n/// @notice When producing hashes of just about anything that isn't already bytes\n/// the common suggestions look something like `keccak256(abi.encode(...))` or\n/// `keccak256(abi.encodePacked(...))` with the main differentiation being\n/// whether dynamic data types are being hashed. If they are then there is a hash\n/// collision risk in the packed case as `\"abc\" + \"def\"` and `\"ab\" + \"cdef\"` will\n/// pack and therefore hash to the same values, the suggested fix commonly being\n/// to use abi.encode, which includes the lengths disambiguating dynamic data.\n/// Something like `3\"abc\" + 3\"def\"` with the length prefixes won't collide with\n/// `2\"ab\" + 4\"cdef\"` but note that ABI provides neither a strong guarantee to\n/// be collision resitant on inputs (as far as I know, it's a coincidence that\n/// this works), nor an efficient solution.\n///\n/// - Abi encoding is a complex algorithm that is easily 1k+ gas for simple\n///   structs with just one or two dynamic typed fields.\n/// - Abi encoding requires allocating and copying all the data plus a header to\n///   a new region of memory, which gives it non-linearly increasing costs due to\n///   memory expansion.\n/// - Abi encoding can't easily be reproduced offchain without specialised tools,\n///   it's not simply a matter of length prefixing some byte string and hashing\n///   with keccak256, the heads and tails all need to be produced recursively\n///   https://docs.soliditylang.org/en/develop/abi-spec.html#formal-specification-of-the-encoding\n///\n/// Consider that `hash(hash(\"abc\") + hash(\"def\"))` won't collide with\n/// `hash(hash(\"ab\") + hash(\"cdef\"))`. It should be easier to convince ourselves\n/// this is true for all possible pairs of byte strings than it is to convince\n/// ourselves that the ABI serialization is never ambigious. Inductively we can\n/// scale this to all possible data structures that are ordered compositions of\n/// byte strings. Even better, the native behaviour of `keccak256` in the EVM\n/// requires no additional allocation of memory. Worst case scenario is that we\n/// want to hash several hashes together like `hash(hash0, hash1, ...)`, in which\n/// case we can write the words after the free memory pointer, hash them, but\n/// leave the pointer. This way we pay for memory expansion but can re-use that\n/// region of memory for subsequent logic, which may effectively make the\n/// expansion free as we would have needed to pay for it anyway. Given that hash\n/// checks often occur early in real world logic due to\n/// checks-effects-interactions, this is not an unreasonable assumption to call\n/// this kind of expansion \"no alloc\".\n///\n/// One problem is that the gas saving for trivial abi encoding,\n/// e.g. ~1-3 uint256 values, can be lost by the overhead of jumps and stack\n/// manipulation due to function calls.\n///\n/// ```\n/// struct Foo {\n///   uint256 a;\n///   address b;\n///   uint32 c;\n/// }\n/// ```\n/// The simplest way to hash `Foo` is to just hash it (crazy, i know!).\n///\n/// ```\n/// assembly (\"memory-safe\") {\n///   hash_ := keccak256(foo_, 0x60)\n/// }\n/// ```\n/// Every struct field is 0x20 bytes in memory so 3 fields = 0x60 bytes to hash\n/// always, with the exception of dynamic types. This costs about 70 gas vs.\n/// about 350 gas for an abi encoding based approach.\nlibrary LibHashNoAlloc {\n    function hashBytes(bytes memory data_) internal pure returns (bytes32 hash_) {\n        assembly (\"memory-safe\") {\n            hash_ := keccak256(add(data_, 0x20), mload(data_))\n        }\n    }\n\n    function hashWords(bytes32[] memory words_) internal pure returns (bytes32 hash_) {\n        assembly (\"memory-safe\") {\n            hash_ := keccak256(add(words_, 0x20), mul(mload(words_), 0x20))\n        }\n    }\n\n    function hashWords(uint256[] memory words_) internal pure returns (bytes32 hash_) {\n        assembly (\"memory-safe\") {\n            hash_ := keccak256(add(words_, 0x20), mul(mload(words_), 0x20))\n        }\n    }\n\n    function combineHashes(bytes32 a_, bytes32 b_) internal pure returns (bytes32 hash_) {\n        assembly (\"memory-safe\") {\n            mstore(0, a_)\n            mstore(0x20, b_)\n            hash_ := keccak256(0, 0x40)\n        }\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n    /**\n     * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n     * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n     *\n     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n     * change through time. It could return true at block N and false at block N+1 (or the opposite).\n     */\n    function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n        (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n        return\n            (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n            isValidERC1271SignatureNow(signer, hash, signature);\n    }\n\n    /**\n     * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n     * against the signer smart contract using ERC1271.\n     *\n     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n     * change through time. It could return true at block N and false at block N+1 (or the opposite).\n     */\n    function isValidERC1271SignatureNow(\n        address signer,\n        bytes32 hash,\n        bytes memory signature\n    ) internal view returns (bool) {\n        (bool success, bytes memory result) = signer.staticcall(\n            abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n        );\n        return (success &&\n            result.length >= 32 &&\n            abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/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.0;\n\nimport \"../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        InvalidSignatureV // Deprecated in v4.8\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\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 opcode 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) {\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);\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 opcode 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) = tryRecover(hash, signature);\n        _throwError(error);\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) {\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\n        return tryRecover(hash, v, r, s);\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) = tryRecover(hash, r, vs);\n        _throwError(error);\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(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\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);\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);\n        }\n\n        return (signer, RecoverError.NoError);\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) = tryRecover(hash, v, r, s);\n        _throwError(error);\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, \"\\x19\\x01\")\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(\"\\x19\\x00\", validator, data));\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/IInterpreterCallerV2.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IExpressionDeployerV3} from \"./IExpressionDeployerV3.sol\";\nimport {IInterpreterStoreV2} from \"./IInterpreterStoreV2.sol\";\nimport {IInterpreterV2} from \"./IInterpreterV2.sol\";\n\n/// Standard struct that can be embedded in ABIs in a consistent format for\n/// tooling to read/write. MAY be useful to bundle up the data required to call\n/// `IExpressionDeployerV3` but is NOT mandatory.\n/// @param deployer Will deploy the expression from sources and constants.\n/// @param bytecode Will be deployed to an expression address for use in\n/// `Evaluable`.\n/// @param constants Will be available to the expression at runtime.\nstruct EvaluableConfigV3 {\n    IExpressionDeployerV3 deployer;\n    bytes bytecode;\n    uint256[] constants;\n}\n\n/// Struct over the return of `IExpressionDeployerV3.deployExpression2`\n/// which MAY be more convenient to work with than raw addresses.\n/// @param interpreter Will evaluate the expression.\n/// @param store Will store state changes due to evaluation of the expression.\n/// @param expression Will be evaluated by the interpreter.\nstruct EvaluableV2 {\n    IInterpreterV2 interpreter;\n    IInterpreterStoreV2 store;\n    address expression;\n}\n\n/// Typed embodiment of some context data with associated signer and signature.\n/// The signature MUST be over the packed encoded bytes of the context array,\n/// i.e. the context array concatenated as bytes without the length prefix, then\n/// hashed, then handled as per EIP-191 to produce a final hash to be signed.\n///\n/// The calling contract (likely with the help of `LibContext`) is responsible\n/// for ensuring the authenticity of the signature, but not authorizing _who_ can\n/// sign. IN ADDITION to authorisation of the signer to known-good entities the\n/// expression is also responsible for:\n///\n/// - Enforcing the context is the expected data (e.g. with a domain separator)\n/// - Tracking and enforcing nonces if signed contexts are only usable one time\n/// - Tracking and enforcing uniqueness of signed data if relevant\n/// - Checking and enforcing expiry times if present and relevant in the context\n/// - Many other potential constraints that expressions may want to enforce\n///\n/// EIP-1271 smart contract signatures are supported in addition to EOA\n/// signatures via. the Open Zeppelin `SignatureChecker` library, which is\n/// wrapped by `LibContext.build`. As smart contract signatures are checked\n/// onchain they CAN BE REVOKED AT ANY MOMENT as the smart contract can simply\n/// return `false` when it previously returned `true`.\n///\n/// @param signer The account that produced the signature for `context`. The\n/// calling contract MUST authenticate that the signer produced the signature.\n/// @param context The signed data in a format that can be merged into a\n/// 2-dimensional context matrix as-is.\n/// @param signature The cryptographic signature for `context`. The calling\n/// contract MUST authenticate that the signature is valid for the `signer` and\n/// `context`.\nstruct SignedContextV1 {\n    // The ordering of these fields is important and used in assembly offset\n    // calculations and hashing.\n    address signer;\n    uint256[] context;\n    bytes signature;\n}\n\nuint256 constant SIGNED_CONTEXT_SIGNER_OFFSET = 0;\nuint256 constant SIGNED_CONTEXT_CONTEXT_OFFSET = 0x20;\nuint256 constant SIGNED_CONTEXT_SIGNATURE_OFFSET = 0x40;\n\n/// @title IInterpreterCallerV2\n/// @notice A contract that calls an `IInterpreterV1` via. `eval`. There are near\n/// zero requirements on a caller other than:\n///\n/// - Emit some meta about itself upon construction so humans know what the\n///   contract does\n/// - Provide the context, which can be built in a standard way by `LibContext`\n/// - Handle the stack array returned from `eval`\n/// - OPTIONALLY emit the `Context` event\n/// - OPTIONALLY set state on the `IInterpreterStoreV1` returned from eval.\ninterface IInterpreterCallerV2 {\n    /// Calling contracts SHOULD emit `Context` before calling `eval` if they\n    /// are able. Notably `eval` MAY be called within a static call which means\n    /// that events cannot be emitted, in which case this does not apply. It MAY\n    /// NOT be useful to emit this multiple times for several eval calls if they\n    /// all share a common context, in which case a single emit is sufficient.\n    /// @param sender `msg.sender` building the context.\n    /// @param context The context that was built.\n    event Context(address sender, uint256[][] context);\n}\n"
      },
      "lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/LibParseStackTracker.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {ParseStackUnderflow} from \"../../error/ErrParse.sol\";\n\ntype ParseStackTracker is uint256;\n\nlibrary LibParseStackTracker {\n    using LibParseStackTracker for ParseStackTracker;\n\n    /// Pushing inputs requires special handling as the inputs need to be tallied\n    /// separately and in addition to the regular stack pushes.\n    function pushInputs(ParseStackTracker tracker, uint256 n) internal pure returns (ParseStackTracker) {\n        unchecked {\n            tracker = tracker.push(n);\n            uint256 inputs = (ParseStackTracker.unwrap(tracker) >> 8) & 0xFF;\n            inputs += n;\n            return ParseStackTracker.wrap((ParseStackTracker.unwrap(tracker) & ~uint256(0xFF00)) | (inputs << 8));\n        }\n    }\n\n    function push(ParseStackTracker tracker, uint256 n) internal pure returns (ParseStackTracker) {\n        unchecked {\n            uint256 current = ParseStackTracker.unwrap(tracker) & 0xFF;\n            uint256 inputs = (ParseStackTracker.unwrap(tracker) >> 8) & 0xFF;\n            uint256 max = ParseStackTracker.unwrap(tracker) >> 0x10;\n            current += n;\n            if (current > max) {\n                max = current;\n            }\n            return ParseStackTracker.wrap(current | (inputs << 8) | (max << 0x10));\n        }\n    }\n\n    function pop(ParseStackTracker tracker, uint256 n) internal pure returns (ParseStackTracker) {\n        unchecked {\n            uint256 current = ParseStackTracker.unwrap(tracker) & 0xFF;\n            if (current < n) {\n                revert ParseStackUnderflow();\n            }\n            return ParseStackTracker.wrap(ParseStackTracker.unwrap(tracker) - n);\n        }\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/src/error/ErrBytecode.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.19;\n\n/// @dev Workaround for https://github.com/foundry-rs/foundry/issues/6572\ncontract ErrBytecode {}\n\n/// Thrown when a bytecode source index is out of bounds.\n/// @param bytecode The bytecode that was inspected.\n/// @param sourceIndex The source index that was out of bounds.\nerror SourceIndexOutOfBounds(bytes bytecode, uint256 sourceIndex);\n\n/// Thrown when a bytecode reports itself as 0 sources but has more than 1 byte.\n/// @param bytecode The bytecode that was inspected.\nerror UnexpectedSources(bytes bytecode);\n\n/// Thrown when bytes are discovered between the offsets and the sources.\n/// @param bytecode The bytecode that was inspected.\nerror UnexpectedTrailingOffsetBytes(bytes bytecode);\n\n/// Thrown when the end of a source as self reported by its header doesnt match\n/// the start of the next source or the end of the bytecode.\n/// @param bytecode The bytecode that was inspected.\nerror TruncatedSource(bytes bytecode);\n\n/// Thrown when the offset to a source points to a location that cannot fit a\n/// header before the start of the next source or the end of the bytecode.\n/// @param bytecode The bytecode that was inspected.\nerror TruncatedHeader(bytes bytecode);\n\n/// Thrown when the bytecode is truncated before the end of the header offsets.\n/// @param bytecode The bytecode that was inspected.\nerror TruncatedHeaderOffsets(bytes bytecode);\n\n/// Thrown when the stack sizings, allocation, inputs and outputs, are not\n/// monotonically increasing.\n/// @param bytecode The bytecode that was inspected.\n/// @param relativeOffset The relative offset of the source that was inspected.\nerror StackSizingsNotMonotonic(bytes bytecode, uint256 relativeOffset);\n"
      },
      "lib/rain.interpreter.interface/lib/rain.solmem/src/error/ErrUint256Array.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\n/// Thrown if a truncated length is longer than the array being truncated. It is\n/// not possible to truncate something and increase its length as the memory\n/// region after the array MAY be allocated for something else already.\nerror OutOfBoundsTruncate(uint256 arrayLength, uint256 truncatedLength);\n"
      },
      "lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterStoreV1.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {StateNamespace} from \"./IInterpreterV1.sol\";\n\n/// A fully qualified namespace includes the interpreter's own namespacing logic\n/// IN ADDITION to the calling contract's requested `StateNamespace`. Typically\n/// this involves hashing the `msg.sender` into the `StateNamespace` so that each\n/// caller operates within its own disjoint state universe. Intepreters MUST NOT\n/// allow either the caller nor any expression/word to modify this directly on\n/// pain of potential key collisions on writes to the interpreter's own storage.\ntype FullyQualifiedNamespace is uint256;\n\nIInterpreterStoreV1 constant NO_STORE = IInterpreterStoreV1(address(0));\n\n/// @title IInterpreterStoreV1\n/// @notice Tracks state changes on behalf of an interpreter. A single store can\n/// handle state changes for many calling contracts, many interpreters and many\n/// expressions. The store is responsible for ensuring that applying these state\n/// changes is safe from key collisions with calls to `set` from different\n/// `msg.sender` callers. I.e. it MUST NOT be possible for a caller to modify the\n/// state changes associated with some other caller.\n///\n/// The store defines the shape of its own state changes, which is opaque to the\n/// calling contract. For example, some store may treat the list of state changes\n/// as a pairwise key/value set, and some other store may treat it as a literal\n/// list to be stored as-is.\n///\n/// Each interpreter decides for itself which store to use based on the\n/// compatibility of its own opcodes.\n///\n/// The store MUST assume the state changes have been corrupted by the calling\n/// contract due to bugs or malicious intent, and enforce state isolation between\n/// callers despite arbitrarily invalid state changes. The store MUST revert if\n/// it can detect invalid state changes, such as a key/value list having an odd\n/// number of items, but this MAY NOT be possible if the corruption is\n/// undetectable.\ninterface IInterpreterStoreV1 {\n    /// Mutates the interpreter store in bulk. The bulk values are provided in\n    /// the form of a `uint256[]` which can be treated e.g. as pairwise keys and\n    /// values to be stored in a Solidity mapping. The `IInterpreterStoreV1`\n    /// defines the meaning of the `uint256[]` for its own storage logic.\n    ///\n    /// @param namespace The unqualified namespace for the set that MUST be\n    /// fully qualified by the `IInterpreterStoreV1` to prevent key collisions\n    /// between callers. The fully qualified namespace forms a compound key with\n    /// the keys for each value to set.\n    /// @param kvs The list of changes to apply to the store's internal state.\n    function set(StateNamespace namespace, uint256[] calldata kvs) external;\n\n    /// Given a fully qualified namespace and key, return the associated value.\n    /// Ostensibly the interpreter can use this to implement opcodes that read\n    /// previously set values. The interpreter MUST apply the same qualification\n    /// logic as the store that it uses to guarantee consistent round tripping of\n    /// data and prevent malicious behaviours. Technically also allows onchain\n    /// reads of any set value from any contract, not just interpreters, but in\n    /// this case readers MUST be aware and handle inconsistencies between get\n    /// and set while the state changes are still in memory in the calling\n    /// context and haven't yet been persisted to the store.\n    ///\n    /// `IInterpreterStoreV1` uses the same fallback behaviour for unset keys as\n    /// Solidity. Specifically, any UNSET VALUES SILENTLY FALLBACK TO `0`.\n    /// @param namespace The fully qualified namespace to get a single value for.\n    /// @param key The key to get the value for within the namespace.\n    /// @return The value OR ZERO IF NOT SET.\n    function get(FullyQualifiedNamespace namespace, uint256 key) external view returns (uint256);\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/deprecated/IInterpreterExternV1.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\ntype EncodedExternDispatch is uint256;\n\ntype ExternDispatch is uint256;\n\n/// @title IInterpreterExternV1\n/// Handle a single dispatch from some calling contract with an array of\n/// inputs and array of outputs. Ostensibly useful to build \"word packs\" for\n/// `IInterpreterV1` so that less frequently used words can be provided in\n/// a less efficient format, but without bloating the base interpreter in\n/// terms of code size. Effectively allows unlimited words to exist as externs\n/// alongside interpreters.\ninterface IInterpreterExternV1 {\n    /// Handles a single dispatch.\n    /// @param dispatch Encoded information about the extern to dispatch.\n    /// Analogous to the opcode/operand in the interpreter.\n    /// @param inputs The array of inputs for the dispatched logic.\n    /// @return outputs The result of the dispatched logic.\n    function extern(ExternDispatch dispatch, uint256[] memory inputs)\n        external\n        view\n        returns (uint256[] memory outputs);\n}\n"
      },
      "lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/interfaces/IERC1271.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n    /**\n     * @dev Should return whether the signature provided is valid for the provided data\n     * @param hash      Hash of the data to be signed\n     * @param signature Signature byte array associated with _data\n     */\n    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"
      },
      "lib/rain.interpreter.interface/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.0;\n\nimport \"./math/Math.sol\";\nimport \"./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 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 toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(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        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[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\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 keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
      },
      "lib/rain.interpreter.interface/src/interface/IExpressionDeployerV3.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport {IInterpreterStoreV2} from \"./IInterpreterStoreV2.sol\";\nimport {IInterpreterV2} from \"./IInterpreterV2.sol\";\n\nstring constant IERC1820_NAME_IEXPRESSION_DEPLOYER_V3 = \"IExpressionDeployerV3\";\n\n/// @title IExpressionDeployerV3\n/// @notice Companion to `IInterpreterV2` responsible for onchain static code\n/// analysis and deploying expressions. Each `IExpressionDeployerV3` is tightly\n/// coupled at the bytecode level to some interpreter that it knows how to\n/// analyse and deploy expressions for. The expression deployer can perform an\n/// integrity check \"dry run\" of candidate source code for the intepreter. The\n/// critical analysis/transformation includes:\n///\n/// - Enforcement of no out of bounds memory reads/writes\n/// - Calculation of memory required to eval the stack with a single allocation\n/// - Replacing index based opcodes with absolute interpreter function pointers\n/// - Enforcement that all opcodes and operands used exist and are valid\n///\n/// This analysis is highly sensitive to the specific implementation and position\n/// of all opcodes and function pointers as compiled into the interpreter. This\n/// is what makes the coupling between an interpreter and expression deployer\n/// so tight. Ideally all responsibilities would be handled by a single contract\n/// but this introduces code size issues quickly by roughly doubling the compiled\n/// logic of each opcode (half for the integrity check and half for evaluation).\n///\n/// Interpreters MUST assume that expression deployers are malicious and fail\n/// gracefully if the integrity check is corrupt/bypassed and/or function\n/// pointers are incorrect, etc. i.e. the interpreter MUST always return a stack\n/// from `eval` in a read only way or error. I.e. it is the expression deployer's\n/// responsibility to do everything it can to prevent undefined behaviour in the\n/// interpreter, and the interpreter's responsibility to handle the expression\n/// deployer completely failing to do so.\ninterface IExpressionDeployerV3 {\n    /// The config of the deployed expression including uncompiled sources. MUST\n    /// be emitted after the config passes the integrity check.\n    /// @param sender The caller of `deployExpression2`.\n    /// @param bytecode As per `IExpressionDeployerV3.deployExpression2` inputs.\n    /// @param constants As per `IExpressionDeployerV3.deployExpression2` inputs.\n    event NewExpression(address sender, bytes bytecode, uint256[] constants);\n\n    /// The address of the deployed expression. MUST be emitted once the\n    /// expression can be loaded and deserialized into an evaluable interpreter\n    /// state.\n    /// @param sender The caller of `deployExpression2`.\n    /// @param interpreter As per `IExpressionDeployerV3.deployExpression2` return.\n    /// @param store As per `IExpressionDeployerV3.deployExpression2` return.\n    /// @param expression As per `IExpressionDeployerV3.deployExpression2` return.\n    /// @param io As per `IExpressionDeployerV3.deployExpression2` return.\n    event DeployedExpression(\n        address sender, IInterpreterV2 interpreter, IInterpreterStoreV2 store, address expression, bytes io\n    );\n\n    /// This is the literal InterpreterOpMeta bytes to be used offchain to make\n    /// sense of the opcodes in this interpreter deployment, as a human. For\n    /// formats like json that make heavy use of boilerplate, repetition and\n    /// whitespace, some kind of compression is recommended.\n    /// The DISPair is a pairing of:\n    /// - Deployer (this contract)\n    /// - Interpreter\n    /// - Store\n    /// - Parser\n    ///\n    /// @param sender The `msg.sender` providing the op meta.\n    /// @param interpreter The interpreter the deployer believes it is qualified\n    /// to perform integrity checks on behalf of.\n    /// @param store The interpreter store the deployer believes is compatible\n    /// with the interpreter.\n    /// @param parser The parser the deployer believes is compatible with the\n    /// interpreter.\n    /// @param meta The raw binary data of the construction meta. Maybe\n    /// compressed data etc. and is intended for offchain consumption.\n    event DISPair(address sender, address interpreter, address store, address parser, bytes meta);\n\n    /// Expressions are expected to be deployed onchain as immutable contract\n    /// code with a first class address like any other contract or account.\n    /// Technically this is optional in the sense that all the tools required to\n    /// eval some expression and define all its opcodes are available as\n    /// libraries.\n    ///\n    /// In practise there are enough advantages to deploying the sources directly\n    /// onchain as contract data and loading them from the interpreter at eval:\n    ///\n    /// - Loading and storing binary data is gas efficient as immutable contract\n    ///   data\n    /// - Expressions need to be immutable between their deploy time integrity\n    ///   check and runtime evaluation\n    /// - Passing the address of an expression through calldata to an interpreter\n    ///   is cheaper than passing an entire expression through calldata\n    /// - Conceptually a very simple approach, even if implementations like\n    ///   SSTORE2 are subtle under the hood\n    ///\n    /// The expression deployer MUST perform an integrity check of the source\n    /// code before it puts the expression onchain at a known address. The\n    /// integrity check MUST at a minimum (it is free to do additional static\n    /// analysis) calculate the memory required to be allocated for the stack in\n    /// total, and that no out of bounds memory reads/writes occur within this\n    /// stack. A simple example of an invalid source would be one that pushes one\n    /// value to the stack then attempts to pops two values, clearly we cannot\n    /// remove more values than we added. The `IExpressionDeployerV3` MUST revert\n    /// in the case of any integrity failure, all integrity checks MUST pass in\n    /// order for the deployment to complete.\n    ///\n    /// Once the integrity check is complete the `IExpressionDeployerV3` MUST do\n    /// any additional processing required by its paired interpreter.\n    /// For example, the `IExpressionDeployerV3` MAY NEED to replace the indexed\n    /// opcodes in the `ExpressionConfig` sources with real function pointers\n    /// from the corresponding interpreter.\n    ///\n    /// The caller MUST check the `io` returned by this function to determine\n    /// the number of inputs and outputs for each source are within the bounds\n    /// of the caller's expectations.\n    ///\n    /// @param bytecode Bytecode verbatim. Exactly how the bytecode is structured\n    /// is up to the deployer and interpreter. The deployer MUST NOT modify the\n    /// bytecode in any way. The interpreter MUST NOT assume anything about the\n    /// bytecode other than that it is valid according to the interpreter's\n    /// integrity checks. It is assumed that the bytecode will be produced from\n    /// a human friendly string via. `IParserV1.parse` but this is not required\n    /// if the caller has some other means to prooduce valid bytecode.\n    /// @param constants Constants verbatim. Constants are provided alongside\n    /// sources rather than inline as it allows us to avoid variable length\n    /// opcodes and can be more memory efficient if the same constant is\n    /// referenced several times from the sources.\n    /// @return interpreter The interpreter the deployer believes it is qualified\n    /// to perform integrity checks on behalf of.\n    /// @return store The interpreter store the deployer believes is compatible\n    /// with the interpreter.\n    /// @return expression The address of the deployed onchain expression. MUST\n    /// be valid according to all integrity checks the deployer is aware of.\n    /// @return io Binary data where each 2 bytes input and output counts for\n    /// each source of the bytecode. MAY simply be copied verbatim from the\n    /// relevant bytes in the bytecode if they exist and integrity checks\n    /// guarantee that the bytecode is valid.\n    function deployExpression2(bytes calldata bytecode, uint256[] calldata constants)\n        external\n        returns (IInterpreterV2 interpreter, IInterpreterStoreV2 store, address expression, bytes calldata io);\n}\n"
      },
      "lib/rain.interpreter.interface/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.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\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        // (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            require(denominator > prod1, \"Math: mulDiv overflow\");\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/rain.interpreter.interface/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.0;\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": [
        "rain.interpreter/=lib/rain.orderbook/lib/rain.interpreter/src/",
        "@prb/test/=lib/rain.orderbook/lib/rain.interpreter/lib/prb-math/lib/prb-test/src/",
        "axelar-gmp-sdk-solidity/=lib/rain.orderbook/lib/sushixswap-v2/lib/axelar-gmp-sdk-solidity/",
        "bitwise/=lib/rain.orderbook/lib/rain.interpreter/src/lib/bitwise/",
        "bytecode/=lib/rain.interpreter.interface/src/lib/bytecode/",
        "caller/=lib/rain.interpreter.interface/src/lib/caller/",
        "compile/=lib/rain.orderbook/lib/rain.factory/lib/rain.interpreter/src/lib/compile/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/rain.interpreter.interface/lib/openzeppelin-contracts/lib/erc4626-tests/",
        "eval/=lib/rain.orderbook/lib/rain.interpreter/src/lib/eval/",
        "extern/=lib/rain.orderbook/lib/rain.interpreter/src/lib/extern/",
        "forge-gas-snapshot/=lib/rain.orderbook/lib/sushixswap-v2/lib/forge-gas-snapshot/src/",
        "forge-std/=lib/forge-std/src/",
        "h20.pubstrats/=lib/h20.pubstrats/src/",
        "integrity/=lib/rain.orderbook/lib/rain.interpreter/src/lib/integrity/",
        "ns/=lib/rain.interpreter.interface/src/lib/ns/",
        "op/=lib/rain.orderbook/lib/rain.interpreter/src/lib/op/",
        "openzeppelin-contracts/=lib/rain.interpreter.interface/lib/openzeppelin-contracts/",
        "openzeppelin/=lib/rain.interpreter.interface/lib/openzeppelin-contracts/contracts/",
        "parse/=lib/rain.orderbook/lib/rain.interpreter/src/lib/parse/",
        "prb-math/=lib/rain.orderbook/lib/rain.interpreter/lib/prb-math/src/",
        "prb-test/=lib/rain.orderbook/lib/rain.interpreter/lib/prb-math/lib/prb-test/src/",
        "rain.chainlink/=lib/rain.orderbook/lib/rain.interpreter/lib/rain.chainlink/src/",
        "rain.datacontract/=lib/rain.orderbook/lib/rain.interpreter/lib/rain.datacontract/src/",
        "rain.erc1820/=lib/rain.orderbook/lib/rain.erc1820/src/",
        "rain.extrospection/=lib/rain.orderbook/lib/rain.factory/lib/rain.extrospection/",
        "rain.factory/=lib/rain.orderbook/lib/rain.factory/",
        "rain.interpreter.interface/=lib/rain.interpreter.interface/src/",
        "rain.intorastring/=lib/rain.intorastring/",
        "rain.lib.hash/=lib/rain.interpreter.interface/lib/rain.lib.hash/src/",
        "rain.lib.memkv/=lib/rain.orderbook/lib/rain.lib.memkv/src/",
        "rain.lib.typecast/=lib/rain.interpreter.interface/lib/rain.lib.typecast/src/",
        "rain.math.fixedpoint/=lib/rain.orderbook/lib/rain.math.fixedpoint/src/",
        "rain.math.saturating/=lib/rain.math.saturating/src/",
        "rain.metadata/=lib/rain.orderbook/lib/rain.metadata/",
        "rain.orderbook/=lib/rain.orderbook/",
        "rain.solmem/=lib/rain.interpreter.interface/lib/rain.solmem/src/",
        "sol.lib.binmaskflag/=lib/rain.orderbook/lib/rain.interpreter/lib/sol.lib.binmaskflag/src/",
        "state/=lib/rain.orderbook/lib/rain.interpreter/src/lib/state/",
        "sushixswap-v2/=lib/rain.orderbook/lib/sushixswap-v2/",
        "uniswap/=lib/rain.orderbook/lib/rain.factory/lib/rain.interpreter/src/lib/uniswap/",
        "v2-core/=lib/rain.orderbook/lib/rain.factory/lib/rain.interpreter/lib/v2-core/contracts/",
        "v2-periphery/=lib/rain.orderbook/lib/rain.factory/lib/rain.interpreter/lib/v2-periphery/contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 1000000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none",
        "appendCBOR": false
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "libraries": {}
    }
  }}