diff --git a/foundry/src/executors/TokenTransfer.sol b/foundry/src/executors/TokenTransfer.sol index 0e69f13..f529b69 100644 --- a/foundry/src/executors/TokenTransfer.sol +++ b/foundry/src/executors/TokenTransfer.sol @@ -5,7 +5,7 @@ import "@interfaces/IExecutor.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@permit2/src/interfaces/IAllowanceTransfer.sol"; -error TokenTransfer__InvalidPermit2(); +error TokenTransfer__AddressZero(); contract TokenTransfer { using SafeERC20 for IERC20; @@ -25,7 +25,7 @@ contract TokenTransfer { constructor(address _permit2) { if (_permit2 == address(0)) { - revert TokenTransfer__InvalidPermit2(); + revert TokenTransfer__AddressZero(); } permit2 = IAllowanceTransfer(_permit2); } diff --git a/foundry/src/executors/UniswapV3Executor.sol b/foundry/src/executors/UniswapV3Executor.sol index 20df282..dbc794e 100644 --- a/foundry/src/executors/UniswapV3Executor.sol +++ b/foundry/src/executors/UniswapV3Executor.sol @@ -11,6 +11,7 @@ error UniswapV3Executor__InvalidDataLength(); error UniswapV3Executor__InvalidFactory(); error UniswapV3Executor__InvalidTarget(); error UniswapV3Executor__InvalidInitCode(); +error UniswapV3Executor__InvalidTransferType(uint8 transferType); contract UniswapV3Executor is IExecutor, ICallback, TokenTransfer { using SafeERC20 for IERC20; @@ -97,12 +98,13 @@ contract UniswapV3Executor is IExecutor, ICallback, TokenTransfer { address tokenIn = address(bytes20(msgData[132:152])); - require( - uint8(msgData[171]) <= uint8(TransferType.NONE), - "InvalidTransferMethod" - ); - TransferType transferType = TransferType(uint8(msgData[171])); - address sender = address(bytes20(msgData[172:192])); + // Transfer type does not exist + if (uint8(msgData[175]) > uint8(TransferType.NONE)) { + revert UniswapV3Executor__InvalidTransferType(uint8(msgData[175])); + } + + TransferType transferType = TransferType(uint8(msgData[175])); + address sender = address(bytes20(msgData[176:196])); verifyCallback(msgData[132:]); @@ -168,7 +170,7 @@ contract UniswapV3Executor is IExecutor, ICallback, TokenTransfer { TransferType transferType ) internal view returns (bytes memory) { return abi.encodePacked( - tokenIn, tokenOut, fee, uint8(transferType), msg.sender, self + tokenIn, tokenOut, fee, uint8(transferType), msg.sender ); } diff --git a/foundry/test/executors/UniswapV3Executor.t.sol b/foundry/test/executors/UniswapV3Executor.t.sol index a81a6e5..24bfd22 100644 --- a/foundry/test/executors/UniswapV3Executor.t.sol +++ b/foundry/test/executors/UniswapV3Executor.t.sol @@ -22,7 +22,7 @@ contract UniswapV3ExecutorExposed is UniswapV3Executor { address receiver, address target, bool zeroForOne, - TransferType method + TransferType transferType ) { return _decodeData(data); @@ -81,7 +81,7 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper { address receiver, address target, bool zeroForOne, - TokenTransfer.TransferType method + TokenTransfer.TransferType transferType ) = uniswapV3Exposed.decodeData(data); assertEq(tokenIn, WETH_ADDR); @@ -90,7 +90,9 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper { assertEq(receiver, address(2)); assertEq(target, address(3)); assertEq(zeroForOne, false); - assertEq(uint8(method), uint8(TokenTransfer.TransferType.TRANSFER)); + assertEq( + uint8(transferType), uint8(TokenTransfer.TransferType.TRANSFER) + ); } function testDecodeParamsInvalidDataLength() public { @@ -142,88 +144,6 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper { assertEq(finalPoolReserve - initialPoolReserve, amountOwed); } - function testSwapWithTransfer() public { - uint256 amountIn = 10 ** 18; - deal(WETH_ADDR, address(uniswapV3Exposed), amountIn); - - uint256 expAmountOut = 1205_128428842122129186; //Swap 1 WETH for 1205.12 DAI - bool zeroForOne = false; - - bytes memory data = encodeUniswapV3Swap( - WETH_ADDR, - DAI_ADDR, - address(this), - DAI_WETH_USV3, - zeroForOne, - TokenTransfer.TransferType.TRANSFER - ); - - uint256 amountOut = uniswapV3Exposed.swap(amountIn, data); - - assertGe(amountOut, expAmountOut); - assertEq(IERC20(WETH_ADDR).balanceOf(address(uniswapV3Exposed)), 0); - assertGe(IERC20(DAI_ADDR).balanceOf(address(this)), expAmountOut); - } - - function testSwapWithTransferFrom() public { - uint256 amountIn = 10 ** 18; - deal(WETH_ADDR, address(this), amountIn); - IERC20(WETH_ADDR).approve(address(uniswapV3Exposed), amountIn); - - uint256 expAmountOut = 1205_128428842122129186; //Swap 1 WETH for 1205.12 DAI - bool zeroForOne = false; - - bytes memory data = encodeUniswapV3Swap( - WETH_ADDR, - DAI_ADDR, - address(this), - DAI_WETH_USV3, - zeroForOne, - TokenTransfer.TransferType.TRANSFERFROM - ); - - uint256 amountOut = uniswapV3Exposed.swap(amountIn, data); - - assertGe(amountOut, expAmountOut); - assertEq(IERC20(WETH_ADDR).balanceOf(address(uniswapV3Exposed)), 0); - assertGe(IERC20(DAI_ADDR).balanceOf(address(this)), expAmountOut); - } - - function testSwapWithPermit2TransferFrom() public { - uint256 amountIn = 10 ** 18; - - uint256 expAmountOut = 1205_128428842122129186; //Swap 1 WETH for 1205.12 DAI - bool zeroForOne = false; - - bytes memory data = encodeUniswapV3Swap( - WETH_ADDR, - DAI_ADDR, - address(this), - DAI_WETH_USV3, - zeroForOne, - TokenTransfer.TransferType.TRANSFERPERMIT2 - ); - - deal(WETH_ADDR, ALICE, amountIn); - vm.startPrank(ALICE); - ( - IAllowanceTransfer.PermitSingle memory permitSingle, - bytes memory signature - ) = handlePermit2Approval( - WETH_ADDR, address(uniswapV3Exposed), amountIn - ); - - // Assume the permit2.approve method will be called from the TychoRouter - // Replicate this scenario in this test. - permit2.permit(ALICE, permitSingle, signature); - uint256 amountOut = uniswapV3Exposed.swap(amountIn, data); - vm.stopPrank(); - - assertGe(amountOut, expAmountOut); - assertEq(IERC20(WETH_ADDR).balanceOf(address(uniswapV3Exposed)), 0); - assertGe(IERC20(DAI_ADDR).balanceOf(address(this)), expAmountOut); - } - function testSwapFailureInvalidTarget() public { uint256 amountIn = 10 ** 18; deal(WETH_ADDR, address(uniswapV3Exposed), amountIn); diff --git a/src/encoding/evm/strategy_encoder/strategy_encoders.rs b/src/encoding/evm/strategy_encoder/strategy_encoders.rs index cbb82be..3151034 100644 --- a/src/encoding/evm/strategy_encoder/strategy_encoders.rs +++ b/src/encoding/evm/strategy_encoder/strategy_encoders.rs @@ -722,7 +722,7 @@ mod tests { "a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id "3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver "00", // zero2one - "00", // transfer method + "00", // transfer type "00000000000000", // padding )); let hex_calldata = encode(&calldata); @@ -826,7 +826,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver "00", // zero2one "00", // exact out - "00", // transfer method + "00", // transfer type "00000000000000000000000000", // padding )); let hex_calldata = encode(&calldata); @@ -1485,7 +1485,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver "00", // zero2one "00", // exact out - "00", // transfer method + "00", // transfer type "00000000000000000000000000", // padding ] .join(""); @@ -1569,7 +1569,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver "00", // zero2one "00", // exact out - "00", // transfer method + "00", // transfer type "000000000000", // padding ] .join(""); @@ -1821,7 +1821,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // router address "88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id "01", // zero2one - "00", // transfer method + "00", // transfer type "006e", // ple encoded swaps "01", // token in index "00000000", // split @@ -1832,7 +1832,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // router address "8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id "00", // zero2one - "00", // transfer method + "00", // transfer type ] .join(""); @@ -1975,7 +1975,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // router address "88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id "01", // zero2one - "00", // transfer method + "00", // transfer type "006e", // ple encoded swaps "00", // token in index "01", // token out index @@ -1987,7 +1987,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // router address "8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id "01", // zero2one - "00", // transfer method + "00", // transfer type "0057", // ple encoded swaps "01", // token in index "00", // token out index @@ -1997,7 +1997,7 @@ mod tests { "b4e16d0168e52d35cacd2c6185b44281ec28c9dc", // component id, "3ede3eca2a72b3aecc820e955b36f38437d01395", // router address "00", // zero2one - "00", // transfer method + "00", // transfer type "00000000000000" // padding ] .join(""); @@ -2135,7 +2135,7 @@ mod tests { "b4e16d0168e52d35cacd2c6185b44281ec28c9dc", // component id "3ede3eca2a72b3aecc820e955b36f38437d01395", // router address "01", // zero2one - "00", // transfer method + "00", // transfer type "006e", // ple encoded swaps "01", // token in index "00", // token out index @@ -2147,7 +2147,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // router address "88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id "00", // zero2one - "00", // transfer method + "00", // transfer type "006e", // ple encoded swaps "01", // token in index "00", // token out index @@ -2159,7 +2159,7 @@ mod tests { "3ede3eca2a72b3aecc820e955b36f38437d01395", // router address "8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id "00", // zero2one - "00", // transfer method + "00", // transfer type "00000000000000" // padding ] .join(""); diff --git a/src/encoding/evm/tycho_encoders.rs b/src/encoding/evm/tycho_encoders.rs index 3a0c96f..92706fc 100644 --- a/src/encoding/evm/tycho_encoders.rs +++ b/src/encoding/evm/tycho_encoders.rs @@ -916,7 +916,7 @@ mod tests { "1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e", // zero for one "00", - // transfer method + // transfer type "00", )) );