diff --git a/foundry/interfaces/ICurveRouter.sol b/foundry/interfaces/ICurveRouter.sol index 00bb9e2..57eb17a 100644 --- a/foundry/interfaces/ICurveRouter.sol +++ b/foundry/interfaces/ICurveRouter.sol @@ -11,6 +11,7 @@ interface ICurveRouter { address receiver ) external payable returns (uint256); + // slither-disable-next-line naming-convention function get_dy( address[] memory route, uint256[] memory swapParams, diff --git a/foundry/src/executors/CurveExecutor.sol b/foundry/src/executors/CurveExecutor.sol index 042b494..fc5748b 100644 --- a/foundry/src/executors/CurveExecutor.sol +++ b/foundry/src/executors/CurveExecutor.sol @@ -5,6 +5,8 @@ import "@interfaces/IExecutor.sol"; import "@interfaces/ICurveRouter.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +error CurveExecutor__InvalidAddresses(); + contract CurveExecutor is IExecutor { using SafeERC20 for IERC20; @@ -12,6 +14,9 @@ contract CurveExecutor is IExecutor { address public immutable ethAddress; constructor(address _curveRouter, address _ethAddress) { + if (_curveRouter == address(0) || _ethAddress == address(0)) { + revert CurveExecutor__InvalidAddresses(); + } curveRouter = ICurveRouter(_curveRouter); ethAddress = _ethAddress; } @@ -24,15 +29,16 @@ contract CurveExecutor is IExecutor { { CurveRouterParams memory params = _decodeData(data); if (params.route[0] != ethAddress) { + // slither-disable-next-line unused-return IERC20(params.route[0]).approve(address(curveRouter), amountIn); return curveRouter.exchange( - params.route, - params.swapParams, - amountIn, - params.minAmountOut, - params.pools, - params.receiver + params.route, + params.swapParams, + amountIn, + params.minAmountOut, + params.pools, + params.receiver ); } else { return curveRouter.exchange{value: amountIn}( diff --git a/foundry/test/Constants.sol b/foundry/test/Constants.sol index 3459a14..567b201 100644 --- a/foundry/test/Constants.sol +++ b/foundry/test/Constants.sol @@ -46,6 +46,12 @@ contract Constants is Test, BaseConstants { address CRV_ADDR = address(0xD533a949740bb3306d119CC777fa900bA034cd52); address ADAI_ADDR = address(0x028171bCA77440897B824Ca71D1c56caC55b68A3); address AUSDC_ADDR = address(0xBcca60bB61934080951369a648Fb03DF4F96263C); + address SUSD_ADDR = address(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51); + address FRAX_ADDR = address(0x853d955aCEf822Db058eb8505911ED77F175b99e); + address DOLA_ADDR = address(0x865377367054516e17014CcdED1e7d814EDC9ce4); + address XYO_ADDR = address(0x55296f69f40Ea6d20E478533C15A6B08B654E758); + address UWU_ADDR = address(0x55C08ca52497e2f1534B59E2917BF524D4765257); + address CRVUSD_ADDR = address(0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E); // Uniswap v2 address WETH_DAI_POOL = 0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11; @@ -102,6 +108,20 @@ contract Constants is Test, BaseConstants { // AAVE - Pool type 0 address AAVE_POOL = 0xDeBF20617708857ebe4F679508E7b7863a8A8EeE; + // BASE META POOL + address FRAXPYUSD_ADDR = address(0xA5588F7cdf560811710A2D82D3C9c99769DB1Dcb); + + // Curve pools taken from the substreams + address TRICRYPTO_USDT_WETH_WBTC = + 0xD51a44d3FaE010294C616388b506AcdA1bfAAE46; + address SUSD_POOL = 0xA5407eAE9Ba41422680e2e00537571bcC53efBfD; + address FRAX_USDC_POOL = 0xDcEF968d416a41Cdac0ED8702fAC8128A64241A2; + address USDE_USDC_POOL = 0x02950460E2b9529D0E00284A5fA2d7bDF3fA4d72; + address DOLA_FRAXPYUSD_POOL = 0xef484de8C07B6e2d732A92B5F78e81B38f99f95E; + address WETH_XYO_POOL = 0x99e09ee2d6Bb16c0F5ADDfEA649dbB2C1d524624; + address UWU_WETH_POOL = 0x77146B0a1d08B6844376dF6d9da99bA7F1b19e71; + address CRVUSD_USDT_POOL = 0x390f3595bCa2Df7d23783dFd126427CCeb997BF4; + // Uniswap universal router address UNIVERSAL_ROUTER = 0x66a9893cC07D91D95644AEDD05D03f95e1dBA8Af; @@ -123,6 +143,9 @@ contract Constants is Test, BaseConstants { // Curve router address CURVE_ROUTER = 0x16C6521Dff6baB339122a0FE25a9116693265353; + // Curve meta registry + address CURVE_META_REGISTRY = 0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC; + /** * @dev Deploys a dummy contract with non-empty bytecode */ diff --git a/foundry/test/executors/CurveExecutor.t.sol b/foundry/test/executors/CurveExecutor.t.sol index 694ae89..32572cd 100644 --- a/foundry/test/executors/CurveExecutor.t.sol +++ b/foundry/test/executors/CurveExecutor.t.sol @@ -5,11 +5,18 @@ import "@src/executors/CurveExecutor.sol"; import {Test} from "../../lib/forge-std/src/Test.sol"; import {Constants} from "../Constants.sol"; - interface ICurvePool { function coins(uint256 i) external view returns (address); } +interface MetaRegistry { + function get_n_coins(address pool) external view returns (uint256); + function get_coin_indices(address pool, address from, address to) + external + view + returns (int128, int128, bool); +} + interface ILendingPool { function deposit( address asset, @@ -24,7 +31,9 @@ interface ILendingPool { } contract CurveExecutorExposed is CurveExecutor { - constructor(address _curveRouter, address _ethAddress) CurveExecutor(_curveRouter, _ethAddress) {} + constructor(address _curveRouter, address _ethAddress) + CurveExecutor(_curveRouter, _ethAddress) + {} function decodeParams(bytes calldata data) external @@ -39,11 +48,13 @@ contract CurveExecutorTest is Test, Constants { using SafeERC20 for IERC20; CurveExecutorExposed curveExecutorExposed; + MetaRegistry metaRegistry; function setUp() public { uint256 forkBlock = 22031795; vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock); curveExecutorExposed = new CurveExecutorExposed(CURVE_ROUTER, ETH_ADDR); + metaRegistry = MetaRegistry(CURVE_META_REGISTRY); } function testDecodeParams() public view { @@ -79,10 +90,10 @@ contract CurveExecutorTest is Test, Constants { assertEq(params.swapParams[0][3], 3); } - function testCurveSwapPoolType0() public { address[11] memory route = _getRoute(ADAI_ADDR, AUSDC_ADDR, AAVE_POOL); - uint256[5][5] memory swapParams = _getSwapParams(AAVE_POOL, ADAI_ADDR, AUSDC_ADDR, 1, 1); + uint256[5][5] memory swapParams = + _getSwapParams(AAVE_POOL, ADAI_ADDR, AUSDC_ADDR, 1, 1); uint256 amountIn = 1 ether; uint256 minAmountOut = 0; @@ -90,16 +101,24 @@ contract CurveExecutorTest is Test, Constants { dealAaveDai(); bytes memory data = abi.encode( - route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed) + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) ); uint256 amountOut = curveExecutorExposed.swap(amountIn, data); assertEq(amountOut, 999734); - assertEq(IERC20(AUSDC_ADDR).balanceOf(address(curveExecutorExposed)), amountOut); + assertEq( + IERC20(AUSDC_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); } - function testCurveSwapPoolType1() public { + function testCurveSwapPoolType1() public { address[11] memory route = _getRoute(DAI_ADDR, USDC_ADDR, TRIPOOL_USDT_USDC_DAI); uint256[5][5] memory swapParams = @@ -142,8 +161,7 @@ contract CurveExecutorTest is Test, Constants { } function testCurveSwapPoolType4() public { - address[11] memory route = - _getRoute(ETH_ADDR, STETH_ADDR, STETH_POOL); + address[11] memory route = _getRoute(ETH_ADDR, STETH_ADDR, STETH_POOL); uint256[5][5] memory swapParams = _getSwapParams(STETH_POOL, ETH_ADDR, STETH_ADDR, 1, 1); @@ -153,40 +171,45 @@ contract CurveExecutorTest is Test, Constants { deal(address(curveExecutorExposed), amountIn); bytes memory data = abi.encode( - route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed) + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) ); - uint256 amountOut = curveExecutorExposed.swap( - amountIn, data - ); + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); assertTrue(amountOut >= 1 ether); - assertEq(IERC20(STETH_ADDR).balanceOf(address(curveExecutorExposed)), amountOut - 1); // Gets 1 wei less than amountOut + assertEq( + IERC20(STETH_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut - 1 + ); // Gets 1 wei less than amountOut // Now reverse the swap amountIn = amountOut - 1; - route = - _getRoute(STETH_ADDR, ETH_ADDR, STETH_POOL); - swapParams = - _getSwapParams(STETH_POOL, STETH_ADDR, ETH_ADDR, 1, 1); + route = _getRoute(STETH_ADDR, ETH_ADDR, STETH_POOL); + swapParams = _getSwapParams(STETH_POOL, STETH_ADDR, ETH_ADDR, 1, 1); data = abi.encode( - route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed) + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) ); - amountOut = curveExecutorExposed.swap( - amountIn, data - ); + amountOut = curveExecutorExposed.swap(amountIn, data); assertEq(address(curveExecutorExposed).balance, 999800010006950374); } - function testCurveSwapPoolType5() public { - address[11] memory route = - _getRoute(LUSD_ADDR, USDT_ADDR, LUSD_POOL); + address[11] memory route = _getRoute(LUSD_ADDR, USDT_ADDR, LUSD_POOL); uint256[5][5] memory swapParams = - _getSwapParams(LUSD_POOL, LUSD_ADDR, USDT_ADDR, 2, 1); + _getSwapParams(LUSD_POOL, LUSD_ADDR, USDT_ADDR, 2, 1); // pool.coins(index) reverts, defaulting tokenOut index to 0 swapParams[0][1] = 3; @@ -197,24 +220,28 @@ contract CurveExecutorTest is Test, Constants { deal(LUSD_ADDR, address(curveExecutorExposed), amountIn); bytes memory data = abi.encode( - route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed) + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) ); - uint256 amountOut = curveExecutorExposed.swap( - amountIn, data - ); + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); assertEq(amountOut, 1001785); - assertEq(IERC20(USDT_ADDR).balanceOf(address(curveExecutorExposed)), amountOut); + assertEq( + IERC20(USDT_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); } - function testCurveSwapPoolType6() public { - address[11] memory route = - _getRoute(DAI_ADDR, USDC_ADDR, CPOOL); + address[11] memory route = _getRoute(DAI_ADDR, USDC_ADDR, CPOOL); uint256[5][5] memory swapParams = - _getSwapParams(CPOOL, DAI_ADDR, USDC_ADDR, 2, 1); - + _getSwapParams(CPOOL, DAI_ADDR, USDC_ADDR, 2, 1); + // pool.coins(index) reverts, defaulting tokenOut index to 0 swapParams[0][1] = 1; @@ -224,19 +251,27 @@ contract CurveExecutorTest is Test, Constants { deal(DAI_ADDR, address(curveExecutorExposed), amountIn); bytes memory data = abi.encode( - route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed) + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) ); - uint256 amountOut = curveExecutorExposed.swap( - amountIn, data); + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); assertEq(amountOut, 999549); - assertEq(IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)), amountOut); + assertEq( + IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); } function testCurveSwapPoolType7() public { address[11] memory route = _getRoute(WETH_ADDR, LDO_ADDR, LDO_POOL); - uint256[5][5] memory swapParams = _getSwapParams(LDO_POOL, WETH_ADDR, LDO_ADDR, 1, 4); + uint256[5][5] memory swapParams = + _getSwapParams(LDO_POOL, WETH_ADDR, LDO_ADDR, 1, 4); // pool.coins(index) reverts, defaulting tokenOut index to 0 swapParams[0][1] = 1; @@ -247,20 +282,33 @@ contract CurveExecutorTest is Test, Constants { deal(WETH_ADDR, address(curveExecutorExposed), amountIn); bytes memory data = abi.encode( - route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed) + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) ); - uint256 amountOut = curveExecutorExposed.swap( - amountIn, data); - + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); assertEq(amountOut, 2075236672516568049094); - assertEq(IERC20(LDO_ADDR).balanceOf(address(curveExecutorExposed)), amountOut); + assertEq( + IERC20(LDO_ADDR).balanceOf(address(curveExecutorExposed)), amountOut + ); } - + function testCurveSwapPoolType8() public { address[11] memory route = _getRoute(CRV_ADDR, WETH_ADDR, CRV_POOL); - uint256[5][5] memory swapParams = _getSwapParams(CRV_POOL, CRV_ADDR, WETH_ADDR, 1, 4); + + // The registry does not have information about the pool. + // We manually set the swap params. + uint256[5][5] memory swapParams; + swapParams[0][0] = 1; + swapParams[0][1] = 0; + swapParams[0][2] = 1; + swapParams[0][3] = 4; + swapParams[0][4] = 2; uint256 amountIn = 1 ether; uint256 minAmountOut = 0; @@ -268,20 +316,253 @@ contract CurveExecutorTest is Test, Constants { deal(CRV_ADDR, address(curveExecutorExposed), amountIn); bytes memory data = abi.encode( - route, swapParams, amountIn, minAmountOut, pools, address(curveExecutorExposed) + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) ); - uint256 amountOut = curveExecutorExposed.swap( - amountIn, data); + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); assertEq(amountOut, 21806692849); - assertEq(IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)), amountOut); + assertEq( + IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); } + /// These tests are taken from the substreams + function testCurveSwapTricrypto2() public { + address[11] memory route = + _getRoute(WETH_ADDR, WBTC_ADDR, TRICRYPTO_USDT_WETH_WBTC); + uint256[5][5] memory swapParams = + _getSwapParams(TRICRYPTO_USDT_WETH_WBTC, WETH_ADDR, WBTC_ADDR, 1, 3); + uint256 amountIn = 1 ether; + uint256 minAmountOut = 0; + address[5] memory pools; + deal(WETH_ADDR, address(curveExecutorExposed), amountIn); + bytes memory data = abi.encode( + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) + ); + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); + + assertEq(amountOut, 2279618); + assertEq( + IERC20(WBTC_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); + } + + function testCurveSwapSUSD() public { + address[11] memory route = _getRoute(USDC_ADDR, SUSD_ADDR, SUSD_POOL); + uint256[5][5] memory swapParams = + _getSwapParams(SUSD_POOL, USDC_ADDR, SUSD_ADDR, 1, 1); + + uint256 amountIn = 100 * 10 ** 6; + uint256 minAmountOut = 0; + address[5] memory pools; + + deal(USDC_ADDR, address(curveExecutorExposed), amountIn); + bytes memory data = abi.encode( + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) + ); + + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); + + assertEq(amountOut, 100488101605550214590); + assertEq( + IERC20(SUSD_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); + } + + function testCurveSwapFraxUSDC() public { + address[11] memory route = + _getRoute(FRAX_ADDR, USDC_ADDR, FRAX_USDC_POOL); + uint256[5][5] memory swapParams = + _getSwapParams(FRAX_USDC_POOL, FRAX_ADDR, USDC_ADDR, 1, 1); + + uint256 amountIn = 1 ether; + uint256 minAmountOut = 0; + address[5] memory pools; + + deal(FRAX_ADDR, address(curveExecutorExposed), amountIn); + bytes memory data = abi.encode( + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) + ); + + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); + + assertEq(amountOut, 998096); + assertEq( + IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); + } + + function testCurveSwapCryptoSwapNGFactoryPlainPool() public { + address[11] memory route = + _getRoute(USDC_ADDR, USDE_ADDR, USDE_USDC_POOL); + uint256[5][5] memory swapParams = + _getSwapParams(USDE_USDC_POOL, USDC_ADDR, USDE_ADDR, 1, 1); + + uint256 amountIn = 100 * 10 ** 6; + uint256 minAmountOut = 0; + address[5] memory pools; + + deal(USDC_ADDR, address(curveExecutorExposed), amountIn); + bytes memory data = abi.encode( + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) + ); + + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); + + assertEq(amountOut, 100064812138999986170); + assertEq( + IERC20(USDE_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); + } + + function testCurveSwapMetaPool() public { + address[11] memory route = + _getRoute(DOLA_ADDR, FRAXPYUSD_ADDR, DOLA_FRAXPYUSD_POOL); + uint256[5][5] memory swapParams = + _getSwapParams(DOLA_FRAXPYUSD_POOL, DOLA_ADDR, FRAXPYUSD_ADDR, 1, 1); + + uint256 amountIn = 100 * 10 ** 6; + uint256 minAmountOut = 0; + address[5] memory pools; + + deal(DOLA_ADDR, address(curveExecutorExposed), amountIn); + bytes memory data = abi.encode( + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) + ); + + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); + + assertEq(amountOut, 99688991); + assertEq( + IERC20(FRAXPYUSD_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); + } + + function testCurveSwapWethXyo() public { + address[11] memory route = _getRoute(XYO_ADDR, WETH_ADDR, WETH_XYO_POOL); + uint256[5][5] memory swapParams = + _getSwapParams(WETH_XYO_POOL, XYO_ADDR, WETH_ADDR, 1, 2); + + uint256 amountIn = 1 ether; + uint256 minAmountOut = 0; + address[5] memory pools; + + deal(XYO_ADDR, address(curveExecutorExposed), amountIn); + bytes memory data = abi.encode( + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) + ); + + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); + + assertEq(amountOut, 6081816039338); + assertEq( + IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); + } + + function testCurveSwapUwuWeth() public { + address[11] memory route = _getRoute(UWU_ADDR, WETH_ADDR, UWU_WETH_POOL); + uint256[5][5] memory swapParams = + _getSwapParams(UWU_WETH_POOL, UWU_ADDR, WETH_ADDR, 1, 2); + + uint256 amountIn = 1 ether; + uint256 minAmountOut = 0; + address[5] memory pools; + + deal(UWU_ADDR, address(curveExecutorExposed), amountIn); + bytes memory data = abi.encode( + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) + ); + + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); + + assertEq(amountOut, 2873786684675); + assertEq( + IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); + } + + function testCurveSwapStableSwapFactoryPlainPool() public { + address[11] memory route = + _getRoute(CRVUSD_ADDR, USDT_ADDR, CRVUSD_USDT_POOL); + uint256[5][5] memory swapParams = + _getSwapParams(CRVUSD_USDT_POOL, CRVUSD_ADDR, USDT_ADDR, 1, 1); + + uint256 amountIn = 1 ether; + uint256 minAmountOut = 0; + address[5] memory pools; + + deal(CRVUSD_ADDR, address(curveExecutorExposed), amountIn); + bytes memory data = abi.encode( + route, + swapParams, + amountIn, + minAmountOut, + pools, + address(curveExecutorExposed) + ); + + uint256 amountOut = curveExecutorExposed.swap(amountIn, data); + + assertEq(amountOut, 999910); + assertEq( + IERC20(USDT_ADDR).balanceOf(address(curveExecutorExposed)), + amountOut + ); + } function _getRoute(address tokenIn, address tokenOut, address pool) internal @@ -300,43 +581,27 @@ contract CurveExecutorTest is Test, Constants { uint256 swapType, uint256 poolType ) internal view returns (uint256[5][5] memory swapParams) { - // Get number of coins in pool and their indices - uint256 coinInIndex; - uint256 coinOutIndex; - uint256 nCoins; - address lastCoinAddress = address(1); - while (lastCoinAddress != address(0)) { - try ICurvePool(pool).coins(nCoins) returns (address coin) { - lastCoinAddress = coin; - nCoins++; - if (coin == tokenIn) { - coinInIndex = nCoins - 1; - } - if (coin == tokenOut) { - coinOutIndex = nCoins - 1; - } - } catch { - lastCoinAddress = address(0); - } - } + uint256 nCoins = metaRegistry.get_n_coins(pool); + (int128 coinInIndex, int128 coinOutIndex, bool isMetapool) = + metaRegistry.get_coin_indices(pool, tokenIn, tokenOut); - swapParams[0][0] = coinInIndex; - swapParams[0][1] = coinOutIndex; + swapParams[0][0] = uint256(int256(coinInIndex)); + swapParams[0][1] = uint256(int256(coinOutIndex)); swapParams[0][2] = swapType; swapParams[0][3] = poolType; swapParams[0][4] = nCoins; } - - function dealAaveDai() internal { - deal(DAI_ADDR, address(curveExecutorExposed), 100_000 * 10 ** 18); + function dealAaveDai() internal { + deal(DAI_ADDR, address(curveExecutorExposed), 100_000 * 10 ** 18); ILendingPool aave = ILendingPool(0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9); vm.startPrank(address(curveExecutorExposed)); IERC20(DAI_ADDR).approve(address(aave), type(uint256).max); - aave.deposit(DAI_ADDR, 100_000 * 10 ** 18, address(curveExecutorExposed), 0); + aave.deposit( + DAI_ADDR, 100_000 * 10 ** 18, address(curveExecutorExposed), 0 + ); vm.stopPrank(); } } -