feat: rm selector from usv3, usv4, update tests, and rename dispatcher file

This commit is contained in:
royvardhan
2025-02-24 17:16:27 +05:30
parent 58116e074a
commit 69745b18fd
10 changed files with 31 additions and 140 deletions

View File

@@ -28,17 +28,10 @@ library LibSwap {
res = address(uint160(bytes20(swap[5:25]))); 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 /// Remaining bytes are interpreted as protocol data
function protocolData( function protocolData(
bytes calldata swap bytes calldata swap
) internal pure returns (bytes calldata res) { ) internal pure returns (bytes calldata res) {
res = swap[29:]; res = swap[25:];
} }
} }

View File

@@ -3,6 +3,7 @@ pragma solidity ^0.8.26;
import "@interfaces/IExecutor.sol"; import "@interfaces/IExecutor.sol";
import "@interfaces/ICallback.sol"; import "@interfaces/ICallback.sol";
import "forge-std/console.sol";
error Dispatcher__UnapprovedExecutor(); error Dispatcher__UnapprovedExecutor();
error Dispatcher__NonContractExecutor(); error Dispatcher__NonContractExecutor();
@@ -81,7 +82,7 @@ contract Dispatcher {
} }
function _handleCallback(bytes calldata data) internal { 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]) { if (!executors[executor]) {
revert Dispatcher__UnapprovedExecutor(); revert Dispatcher__UnapprovedExecutor();

View File

@@ -148,9 +148,7 @@ contract UniswapV3Executor is IExecutor, ICallback {
view view
returns (bytes memory) returns (bytes memory)
{ {
return abi.encodePacked( return abi.encodePacked(tokenIn, tokenOut, fee, self);
tokenIn, tokenOut, fee, self, ICallback.handleCallback.selector
);
} }
function _verifyPairAddress( function _verifyPairAddress(

View File

@@ -42,7 +42,6 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback {
address tokenOut, address tokenOut,
bool zeroForOne, bool zeroForOne,
address callbackExecutor, address callbackExecutor,
bytes4 callbackSelector,
UniswapV4Executor.UniswapV4Pool[] memory pools UniswapV4Executor.UniswapV4Pool[] memory pools
) = _decodeData(data); ) = _decodeData(data);
@@ -108,8 +107,7 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback {
params[2] = abi.encode(Currency.wrap(tokenOut), uint256(0)); params[2] = abi.encode(Currency.wrap(tokenOut), uint256(0));
swapData = abi.encode(actions, params); swapData = abi.encode(actions, params);
} }
bytes memory fullData = bytes memory fullData = abi.encodePacked(swapData, callbackExecutor);
abi.encodePacked(swapData, callbackExecutor, callbackSelector);
uint256 tokenOutBalanceBefore; uint256 tokenOutBalanceBefore;
tokenOutBalanceBefore = tokenOut == address(0) tokenOutBalanceBefore = tokenOut == address(0)
@@ -143,11 +141,10 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback {
address tokenOut, address tokenOut,
bool zeroForOne, bool zeroForOne,
address callbackExecutor, address callbackExecutor,
bytes4 callbackSelector,
UniswapV4Pool[] memory pools UniswapV4Pool[] memory pools
) )
{ {
if (data.length < 91) { if (data.length < 87) {
revert UniswapV4Executor__InvalidDataLength(); revert UniswapV4Executor__InvalidDataLength();
} }
@@ -155,11 +152,10 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback {
tokenOut = address(bytes20(data[20:40])); tokenOut = address(bytes20(data[20:40]));
zeroForOne = (data[40] != 0); zeroForOne = (data[40] != 0);
callbackExecutor = address(bytes20(data[41:61])); 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); pools = new UniswapV4Pool[](poolsLength);
bytes memory poolsData = data[65:]; bytes memory poolsData = data[61:];
uint256 offset = 0; uint256 offset = 0;
for (uint256 i = 0; i < poolsLength; i++) { for (uint256 i = 0; i < poolsLength; i++) {
address intermediaryToken; address intermediaryToken;

View File

@@ -12,15 +12,12 @@ contract LibSwapTest is Test {
uint8 tokenOutIndex = 2; uint8 tokenOutIndex = 2;
uint24 split = 3; uint24 split = 3;
address executor = 0x1234567890123456789012345678901234567890; address executor = 0x1234567890123456789012345678901234567890;
bytes4 selector = 0x12345678;
bytes memory protocolData = abi.encodePacked(uint256(456)); bytes memory protocolData = abi.encodePacked(uint256(456));
bytes memory swap = abi.encodePacked( bytes memory swap = abi.encodePacked(
tokenInIndex, tokenOutIndex, split, executor, selector, protocolData tokenInIndex, tokenOutIndex, split, executor, protocolData
);
this.assertSwap(
swap, tokenInIndex, tokenOutIndex, split, executor, selector
); );
this.assertSwap(swap, tokenInIndex, tokenOutIndex, split, executor);
} }
// This is necessary so that the compiler accepts bytes as a LibSwap.sol // This is necessary so that the compiler accepts bytes as a LibSwap.sol
@@ -29,13 +26,11 @@ contract LibSwapTest is Test {
uint8 tokenInIndex, uint8 tokenInIndex,
uint8 tokenOutIndex, uint8 tokenOutIndex,
uint24 split, uint24 split,
address executor, address executor
bytes4 selector
) public pure { ) public pure {
assert(swap.tokenInIndex() == tokenInIndex); assert(swap.tokenInIndex() == tokenInIndex);
assert(swap.tokenOutIndex() == tokenOutIndex); assert(swap.tokenOutIndex() == tokenOutIndex);
assert(swap.splitPercentage() == split); assert(swap.splitPercentage() == split);
assert(swap.executor() == executor); assert(swap.executor() == executor);
assert(swap.executorSelector() == selector);
} }
} }

View File

@@ -219,12 +219,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
uint8(1),
uint24(0),
address(usv2Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
swaps[0] = swap; swaps[0] = swap;
@@ -250,7 +245,6 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(1), uint8(1),
uint24(0), uint24(0),
address(usv2Executor), address(usv2Executor),
bytes4(0),
encodeUniswapV2Swap( encodeUniswapV2Swap(
WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false
) )
@@ -262,7 +256,6 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(2), uint8(2),
uint24(0), uint24(0),
address(usv2Executor), address(usv2Executor),
bytes4(0),
encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, tychoRouterAddr, true) encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, tychoRouterAddr, true)
); );
@@ -289,7 +282,6 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(1), uint8(1),
(0xffffff * 60) / 100, // 60% (0xffffff * 60) / 100, // 60%
address(usv2Executor), address(usv2Executor),
bytes4(0),
encodeUniswapV2Swap( encodeUniswapV2Swap(
WETH_ADDR, WETH_WBTC_POOL, tychoRouterAddr, false WETH_ADDR, WETH_WBTC_POOL, tychoRouterAddr, false
) )
@@ -300,7 +292,6 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(2), uint8(2),
uint24(0), uint24(0),
address(usv2Executor), address(usv2Executor),
bytes4(0),
encodeUniswapV2Swap( encodeUniswapV2Swap(
WBTC_ADDR, USDC_WBTC_POOL, tychoRouterAddr, true WBTC_ADDR, USDC_WBTC_POOL, tychoRouterAddr, true
) )
@@ -311,7 +302,6 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(3), uint8(3),
uint24(0), uint24(0),
address(usv2Executor), address(usv2Executor),
bytes4(0),
encodeUniswapV2Swap( encodeUniswapV2Swap(
WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false
) )
@@ -323,7 +313,6 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(2), uint8(2),
uint24(0), uint24(0),
address(usv2Executor), address(usv2Executor),
bytes4(0),
encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, tychoRouterAddr, true) encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, tychoRouterAddr, true)
); );
@@ -353,12 +342,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
uint8(1),
uint24(0),
address(usv2Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
swaps[0] = swap; swaps[0] = swap;
@@ -402,12 +386,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
uint8(1),
uint24(0),
address(usv2Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
swaps[0] = swap; swaps[0] = swap;
@@ -453,12 +432,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
uint8(1),
uint24(0),
address(usv2Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
swaps[0] = swap; swaps[0] = swap;
@@ -512,12 +486,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
uint8(1),
uint24(0),
address(usv2Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
swaps[0] = swap; swaps[0] = swap;
@@ -569,12 +538,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
uint8(1),
uint24(0),
address(usv2Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
swaps[0] = swap; swaps[0] = swap;
@@ -618,12 +582,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
encodeUniswapV2Swap(DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true); encodeUniswapV2Swap(DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true);
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
uint8(1),
uint24(0),
address(usv2Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
swaps[0] = swap; swaps[0] = swap;
@@ -662,12 +621,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
WETH_ADDR, DAI_ADDR, tychoRouterAddr, DAI_WETH_USV3, zeroForOne WETH_ADDR, DAI_ADDR, tychoRouterAddr, DAI_WETH_USV3, zeroForOne
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv3Executor), protocolData
uint8(1),
uint24(0),
address(usv3Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
@@ -933,7 +887,6 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(1), uint8(1),
(0xffffff * 60) / 100, // 60% (0xffffff * 60) / 100, // 60%
address(usv2Executor), address(usv2Executor),
bytes4(0),
protocolData protocolData
); );
@@ -976,21 +929,11 @@ contract TychoRouterTest is TychoRouterTestSetup {
}); });
bytes memory protocolData = UniswapV4Utils.encodeExactInput( bytes memory protocolData = UniswapV4Utils.encodeExactInput(
USDE_ADDR, USDE_ADDR, USDT_ADDR, true, address(usv4Executor), pools
USDT_ADDR,
true,
address(usv4Executor),
SafeCallback.unlockCallback.selector,
pools
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv4Executor), protocolData
uint8(1),
uint24(0),
address(usv4Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);
@@ -1021,21 +964,11 @@ contract TychoRouterTest is TychoRouterTestSetup {
}); });
bytes memory protocolData = UniswapV4Utils.encodeExactInput( bytes memory protocolData = UniswapV4Utils.encodeExactInput(
USDE_ADDR, USDE_ADDR, WBTC_ADDR, true, address(usv4Executor), pools
WBTC_ADDR,
true,
address(usv4Executor),
SafeCallback.unlockCallback.selector,
pools
); );
bytes memory swap = encodeSwap( bytes memory swap = encodeSwap(
uint8(0), uint8(0), uint8(1), uint24(0), address(usv4Executor), protocolData
uint8(1),
uint24(0),
address(usv4Executor),
bytes4(0),
protocolData
); );
bytes[] memory swaps = new bytes[](1); bytes[] memory swaps = new bytes[](1);

