Merge pull request #82 from propeller-heads/router/hr/ENG-4262-hardcode-callback-swap-selector

feat: hardcode callback and swap selection in dispatcher
This commit is contained in:
Harsh Vardhan Roy
2025-02-24 22:27:55 +05:30
committed by GitHub
17 changed files with 96 additions and 281 deletions

View File

@@ -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:];
}
}

View File

@@ -55,7 +55,6 @@ contract Dispatcher {
// slither-disable-next-line delegatecall-loop
function _callExecutor(
address executor,
bytes4 selector,
uint256 amount,
bytes calldata data
) internal returns (uint256 calculatedAmount) {
@@ -63,10 +62,9 @@ contract Dispatcher {
revert Dispatcher__UnapprovedExecutor();
}
selector = selector == bytes4(0) ? IExecutor.swap.selector : selector;
// slither-disable-next-line controlled-delegatecall,low-level-calls
(bool success, bytes memory result) = executor.delegatecall(
abi.encodeWithSelector(selector, amount, data)
abi.encodeWithSelector(IExecutor.swap.selector, amount, data)
);
if (!success) {
@@ -83,18 +81,16 @@ contract Dispatcher {
}
function _handleCallback(bytes calldata data) internal {
bytes4 selector = bytes4(data[data.length - 4:]);
address executor = address(uint160(bytes20(data[data.length - 24:])));
address executor = address(uint160(bytes20(data[data.length - 20:])));
if (!executors[executor]) {
revert Dispatcher__UnapprovedExecutor();
}
selector =
selector == bytes4(0) ? ICallback.handleCallback.selector : selector;
// slither-disable-next-line controlled-delegatecall,low-level-calls
(bool success, bytes memory result) =
executor.delegatecall(abi.encodeWithSelector(selector, data));
(bool success, bytes memory result) = executor.delegatecall(
abi.encodeWithSelector(ICallback.handleCallback.selector, data)
);
if (!success) {
revert(

View File

@@ -286,10 +286,7 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
: remainingAmounts[tokenInIndex];
currentAmountOut = _callExecutor(
swapData.executor(),
swapData.executorSelector(),
currentAmountIn,
swapData.protocolData()
swapData.executor(), currentAmountIn, swapData.protocolData()
);
amounts[tokenOutIndex] += currentAmountOut;
remainingAmounts[tokenOutIndex] += currentAmountOut;

View File

@@ -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(

View File

@@ -16,10 +16,11 @@ import {V4Router} from "@uniswap/v4-periphery/src/V4Router.sol";
import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol";
import {IV4Router} from "@uniswap/v4-periphery/src/interfaces/IV4Router.sol";
import {PathKey} from "@uniswap/v4-periphery/src/libraries/PathKey.sol";
import {ICallback} from "@interfaces/ICallback.sol";
error UniswapV4Executor__InvalidDataLength();
contract UniswapV4Executor is IExecutor, V4Router {
contract UniswapV4Executor is IExecutor, V4Router, ICallback {
using SafeERC20 for IERC20;
using CurrencyLibrary for Currency;
@@ -41,7 +42,6 @@ contract UniswapV4Executor is IExecutor, V4Router {
address tokenOut,
bool zeroForOne,
address callbackExecutor,
bytes4 callbackSelector,
UniswapV4Executor.UniswapV4Pool[] memory pools
) = _decodeData(data);
@@ -107,8 +107,7 @@ contract UniswapV4Executor is IExecutor, V4Router {
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)
@@ -142,11 +141,10 @@ contract UniswapV4Executor is IExecutor, V4Router {
address tokenOut,
bool zeroForOne,
address callbackExecutor,
bytes4 callbackSelector,
UniswapV4Pool[] memory pools
)
{
if (data.length < 91) {
if (data.length < 87) {
revert UniswapV4Executor__InvalidDataLength();
}
@@ -154,11 +152,10 @@ contract UniswapV4Executor is IExecutor, V4Router {
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;
@@ -176,6 +173,16 @@ contract UniswapV4Executor is IExecutor, V4Router {
}
}
function handleCallback(bytes calldata data)
external
returns (bytes memory)
{
verifyCallback(data);
return _unlockCallback(data);
}
function verifyCallback(bytes calldata) public view onlyPoolManager {}
function _pay(Currency token, address, uint256 amount) internal override {
IERC20(Currency.unwrap(token)).safeTransfer(
address(poolManager), amount

View File

@@ -7,11 +7,10 @@ import "./TychoRouterTestSetup.sol";
contract DispatcherExposed is Dispatcher {
function exposedCallExecutor(
address executor,
bytes4 selector,
uint256 amount,
bytes calldata data
) external returns (uint256 calculatedAmount) {
return _callExecutor(executor, selector, amount, data);
return _callExecutor(executor, amount, data);
}
function exposedSetExecutor(address target) external {
@@ -83,10 +82,7 @@ contract DispatcherTest is Constants {
hex"5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72fc8c39af7983bf329086de522229a7be5fc4e41cc51c72848c68a965f66fa7a88855f9f7784502a7f2606beffe61000613d6a25b5bfef4cd7652aa94777d4a46b39f2e206411280a12c9344b769ff1066c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000d02ab486cedc0000000000000000000000000000000000000000000000000000000000082ec8ad1b0000000000000000000000000000000000000000000000000000000066d7b65800000000000000000000000000000000000000000000000000000191ba9f843c125000064000640000d52de09955f0ffffffffffffff00225c389e595fe9000001fcc910754b349f821e4bb5d8444822a63920be943aba6f1b31ee14ef0fc6840b6d28d604e04a78834b668dba24a6c082ffb901e4fffa9600649e8d991af593c81c";
uint256 givenAmount = 15 ether;
uint256 amount = dispatcherExposed.exposedCallExecutor(
0xe592557AB9F4A75D992283fD6066312FF013ba3d,
IExecutor.swap.selector,
givenAmount,
data
0xe592557AB9F4A75D992283fD6066312FF013ba3d, givenAmount, data
);
assert(amount == 35144641819);
}
@@ -110,10 +106,7 @@ contract DispatcherTest is Constants {
hex"5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72fc8c39af7983bf329086de522229a7be5fc4e41cc51c72848c68a965f66fa7a88855f9f7784502a7f2606beffe61000613d6a25b5bfef4cd7652aa94777d4a46b39f2e206411280a12c9344b769ff1066c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000d02ab486cedc0000000000000000000000000000000000000000000000000000000000082ec8ad1b0000000000000000000000000000000000000000000000000000000066d7b65800000000000000000000000000000000000000000000000000000191ba9f843c125000064000640000d52de09955f0ffffffffffffff00225c389e595fe9000001fcc910754b349f821e4bb5d8444822a63920be943aba6f1b31ee14ef0fc6840b6d28d604e04a78834b668dba24a6c082ffb901e4fffa9600649e8d991af593c81c";
uint256 givenAmount = 15 ether;
uint256 amount = dispatcherExposed.exposedCallExecutor(
0xe592557AB9F4A75D992283fD6066312FF013ba3d,
bytes4(0),
givenAmount,
data
0xe592557AB9F4A75D992283fD6066312FF013ba3d, givenAmount, data
);
assert(amount == 35144641819);
}
@@ -127,10 +120,7 @@ contract DispatcherTest is Constants {
hex"5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72fc8c39af7983bf329086de522229a7be5fc4e41cc51c72848c68a965f66fa7a88855f9f7784502a7f2606beffe61000613d6a25b5bfef4cd7652aa94777d4a46b39f2e206411280a12c9344b769ff1066c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000d02ab486cedc0000000000000000000000000000000000000000000000000000000000082ec8ad1b0000000000000000000000000000000000000000000000000000000066d7b65800000000000000000000000000000000000000000000000000000191ba9f843c125000064000640000d52de09955f0ffffffffffffff00225c389e595fe9000001fcc910754b349f821e4bb5d8444822a63920be943aba6f1b31ee14ef0fc6840b6d28d604e04a78834b668dba24a6c082ffb901e4fffa9600649e8d991af593";
vm.expectRevert();
dispatcherExposed.exposedCallExecutor(
0xe592557AB9F4A75D992283fD6066312FF013ba3d,
IExecutor.swap.selector,
0,
data
0xe592557AB9F4A75D992283fD6066312FF013ba3d, 0, data
);
}
@@ -138,7 +128,7 @@ contract DispatcherTest is Constants {
bytes memory data = hex"aabbccdd1111111111111111";
vm.expectRevert();
dispatcherExposed.exposedCallExecutor(
0x5d622C9053b8FFB1B3465495C8a42E603632bA70, bytes4(0), 0, data
0x5d622C9053b8FFB1B3465495C8a42E603632bA70, 0, data
);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
@@ -702,7 +656,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
// `5c2f5a71f67c01775180adc06909288b4c329308` with the one in this test
// `5615deb798bb3e4dfa0139dfa1b3d433cc23b72f`
(bool success,) = tychoRouterAddr.call(
hex"d499aa880000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000067d481bb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067acfbc3000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041f2740fde9662d8bc1f8fe8e8fc29447c1832d625f06f4a56ee5103ad555c12323af5d50eb840f73d17873383ae3b7573956d5df7b2bf76bddba768c2837894a51b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c005a00010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fbd0625abc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000000000"
hex"d499aa880000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000067e4225a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067bc9c620000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000411fdbe0ac6bdafd51044f24b158235effa29797f468cd4684efa379053d3d15d47ed8b8206e3f6e7349f40aad231cc7e04ed25cbea1ac659b575be8cc168fc2361c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058005600010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000"
);
vm.stopPrank();
@@ -725,7 +679,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
// `5c2f5a71f67c01775180adc06909288b4c329308` with the one in this test
// `5615deb798bb3e4dfa0139dfa1b3d433cc23b72f`
(bool success,) = tychoRouterAddr.call(
hex"0a83cb080000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000008f1d5c1cae37400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000005c005a00010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fbd0625abc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000000000"
hex"0a83cb080000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000008f1d5c1cae37400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000058005600010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000"
);
vm.stopPrank();
@@ -734,7 +688,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
assertEq(balancerAfter - balancerBefore, 2659881924818443699787);
}
function testUSV4Integration() public {
function testUSV4Integration4() public {
// Test created with calldata from our router encoder.
// Performs a sequential swap from USDC to PEPE though ETH using two
@@ -752,7 +706,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
// and ensuring that the encoded executor address is the one in this test
// `f62849f9a0b5bf2913b396098f7c7019b51a820a`
(bool success,) = tychoRouterAddr.call(
hex"d499aa88000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000067ddee9e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067b668a6000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041bdf91011918dcb5f59ab3588212a035c770a2839fe2c19060491370fa89685b8469def9e83c7b9cf8f0ef5088a3179556a6ba1096cefbe83c09a1182981c93e41c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009400920001000000f62849f9a0b5bf2913b396098f7c7019b51a820abd0625aba0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d231193300f62849f9a0b5bf2913b396098f7c7019b51a820a91dd73460000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f4000000000000000000000000"
hex"d499aa88000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000067e4237600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067bc9d7e00000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004166b5d3bb274c323e08eeba45d308cc9c11216f9aaafad2a22e94b94fec39293e5480f65f6238d7c8f1e8177f39118373e1041b0ab3a674d3041d119bdb6bc39c1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008c008a0001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d231193300f62849f9a0b5bf2913b396098f7c7019b51a820a0000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000"
);
vm.stopPrank();
@@ -777,7 +731,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
// and ensuring that the encoded executor address is the one in this test
// `f62849f9a0b5bf2913b396098f7c7019b51a820a`
(bool success,) = tychoRouterAddr.call{value: 1 ether}(
hex"d499aa880000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000067def8e900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067b772f100000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004192bf6f59a6e114588b4b5fb00f3acae3eb2dd18b673924b9cf27d1414be469b70113e4ceef228e11c91d178fea26673d9edcd013dee23fa3c45abdfcb573c9371c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a00780001000000f62849f9a0b5bf2913b396098f7c7019b51a820abd0625ab00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d231193301f62849f9a0b5bf2913b396098f7c7019b51a820a91dd73466982508145454ce325ddbe47a25d4ec3d23119330061a80001f4000000000000"
hex"d499aa880000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000067e423f900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067bc9e0100000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004191fb870eca5e2339fd38cd274ca75c2fbb42ffe47a04106d53f22a51c983c5e41e8d2c33be7c4d9e5220e87a42af0853c4cfc264f7ed7363a71b3d1ed89941ce1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007200700001000000f62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d231193301f62849f9a0b5bf2913b396098f7c7019b51a820a6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000"
);
vm.stopPrank();
@@ -806,7 +760,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
// and ensuring that the encoded executor address is the one in this test
// `f62849f9a0b5bf2913b396098f7c7019b51a820a`
(bool success,) = tychoRouterAddr.call(
hex"d499aa8800000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e000000000000000000000000000000000000000000000000000000000067df206000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067b79a68000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041d603720f916c45405d4655476fc8f5d5e93e561d1bc1bbd944f865ac2b53638e28fa06fde0c1097d688029c85940a53ba54902b42d17378159ae4affb8b958b01b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a00780001000000f62849f9a0b5bf2913b396098f7c7019b51a820abd0625aba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000f62849f9a0b5bf2913b396098f7c7019b51a820a91dd73460000000000000000000000000000000000000000000bb800003c000000000000"
hex"d499aa8800000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e000000000000000000000000000000000000000000000000000000000067e4245900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067bc9e610000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000415f73f0c9f3edc7ca941874d734f96310db5f1c68d7df17cf00ad0d51915dadf727651a1436920869f7431dda753a8fc9c86ad57b3bbd1c7e86a2416917362a9b1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007200700001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000f62849f9a0b5bf2913b396098f7c7019b51a820a0000000000000000000000000000000000000000000bb800003c0000000000000000000000000000"
);
vm.stopPrank();
@@ -836,7 +790,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
// `5c2f5a71f67c01775180adc06909288b4c329308` with the one in this test
// `5615deb798bb3e4dfa0139dfa1b3d433cc23b72f`
(bool success,) = tychoRouterAddr.call{value: 1 ether}(
hex"d499aa880000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000067d4806b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067acfa73000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041c36406a750c499ac7f79f7666650f0d4f20fc27bb49ab68121c0be6554cb5cab6caf90dc3aab2e21083a8fa46976521a1e9df41ce74be59abf03e0d3691541e91c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c005a00020000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fbd0625abc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000000000"
hex"d499aa880000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000067e424b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067bc9ebb0000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000419db5448f5a0665118d9ea3552572c0d733c3886142d930eda1beb979891fd74612771b3809c4a569b2b2b91fe72bc8214d736eb1fb6cff2f33d1bc9947f1efe91b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058005600020000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000"
);
vm.stopPrank();
@@ -865,7 +819,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
// `5c2f5a71f67c01775180adc06909288b4c329308` with the one in this test
// `5615deb798bb3e4dfa0139dfa1b3d433cc23b72f`
(bool success,) = tychoRouterAddr.call(
hex"d499aa880000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000000000000000000000000000000000000067d4809800000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067acfaa000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004146411c70ec7fee0d5d260803cb220f5365792426c5d94f7a0a4d37abb05205752c5418b1fadd059570a71f0911814e546728e1f21876f2a1c6d38d34bd235fd61c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c005a00010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fbd0625ab6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950100000000"
hex"d499aa880000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000000000000000000000000000000000000067e4250200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067bc9f0a000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041a94c89ae0335fecf539e5b343c84e6e44aff78de119a407512035c8f0d79005d3bdddcb8b6152ab93dc6e338a4af49cdda382273011178a82eaa100e3dbf04a51b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058005600010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d01395010000000000000000"
);
vm.stopPrank();
@@ -896,7 +850,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
// `5c2f5a71f67c01775180adc06909288b4c329308` with the one in this test
// `5615deb798bb3e4dfa0139dfa1b3d433cc23b72f`
(bool success,) = tychoRouterAddr.call(
hex"d499aa880000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000067d4810d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067acfb15000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041ecaab75f0791c9683b001ea2f0e01a0a6aaf03e6e49c83e9c8a8e588a38e3be9230d962926628ffbf6a5370cda559ff0e7876a63ed38eebe33dbef5b5e2e46ef1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000170005a00028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fbd0625abc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139500005a00010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fbd0625abc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d0139500005a02030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fbd0625ab6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d53ede3eca2a72b3aecc820e955b36f38437d0139501005a01030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fbd0625ab2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a4163ede3eca2a72b3aecc820e955b36f38437d013950100000000000000000000000000000000"
hex"d499aa880000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000067e425a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067bc9faa0000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000412cfd5fbb0477fae3b9521a5528afebfe1bffed7b2f5da65d83e8ab6a7e175b1f390705dc7ec3d884b606a3a579b8d735996375fbe6a26987dc236aeaa9736de31b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000160005600028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139500005600010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d0139500005602030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d53ede3eca2a72b3aecc820e955b36f38437d0139501005601030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a4163ede3eca2a72b3aecc820e955b36f38437d0139501"
);
vm.stopPrank();
@@ -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);

View File

@@ -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
);
}

View File

@@ -19,7 +19,6 @@ contract UniswapV4ExecutorExposed is UniswapV4Executor {
address tokenOut,
bool zeroForOne,
address callbackExecutor,
bytes4 callbackSelector,
UniswapV4Pool[] memory pools
)
{
@@ -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);
@@ -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);
@@ -131,8 +118,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
// USDE -> USDT
// Generated by the Tycho swap encoder - test_encode_uniswap_v4_simple_swap
bytes memory protocolData =
hex"4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec701f62849f9a0b5bf2913b396098f7c7019b51a820a91dd7346dac17f958d2ee523a2206206994597c13d831ec7000064000001";
hex"4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec701f62849f9a0b5bf2913b396098f7c7019b51a820adac17f958d2ee523a2206206994597c13d831ec7000064000001";
uint256 amountIn = 100 ether;
deal(USDE_ADDR, address(uniswapV4Exposed), amountIn);
uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager);
@@ -170,12 +156,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);
@@ -192,8 +173,9 @@ contract UniswapV4ExecutorTest is Test, Constants {
function testMultipleSwapIntegration() public {
// USDE -> USDT -> WBTC
// Generated by the Tycho swap encoder - test_encode_uniswap_v4_sequential_swap
bytes memory protocolData =
hex"4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c59901f62849f9a0b5bf2913b396098f7c7019b51a820a91dd7346dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c";
hex"4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c59901f62849f9a0b5bf2913b396098f7c7019b51a820adac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c";
uint256 amountIn = 100 ether;
deal(USDE_ADDR, address(uniswapV4Exposed), amountIn);

View File

@@ -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
);
}
}

View File

@@ -1,8 +1,8 @@
use std::{collections::HashSet, str::FromStr};
use alloy_primitives::{aliases::U24, FixedBytes, U256, U8};
use alloy_primitives::{aliases::U24, U256, U8};
use alloy_sol_types::SolValue;
use tycho_core::{keccak256, Bytes};
use tycho_core::Bytes;
use crate::encoding::{
errors::EncodingError,
@@ -30,7 +30,6 @@ pub trait EVMStrategyEncoder: StrategyEncoder {
token_out: U8,
split: U24,
executor_address: Bytes,
executor_selector: FixedBytes<4>,
protocol_data: Vec<u8>,
) -> Vec<u8> {
let mut encoded = Vec::new();
@@ -38,17 +37,10 @@ pub trait EVMStrategyEncoder: StrategyEncoder {
encoded.push(token_out.to_be_bytes_vec()[0]);
encoded.extend_from_slice(&split.to_be_bytes_vec());
encoded.extend(executor_address.to_vec());
encoded.extend(executor_selector);
encoded.extend(protocol_data);
encoded
}
/// Encodes a selector string into its 4-byte representation.
fn encode_executor_selector(&self, selector: &str) -> FixedBytes<4> {
let hash = keccak256(selector.as_bytes());
FixedBytes::<4>::from([hash[0], hash[1], hash[2], hash[3]])
}
/// Uses prefix-length encoding to efficient encode action data.
///
/// Prefix-length encoding is a data encoding method where the beginning of a data segment
@@ -114,10 +106,7 @@ impl SplitSwapStrategyEncoder {
impl EVMStrategyEncoder for SplitSwapStrategyEncoder {}
impl StrategyEncoder for SplitSwapStrategyEncoder {
fn encode_strategy(
&self,
solution: Solution,
) -> Result<(Vec<u8>, Bytes, Option<String>), EncodingError> {
fn encode_strategy(&self, solution: Solution) -> Result<(Vec<u8>, Bytes), EncodingError> {
self.split_swap_validator
.validate_split_percentages(&solution.swaps)?;
self.split_swap_validator
@@ -209,7 +198,6 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
Bytes::from_str(swap_encoder.executor_address()).map_err(|_| {
EncodingError::FatalError("Invalid executor address".to_string())
})?,
self.encode_executor_selector(swap_encoder.swap_selector()),
grouped_protocol_data,
);
swaps.push(swap_data);
@@ -253,7 +241,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
};
let contract_interaction = encode_input(&self.selector, method_calldata);
Ok((contract_interaction, solution.router_address, None))
Ok((contract_interaction, solution.router_address))
}
fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box<dyn SwapEncoder>> {
@@ -283,10 +271,7 @@ impl ExecutorStrategyEncoder {
}
impl EVMStrategyEncoder for ExecutorStrategyEncoder {}
impl StrategyEncoder for ExecutorStrategyEncoder {
fn encode_strategy(
&self,
solution: Solution,
) -> Result<(Vec<u8>, Bytes, Option<String>), EncodingError> {
fn encode_strategy(&self, solution: Solution) -> Result<(Vec<u8>, Bytes), EncodingError> {
let grouped_swaps = group_swaps(solution.clone().swaps);
let number_of_groups = grouped_swaps.len();
if number_of_groups > 1 {
@@ -328,11 +313,7 @@ impl StrategyEncoder for ExecutorStrategyEncoder {
let executor_address = Bytes::from_str(swap_encoder.executor_address())
.map_err(|_| EncodingError::FatalError("Invalid executor address".to_string()))?;
Ok((
grouped_protocol_data,
executor_address,
Some(swap_encoder.swap_selector().to_string()),
))
Ok((grouped_protocol_data, executor_address))
}
fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box<dyn SwapEncoder>> {
@@ -413,7 +394,7 @@ mod tests {
native_action: None,
};
let (protocol_data, executor_address, selector) = encoder
let (protocol_data, executor_address) = encoder
.encode_strategy(solution)
.unwrap();
let hex_protocol_data = encode(&protocol_data);
@@ -434,7 +415,6 @@ mod tests {
"00",
))
);
assert_eq!(selector, Some("swap(uint256,bytes)".to_string()));
}
#[test]
@@ -539,7 +519,7 @@ mod tests {
..Default::default()
};
let (protocol_data, executor_address, selector) = encoder
let (protocol_data, executor_address) = encoder
.encode_strategy(solution)
.unwrap();
let hex_protocol_data = encode(&protocol_data);
@@ -558,8 +538,6 @@ mod tests {
"00",
// executor address
"f62849f9a0b5bf2913b396098f7c7019b51a820a",
// callback selector
"91dd7346",
// first pool intermediary token (ETH)
"0000000000000000000000000000000000000000",
// fee
@@ -574,7 +552,6 @@ mod tests {
"0001f4"
))
);
assert_eq!(selector, Some("swap(uint256,bytes)".to_string()));
}
#[rstest]
@@ -646,7 +623,7 @@ mod tests {
..Default::default()
};
let (calldata, _, _) = encoder
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();
let expected_min_amount_encoded = hex::encode(U256::abi_encode(&expected_min_amount));
@@ -684,22 +661,21 @@ mod tests {
let expected_swaps = String::from(concat!(
// length of ple encoded swaps without padding
"000000000000000000000000000000000000000000000000000000000000005c",
"0000000000000000000000000000000000000000000000000000000000000058",
// ple encoded swaps
"005a",
"0056",
// Swap header
"00", // token in index
"01", // token out index
"000000", // split
// Swap data
"5c2f5a71f67c01775180adc06909288b4c329308", // executor address
"bd0625ab", // selector
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"00", // zero2one
"00", // exact out
"000000", // padding
"00000000000000", // padding
));
let hex_calldata = encode(&calldata);
@@ -748,7 +724,7 @@ mod tests {
..Default::default()
};
let (calldata, _, _) = encoder
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();
@@ -797,7 +773,7 @@ mod tests {
..Default::default()
};
let (calldata, _, _) = encoder
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();
@@ -886,7 +862,7 @@ mod tests {
..Default::default()
};
let (calldata, _, _) = encoder
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();
@@ -968,7 +944,7 @@ mod tests {
..Default::default()
};
let (calldata, _, _) = encoder
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();
@@ -1007,21 +983,19 @@ mod tests {
let expected_swaps = String::from(concat!(
// length of ple encoded swaps without padding
"0000000000000000000000000000000000000000000000000000000000000094",
"000000000000000000000000000000000000000000000000000000000000008c",
// ple encoded swaps
"0092", // Swap length
"008a", // Swap length
"00", // token in index
"01", // token out index
"000000", // split
// Swap data header
"f62849f9a0b5bf2913b396098f7c7019b51a820a", // executor address
"bd0625ab", // selector
// Protocol data
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // group token in
"6982508145454ce325ddbe47a25d4ec3d2311933", // group token in
"00", // zero2one
"f62849f9a0b5bf2913b396098f7c7019b51a820a", // executor address
"91dd7346", // callback selector
// First pool params
"0000000000000000000000000000000000000000", // intermediary token (ETH)
"000bb8", // fee
@@ -1030,8 +1004,9 @@ mod tests {
"6982508145454ce325ddbe47a25d4ec3d2311933", // intermediary token (PEPE)
"0061a8", // fee
"0001f4", // tick spacing
"000000000000000000000000" // padding
"0000000000000000000000000000000000000000" // padding
));
let hex_calldata = encode(&calldata);
assert_eq!(hex_calldata[..520], expected_input);
@@ -1079,7 +1054,7 @@ mod tests {
..Default::default()
};
let (calldata, _, _) = encoder
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();
let expected_min_amount_encoded = hex::encode(U256::abi_encode(&expected_min_amount));
@@ -1094,21 +1069,20 @@ mod tests {
"0000000000000000000000000000000000000000000000000000000000000002", // tokens length
"000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"0000000000000000000000000000000000000000000000000000000000000120", // offset of ple encoded swaps
"000000000000000000000000000000000000000000000000000000000000005c", // length of ple encoded swaps without padding
"005a", // ple encoded swaps
"0000000000000000000000000000000000000000000000000000000000000058", // length of ple encoded swaps without padding
"0056", // ple encoded swaps
// Swap header
"00", // token in index
"01", // token out index
"000000", // split
// Swap data
"5c2f5a71f67c01775180adc06909288b4c329308", // executor address
"bd0625ab", // selector
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"00", // zero2one
"00", // exact out
"000000", // padding
"00000000000000", // padding
]
.join("");
@@ -1171,7 +1145,7 @@ mod tests {
..Default::default()
};
let (calldata, _, _) = encoder
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();
let hex_calldata = encode(&calldata);
@@ -1235,7 +1209,7 @@ mod tests {
..Default::default()
};
let (calldata, _, _) = encoder
let (calldata, _) = encoder
.encode_strategy(solution)
.unwrap();

View File

@@ -8,9 +8,7 @@ use crate::encoding::{
errors::EncodingError,
evm::{
approvals::protocol_approvals_manager::ProtocolApprovalsManager,
utils::{
bytes_to_address, encode_function_selector, get_static_attribute, pad_to_fixed_size,
},
utils::{bytes_to_address, get_static_attribute, pad_to_fixed_size},
},
models::{EncodingContext, Swap},
swap_encoder::SwapEncoder,
@@ -24,7 +22,6 @@ use crate::encoding::{
#[derive(Clone)]
pub struct UniswapV2SwapEncoder {
executor_address: String,
swap_selector: String,
}
impl UniswapV2SwapEncoder {
@@ -35,7 +32,7 @@ impl UniswapV2SwapEncoder {
impl SwapEncoder for UniswapV2SwapEncoder {
fn new(executor_address: String) -> Self {
Self { executor_address, swap_selector: "swap(uint256,bytes)".to_string() }
Self { executor_address }
}
fn encode_swap(
@@ -66,10 +63,6 @@ impl SwapEncoder for UniswapV2SwapEncoder {
&self.executor_address
}
fn swap_selector(&self) -> &str {
&self.swap_selector
}
fn clone_box(&self) -> Box<dyn SwapEncoder> {
Box::new(self.clone())
}
@@ -83,7 +76,6 @@ impl SwapEncoder for UniswapV2SwapEncoder {
#[derive(Clone)]
pub struct UniswapV3SwapEncoder {
executor_address: String,
swap_selector: String,
}
impl UniswapV3SwapEncoder {
@@ -94,7 +86,7 @@ impl UniswapV3SwapEncoder {
impl SwapEncoder for UniswapV3SwapEncoder {
fn new(executor_address: String) -> Self {
Self { executor_address, swap_selector: "swap(uint256,bytes)".to_string() }
Self { executor_address }
}
fn encode_swap(
@@ -128,9 +120,6 @@ impl SwapEncoder for UniswapV3SwapEncoder {
fn executor_address(&self) -> &str {
&self.executor_address
}
fn swap_selector(&self) -> &str {
&self.swap_selector
}
fn clone_box(&self) -> Box<dyn SwapEncoder> {
Box::new(self.clone())
}
@@ -145,8 +134,6 @@ impl SwapEncoder for UniswapV3SwapEncoder {
#[derive(Clone)]
pub struct UniswapV4SwapEncoder {
executor_address: String,
swap_selector: String,
callback_selector: String,
}
impl UniswapV4SwapEncoder {
@@ -157,11 +144,7 @@ impl UniswapV4SwapEncoder {
impl SwapEncoder for UniswapV4SwapEncoder {
fn new(executor_address: String) -> Self {
Self {
executor_address,
swap_selector: "swap(uint256,bytes)".to_string(),
callback_selector: "unlockCallback(bytes)".to_string(),
}
Self { executor_address }
}
fn encode_swap(
@@ -206,7 +189,6 @@ impl SwapEncoder for UniswapV4SwapEncoder {
group_token_out_address,
zero_to_one,
callback_executor,
encode_function_selector(&self.callback_selector),
pool_params,
);
@@ -217,10 +199,6 @@ impl SwapEncoder for UniswapV4SwapEncoder {
&self.executor_address
}
fn swap_selector(&self) -> &str {
&self.swap_selector
}
fn clone_box(&self) -> Box<dyn SwapEncoder> {
Box::new(self.clone())
}
@@ -230,11 +208,10 @@ impl SwapEncoder for UniswapV4SwapEncoder {
///
/// # Fields
/// * `executor_address` - The address of the executor contract that will perform the swap.
/// * `swap_selector` - The selector of the swap function in the executor contract.
/// * `vault_address` - The address of the vault contract that will perform the swap.
#[derive(Clone)]
pub struct BalancerV2SwapEncoder {
executor_address: String,
swap_selector: String,
vault_address: String,
}
@@ -242,7 +219,6 @@ impl SwapEncoder for BalancerV2SwapEncoder {
fn new(executor_address: String) -> Self {
Self {
executor_address,
swap_selector: "swap(uint256,bytes)".to_string(),
vault_address: "0xba12222222228d8ba445958a75a0704d566bf2c8".to_string(),
}
}
@@ -277,9 +253,6 @@ impl SwapEncoder for BalancerV2SwapEncoder {
fn executor_address(&self) -> &str {
&self.executor_address
}
fn swap_selector(&self) -> &str {
&self.swap_selector
}
fn clone_box(&self) -> Box<dyn SwapEncoder> {
Box::new(self.clone())
}
@@ -418,7 +391,6 @@ mod tests {
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
println!("{}", hex_swap);
assert_eq!(
hex_swap,
@@ -478,6 +450,7 @@ mod tests {
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
println!("{}", hex_swap);
assert_eq!(
hex_swap,
@@ -490,8 +463,6 @@ mod tests {
"01",
// executor address
"f62849f9a0b5bf2913b396098f7c7019b51a820a",
// callback selector for "unlockCallback(bytes)"
"91dd7346",
// pool params:
// - intermediary token
"dac17f958d2ee523a2206206994597c13d831ec7",
@@ -649,8 +620,6 @@ mod tests {
"01",
// executor address
"f62849f9a0b5bf2913b396098f7c7019b51a820a",
// callback selector for "unlockCallback(bytes)"
"91dd7346",
// pool params:
// - intermediary token USDT
"dac17f958d2ee523a2206206994597c13d831ec7",

View File

@@ -105,7 +105,7 @@ impl TychoEncoder for EVMTychoEncoder {
for solution in solutions.iter() {
self.validate_solution(solution)?;
let (contract_interaction, target_address, selector) = self
let (contract_interaction, target_address) = self
.strategy_encoder
.encode_strategy(solution.clone())?;
@@ -118,7 +118,6 @@ impl TychoEncoder for EVMTychoEncoder {
value,
data: contract_interaction,
to: target_address,
selector,
});
}
Ok(transactions)
@@ -152,16 +151,12 @@ mod tests {
struct MockStrategy;
impl StrategyEncoder for MockStrategy {
fn encode_strategy(
&self,
_solution: Solution,
) -> Result<(Vec<u8>, Bytes, Option<String>), EncodingError> {
fn encode_strategy(&self, _solution: Solution) -> Result<(Vec<u8>, Bytes), EncodingError> {
Ok((
Bytes::from_str("0x1234")
.unwrap()
.to_vec(),
Bytes::from_str("0xabcd").unwrap(),
None,
))
}

View File

@@ -96,7 +96,6 @@ pub struct Transaction {
pub to: Bytes,
pub value: BigUint,
pub data: Vec<u8>,
pub selector: Option<String>,
}
/// Represents necessary attributes for encoding an order.

View File

@@ -17,10 +17,7 @@ pub trait StrategyEncoder {
/// - The encoded data as bytes
/// - The address of the contract to call (router or executor)
/// - Optionally, the function selector to use when calling the contract
fn encode_strategy(
&self,
solution: Solution,
) -> Result<(Vec<u8>, Bytes, Option<String>), EncodingError>;
fn encode_strategy(&self, solution: Solution) -> Result<(Vec<u8>, Bytes), EncodingError>;
/// Retrieves the swap encoder for a specific protocol system.
///

View File

@@ -32,9 +32,6 @@ pub trait SwapEncoder: Sync + Send {
/// Returns the address of the protocol-specific executor contract.
fn executor_address(&self) -> &str;
/// Returns the function selector used to execute the swap on the protocol.
fn swap_selector(&self) -> &str;
/// Creates a cloned instance of the swap encoder.
///
/// This allows the encoder to be cloned when it is being used as a `Box<dyn SwapEncoder>`.