diff --git a/foundry/src/CallbackVerificationDispatcher.sol b/foundry/src/CallbackVerificationDispatcher.sol index 0e2a058..48d76d9 100644 --- a/foundry/src/CallbackVerificationDispatcher.sol +++ b/foundry/src/CallbackVerificationDispatcher.sol @@ -49,6 +49,7 @@ contract CallbackVerificationDispatcher { // slither-disable-next-line dead-code function _callVerifyCallback(bytes calldata data) internal + view returns ( uint256 amountOwed, uint256 amountReceived, diff --git a/foundry/src/TychoRouter.sol b/foundry/src/TychoRouter.sol index 2d43030..1308868 100644 --- a/foundry/src/TychoRouter.sol +++ b/foundry/src/TychoRouter.sol @@ -130,13 +130,13 @@ contract TychoRouter is if (wrapEth) { _wrapETH(amountIn); } else if (tokenIn != address(0)) { - permit2.permit(msg.sender, permitSingle, signature); - permit2.transferFrom( - msg.sender, - address(this), - uint160(amountIn), - permitSingle.details.token - ); + permit2.permit(msg.sender, permitSingle, signature); + permit2.transferFrom( + msg.sender, + address(this), + uint160(amountIn), + permitSingle.details.token + ); } amountOut = _splitSwap(amountIn, nTokens, swaps); diff --git a/foundry/test/CallbackVerificationDispatcher.t.sol b/foundry/test/CallbackVerificationDispatcher.t.sol index 8480a96..e672642 100644 --- a/foundry/test/CallbackVerificationDispatcher.t.sol +++ b/foundry/test/CallbackVerificationDispatcher.t.sol @@ -9,6 +9,7 @@ contract CallbackVerificationDispatcherExposed is { function exposedCallVerifier(bytes calldata data) external + view returns ( uint256 amountOwed, uint256 amountReceived, @@ -176,7 +177,7 @@ contract CallbackVerificationDispatcherTest is Constants { dispatcherExposed.exposedCallVerifier(data); } - function testDecodeVerifierAndSelector() public { + function testDecodeVerifierAndSelector() public view { bytes memory data = hex"2C960bD1CFE09A26105ad3C351bEa0a3fAD0F8e876b20f8aA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; (address executor, bytes4 selector, bytes memory verifierData) = diff --git a/foundry/test/ExecutionDispatcher.t.sol b/foundry/test/ExecutionDispatcher.t.sol index 4895d03..2e49482 100644 --- a/foundry/test/ExecutionDispatcher.t.sol +++ b/foundry/test/ExecutionDispatcher.t.sol @@ -136,7 +136,7 @@ contract ExecutionDispatcherTest is Constants { dispatcherExposed.exposedCallExecutor(0, data); } - function testDecodeExecutorAndSelector() public { + function testDecodeExecutorAndSelector() public view { bytes memory data = hex"6611e616d2db3244244a54c754a16dd3ac7ca7a2aabbccdd1111111111111111"; (address executor, bytes4 selector, bytes memory protocolData) = diff --git a/foundry/test/LibPrefixLengthEncodedByteArray.t.sol b/foundry/test/LibPrefixLengthEncodedByteArray.t.sol index c06eb47..d56b298 100644 --- a/foundry/test/LibPrefixLengthEncodedByteArray.t.sol +++ b/foundry/test/LibPrefixLengthEncodedByteArray.t.sol @@ -8,14 +8,14 @@ import {LibPrefixLengthEncodedByteArray} from contract LibPrefixLengthEncodedByteArrayTest is Test { using LibPrefixLengthEncodedByteArray for bytes; - function testNextEmpty() public { + function testNextEmpty() public view { bytes memory encoded = ""; (bytes memory elem, bytes memory remaining) = this.next(encoded); assertEq(elem.length, 0); assertEq(remaining.length, 0); } - function testNextSingleElement() public { + function testNextSingleElement() public view { // Create encoded data: length prefix (0003) followed by "ABC" bytes memory encoded = hex"0003414243"; (bytes memory elem, bytes memory remaining) = this.next(encoded); @@ -25,7 +25,7 @@ contract LibPrefixLengthEncodedByteArrayTest is Test { assertEq(remaining.length, 0); } - function testNextMultipleElements() public { + function testNextMultipleElements() public view { // Encoded data: [0003]ABC[0002]DE bytes memory encoded = hex"000341424300024445"; @@ -40,7 +40,7 @@ contract LibPrefixLengthEncodedByteArrayTest is Test { assertEq(remaining2.length, 0); } - function testSize() public { + function testSize() public view { bytes memory empty = ""; assertEq(this.size(empty), 0); @@ -51,19 +51,19 @@ contract LibPrefixLengthEncodedByteArrayTest is Test { assertEq(this.size(multiple), 3); } - function testFailInvalidLength() public { + function testFailInvalidLength() public view { // Length prefix larger than remaining data bytes memory invalid = hex"0004414243"; - (bytes memory elem, bytes memory remaining) = this.next(invalid); + this.next(invalid); } - function testFailIncompletePrefix() public { + function testFailIncompletePrefix() public view { // Only 1 byte instead of 2 bytes prefix bytes memory invalid = hex"01"; - (bytes memory elem, bytes memory remaining) = this.next(invalid); + this.next(invalid); } - function testLargeElement() public { + function testLargeElement() public view { // Test with a large but manageable size (1000 bytes) bytes memory large = new bytes(1002); // 2 bytes prefix + 1000 bytes data large[0] = bytes1(uint8(0x03)); // 03 @@ -79,7 +79,7 @@ contract LibPrefixLengthEncodedByteArrayTest is Test { assertEq(remaining.length, 0); } - function testSizeWithLargeElements() public { + function testSizeWithLargeElements() public view { // Two elements: 1000 bytes + 500 bytes bytes memory data = new bytes(1504); // 1000 + 2 + 500 + 2 diff --git a/foundry/test/TychoRouter.t.sol b/foundry/test/TychoRouter.t.sol index 7df01bf..9f3b1b9 100644 --- a/foundry/test/TychoRouter.t.sol +++ b/foundry/test/TychoRouter.t.sol @@ -20,14 +20,14 @@ contract TychoRouterTest is TychoRouterTestSetup { ); function testSetExecutorValidRole() public { - vm.startPrank(executorSetter); + vm.startPrank(EXECUTOR_SETTER); tychoRouter.setExecutor(DUMMY); vm.stopPrank(); assert(tychoRouter.executors(DUMMY) == true); } function testRemoveExecutorValidRole() public { - vm.startPrank(executorSetter); + vm.startPrank(EXECUTOR_SETTER); tychoRouter.setExecutor(DUMMY); tychoRouter.removeExecutor(DUMMY); vm.stopPrank(); @@ -45,14 +45,14 @@ contract TychoRouterTest is TychoRouterTestSetup { } function testSetVerifierValidRole() public { - vm.startPrank(executorSetter); + vm.startPrank(EXECUTOR_SETTER); tychoRouter.setCallbackVerifier(DUMMY); vm.stopPrank(); assert(tychoRouter.callbackVerifiers(DUMMY) == true); } function testRemoveVerifierValidRole() public { - vm.startPrank(executorSetter); + vm.startPrank(EXECUTOR_SETTER); tychoRouter.setCallbackVerifier(DUMMY); tychoRouter.removeCallbackVerifier(DUMMY); vm.stopPrank(); @@ -216,8 +216,8 @@ contract TychoRouterTest is TychoRouterTestSetup { // Trade 1 WETH for DAI with 1 swap on Uniswap V2 // 1 WETH -> DAI // (univ2) - uint256 amount_in = 1 ether; - deal(WETH_ADDR, address(tychoRouter), amount_in); + uint256 amountIn = 1 ether; + deal(WETH_ADDR, address(tychoRouter), amountIn); bytes memory protocolData = encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false); @@ -227,9 +227,7 @@ contract TychoRouterTest is TychoRouterTestSetup { bytes[] memory swaps = new bytes[](1); swaps[0] = swap; - uint256 minAmountOut = 2600 * 1e18; - uint256 amountOut = - tychoRouter.splitSwap(amount_in, 2, pleEncode(swaps)); + tychoRouter.splitSwap(amountIn, 2, pleEncode(swaps)); uint256 daiBalance = IERC20(DAI_ADDR).balanceOf(ALICE); assertEq(daiBalance, 2630432278145144658455); @@ -240,8 +238,8 @@ contract TychoRouterTest is TychoRouterTestSetup { // Trade 1 WETH for USDC through DAI with 2 swaps on Uniswap V2 // 1 WETH -> DAI -> USDC // (univ2) (univ2) - uint256 amount_in = 1 ether; - deal(WETH_ADDR, address(tychoRouter), amount_in); + uint256 amountIn = 1 ether; + deal(WETH_ADDR, address(tychoRouter), amountIn); bytes[] memory swaps = new bytes[](2); // WETH -> DAI @@ -262,9 +260,7 @@ contract TychoRouterTest is TychoRouterTestSetup { encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, ALICE, true) ); - uint256 minAmountOut = 2600 * 1e6; - uint256 amountOut = - tychoRouter.splitSwap(amount_in, 3, pleEncode(swaps)); + tychoRouter.splitSwap(amountIn, 3, pleEncode(swaps)); uint256 usdcBalance = IERC20(USDC_ADDR).balanceOf(ALICE); assertEq(usdcBalance, 2610580090); @@ -277,8 +273,8 @@ contract TychoRouterTest is TychoRouterTestSetup { // 1 WETH USDC // -> WBTC -> // (univ2) (univ2) - uint256 amount_in = 1 ether; - deal(WETH_ADDR, address(tychoRouter), amount_in); + uint256 amountIn = 1 ether; + deal(WETH_ADDR, address(tychoRouter), amountIn); bytes[] memory swaps = new bytes[](4); // WETH -> WBTC (60%) @@ -315,9 +311,7 @@ contract TychoRouterTest is TychoRouterTestSetup { encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, ALICE, true) ); - uint256 minAmountOut = 2580 * 1e6; - uint256 amountOut = - tychoRouter.splitSwap(amount_in, 4, pleEncode(swaps)); + tychoRouter.splitSwap(amountIn, 4, pleEncode(swaps)); uint256 usdcBalance = IERC20(USDC_ADDR).balanceOf(ALICE); assertEq(usdcBalance, 2581503157); @@ -328,15 +322,15 @@ contract TychoRouterTest is TychoRouterTestSetup { // Trade 1 WETH for DAI with 1 swap on Uniswap V2 // Does permit2 token approval and transfer // Checks amount out at the end - uint256 amount_in = 1 ether; - deal(WETH_ADDR, ALICE, amount_in); + uint256 amountIn = 1 ether; + deal(WETH_ADDR, ALICE, amountIn); vm.startPrank(ALICE); ( IAllowanceTransfer.PermitSingle memory permitSingle, bytes memory signature - ) = handlePermit2Approval(WETH_ADDR, amount_in); + ) = handlePermit2Approval(WETH_ADDR, amountIn); bytes memory protocolData = encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false); @@ -348,7 +342,7 @@ contract TychoRouterTest is TychoRouterTestSetup { uint256 minAmountOut = 2600 * 1e18; uint256 amountOut = tychoRouter.swap( - amount_in, + amountIn, WETH_ADDR, DAI_ADDR, minAmountOut, @@ -361,8 +355,10 @@ contract TychoRouterTest is TychoRouterTestSetup { pleEncode(swaps) ); + uint256 expectedAmount = 2630432278145144658455; + assertEq(amountOut, expectedAmount); uint256 daiBalance = IERC20(DAI_ADDR).balanceOf(ALICE); - assertEq(daiBalance, 2630432278145144658455); + assertEq(daiBalance, expectedAmount); assertEq(IERC20(WETH_ADDR).balanceOf(ALICE), 0); vm.stopPrank(); @@ -372,15 +368,15 @@ contract TychoRouterTest is TychoRouterTestSetup { // Trade 1 WETH for DAI with 1 swap on Uniswap V2 // Does permit2 token approval and transfer // Checks amount out at the end and fails - uint256 amount_in = 1 ether; - deal(WETH_ADDR, ALICE, amount_in); + uint256 amountIn = 1 ether; + deal(WETH_ADDR, ALICE, amountIn); vm.startPrank(ALICE); ( IAllowanceTransfer.PermitSingle memory permitSingle, bytes memory signature - ) = handlePermit2Approval(WETH_ADDR, amount_in); + ) = handlePermit2Approval(WETH_ADDR, amountIn); bytes memory protocolData = encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false); @@ -398,8 +394,8 @@ contract TychoRouterTest is TychoRouterTestSetup { minAmountOut ) ); - uint256 amountOut = tychoRouter.swap( - amount_in, + tychoRouter.swap( + amountIn, WETH_ADDR, DAI_ADDR, minAmountOut, @@ -424,15 +420,15 @@ contract TychoRouterTest is TychoRouterTestSetup { tychoRouter.setFeeReceiver(FEE_RECEIVER); vm.stopPrank(); - uint256 amount_in = 1 ether; - deal(WETH_ADDR, ALICE, amount_in); + uint256 amountIn = 1 ether; + deal(WETH_ADDR, ALICE, amountIn); vm.startPrank(ALICE); ( IAllowanceTransfer.PermitSingle memory permitSingle, bytes memory signature - ) = handlePermit2Approval(WETH_ADDR, amount_in); + ) = handlePermit2Approval(WETH_ADDR, amountIn); bytes memory protocolData = encodeUniswapV2Swap( WETH_ADDR, WETH_DAI_POOL, address(tychoRouter), false @@ -444,7 +440,7 @@ contract TychoRouterTest is TychoRouterTestSetup { swaps[0] = swap; uint256 amountOut = tychoRouter.swap( - amount_in, + amountIn, WETH_ADDR, DAI_ADDR, 0, @@ -457,8 +453,10 @@ contract TychoRouterTest is TychoRouterTestSetup { pleEncode(swaps) ); + uint256 expectedAmount = 2604127955363693211871; + assertEq(amountOut, expectedAmount); uint256 daiBalance = IERC20(DAI_ADDR).balanceOf(ALICE); - assertEq(daiBalance, 2604127955363693211871); + assertEq(daiBalance, expectedAmount); assertEq(IERC20(DAI_ADDR).balanceOf(FEE_RECEIVER), 26304322781451446584); vm.stopPrank(); @@ -467,8 +465,8 @@ contract TychoRouterTest is TychoRouterTestSetup { function testSwapWrapETH() public { // Trade 1 ETH (and wrap it) for DAI with 1 swap on Uniswap V2 - uint256 amount_in = 1 ether; - deal(ALICE, amount_in); + uint256 amountIn = 1 ether; + deal(ALICE, amountIn); vm.startPrank(ALICE); @@ -491,8 +489,8 @@ contract TychoRouterTest is TychoRouterTestSetup { bytes[] memory swaps = new bytes[](1); swaps[0] = swap; - uint256 amountOut = tychoRouter.swap{value: amount_in}( - amount_in, + uint256 amountOut = tychoRouter.swap{value: amountIn}( + amountIn, address(0), DAI_ADDR, 0, @@ -504,9 +502,10 @@ contract TychoRouterTest is TychoRouterTestSetup { "", pleEncode(swaps) ); - + uint256 expectedAmount = 2630432278145144658455; + assertEq(amountOut, expectedAmount); uint256 daiBalance = IERC20(DAI_ADDR).balanceOf(ALICE); - assertEq(daiBalance, 2630432278145144658455); + assertEq(daiBalance, expectedAmount); assertEq(ALICE.balance, 0); vm.stopPrank(); @@ -515,15 +514,15 @@ contract TychoRouterTest is TychoRouterTestSetup { function testSwapUnwrapETH() public { // Trade 3k DAI for WETH with 1 swap on Uniswap V2 and unwrap it at the end - uint256 amount_in = 3_000 * 10 ** 18; - deal(DAI_ADDR, ALICE, amount_in); + uint256 amountIn = 3_000 * 10 ** 18; + deal(DAI_ADDR, ALICE, amountIn); vm.startPrank(ALICE); ( IAllowanceTransfer.PermitSingle memory permitSingle, bytes memory signature - ) = handlePermit2Approval(DAI_ADDR, amount_in); + ) = handlePermit2Approval(DAI_ADDR, amountIn); bytes memory protocolData = encodeUniswapV2Swap( DAI_ADDR, WETH_DAI_POOL, address(tychoRouter), true @@ -535,7 +534,7 @@ contract TychoRouterTest is TychoRouterTestSetup { swaps[0] = swap; uint256 amountOut = tychoRouter.swap( - amount_in, + amountIn, DAI_ADDR, address(0), 0, @@ -548,7 +547,9 @@ contract TychoRouterTest is TychoRouterTestSetup { pleEncode(swaps) ); - assertEq(ALICE.balance, 1132829934891544187); // 1.13 ETH + uint256 expectedAmount = 1132829934891544187; // 1.13 ETH + assertEq(amountOut, expectedAmount); + assertEq(ALICE.balance, expectedAmount); vm.stopPrank(); } diff --git a/foundry/test/TychoRouterTestSetup.sol b/foundry/test/TychoRouterTestSetup.sol index d1bb5ea..45212f8 100644 --- a/foundry/test/TychoRouterTestSetup.sol +++ b/foundry/test/TychoRouterTestSetup.sol @@ -28,7 +28,6 @@ contract TychoRouterExposed is TychoRouter { contract TychoRouterTestSetup is Test, Constants { TychoRouterExposed tychoRouter; - address executorSetter; address permit2Address = address(0x000000000022D473030F116dDEE9F6B43aC78BA3); UniswapV2Executor public usv2Executor; MockERC20[] tokens; @@ -39,7 +38,6 @@ contract TychoRouterTestSetup is Test, Constants { vm.startPrank(ADMIN); tychoRouter = new TychoRouterExposed(permit2Address, WETH_ADDR); - tychoRouter.grantRole(keccak256("EXECUTOR_SETTER_ROLE"), BOB); tychoRouter.grantRole(keccak256("FUND_RESCUER_ROLE"), FUND_RESCUER); tychoRouter.grantRole(keccak256("FEE_SETTER_ROLE"), FEE_SETTER); tychoRouter.grantRole(keccak256("PAUSER_ROLE"), PAUSER); @@ -47,7 +45,6 @@ contract TychoRouterTestSetup is Test, Constants { tychoRouter.grantRole( keccak256("EXECUTOR_SETTER_ROLE"), EXECUTOR_SETTER ); - executorSetter = BOB; deployDummyContract(); vm.stopPrank(); @@ -118,7 +115,7 @@ contract TychoRouterTestSetup is Test, Constants { function signPermit2( IAllowanceTransfer.PermitSingle memory permit, uint256 privateKey - ) internal returns (bytes memory) { + ) internal view returns (bytes memory) { bytes32 _PERMIT_DETAILS_TYPEHASH = keccak256( "PermitDetails(address token,uint160 amount,uint48 expiration,uint48 nonce)" );