diff --git a/foundry/src/ExecutionDispatcher.sol b/foundry/src/ExecutionDispatcher.sol index 973f6f0..eae85dc 100644 --- a/foundry/src/ExecutionDispatcher.sol +++ b/foundry/src/ExecutionDispatcher.sol @@ -2,7 +2,6 @@ pragma solidity ^0.8.26; import "@interfaces/IExecutor.sol"; -import "forge-std/console.sol"; error ExecutionDispatcher__UnapprovedExecutor(); error ExecutionDispatcher__NonContractExecutor(); diff --git a/foundry/src/executors/UniswapV4Executor.sol b/foundry/src/executors/UniswapV4Executor.sol index c365a89..2a2e40b 100644 --- a/foundry/src/executors/UniswapV4Executor.sol +++ b/foundry/src/executors/UniswapV4Executor.sol @@ -17,9 +17,6 @@ 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"; -error UniswapV4Executor__InvalidDataLength(); -error UniswapV4Executor__SwapFailed(); - contract UniswapV4Executor is IExecutor, V4Router { using SafeERC20 for IERC20; using CurrencyLibrary for Currency; diff --git a/foundry/test/TychoRouter.t.sol b/foundry/test/TychoRouter.t.sol index 095af50..bfbca0b 100644 --- a/foundry/test/TychoRouter.t.sol +++ b/foundry/test/TychoRouter.t.sol @@ -626,24 +626,6 @@ contract TychoRouterTest is TychoRouterTestSetup { vm.stopPrank(); } - // function testUSV3Callback() public { - // uint24 poolFee = 3000; - // uint256 amountOwed = 1000000000000000000; - // deal(WETH_ADDR, tychoRouterAddr, amountOwed); - // uint256 initialPoolReserve = IERC20(WETH_ADDR).balanceOf(DAI_WETH_USV3); - - // vm.startPrank(DAI_WETH_USV3); - // tychoRouter.uniswapV3SwapCallback( - // -2631245338449998525223, - // int256(amountOwed), - // abi.encodePacked(WETH_ADDR, DAI_ADDR, poolFee) - // ); - // vm.stopPrank(); - - // uint256 finalPoolReserve = IERC20(WETH_ADDR).balanceOf(DAI_WETH_USV3); - // assertEq(finalPoolReserve - initialPoolReserve, amountOwed); - // } - function testSwapSingleUSV3() public { // Trade 1 WETH for DAI with 1 swap on Uniswap V3 // 1 WETH -> DAI diff --git a/foundry/test/executors/UniswapV3Executor.t.sol b/foundry/test/executors/UniswapV3Executor.t.sol index 2116cb1..e0d1638 100644 --- a/foundry/test/executors/UniswapV3Executor.t.sol +++ b/foundry/test/executors/UniswapV3Executor.t.sol @@ -69,4 +69,48 @@ contract UniswapV3ExecutorTest is Test, Constants { vm.expectRevert(UniswapV3Executor__InvalidDataLength.selector); uniswapV3Exposed.decodeData(invalidParams); } + + function testUSV3Callback() public { + uint24 poolFee = 3000; + uint256 amountOwed = 1000000000000000000; + deal(WETH_ADDR, address(uniswapV3Exposed), amountOwed); + uint256 initialPoolReserve = IERC20(WETH_ADDR).balanceOf(DAI_WETH_USV3); + + vm.startPrank(DAI_WETH_USV3); + bytes memory callbackData = _encodeUSV3CallbackData( + int256(amountOwed), // amount0Delta + int256(0), // amount1Delta + WETH_ADDR, + DAI_ADDR, + poolFee + ); + uniswapV3Exposed.handleCallback(callbackData); + vm.stopPrank(); + + uint256 finalPoolReserve = IERC20(WETH_ADDR).balanceOf(DAI_WETH_USV3); + assertEq(finalPoolReserve - initialPoolReserve, amountOwed); + } + + function _encodeUSV3CallbackData( + int256 amount0Delta, + int256 amount1Delta, + address tokenIn, + address tokenOut, + uint24 fee + ) internal pure returns (bytes memory) { + // Dummy selector for handleCallback + bytes4 selector = + bytes4(keccak256("handleCallback(int256,int256,bytes)")); + + bytes memory tokenData = abi.encodePacked(tokenIn, tokenOut, fee); + + // [0:4] - function selector + // [4:68] - abi.encode(amount0Delta, amount1Delta) + // [68:end] - abi.encode(tokenData) where tokenData is the packed bytes + return abi.encodePacked( + selector, + abi.encode(amount0Delta, amount1Delta), + abi.encode(tokenData) + ); + } }