Skip to content

Commit

Permalink
update to obv4
Browse files Browse the repository at this point in the history
  • Loading branch information
Siddharth2207 committed Jul 19, 2024
1 parent a3722c0 commit b49b490
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 227 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ jobs:
fail-fast: true
runs-on: ubuntu-latest
env:
RPC_URL_ARBITRUM: ${{ secrets. RPC_URL_ARBITRUM}}
RPC_URL_ETH: ${{ secrets. RPC_URL_ETH}}
CI_DEPLOY_SEPOLIA_RPC_URL: ${{ secrets.CI_DEPLOY_SEPOLIA_RPC_URL || vars.CI_DEPLOY_SEPOLIA_RPC_URL }}
CI_FORK_SEPOLIA_BLOCK_NUMBER: ${{ vars.CI_FORK_SEPOLIA_BLOCK_NUMBER }}
CI_FORK_SEPOLIA_DEPLOYER_ADDRESS: ${{ vars.CI_FORK_SEPOLIA_DEPLOYER_ADDRESS }}
CI_SEPOLIA_METABOARD_URL: ${{ vars.CI_SEPOLIA_METABOARD_URL }}
CI_DEPLOY_POLYGON_RPC_URL: ${{ secrets.CI_DEPLOY_POLYGON_RPC_URL }}
RPC_URL_ETHEREUM_FORK: ${{ secrets.RPC_URL_ETHEREUM_FORK }}
RPC_URL_ARBITRUM: ${{ secrets.CI_DEPLOY_ARBITRUM_RPC_URL || vars.CI_DEPLOY_ARBITRUM_RPC_URL }}
RPC_URL_BASE: ${{ secrets.CI_DEPLOY_BASE_RPC_URL || vars.CI_DEPLOY_BASE_RPC_URL }}
RPC_URL_FLARE: ${{ secrets.CI_DEPLOY_FLARE_RPC_URL || vars.CI_DEPLOY_FLARE_RPC_URL }}
RPC_URL_POLYGON: ${{ secrets.CI_DEPLOY_POLYGON_RPC_URL || vars.CI_DEPLOY_POLYGON_RPC_URL }}
RPC_URL_ETH: ${{ secrets.CI_DEPLOY_ETH_RPC_URL || vars.CI_DEPLOY_ETH_RPC_URL }}

