creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "lib/rain.flow/lib/rain.interpreter/src/concrete/RainterpreterStore.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity =0.8.19;\n\nimport \"openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\";\n\nimport \"../interface/IInterpreterStoreV1.sol\";\nimport \"../lib/ns/LibNamespace.sol\";\n\n/// Thrown when a `set` call is made with an odd number of arguments.\nerror RainterpreterStoreOddSetLength(uint256 length);\n\n/// @title RainterpreterStore\n/// @notice Simplest possible `IInterpreterStoreV1` that could work.\n/// Takes key/value pairings from the input array and stores each in an internal\n/// mapping. `StateNamespace` is fully qualified only by `msg.sender` on set and\n/// doesn't attempt to do any deduping etc. if the same key appears twice it will\n/// be set twice.\ncontract RainterpreterStore is IInterpreterStoreV1, ERC165 {\n    using LibNamespace for StateNamespace;\n\n    /// Store is several tiers of sandbox.\n    ///\n    /// 0. Address hashed into `FullyQualifiedNamespace` is `msg.sender` so that\n    ///    callers cannot attack each other\n    /// 1. StateNamespace is caller-provided namespace so that expressions cannot\n    ///    attack each other\n    /// 2. `uint256` is expression-provided key\n    /// 3. `uint256` is expression-provided value\n    ///\n    /// tiers 0 and 1 are both embodied in the `FullyQualifiedNamespace`.\n    // Slither doesn't like the leading underscore.\n    //solhint-disable-next-line private-vars-leading-underscore\n    mapping(FullyQualifiedNamespace fullyQualifiedNamespace => mapping(uint256 key => uint256 value)) internal sStore;\n\n    // @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IInterpreterStoreV1).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /// @inheritdoc IInterpreterStoreV1\n    function set(StateNamespace namespace, uint256[] calldata kvs) external {\n        /// This would be picked up by an out of bounds index below, but it's\n        /// nice to have a more specific error message.\n        if (kvs.length % 2 != 0) {\n            revert RainterpreterStoreOddSetLength(kvs.length);\n        }\n        unchecked {\n            FullyQualifiedNamespace fullyQualifiedNamespace = namespace.qualifyNamespace(msg.sender);\n            for (uint256 i = 0; i < kvs.length; i += 2) {\n                sStore[fullyQualifiedNamespace][kvs[i]] = kvs[i + 1];\n            }\n        }\n    }\n\n    /// @inheritdoc IInterpreterStoreV1\n    function get(FullyQualifiedNamespace namespace, uint256 key) external view returns (uint256) {\n        return sStore[namespace][key];\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.factory/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.flow/lib/rain.interpreter/src/interface/IInterpreterStoreV1.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./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.flow/lib/rain.interpreter/src/lib/ns/LibNamespace.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"../../interface/IInterpreterV1.sol\";\n\nlibrary LibNamespace {\n    /// Standard way to elevate a caller-provided state namespace to a universal\n    /// namespace that is disjoint from all other caller-provided namespaces.\n    /// Essentially just hashes the `msg.sender` into the state namespace as-is.\n    ///\n    /// This is deterministic such that the same combination of state namespace\n    /// and caller will produce the same fully qualified namespace, even across\n    /// multiple transactions/blocks.\n    ///\n    /// @param stateNamespace The state namespace as specified by the caller.\n    /// @param sender The caller this namespace is bound to.\n    /// @return qualifiedNamespace A fully qualified namespace that cannot\n    /// collide with any other state namespace specified by any other caller.\n    function qualifyNamespace(StateNamespace stateNamespace, address sender)\n        internal\n        pure\n        returns (FullyQualifiedNamespace qualifiedNamespace)\n    {\n        assembly (\"memory-safe\") {\n            mstore(0, stateNamespace)\n            mstore(0x20, sender)\n            qualifiedNamespace := keccak256(0, 0x40)\n        }\n    }\n}\n"
      },
      "lib/rain.flow/lib/rain.factory/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.flow/lib/rain.interpreter/src/interface/IInterpreterV1.sol": {
        "content": "// SPDX-License-Identifier: CAL\npragma solidity ^0.8.18;\n\nimport \"./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"
      }
    },
    "settings": {
      "remappings": [
        "@prb/test/=lib/rain.flow/lib/rain.interpreter/lib/prb-math/lib/prb-test/src/",
        "bitwise/=lib/rain.flow/lib/rain.interpreter/src/lib/bitwise/",
        "bytecode/=lib/rain.flow/lib/rain.interpreter/src/lib/bytecode/",
        "caller/=lib/rain.flow/lib/rain.interpreter/src/lib/caller/",
        "compile/=lib/rain.flow/lib/rain.interpreter/src/lib/compile/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "erc4626-tests/=lib/rain.flow/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
        "eval/=lib/rain.flow/lib/rain.interpreter/src/lib/eval/",
        "extern/=lib/rain.flow/lib/rain.interpreter/src/lib/extern/",
        "forge-std/=lib/forge-std/src/",
        "integrity/=lib/rain.flow/lib/rain.interpreter/src/lib/integrity/",
        "ns/=lib/rain.flow/lib/rain.interpreter/src/lib/ns/",
        "op/=lib/rain.flow/lib/rain.interpreter/src/lib/op/",
        "openzeppelin-contracts-upgradeable/=lib/rain.flow/lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/rain.flow/lib/rain.factory/lib/openzeppelin-contracts/",
        "openzeppelin/=lib/rain.flow/lib/openzeppelin-contracts-upgradeable/contracts/",
        "parse/=lib/rain.flow/lib/rain.interpreter/src/lib/parse/",
        "prb-math/=lib/rain.flow/lib/rain.interpreter/lib/prb-math/src/",
        "prb-test/=lib/rain.flow/lib/rain.interpreter/lib/prb-math/lib/prb-test/src/",
        "rain.chainlink/=lib/rain.flow/lib/rain.interpreter/lib/rain.chainlink/src/",
        "rain.datacontract/=lib/rain.flow/lib/rain.interpreter/lib/rain.datacontract/src/",
        "rain.erc1820/=lib/rain.flow/lib/rain.interpreter/lib/rain.erc1820/src/",
        "rain.extrospection/=lib/rain.flow/lib/rain.factory/lib/rain.extrospection/",
        "rain.factory/=lib/rain.flow/lib/rain.factory/",
        "rain.flow/=lib/rain.flow/",
        "rain.interpreter/=lib/rain.flow/lib/rain.interpreter/",
        "rain.lib.hash/=lib/rain.flow/lib/rain.interpreter/lib/rain.lib.memkv/lib/rain.lib.hash/src/",
        "rain.lib.memkv/=lib/rain.flow/lib/rain.interpreter/lib/rain.lib.memkv/src/",
        "rain.lib.typecast/=lib/rain.flow/lib/rain.interpreter/lib/rain.lib.typecast/src/",
        "rain.math.fixedpoint/=lib/rain.flow/lib/rain.interpreter/lib/rain.math.fixedpoint/src/",
        "rain.math.saturating/=lib/rain.flow/lib/rain.interpreter/lib/rain.math.fixedpoint/lib/rain.math.saturating/src/",
        "rain.metadata/=lib/rain.flow/lib/rain.interpreter/lib/rain.metadata/src/",
        "rain.solmem/=lib/rain.flow/lib/rain.interpreter/lib/rain.solmem/src/",
        "sol.lib.binmaskflag/=lib/rain.flow/lib/rain.interpreter/lib/sol.lib.binmaskflag/src/",
        "state/=lib/rain.flow/lib/rain.interpreter/src/lib/state/",
        "uniswap/=lib/rain.flow/lib/rain.interpreter/src/lib/uniswap/",
        "v2-core/=lib/rain.flow/lib/rain.interpreter/lib/v2-core/contracts/",
        "v2-periphery/=lib/rain.flow/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",
      "viaIR": false,
      "libraries": {}
    }
  }}