From bdd3daffba3853ad084f7d3454e3c72fd6a1679c Mon Sep 17 00:00:00 2001 From: royvardhan Date: Mon, 10 Feb 2025 20:21:59 +0530 Subject: [PATCH] feat: update solc and add V4Router into UniswapV4Executor --- .gitmodules | 3 ++ foundry/foundry.toml | 2 +- foundry/interfaces/ICallbackVerifier.sol | 12 ++--- foundry/interfaces/IExecutor.sol | 10 ++-- foundry/lib/IWETH.sol | 2 +- foundry/lib/LibSwap.sol | 48 +++++++------------ .../bytes/LibPrefixLengthEncodedByteArray.sol | 24 +++++----- foundry/lib/v4-periphery | 1 + foundry/remappings.txt | 3 +- .../src/CallbackVerificationDispatcher.sol | 2 +- foundry/src/ExecutionDispatcher.sol | 2 +- foundry/src/TychoRouter.sol | 2 +- foundry/src/executors/BalancerV2Executor.sol | 2 +- foundry/src/executors/UniswapV2Executor.sol | 2 +- foundry/src/executors/UniswapV3Executor.sol | 2 +- foundry/src/executors/UniswapV4Executor.sol | 31 ++++++++---- .../test/CallbackVerificationDispatcher.t.sol | 2 +- foundry/test/Constants.sol | 2 +- foundry/test/ExecutionDispatcher.t.sol | 2 +- .../LibPrefixLengthEncodedByteArray.t.sol | 2 +- foundry/test/LibSwap.t.sol | 2 +- foundry/test/TychoRouter.t.sol | 2 +- foundry/test/TychoRouterTestSetup.sol | 2 +- .../test/executors/BalancerV2Executor.t.sol | 2 +- .../test/executors/UniswapV2Executor.t.sol | 2 +- .../test/executors/UniswapV3Executor.t.sol | 2 +- foundry/test/mock/MockERC20.sol | 2 +- 27 files changed, 86 insertions(+), 84 deletions(-) create mode 160000 foundry/lib/v4-periphery diff --git a/.gitmodules b/.gitmodules index ef3de4b..a1835d6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "foundry/lib/v4-core"] path = foundry/lib/v4-core url = https://github.com/Uniswap/v4-core +[submodule "foundry/lib/universal-router"] + path = foundry/lib/universal-router + url = https://github.com/uniswap/universal-router diff --git a/foundry/foundry.toml b/foundry/foundry.toml index 3d55450..e573137 100644 --- a/foundry/foundry.toml +++ b/foundry/foundry.toml @@ -2,7 +2,7 @@ src = 'src' out = 'out' libs = ['lib'] -solc = "0.8.28" +auto_detect_sol = true evm_version = 'cancun' optimizer = true optimizer_runs = 1000 diff --git a/foundry/interfaces/ICallbackVerifier.sol b/foundry/interfaces/ICallbackVerifier.sol index 6161e55..612279c 100644 --- a/foundry/interfaces/ICallbackVerifier.sol +++ b/foundry/interfaces/ICallbackVerifier.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; interface ICallbackVerifier { error UnauthorizedCaller(string exchange, address sender); @@ -7,10 +7,8 @@ interface ICallbackVerifier { /** * @dev This method should revert if the sender is not a verified sender of the exchange. */ - function verifyCallback(address sender, bytes calldata data) - external - returns ( - uint256 amountOwed, - address tokenOwed - ); + function verifyCallback( + address sender, + bytes calldata data + ) external returns (uint256 amountOwed, address tokenOwed); } diff --git a/foundry/interfaces/IExecutor.sol b/foundry/interfaces/IExecutor.sol index 9c5a55c..0a60022 100644 --- a/foundry/interfaces/IExecutor.sol +++ b/foundry/interfaces/IExecutor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -20,10 +20,10 @@ interface IExecutor { * @return calculatedAmount The amount of the output token swapped, depending on * the givenAmount inputted. */ - function swap(uint256 givenAmount, bytes calldata data) - external - payable - returns (uint256 calculatedAmount); + function swap( + uint256 givenAmount, + bytes calldata data + ) external payable returns (uint256 calculatedAmount); } interface IExecutorErrors { diff --git a/foundry/lib/IWETH.sol b/foundry/lib/IWETH.sol index 3b4a359..8ab98fa 100644 --- a/foundry/lib/IWETH.sol +++ b/foundry/lib/IWETH.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/foundry/lib/LibSwap.sol b/foundry/lib/LibSwap.sol index f581d8c..1770005 100644 --- a/foundry/lib/LibSwap.sol +++ b/foundry/lib/LibSwap.sol @@ -1,58 +1,44 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; library LibSwap { /// Returns the InToken index into an array of tokens - function tokenInIndex(bytes calldata swap) - internal - pure - returns (uint8 res) - { + function tokenInIndex( + bytes calldata swap + ) internal pure returns (uint8 res) { res = uint8(swap[0]); } /// The OutToken index into an array of tokens - function tokenOutIndex(bytes calldata swap) - internal - pure - returns (uint8 res) - { + function tokenOutIndex( + bytes calldata swap + ) internal pure returns (uint8 res) { res = uint8(swap[1]); } /// The relative amount of token quantity routed into this swap - function splitPercentage(bytes calldata swap) - internal - pure - returns (uint24 res) - { + function splitPercentage( + bytes calldata swap + ) internal pure returns (uint24 res) { res = uint24(bytes3(swap[2:5])); } /// The address of the executor contract - function executor(bytes calldata swap) - internal - pure - returns (address res) - { + function executor(bytes calldata swap) internal pure returns (address res) { 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) - { + 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) - { + function protocolData( + bytes calldata swap + ) internal pure returns (bytes calldata res) { res = swap[29:]; } } diff --git a/foundry/lib/bytes/LibPrefixLengthEncodedByteArray.sol b/foundry/lib/bytes/LibPrefixLengthEncodedByteArray.sol index b5773fd..7368b58 100644 --- a/foundry/lib/bytes/LibPrefixLengthEncodedByteArray.sol +++ b/foundry/lib/bytes/LibPrefixLengthEncodedByteArray.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; /** * @title Propellerheads PrefixLengthEncoded Byte Array Library @@ -16,11 +16,9 @@ library LibPrefixLengthEncodedByteArray { /** * @dev Pop the first element of an array and returns it with the remaining data. */ - function next(bytes calldata encoded) - internal - pure - returns (bytes calldata elem, bytes calldata res) - { + function next( + bytes calldata encoded + ) internal pure returns (bytes calldata elem, bytes calldata res) { assembly { switch iszero(encoded.length) case 1 { @@ -46,7 +44,11 @@ library LibPrefixLengthEncodedByteArray { assembly { let offset := encoded.offset let end := add(encoded.offset, encoded.length) - for {} lt(offset, end) {} { + for { + + } lt(offset, end) { + + } { offset := add(offset, add(shr(240, calldataload(offset)), 2)) s := add(s, 1) } @@ -56,11 +58,9 @@ library LibPrefixLengthEncodedByteArray { /** * @dev Cast an encoded array into a Solidity array. */ - function toArray(bytes calldata encoded) - internal - pure - returns (bytes[] memory arr) - { + function toArray( + bytes calldata encoded + ) internal pure returns (bytes[] memory arr) { bytes calldata elem; uint256 idx = 0; arr = new bytes[](LibPrefixLengthEncodedByteArray.size(encoded)); diff --git a/foundry/lib/v4-periphery b/foundry/lib/v4-periphery new file mode 160000 index 0000000..cf451c4 --- /dev/null +++ b/foundry/lib/v4-periphery @@ -0,0 +1 @@ +Subproject commit cf451c4f55f36ea64c2007d331e3a3574225fc8b diff --git a/foundry/remappings.txt b/foundry/remappings.txt index 74a44ca..04240ad 100644 --- a/foundry/remappings.txt +++ b/foundry/remappings.txt @@ -6,4 +6,5 @@ @balancer-labs/v2-interfaces=lib/balancer-v2-monorepo/pkg/interfaces @uniswap/v3-updated/=lib/v3-updated/ @uniswap/v3-core/=lib/v3-core/ -@uniswap/v4-core/=lib/v4-core/src/ \ No newline at end of file +@uniswap/v4-core/=lib/v4-core/ +@uniswap/v4-periphery/=lib/v4-periphery/ \ No newline at end of file diff --git a/foundry/src/CallbackVerificationDispatcher.sol b/foundry/src/CallbackVerificationDispatcher.sol index 87ccc8e..8df5848 100644 --- a/foundry/src/CallbackVerificationDispatcher.sol +++ b/foundry/src/CallbackVerificationDispatcher.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@interfaces/ICallbackVerifier.sol"; diff --git a/foundry/src/ExecutionDispatcher.sol b/foundry/src/ExecutionDispatcher.sol index 9e084c0..73bd554 100644 --- a/foundry/src/ExecutionDispatcher.sol +++ b/foundry/src/ExecutionDispatcher.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@interfaces/IExecutor.sol"; diff --git a/foundry/src/TychoRouter.sol b/foundry/src/TychoRouter.sol index c2e0b52..311c916 100644 --- a/foundry/src/TychoRouter.sol +++ b/foundry/src/TychoRouter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "../lib/IWETH.sol"; import "../lib/bytes/LibPrefixLengthEncodedByteArray.sol"; diff --git a/foundry/src/executors/BalancerV2Executor.sol b/foundry/src/executors/BalancerV2Executor.sol index 79777cb..14340cf 100644 --- a/foundry/src/executors/BalancerV2Executor.sol +++ b/foundry/src/executors/BalancerV2Executor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@interfaces/IExecutor.sol"; import { diff --git a/foundry/src/executors/UniswapV2Executor.sol b/foundry/src/executors/UniswapV2Executor.sol index 9f447f1..7239a8a 100644 --- a/foundry/src/executors/UniswapV2Executor.sol +++ b/foundry/src/executors/UniswapV2Executor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@interfaces/IExecutor.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/foundry/src/executors/UniswapV3Executor.sol b/foundry/src/executors/UniswapV3Executor.sol index 64ae64d..ac986c5 100644 --- a/foundry/src/executors/UniswapV3Executor.sol +++ b/foundry/src/executors/UniswapV3Executor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@interfaces/IExecutor.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/foundry/src/executors/UniswapV4Executor.sol b/foundry/src/executors/UniswapV4Executor.sol index 7b1556e..618d3f2 100644 --- a/foundry/src/executors/UniswapV4Executor.sol +++ b/foundry/src/executors/UniswapV4Executor.sol @@ -1,23 +1,24 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@interfaces/IExecutor.sol"; import {IERC20, SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {IPoolManager} from "@uniswap/v4-core/interfaces/IPoolManager.sol"; -import {Currency, CurrencyLibrary} from "@uniswap/v4-core/types/Currency.sol"; -import {PoolKey} from "@uniswap/v4-core/types/PoolKey.sol"; -import {BalanceDelta} from "@uniswap/v4-core/types/BalanceDelta.sol"; +import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; +import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; +import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; +import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import {IHooks} from "@uniswap/v4-core/interfaces/IHooks.sol"; -import {IUnlockCallback} from "@uniswap/v4-core/interfaces/callback/IUnlockCallback.sol"; -import {TransientStateLibrary} from "@uniswap/v4-core/libraries/TransientStateLibrary.sol"; +import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; +import {IUnlockCallback} from "@uniswap/v4-core/src/interfaces/callback/IUnlockCallback.sol"; +import {TransientStateLibrary} from "@uniswap/v4-core/src/libraries/TransientStateLibrary.sol"; +import {V4Router} from "@uniswap/v4-periphery/src/V4Router.sol"; error UniswapV4Executor__InvalidDataLength(); error UniswapV4Executor__SwapFailed(); error UniswapV4Executor__InsufficientOutput(); error UniswapV4Executor__ManagerMismatch(); -contract UniswapV4Executor is IExecutor { +contract UniswapV4Executor is IExecutor, V4Router { using SafeERC20 for IERC20; using CurrencyLibrary for Currency; using SafeCast for int128; @@ -36,6 +37,8 @@ contract UniswapV4Executor is IExecutor { address receiver; } + constructor(IPoolManager _poolManager) V4Router(_poolManager) {} + function swap( uint256 amountIn, bytes calldata data @@ -111,4 +114,14 @@ contract UniswapV4Executor is IExecutor { target = address(bytes20(data[63:83])); zeroForOne = uint8(data[83]) > 0; } + + function _pay( + Currency token, + address payer, + uint256 amount + ) internal override {} + + function msgSender() public view override returns (address) { + return msg.sender; + } } diff --git a/foundry/test/CallbackVerificationDispatcher.t.sol b/foundry/test/CallbackVerificationDispatcher.t.sol index 7a99f13..fd2577e 100644 --- a/foundry/test/CallbackVerificationDispatcher.t.sol +++ b/foundry/test/CallbackVerificationDispatcher.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@src/CallbackVerificationDispatcher.sol"; import "./TychoRouterTestSetup.sol"; diff --git a/foundry/test/Constants.sol b/foundry/test/Constants.sol index 835f4d6..f526d64 100644 --- a/foundry/test/Constants.sol +++ b/foundry/test/Constants.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "forge-std/Test.sol"; diff --git a/foundry/test/ExecutionDispatcher.t.sol b/foundry/test/ExecutionDispatcher.t.sol index a88dc44..7f2fb81 100644 --- a/foundry/test/ExecutionDispatcher.t.sol +++ b/foundry/test/ExecutionDispatcher.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@src/ExecutionDispatcher.sol"; import "./TychoRouterTestSetup.sol"; diff --git a/foundry/test/LibPrefixLengthEncodedByteArray.t.sol b/foundry/test/LibPrefixLengthEncodedByteArray.t.sol index d56b298..123f565 100644 --- a/foundry/test/LibPrefixLengthEncodedByteArray.t.sol +++ b/foundry/test/LibPrefixLengthEncodedByteArray.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.26; import {Test} from "forge-std/Test.sol"; import {LibPrefixLengthEncodedByteArray} from diff --git a/foundry/test/LibSwap.t.sol b/foundry/test/LibSwap.t.sol index eedc931..0627740 100644 --- a/foundry/test/LibSwap.t.sol +++ b/foundry/test/LibSwap.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "forge-std/Test.sol"; import "../lib/LibSwap.sol"; diff --git a/foundry/test/TychoRouter.t.sol b/foundry/test/TychoRouter.t.sol index 489d366..f7df52a 100644 --- a/foundry/test/TychoRouter.t.sol +++ b/foundry/test/TychoRouter.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import {TychoRouter} from "@src/TychoRouter.sol"; import "./TychoRouterTestSetup.sol"; diff --git a/foundry/test/TychoRouterTestSetup.sol b/foundry/test/TychoRouterTestSetup.sol index 839e3ee..2d63fe2 100644 --- a/foundry/test/TychoRouterTestSetup.sol +++ b/foundry/test/TychoRouterTestSetup.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; +pragma solidity ^0.8.26; import "../src/executors/UniswapV2Executor.sol"; import "./Constants.sol"; diff --git a/foundry/test/executors/BalancerV2Executor.t.sol b/foundry/test/executors/BalancerV2Executor.t.sol index f537cbf..117b153 100644 --- a/foundry/test/executors/BalancerV2Executor.t.sol +++ b/foundry/test/executors/BalancerV2Executor.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@src/executors/BalancerV2Executor.sol"; import {Test} from "../../lib/forge-std/src/Test.sol"; diff --git a/foundry/test/executors/UniswapV2Executor.t.sol b/foundry/test/executors/UniswapV2Executor.t.sol index 765d79c..dbcffbc 100644 --- a/foundry/test/executors/UniswapV2Executor.t.sol +++ b/foundry/test/executors/UniswapV2Executor.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@src/executors/UniswapV2Executor.sol"; import {Test} from "../../lib/forge-std/src/Test.sol"; diff --git a/foundry/test/executors/UniswapV3Executor.t.sol b/foundry/test/executors/UniswapV3Executor.t.sol index b73d580..4c9c1e9 100644 --- a/foundry/test/executors/UniswapV3Executor.t.sol +++ b/foundry/test/executors/UniswapV3Executor.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import "@src/executors/UniswapV3Executor.sol"; import {Test} from "../../lib/forge-std/src/Test.sol"; diff --git a/foundry/test/mock/MockERC20.sol b/foundry/test/mock/MockERC20.sol index 013c439..1ba6525 100644 --- a/foundry/test/mock/MockERC20.sol +++ b/foundry/test/mock/MockERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Unlicense -pragma solidity ^0.8.28; +pragma solidity ^0.8.26; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";