diff --git a/.gitmodules b/.gitmodules index ce230cde8..dfb7e6e98 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,9 +10,6 @@ [submodule "lib/rain.lib.memkv"] path = lib/rain.lib.memkv url = https://github.com/rainprotocol/rain.lib.memkv -[submodule "lib/rain.factory"] - path = lib/rain.factory - url = https://github.com/rainprotocol/rain.factory [submodule "lib/sushixswap-v2"] path = lib/sushixswap-v2 url = https://github.com/rainprotocol/sushixswap-v2 @@ -28,3 +25,6 @@ [submodule "lib/rain.interpreter"] path = lib/rain.interpreter url = https://github.com/rainprotocol/rain.interpreter +[submodule "lib/rain.factory"] + path = lib/rain.factory + url = https://github.com/rainprotocol/rain.factory diff --git a/lib/rain.factory b/lib/rain.factory index e6babfcc5..0a02f9119 160000 --- a/lib/rain.factory +++ b/lib/rain.factory @@ -1 +1 @@ -Subproject commit e6babfcc5788bb387878d6915955228b2a4cfc70 +Subproject commit 0a02f91190531aa7bf7f7b28d31a9bb70e9e7a0a diff --git a/lib/rain.interpreter b/lib/rain.interpreter index 5222a43e9..059d6405c 160000 --- a/lib/rain.interpreter +++ b/lib/rain.interpreter @@ -1 +1 @@ -Subproject commit 5222a43e9a088b41a7eca4a3d283721fccbc1058 +Subproject commit 059d6405c4315a1c681492c9c73315d06bcff162 diff --git a/src/abstract/OrderBookV3ArbOrderTaker.sol b/src/abstract/OrderBookV3ArbOrderTaker.sol index 948302163..27f7c8d29 100644 --- a/src/abstract/OrderBookV3ArbOrderTaker.sol +++ b/src/abstract/OrderBookV3ArbOrderTaker.sol @@ -12,16 +12,22 @@ import { DeployerDiscoverableMetaV3ConstructionConfig, LibMeta } from "lib/rain.interpreter/src/abstract/DeployerDiscoverableMetaV3.sol"; -import "lib/rain.factory/src/interface/ICloneableV2.sol"; -import "lib/rain.interpreter/src/lib/caller/LibContext.sol"; -import "lib/rain.interpreter/src/lib/caller/LibEncodedDispatch.sol"; -import "lib/rain.interpreter/src/lib/bytecode/LibBytecode.sol"; - -import "../interface/unstable/IOrderBookV3.sol"; -import "../interface/unstable/IOrderBookV3OrderTaker.sol"; -import "../interface/unstable/IOrderBookV3ArbOrderTaker.sol"; - -import "./OrderBookV3ArbCommon.sol"; +import {EvaluableConfigV3, SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; +import {SourceIndexV2} from "rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; +import {ICloneableV2, ICLONEABLE_V2_SUCCESS} from "lib/rain.factory/src/interface/ICloneableV2.sol"; +import {EncodedDispatch, LibEncodedDispatch} from "lib/rain.interpreter/src/lib/caller/LibEncodedDispatch.sol"; + +import {IOrderBookV3, NoOrders} from "../interface/unstable/IOrderBookV3.sol"; +import {IOrderBookV3ArbOrderTaker, IOrderBookV3OrderTaker} from "../interface/unstable/IOrderBookV3ArbOrderTaker.sol"; +import {IInterpreterV2, DEFAULT_STATE_NAMESPACE} from "rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; +import {IInterpreterStoreV1} from "rain.interpreter/src/interface/IInterpreterStoreV1.sol"; +import {TakeOrdersConfigV2} from "../interface/unstable/IOrderBookV3.sol"; +import {BadLender, MinimumOutput, NonZeroBeforeArbStack, Initializing} from "./OrderBookV3ArbCommon.sol"; +import {LibContext} from "rain.interpreter/src/lib/caller/LibContext.sol"; +import {LibBytecode} from "rain.interpreter/src/lib/bytecode/LibBytecode.sol"; + +/// Thrown when "before arb" wants inputs that we don't have. +error NonZeroBeforeArbInputs(uint256 inputs); /// Config for `OrderBookV3ArbOrderTakerConfigV1` to initialize. /// @param orderBook The `IOrderBookV3` to use for `takeOrders`. @@ -30,13 +36,13 @@ import "./OrderBookV3ArbCommon.sol"; /// the `beforeInitialize` hook. struct OrderBookV3ArbOrderTakerConfigV1 { address orderBook; - EvaluableConfigV2 evaluableConfig; + EvaluableConfigV3 evaluableConfig; bytes implementationData; } /// @dev "Before arb" is evaluabled before the arb is executed. Ostensibly this /// is to allow for access control to the arb, the return values are ignored. -SourceIndex constant BEFORE_ARB_SOURCE_INDEX = SourceIndex.wrap(0); +SourceIndexV2 constant BEFORE_ARB_SOURCE_INDEX = SourceIndexV2.wrap(0); /// @dev "Before arb" has no return values. uint256 constant BEFORE_ARB_MIN_OUTPUTS = 0; /// @dev "Before arb" has no return values. @@ -56,7 +62,7 @@ abstract contract OrderBookV3ArbOrderTaker is IOrderBookV3 public sOrderBook; EncodedDispatch public sI9rDispatch; - IInterpreterV1 public sI9r; + IInterpreterV2 public sI9r; IInterpreterStoreV1 public sI9rStore; constructor(bytes32 metaHash, DeployerDiscoverableMetaV3ConstructionConfig memory config) @@ -103,18 +109,25 @@ abstract contract OrderBookV3ArbOrderTaker is if (LibBytecode.sourceCount(config.evaluableConfig.bytecode) > 0) { address expression; - uint256[] memory entrypoints = new uint256[](1); - entrypoints[SourceIndex.unwrap(BEFORE_ARB_SOURCE_INDEX)] = BEFORE_ARB_MIN_OUTPUTS; - + bytes memory io; // We have to trust the deployer because it produces the expression // address for dispatch anyway. // All external functions on this contract have `onlyNotInitializing` // modifier on them so can't be reentered here anyway. //slither-disable-next-line reentrancy-benign - (sI9r, sI9rStore, expression) = config.evaluableConfig.deployer.deployExpression( - config.evaluableConfig.bytecode, config.evaluableConfig.constants, entrypoints + (sI9r, sI9rStore, expression, io) = config.evaluableConfig.deployer.deployExpression2( + config.evaluableConfig.bytecode, config.evaluableConfig.constants ); - sI9rDispatch = LibEncodedDispatch.encode(expression, BEFORE_ARB_SOURCE_INDEX, BEFORE_ARB_MAX_OUTPUTS); + { + uint256 inputs; + assembly ("memory-safe") { + inputs := and(mload(add(io, 1)), 0xFF) + } + if (inputs != 0) { + revert NonZeroBeforeArbInputs(inputs); + } + } + sI9rDispatch = LibEncodedDispatch.encode2(expression, BEFORE_ARB_SOURCE_INDEX, BEFORE_ARB_MAX_OUTPUTS); } return ICLONEABLE_V2_SUCCESS; @@ -138,11 +151,12 @@ abstract contract OrderBookV3ArbOrderTaker is // Run the access control dispatch if it is set. EncodedDispatch dispatch = sI9rDispatch; if (EncodedDispatch.unwrap(dispatch) > 0) { - (uint256[] memory stack, uint256[] memory kvs) = sI9r.eval( + (uint256[] memory stack, uint256[] memory kvs) = sI9r.eval2( sI9rStore, DEFAULT_STATE_NAMESPACE, dispatch, - LibContext.build(new uint256[][](0), new SignedContextV1[](0)) + LibContext.build(new uint256[][](0), new SignedContextV1[](0)), + new uint256[](0) ); // This can only happen if interpreter is broken. if (stack.length > 0) { diff --git a/src/abstract/OrderBookV3FlashBorrower.sol b/src/abstract/OrderBookV3FlashBorrower.sol index 13c2f112e..5464afa23 100644 --- a/src/abstract/OrderBookV3FlashBorrower.sol +++ b/src/abstract/OrderBookV3FlashBorrower.sol @@ -16,16 +16,15 @@ import {LibEncodedDispatch, EncodedDispatch} from "lib/rain.interpreter/src/lib/ import {LibContext} from "lib/rain.interpreter/src/lib/caller/LibContext.sol"; import {LibBytecode} from "lib/rain.interpreter/src/lib/bytecode/LibBytecode.sol"; import {ON_FLASH_LOAN_CALLBACK_SUCCESS} from "../interface/ierc3156/IERC3156FlashBorrower.sol"; -import {EvaluableConfigV2} from "rain.interpreter/src/lib/caller/LibEvaluable.sol"; import {IOrderBookV3, TakeOrdersConfigV2, NoOrders} from "../interface/unstable/IOrderBookV3.sol"; import {ICloneableV2, ICLONEABLE_V2_SUCCESS} from "lib/rain.factory/src/interface/ICloneableV2.sol"; import { - IInterpreterV2, SourceIndex, DEFAULT_STATE_NAMESPACE + IInterpreterV2, SourceIndexV2, DEFAULT_STATE_NAMESPACE } from "lib/rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; import {IERC3156FlashBorrower} from "../interface/ierc3156/IERC3156FlashBorrower.sol"; import {IInterpreterStoreV1} from "lib/rain.interpreter/src/interface/IInterpreterStoreV1.sol"; import {BadLender, MinimumOutput, NonZeroBeforeArbStack, Initializing} from "./OrderBookV3ArbCommon.sol"; -import {SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; +import {EvaluableConfigV3, SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; /// Thrown when the initiator is not the order book. /// @param badInitiator The untrusted initiator of the flash loan. @@ -37,6 +36,9 @@ error FlashLoanFailed(); /// Thrown when the swap fails. error SwapFailed(); +/// Thrown when "Before arb" expects inputs. +error NonZeroBeforeArbInputs(); + /// Config for `OrderBookV3FlashBorrower` to initialize. /// @param orderBook The `IOrderBookV3` contract to arb against. /// @param evaluableConfig The config to eval for access control to arb. @@ -44,17 +46,19 @@ error SwapFailed(); /// the `beforeInitialize` hook. struct OrderBookV3FlashBorrowerConfigV2 { address orderBook; - EvaluableConfigV2 evaluableConfig; + EvaluableConfigV3 evaluableConfig; bytes implementationData; } /// @dev "Before arb" is evaluated before the flash loan is taken. Ostensibly /// allows for some kind of access control to the arb. -SourceIndex constant BEFORE_ARB_SOURCE_INDEX = SourceIndex.wrap(0); +SourceIndexV2 constant BEFORE_ARB_SOURCE_INDEX = SourceIndexV2.wrap(0); +/// @dev "Before arb" has no inputs. +uint256 constant BEFORE_ARB_MIN_INPUTS = 0; /// @dev "Before arb" has no outputs. uint256 constant BEFORE_ARB_MIN_OUTPUTS = 0; /// @dev "Before arb" has no outputs. -uint16 constant BEFORE_ARB_MAX_OUTPUTS = 0; +uint256 constant BEFORE_ARB_MAX_OUTPUTS = 0; /// @title OrderBookV3FlashBorrower /// @notice Abstract contract that liq-source specifialized contracts can inherit @@ -108,7 +112,7 @@ abstract contract OrderBookV3FlashBorrower is /// The encoded dispatch that will run for access control to `arb`. EncodedDispatch public sI9rDispatch; /// The interpreter that will eval access control to `arb`. - IInterpreterV1 public sI9r; + IInterpreterV2 public sI9r; /// The associated store for the interpreter. IInterpreterStoreV1 public sI9rStore; @@ -156,18 +160,24 @@ abstract contract OrderBookV3FlashBorrower is if (LibBytecode.sourceCount(config.evaluableConfig.bytecode) > 0) { address expression; - uint256[] memory entrypoints = new uint256[](1); - entrypoints[SourceIndex.unwrap(BEFORE_ARB_SOURCE_INDEX)] = BEFORE_ARB_MIN_OUTPUTS; - + bytes memory io; // We have to trust the deployer because it produces the expression // address for the dispatch anyway. // All external functions on this contract have `onlyNotInitializing` // modifier on them so can't be reentered here anyway. //slither-disable-next-line reentrancy-benign - (sI9r, sI9rStore, expression) = config.evaluableConfig.deployer.deployExpression( - config.evaluableConfig.bytecode, config.evaluableConfig.constants, entrypoints + (sI9r, sI9rStore, expression, io) = config.evaluableConfig.deployer.deployExpression2( + config.evaluableConfig.bytecode, config.evaluableConfig.constants ); - sI9rDispatch = LibEncodedDispatch.encode(expression, BEFORE_ARB_SOURCE_INDEX, BEFORE_ARB_MAX_OUTPUTS); + // There can't be any inputs because we don't pass any in. + uint256 inputs; + assembly ("memory-safe") { + inputs := and(mload(add(io, 1)), 0xFF) + } + if (inputs > 0) { + revert NonZeroBeforeArbInputs(); + } + sI9rDispatch = LibEncodedDispatch.encode2(expression, BEFORE_ARB_SOURCE_INDEX, BEFORE_ARB_MAX_OUTPUTS); } return ICLONEABLE_V2_SUCCESS; @@ -278,11 +288,12 @@ abstract contract OrderBookV3FlashBorrower is // Run the access control dispatch if it is set. EncodedDispatch dispatch = sI9rDispatch; if (EncodedDispatch.unwrap(dispatch) > 0) { - (uint256[] memory stack, uint256[] memory kvs) = sI9r.eval( + (uint256[] memory stack, uint256[] memory kvs) = sI9r.eval2( sI9rStore, DEFAULT_STATE_NAMESPACE, dispatch, - LibContext.build(new uint256[][](0), new SignedContextV1[](0)) + LibContext.build(new uint256[][](0), new SignedContextV1[](0)), + new uint256[](0) ); // This can only happen if the interpreter is broken. if (stack.length > 0) { diff --git a/src/concrete/OrderBook.sol b/src/concrete/OrderBook.sol index 6c44b29bb..a854a1fc8 100644 --- a/src/concrete/OrderBook.sol +++ b/src/concrete/OrderBook.sol @@ -19,13 +19,13 @@ import { LibMeta } from "rain.interpreter/src/abstract/DeployerDiscoverableMetaV3.sol"; import {LibBytecode} from "rain.interpreter/src/lib/bytecode/LibBytecode.sol"; -import {SourceIndex, StateNamespace, IInterpreterV2} from "rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; +import {SourceIndexV2, StateNamespace, IInterpreterV2} from "rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; import { IOrderBookV3, NoOrders, - Order, + OrderV2, OrderConfigV2, - TakeOrderConfig, + TakeOrderConfigV2, TakeOrdersConfigV2, ClearConfig, ClearStateChange, @@ -36,7 +36,7 @@ import {LibOrder} from "../lib/LibOrder.sol"; import {OrderBookV3FlashLender} from "../abstract/OrderBookV3FlashLender.sol"; import {LibUint256Array} from "rain.solmem/lib/LibUint256Array.sol"; import {SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; -import {Evaluable} from "rain.interpreter/src/lib/caller/LibEvaluable.sol"; +import {EvaluableV2} from "rain.interpreter/src/lib/caller/LibEvaluable.sol"; import {IInterpreterStoreV1} from "rain.interpreter/src/interface/IInterpreterStoreV1.sol"; import {IExpressionDeployerV3} from "rain.interpreter/src/interface/unstable/IExpressionDeployerV3.sol"; @@ -69,6 +69,18 @@ error MinimumInput(uint256 minimumInput, uint256 input); /// @param owner The owner of both orders. error SameOwner(address owner); +/// Thrown when calculate order expression wants inputs. +/// @param inputs The inputs the expression wants. +error UnsupportedCalculateInputs(uint256 inputs); + +/// Thrown when calculate order expression offers too few outputs. +/// @param outputs The outputs the expression offers. +error UnsupportedCalculateOutputs(uint256 outputs); + +/// Thrown when handle IO expression wants inputs. +/// @param inputs The inputs the expression wants. +error UnsupportedHandleInputs(uint256 inputs); + /// @dev Stored value for a live order. NOT a boolean because storing a boolean /// is more expensive than storing a uint256. uint256 constant ORDER_LIVE = 1; @@ -79,10 +91,10 @@ uint256 constant ORDER_LIVE = 1; uint256 constant ORDER_DEAD = 0; /// @dev Entrypoint to a calculate the amount and ratio of an order. -SourceIndex constant CALCULATE_ORDER_ENTRYPOINT = SourceIndex.wrap(0); +SourceIndexV2 constant CALCULATE_ORDER_ENTRYPOINT = SourceIndexV2.wrap(0); /// @dev Entrypoint to handle the final internal vault movements resulting from /// matching multiple calculated orders. -SourceIndex constant HANDLE_IO_ENTRYPOINT = SourceIndex.wrap(1); +SourceIndexV2 constant HANDLE_IO_ENTRYPOINT = SourceIndexV2.wrap(1); /// @dev Minimum outputs for calculate order are the amount and ratio. uint256 constant CALCULATE_ORDER_MIN_OUTPUTS = 2; @@ -171,8 +183,8 @@ bytes32 constant CALLER_META_HASH = bytes32(0xd6912c2a900b10b78c9c43592b8690b48c /// IO state changes. /// @param kvs KVs returned from calculate order entrypoint to pass to the store /// before calling handle IO entrypoint. -struct OrderIOCalculation { - Order order; +struct OrderIOCalculationV2 { + OrderV2 order; uint256 outputIOIndex; Output18Amount outputMax; //solhint-disable-next-line var-name-mixedcase @@ -191,7 +203,7 @@ type Input18Amount is uint256; contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3FlashLender, DeployerDiscoverableMetaV3 { using LibUint256Array for uint256[]; using SafeERC20 for IERC20; - using LibOrder for Order; + using LibOrder for OrderV2; using LibUint256Array for uint256; using Math for uint256; using LibFixedPointDecimalScale for uint256; @@ -270,33 +282,55 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash function addOrder(OrderConfigV2 calldata config) external nonReentrant returns (bool stateChanged) { uint256 sourceCount = LibBytecode.sourceCount(config.evaluableConfig.bytecode); if (sourceCount == 0) { - revert OrderNoSources(msg.sender); + revert OrderNoSources(); } if (sourceCount == 1) { - revert OrderNoHandleIO(msg.sender); + revert OrderNoHandleIO(); } if (config.validInputs.length == 0) { - revert OrderNoInputs(msg.sender); + revert OrderNoInputs(); } if (config.validOutputs.length == 0) { - revert OrderNoOutputs(msg.sender); + revert OrderNoOutputs(); } - (IInterpreterV1 interpreter, IInterpreterStoreV1 store, address expression) = config + (IInterpreterV2 interpreter, IInterpreterStoreV1 store, address expression, bytes memory io) = config .evaluableConfig .deployer - .deployExpression( + .deployExpression2( config.evaluableConfig.bytecode, - config.evaluableConfig.constants, - LibUint256Array.arrayFrom(CALCULATE_ORDER_MIN_OUTPUTS, HANDLE_IO_MIN_OUTPUTS) + config.evaluableConfig.constants ); + { + uint256 calculateInputs; + uint256 calculateOutputs; + uint256 handleInputs; + assembly ("memory-safe") { + let ioWord := mload(add(io, 0x20)) + calculateInputs := byte(0, ioWord) + calculateOutputs := byte(1, ioWord) + handleInputs := byte(2, ioWord) + } + + if (calculateInputs != 0) { + revert UnsupportedCalculateInputs(calculateInputs); + } + + if (calculateOutputs < CALCULATE_ORDER_MIN_OUTPUTS) { + revert UnsupportedCalculateOutputs(calculateOutputs); + } + + if (handleInputs != 0) { + revert UnsupportedHandleInputs(handleInputs); + } + } // Merge our view on the sender/owner and handle IO emptiness with the - // config and deployer's view on the `Evaluable` to produce the final + // config and deployer's view on the `EvaluableV2` to produce the final // order. - Order memory order = Order( + OrderV2 memory order = OrderV2( msg.sender, - LibBytecode.sourceOpsLength(config.evaluableConfig.bytecode, SourceIndex.unwrap(HANDLE_IO_ENTRYPOINT)) > 0, - Evaluable(interpreter, store, expression), + LibBytecode.sourceOpsCount(config.evaluableConfig.bytecode, SourceIndexV2.unwrap(HANDLE_IO_ENTRYPOINT)) > 0, + EvaluableV2(interpreter, store, expression), config.validInputs, config.validOutputs ); @@ -323,7 +357,7 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash } /// @inheritdoc IOrderBookV3 - function removeOrder(Order calldata order) external nonReentrant returns (bool stateChanged) { + function removeOrder(OrderV2 calldata order) external nonReentrant returns (bool stateChanged) { if (msg.sender != order.owner) { revert NotOrderOwner(msg.sender, order.owner); } @@ -348,8 +382,8 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash revert NoOrders(); } - TakeOrderConfig memory takeOrderConfig; - Order memory order; + TakeOrderConfigV2 memory takeOrderConfig; + OrderV2 memory order; // Allocate a region of memory to hold pointers. We don't know how many // will run at this point, but we conservatively set aside a slot for @@ -357,7 +391,7 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash // resize the array later. There's no guarantee that a dynamic solution // would even be cheaper gas-wise, and it would almost certainly be more // complex. - OrderIOCalculation[] memory orderIOCalculationsToHandle; + OrderIOCalculationV2[] memory orderIOCalculationsToHandle; { uint256 length = config.orders.length; assembly ("memory-safe") { @@ -421,7 +455,7 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash if (sOrders[orderHash] == ORDER_DEAD) { emit OrderNotFound(msg.sender, order.owner, orderHash); } else { - OrderIOCalculation memory orderIOCalculation = calculateOrderIO( + OrderIOCalculationV2 memory orderIOCalculation = calculateOrderIO( order, takeOrderConfig.inputIOIndex, takeOrderConfig.outputIOIndex, @@ -546,8 +580,8 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash /// @inheritdoc IOrderBookV3 function clear( - Order memory aliceOrder, - Order memory bobOrder, + OrderV2 memory aliceOrder, + OrderV2 memory bobOrder, ClearConfig calldata clearConfig, SignedContextV1[] memory aliceSignedContext, SignedContextV1[] memory bobSignedContext @@ -611,10 +645,10 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash // Emit the Clear event before `eval2`. emit Clear(msg.sender, aliceOrder, bobOrder, clearConfig); } - OrderIOCalculation memory aliceOrderIOCalculation = calculateOrderIO( + OrderIOCalculationV2 memory aliceOrderIOCalculation = calculateOrderIO( aliceOrder, clearConfig.aliceInputIOIndex, clearConfig.aliceOutputIOIndex, bobOrder.owner, bobSignedContext ); - OrderIOCalculation memory bobOrderIOCalculation = calculateOrderIO( + OrderIOCalculationV2 memory bobOrderIOCalculation = calculateOrderIO( bobOrder, clearConfig.bobInputIOIndex, clearConfig.bobOutputIOIndex, aliceOrder.owner, aliceSignedContext ); ClearStateChange memory clearStateChange = @@ -656,12 +690,12 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash /// @param signedContext Any signed context provided by the clearer/taker /// that the order may need for its calculations. function calculateOrderIO( - Order memory order, + OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex, address counterparty, SignedContextV1[] memory signedContext - ) internal view returns (OrderIOCalculation memory) { + ) internal view returns (OrderIOCalculationV2 memory) { unchecked { bytes32 orderHash = order.hash(); @@ -707,7 +741,7 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash (uint256[] memory calculateOrderStack, uint256[] memory calculateOrderKVs) = order .evaluable .interpreter - .eval2(order.evaluable.store, namespace, _calculateOrderDispatch(order.evaluable.expression), context); + .eval2(order.evaluable.store, namespace, _calculateOrderDispatch(order.evaluable.expression), context, new uint256[](0)); Output18Amount orderOutputMax18 = Output18Amount.wrap(calculateOrderStack[calculateOrderStack.length - 2]); uint256 orderIORatio = calculateOrderStack[calculateOrderStack.length - 1]; @@ -741,7 +775,7 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash context[CONTEXT_CALCULATIONS_COLUMN] = LibUint256Array.arrayFrom(Output18Amount.unwrap(orderOutputMax18), orderIORatio); - return OrderIOCalculation( + return OrderIOCalculationV2( order, outputIOIndex, orderOutputMax18, orderIORatio, context, namespace, calculateOrderKVs ); } @@ -756,7 +790,7 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash /// vault. /// @param orderIOCalculation The verbatim order IO calculation returned by /// `_calculateOrderIO`. - function recordVaultIO(uint256 input, uint256 output, OrderIOCalculation memory orderIOCalculation) internal { + function recordVaultIO(uint256 input, uint256 output, OrderIOCalculationV2 memory orderIOCalculation) internal { orderIOCalculation.context[CONTEXT_VAULT_INPUTS_COLUMN][CONTEXT_VAULT_IO_BALANCE_DIFF] = input; orderIOCalculation.context[CONTEXT_VAULT_OUTPUTS_COLUMN][CONTEXT_VAULT_IO_BALANCE_DIFF] = output; @@ -778,7 +812,7 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash emit Context(msg.sender, orderIOCalculation.context); } - function handleIO(OrderIOCalculation memory orderIOCalculation) internal { + function handleIO(OrderIOCalculationV2 memory orderIOCalculation) internal { // Apply state changes to the interpreter store after the vault balances // are updated, but before we call handle IO. We want handle IO to see // a consistent view on sets from calculate IO. @@ -809,7 +843,8 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash orderIOCalculation.order.evaluable.store, orderIOCalculation.namespace, _handleIODispatch(orderIOCalculation.order.evaluable.expression), - orderIOCalculation.context + orderIOCalculation.context, + new uint256[](0) ); // There's nothing to be done with the stack. (handleIOStack); @@ -835,8 +870,8 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash /// @return clearStateChange The clear state change with absolute inputs and /// outputs for Alice and Bob. function calculateClearStateChange( - OrderIOCalculation memory aliceOrderIOCalculation, - OrderIOCalculation memory bobOrderIOCalculation + OrderIOCalculationV2 memory aliceOrderIOCalculation, + OrderIOCalculationV2 memory bobOrderIOCalculation ) internal pure returns (ClearStateChange memory clearStateChange) { // Calculate the clear state change for Alice. (clearStateChange.aliceInput, clearStateChange.aliceOutput) = @@ -848,8 +883,8 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash } function calculateClearStateAlice( - OrderIOCalculation memory aliceOrderIOCalculation, - OrderIOCalculation memory bobOrderIOCalculation + OrderIOCalculationV2 memory aliceOrderIOCalculation, + OrderIOCalculationV2 memory bobOrderIOCalculation ) internal pure returns (uint256 aliceInput, uint256 aliceOutput) { // Always round IO calculations up so that the counterparty pays more. // This is the max input that bob can afford, given his own IO ratio @@ -886,10 +921,10 @@ contract OrderBook is IOrderBookV3, ReentrancyGuard, Multicall, OrderBookV3Flash } function _calculateOrderDispatch(address expression_) internal pure returns (EncodedDispatch) { - return LibEncodedDispatch.encode(expression_, CALCULATE_ORDER_ENTRYPOINT, CALCULATE_ORDER_MAX_OUTPUTS); + return LibEncodedDispatch.encode2(expression_, CALCULATE_ORDER_ENTRYPOINT, CALCULATE_ORDER_MAX_OUTPUTS); } function _handleIODispatch(address expression_) internal pure returns (EncodedDispatch) { - return LibEncodedDispatch.encode(expression_, HANDLE_IO_ENTRYPOINT, HANDLE_IO_MAX_OUTPUTS); + return LibEncodedDispatch.encode2(expression_, HANDLE_IO_ENTRYPOINT, HANDLE_IO_MAX_OUTPUTS); } } diff --git a/src/interface/IOrderBookV2.sol b/src/interface/deprecated/IOrderBookV2.sol similarity index 98% rename from src/interface/IOrderBookV2.sol rename to src/interface/deprecated/IOrderBookV2.sol index c7ed6f94f..4f25a93e2 100644 --- a/src/interface/IOrderBookV2.sol +++ b/src/interface/deprecated/IOrderBookV2.sol @@ -1,9 +1,10 @@ // SPDX-License-Identifier: CAL pragma solidity ^0.8.18; -import "./ierc3156/IERC3156FlashLender.sol"; -import "lib/rain.interpreter/src/lib/caller/LibEvaluable.sol"; -import "lib/rain.interpreter/src/interface/IInterpreterCallerV2.sol"; +import {IERC3156FlashLender} from "../ierc3156/IERC3156FlashLender.sol"; +import {EvaluableConfig, Evaluable} from "lib/rain.interpreter/src/interface/deprecated/IInterpreterCallerV1.sol"; +import {SignedContextV1, IInterpreterCallerV2} from "lib/rain.interpreter/src/interface/IInterpreterCallerV2.sol"; +import {IExpressionDeployerV2} from "lib/rain.interpreter/src/interface/deprecated/IExpressionDeployerV2.sol"; /// Configuration for a deposit. All deposits are processed by and for /// `msg.sender` so the vaults are unambiguous here. @@ -321,7 +322,7 @@ interface IOrderBookV2 is IERC3156FlashLender, IInterpreterCallerV2 { /// @param orderHash The hash of the order as it is recorded onchain. Only /// the hash is stored in Orderbook storage to avoid paying gas to store the /// entire order. - event AddOrder(address sender, IExpressionDeployerV3 expressionDeployer, Order order, uint256 orderHash); + event AddOrder(address sender, IExpressionDeployerV2 expressionDeployer, Order order, uint256 orderHash); /// An order has been removed from the orderbook. This effectively /// deactivates it. Orders can be added again after removal. diff --git a/src/interface/unstable/IOrderBookV3.sol b/src/interface/unstable/IOrderBookV3.sol index 9c979cf48..b4676f3c7 100644 --- a/src/interface/unstable/IOrderBookV3.sol +++ b/src/interface/unstable/IOrderBookV3.sol @@ -3,12 +3,12 @@ pragma solidity ^0.8.18; import "../ierc3156/IERC3156FlashLender.sol"; import { - EvaluableConfigV2, IExpressionDeployerV3, Evaluable + IExpressionDeployerV3, EvaluableV2 } from "lib/rain.interpreter/src/lib/caller/LibEvaluable.sol"; -import "lib/rain.interpreter/src/interface/IInterpreterCallerV2.sol"; +import {EvaluableConfigV3, IInterpreterCallerV2, SignedContextV1} from "lib/rain.interpreter/src/interface/IInterpreterCallerV2.sol"; /// Import unmodified structures from older versions of `IOrderBook`. -import {IO, Order, TakeOrderConfig, ClearConfig, ClearStateChange} from "../IOrderBookV2.sol"; +import {IO, ClearConfig, ClearStateChange} from "../deprecated/IOrderBookV2.sol"; /// Thrown when take orders is called with no orders. error NoOrders(); @@ -31,10 +31,48 @@ error ZeroMaximumInput(); struct OrderConfigV2 { IO[] validInputs; IO[] validOutputs; - EvaluableConfigV2 evaluableConfig; + EvaluableConfigV3 evaluableConfig; bytes meta; } +/// Config for an individual take order from the overall list of orders in a +/// call to `takeOrders`. +/// @param order The order being taken this iteration. +/// @param inputIOIndex The index of the input token in `order` to match with the +/// take order output. +/// @param outputIOIndex The index of the output token in `order` to match with +/// the take order input. +/// @param signedContext Optional additional signed context relevant to the +/// taken order. +struct TakeOrderConfigV2 { + OrderV2 order; + uint256 inputIOIndex; + uint256 outputIOIndex; + SignedContextV1[] signedContext; +} + +/// Defines a fully deployed order ready to evaluate by Orderbook. Identical to +/// `Order` except for the newer `EvaluableV2`. +/// @param owner The owner of the order is the `msg.sender` that added the order. +/// @param handleIO true if there is a "handle IO" entrypoint to run. If false +/// the order book MAY skip calling the interpreter to save gas. +/// @param evaluable Standard `EvaluableV2` with entrypoints for both +/// "calculate order" and "handle IO". The latter MAY be empty bytes, in which +/// case it will be skipped at runtime to save gas. +/// @param validInputs A list of input tokens that are economically equivalent +/// for the purpose of processing this order. Inputs are relative to the order +/// so these tokens will be sent to the owners vault. +/// @param validOutputs A list of output tokens that are economically equivalent +/// for the purpose of processing this order. Outputs are relative to the order +/// so these tokens will be sent from the owners vault. +struct OrderV2 { + address owner; + bool handleIO; + EvaluableV2 evaluable; + IO[] validInputs; + IO[] validOutputs; +} + /// Config for a list of orders to take sequentially as part of a `takeOrders` /// call. /// @param minimumInput Minimum input from the perspective of the order taker. @@ -54,7 +92,7 @@ struct TakeOrdersConfigV2 { uint256 minimumInput; uint256 maximumInput; uint256 maximumIORatio; - TakeOrderConfig[] orders; + TakeOrderConfigV2[] orders; bytes data; } @@ -214,20 +252,16 @@ interface IOrderBookV3 is IERC3156FlashLender, IInterpreterCallerV2 { error ZeroWithdrawTargetAmount(address sender, address token, uint256 vaultId); /// MUST be thrown by `addOrder` if the order has no associated calculation. - /// @param sender `msg.sender` adding the order. - error OrderNoSources(address sender); + error OrderNoSources(); /// MUST be thrown by `addOrder` if the order has no associated handle IO. - /// @param sender `msg.sender` adding the order. - error OrderNoHandleIO(address sender); + error OrderNoHandleIO(); /// MUST be thrown by `addOrder` if the order has no inputs. - /// @param sender `msg.sender` adding the order. - error OrderNoInputs(address sender); + error OrderNoInputs(); /// MUST be thrown by `addOrder` if the order has no outputs. - /// @param sender `msg.sender` adding the order. - error OrderNoOutputs(address sender); + error OrderNoOutputs(); /// Some tokens have been deposited to a vault. /// @param sender `msg.sender` depositing tokens. Delegated deposits are NOT @@ -262,14 +296,14 @@ interface IOrderBookV3 is IERC3156FlashLender, IInterpreterCallerV2 { /// @param orderHash The hash of the order as it is recorded onchain. Only /// the hash is stored in Orderbook storage to avoid paying gas to store the /// entire order. - event AddOrder(address sender, IExpressionDeployerV3 expressionDeployer, Order order, bytes32 orderHash); + event AddOrder(address sender, IExpressionDeployerV3 expressionDeployer, OrderV2 order, bytes32 orderHash); /// An order has been removed from the orderbook. This effectively /// deactivates it. Orders can be added again after removal. /// @param sender `msg.sender` removing the order and is owner of the order. /// @param order The removed order. /// @param orderHash The hash of the removed order. - event RemoveOrder(address sender, Order order, bytes32 orderHash); + event RemoveOrder(address sender, OrderV2 order, bytes32 orderHash); /// Some order has been taken by `msg.sender`. This is the same as them /// placing inverse orders then immediately clearing them all, but costs less @@ -280,7 +314,7 @@ interface IOrderBookV3 is IERC3156FlashLender, IInterpreterCallerV2 { /// @param config All config defining the orders to attempt to take. /// @param input The input amount from the perspective of sender. /// @param output The output amount from the perspective of sender. - event TakeOrder(address sender, TakeOrderConfig config, uint256 input, uint256 output); + event TakeOrder(address sender, TakeOrderConfigV2 config, uint256 input, uint256 output); /// Emitted when attempting to match an order that either never existed or /// was removed. An event rather than an error so that we allow attempting @@ -312,7 +346,7 @@ interface IOrderBookV3 is IERC3156FlashLender, IInterpreterCallerV2 { /// @param alice One of the orders. /// @param bob The other order. /// @param clearConfig Additional config required to process the clearance. - event Clear(address sender, Order alice, Order bob, ClearConfig clearConfig); + event Clear(address sender, OrderV2 alice, OrderV2 bob, ClearConfig clearConfig); /// Emitted after two orders clear. Includes all final state changes in the /// vault balances, including the clearer's vaults. @@ -413,7 +447,7 @@ interface IOrderBookV3 is IERC3156FlashLender, IInterpreterCallerV2 { /// @param order The `Order` data exactly as it was added. /// @return stateChanged True if the order was removed, false if it did not /// exist. - function removeOrder(Order calldata order) external returns (bool stateChanged); + function removeOrder(OrderV2 calldata order) external returns (bool stateChanged); /// Allows `msg.sender` to attempt to fill a list of orders in sequence /// without needing to place their own order and clear them. This works like @@ -505,8 +539,8 @@ interface IOrderBookV3 is IERC3156FlashLender, IInterpreterCallerV2 { /// @param aliceSignedContext Optional signed context that is relevant to A. /// @param bobSignedContext Optional signed context that is relevant to B. function clear( - Order memory alice, - Order memory bob, + OrderV2 memory alice, + OrderV2 memory bob, ClearConfig calldata clearConfig, SignedContextV1[] memory aliceSignedContext, SignedContextV1[] memory bobSignedContext diff --git a/src/interface/unstable/IOrderBookV3ArbOrderTaker.sol b/src/interface/unstable/IOrderBookV3ArbOrderTaker.sol index 9a1fa234b..f321dd666 100644 --- a/src/interface/unstable/IOrderBookV3ArbOrderTaker.sol +++ b/src/interface/unstable/IOrderBookV3ArbOrderTaker.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: CAL pragma solidity ^0.8.18; -import "./IOrderBookV3OrderTaker.sol"; -import "./IOrderBookV3.sol"; +import {IOrderBookV3OrderTaker} from "./IOrderBookV3OrderTaker.sol"; +import {TakeOrdersConfigV2} from "./IOrderBookV3.sol"; interface IOrderBookV3ArbOrderTaker is IOrderBookV3OrderTaker { function arb(TakeOrdersConfigV2 calldata takeOrders, uint256 minimumSenderOutput) external payable; diff --git a/src/lib/LibOrder.sol b/src/lib/LibOrder.sol index d2338fbac..ad47b9aa4 100644 --- a/src/lib/LibOrder.sol +++ b/src/lib/LibOrder.sol @@ -4,15 +4,15 @@ pragma solidity ^0.8.18; import "../interface/unstable/IOrderBookV3.sol"; /// @title LibOrder -/// @notice Consistent handling of `Order` for where it matters w.r.t. +/// @notice Consistent handling of `OrderV2` for where it matters w.r.t. /// determinism and security. library LibOrder { - /// Hashes `Order` in a secure and deterministic way. Uses abi.encode rather - /// than abi.encodePacked to guard against potential collisions where many - /// inputs encode to the same output bytes. + /// Hashes `OrderV2` in a secure and deterministic way. Uses abi.encode + /// rather than abi.encodePacked to guard against potential collisions where + /// many inputs encode to the same output bytes. /// @param order The order to hash. /// @return The hash of `order`. - function hash(Order memory order) internal pure returns (bytes32) { + function hash(OrderV2 memory order) internal pure returns (bytes32) { return keccak256(abi.encode(order)); } } diff --git a/test/concrete/GenericPoolOrderBookV3ArbOrderTaker.sender.t.sol b/test/concrete/GenericPoolOrderBookV3ArbOrderTaker.sender.t.sol index 840094fc2..060871c64 100644 --- a/test/concrete/GenericPoolOrderBookV3ArbOrderTaker.sender.t.sol +++ b/test/concrete/GenericPoolOrderBookV3ArbOrderTaker.sender.t.sol @@ -21,14 +21,14 @@ contract GenericPoolOrderBookV3ArbOrderTakerTest is ArbTest { ICloneableV2(iArb).initialize( abi.encode( OrderBookV3ArbOrderTakerConfigV1( - address(iOrderBook), EvaluableConfigV2(IExpressionDeployerV3(address(0)), "", new uint256[](0)), "" + address(iOrderBook), EvaluableConfigV3(IExpressionDeployerV3(address(0)), "", new uint256[](0)), "" ) ) ); } - function testTakeOrdersSender(Order memory order, uint256 inputIOIndex, uint256 outputIOIndex) public { - TakeOrderConfig[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); + function testTakeOrdersSender(OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex) public { + TakeOrderConfigV2[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); GenericPoolOrderBookV3ArbOrderTaker(iArb).arb( TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, orders, abi.encode(iRefundoor, iRefundoor, "")), @@ -37,7 +37,7 @@ contract GenericPoolOrderBookV3ArbOrderTakerTest is ArbTest { } function testMinimumOutput( - Order memory order, + OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex, uint256 minimumOutput, @@ -47,7 +47,7 @@ contract GenericPoolOrderBookV3ArbOrderTakerTest is ArbTest { minimumOutput = bound(minimumOutput, mintAmount + 1, type(uint256).max); iTakerOutput.mint(iArb, mintAmount); - TakeOrderConfig[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); + TakeOrderConfigV2[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); vm.expectRevert(abi.encodeWithSelector(MinimumOutput.selector, minimumOutput, mintAmount)); GenericPoolOrderBookV3ArbOrderTaker(iArb).arb( diff --git a/test/concrete/GenericPoolOrderBookV3FlashBorrower.sender.t.sol b/test/concrete/GenericPoolOrderBookV3FlashBorrower.sender.t.sol index cc1bd81b7..b022b7721 100644 --- a/test/concrete/GenericPoolOrderBookV3FlashBorrower.sender.t.sol +++ b/test/concrete/GenericPoolOrderBookV3FlashBorrower.sender.t.sol @@ -21,14 +21,14 @@ contract GenericPoolOrderBookV3FlashBorrowerTest is ArbTest { ICloneableV2(iArb).initialize( abi.encode( OrderBookV3FlashBorrowerConfigV2( - address(iOrderBook), EvaluableConfigV2(IExpressionDeployerV3(address(0)), "", new uint256[](0)), "" + address(iOrderBook), EvaluableConfigV3(IExpressionDeployerV3(address(0)), "", new uint256[](0)), "" ) ) ); } - function testTakeOrdersSender(Order memory order, uint256 inputIOIndex, uint256 outputIOIndex) public { - TakeOrderConfig[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); + function testTakeOrdersSender(OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex) public { + TakeOrderConfigV2[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); GenericPoolOrderBookV3FlashBorrower(iArb).arb( TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, orders, ""), @@ -38,7 +38,7 @@ contract GenericPoolOrderBookV3FlashBorrowerTest is ArbTest { } function testMinimumOutput( - Order memory order, + OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex, uint256 minimumOutput, @@ -48,7 +48,7 @@ contract GenericPoolOrderBookV3FlashBorrowerTest is ArbTest { minimumOutput = bound(minimumOutput, mintAmount + 1, type(uint256).max); iTakerOutput.mint(iArb, mintAmount); - TakeOrderConfig[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); + TakeOrderConfigV2[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); vm.expectRevert(abi.encodeWithSelector(MinimumOutput.selector, minimumOutput, mintAmount)); GenericPoolOrderBookV3FlashBorrower(iArb).arb( diff --git a/test/concrete/OrderBook.addOrder.mock.t.sol b/test/concrete/OrderBook.addOrder.mock.t.sol index 9caa43ad2..ff2da95c8 100644 --- a/test/concrete/OrderBook.addOrder.mock.t.sol +++ b/test/concrete/OrderBook.addOrder.mock.t.sol @@ -1,8 +1,12 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; -import "test/util/abstract/OrderBookExternalMockTest.sol"; -import "test/util/lib/LibTestAddOrder.sol"; +import {OrderBookExternalMockTest} from "test/util/abstract/OrderBookExternalMockTest.sol"; +import {OrderConfigV2, OrderV2, IO} from "src/interface/unstable/IOrderBookV3.sol"; +import {LibTestAddOrder} from "test/util/lib/LibTestAddOrder.sol"; +import {NotRainMetaV1, META_MAGIC_NUMBER_V1} from "rain.metadata/IMetaV1.sol"; +import {LibMeta} from "rain.metadata/LibMeta.sol"; +import {IExpressionDeployerV3} from "rain.interpreter/src/interface/unstable/IExpressionDeployerV3.sol"; /// @title OrderBookAddOrderMockTest /// @notice Tests the addOrder function of the OrderBook contract. @@ -13,7 +17,7 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { config.evaluableConfig.bytecode = ""; vm.expectRevert(abi.encodeWithSelector(OrderNoSources.selector, owner)); iOrderbook.addOrder(config); - (Order memory order, bytes32 orderHash) = + (OrderV2 memory order, bytes32 orderHash) = LibTestAddOrder.expectedOrder(owner, config, iInterpreter, iStore, address(0)); (order); assertTrue(!iOrderbook.orderExists(orderHash)); @@ -26,7 +30,7 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { config.validInputs = new IO[](0); vm.expectRevert(abi.encodeWithSelector(OrderNoInputs.selector, owner)); iOrderbook.addOrder(config); - (Order memory order, bytes32 orderHash) = + (OrderV2 memory order, bytes32 orderHash) = LibTestAddOrder.expectedOrder(owner, config, iInterpreter, iStore, address(0)); (order); assertTrue(!iOrderbook.orderExists(orderHash)); @@ -40,7 +44,7 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { config.validOutputs = new IO[](0); vm.expectRevert(abi.encodeWithSelector(OrderNoOutputs.selector, owner)); iOrderbook.addOrder(config); - (Order memory order, bytes32 orderHash) = + (OrderV2 memory order, bytes32 orderHash) = LibTestAddOrder.expectedOrder(owner, config, iInterpreter, iStore, address(0)); (order); assertTrue(!iOrderbook.orderExists(orderHash)); @@ -58,7 +62,7 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { vm.assume(config.validInputs.length > 0); vm.assume(config.validOutputs.length > 0); config.meta = new bytes(0); - (Order memory order, bytes32 orderhash) = addOrderWithChecks(owner, config, expression); + (OrderV2 memory order, bytes32 orderhash) = addOrderWithChecks(owner, config, expression); (order); (orderhash); } @@ -78,13 +82,13 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { config.evaluableConfig.deployer = iDeployer; vm.mockCall( address(iDeployer), - abi.encodeWithSelector(IExpressionDeployerV3.deployExpression.selector), - abi.encode(iInterpreter, iStore, expression) + abi.encodeWithSelector(IExpressionDeployerV3.deployExpression2.selector), + abi.encode(iInterpreter, iStore, expression, "") ); vm.expectRevert(abi.encodeWithSelector(NotRainMetaV1.selector, config.meta)); iOrderbook.addOrder(config); - (Order memory order, bytes32 orderHash) = + (OrderV2 memory order, bytes32 orderHash) = LibTestAddOrder.expectedOrder(owner, config, iInterpreter, iStore, expression); (order); assertTrue(!iOrderbook.orderExists(orderHash)); @@ -104,7 +108,7 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { // meta document. config.meta = abi.encodePacked(META_MAGIC_NUMBER_V1, config.meta); - (Order memory order, bytes32 orderHash) = addOrderWithChecks(owner, config, expression); + (OrderV2 memory order, bytes32 orderHash) = addOrderWithChecks(owner, config, expression); (order); (orderHash); } @@ -119,8 +123,8 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { ) public { vm.assume(alice != bob); LibTestAddOrder.conformConfig(config, iDeployer); - (Order memory aliceOrder, bytes32 aliceOrderHash) = addOrderWithChecks(alice, config, expression); - (Order memory bobOrder, bytes32 bobOrderHash) = addOrderWithChecks(bob, config, expression); + (OrderV2 memory aliceOrder, bytes32 aliceOrderHash) = addOrderWithChecks(alice, config, expression); + (OrderV2 memory bobOrder, bytes32 bobOrderHash) = addOrderWithChecks(bob, config, expression); (aliceOrder); (bobOrder); assertTrue(aliceOrderHash != bobOrderHash); @@ -139,8 +143,8 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { vm.assume(alice != bob); LibTestAddOrder.conformConfig(aliceConfig, iDeployer); LibTestAddOrder.conformConfig(bobConfig, iDeployer); - (Order memory aliceOrder, bytes32 aliceOrderHash) = addOrderWithChecks(alice, aliceConfig, aliceExpression); - (Order memory bobOrder, bytes32 bobOrderHash) = addOrderWithChecks(bob, bobConfig, bobExpression); + (OrderV2 memory aliceOrder, bytes32 aliceOrderHash) = addOrderWithChecks(alice, aliceConfig, aliceExpression); + (OrderV2 memory bobOrder, bytes32 bobOrderHash) = addOrderWithChecks(bob, bobConfig, bobExpression); (aliceOrder); (bobOrder); assertTrue(aliceOrderHash != bobOrderHash); @@ -157,15 +161,15 @@ contract OrderBookAddOrderMockTest is OrderBookExternalMockTest { ) public { LibTestAddOrder.conformConfig(configOne, iDeployer); LibTestAddOrder.conformConfig(configTwo, iDeployer); - (Order memory expectedOrderOne, bytes32 expectedOrderOneHash) = + (OrderV2 memory expectedOrderOne, bytes32 expectedOrderOneHash) = LibTestAddOrder.expectedOrder(alice, configOne, iInterpreter, iStore, expressionOne); - (Order memory expectedOrderTwo, bytes32 expectedOrderTwoHash) = + (OrderV2 memory expectedOrderTwo, bytes32 expectedOrderTwoHash) = LibTestAddOrder.expectedOrder(alice, configTwo, iInterpreter, iStore, expressionTwo); (expectedOrderOne); (expectedOrderTwo); assertTrue(expectedOrderOneHash != expectedOrderTwoHash); - (Order memory orderOne, bytes32 orderOneHash) = addOrderWithChecks(alice, configOne, expressionOne); - (Order memory orderTwo, bytes32 orderTwoHash) = addOrderWithChecks(alice, configTwo, expressionTwo); + (OrderV2 memory orderOne, bytes32 orderOneHash) = addOrderWithChecks(alice, configOne, expressionOne); + (OrderV2 memory orderTwo, bytes32 orderTwoHash) = addOrderWithChecks(alice, configTwo, expressionTwo); (orderOne); (orderTwo); assertTrue(orderOneHash != orderTwoHash); diff --git a/test/concrete/OrderBook.addOrder.t.sol b/test/concrete/OrderBook.addOrder.t.sol index 4e1aa4a3a..ae5568cca 100644 --- a/test/concrete/OrderBook.addOrder.t.sol +++ b/test/concrete/OrderBook.addOrder.t.sol @@ -1,8 +1,10 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; -import "test/util/abstract/OrderBookExternalRealTest.sol"; +import {OrderBookExternalRealTest} from "test/util/abstract/OrderBookExternalRealTest.sol"; import {LibTestAddOrder} from "test/util/lib/LibTestAddOrder.sol"; +import {OrderConfigV2} from "src/interface/unstable/IOrderBookV3.sol"; +import {IParserV1} from "rain.interpreter/src/interface/IParserV1.sol"; /// @title OrderBookAddOrderTest /// @notice A test harness for testing the OrderBook addOrder function. @@ -27,28 +29,28 @@ contract OrderBookAddOrderTest is OrderBookExternalRealTest { iOrderbook.addOrder(config); } - /// A stack of 0 for calculate order reverts. - function testAddOrderRealZeroStackCalculateReverts(address owner, OrderConfigV2 memory config) public { - LibTestAddOrder.conformConfig(config, iDeployer); - (bytes memory bytecode, uint256[] memory constants) = IParserV1(address(iDeployer)).parse(":;:;"); - config.evaluableConfig.constants = constants; - config.evaluableConfig.bytecode = bytecode; - vm.expectRevert(abi.encodeWithSelector(EntrypointMinOutputs.selector, 0, 0, 2)); - vm.prank(owner); - iOrderbook.addOrder(config); - } + // /// A stack of 0 for calculate order reverts. + // function testAddOrderRealZeroStackCalculateReverts(address owner, OrderConfigV2 memory config) public { + // LibTestAddOrder.conformConfig(config, iDeployer); + // (bytes memory bytecode, uint256[] memory constants) = IParserV1(address(iDeployer)).parse(":;:;"); + // config.evaluableConfig.constants = constants; + // config.evaluableConfig.bytecode = bytecode; + // vm.expectRevert(abi.encodeWithSelector(EntrypointMinOutputs.selector, 0, 0, 2)); + // vm.prank(owner); + // iOrderbook.addOrder(config); + // } - /// A stack of 1 for calculate order reverts. - function testAddOrderRealOneStackCalculateReverts(address owner, OrderConfigV2 memory config) public { - LibTestAddOrder.conformConfig(config, iDeployer); - (bytes memory bytecode, uint256[] memory constants) = - IParserV1(address(iDeployer)).parse("_:block-timestamp();:;"); - config.evaluableConfig.constants = constants; - config.evaluableConfig.bytecode = bytecode; - vm.expectRevert(abi.encodeWithSelector(EntrypointMinOutputs.selector, 0, 1, 2)); - vm.prank(owner); - iOrderbook.addOrder(config); - } + // /// A stack of 1 for calculate order reverts. + // function testAddOrderRealOneStackCalculateReverts(address owner, OrderConfigV2 memory config) public { + // LibTestAddOrder.conformConfig(config, iDeployer); + // (bytes memory bytecode, uint256[] memory constants) = + // IParserV1(address(iDeployer)).parse("_:block-timestamp();:;"); + // config.evaluableConfig.constants = constants; + // config.evaluableConfig.bytecode = bytecode; + // vm.expectRevert(abi.encodeWithSelector(EntrypointMinOutputs.selector, 0, 1, 2)); + // vm.prank(owner); + // iOrderbook.addOrder(config); + // } /// A stack of 2 for calculate order deploys. function testAddOrderRealTwoStackCalculateReverts(address owner, OrderConfigV2 memory config) public { diff --git a/test/concrete/OrderBook.clear.handleIO.revert.t.sol b/test/concrete/OrderBook.clear.handleIO.revert.t.sol index 4c10cec41..124cfbe9e 100644 --- a/test/concrete/OrderBook.clear.handleIO.revert.t.sol +++ b/test/concrete/OrderBook.clear.handleIO.revert.t.sol @@ -3,16 +3,11 @@ pragma solidity =0.8.19; import {Vm} from "forge-std/Vm.sol"; import { - OrderBookExternalRealTest, - OrderConfigV2, - IO, - TakeOrderConfig, - Order, - IParserV1, - EvaluableConfigV2, - ClearConfig, - SignedContextV1 + OrderBookExternalRealTest } from "test/util/abstract/OrderBookExternalRealTest.sol"; +import {ClearConfig, OrderV2, TakeOrderConfigV2, IO, OrderConfigV2} from "src/interface/unstable/IOrderBookV3.sol"; +import {SignedContextV1, EvaluableConfigV3} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; +import {IParserV1} from "rain.interpreter/src/interface/IParserV1.sol"; import {EnsureFailed} from "rain.interpreter/src/lib/op/logic/LibOpEnsureNP.sol"; /// @title OrderBookClearHandleIORevertTest @@ -21,7 +16,7 @@ import {EnsureFailed} from "rain.interpreter/src/lib/op/logic/LibOpEnsureNP.sol" contract OrderBookClearHandleIORevertTest is OrderBookExternalRealTest { function userDeposit(bytes memory rainString, address owner, address inputToken, address outputToken) internal - returns (Order memory) + returns (OrderV2 memory) { uint256 vaultId = 0; @@ -47,7 +42,7 @@ contract OrderBookClearHandleIORevertTest is OrderBookExternalRealTest { assertEq(iOrderbook.vaultBalance(owner, outputToken, vaultId), type(uint256).max); (bytes memory bytecode, uint256[] memory constants) = IParserV1(address(iDeployer)).parse(rainString); - EvaluableConfigV2 memory evaluableConfig = EvaluableConfigV2(iDeployer, bytecode, constants); + EvaluableConfigV3 memory evaluableConfig = EvaluableConfigV3(iDeployer, bytecode, constants); config = OrderConfigV2(validInputs, validOutputs, evaluableConfig, ""); vm.prank(owner); @@ -55,7 +50,7 @@ contract OrderBookClearHandleIORevertTest is OrderBookExternalRealTest { iOrderbook.addOrder(config); Vm.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries.length, 3); - (,, Order memory order,) = abi.decode(entries[2].data, (address, address, Order, bytes32)); + (,, OrderV2 memory order,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32)); return order; } @@ -71,8 +66,8 @@ contract OrderBookClearHandleIORevertTest is OrderBookExternalRealTest { address alice = address(0x102); address bob = address(0x103); - Order memory aliceOrder = userDeposit(aliceString, alice, aliceInputToken, aliceOutputToken); - Order memory bobOrder = userDeposit(bobString, bob, aliceOutputToken, aliceInputToken); + OrderV2 memory aliceOrder = userDeposit(aliceString, alice, aliceInputToken, aliceOutputToken); + OrderV2 memory bobOrder = userDeposit(bobString, bob, aliceOutputToken, aliceInputToken); ClearConfig memory clearConfig = ClearConfig(0, 0, 0, 0, 0, 0); if (aliceErr.length > 0) { vm.expectRevert(aliceErr); diff --git a/test/concrete/OrderBook.clear.mock.t.sol b/test/concrete/OrderBook.clear.mock.t.sol index befabdca0..de0e5a439 100644 --- a/test/concrete/OrderBook.clear.mock.t.sol +++ b/test/concrete/OrderBook.clear.mock.t.sol @@ -5,10 +5,11 @@ import {Test} from "lib/forge-std/src/Test.sol"; import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import {OrderBookExternalMockTest} from "test/util/abstract/OrderBookExternalMockTest.sol"; -import {OrderConfigV2, Order, IO, ClearConfig} from "src/interface/unstable/IOrderBookV3.sol"; +import {OrderConfigV2, OrderV2, IO, ClearConfig} from "src/interface/unstable/IOrderBookV3.sol"; import {LibTestAddOrder} from "test/util/lib/LibTestAddOrder.sol"; import {SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; import {IInterpreterV2} from "rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; +import {NotOrderOwner} from "src/concrete/OrderBook.sol"; /// @title OrderBookClearTest /// Tests clearing an order. @@ -32,12 +33,12 @@ contract OrderBookClearTest is OrderBookExternalMockTest { // -- Add two orders with similar IO tokens (swapped) // Add alice order with a input token (iToken0) and output token (iToken1) - (Order memory aliceOrder, bytes32 aliceOrderHash) = + (OrderV2 memory aliceOrder, bytes32 aliceOrderHash) = _addOrderMockInternal(alice, aliceConfig, expression, iToken0, iToken1); assertTrue(iOrderbook.orderExists(aliceOrderHash)); // Add bob order with a input token (iToken1) and output token (iToken0) - (Order memory bobOrder, bytes32 bobOrderHash) = + (OrderV2 memory bobOrder, bytes32 bobOrderHash) = _addOrderMockInternal(bob, bobConfig, expression, iToken1, iToken0); assertTrue(iOrderbook.orderExists(bobOrderHash)); @@ -61,7 +62,7 @@ contract OrderBookClearTest is OrderBookExternalMockTest { orderStack[1] = 1e18; // orderIORatio vm.mockCall( address(iInterpreter), - abi.encodeWithSelector(IInterpreterV1.eval.selector), + abi.encodeWithSelector(IInterpreterV2.eval2.selector), abi.encode(orderStack, new uint256[](0)) ); @@ -78,7 +79,7 @@ contract OrderBookClearTest is OrderBookExternalMockTest { address expression, IERC20 inputToken, IERC20 outputToken - ) internal returns (Order memory, bytes32) { + ) internal returns (OrderV2 memory, bytes32) { vm.assume(config.validInputs.length > 0); vm.assume(config.validOutputs.length > 0); config.evaluableConfig.bytecode = hex"02000000040000000000000000"; diff --git a/test/concrete/OrderBook.removeOrder.mock.t.sol b/test/concrete/OrderBook.removeOrder.mock.t.sol index 4e508260a..d017b487a 100644 --- a/test/concrete/OrderBook.removeOrder.mock.t.sol +++ b/test/concrete/OrderBook.removeOrder.mock.t.sol @@ -1,7 +1,10 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; -import "test/util/abstract/OrderBookExternalMockTest.sol"; +import {OrderBookExternalMockTest} from "test/util/abstract/OrderBookExternalMockTest.sol"; +import {OrderConfigV2, OrderV2} from "src/interface/unstable/IOrderBookV3.sol"; +import {LibTestAddOrder} from "test/util/lib/LibTestAddOrder.sol"; +import {NotOrderOwner} from "src/concrete/OrderBook.sol"; /// @title OrderBookRemoveOrderMockTest /// @notice A contract to test the OrderBook removeOrder function. @@ -13,7 +16,7 @@ contract OrderBookRemoveOrderMockTest is OrderBookExternalMockTest { LibTestAddOrder.conformConfig(config, iDeployer); vm.assume(alice != bob); - (Order memory expectedOrder, bytes32 expectedOrderHash) = + (OrderV2 memory expectedOrder, bytes32 expectedOrderHash) = LibTestAddOrder.expectedOrder(alice, config, iInterpreter, iStore, expression); // It will revert even if the order has not been added yet. @@ -22,7 +25,7 @@ contract OrderBookRemoveOrderMockTest is OrderBookExternalMockTest { iOrderbook.removeOrder(expectedOrder); // And will revert after the order is added. - (Order memory order, bytes32 orderHash) = addOrderWithChecks(alice, config, expression); + (OrderV2 memory order, bytes32 orderHash) = addOrderWithChecks(alice, config, expression); assertEq(orderHash, expectedOrderHash); vm.expectRevert(abi.encodeWithSelector(NotOrderOwner.selector, bob, alice)); @@ -42,7 +45,7 @@ contract OrderBookRemoveOrderMockTest is OrderBookExternalMockTest { function testRemoveOrderAddRemoveMulti(address alice, OrderConfigV2 memory config, address expression) external { LibTestAddOrder.conformConfig(config, iDeployer); - Order memory order; + OrderV2 memory order; bytes32 orderHashA; bytes32 orderHashB; // Each iteration is quite slow so 3 is about as much as we want to do. @@ -59,7 +62,7 @@ contract OrderBookRemoveOrderMockTest is OrderBookExternalMockTest { /// An order MUST NOT change state if it does not exist. function testRemoveOrderDoesNotExist(address alice, OrderConfigV2 memory config, address expression) external { LibTestAddOrder.conformConfig(config, iDeployer); - (Order memory order, bytes32 orderHash) = + (OrderV2 memory order, bytes32 orderHash) = LibTestAddOrder.expectedOrder(alice, config, iInterpreter, iStore, expression); assertFalse(iOrderbook.orderExists(orderHash)); vm.record(); @@ -85,16 +88,16 @@ contract OrderBookRemoveOrderMockTest is OrderBookExternalMockTest { LibTestAddOrder.conformConfig(configOne, iDeployer); LibTestAddOrder.conformConfig(configTwo, iDeployer); - (Order memory expectedOrderOne, bytes32 expectedOrderHashOne) = + (OrderV2 memory expectedOrderOne, bytes32 expectedOrderHashOne) = LibTestAddOrder.expectedOrder(alice, configOne, iInterpreter, iStore, expressionOne); - (Order memory expectedOrderTwo, bytes32 expectedOrderHashTwo) = + (OrderV2 memory expectedOrderTwo, bytes32 expectedOrderHashTwo) = LibTestAddOrder.expectedOrder(alice, configTwo, iInterpreter, iStore, expressionTwo); (expectedOrderOne); (expectedOrderTwo); vm.assume(expectedOrderHashOne != expectedOrderHashTwo); - (Order memory orderOne, bytes32 orderHashOne) = addOrderWithChecks(alice, configOne, expressionOne); - (Order memory orderTwo, bytes32 orderHashTwo) = addOrderWithChecks(alice, configTwo, expressionTwo); + (OrderV2 memory orderOne, bytes32 orderHashOne) = addOrderWithChecks(alice, configOne, expressionOne); + (OrderV2 memory orderTwo, bytes32 orderHashTwo) = addOrderWithChecks(alice, configTwo, expressionTwo); assertEq(orderHashOne, expectedOrderHashOne); assertEq(orderHashTwo, expectedOrderHashTwo); removeOrderWithChecks(alice, orderOne); @@ -107,8 +110,8 @@ contract OrderBookRemoveOrderMockTest is OrderBookExternalMockTest { { LibTestAddOrder.conformConfig(config, iDeployer); vm.assume(alice != bob); - (Order memory orderAlice, bytes32 orderHashAlice) = addOrderWithChecks(alice, config, expression); - (Order memory orderBob, bytes32 orderHashBob) = addOrderWithChecks(bob, config, expression); + (OrderV2 memory orderAlice, bytes32 orderHashAlice) = addOrderWithChecks(alice, config, expression); + (OrderV2 memory orderBob, bytes32 orderHashBob) = addOrderWithChecks(bob, config, expression); assertTrue(orderHashAlice != orderHashBob); // Owners can't interfere with each other. @@ -139,19 +142,19 @@ contract OrderBookRemoveOrderMockTest is OrderBookExternalMockTest { vm.assume(alice != bob); // Ensure the configs are different. - (Order memory expectedOrderOne, bytes32 expectedOrderHashOne) = + (OrderV2 memory expectedOrderOne, bytes32 expectedOrderHashOne) = LibTestAddOrder.expectedOrder(address(0), configOne, iInterpreter, iStore, expressionOne); - (Order memory expectedOrderTwo, bytes32 expectedOrderHashTwo) = + (OrderV2 memory expectedOrderTwo, bytes32 expectedOrderHashTwo) = LibTestAddOrder.expectedOrder(address(0), configTwo, iInterpreter, iStore, expressionTwo); (expectedOrderOne); (expectedOrderTwo); vm.assume(expectedOrderHashOne != expectedOrderHashTwo); } - Order memory orderAliceOne; - Order memory orderBobOne; - Order memory orderAliceTwo; - Order memory orderBobTwo; + OrderV2 memory orderAliceOne; + OrderV2 memory orderBobOne; + OrderV2 memory orderAliceTwo; + OrderV2 memory orderBobTwo; { bytes32 orderHashAliceOne; bytes32 orderHashBobOne; diff --git a/test/concrete/OrderBook.takeOrder.handleIO.revert.t.sol b/test/concrete/OrderBook.takeOrder.handleIO.revert.t.sol index 29ccbf434..4c121969d 100644 --- a/test/concrete/OrderBook.takeOrder.handleIO.revert.t.sol +++ b/test/concrete/OrderBook.takeOrder.handleIO.revert.t.sol @@ -3,17 +3,12 @@ pragma solidity =0.8.19; import {Vm} from "forge-std/Vm.sol"; import { - OrderBookExternalRealTest, - OrderConfigV2, - IO, - IParserV1, - EvaluableConfigV2, - Order, - TakeOrderConfig, - SignedContextV1, - TakeOrdersConfigV2 + OrderBookExternalRealTest } from "test/util/abstract/OrderBookExternalRealTest.sol"; +import {ClearConfig, OrderV2, TakeOrderConfigV2, IO, OrderConfigV2, TakeOrdersConfigV2} from "src/interface/unstable/IOrderBookV3.sol"; import {EnsureFailed} from "rain.interpreter/src/lib/op/logic/LibOpEnsureNP.sol"; +import {IParserV1} from "rain.interpreter/src/interface/IParserV1.sol"; +import {SignedContextV1, EvaluableConfigV3} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; /// @title OrderBookTakeOrderHandleIORevertTest /// @notice A test harness for testing the OrderBook takeOrder function will run @@ -43,20 +38,20 @@ contract OrderBookTakeOrderHandleIORevertTest is OrderBookExternalRealTest { iOrderbook.deposit(outputToken, vaultId, type(uint256).max); assertEq(iOrderbook.vaultBalance(address(this), outputToken, vaultId), type(uint256).max); - TakeOrderConfig[] memory orders = new TakeOrderConfig[](configs.length); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](configs.length); for (uint256 i = 0; i < configs.length; i++) { (bytes memory bytecode, uint256[] memory constants) = IParserV1(address(iDeployer)).parse(configs[i]); - EvaluableConfigV2 memory evaluableConfig = EvaluableConfigV2(iDeployer, bytecode, constants); + EvaluableConfigV3 memory evaluableConfig = EvaluableConfigV3(iDeployer, bytecode, constants); config = OrderConfigV2(validInputs, validOutputs, evaluableConfig, ""); vm.recordLogs(); iOrderbook.addOrder(config); Vm.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries.length, 3); - (,, Order memory order,) = abi.decode(entries[2].data, (address, address, Order, bytes32)); + (,, OrderV2 memory order,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32)); - orders[i] = TakeOrderConfig(order, 0, 0, new SignedContextV1[](0)); + orders[i] = TakeOrderConfigV2(order, 0, 0, new SignedContextV1[](0)); } TakeOrdersConfigV2 memory takeOrdersConfig = TakeOrdersConfigV2(0, maxInput, type(uint256).max, orders, ""); diff --git a/test/concrete/OrderBook.takeOrder.maximumInput.t.sol b/test/concrete/OrderBook.takeOrder.maximumInput.t.sol index 0e5740436..665780efd 100644 --- a/test/concrete/OrderBook.takeOrder.maximumInput.t.sol +++ b/test/concrete/OrderBook.takeOrder.maximumInput.t.sol @@ -4,28 +4,28 @@ pragma solidity =0.8.19; import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import {OrderBookExternalRealTest, Vm} from "test/util/abstract/OrderBookExternalRealTest.sol"; import { - Order, - SignedContextV1, - TakeOrderConfig, + OrderV2, + TakeOrderConfigV2, TakeOrdersConfigV2, ZeroMaximumInput, IO, - EvaluableConfigV2, + EvaluableConfigV3, OrderConfigV2 } from "src/interface/unstable/IOrderBookV3.sol"; +import {SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; import {IParserV1} from "rain.interpreter/src/interface/IParserV1.sol"; contract OrderBookTakeOrderMaximumInputTest is OrderBookExternalRealTest { /// If there is some live order(s) but the maxTakerInput is zero we error as /// the caller has full control over this, and it would cause none of the /// orders to be taken. - function testTakeOrderNoopZeroMaxTakerInput(Order memory order, SignedContextV1 memory signedContext) external { + function testTakeOrderNoopZeroMaxTakerInput(OrderV2 memory order, SignedContextV1 memory signedContext) external { vm.assume(order.validInputs.length > 0); vm.assume(order.validOutputs.length > 0); - TakeOrderConfig[] memory orders = new TakeOrderConfig[](1); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](1); SignedContextV1[] memory signedContexts = new SignedContextV1[](1); signedContexts[0] = signedContext; - orders[0] = TakeOrderConfig(order, 0, 0, signedContexts); + orders[0] = TakeOrderConfigV2(order, 0, 0, signedContexts); TakeOrdersConfigV2 memory config = TakeOrdersConfigV2(0, 0, type(uint256).max, orders, ""); vm.expectRevert(ZeroMaximumInput.selector); (uint256 totalTakerInput, uint256 totalTakerOutput) = iOrderbook.takeOrders(config); @@ -54,7 +54,7 @@ contract OrderBookTakeOrderMaximumInputTest is OrderBookExternalRealTest { address bob = address(uint160(uint256(keccak256("bob.rain.test")))); uint256 vaultId = 0; - Order[] memory orders = new Order[](testOrders.length); + OrderV2[] memory orders = new OrderV2[](testOrders.length); for (uint256 i = 0; i < testOrders.length; i++) { { @@ -66,7 +66,7 @@ contract OrderBookTakeOrderMaximumInputTest is OrderBookExternalRealTest { inputs[0] = IO(address(iToken0), 18, vaultId); IO[] memory outputs = new IO[](1); outputs[0] = IO(address(iToken1), 18, vaultId); - EvaluableConfigV2 memory evaluableConfig = EvaluableConfigV2(iDeployer, bytecode, constants); + EvaluableConfigV3 memory evaluableConfig = EvaluableConfigV3(iDeployer, bytecode, constants); orderConfig = OrderConfigV2(inputs, outputs, evaluableConfig, ""); } @@ -75,7 +75,7 @@ contract OrderBookTakeOrderMaximumInputTest is OrderBookExternalRealTest { iOrderbook.addOrder(orderConfig); Vm.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries.length, 3); - (,, Order memory order,) = abi.decode(entries[2].data, (address, address, Order, bytes32)); + (,, OrderV2 memory order,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32)); orders[i] = order; } } @@ -108,9 +108,9 @@ contract OrderBookTakeOrderMaximumInputTest is OrderBookExternalRealTest { } } - TakeOrderConfig[] memory takeOrders = new TakeOrderConfig[](orders.length); + TakeOrderConfigV2[] memory takeOrders = new TakeOrderConfigV2[](orders.length); for (uint256 i = 0; i < orders.length; i++) { - takeOrders[i] = TakeOrderConfig(orders[i], 0, 0, new SignedContextV1[](0)); + takeOrders[i] = TakeOrderConfigV2(orders[i], 0, 0, new SignedContextV1[](0)); } TakeOrdersConfigV2 memory config = TakeOrdersConfigV2(0, maximumTakerInput, type(uint256).max, takeOrders, ""); diff --git a/test/concrete/OrderBook.takeOrder.noop.t.sol b/test/concrete/OrderBook.takeOrder.noop.t.sol index 26524ead2..9f148bb71 100644 --- a/test/concrete/OrderBook.takeOrder.noop.t.sol +++ b/test/concrete/OrderBook.takeOrder.noop.t.sol @@ -1,22 +1,25 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; -import "src/lib/LibOrder.sol"; +import {Vm} from "forge-std/Test.sol"; +import {LibOrder} from "src/lib/LibOrder.sol"; -import "test/util/abstract/OrderBookExternalRealTest.sol"; +import {OrderBookExternalRealTest} from "test/util/abstract/OrderBookExternalRealTest.sol"; import {NoOrders} from "src/concrete/OrderBook.sol"; +import {OrderV2, TakeOrdersConfigV2, TakeOrderConfigV2} from "src/interface/unstable/IOrderBookV3.sol"; +import {SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; /// @title OrderBookTakeOrderNoopTest /// @notice A test harness for testing the OrderBook takeOrder function. Focuses /// on the no-op case. contract OrderBookTakeOrderNoopTest is OrderBookExternalRealTest { - using LibOrder for Order; + using LibOrder for OrderV2; /// Take orders makes no sense without any orders in the input array and the /// caller has full control over this so we error. function testTakeOrderNoopZeroOrders() external { TakeOrdersConfigV2 memory config = - TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, new TakeOrderConfig[](0), ""); + TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, new TakeOrderConfigV2[](0), ""); vm.expectRevert(NoOrders.selector); (uint256 totalTakerInput, uint256 totalTakerOutput) = iOrderbook.takeOrders(config); (totalTakerInput, totalTakerOutput); @@ -28,7 +31,7 @@ contract OrderBookTakeOrderNoopTest is OrderBookExternalRealTest { /// transaction in this case as there may be other orders in the input array /// in the general case. function testTakeOrderNoopNonLiveOrderOne( - Order memory order, + OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex, SignedContextV1 memory signedContext @@ -41,8 +44,8 @@ contract OrderBookTakeOrderNoopTest is OrderBookExternalRealTest { // malformed orders to be passed in, and still show that nothing happens. SignedContextV1[] memory signedContexts = new SignedContextV1[](1); signedContexts[0] = signedContext; - TakeOrderConfig memory orderConfig = TakeOrderConfig(order, inputIOIndex, outputIOIndex, signedContexts); - TakeOrderConfig[] memory orders = new TakeOrderConfig[](1); + TakeOrderConfigV2 memory orderConfig = TakeOrderConfigV2(order, inputIOIndex, outputIOIndex, signedContexts); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](1); orders[0] = orderConfig; TakeOrdersConfigV2 memory config = TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, orders, ""); vm.expectEmit(address(iOrderbook)); @@ -57,8 +60,8 @@ contract OrderBookTakeOrderNoopTest is OrderBookExternalRealTest { /// Same as above but with two orders. function testTakeOrderNoopNonLiveOrderTwo( - Order memory order1, - Order memory order2, + OrderV2 memory order1, + OrderV2 memory order2, uint256 inputIOIndex1, uint256 outputIOIndex1, uint256 inputIOIndex2, @@ -84,19 +87,19 @@ contract OrderBookTakeOrderNoopTest is OrderBookExternalRealTest { TakeOrdersConfigV2 memory config; { - TakeOrderConfig[] memory orders; + TakeOrderConfigV2[] memory orders; { // We don't bound the input or output indexes as we want to allow // malformed orders to be passed in, and still show that nothing happens. SignedContextV1[] memory signedContexts1 = new SignedContextV1[](1); signedContexts1[0] = signedContext1; - TakeOrderConfig memory orderConfig1 = - TakeOrderConfig(order1, inputIOIndex1, outputIOIndex1, signedContexts1); + TakeOrderConfigV2 memory orderConfig1 = + TakeOrderConfigV2(order1, inputIOIndex1, outputIOIndex1, signedContexts1); SignedContextV1[] memory signedContexts2 = new SignedContextV1[](1); signedContexts2[0] = signedContext2; - TakeOrderConfig memory orderConfig2 = - TakeOrderConfig(order2, inputIOIndex2, outputIOIndex2, signedContexts2); - orders = new TakeOrderConfig[](2); + TakeOrderConfigV2 memory orderConfig2 = + TakeOrderConfigV2(order2, inputIOIndex2, outputIOIndex2, signedContexts2); + orders = new TakeOrderConfigV2[](2); orders[0] = orderConfig1; orders[1] = orderConfig2; } diff --git a/test/concrete/OrderBook.takeOrder.precision.t.sol b/test/concrete/OrderBook.takeOrder.precision.t.sol index 9ef9ee4a2..f61841d2e 100644 --- a/test/concrete/OrderBook.takeOrder.precision.t.sol +++ b/test/concrete/OrderBook.takeOrder.precision.t.sol @@ -1,18 +1,13 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; +import {Vm} from "forge-std/Test.sol"; import { - OrderBookExternalRealTest, - OrderConfigV2, - IO, - EvaluableConfigV2, - IParserV1, - Vm, - Order, - TakeOrderConfig, - SignedContextV1, - TakeOrdersConfigV2 + OrderBookExternalRealTest } from "test/util/abstract/OrderBookExternalRealTest.sol"; +import {OrderV2, TakeOrdersConfigV2, TakeOrderConfigV2, IO, OrderConfigV2} from "src/interface/unstable/IOrderBookV3.sol"; +import {IParserV1} from "rain.interpreter/src/interface/IParserV1.sol"; +import {SignedContextV1, EvaluableConfigV3} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; /// @title OrderBookTakeOrderPrecisionTest /// @notice A test harness for testing the OrderBook takeOrder function. @@ -36,7 +31,7 @@ contract OrderBookTakeOrderPrecisionTest is OrderBookExternalRealTest { // These numbers are known to cause large rounding errors if the // precision is not handled correctly. (bytes memory bytecode, uint256[] memory constants) = IParserV1(address(iDeployer)).parse(rainString); - EvaluableConfigV2 memory evaluableConfig = EvaluableConfigV2(iDeployer, bytecode, constants); + EvaluableConfigV3 memory evaluableConfig = EvaluableConfigV3(iDeployer, bytecode, constants); config = OrderConfigV2(validInputs, validOutputs, evaluableConfig, ""); // Etch with invalid. vm.etch(outputToken, hex"fe"); @@ -54,10 +49,10 @@ contract OrderBookTakeOrderPrecisionTest is OrderBookExternalRealTest { iOrderbook.addOrder(config); Vm.Log[] memory entries = vm.getRecordedLogs(); assertEq(entries.length, 3); - (,, Order memory order,) = abi.decode(entries[2].data, (address, address, Order, bytes32)); + (,, OrderV2 memory order,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32)); - TakeOrderConfig[] memory orders = new TakeOrderConfig[](1); - orders[0] = TakeOrderConfig(order, 0, 0, new SignedContextV1[](0)); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](1); + orders[0] = TakeOrderConfigV2(order, 0, 0, new SignedContextV1[](0)); TakeOrdersConfigV2 memory takeOrdersConfig = TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, orders, ""); (uint256 totalTakerInput, uint256 totalTakerOutput) = iOrderbook.takeOrders(takeOrdersConfig); diff --git a/test/concrete/OrderBook.takeOrder.tokenMismatch.t.sol b/test/concrete/OrderBook.takeOrder.tokenMismatch.t.sol index 5f8634621..339ac99b4 100644 --- a/test/concrete/OrderBook.takeOrder.tokenMismatch.t.sol +++ b/test/concrete/OrderBook.takeOrder.tokenMismatch.t.sol @@ -1,8 +1,10 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; -import "test/util/abstract/OrderBookExternalRealTest.sol"; +import {OrderBookExternalRealTest} from "test/util/abstract/OrderBookExternalRealTest.sol"; +import {OrderV2, IO, TakeOrderConfigV2, TakeOrdersConfigV2} from "src/interface/unstable/IOrderBookV3.sol"; import {TokenMismatch} from "src/concrete/OrderBook.sol"; +import {SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; /// @title OrderBookTakeOrderTokenMismatchTest /// @notice A test harness for testing the OrderBook takeOrder function. @@ -14,10 +16,10 @@ contract OrderBookTakeOrderTokenMismatchTest is OrderBookExternalRealTest { /// pass in. /// Test a mismatch in the input tokens. function testTokenMismatchInputs( - Order memory a, + OrderV2 memory a, uint256 aInputIOIndex, uint256 aOutputIOIndex, - Order memory b, + OrderV2 memory b, uint256 bInputIOIndex, uint256 bOutputIOIndex, uint256 maxTakerInput, @@ -38,9 +40,9 @@ contract OrderBookTakeOrderTokenMismatchTest is OrderBookExternalRealTest { // Line up outputs so we don't trigger that code path. b.validOutputs[bOutputIOIndex].token = a.validOutputs[aOutputIOIndex].token; - TakeOrderConfig[] memory orders = new TakeOrderConfig[](2); - orders[0] = TakeOrderConfig(a, aInputIOIndex, aOutputIOIndex, new SignedContextV1[](0)); - orders[1] = TakeOrderConfig(b, bInputIOIndex, bOutputIOIndex, new SignedContextV1[](0)); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](2); + orders[0] = TakeOrderConfigV2(a, aInputIOIndex, aOutputIOIndex, new SignedContextV1[](0)); + orders[1] = TakeOrderConfigV2(b, bInputIOIndex, bOutputIOIndex, new SignedContextV1[](0)); TakeOrdersConfigV2 memory config = TakeOrdersConfigV2(0, maxTakerInput, maxIORatio, orders, ""); vm.expectRevert( abi.encodeWithSelector( @@ -53,10 +55,10 @@ contract OrderBookTakeOrderTokenMismatchTest is OrderBookExternalRealTest { /// Test a mismatch in the output tokens. function testTokenMismatchOutputs( - Order memory a, + OrderV2 memory a, uint256 aInputIOIndex, uint256 aOutputIOIndex, - Order memory b, + OrderV2 memory b, uint256 bInputIOIndex, uint256 bOutputIOIndex, uint256 maxTakerInput, @@ -77,9 +79,9 @@ contract OrderBookTakeOrderTokenMismatchTest is OrderBookExternalRealTest { // Line up inputs so we don't trigger that code path. b.validInputs[bInputIOIndex].token = a.validInputs[aInputIOIndex].token; - TakeOrderConfig[] memory orders = new TakeOrderConfig[](2); - orders[0] = TakeOrderConfig(a, aInputIOIndex, aOutputIOIndex, new SignedContextV1[](0)); - orders[1] = TakeOrderConfig(b, bInputIOIndex, bOutputIOIndex, new SignedContextV1[](0)); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](2); + orders[0] = TakeOrderConfigV2(a, aInputIOIndex, aOutputIOIndex, new SignedContextV1[](0)); + orders[1] = TakeOrderConfigV2(b, bInputIOIndex, bOutputIOIndex, new SignedContextV1[](0)); TakeOrdersConfigV2 memory config = TakeOrdersConfigV2(0, maxTakerInput, maxIORatio, orders, ""); vm.expectRevert( abi.encodeWithSelector( diff --git a/test/concrete/OrderBook.takeOrder.tokenMismatchDecimals.t.sol b/test/concrete/OrderBook.takeOrder.tokenMismatchDecimals.t.sol index c4b1a66f0..43c22d682 100644 --- a/test/concrete/OrderBook.takeOrder.tokenMismatchDecimals.t.sol +++ b/test/concrete/OrderBook.takeOrder.tokenMismatchDecimals.t.sol @@ -1,8 +1,10 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; -import "test/util/abstract/OrderBookExternalRealTest.sol"; +import {OrderBookExternalRealTest} from "test/util/abstract/OrderBookExternalRealTest.sol"; import {TokenDecimalsMismatch} from "src/concrete/OrderBook.sol"; +import {SignedContextV1} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; +import {TakeOrderConfigV2, TakeOrdersConfigV2, OrderV2} from "src/interface/unstable/IOrderBookV3.sol"; /// @title OrderBookTakeOrderTokenMismatchDecimalsTest /// @notice A test harness for testing the OrderBook takeOrder function. @@ -14,10 +16,10 @@ contract OrderBookTakeOrderTokenMismatchDecimalsTest is OrderBookExternalRealTes /// pass in. /// Test a mismatch in the input tokens decimals. function testTokenMismatchInputs( - Order memory a, + OrderV2 memory a, uint256 aInputIOIndex, uint256 aOutputIOIndex, - Order memory b, + OrderV2 memory b, uint256 bInputIOIndex, uint256 bOutputIOIndex ) external { @@ -39,9 +41,9 @@ contract OrderBookTakeOrderTokenMismatchDecimalsTest is OrderBookExternalRealTes // Line up output decimals so we don't trigger that code path. b.validOutputs[bOutputIOIndex].decimals = a.validOutputs[aOutputIOIndex].decimals; - TakeOrderConfig[] memory orders = new TakeOrderConfig[](2); - orders[0] = TakeOrderConfig(a, aInputIOIndex, aOutputIOIndex, new SignedContextV1[](0)); - orders[1] = TakeOrderConfig(b, bInputIOIndex, bOutputIOIndex, new SignedContextV1[](0)); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](2); + orders[0] = TakeOrderConfigV2(a, aInputIOIndex, aOutputIOIndex, new SignedContextV1[](0)); + orders[1] = TakeOrderConfigV2(b, bInputIOIndex, bOutputIOIndex, new SignedContextV1[](0)); TakeOrdersConfigV2 memory config = TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, orders, ""); vm.expectRevert( abi.encodeWithSelector( @@ -56,10 +58,10 @@ contract OrderBookTakeOrderTokenMismatchDecimalsTest is OrderBookExternalRealTes /// Test a mismatch in the output tokens decimals. function testTokenMismatchOutputs( - Order memory a, + OrderV2 memory a, uint256 aInputIOIndex, uint256 aOutputIOIndex, - Order memory b, + OrderV2 memory b, uint256 bInputIOIndex, uint256 bOutputIOIndex ) external { @@ -81,9 +83,9 @@ contract OrderBookTakeOrderTokenMismatchDecimalsTest is OrderBookExternalRealTes // Line up input decimals so we don't trigger that code path. b.validInputs[bInputIOIndex].decimals = a.validInputs[aInputIOIndex].decimals; - TakeOrderConfig[] memory orders = new TakeOrderConfig[](2); - orders[0] = TakeOrderConfig(a, aInputIOIndex, aOutputIOIndex, new SignedContextV1[](0)); - orders[1] = TakeOrderConfig(b, bInputIOIndex, bOutputIOIndex, new SignedContextV1[](0)); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](2); + orders[0] = TakeOrderConfigV2(a, aInputIOIndex, aOutputIOIndex, new SignedContextV1[](0)); + orders[1] = TakeOrderConfigV2(b, bInputIOIndex, bOutputIOIndex, new SignedContextV1[](0)); TakeOrdersConfigV2 memory config = TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, orders, ""); vm.expectRevert( abi.encodeWithSelector( diff --git a/test/concrete/OrderBookV3FlashLender.reentrant.t.sol b/test/concrete/OrderBookV3FlashLender.reentrant.t.sol index fc4f593f4..d45402377 100644 --- a/test/concrete/OrderBookV3FlashLender.reentrant.t.sol +++ b/test/concrete/OrderBookV3FlashLender.reentrant.t.sol @@ -7,8 +7,8 @@ import {Reenteroor} from "test/util/concrete/Reenteroor.sol"; import { IOrderBookV3, OrderConfigV2, - Order, - TakeOrderConfig, + OrderV2, + TakeOrderConfigV2, TakeOrdersConfigV2, ClearConfig } from "src/interface/unstable/IOrderBookV3.sol"; @@ -111,7 +111,7 @@ contract OrderBookV3FlashLenderReentrant is OrderBookExternalRealTest { } /// Can reenter and remove an order from within a flash loan. - function testReenterRemoveOrder(uint256 loanAmount, Order memory order) external { + function testReenterRemoveOrder(uint256 loanAmount, OrderV2 memory order) external { // Create a flash borrower. Reenteroor borrower = new Reenteroor(); order.owner = address(borrower); @@ -129,10 +129,10 @@ contract OrderBookV3FlashLenderReentrant is OrderBookExternalRealTest { vm.recordLogs(); iOrderbook.addOrder(config); Vm.Log[] memory entries = vm.getRecordedLogs(); - (,, Order memory order,) = abi.decode(entries[2].data, (address, address, Order, bytes32)); + (,, OrderV2 memory order,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32)); - TakeOrderConfig[] memory orders = new TakeOrderConfig[](1); - orders[0] = TakeOrderConfig(order, 0, 0, new SignedContextV1[](0)); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](1); + orders[0] = TakeOrderConfigV2(order, 0, 0, new SignedContextV1[](0)); TakeOrdersConfigV2 memory takeOrdersConfig = TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, orders, ""); @@ -171,13 +171,13 @@ contract OrderBookV3FlashLenderReentrant is OrderBookExternalRealTest { vm.prank(alice); iOrderbook.addOrder(aliceConfig); Vm.Log[] memory entries = vm.getRecordedLogs(); - (,, Order memory aliceOrder,) = abi.decode(entries[2].data, (address, address, Order, bytes32)); + (,, OrderV2 memory aliceOrder,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32)); vm.recordLogs(); vm.prank(bob); iOrderbook.addOrder(bobConfig); entries = vm.getRecordedLogs(); - (,, Order memory bobOrder,) = abi.decode(entries[2].data, (address, address, Order, bytes32)); + (,, OrderV2 memory bobOrder,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32)); ClearConfig memory clearConfig = ClearConfig(0, 0, 0, 0, 0, 0); diff --git a/test/concrete/RouteProcessorOrderBookV3ArbOrderTaker.sender.t.sol b/test/concrete/RouteProcessorOrderBookV3ArbOrderTaker.sender.t.sol index 844e34e55..39724f37c 100644 --- a/test/concrete/RouteProcessorOrderBookV3ArbOrderTaker.sender.t.sol +++ b/test/concrete/RouteProcessorOrderBookV3ArbOrderTaker.sender.t.sol @@ -23,15 +23,15 @@ contract RouteProcessorOrderBookV3ArbOrderTakerTest is ArbTest { abi.encode( OrderBookV3ArbOrderTakerConfigV1( address(iOrderBook), - EvaluableConfigV2(IExpressionDeployerV3(address(0)), "", new uint256[](0)), + EvaluableConfigV3(IExpressionDeployerV3(address(0)), "", new uint256[](0)), abi.encode(iRefundoor) ) ) ); } - function testTakeOrdersSender(Order memory order, uint256 inputIOIndex, uint256 outputIOIndex) public { - TakeOrderConfig[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); + function testTakeOrdersSender(OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex) public { + TakeOrderConfigV2[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); RouteProcessorOrderBookV3ArbOrderTaker(iArb).arb( TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, orders, abi.encode(bytes("0x00"))), 0 @@ -39,7 +39,7 @@ contract RouteProcessorOrderBookV3ArbOrderTakerTest is ArbTest { } function testMinimumOutput( - Order memory order, + OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex, uint256 minimumOutput, @@ -49,7 +49,7 @@ contract RouteProcessorOrderBookV3ArbOrderTakerTest is ArbTest { minimumOutput = bound(minimumOutput, mintAmount + 1, type(uint256).max); iTakerOutput.mint(iArb, mintAmount); - TakeOrderConfig[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); + TakeOrderConfigV2[] memory orders = buildTakeOrderConfig(order, inputIOIndex, outputIOIndex); vm.expectRevert(abi.encodeWithSelector(MinimumOutput.selector, minimumOutput, mintAmount)); RouteProcessorOrderBookV3ArbOrderTaker(iArb).arb( diff --git a/test/lib/LibOrder.t.sol b/test/lib/LibOrder.t.sol index 414af3dbb..a5bdb52d6 100644 --- a/test/lib/LibOrder.t.sol +++ b/test/lib/LibOrder.t.sol @@ -9,12 +9,12 @@ import "src/lib/LibOrder.sol"; /// Exercises the LibOrder library. contract LibOrderTest is Test { /// Hashing should always produce the same result for the same input. - function testHashEqual(Order memory a) public { + function testHashEqual(OrderV2 memory a) public { assertTrue(LibOrder.hash(a) == LibOrder.hash(a)); } /// Hashing should always produce different results for different inputs. - function testHashNotEqual(Order memory a, Order memory b) public { + function testHashNotEqual(OrderV2 memory a, OrderV2 memory b) public { assertTrue(LibOrder.hash(a) != LibOrder.hash(b)); } } diff --git a/test/util/abstract/ArbTest.sol b/test/util/abstract/ArbTest.sol index 2ba7c2e73..6ad71c77c 100644 --- a/test/util/abstract/ArbTest.sol +++ b/test/util/abstract/ArbTest.sol @@ -53,8 +53,8 @@ abstract contract ArbTest is Test { vm.etch(deployer, REVERTING_MOCK_BYTECODE); vm.mockCall( deployer, - abi.encodeWithSelector(IExpressionDeployerV3.deployExpression.selector), - abi.encode(address(0), address(0), address(0)) + abi.encodeWithSelector(IExpressionDeployerV3.deployExpression2.selector), + abi.encode(address(0), address(0), address(0), "") ); bytes memory meta = vm.readFileBinary(metaPath); console2.log("RouteProcessorOrderBookV3ArbOrderTakerTest meta hash:"); @@ -62,10 +62,10 @@ abstract contract ArbTest is Test { config = DeployerDiscoverableMetaV3ConstructionConfig(deployer, meta); } - function buildTakeOrderConfig(Order memory order, uint256 inputIOIndex, uint256 outputIOIndex) + function buildTakeOrderConfig(OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex) internal view - returns (TakeOrderConfig[] memory) + returns (TakeOrderConfigV2[] memory) { if (order.validInputs.length == 0) { order.validInputs = new IO[](1); @@ -79,8 +79,8 @@ abstract contract ArbTest is Test { order.validInputs[inputIOIndex].token = address(iTakerOutput); order.validOutputs[outputIOIndex].token = address(iTakerInput); - TakeOrderConfig[] memory orders = new TakeOrderConfig[](1); - orders[0] = TakeOrderConfig(order, inputIOIndex, outputIOIndex, new SignedContextV1[](0)); + TakeOrderConfigV2[] memory orders = new TakeOrderConfigV2[](1); + orders[0] = TakeOrderConfigV2(order, inputIOIndex, outputIOIndex, new SignedContextV1[](0)); return orders; } diff --git a/test/util/abstract/IOrderBookV3Stub.sol b/test/util/abstract/IOrderBookV3Stub.sol index 1fcf4e7ec..f8e63659d 100644 --- a/test/util/abstract/IOrderBookV3Stub.sol +++ b/test/util/abstract/IOrderBookV3Stub.sol @@ -15,12 +15,12 @@ abstract contract IOrderBookV3Stub is IOrderBookV3 { } /// @inheritdoc IOrderBookV3 - function removeOrder(Order calldata) external pure returns (bool) { + function removeOrder(OrderV2 calldata) external pure returns (bool) { revert("removeOrder"); } /// @inheritdoc IOrderBookV3 - function clear(Order memory, Order memory, ClearConfig calldata, SignedContextV1[] memory, SignedContextV1[] memory) + function clear(OrderV2 memory, OrderV2 memory, ClearConfig calldata, SignedContextV1[] memory, SignedContextV1[] memory) external pure { diff --git a/test/util/abstract/OrderBookExternalMockTest.sol b/test/util/abstract/OrderBookExternalMockTest.sol index b1b302a69..1f839d10d 100644 --- a/test/util/abstract/OrderBookExternalMockTest.sol +++ b/test/util/abstract/OrderBookExternalMockTest.sol @@ -1,17 +1,23 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; -import "lib/forge-std/src/Test.sol"; +import {Test} from "lib/forge-std/src/Test.sol"; +import {console2} from "forge-std/console2.sol"; -import "lib/rain.interpreter/src/interface/unstable/IExpressionDeployerV3.sol"; -import "lib/rain.metadata/src/LibMeta.sol"; +import {IExpressionDeployerV3} from "rain.interpreter/src/interface/unstable/IExpressionDeployerV3.sol"; +import {IMetaV1} from "rain.metadata/LibMeta.sol"; -import "test/util/lib/LibTestConstants.sol"; -import "test/util/lib/LibOrderBookConstants.sol"; -import "test/util/abstract/IOrderBookV3Stub.sol"; -import "test/util/lib/LibTestAddOrder.sol"; - -import "src/concrete/OrderBook.sol"; +import {REVERTING_MOCK_BYTECODE} from "test/util/lib/LibTestConstants.sol"; +import {ORDER_BOOK_META_PATH} from "test/util/lib/LibOrderBookConstants.sol"; +import {IOrderBookV3Stub} from "test/util/abstract/IOrderBookV3Stub.sol"; +import {LibTestAddOrder} from "test/util/lib/LibTestAddOrder.sol"; +import {IInterpreterV2} from "rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; +import {IInterpreterStoreV1} from "rain.interpreter/src/interface/IInterpreterStoreV1.sol"; +import {IOrderBookV3, OrderConfigV2, OrderV2} from "src/interface/unstable/IOrderBookV3.sol"; +import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; +import {LibOrder} from "src/lib/LibOrder.sol"; +import {OrderBook} from "src/concrete/OrderBook.sol"; +import {DeployerDiscoverableMetaV3ConstructionConfig} from "rain.interpreter/src/abstract/DeployerDiscoverableMetaV3.sol"; /// @title OrderBookExternalTest /// Abstract contract that performs common setup needed for testing an orderbook @@ -25,7 +31,7 @@ import "src/concrete/OrderBook.sol"; /// Inherits from Test so that it can be used as a base contract for other tests. /// Implements IOrderBookV3 so that it has access to all the relevant events. abstract contract OrderBookExternalMockTest is Test, IMetaV1, IOrderBookV3Stub { - IInterpreterV1 immutable iInterpreter; + IInterpreterV2 immutable iInterpreter; IInterpreterStoreV1 immutable iStore; IExpressionDeployerV3 immutable iDeployer; IOrderBookV3 immutable iOrderbook; @@ -34,7 +40,7 @@ abstract contract OrderBookExternalMockTest is Test, IMetaV1, IOrderBookV3Stub { constructor() { vm.pauseGasMetering(); - iInterpreter = IInterpreterV1(address(uint160(uint256(keccak256("interpreter.rain.test"))))); + iInterpreter = IInterpreterV2(address(uint160(uint256(keccak256("interpreter.rain.test"))))); vm.etch(address(iInterpreter), REVERTING_MOCK_BYTECODE); iStore = IInterpreterStoreV1(address(uint160(uint256(keccak256("store.rain.test"))))); vm.etch(address(iStore), REVERTING_MOCK_BYTECODE); @@ -43,8 +49,8 @@ abstract contract OrderBookExternalMockTest is Test, IMetaV1, IOrderBookV3Stub { vm.etch(address(iDeployer), REVERTING_MOCK_BYTECODE); vm.mockCall( address(iDeployer), - abi.encodeWithSelector(IExpressionDeployerV3.deployExpression.selector), - abi.encode(iInterpreter, iStore, address(0)) + abi.encodeWithSelector(IExpressionDeployerV3.deployExpression2.selector), + abi.encode(iInterpreter, iStore, address(0), "") ); bytes memory meta = vm.readFileBinary(ORDER_BOOK_META_PATH); console2.log("OrderBookExternalMockTest meta hash:"); @@ -63,16 +69,16 @@ abstract contract OrderBookExternalMockTest is Test, IMetaV1, IOrderBookV3Stub { /// storage accesses. function addOrderWithChecks(address owner, OrderConfigV2 memory config, address expression) internal - returns (Order memory, bytes32) + returns (OrderV2 memory, bytes32) { config.evaluableConfig.deployer = iDeployer; - (Order memory order, bytes32 orderHash) = + (OrderV2 memory order, bytes32 orderHash) = LibTestAddOrder.expectedOrder(owner, config, iInterpreter, iStore, expression); assertTrue(!iOrderbook.orderExists(orderHash)); vm.mockCall( address(iDeployer), - abi.encodeWithSelector(IExpressionDeployerV3.deployExpression.selector), - abi.encode(iInterpreter, iStore, expression) + abi.encodeWithSelector(IExpressionDeployerV3.deployExpression2.selector), + abi.encode(iInterpreter, iStore, expression, "") ); vm.expectEmit(false, false, false, true); emit AddOrder(owner, iDeployer, order, orderHash); @@ -100,8 +106,8 @@ abstract contract OrderBookExternalMockTest is Test, IMetaV1, IOrderBookV3Stub { // mock. vm.mockCall( address(iDeployer), - abi.encodeWithSelector(IExpressionDeployerV3.deployExpression.selector), - abi.encode(iInterpreter, iStore, expression) + abi.encodeWithSelector(IExpressionDeployerV3.deployExpression2.selector), + abi.encode(iInterpreter, iStore, expression, "") ); vm.record(); vm.recordLogs(); @@ -120,7 +126,7 @@ abstract contract OrderBookExternalMockTest is Test, IMetaV1, IOrderBookV3Stub { /// Boilerplate to remove an order with a mocked deployer and checks events /// and storage accesses. - function removeOrderWithChecks(address owner, Order memory order) internal { + function removeOrderWithChecks(address owner, OrderV2 memory order) internal { bytes32 orderHash = LibOrder.hash(order); // This check assumes the order exists before we try to remove it. assertTrue(iOrderbook.orderExists(orderHash)); diff --git a/test/util/abstract/OrderBookExternalRealTest.sol b/test/util/abstract/OrderBookExternalRealTest.sol index 84e8607f9..ce094642a 100644 --- a/test/util/abstract/OrderBookExternalRealTest.sol +++ b/test/util/abstract/OrderBookExternalRealTest.sol @@ -1,28 +1,37 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.19; -import "lib/forge-std/src/Test.sol"; -import {RainterpreterNPE2} from "lib/rain.interpreter/src/concrete/RainterpreterNPE2.sol"; -import {RainterpreterStoreNPE2} from "lib/rain.interpreter/src/concrete/RainterpreterStoreNPE2.sol"; -import {RainterpreterExpressionDeployerNPE2} from "lib/rain.interpreter/src/concrete/RainterpreterExpressionDeployerNPE2.sol"; - -import "test/util/lib/LibTestConstants.sol"; -import "test/util/lib/LibOrderBookConstants.sol"; -import "test/util/abstract/IOrderBookV3Stub.sol"; - +import {Test, Vm, console2} from "forge-std/Test.sol"; +import {RainterpreterNPE2} from "rain.interpreter/src/concrete/RainterpreterNPE2.sol"; +import {RainterpreterStoreNPE2} from "rain.interpreter/src/concrete/RainterpreterStoreNPE2.sol"; +import {RainterpreterExpressionDeployerNPE2, RainterpreterExpressionDeployerNPE2ConstructionConfig} from "rain.interpreter/src/concrete/RainterpreterExpressionDeployerNPE2.sol"; +import {LibAllStandardOpsNP} from "rain.interpreter/src/lib/op/LibAllStandardOpsNP.sol"; +import {REVERTING_MOCK_BYTECODE} from "test/util/lib/LibTestConstants.sol"; +import {ORDER_BOOK_META_PATH} from "test/util/lib/LibOrderBookConstants.sol"; +import {IOrderBookV3Stub} from "test/util/abstract/IOrderBookV3Stub.sol"; +import {IInterpreterV2} from "rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; +import {IInterpreterStoreV1} from "rain.interpreter/src/interface/IInterpreterStoreV1.sol"; +import {IExpressionDeployerV3} from "rain.interpreter/src/interface/unstable/IExpressionDeployerV3.sol"; +import {IOrderBookV3} from "src/interface/unstable/IOrderBookV3.sol"; import {OrderBook, IERC20, DeployerDiscoverableMetaV3ConstructionConfig} from "src/concrete/OrderBook.sol"; +import {IERC1820Registry} from "rain.erc1820/interface/IERC1820Registry.sol"; +import {IERC1820_REGISTRY} from "rain.erc1820/lib/LibIERC1820.sol"; +import {IParserV1} from "rain.interpreter/src/interface/IParserV1.sol"; +import {RainterpreterParserNPE2} from "rain.interpreter/src/concrete/RainterpreterParserNPE2.sol"; abstract contract OrderBookExternalRealTest is Test, IOrderBookV3Stub { - IInterpreterV1 internal immutable iInterpreter; - IInterpreterStoreV1 internal immutable iStore; IExpressionDeployerV3 internal immutable iDeployer; + IInterpreterV2 internal immutable iInterpreter; + IInterpreterStoreV1 internal immutable iStore; + IParserV1 internal immutable iParser; IOrderBookV3 internal immutable iOrderbook; IERC20 internal immutable iToken0; IERC20 internal immutable iToken1; constructor() { - iInterpreter = IInterpreterV1(new RainterpreterNP()); - iStore = IInterpreterStoreV1(new RainterpreterStore()); + iInterpreter = IInterpreterV2(new RainterpreterNPE2()); + iStore = IInterpreterStoreV1(new RainterpreterStoreNPE2()); + iParser = IParserV1(new RainterpreterParserNPE2()); // Deploy the expression deployer. vm.etch(address(IERC1820_REGISTRY), REVERTING_MOCK_BYTECODE); @@ -39,9 +48,10 @@ abstract contract OrderBookExternalRealTest is Test, IOrderBookV3Stub { console2.logBytes32(keccak256(deployerMeta)); iDeployer = IExpressionDeployerV3( address( - new RainterpreterExpressionDeployerNP(RainterpreterExpressionDeployerConstructionConfig( + new RainterpreterExpressionDeployerNPE2(RainterpreterExpressionDeployerNPE2ConstructionConfig( address(iInterpreter), address(iStore), + address(iParser), deployerMeta )) ) diff --git a/test/util/abstract/OrderBookSelfTest.sol b/test/util/abstract/OrderBookSelfTest.sol index e52f760c4..9d49ce726 100644 --- a/test/util/abstract/OrderBookSelfTest.sol +++ b/test/util/abstract/OrderBookSelfTest.sol @@ -20,8 +20,8 @@ abstract contract OrderBookSelfTest is Test, OrderBook { vm.etch(address(deployer), REVERTING_MOCK_BYTECODE); vm.mockCall( address(deployer), - abi.encodeWithSelector(IExpressionDeployerV3.deployExpression.selector), - abi.encode(address(0), address(0), address(0)) + abi.encodeWithSelector(IExpressionDeployerV3.deployExpression2.selector), + abi.encode(address(0), address(0), address(0), "") ); vm.resumeGasMetering(); } diff --git a/test/util/concrete/FlashLendingMockOrderBook.sol b/test/util/concrete/FlashLendingMockOrderBook.sol index 79f21c3be..66bf219cd 100644 --- a/test/util/concrete/FlashLendingMockOrderBook.sol +++ b/test/util/concrete/FlashLendingMockOrderBook.sol @@ -25,8 +25,8 @@ contract FlashLendingMockOrderBook is IOrderBookV3 { } function clear( - Order memory alice, - Order memory bob, + OrderV2 memory alice, + OrderV2 memory bob, ClearConfig calldata clearConfig, SignedContextV1[] memory aliceSignedContextV1, SignedContextV1[] memory bobSignedContextV1 @@ -34,7 +34,7 @@ contract FlashLendingMockOrderBook is IOrderBookV3 { function deposit(address token, uint256 vaultId, uint256 amount) external {} function flashFee(address token, uint256 amount) external view returns (uint256) {} function maxFlashLoan(address token) external view returns (uint256) {} - function removeOrder(Order calldata order) external returns (bool stateChanged) {} + function removeOrder(OrderV2 calldata order) external returns (bool stateChanged) {} function vaultBalance(address owner, address token, uint256 id) external view returns (uint256 balance) {} function withdraw(address token, uint256 vaultId, uint256 targetAmount) external {} diff --git a/test/util/lib/LibTestAddOrder.sol b/test/util/lib/LibTestAddOrder.sol index 0ffe18296..443807561 100644 --- a/test/util/lib/LibTestAddOrder.sol +++ b/test/util/lib/LibTestAddOrder.sol @@ -1,10 +1,15 @@ // SPDX-License-Identifier: CAL pragma solidity ^0.8.19; -import "lib/rain.metadata/src/LibMeta.sol"; -import "src/interface/unstable/IOrderBookV3.sol"; -import "src/lib/LibOrder.sol"; -import "src/concrete/OrderBook.sol"; +import {META_MAGIC_NUMBER_V1} from "lib/rain.metadata/src/LibMeta.sol"; +import {LibOrder} from "src/lib/LibOrder.sol"; +import {OrderConfigV2, OrderV2, IO} from "src/interface/unstable/IOrderBookV3.sol"; +import {IInterpreterV2, SourceIndexV2} from "rain.interpreter/src/interface/unstable/IInterpreterV2.sol"; +import {IInterpreterStoreV1} from "rain.interpreter/src/interface/IInterpreterStoreV1.sol"; +import {IExpressionDeployerV3} from "rain.interpreter/src/interface/unstable/IExpressionDeployerV3.sol"; +import {EvaluableV2} from "rain.interpreter/src/interface/IInterpreterCallerV2.sol"; +import {HANDLE_IO_ENTRYPOINT} from "src/concrete/OrderBook.sol"; +import {LibBytecode} from "rain.interpreter/src/lib/bytecode/LibBytecode.sol"; library LibTestAddOrder { /// A little boilerplate to make it easier to build the order that we expect @@ -12,15 +17,15 @@ library LibTestAddOrder { function expectedOrder( address owner, OrderConfigV2 memory config, - IInterpreterV1 interpreter, + IInterpreterV2 interpreter, IInterpreterStoreV1 store, address expression - ) internal pure returns (Order memory, bytes32) { - Evaluable memory expectedEvaluable = Evaluable(interpreter, store, expression); - Order memory order = Order( + ) internal pure returns (OrderV2 memory, bytes32) { + EvaluableV2 memory expectedEvaluable = EvaluableV2(interpreter, store, expression); + OrderV2 memory order = OrderV2( owner, LibBytecode.sourceCount(config.evaluableConfig.bytecode) > 1 - && LibBytecode.sourceOpsLength(config.evaluableConfig.bytecode, SourceIndex.unwrap(HANDLE_IO_ENTRYPOINT)) + && LibBytecode.sourceOpsCount(config.evaluableConfig.bytecode, SourceIndexV2.unwrap(HANDLE_IO_ENTRYPOINT)) > 0, expectedEvaluable, config.validInputs,