diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 28ffac9..bf0f9c7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,6 +26,24 @@ jobs: with: submodules: recursive fetch-depth: 0 + + # https://github.com/actions/runner-images/issues/2840#issuecomment-2272410832 + - run: | + sudo rm -rf \ + "$AGENT_TOOLSDIRECTORY" \ + /opt/google/chrome \ + /opt/microsoft/msedge \ + /opt/microsoft/powershell \ + /opt/pipx \ + /usr/lib/mono \ + /usr/local/julia* \ + /usr/local/lib/android \ + /usr/local/lib/node_modules \ + /usr/local/share/chromium \ + /usr/local/share/powershell \ + /usr/share/dotnet \ + /usr/share/swift + df -h - name: Install Nix uses: DeterminateSystems/nix-installer-action@v4 diff --git a/flake.lock b/flake.lock index cacb66b..6ba133d 100644 --- a/flake.lock +++ b/flake.lock @@ -75,11 +75,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1719997877, - "narHash": "sha256-/Edw+w0PiGgxwnCeJycM0VgH4HtlCi91v1d8xbi+REE=", + "lastModified": 1722676286, + "narHash": "sha256-wEDJdvwRZF2ErQ33nQ0Lqn/48XrPbaadv56/bM2MSZU=", "owner": "shazow", "repo": "foundry.nix", - "rev": "02febba4f1cf0606d790acdb24adcf7a64afb4e1", + "rev": "d84c83b1c1722c8742b3d2d84c9386814d75384e", "type": "github" }, "original": { @@ -105,11 +105,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1720771713, - "narHash": "sha256-bfsLhD3deWYECwvo3b8AQPQkdx0Pqu3Qyds5UP6a2x0=", + "lastModified": 1723043047, + "narHash": "sha256-s6LBVajxwWulSiFYRmxfGFHTlyiy1+lHGbW0nCOTPRk=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2977213b607671ed2d9b8a935eb55ae998dbb964", + "rev": "4e8f8f13e64d2795384ed17679bf193987a1f731", "type": "github" }, "original": { @@ -159,11 +159,11 @@ "solc": "solc" }, "locked": { - "lastModified": 1720772500, - "narHash": "sha256-UFqI1xkg01ZddqOqJmUz3rG2jE4DusR9IwFcAbiCQ6M=", + "lastModified": 1723043648, + "narHash": "sha256-DZCGdrjDRjjKF2BuPCqGb7H8guYA7uWsCeOT30tUWrk=", "owner": "rainprotocol", "repo": "rainix", - "rev": "eeb91c191c4b94b0a1716b3dd9956372a092474c", + "rev": "6baf112368cb17b44233b5fce6848aa0cc2d36d6", "type": "github" }, "original": { @@ -183,11 +183,11 @@ "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1720750737, - "narHash": "sha256-hPXe9Pr3s2EKRdDki3UkCKoPGlNkOhplCooNoC/L7Qc=", + "lastModified": 1722997267, + "narHash": "sha256-8Pncp8IKd0f0N711CRrCGTC4iLfBE+/5kaMqyWxnYic=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "a17c5d38c6fe47880eb8c6bede15d943ac2c4d17", + "rev": "d720bf3cebac38c2426d77ee2e59943012854cb8", "type": "github" }, "original": { diff --git a/foundry.toml b/foundry.toml index ef43b0f..cfba025 100644 --- a/foundry.toml +++ b/foundry.toml @@ -5,17 +5,10 @@ libs = ["lib"] solc = "0.8.25" -# Try to make sure the optimizer doesn't touch the output in a way that can break -# source maps for debugging. -# via_ir = false -# optimizer = false -# optimizer_runs = 0 -# optimizer_steps = 0 - # These settings should be used for snapshots optimizer = true optimizer_runs = 1000000 - +evm_version = "cancun" bytecode_hash = "none" cbor_metadata = false @@ -23,8 +16,4 @@ cbor_metadata = false ffi = true [fuzz] -runs = 1024 - -remappings = [ - "rain.math.fixedpoint/=lib/rain.orderbook/lib/rain.interpreter/lib/rain.math.fixedpoint/src/", -] \ No newline at end of file +runs = 1024 \ No newline at end of file diff --git a/lib/rain.orderbook b/lib/rain.orderbook index 253e2da..151c041 160000 --- a/lib/rain.orderbook +++ b/lib/rain.orderbook @@ -1 +1 @@ -Subproject commit 253e2da506eac3bfbc71d6bce4fff0c90bd38592 +Subproject commit 151c0412c6b6f847d2f24ce8c4daf7f465e1dd60 diff --git a/src/StrategyTests.sol b/src/StrategyTests.sol index 6bfe56a..9305d5b 100644 --- a/src/StrategyTests.sol +++ b/src/StrategyTests.sol @@ -2,7 +2,8 @@ pragma solidity =0.8.25; import "src/abstract/OrderBookStrategyTest.sol"; -import {LibEncodedDispatch} from "rain.interpreter.interface/lib/caller/LibEncodedDispatch.sol"; +import {LibEncodedDispatch} from "rain.interpreter.interface/lib/deprecated/caller/LibEncodedDispatch.sol"; +import {ActionV1} from "rain.orderbook.interface/interface/IOrderBookV4.sol"; import {StateNamespace, LibNamespace, FullyQualifiedNamespace} from "rain.interpreter.interface/lib/ns/LibNamespace.sol"; import {LibStrategyDeployment} from "src/lib/LibStrategyDeployment.sol"; import {LibComposeOrders} from "src/lib/LibComposeOrder.sol"; @@ -11,7 +12,7 @@ contract StrategyTests is OrderBookStrategyTest { // Function to add OrderBook order and deposit tokens. // Input and Output tokens are extracted from `inputVaults` and `outputVaults`, // indexed by `inputTokenIndex` and `outputTokenIndex`. - function addOrderDepositOutputTokens(LibStrategyDeployment.StrategyDeployment memory strategy) + function addOrderDepositOutputTokens(LibStrategyDeployment.StrategyDeploymentV4 memory strategy) internal returns (OrderV3 memory order) { @@ -35,19 +36,31 @@ contract StrategyTests is OrderBookStrategyTest { { depositTokens(ORDER_OWNER, outputToken, outputTokenVaultId, strategy.takerAmount, new ActionV1[](0)); } - { + { + ActionV1[] memory postAddOrderTasks; + { + bytes memory postOrderCompose = iParser.parse2( + LibComposeOrders.getComposedPostAddOrder( + vm, strategy.strategyFile, strategy.strategyScenario, strategy.buildPath, strategy.manifestPath + ) + ); + EvaluableV3 memory postOrderEvaluable = EvaluableV3(iInterpreter, iStore, postOrderCompose); + ActionV1 memory postOrderAction = ActionV1(postOrderEvaluable,strategy.postAddOrderTaskSignedContext); + postAddOrderTasks = new ActionV1[](1); + postAddOrderTasks[0] = postOrderAction; + } bytes memory bytecode = iParser.parse2( LibComposeOrders.getComposedOrder( vm, strategy.strategyFile, strategy.strategyScenario, strategy.buildPath, strategy.manifestPath ) ); - order = placeOrder(ORDER_OWNER, bytecode, strategy.inputVaults, strategy.outputVaults, new ActionV1[](0)); + order = placeOrder(ORDER_OWNER, bytecode, strategy.inputVaults, strategy.outputVaults, postAddOrderTasks); } } // Function to assert OrderBook calculations context by calling 'takeOrders' function // directly from the OrderBook contract. - function checkStrategyCalculations(LibStrategyDeployment.StrategyDeployment memory strategy) internal { + function checkStrategyCalculations(LibStrategyDeployment.StrategyDeploymentV4 memory strategy) internal { OrderV3 memory order = addOrderDepositOutputTokens(strategy); { vm.recordLogs(); @@ -65,7 +78,7 @@ contract StrategyTests is OrderBookStrategyTest { // Function to assert OrderBook calculations context by calling 'arb' function // from the OrderBookV3ArbOrderTaker contract. - function checkStrategyCalculationsArbOrder(LibStrategyDeployment.StrategyDeployment memory strategy) internal { + function checkStrategyCalculationsArbOrder(LibStrategyDeployment.StrategyDeploymentV4 memory strategy) internal { OrderV3 memory order = addOrderDepositOutputTokens(strategy); // Move external pool price in opposite direction that of the order @@ -92,7 +105,7 @@ contract StrategyTests is OrderBookStrategyTest { } function evalExpression( - LibStrategyDeployment.StrategyDeployment memory strategy, + LibStrategyDeployment.StrategyDeploymentV4 memory strategy, FullyQualifiedNamespace namespace, uint256[][] memory context, uint256[] memory inputs, diff --git a/src/abstract/OrderBookStrategyTest.sol b/src/abstract/OrderBookStrategyTest.sol index 7409116..fe924ba 100644 --- a/src/abstract/OrderBookStrategyTest.sol +++ b/src/abstract/OrderBookStrategyTest.sol @@ -3,17 +3,16 @@ pragma solidity =0.8.25; import {Vm} from "forge-std/Vm.sol"; import {Test, console2, stdError} from "forge-std/Test.sol"; -import {IParserV1} from "rain.interpreter.interface/interface/IParserV1.sol"; -import {IParserV2} from "rain.interpreter.interface/interface/unstable/IParserV2.sol"; -import {IExpressionDeployerV3} from "rain.interpreter.interface/interface/IExpressionDeployerV3.sol"; -import {IInterpreterV3} from "rain.interpreter.interface/interface/unstable/IInterpreterV3.sol"; +import {IParserV2} from "rain.interpreter.interface/interface/IParserV2.sol"; +import {IExpressionDeployerV3} from "rain.interpreter.interface/interface/deprecated/IExpressionDeployerV3.sol"; +import {IInterpreterV3} from "rain.interpreter.interface/interface/IInterpreterV3.sol"; import {IInterpreterStoreV2} from "rain.interpreter.interface/interface/IInterpreterStoreV2.sol"; -import {SourceIndexV2} from "rain.interpreter.interface/interface/IInterpreterV2.sol"; -import {EvaluableConfigV3, SignedContextV1} from "rain.interpreter.interface/interface/IInterpreterCallerV2.sol"; +import {SourceIndexV2} from "rain.interpreter.interface/interface/deprecated/IInterpreterV2.sol"; +import {EvaluableConfigV3, SignedContextV1} from "rain.interpreter.interface/interface/deprecated/IInterpreterCallerV2.sol"; import { IOrderBookV3, IO -} from "rain.orderbook.interface/interface/IOrderBookV3.sol"; +} from "rain.orderbook.interface/interface/deprecated/v3/IOrderBookV3.sol"; import { IOrderBookV4, OrderV3, @@ -22,8 +21,8 @@ import { TakeOrdersConfigV3, ActionV1, EvaluableV3 -}from "rain.orderbook.interface/interface/unstable/IOrderBookV4.sol"; -import {IOrderBookV4ArbOrderTaker} from "rain.orderbook.interface/interface/unstable/IOrderBookV4ArbOrderTaker.sol"; +}from "rain.orderbook.interface/interface/IOrderBookV4.sol"; +import {IOrderBookV4ArbOrderTaker} from "rain.orderbook.interface/interface/IOrderBookV4ArbOrderTaker.sol"; import {SafeERC20, IERC20} from "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol"; import {IRouteProcessor} from "src/interface/IRouteProcessor.sol"; @@ -77,7 +76,6 @@ abstract contract OrderBookStrategyTest is Test { vm.recordLogs(); (bool stateChanged) = iOrderBook.addOrder2(orderV3Config,actionV1); Vm.Log[] memory entries = vm.getRecordedLogs(); - assertEq(entries.length, 1); (,, order) = abi.decode(entries[0].data, (address, bytes32, OrderV3)); assertEq(order.owner, orderOwner); assertEq(stateChanged, true); diff --git a/src/lib/LibComposeOrder.sol b/src/lib/LibComposeOrder.sol index bc55e92..ea2fbfa 100644 --- a/src/lib/LibComposeOrder.sol +++ b/src/lib/LibComposeOrder.sol @@ -14,7 +14,7 @@ library LibComposeOrders { string memory scenario, string memory buildPath, string memory manifestPath - ) internal returns (bytes memory trancheOrder) { + ) internal returns (bytes memory composedOrder) { string[] memory ffi = new string[](16); ffi[0] = "nix"; ffi[1] = "develop"; @@ -33,6 +33,35 @@ library LibComposeOrders { ffi[14] = "-s"; ffi[15] = scenario; - trancheOrder = vm.ffi(ffi); + composedOrder = vm.ffi(ffi); + } + + function getComposedPostAddOrder( + Vm vm, + string memory filePath, + string memory scenario, + string memory buildPath, + string memory manifestPath + ) internal returns (bytes memory composedSource) { + string[] memory ffi = new string[](17); + ffi[0] = "nix"; + ffi[1] = "develop"; + ffi[2] = buildPath; + ffi[3] = "--command"; + ffi[4] = "cargo"; + ffi[5] = "run"; + ffi[6] = "--manifest-path"; + ffi[7] = manifestPath; + ffi[8] = "--package"; + ffi[9] = "rain_orderbook_cli"; + ffi[10] = "order"; + ffi[11] = "compose"; + ffi[12] = "-f"; + ffi[13] = filePath; + ffi[14] = "-s"; + ffi[15] = scenario; + ffi[16] = "-p"; + + composedSource = vm.ffi(ffi); } } diff --git a/src/lib/LibProcessStream.sol b/src/lib/LibProcessStream.sol index 248c7f9..6d3b6b2 100644 --- a/src/lib/LibProcessStream.sol +++ b/src/lib/LibProcessStream.sol @@ -56,7 +56,7 @@ library LibProcessStream { } /// Log the processed route data. - function logRoute(RouteProcessor4Route[] memory routeData) internal pure { + function logRoute(RouteProcessor4Route[] memory routeData) internal view { if(routeData.length > 0){ for(uint256 i = 0 ; i < routeData.length; i++){ console2.log("----------------------Processed Route----------------------"); diff --git a/src/lib/LibStrategyDeployment.sol b/src/lib/LibStrategyDeployment.sol index dec958c..47ed4c8 100644 --- a/src/lib/LibStrategyDeployment.sol +++ b/src/lib/LibStrategyDeployment.sol @@ -2,10 +2,11 @@ pragma solidity =0.8.25; import {Vm} from "forge-std/Vm.sol"; -import {IO} from "rain.orderbook.interface/interface/IOrderBookV3.sol"; +import {IO} from "rain.orderbook.interface/interface/deprecated/v3/IOrderBookV3.sol"; +import {SignedContextV1} from "rain.interpreter.interface/interface/deprecated/IInterpreterCallerV2.sol"; library LibStrategyDeployment { - struct StrategyDeployment { + struct StrategyDeploymentV4 { bytes makerRoute; bytes takerRoute; uint256 inputTokenIndex; @@ -20,5 +21,6 @@ library LibStrategyDeployment { string manifestPath; IO[] inputVaults; IO[] outputVaults; + SignedContextV1[] postAddOrderTaskSignedContext; } } diff --git a/test/DeployedStrategyTest.t.sol b/test/DeployedStrategyTest.t.sol index c947607..07dcbeb 100644 --- a/test/DeployedStrategyTest.t.sol +++ b/test/DeployedStrategyTest.t.sol @@ -11,7 +11,7 @@ import "src/StrategyTests.sol"; /// to initialize the suite for a particular fork. contract DeployedStrategyTest is StrategyTests { // Inheriting contract defines the fork block number. - uint256 constant FORK_BLOCK_NUMBER = 17300025; + uint256 constant FORK_BLOCK_NUMBER = 18371042; // https://basescan.org/address/0x222789334d44bb5b2364939477e15a6c981ca165 address constant RED_TOKEN = address(0x222789334D44bB5b2364939477E15A6c981Ca165); @@ -34,8 +34,8 @@ contract DeployedStrategyTest is StrategyTests { iStore = IInterpreterStoreV2(0x6E4b01603edBDa617002A077420E98C86595748E); iInterpreter = IInterpreterV3(0x379b966DC6B117dD47b5Fc5308534256a4Ab1BCC); iExpressionDeployer = IExpressionDeployerV3(0x56394785a22b3BE25470a0e03eD9E0a939C47b9b); - iOrderBook = IOrderBookV4(0xA2f56F8F74B7d04d61f281BE6576b6155581dcBA); - iArbInstance = IOrderBookV4ArbOrderTaker(0xF97A86C2Cb3e42f89AC5f5AA020E5c3505015a88); + iOrderBook = IOrderBookV4(0x7A44459893F99b9d9a92d488eb5d16E4090f0545); + iArbInstance = IOrderBookV4ArbOrderTaker(0x03B6A05D487e760edb383754dA58C801D860D1d0); iRouteProcessor = IRouteProcessor(address(0x0389879e0156033202C44BF784ac18fC02edeE4f)); EXTERNAL_EOA = address(0x654FEf5Fb8A1C91ad47Ba192F7AA81dd3C821427); APPROVED_EOA = address(0x669845c29D9B1A64FFF66a55aA13EB4adB889a88); @@ -56,11 +56,11 @@ contract DeployedStrategyTest is StrategyTests { outputVaults[0] = outputVault; // Expected calculations context - uint256 expectedRatio = 1e10; - uint256 expectedAmountOutputMax = 1e18; + uint256 expectedRatio = 0.001e18; + uint256 expectedAmountOutputMax = 0.0000000000000001e18; // Init params for the strategy - LibStrategyDeployment.StrategyDeployment memory strategy = LibStrategyDeployment.StrategyDeployment( + LibStrategyDeployment.StrategyDeploymentV4 memory strategy = LibStrategyDeployment.StrategyDeploymentV4( "", "", 0, @@ -74,7 +74,8 @@ contract DeployedStrategyTest is StrategyTests { "./lib/rain.orderbook", "./lib/rain.orderbook/Cargo.toml", inputVaults, - outputVaults + outputVaults, + new SignedContextV1[](0) ); // Assert strategy calculations by executing order by directly calling 'takeOrder' function @@ -95,17 +96,17 @@ contract DeployedStrategyTest is StrategyTests { outputVaults[0] = outputVault; // Expected calculations context - uint256 expectedRatio = 1e10; - uint256 expectedAmountOutputMax = 1e18; + uint256 expectedRatio = 0.001e18; + uint256 expectedAmountOutputMax = 0.0000000000000001e18; // Init params for the strategy - LibStrategyDeployment.StrategyDeployment memory strategy = LibStrategyDeployment.StrategyDeployment( + LibStrategyDeployment.StrategyDeploymentV4 memory strategy = LibStrategyDeployment.StrategyDeploymentV4( getEncodedBlueToRedRoute(), getEncodedRedToBlueRoute(), 0, 0, - 5e17, - 1e18, + 1e1, + 10e18, expectedRatio, expectedAmountOutputMax, "test/strategies/base-order.rain", @@ -113,24 +114,39 @@ contract DeployedStrategyTest is StrategyTests { "./lib/rain.orderbook", "./lib/rain.orderbook/Cargo.toml", inputVaults, - outputVaults + outputVaults, + new SignedContextV1[](0) ); // Assert strategy calculations by executing order by calling 'arb' function // on the OrderBookV3ArbOrderTaker contract. - checkStrategyCalculationsArbOrder(strategy); + // checkStrategyCalculationsArbOrder(strategy); + OrderV3 memory order = addOrderDepositOutputTokens(strategy); + + { + vm.recordLogs(); + + // `arb()` called + takeArbOrder(order, strategy.takerRoute, strategy.inputTokenIndex, strategy.outputTokenIndex); + + Vm.Log[] memory entries = vm.getRecordedLogs(); + (uint256 strategyAmount, uint256 strategyRatio) = getCalculationContext(entries); + + assertEq(strategyRatio, strategy.expectedRatio); + assertEq(strategyAmount, strategy.expectedAmount); + } } // Inheriting contract defines the route for the strategy. function getEncodedRedToBlueRoute() internal pure returns (bytes memory) { - bytes memory RED_TO_BLUE_ROUTE = hex"02222789334D44bB5b2364939477E15A6c981Ca16501ffff00822abC8C238cFe43344C5db8629ed7e626fda08c01F97A86C2Cb3e42f89AC5f5AA020E5c3505015a88000bb8"; + bytes memory RED_TO_BLUE_ROUTE = hex"02222789334D44bB5b2364939477E15A6c981Ca16501ffff00822abC8C238cFe43344C5db8629ed7e626fda08c0103B6A05D487e760edb383754dA58C801D860D1d0"; return abi.encode(RED_TO_BLUE_ROUTE); } // Inheriting contract defines the route for the strategy. function getEncodedBlueToRedRoute() internal pure returns (bytes memory) { - bytes memory BLUE_TO_RED_ROUTE = hex"026d3AbB80c3CBAe0f60ba274F36137298D8571Fbe01ffff00822abC8C238cFe43344C5db8629ed7e626fda08c00F97A86C2Cb3e42f89AC5f5AA020E5c3505015a88000bb8"; + bytes memory BLUE_TO_RED_ROUTE = hex"026d3AbB80c3CBAe0f60ba274F36137298D8571Fbe01ffff00822abC8C238cFe43344C5db8629ed7e626fda08c0003B6A05D487e760edb383754dA58C801D860D1d0"; return abi.encode(BLUE_TO_RED_ROUTE); } diff --git a/test/ProcessRouteTest.t.sol b/test/ProcessRouteTest.t.sol index 34c7ae9..943a6d6 100644 --- a/test/ProcessRouteTest.t.sol +++ b/test/ProcessRouteTest.t.sol @@ -7,7 +7,7 @@ import "src/lib/LibProcessStream.sol"; contract ProcessRouteTest is Test { - uint256 constant BASE_FORK_BLOCK_NUMBER = 17300025; + uint256 constant BASE_FORK_BLOCK_NUMBER = 18371042; uint256 constant ETH_FORK_BLOCK_NUMBER = 20341342; function testProcessUniv3Route() public { diff --git a/test/strategies/base-order.rain b/test/strategies/base-order.rain index 786828b..2ee1024 100644 --- a/test/strategies/base-order.rain +++ b/test/strategies/base-order.rain @@ -6,11 +6,11 @@ networks: currency: ETH subgraphs: - base-test: https://api.goldsky.com/api/public/project_clv14x04y9kzi01saerx7bxpg/subgraphs/ob4-base/0.1/gn + base-test: https://api.goldsky.com/api/public/project_clv14x04y9kzi01saerx7bxpg/subgraphs/ob4-base/0.3/gn orderbooks: base-test: - address: 0xA2f56F8F74B7d04d61f281BE6576b6155581dcBA + address: 0x7A44459893F99b9d9a92d488eb5d16E4090f0545 network: base-test subgraph: base-test @@ -44,8 +44,10 @@ scenarios: orderbook: base-test runs: 100 bindings: - max-output: 1 - io-ratio: 0.00000001 + # Ask for now, registry in future. + orderbook-subparser: 0x762adD85a30A83722feF2e029087C9D110B6a7b3 + max-output: 0.0000000000000001 + io-ratio: 0.001 charts: base-simulation: @@ -64,10 +66,22 @@ deployments: order: base-order --- +#orderbook-subparser !The subparser for the Orderbook words #max-output !OrderBook max output #io-ratio !OrderBook order ratio + +#amount-key "amount-key" +#ratio-key "ratio-key" + #calculate-io - _ _: max-output io-ratio; + using-words-from orderbook-subparser + _: get(hash(order-hash() amount-key)), + _: get(hash(order-hash() ratio-key)); #handle-io - :; \ No newline at end of file + :; + +#post-add-order + using-words-from orderbook-subparser + :set(hash(order-hash() amount-key) max-output), + :set(hash(order-hash() ratio-key) io-ratio); \ No newline at end of file