View File

@@ -186,11 +186,10 @@ contract TychoRouterTestSetup is Test, Constants {
uint8 tokenOutIndex, uint8 tokenOutIndex,
uint24 split, uint24 split,
address executor, address executor,
bytes4 selector,
bytes memory protocolData bytes memory protocolData
) internal pure returns (bytes memory) { ) internal pure returns (bytes memory) {
return abi.encodePacked( return abi.encodePacked(
tokenInIndex, tokenOutIndex, split, executor, selector, protocolData tokenInIndex, tokenOutIndex, split, executor, protocolData
); );
} }

View File

@@ -19,7 +19,6 @@ contract UniswapV4ExecutorExposed is UniswapV4Executor {
address tokenOut, address tokenOut,
bool zeroForOne, bool zeroForOne,
address callbackExecutor, address callbackExecutor,
bytes4 callbackSelector,
UniswapV4Pool[] memory pools UniswapV4Pool[] memory pools
) )
{ {
@@ -42,7 +41,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
new UniswapV4ExecutorExposed(IPoolManager(poolManager)); new UniswapV4ExecutorExposed(IPoolManager(poolManager));
} }
function testDecodeParams() public view { function testDecodeParamsV4() public view {
bool zeroForOne = true; bool zeroForOne = true;
uint24 pool1Fee = 500; uint24 pool1Fee = 500;
int24 tickSpacing1 = 60; int24 tickSpacing1 = 60;
@@ -63,12 +62,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
}); });
bytes memory data = UniswapV4Utils.encodeExactInput( bytes memory data = UniswapV4Utils.encodeExactInput(
USDE_ADDR, USDE_ADDR, USDT_ADDR, zeroForOne, address(uniswapV4Exposed), pools
USDT_ADDR,
zeroForOne,
address(uniswapV4Exposed),
SafeCallback.unlockCallback.selector,
pools
); );
( (
@@ -76,7 +70,6 @@ contract UniswapV4ExecutorTest is Test, Constants {
address tokenOut, address tokenOut,
bool zeroForOneDecoded, bool zeroForOneDecoded,
address callbackExecutor, address callbackExecutor,
bytes4 callbackSelector,
UniswapV4Executor.UniswapV4Pool[] memory decodedPools UniswapV4Executor.UniswapV4Pool[] memory decodedPools
) = uniswapV4Exposed.decodeData(data); ) = uniswapV4Exposed.decodeData(data);
@@ -84,7 +77,6 @@ contract UniswapV4ExecutorTest is Test, Constants {
assertEq(tokenOut, USDT_ADDR); assertEq(tokenOut, USDT_ADDR);
assertEq(zeroForOneDecoded, zeroForOne); assertEq(zeroForOneDecoded, zeroForOne);
assertEq(callbackExecutor, address(uniswapV4Exposed)); assertEq(callbackExecutor, address(uniswapV4Exposed));
assertEq(callbackSelector, SafeCallback.unlockCallback.selector);
assertEq(decodedPools.length, 2); assertEq(decodedPools.length, 2);
assertEq(decodedPools[0].intermediaryToken, USDT_ADDR); assertEq(decodedPools[0].intermediaryToken, USDT_ADDR);
assertEq(decodedPools[0].fee, pool1Fee); assertEq(decodedPools[0].fee, pool1Fee);
@@ -94,7 +86,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
assertEq(decodedPools[1].tickSpacing, tickSpacing2); assertEq(decodedPools[1].tickSpacing, tickSpacing2);
} }
function testSingleSwap() public { function testSingleSwapV4() public {
uint256 amountIn = 100 ether; uint256 amountIn = 100 ether;
deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); deal(USDE_ADDR, address(uniswapV4Exposed), amountIn);
uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager);
@@ -110,12 +102,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
}); });
bytes memory data = UniswapV4Utils.encodeExactInput( bytes memory data = UniswapV4Utils.encodeExactInput(
USDE_ADDR, USDE_ADDR, USDT_ADDR, true, address(uniswapV4Exposed), pools
USDT_ADDR,
true,
address(uniswapV4Exposed),
SafeCallback.unlockCallback.selector,
pools
); );
uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); uint256 amountOut = uniswapV4Exposed.swap(amountIn, data);
@@ -148,7 +135,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
assertTrue(USDT.balanceOf(address(uniswapV4Exposed)) == amountOut); assertTrue(USDT.balanceOf(address(uniswapV4Exposed)) == amountOut);
} }
function testMultipleSwap() public { function testMultipleSwapV4() public {
// USDE -> USDT -> WBTC // USDE -> USDT -> WBTC
uint256 amountIn = 100 ether; uint256 amountIn = 100 ether;
deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); deal(USDE_ADDR, address(uniswapV4Exposed), amountIn);
@@ -170,12 +157,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
}); });
bytes memory data = UniswapV4Utils.encodeExactInput( bytes memory data = UniswapV4Utils.encodeExactInput(
USDE_ADDR, USDE_ADDR, WBTC_ADDR, true, address(uniswapV4Exposed), pools
WBTC_ADDR,
true,
address(uniswapV4Exposed),
SafeCallback.unlockCallback.selector,
pools
); );
uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); uint256 amountOut = uniswapV4Exposed.swap(amountIn, data);

View File

@@ -9,7 +9,6 @@ library UniswapV4Utils {
address tokenOut, address tokenOut,
bool zeroForOne, bool zeroForOne,
address callbackExecutor, address callbackExecutor,
bytes4 callbackSelector,
UniswapV4Executor.UniswapV4Pool[] memory pools UniswapV4Executor.UniswapV4Pool[] memory pools
) public pure returns (bytes memory) { ) public pure returns (bytes memory) {
bytes memory encodedPools; bytes memory encodedPools;
@@ -24,12 +23,7 @@ library UniswapV4Utils {
} }
return abi.encodePacked( return abi.encodePacked(
tokenIn, tokenIn, tokenOut, zeroForOne, callbackExecutor, encodedPools
tokenOut,
zeroForOne,
callbackExecutor,
bytes4(callbackSelector),
encodedPools
); );
} }
} }