diff --git a/.forge-snapshots/simple swap with native.snap b/.forge-snapshots/simple swap with native.snap index eca48267a..6dae873bb 100644 --- a/.forge-snapshots/simple swap with native.snap +++ b/.forge-snapshots/simple swap with native.snap @@ -1 +1 @@ -131040 \ No newline at end of file +117440 \ No newline at end of file diff --git a/.forge-snapshots/simple swap.snap b/.forge-snapshots/simple swap.snap index 095efb63e..7652dce80 100644 --- a/.forge-snapshots/simple swap.snap +++ b/.forge-snapshots/simple swap.snap @@ -1 +1 @@ -149399 \ No newline at end of file +132636 \ No newline at end of file diff --git a/src/test/PoolSwapTest.sol b/src/test/PoolSwapTest.sol index 5bb773e8b..b1bdd5b24 100644 --- a/src/test/PoolSwapTest.sol +++ b/src/test/PoolSwapTest.sol @@ -8,8 +8,6 @@ import {PoolKey} from "../types/PoolKey.sol"; import {IHooks} from "../interfaces/IHooks.sol"; import {Hooks} from "../libraries/Hooks.sol"; import {PoolTestBase} from "./PoolTestBase.sol"; -import {Hooks} from "../libraries/Hooks.sol"; -import {IHooks} from "../interfaces/IHooks.sol"; import {CurrencySettleTake} from "../libraries/CurrencySettleTake.sol"; contract PoolSwapTest is PoolTestBase { diff --git a/src/test/SwapRouterNoChecks.sol b/src/test/SwapRouterNoChecks.sol new file mode 100644 index 000000000..9c00976d8 --- /dev/null +++ b/src/test/SwapRouterNoChecks.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +import {CurrencyLibrary, Currency} from "../types/Currency.sol"; +import {IPoolManager} from "../interfaces/IPoolManager.sol"; +import {BalanceDelta, BalanceDeltaLibrary} from "../types/BalanceDelta.sol"; +import {PoolKey} from "../types/PoolKey.sol"; +import {IHooks} from "../interfaces/IHooks.sol"; +import {Hooks} from "../libraries/Hooks.sol"; +import {PoolTestBase} from "./PoolTestBase.sol"; +import {CurrencySettleTake} from "../libraries/CurrencySettleTake.sol"; + +contract SwapRouterNoChecks is PoolTestBase { + using CurrencyLibrary for Currency; + using CurrencySettleTake for Currency; + using Hooks for IHooks; + + constructor(IPoolManager _manager) PoolTestBase(_manager) {} + + error NoSwapOccurred(); + + struct CallbackData { + address sender; + PoolKey key; + IPoolManager.SwapParams params; + } + + function swap(PoolKey memory key, IPoolManager.SwapParams memory params) external payable { + manager.unlock(abi.encode(CallbackData(msg.sender, key, params))); + } + + function unlockCallback(bytes calldata rawData) external returns (bytes memory) { + require(msg.sender == address(manager)); + + CallbackData memory data = abi.decode(rawData, (CallbackData)); + + BalanceDelta delta = manager.swap(data.key, data.params, new bytes(0)); + + if (data.params.zeroForOne) { + data.key.currency0.settle(manager, data.sender, uint256(int256(-delta.amount0())), false); + data.key.currency1.take(manager, data.sender, uint256(int256(delta.amount1())), false); + } else { + data.key.currency1.settle(manager, data.sender, uint256(int256(-delta.amount1())), false); + data.key.currency0.take(manager, data.sender, uint256(int256(delta.amount0())), false); + } + } +} diff --git a/test/PoolManager.t.sol b/test/PoolManager.t.sol index 8df6ddbcf..75aff2973 100644 --- a/test/PoolManager.t.sol +++ b/test/PoolManager.t.sol @@ -638,7 +638,7 @@ contract PoolManagerTest is Test, Deployers, GasSnapshot { swapRouter.swap(key, swapParams, testSettings, ZERO_BYTES); } - function test_swap_gas() public { + function test_swap_succeeds() public { IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({zeroForOne: true, amountSpecified: -100, sqrtPriceLimitX96: SQRT_PRICE_1_2}); @@ -646,10 +646,17 @@ contract PoolManagerTest is Test, Deployers, GasSnapshot { PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); swapRouter.swap(key, swapParams, testSettings, ZERO_BYTES); + } + + function test_swap_gas() public { + IPoolManager.SwapParams memory swapParams = + IPoolManager.SwapParams({zeroForOne: true, amountSpecified: -100, sqrtPriceLimitX96: SQRT_PRICE_1_2}); + + swapRouterNoChecks.swap(key, swapParams); snapLastCall("simple swap"); } - function test_swap_withNative_gas() public { + function test_swap_withNative_succeeds() public { IPoolManager.SwapParams memory swapParams = IPoolManager.SwapParams({zeroForOne: true, amountSpecified: -100, sqrtPriceLimitX96: SQRT_PRICE_1_2}); @@ -657,6 +664,13 @@ contract PoolManagerTest is Test, Deployers, GasSnapshot { PoolSwapTest.TestSettings({takeClaims: false, settleUsingBurn: false}); swapRouter.swap{value: 100}(nativeKey, swapParams, testSettings, ZERO_BYTES); + } + + function test_swap_withNative_gas() public { + IPoolManager.SwapParams memory swapParams = + IPoolManager.SwapParams({zeroForOne: true, amountSpecified: -100, sqrtPriceLimitX96: SQRT_PRICE_1_2}); + + swapRouterNoChecks.swap{value: 100}(nativeKey, swapParams); snapLastCall("simple swap with native"); } diff --git a/test/utils/Deployers.sol b/test/utils/Deployers.sol index 17b8c7b21..9a0df5ed4 100644 --- a/test/utils/Deployers.sol +++ b/test/utils/Deployers.sol @@ -16,6 +16,7 @@ import {Constants} from "../utils/Constants.sol"; import {SortTokens} from "./SortTokens.sol"; import {PoolModifyLiquidityTest} from "../../src/test/PoolModifyLiquidityTest.sol"; import {PoolSwapTest} from "../../src/test/PoolSwapTest.sol"; +import {SwapRouterNoChecks} from "../../src/test/SwapRouterNoChecks.sol"; import {PoolDonateTest} from "../../src/test/PoolDonateTest.sol"; import {PoolNestedActionsTest} from "../../src/test/PoolNestedActionsTest.sol"; import {PoolTakeTest} from "../../src/test/PoolTakeTest.sol"; @@ -55,6 +56,7 @@ contract Deployers { Currency internal currency1; IPoolManager manager; PoolModifyLiquidityTest modifyLiquidityRouter; + SwapRouterNoChecks swapRouterNoChecks; PoolSwapTest swapRouter; PoolDonateTest donateRouter; PoolTakeTest takeRouter; @@ -93,6 +95,7 @@ contract Deployers { function deployFreshManagerAndRouters() internal { deployFreshManager(); swapRouter = new PoolSwapTest(manager); + swapRouterNoChecks = new SwapRouterNoChecks(manager); modifyLiquidityRouter = new PoolModifyLiquidityTest(manager); donateRouter = new PoolDonateTest(manager); takeRouter = new PoolTakeTest(manager); @@ -122,8 +125,9 @@ contract Deployers { function deployMintAndApproveCurrency() internal returns (Currency currency) { MockERC20 token = deployTokens(1, 2 ** 255)[0]; - address[6] memory toApprove = [ + address[7] memory toApprove = [ address(swapRouter), + address(swapRouterNoChecks), address(modifyLiquidityRouter), address(donateRouter), address(takeRouter),