steps:
- uses: actions/checkout@v4
Expand Down
12 changes: 6 additions & 6 deletions src/StrategyTests.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ contract StrategyTests is OrderBookStrategyTest {
// indexed by `inputTokenIndex` and `outputTokenIndex`.
function addOrderDepositOutputTokens(LibStrategyDeployment.StrategyDeployment memory strategy)
internal
returns (OrderV2 memory order)
returns (OrderV3 memory order)
{
address inputToken;
address outputToken;
Expand All @@ -31,22 +31,22 @@ contract StrategyTests is OrderBookStrategyTest {
deal(address(outputToken), ORDER_OWNER, 1e30);
}
{
depositTokens(ORDER_OWNER, outputToken, outputTokenVaultId, strategy.takerAmount);
depositTokens(ORDER_OWNER, outputToken, outputTokenVaultId, strategy.takerAmount, new ActionV1[](0));
}
{
(bytes memory bytecode, uint256[] memory constants) = PARSER.parse(
bytes memory bytecode = PARSER.parse2(
LibComposeOrders.getComposedOrder(
vm, strategy.strategyFile, strategy.strategyScenario, strategy.buildPath, strategy.manifestPath
)
);
order = placeOrder(ORDER_OWNER, bytecode, constants, strategy.inputVaults, strategy.outputVaults);
order = placeOrder(ORDER_OWNER, bytecode, strategy.inputVaults, strategy.outputVaults, new ActionV1[](0));
}
}

// Function to assert OrderBook calculations context by calling 'takeOrders' function
// directly from the OrderBook contract.
function checkStrategyCalculations(LibStrategyDeployment.StrategyDeployment memory strategy) internal {
OrderV2 memory order = addOrderDepositOutputTokens(strategy);
OrderV3 memory order = addOrderDepositOutputTokens(strategy);
{
vm.recordLogs();

Expand All @@ -64,7 +64,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 {
OrderV2 memory order = addOrderDepositOutputTokens(strategy);
OrderV3 memory order = addOrderDepositOutputTokens(strategy);

// Move external pool price in opposite direction that of the order
{
Expand Down
88 changes: 51 additions & 37 deletions src/abstract/OrderBookStrategyTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@ pragma solidity =0.8.25;

import {Vm} from "forge-std/Vm.sol";
import {Test, console2, stdError} from "forge-std/Test.sol";
import {IOrderBookV3ArbOrderTaker} from "rain.orderbook.interface/interface/IOrderBookV3ArbOrderTaker.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 {IInterpreterV2} from "rain.interpreter.interface/interface/IInterpreterV2.sol";
import {IInterpreterV3} from "rain.interpreter.interface/interface/unstable/IInterpreterV3.sol";
import {IInterpreterStoreV2} from "rain.interpreter.interface/interface/IInterpreterStoreV2.sol";
import {EvaluableConfigV3, SignedContextV1} from "rain.interpreter.interface/interface/IInterpreterCallerV2.sol";
import {
IOrderBookV3,
IO,
OrderV2,
OrderConfigV2,
TakeOrderConfigV2,
TakeOrdersConfigV2
IO
} from "rain.orderbook.interface/interface/IOrderBookV3.sol";
import {
IOrderBookV4,
OrderV3,
OrderConfigV3,
TakeOrderConfigV3,
TakeOrdersConfigV3,
ActionV1,
EvaluableV3
}from "rain.orderbook.interface/interface/unstable/IOrderBookV4.sol";
import {IOrderBookV4ArbOrderTaker} from "rain.orderbook.interface/interface/unstable/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";
Expand All @@ -30,24 +37,24 @@ abstract contract OrderBookStrategyTest is Test {
address public APPROVED_EOA;
address public ORDER_OWNER;

IParserV1 public PARSER;
IParserV2 public PARSER;
IExpressionDeployerV3 public EXPRESSION_DEPLOYER;
IInterpreterV2 public INTERPRETER;
IInterpreterV3 public INTERPRETER;
IInterpreterStoreV2 public STORE;
IOrderBookV3 public ORDERBOOK;
IOrderBookV3ArbOrderTaker public ARB_INSTANCE;
IOrderBookV4 public ORDERBOOK;
IOrderBookV4ArbOrderTaker public ARB_INSTANCE;
IRouteProcessor public ROUTE_PROCESSOR;

function depositTokens(address owner, address token, uint256 vaultId, uint256 amount) internal {
function depositTokens(address owner, address token, uint256 vaultId, uint256 amount, ActionV1[] memory actionV1) internal {
vm.startPrank(owner);
IERC20(token).safeApprove(address(ORDERBOOK), amount);
ORDERBOOK.deposit(address(token), vaultId, amount);
ORDERBOOK.deposit2(address(token), vaultId, amount, actionV1);
vm.stopPrank();
}

function withdrawTokens(address owner, address token, uint256 vaultId, uint256 amount) internal {
function withdrawTokens(address owner, address token, uint256 vaultId, uint256 amount, ActionV1[] memory actionV1) internal {
vm.startPrank(owner);
ORDERBOOK.withdraw(address(token), vaultId, amount);
ORDERBOOK.withdraw2(address(token), vaultId, amount, actionV1);
vm.stopPrank();
}

Expand All @@ -58,49 +65,56 @@ abstract contract OrderBookStrategyTest is Test {
function placeOrder(
address orderOwner,
bytes memory bytecode,
uint256[] memory constants,
IO[] memory inputs,
IO[] memory outputs
) internal returns (OrderV2 memory order) {
EvaluableConfigV3 memory evaluableConfig = EvaluableConfigV3(EXPRESSION_DEPLOYER, bytecode, constants);
OrderConfigV2 memory orderConfig = OrderConfigV2(inputs, outputs, evaluableConfig, "");
IO[] memory outputs,
ActionV1[] memory actionV1
) internal returns (OrderV3 memory order) {

EvaluableV3 memory evaluableConfig = EvaluableV3(INTERPRETER, STORE ,bytecode);
OrderConfigV3 memory orderV3Config = OrderConfigV3(evaluableConfig, inputs, outputs, "", "", "");

vm.startPrank(orderOwner);
vm.recordLogs();
(bool stateChanged) = ORDERBOOK.addOrder(orderConfig);
(bool stateChanged) = ORDERBOOK.addOrder2(orderV3Config,actionV1);
Vm.Log[] memory entries = vm.getRecordedLogs();
assertEq(entries.length, 3);
(,, order,) = abi.decode(entries[2].data, (address, address, OrderV2, bytes32));
assertEq(entries.length, 1);
(,, order) = abi.decode(entries[0].data, (address, bytes32, OrderV3));
assertEq(order.owner, orderOwner);
assertEq(stateChanged, true);
}

function takeArbOrder(OrderV2 memory order, bytes memory route, uint256 inputIOIndex, uint256 outputIOIndex)
function takeArbOrder(OrderV3 memory order, bytes memory route, uint256 inputIOIndex, uint256 outputIOIndex)
internal
{
vm.startPrank(APPROVED_EOA);

TakeOrderConfigV2[] memory innerConfigs = new TakeOrderConfigV2[](1);

innerConfigs[0] = TakeOrderConfigV2(order, inputIOIndex, outputIOIndex, new SignedContextV1[](0));
TakeOrdersConfigV2 memory takeOrdersConfig =
TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, innerConfigs, route);
ARB_INSTANCE.arb(takeOrdersConfig, 0);
EvaluableV3 memory arbEvaluableV3Config = EvaluableV3(
IInterpreterV3(0x0000000000000000000000000000000000000000),
IInterpreterStoreV2(0x0000000000000000000000000000000000000000),
""
);
TakeOrderConfigV3[] memory innerConfigs = new TakeOrderConfigV3[](1);
innerConfigs[0] = TakeOrderConfigV3(order, inputIOIndex, outputIOIndex, new SignedContextV1[](0));

TakeOrdersConfigV3 memory takeOrdersConfig =
TakeOrdersConfigV3(0, type(uint256).max, type(uint256).max, innerConfigs, route);
ARB_INSTANCE.arb2(takeOrdersConfig, 0, arbEvaluableV3Config);
vm.stopPrank();
}

function takeExternalOrder(OrderV2 memory order, uint256 inputIOIndex, uint256 outputIOIndex) internal {
function takeExternalOrder(OrderV3 memory order, uint256 inputIOIndex, uint256 outputIOIndex) internal {
vm.startPrank(APPROVED_EOA);
address inputTokenAddress = order.validInputs[inputIOIndex].token;

address inputTokenAddress = order.validInputs[inputIOIndex].token;
IERC20(inputTokenAddress).safeApprove(address(ORDERBOOK), type(uint256).max);
TakeOrderConfigV2[] memory innerConfigs = new TakeOrderConfigV2[](1);

innerConfigs[0] = TakeOrderConfigV2(order, inputIOIndex, outputIOIndex, new SignedContextV1[](0));
TakeOrdersConfigV2 memory takeOrdersConfig =
TakeOrdersConfigV2(0, type(uint256).max, type(uint256).max, innerConfigs, "");
TakeOrderConfigV3[] memory innerConfigs = new TakeOrderConfigV3[](1);

innerConfigs[0] = TakeOrderConfigV3(order, inputIOIndex, outputIOIndex, new SignedContextV1[](0));
TakeOrdersConfigV3 memory takeOrdersConfig =
TakeOrdersConfigV3(0, type(uint256).max, type(uint256).max, innerConfigs, "");

ORDERBOOK.takeOrders(takeOrdersConfig);
ORDERBOOK.takeOrders2(takeOrdersConfig);
vm.stopPrank();
}

Expand Down
56 changes: 39 additions & 17 deletions src/lib/LibProcessStream.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ pragma solidity =0.8.25;
import {Vm} from "forge-std/Vm.sol";
import {Strings} from "openzeppelin-contracts/contracts/utils/Strings.sol";
import {InputStream} from "lib/sushiswap/protocols/route-processor/contracts/InputStream.sol";
import {IUniswapV2Pair} from "lib/sushiswap/protocols/route-processor/interfaces/IUniswapV2Pair.sol";

import "forge-std/console2.sol";

/// Library to decompile sushi routes
Expand All @@ -17,8 +19,8 @@ library LibProcessStream {

/// Struct representing relevant data for a route.
struct RouteProcessorData{
uint8 direction;
address tokenIn;
address tokenOut;
address pool;
address to;
}
Expand All @@ -32,7 +34,7 @@ library LibProcessStream {
}

/// Process a route stream.
function processRoute(bytes memory route) internal pure returns(ProcessedRoute memory processedRoute){
function processRoute(bytes memory route) internal view returns(ProcessedRoute memory processedRoute){
uint256 stream = InputStream.createStream(route);
while (stream.isNotEmpty()) {
uint8 commandCode = stream.readUint8();
Expand All @@ -49,6 +51,7 @@ library LibProcessStream {
processedRoute.processedOnePool = processOnePool(stream);
logRoute(processedRoute.processedOnePool);
}
else revert('RouteProcessor: Decompiler unknown command code');
}
}

Expand All @@ -58,34 +61,34 @@ library LibProcessStream {
for(uint256 i = 0 ; i < routeData.length; i++){
console2.log("----------------------Processed Route----------------------");
console2.log("TOKEN IN : ",routeData[i].tokenIn);
console2.log("TOKEN OUT : ",routeData[i].tokenOut);
console2.log("POOL : ",routeData[i].pool);
console2.log("DIRECTION : ",routeData[i].direction);
console2.log("TO : ",routeData[i].to);
}
}
}

function processMyERC20(uint256 stream) internal pure returns(RouteProcessorData[] memory){
function processMyERC20(uint256 stream) internal view returns(RouteProcessorData[] memory){
address token = stream.readAddress();
return distributeAndSwap(stream,token);
}

function processUserERC20(uint256 stream) internal pure returns(RouteProcessorData[] memory){
function processUserERC20(uint256 stream) internal view returns(RouteProcessorData[] memory){
address token = stream.readAddress();
return distributeAndSwap(stream, token);
}

function processNative(uint256 stream) internal pure returns(RouteProcessorData[] memory){
function processNative(uint256 stream) internal view returns(RouteProcessorData[] memory){
return distributeAndSwap(stream, NATIVE_ADDRESS);
}

function processOnePool(uint256 stream) internal pure returns(RouteProcessorData[] memory processedRoutes){
function processOnePool(uint256 stream) internal view returns(RouteProcessorData[] memory processedRoutes){
address token = stream.readAddress();
processedRoutes = new RouteProcessorData[](1);
processedRoutes[0] = swap(stream, token);
}

function distributeAndSwap(uint256 stream, address tokenIn) internal pure returns(RouteProcessorData[] memory processedRoutes){
function distributeAndSwap(uint256 stream, address tokenIn) internal view returns(RouteProcessorData[] memory processedRoutes){
uint8 num = stream.readUint8();
processedRoutes = new RouteProcessorData[](num);
unchecked {
Expand All @@ -96,31 +99,50 @@ library LibProcessStream {
}
}

function swap(uint256 stream, address tokenIn) internal pure returns(RouteProcessorData memory routeData){
function swap(uint256 stream, address tokenIn) internal view returns(RouteProcessorData memory routeData){
uint8 poolType = stream.readUint8();
if (poolType == 0) routeData = swapUniV2(stream,tokenIn);
else if (poolType == 1) routeData = swapUniV3(stream,tokenIn);
else if (poolType == 2) routeData = wrapNative(stream,tokenIn);
else if (poolType == 5) routeData = swapCurve(stream,tokenIn);
else revert('RouteProcessor: Unknown pool type');
}

function swapUniV2(uint256 stream, address tokenIn) internal pure returns(RouteProcessorData memory routeData){
function swapUniV2(uint256 stream, address tokenIn) internal view returns(RouteProcessorData memory routeData){
address pool = stream.readAddress();
uint8 direction = stream.readUint8();
uint8 direction = stream.readUint8() ;
address to = stream.readAddress();
routeData = RouteProcessorData(direction,tokenIn,pool,to);
uint24 fee = stream.readUint24();
(fee);
address tokenOut = direction == 1 ? IUniswapV2Pair(pool).token1() : IUniswapV2Pair(pool).token0();
routeData = RouteProcessorData(tokenIn,tokenOut,pool,to);
}

function swapUniV3(uint256 stream, address tokenIn) internal pure returns(RouteProcessorData memory routeData){
function swapUniV3(uint256 stream, address tokenIn) internal view returns(RouteProcessorData memory routeData){
address pool = stream.readAddress();
uint8 direction = stream.readUint8() > 0 ? 1 : 0 ;
uint8 direction = stream.readUint8() ;
address recipient = stream.readAddress();
routeData = RouteProcessorData(direction,tokenIn,pool,recipient);
address tokenOut = direction == 1 ? IUniswapV2Pair(pool).token1() : IUniswapV2Pair(pool).token0();
routeData = RouteProcessorData(tokenIn,tokenOut,pool,recipient);
}

function wrapNative(uint256 stream, address tokenIn) internal pure returns(RouteProcessorData memory routeData){
uint8 directionAndFake = stream.readUint8();
(directionAndFake);
address to = stream.readAddress();
routeData = RouteProcessorData(directionAndFake,tokenIn,NATIVE_ADDRESS,to);
routeData = RouteProcessorData(tokenIn,tokenIn,NATIVE_ADDRESS,to);
}

function swapCurve(uint256 stream, address tokenIn) internal pure returns(RouteProcessorData memory routeData){
address pool = stream.readAddress();
uint8 poolType = stream.readUint8();
int128 fromIndex = int8(stream.readUint8());
int128 toIndex = int8(stream.readUint8());
address to = stream.readAddress();
address tokenOut = stream.readAddress();
(poolType,fromIndex,toIndex);
routeData = RouteProcessorData(tokenIn,tokenOut,pool,to);
}


}
}
Loading

0 comments on commit b49b490

Please sign in to comment.