From 69745b18fdbb4cab8a8fce1d4cf872720358db92 Mon Sep 17 00:00:00 2001 From: royvardhan Date: Mon, 24 Feb 2025 17:16:27 +0530 Subject: [PATCH] feat: rm selector from usv3, usv4, update tests, and rename dispatcher file --- foundry/lib/LibSwap.sol | 9 +- foundry/src/Dispatcher.sol | 3 +- foundry/src/executors/UniswapV3Executor.sol | 4 +- foundry/src/executors/UniswapV4Executor.sol | 12 +-- ...utionDispatcher.t.sol => Dispatcher.t.sol} | 0 foundry/test/LibSwap.t.sol | 11 +-- foundry/test/TychoRouter.t.sol | 91 +++---------------- foundry/test/TychoRouterTestSetup.sol | 3 +- .../test/executors/UniswapV4Executor.t.sol | 30 ++---- foundry/test/executors/UniswapV4Utils.sol | 8 +- 10 files changed, 31 insertions(+), 140 deletions(-) rename foundry/test/{ExecutionDispatcher.t.sol => Dispatcher.t.sol} (100%) diff --git a/foundry/lib/LibSwap.sol b/foundry/lib/LibSwap.sol index 1770005..b0c6717 100644 --- a/foundry/lib/LibSwap.sol +++ b/foundry/lib/LibSwap.sol @@ -28,17 +28,10 @@ library LibSwap { res = address(uint160(bytes20(swap[5:25]))); } - /// The selector to be used of the executor contract - function executorSelector( - bytes calldata swap - ) internal pure returns (bytes4 res) { - res = bytes4(swap[25:29]); - } - /// Remaining bytes are interpreted as protocol data function protocolData( bytes calldata swap ) internal pure returns (bytes calldata res) { - res = swap[29:]; + res = swap[25:]; } } diff --git a/foundry/src/Dispatcher.sol b/foundry/src/Dispatcher.sol index 393391b..33732d6 100644 --- a/foundry/src/Dispatcher.sol +++ b/foundry/src/Dispatcher.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.26; import "@interfaces/IExecutor.sol"; import "@interfaces/ICallback.sol"; +import "forge-std/console.sol"; error Dispatcher__UnapprovedExecutor(); error Dispatcher__NonContractExecutor(); @@ -81,7 +82,7 @@ contract Dispatcher { } function _handleCallback(bytes calldata data) internal { - address executor = address(uint160(bytes20(data[data.length - 24:]))); + address executor = address(uint160(bytes20(data[data.length - 20:]))); if (!executors[executor]) { revert Dispatcher__UnapprovedExecutor(); diff --git a/foundry/src/executors/UniswapV3Executor.sol b/foundry/src/executors/UniswapV3Executor.sol index 431e2d7..8229825 100644 --- a/foundry/src/executors/UniswapV3Executor.sol +++ b/foundry/src/executors/UniswapV3Executor.sol @@ -148,9 +148,7 @@ contract UniswapV3Executor is IExecutor, ICallback { view returns (bytes memory) { - return abi.encodePacked( - tokenIn, tokenOut, fee, self, ICallback.handleCallback.selector - ); + return abi.encodePacked(tokenIn, tokenOut, fee, self); } function _verifyPairAddress( diff --git a/foundry/src/executors/UniswapV4Executor.sol b/foundry/src/executors/UniswapV4Executor.sol index 2849bac..fff7e25 100644 --- a/foundry/src/executors/UniswapV4Executor.sol +++ b/foundry/src/executors/UniswapV4Executor.sol @@ -42,7 +42,6 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback { address tokenOut, bool zeroForOne, address callbackExecutor, - bytes4 callbackSelector, UniswapV4Executor.UniswapV4Pool[] memory pools ) = _decodeData(data); @@ -108,8 +107,7 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback { params[2] = abi.encode(Currency.wrap(tokenOut), uint256(0)); swapData = abi.encode(actions, params); } - bytes memory fullData = - abi.encodePacked(swapData, callbackExecutor, callbackSelector); + bytes memory fullData = abi.encodePacked(swapData, callbackExecutor); uint256 tokenOutBalanceBefore; tokenOutBalanceBefore = tokenOut == address(0) @@ -143,11 +141,10 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback { address tokenOut, bool zeroForOne, address callbackExecutor, - bytes4 callbackSelector, UniswapV4Pool[] memory pools ) { - if (data.length < 91) { + if (data.length < 87) { revert UniswapV4Executor__InvalidDataLength(); } @@ -155,11 +152,10 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback { tokenOut = address(bytes20(data[20:40])); zeroForOne = (data[40] != 0); callbackExecutor = address(bytes20(data[41:61])); - callbackSelector = bytes4(data[61:65]); - uint256 poolsLength = (data.length - 65) / 26; // 26 bytes per pool object + uint256 poolsLength = (data.length - 61) / 26; // 26 bytes per pool object pools = new UniswapV4Pool[](poolsLength); - bytes memory poolsData = data[65:]; + bytes memory poolsData = data[61:]; uint256 offset = 0; for (uint256 i = 0; i < poolsLength; i++) { address intermediaryToken; diff --git a/foundry/test/ExecutionDispatcher.t.sol b/foundry/test/Dispatcher.t.sol similarity index 100% rename from foundry/test/ExecutionDispatcher.t.sol rename to foundry/test/Dispatcher.t.sol diff --git a/foundry/test/LibSwap.t.sol b/foundry/test/LibSwap.t.sol index 0627740..37c6a2e 100644 --- a/foundry/test/LibSwap.t.sol +++ b/foundry/test/LibSwap.t.sol @@ -12,15 +12,12 @@ contract LibSwapTest is Test { uint8 tokenOutIndex = 2; uint24 split = 3; address executor = 0x1234567890123456789012345678901234567890; - bytes4 selector = 0x12345678; bytes memory protocolData = abi.encodePacked(uint256(456)); bytes memory swap = abi.encodePacked( - tokenInIndex, tokenOutIndex, split, executor, selector, protocolData - ); - this.assertSwap( - swap, tokenInIndex, tokenOutIndex, split, executor, selector + tokenInIndex, tokenOutIndex, split, executor, protocolData ); + this.assertSwap(swap, tokenInIndex, tokenOutIndex, split, executor); } // This is necessary so that the compiler accepts bytes as a LibSwap.sol @@ -29,13 +26,11 @@ contract LibSwapTest is Test { uint8 tokenInIndex, uint8 tokenOutIndex, uint24 split, - address executor, - bytes4 selector + address executor ) public pure { assert(swap.tokenInIndex() == tokenInIndex); assert(swap.tokenOutIndex() == tokenOutIndex); assert(swap.splitPercentage() == split); assert(swap.executor() == executor); - assert(swap.executorSelector() == selector); } } diff --git a/foundry/test/TychoRouter.t.sol b/foundry/test/TychoRouter.t.sol index d611e99..c07ab69 100644 --- a/foundry/test/TychoRouter.t.sol +++ b/foundry/test/TychoRouter.t.sol @@ -219,12 +219,7 @@ contract TychoRouterTest is TychoRouterTestSetup { ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv2Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData ); bytes[] memory swaps = new bytes[](1); swaps[0] = swap; @@ -250,7 +245,6 @@ contract TychoRouterTest is TychoRouterTestSetup { uint8(1), uint24(0), address(usv2Executor), - bytes4(0), encodeUniswapV2Swap( WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false ) @@ -262,7 +256,6 @@ contract TychoRouterTest is TychoRouterTestSetup { uint8(2), uint24(0), address(usv2Executor), - bytes4(0), encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, tychoRouterAddr, true) ); @@ -289,7 +282,6 @@ contract TychoRouterTest is TychoRouterTestSetup { uint8(1), (0xffffff * 60) / 100, // 60% address(usv2Executor), - bytes4(0), encodeUniswapV2Swap( WETH_ADDR, WETH_WBTC_POOL, tychoRouterAddr, false ) @@ -300,7 +292,6 @@ contract TychoRouterTest is TychoRouterTestSetup { uint8(2), uint24(0), address(usv2Executor), - bytes4(0), encodeUniswapV2Swap( WBTC_ADDR, USDC_WBTC_POOL, tychoRouterAddr, true ) @@ -311,7 +302,6 @@ contract TychoRouterTest is TychoRouterTestSetup { uint8(3), uint24(0), address(usv2Executor), - bytes4(0), encodeUniswapV2Swap( WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false ) @@ -323,7 +313,6 @@ contract TychoRouterTest is TychoRouterTestSetup { uint8(2), uint24(0), address(usv2Executor), - bytes4(0), encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, tychoRouterAddr, true) ); @@ -353,12 +342,7 @@ contract TychoRouterTest is TychoRouterTestSetup { ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv2Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData ); bytes[] memory swaps = new bytes[](1); swaps[0] = swap; @@ -402,12 +386,7 @@ contract TychoRouterTest is TychoRouterTestSetup { ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv2Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData ); bytes[] memory swaps = new bytes[](1); swaps[0] = swap; @@ -453,12 +432,7 @@ contract TychoRouterTest is TychoRouterTestSetup { ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv2Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData ); bytes[] memory swaps = new bytes[](1); swaps[0] = swap; @@ -512,12 +486,7 @@ contract TychoRouterTest is TychoRouterTestSetup { ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv2Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData ); bytes[] memory swaps = new bytes[](1); swaps[0] = swap; @@ -569,12 +538,7 @@ contract TychoRouterTest is TychoRouterTestSetup { ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv2Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData ); bytes[] memory swaps = new bytes[](1); swaps[0] = swap; @@ -618,12 +582,7 @@ contract TychoRouterTest is TychoRouterTestSetup { encodeUniswapV2Swap(DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv2Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData ); bytes[] memory swaps = new bytes[](1); swaps[0] = swap; @@ -662,12 +621,7 @@ contract TychoRouterTest is TychoRouterTestSetup { WETH_ADDR, DAI_ADDR, tychoRouterAddr, DAI_WETH_USV3, zeroForOne ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv3Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv3Executor), protocolData ); bytes[] memory swaps = new bytes[](1); @@ -933,7 +887,6 @@ contract TychoRouterTest is TychoRouterTestSetup { uint8(1), (0xffffff * 60) / 100, // 60% address(usv2Executor), - bytes4(0), protocolData ); @@ -976,21 +929,11 @@ contract TychoRouterTest is TychoRouterTestSetup { }); bytes memory protocolData = UniswapV4Utils.encodeExactInput( - USDE_ADDR, - USDT_ADDR, - true, - address(usv4Executor), - SafeCallback.unlockCallback.selector, - pools + USDE_ADDR, USDT_ADDR, true, address(usv4Executor), pools ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv4Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv4Executor), protocolData ); bytes[] memory swaps = new bytes[](1); @@ -1021,21 +964,11 @@ contract TychoRouterTest is TychoRouterTestSetup { }); bytes memory protocolData = UniswapV4Utils.encodeExactInput( - USDE_ADDR, - WBTC_ADDR, - true, - address(usv4Executor), - SafeCallback.unlockCallback.selector, - pools + USDE_ADDR, WBTC_ADDR, true, address(usv4Executor), pools ); bytes memory swap = encodeSwap( - uint8(0), - uint8(1), - uint24(0), - address(usv4Executor), - bytes4(0), - protocolData + uint8(0), uint8(1), uint24(0), address(usv4Executor), protocolData ); bytes[] memory swaps = new bytes[](1); diff --git a/foundry/test/TychoRouterTestSetup.sol b/foundry/test/TychoRouterTestSetup.sol index 9fb1f44..e66d3c2 100644 --- a/foundry/test/TychoRouterTestSetup.sol +++ b/foundry/test/TychoRouterTestSetup.sol @@ -186,11 +186,10 @@ contract TychoRouterTestSetup is Test, Constants { uint8 tokenOutIndex, uint24 split, address executor, - bytes4 selector, bytes memory protocolData ) internal pure returns (bytes memory) { return abi.encodePacked( - tokenInIndex, tokenOutIndex, split, executor, selector, protocolData + tokenInIndex, tokenOutIndex, split, executor, protocolData ); } diff --git a/foundry/test/executors/UniswapV4Executor.t.sol b/foundry/test/executors/UniswapV4Executor.t.sol index c4d0787..86d78fa 100644 --- a/foundry/test/executors/UniswapV4Executor.t.sol +++ b/foundry/test/executors/UniswapV4Executor.t.sol @@ -19,7 +19,6 @@ contract UniswapV4ExecutorExposed is UniswapV4Executor { address tokenOut, bool zeroForOne, address callbackExecutor, - bytes4 callbackSelector, UniswapV4Pool[] memory pools ) { @@ -42,7 +41,7 @@ contract UniswapV4ExecutorTest is Test, Constants { new UniswapV4ExecutorExposed(IPoolManager(poolManager)); } - function testDecodeParams() public view { + function testDecodeParamsV4() public view { bool zeroForOne = true; uint24 pool1Fee = 500; int24 tickSpacing1 = 60; @@ -63,12 +62,7 @@ contract UniswapV4ExecutorTest is Test, Constants { }); bytes memory data = UniswapV4Utils.encodeExactInput( - USDE_ADDR, - USDT_ADDR, - zeroForOne, - address(uniswapV4Exposed), - SafeCallback.unlockCallback.selector, - pools + USDE_ADDR, USDT_ADDR, zeroForOne, address(uniswapV4Exposed), pools ); ( @@ -76,7 +70,6 @@ contract UniswapV4ExecutorTest is Test, Constants { address tokenOut, bool zeroForOneDecoded, address callbackExecutor, - bytes4 callbackSelector, UniswapV4Executor.UniswapV4Pool[] memory decodedPools ) = uniswapV4Exposed.decodeData(data); @@ -84,7 +77,6 @@ contract UniswapV4ExecutorTest is Test, Constants { assertEq(tokenOut, USDT_ADDR); assertEq(zeroForOneDecoded, zeroForOne); assertEq(callbackExecutor, address(uniswapV4Exposed)); - assertEq(callbackSelector, SafeCallback.unlockCallback.selector); assertEq(decodedPools.length, 2); assertEq(decodedPools[0].intermediaryToken, USDT_ADDR); assertEq(decodedPools[0].fee, pool1Fee); @@ -94,7 +86,7 @@ contract UniswapV4ExecutorTest is Test, Constants { assertEq(decodedPools[1].tickSpacing, tickSpacing2); } - function testSingleSwap() public { + function testSingleSwapV4() public { uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); @@ -110,12 +102,7 @@ contract UniswapV4ExecutorTest is Test, Constants { }); bytes memory data = UniswapV4Utils.encodeExactInput( - USDE_ADDR, - USDT_ADDR, - true, - address(uniswapV4Exposed), - SafeCallback.unlockCallback.selector, - pools + USDE_ADDR, USDT_ADDR, true, address(uniswapV4Exposed), pools ); uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); @@ -148,7 +135,7 @@ contract UniswapV4ExecutorTest is Test, Constants { assertTrue(USDT.balanceOf(address(uniswapV4Exposed)) == amountOut); } - function testMultipleSwap() public { + function testMultipleSwapV4() public { // USDE -> USDT -> WBTC uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); @@ -170,12 +157,7 @@ contract UniswapV4ExecutorTest is Test, Constants { }); bytes memory data = UniswapV4Utils.encodeExactInput( - USDE_ADDR, - WBTC_ADDR, - true, - address(uniswapV4Exposed), - SafeCallback.unlockCallback.selector, - pools + USDE_ADDR, WBTC_ADDR, true, address(uniswapV4Exposed), pools ); uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); diff --git a/foundry/test/executors/UniswapV4Utils.sol b/foundry/test/executors/UniswapV4Utils.sol index 272d319..cf5ad19 100644 --- a/foundry/test/executors/UniswapV4Utils.sol +++ b/foundry/test/executors/UniswapV4Utils.sol @@ -9,7 +9,6 @@ library UniswapV4Utils { address tokenOut, bool zeroForOne, address callbackExecutor, - bytes4 callbackSelector, UniswapV4Executor.UniswapV4Pool[] memory pools ) public pure returns (bytes memory) { bytes memory encodedPools; @@ -24,12 +23,7 @@ library UniswapV4Utils { } return abi.encodePacked( - tokenIn, - tokenOut, - zeroForOne, - callbackExecutor, - bytes4(callbackSelector), - encodedPools + tokenIn, tokenOut, zeroForOne, callbackExecutor, encodedPools ); } }