From 86054065bdef1d8c64f9de40c7605dcc04901200 Mon Sep 17 00:00:00 2001 From: Diana Kocsis Date: Wed, 20 Mar 2024 17:45:40 -0400 Subject: [PATCH] changes with core update --- .../FullOracleObserve0After5Seconds.snap | 2 +- .../FullOracleObserve200By13.snap | 2 +- .../FullOracleObserve200By13Plus5.snap | 2 +- .../FullOracleObserve5After5Seconds.snap | 2 +- .forge-snapshots/FullOracleObserveOldest.snap | 2 +- .../FullOracleObserveOldestAfter5Seconds.snap | 2 +- .forge-snapshots/FullOracleObserveZero.snap | 2 +- .forge-snapshots/OracleGrow10Slots.snap | 2 +- .../OracleGrow10SlotsCardinalityGreater.snap | 2 +- .forge-snapshots/OracleGrow1Slot.snap | 2 +- .../OracleGrow1SlotCardinalityGreater.snap | 2 +- .forge-snapshots/OracleInitialize.snap | 2 +- ...eObserveBetweenOldestAndOldestPlusOne.snap | 2 +- .../OracleObserveCurrentTime.snap | 2 +- ...racleObserveCurrentTimeCounterfactual.snap | 2 +- .../OracleObserveLast20Seconds.snap | 2 +- .../OracleObserveLatestEqual.snap | 2 +- .../OracleObserveLatestTransform.snap | 2 +- .forge-snapshots/OracleObserveMiddle.snap | 2 +- .forge-snapshots/OracleObserveOldest.snap | 2 +- .../OracleObserveSinceMostRecent.snap | 2 +- .forge-snapshots/RouterBytecode.snap | 2 +- .forge-snapshots/TWAMMSubmitOrder.snap | 2 +- contracts/BaseHook.sol | 28 +++++-- contracts/V4Router.sol | 12 +-- contracts/base/Multicall.sol | 2 +- contracts/base/PeripheryPayments.sol | 2 +- contracts/base/PeripheryValidation.sol | 2 +- contracts/base/SelfPermit.sol | 2 +- contracts/hooks/examples/FullRange.sol | 73 +++++++++++-------- contracts/hooks/examples/GeomeanOracle.sol | 38 +++++++--- contracts/hooks/examples/LimitOrder.sol | 56 +++++++------- contracts/hooks/examples/TWAMM.sol | 34 ++++++--- contracts/hooks/examples/VolatilityOracle.sol | 19 +++-- contracts/interfaces/IMulticall.sol | 2 +- contracts/interfaces/IPeripheryPayments.sol | 2 +- contracts/interfaces/IV4Router.sol | 2 +- contracts/lens/Quoter.sol | 28 +++---- contracts/libraries/Oracle.sol | 2 +- contracts/libraries/PoolGetters.sol | 2 +- contracts/libraries/UniswapV4ERC20.sol | 2 +- foundry.toml | 7 +- lib/v4-core | 2 +- test/FullRange.t.sol | 48 ++++++------ test/GeomeanOracle.t.sol | 49 ++++++------- test/LimitOrder.t.sol | 6 +- test/Oracle.t.sol | 2 +- test/Quoter.t.sol | 46 ++++++------ test/TWAMM.t.sol | 24 +++--- test/V4Router.t.sol | 12 +-- test/shared/GetSender.sol | 2 +- .../FullRangeImplementation.sol | 2 +- .../GeomeanOracleImplementation.sol | 2 +- .../LimitOrderImplementation.sol | 2 +- .../implementation/OracleImplementation.sol | 2 +- .../implementation/TWAMMImplementation.sol | 2 +- .../implementation/V4RouterImplementation.sol | 2 +- test/utils/HookEnabledSwapRouter.sol | 4 +- 58 files changed, 308 insertions(+), 260 deletions(-) diff --git a/.forge-snapshots/FullOracleObserve0After5Seconds.snap b/.forge-snapshots/FullOracleObserve0After5Seconds.snap index a08fb8e1..3411e3a3 100644 --- a/.forge-snapshots/FullOracleObserve0After5Seconds.snap +++ b/.forge-snapshots/FullOracleObserve0After5Seconds.snap @@ -1 +1 @@ -2687 \ No newline at end of file +2681 \ No newline at end of file diff --git a/.forge-snapshots/FullOracleObserve200By13.snap b/.forge-snapshots/FullOracleObserve200By13.snap index bb219663..b972d13c 100644 --- a/.forge-snapshots/FullOracleObserve200By13.snap +++ b/.forge-snapshots/FullOracleObserve200By13.snap @@ -1 +1 @@ -22933 \ No newline at end of file +22914 \ No newline at end of file diff --git a/.forge-snapshots/FullOracleObserve200By13Plus5.snap b/.forge-snapshots/FullOracleObserve200By13Plus5.snap index 6eb59a1d..9792572d 100644 --- a/.forge-snapshots/FullOracleObserve200By13Plus5.snap +++ b/.forge-snapshots/FullOracleObserve200By13Plus5.snap @@ -1 +1 @@ -23180 \ No newline at end of file +23161 \ No newline at end of file diff --git a/.forge-snapshots/FullOracleObserve5After5Seconds.snap b/.forge-snapshots/FullOracleObserve5After5Seconds.snap index 94c197e9..79eded72 100644 --- a/.forge-snapshots/FullOracleObserve5After5Seconds.snap +++ b/.forge-snapshots/FullOracleObserve5After5Seconds.snap @@ -1 +1 @@ -2738 \ No newline at end of file +2727 \ No newline at end of file diff --git a/.forge-snapshots/FullOracleObserveOldest.snap b/.forge-snapshots/FullOracleObserveOldest.snap index 75080690..3a8f8b89 100644 --- a/.forge-snapshots/FullOracleObserveOldest.snap +++ b/.forge-snapshots/FullOracleObserveOldest.snap @@ -1 +1 @@ -21892 \ No newline at end of file +21874 \ No newline at end of file diff --git a/.forge-snapshots/FullOracleObserveOldestAfter5Seconds.snap b/.forge-snapshots/FullOracleObserveOldestAfter5Seconds.snap index 9b54c31b..07de8526 100644 --- a/.forge-snapshots/FullOracleObserveOldestAfter5Seconds.snap +++ b/.forge-snapshots/FullOracleObserveOldestAfter5Seconds.snap @@ -1 +1 @@ -22191 \ No newline at end of file +22172 \ No newline at end of file diff --git a/.forge-snapshots/FullOracleObserveZero.snap b/.forge-snapshots/FullOracleObserveZero.snap index 2a55d550..34d11379 100644 --- a/.forge-snapshots/FullOracleObserveZero.snap +++ b/.forge-snapshots/FullOracleObserveZero.snap @@ -1 +1 @@ -2070 \ No newline at end of file +2069 \ No newline at end of file diff --git a/.forge-snapshots/OracleGrow10Slots.snap b/.forge-snapshots/OracleGrow10Slots.snap index f484e31f..09fe751f 100644 --- a/.forge-snapshots/OracleGrow10Slots.snap +++ b/.forge-snapshots/OracleGrow10Slots.snap @@ -1 +1 @@ -254660 \ No newline at end of file +254652 \ No newline at end of file diff --git a/.forge-snapshots/OracleGrow10SlotsCardinalityGreater.snap b/.forge-snapshots/OracleGrow10SlotsCardinalityGreater.snap index 83917a8d..8e9ce402 100644 --- a/.forge-snapshots/OracleGrow10SlotsCardinalityGreater.snap +++ b/.forge-snapshots/OracleGrow10SlotsCardinalityGreater.snap @@ -1 +1 @@ -245360 \ No newline at end of file +245352 \ No newline at end of file diff --git a/.forge-snapshots/OracleGrow1Slot.snap b/.forge-snapshots/OracleGrow1Slot.snap index 8f98b8b1..38036bf4 100644 --- a/.forge-snapshots/OracleGrow1Slot.snap +++ b/.forge-snapshots/OracleGrow1Slot.snap @@ -1 +1 @@ -54869 \ No newline at end of file +54861 \ No newline at end of file diff --git a/.forge-snapshots/OracleGrow1SlotCardinalityGreater.snap b/.forge-snapshots/OracleGrow1SlotCardinalityGreater.snap index ee2ae68d..2d134998 100644 --- a/.forge-snapshots/OracleGrow1SlotCardinalityGreater.snap +++ b/.forge-snapshots/OracleGrow1SlotCardinalityGreater.snap @@ -1 +1 @@ -45569 \ No newline at end of file +45561 \ No newline at end of file diff --git a/.forge-snapshots/OracleInitialize.snap b/.forge-snapshots/OracleInitialize.snap index 1e8b26e0..ed35f5a6 100644 --- a/.forge-snapshots/OracleInitialize.snap +++ b/.forge-snapshots/OracleInitialize.snap @@ -1 +1 @@ -72316 \ No newline at end of file +72306 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveBetweenOldestAndOldestPlusOne.snap b/.forge-snapshots/OracleObserveBetweenOldestAndOldestPlusOne.snap index a695bf26..2b11cfa9 100644 --- a/.forge-snapshots/OracleObserveBetweenOldestAndOldestPlusOne.snap +++ b/.forge-snapshots/OracleObserveBetweenOldestAndOldestPlusOne.snap @@ -1 +1 @@ -6492 \ No newline at end of file +6473 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveCurrentTime.snap b/.forge-snapshots/OracleObserveCurrentTime.snap index 2a55d550..34d11379 100644 --- a/.forge-snapshots/OracleObserveCurrentTime.snap +++ b/.forge-snapshots/OracleObserveCurrentTime.snap @@ -1 +1 @@ -2070 \ No newline at end of file +2069 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveCurrentTimeCounterfactual.snap b/.forge-snapshots/OracleObserveCurrentTimeCounterfactual.snap index 2a55d550..34d11379 100644 --- a/.forge-snapshots/OracleObserveCurrentTimeCounterfactual.snap +++ b/.forge-snapshots/OracleObserveCurrentTimeCounterfactual.snap @@ -1 +1 @@ -2070 \ No newline at end of file +2069 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveLast20Seconds.snap b/.forge-snapshots/OracleObserveLast20Seconds.snap index 5265bba3..0bd03724 100644 --- a/.forge-snapshots/OracleObserveLast20Seconds.snap +++ b/.forge-snapshots/OracleObserveLast20Seconds.snap @@ -1 +1 @@ -86878 \ No newline at end of file +86537 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveLatestEqual.snap b/.forge-snapshots/OracleObserveLatestEqual.snap index 2a55d550..34d11379 100644 --- a/.forge-snapshots/OracleObserveLatestEqual.snap +++ b/.forge-snapshots/OracleObserveLatestEqual.snap @@ -1 +1 @@ -2070 \ No newline at end of file +2069 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveLatestTransform.snap b/.forge-snapshots/OracleObserveLatestTransform.snap index a08fb8e1..3411e3a3 100644 --- a/.forge-snapshots/OracleObserveLatestTransform.snap +++ b/.forge-snapshots/OracleObserveLatestTransform.snap @@ -1 +1 @@ -2687 \ No newline at end of file +2681 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveMiddle.snap b/.forge-snapshots/OracleObserveMiddle.snap index d0974c4f..d7915ea2 100644 --- a/.forge-snapshots/OracleObserveMiddle.snap +++ b/.forge-snapshots/OracleObserveMiddle.snap @@ -1 +1 @@ -6684 \ No newline at end of file +6665 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveOldest.snap b/.forge-snapshots/OracleObserveOldest.snap index 05796bbf..16e3b167 100644 --- a/.forge-snapshots/OracleObserveOldest.snap +++ b/.forge-snapshots/OracleObserveOldest.snap @@ -1 +1 @@ -6193 \ No newline at end of file +6175 \ No newline at end of file diff --git a/.forge-snapshots/OracleObserveSinceMostRecent.snap b/.forge-snapshots/OracleObserveSinceMostRecent.snap index ed8dd329..18c6d0f8 100644 --- a/.forge-snapshots/OracleObserveSinceMostRecent.snap +++ b/.forge-snapshots/OracleObserveSinceMostRecent.snap @@ -1 +1 @@ -3382 \ No newline at end of file +3365 \ No newline at end of file diff --git a/.forge-snapshots/RouterBytecode.snap b/.forge-snapshots/RouterBytecode.snap index 2fef3e2c..f424f4ac 100644 --- a/.forge-snapshots/RouterBytecode.snap +++ b/.forge-snapshots/RouterBytecode.snap @@ -1 +1 @@ -5638 \ No newline at end of file +5482 \ No newline at end of file diff --git a/.forge-snapshots/TWAMMSubmitOrder.snap b/.forge-snapshots/TWAMMSubmitOrder.snap index 1ba4a8d1..0807b6ef 100644 --- a/.forge-snapshots/TWAMMSubmitOrder.snap +++ b/.forge-snapshots/TWAMMSubmitOrder.snap @@ -1 +1 @@ -145648 \ No newline at end of file +145810 \ No newline at end of file diff --git a/contracts/BaseHook.sol b/contracts/BaseHook.sol index 941de34c..c0292130 100644 --- a/contracts/BaseHook.sol +++ b/contracts/BaseHook.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; @@ -49,7 +49,7 @@ abstract contract BaseHook is IHooks { Hooks.validateHookPermissions(_this, getHooksCalls()); } - function lockAcquired(address, /*sender*/ bytes calldata data) + function unlockCallback(bytes calldata data) external virtual poolManagerOnly @@ -77,7 +77,7 @@ abstract contract BaseHook is IHooks { revert HookNotImplemented(); } - function beforeModifyPosition(address, PoolKey calldata, IPoolManager.ModifyPositionParams calldata, bytes calldata) + function beforeAddLiquidity(address, PoolKey calldata, IPoolManager.ModifyLiquidityParams calldata, bytes calldata) external virtual returns (bytes4) @@ -85,10 +85,28 @@ abstract contract BaseHook is IHooks { revert HookNotImplemented(); } - function afterModifyPosition( + function beforeRemoveLiquidity(address, PoolKey calldata, IPoolManager.ModifyLiquidityParams calldata, bytes calldata) + external + virtual + returns (bytes4) + { + revert HookNotImplemented(); + } + + function afterAddLiquidity( + address, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + BalanceDelta, + bytes calldata + ) external virtual returns (bytes4) { + revert HookNotImplemented(); + } + + function afterRemoveLiquidity( address, PoolKey calldata, - IPoolManager.ModifyPositionParams calldata, + IPoolManager.ModifyLiquidityParams calldata, BalanceDelta, bytes calldata ) external virtual returns (bytes4) { diff --git a/contracts/V4Router.sol b/contracts/V4Router.sol index 8b14c3fa..1c4b9600 100644 --- a/contracts/V4Router.sol +++ b/contracts/V4Router.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {ILockCallback} from "@uniswap/v4-core/src/interfaces/callback/ILockCallback.sol"; +import {IUnlockCallback} from "@uniswap/v4-core/src/interfaces/callback/IUnLockCallback.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; @@ -14,7 +14,7 @@ import {IV4Router} from "./interfaces/IV4Router.sol"; /// @title UniswapV4Router /// @notice Abstract contract that contains all internal logic needed for routing through Uniswap V4 pools -abstract contract V4Router is IV4Router, ILockCallback { +abstract contract V4Router is IV4Router, IUnlockCallback { using CurrencyLibrary for Currency; IPoolManager immutable poolManager; @@ -30,11 +30,11 @@ abstract contract V4Router is IV4Router, ILockCallback { } function _v4Swap(SwapType swapType, bytes memory params) internal { - poolManager.lock(address(this), abi.encode(SwapInfo(swapType, msg.sender, params))); + poolManager.unlock(abi.encode(SwapInfo(swapType, msg.sender, params))); } - /// @inheritdoc ILockCallback - function lockAcquired(address, /*lockCaller*/ bytes calldata encodedSwapInfo) + /// @inheritdoc IUnlockCallback + function unlockCallback(bytes calldata encodedSwapInfo) external override poolManagerOnly diff --git a/contracts/base/Multicall.sol b/contracts/base/Multicall.sol index bd926766..d754f6a3 100644 --- a/contracts/base/Multicall.sol +++ b/contracts/base/Multicall.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IMulticall} from "../interfaces/IMulticall.sol"; diff --git a/contracts/base/PeripheryPayments.sol b/contracts/base/PeripheryPayments.sol index 24466924..dc95ea23 100644 --- a/contracts/base/PeripheryPayments.sol +++ b/contracts/base/PeripheryPayments.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {ERC20} from "solmate/tokens/ERC20.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; diff --git a/contracts/base/PeripheryValidation.sol b/contracts/base/PeripheryValidation.sol index b8ea81d4..de719519 100644 --- a/contracts/base/PeripheryValidation.sol +++ b/contracts/base/PeripheryValidation.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; abstract contract PeripheryValidation { error TransactionTooOld(); diff --git a/contracts/base/SelfPermit.sol b/contracts/base/SelfPermit.sol index 40449636..9a2d88d6 100644 --- a/contracts/base/SelfPermit.sol +++ b/contracts/base/SelfPermit.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; diff --git a/contracts/hooks/examples/FullRange.sol b/contracts/hooks/examples/FullRange.sol index 1bd0cfe2..f09ba44d 100644 --- a/contracts/hooks/examples/FullRange.sol +++ b/contracts/hooks/examples/FullRange.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol"; @@ -11,7 +11,7 @@ import {CurrencyLibrary, Currency} from "@uniswap/v4-core/src/types/Currency.sol import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; import {IERC20Minimal} from "@uniswap/v4-core/src/interfaces/external/IERC20Minimal.sol"; -import {ILockCallback} from "@uniswap/v4-core/src/interfaces/callback/ILockCallback.sol"; +import {IUnlockCallback} from "@uniswap/v4-core/src/interfaces/callback/IUnlockCallback.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {FullMath} from "@uniswap/v4-core/src/libraries/FullMath.sol"; @@ -23,7 +23,7 @@ import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import "../../libraries/LiquidityAmounts.sol"; -contract FullRange is BaseHook, ILockCallback { +contract FullRange is BaseHook, IUnlockCallback { using CurrencyLibrary for Currency; using PoolIdLibrary for PoolKey; using SafeCast for uint256; @@ -50,7 +50,7 @@ contract FullRange is BaseHook, ILockCallback { struct CallbackData { address sender; PoolKey key; - IPoolManager.ModifyPositionParams params; + IPoolManager.ModifyLiquidityParams params; } struct PoolInfo { @@ -91,14 +91,14 @@ contract FullRange is BaseHook, ILockCallback { return Hooks.Permissions({ beforeInitialize: true, afterInitialize: false, - beforeModifyPosition: true, - afterModifyPosition: false, + beforeAddLiquidity: true, + beforeRemoveLiquidity: true, + afterAddLiquidity: false, + afterRemoveLiquidity: false, beforeSwap: true, afterSwap: false, beforeDonate: false, - afterDonate: false, - noOp: false, - accessLock: false + afterDonate: false }); } @@ -117,7 +117,7 @@ contract FullRange is BaseHook, ILockCallback { PoolId poolId = key.toId(); - (uint160 sqrtPriceX96,,) = poolManager.getSlot0(poolId); + (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(poolId); if (sqrtPriceX96 == 0) revert PoolNotInitialized(); @@ -136,9 +136,9 @@ contract FullRange is BaseHook, ILockCallback { if (poolLiquidity == 0 && liquidity <= MINIMUM_LIQUIDITY) { revert LiquidityDoesntMeetMinimum(); } - BalanceDelta addedDelta = modifyPosition( + BalanceDelta addedDelta = modifyLiquidity( key, - IPoolManager.ModifyPositionParams({ + IPoolManager.ModifyLiquidityParams({ tickLower: MIN_TICK, tickUpper: MAX_TICK, liquidityDelta: liquidity.toInt256() @@ -174,15 +174,15 @@ contract FullRange is BaseHook, ILockCallback { PoolId poolId = key.toId(); - (uint160 sqrtPriceX96,,) = poolManager.getSlot0(poolId); + (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(poolId); if (sqrtPriceX96 == 0) revert PoolNotInitialized(); UniswapV4ERC20 erc20 = UniswapV4ERC20(poolInfo[poolId].liquidityToken); - delta = modifyPosition( + delta = modifyLiquidity( key, - IPoolManager.ModifyPositionParams({ + IPoolManager.ModifyLiquidityParams({ tickLower: MIN_TICK, tickUpper: MAX_TICK, liquidityDelta: -(params.liquidity.toInt256()) @@ -219,15 +219,26 @@ contract FullRange is BaseHook, ILockCallback { return FullRange.beforeInitialize.selector; } - function beforeModifyPosition( + function beforeAddLiquidity( address sender, PoolKey calldata, - IPoolManager.ModifyPositionParams calldata, + IPoolManager.ModifyLiquidityParams calldata, bytes calldata ) external view override returns (bytes4) { if (sender != address(this)) revert SenderMustBeHook(); - return FullRange.beforeModifyPosition.selector; + return FullRange.beforeAddLiquidity.selector; + } + + function beforeRemoveLiquidity( + address sender, + PoolKey calldata, + IPoolManager.ModifyLiquidityParams calldata, + bytes calldata + ) external view override returns (bytes4) { + if (sender != address(this)) revert SenderMustBeHook(); + + return FullRange.beforeRemoveLiquidity.selector; } function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, bytes calldata) @@ -245,12 +256,12 @@ contract FullRange is BaseHook, ILockCallback { return IHooks.beforeSwap.selector; } - function modifyPosition(PoolKey memory key, IPoolManager.ModifyPositionParams memory params) + function modifyLiquidity(PoolKey memory key, IPoolManager.ModifyLiquidityParams memory params) internal returns (BalanceDelta delta) { delta = abi.decode( - poolManager.lock(address(this), abi.encode(CallbackData(msg.sender, key, params))), (BalanceDelta) + poolManager.unlock(abi.encode(CallbackData(msg.sender, key, params))), (BalanceDelta) ); } @@ -277,7 +288,7 @@ contract FullRange is BaseHook, ILockCallback { poolManager.take(key.currency1, sender, uint256(uint128(-delta.amount1()))); } - function _removeLiquidity(PoolKey memory key, IPoolManager.ModifyPositionParams memory params) + function _removeLiquidity(PoolKey memory key, IPoolManager.ModifyLiquidityParams memory params) internal returns (BalanceDelta delta) { @@ -295,18 +306,18 @@ contract FullRange is BaseHook, ILockCallback { ); params.liquidityDelta = -(liquidityToRemove.toInt256()); - delta = poolManager.modifyPosition(key, params, ZERO_BYTES); + delta = poolManager.modifyLiquidity(key, params, ZERO_BYTES); pool.hasAccruedFees = false; } - function lockAcquired(address sender, bytes calldata rawData) + function unlockCallback(bytes calldata rawData) external - override(ILockCallback, BaseHook) + override(IUnlockCallback, BaseHook) poolManagerOnly returns (bytes memory) { // Now that manager can be called by EOAs with a lock target, it's necessary for lockAcquired to check the original sender if it wants to trust the data passed through. - if (sender != address(this)) revert SenderMustBeHook(); + if (msg.sender != address(this)) revert SenderMustBeHook(); CallbackData memory data = abi.decode(rawData, (CallbackData)); BalanceDelta delta; @@ -314,7 +325,7 @@ contract FullRange is BaseHook, ILockCallback { delta = _removeLiquidity(data.key, data.params); _takeDeltas(data.sender, data.key, delta); } else { - delta = poolManager.modifyPosition(data.key, data.params, ZERO_BYTES); + delta = poolManager.modifyLiquidity(data.key, data.params, ZERO_BYTES); _settleDeltas(data.sender, data.key, delta); } return abi.encode(delta); @@ -322,9 +333,9 @@ contract FullRange is BaseHook, ILockCallback { function _rebalance(PoolKey memory key) public { PoolId poolId = key.toId(); - BalanceDelta balanceDelta = poolManager.modifyPosition( + BalanceDelta balanceDelta = poolManager.modifyLiquidity( key, - IPoolManager.ModifyPositionParams({ + IPoolManager.ModifyLiquidityParams({ tickLower: MIN_TICK, tickUpper: MAX_TICK, liquidityDelta: -(poolManager.getLiquidity(poolId).toInt256()) @@ -338,7 +349,7 @@ contract FullRange is BaseHook, ILockCallback { ) * FixedPointMathLib.sqrt(FixedPoint96.Q96) ).toUint160(); - (uint160 sqrtPriceX96,,) = poolManager.getSlot0(poolId); + (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(poolId); poolManager.swap( key, @@ -358,9 +369,9 @@ contract FullRange is BaseHook, ILockCallback { uint256(uint128(-balanceDelta.amount1())) ); - BalanceDelta balanceDeltaAfter = poolManager.modifyPosition( + BalanceDelta balanceDeltaAfter = poolManager.modifyLiquidity( key, - IPoolManager.ModifyPositionParams({ + IPoolManager.ModifyLiquidityParams({ tickLower: MIN_TICK, tickUpper: MAX_TICK, liquidityDelta: liquidity.toInt256() diff --git a/contracts/hooks/examples/GeomeanOracle.sol b/contracts/hooks/examples/GeomeanOracle.sol index 35389d0f..9d3af14a 100644 --- a/contracts/hooks/examples/GeomeanOracle.sol +++ b/contracts/hooks/examples/GeomeanOracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; @@ -64,14 +64,14 @@ contract GeomeanOracle is BaseHook { return Hooks.Permissions({ beforeInitialize: true, afterInitialize: true, - beforeModifyPosition: true, - afterModifyPosition: false, + beforeAddLiquidity: true, + beforeRemoveLiquidity: true, + afterAddLiquidity: false, + afterRemoveLiquidity: false, beforeSwap: true, afterSwap: false, beforeDonate: false, - afterDonate: false, - noOp: false, - accessLock: false + afterDonate: false }); } @@ -103,7 +103,7 @@ contract GeomeanOracle is BaseHook { /// @dev Called before any action that potentially modifies pool price or liquidity, such as swap or modify position function _updatePool(PoolKey calldata key) private { PoolId id = key.toId(); - (, int24 tick,) = poolManager.getSlot0(id); + (, int24 tick,,) = poolManager.getSlot0(id); uint128 liquidity = poolManager.getLiquidity(id); @@ -112,10 +112,10 @@ contract GeomeanOracle is BaseHook { ); } - function beforeModifyPosition( + function beforeAddLiquidity( address, PoolKey calldata key, - IPoolManager.ModifyPositionParams calldata params, + IPoolManager.ModifyLiquidityParams calldata params, bytes calldata ) external override poolManagerOnly returns (bytes4) { if (params.liquidityDelta < 0) revert OraclePoolMustLockLiquidity(); @@ -125,7 +125,23 @@ contract GeomeanOracle is BaseHook { || params.tickUpper != TickMath.maxUsableTick(maxTickSpacing) ) revert OraclePositionsMustBeFullRange(); _updatePool(key); - return GeomeanOracle.beforeModifyPosition.selector; + return GeomeanOracle.beforeAddLiquidity.selector; + } + + function beforeRemoveLiquidity( + address, + PoolKey calldata key, + IPoolManager.ModifyLiquidityParams calldata params, + bytes calldata + ) external override poolManagerOnly returns (bytes4) { + if (params.liquidityDelta < 0) revert OraclePoolMustLockLiquidity(); + int24 maxTickSpacing = poolManager.MAX_TICK_SPACING(); + if ( + params.tickLower != TickMath.minUsableTick(maxTickSpacing) + || params.tickUpper != TickMath.maxUsableTick(maxTickSpacing) + ) revert OraclePositionsMustBeFullRange(); + _updatePool(key); + return GeomeanOracle.beforeRemoveLiquidity.selector; } function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, bytes calldata) @@ -148,7 +164,7 @@ contract GeomeanOracle is BaseHook { ObservationState memory state = states[id]; - (, int24 tick,) = poolManager.getSlot0(id); + (, int24 tick,,) = poolManager.getSlot0(id); uint128 liquidity = poolManager.getLiquidity(id); diff --git a/contracts/hooks/examples/LimitOrder.sol b/contracts/hooks/examples/LimitOrder.sol index 2a5287bf..e5dd2230 100644 --- a/contracts/hooks/examples/LimitOrder.sol +++ b/contracts/hooks/examples/LimitOrder.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; @@ -77,14 +77,14 @@ contract LimitOrder is BaseHook { return Hooks.Permissions({ beforeInitialize: false, afterInitialize: true, - beforeModifyPosition: false, - afterModifyPosition: false, + beforeAddLiquidity: false, + beforeRemoveLiquidity: false, + afterAddLiquidity: false, + afterRemoveLiquidity: false, beforeSwap: false, afterSwap: true, beforeDonate: false, - afterDonate: false, - noOp: false, - accessLock: false + afterDonate: false }); } @@ -109,7 +109,7 @@ contract LimitOrder is BaseHook { } function getTick(PoolId poolId) private view returns (int24 tick) { - (, tick,) = poolManager.getSlot0(poolId); + (, tick,,) = poolManager.getSlot0(poolId); } function getTickLower(int24 tick, int24 tickSpacing) private pure returns (int24) { @@ -157,8 +157,7 @@ contract LimitOrder is BaseHook { epochInfo.filled = true; (uint256 amount0, uint256 amount1) = abi.decode( - poolManager.lock( - address(this), + poolManager.unlock( abi.encodeCall(this.lockAcquiredFill, (key, lower, -int256(uint256(epochInfo.liquidityTotal)))) ), (uint256, uint256) @@ -197,9 +196,9 @@ contract LimitOrder is BaseHook { selfOnly returns (uint128 amount0, uint128 amount1) { - BalanceDelta delta = poolManager.modifyPosition( + BalanceDelta delta = poolManager.modifyLiquidity( key, - IPoolManager.ModifyPositionParams({ + IPoolManager.ModifyLiquidityParams({ tickLower: tickLower, tickUpper: tickLower + key.tickSpacing, liquidityDelta: liquidityDelta @@ -208,10 +207,10 @@ contract LimitOrder is BaseHook { ); if (delta.amount0() < 0) { - poolManager.mint(key.currency0, address(this), amount0 = uint128(-delta.amount0())); + poolManager.mint(address(this), key.currency0.toId(), amount0 = uint128(-delta.amount0())); } if (delta.amount1() < 0) { - poolManager.mint(key.currency1, address(this), amount1 = uint128(-delta.amount1())); + poolManager.mint(address(this), key.currency1.toId(), amount1 = uint128(-delta.amount1())); } } @@ -221,8 +220,7 @@ contract LimitOrder is BaseHook { { if (liquidity == 0) revert ZeroLiquidity(); - poolManager.lock( - address(this), + poolManager.unlock( abi.encodeCall(this.lockAcquiredPlace, (key, tickLower, zeroForOne, int256(uint256(liquidity)), msg.sender)) ); @@ -258,9 +256,9 @@ contract LimitOrder is BaseHook { int256 liquidityDelta, address owner ) external selfOnly { - BalanceDelta delta = poolManager.modifyPosition( + BalanceDelta delta = poolManager.modifyLiquidity( key, - IPoolManager.ModifyPositionParams({ + IPoolManager.ModifyLiquidityParams({ tickLower: tickLower, tickUpper: tickLower + key.tickSpacing, liquidityDelta: liquidityDelta @@ -305,8 +303,7 @@ contract LimitOrder is BaseHook { uint256 amount0Fee; uint256 amount1Fee; (amount0, amount1, amount0Fee, amount1Fee) = abi.decode( - poolManager.lock( - address(this), + poolManager.unlock( abi.encodeCall( this.lockAcquiredKill, (key, tickLower, -int256(uint256(liquidity)), to, liquidity == liquidityTotal) @@ -332,28 +329,28 @@ contract LimitOrder is BaseHook { ) external selfOnly returns (uint256 amount0, uint256 amount1, uint128 amount0Fee, uint128 amount1Fee) { int24 tickUpper = tickLower + key.tickSpacing; - // because `modifyPosition` includes not just principal value but also fees, we cannot allocate + // because `modifyLiquidity` includes not just principal value but also fees, we cannot allocate // the proceeds pro-rata. if we were to do so, users who have been in a limit order that's partially filled // could be unfairly diluted by a user sychronously placing then killing a limit order to skim off fees. // to prevent this, we allocate all fee revenue to remaining limit order placers, unless this is the last order. if (!removingAllLiquidity) { - BalanceDelta deltaFee = poolManager.modifyPosition( + BalanceDelta deltaFee = poolManager.modifyLiquidity( key, - IPoolManager.ModifyPositionParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: 0}), + IPoolManager.ModifyLiquidityParams({tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: 0}), ZERO_BYTES ); if (deltaFee.amount0() < 0) { - poolManager.mint(key.currency0, address(this), amount0Fee = uint128(-deltaFee.amount0())); + poolManager.mint(address(this), key.currency0.toId(), amount0Fee = uint128(-deltaFee.amount0())); } if (deltaFee.amount1() < 0) { - poolManager.mint(key.currency1, address(this), amount1Fee = uint128(-deltaFee.amount1())); + poolManager.mint(address(this), key.currency1.toId(), amount1Fee = uint128(-deltaFee.amount1())); } } - BalanceDelta delta = poolManager.modifyPosition( + BalanceDelta delta = poolManager.modifyLiquidity( key, - IPoolManager.ModifyPositionParams({ + IPoolManager.ModifyLiquidityParams({ tickLower: tickLower, tickUpper: tickUpper, liquidityDelta: liquidityDelta @@ -389,8 +386,7 @@ contract LimitOrder is BaseHook { epochInfo.token1Total = token1Total - amount1; epochInfo.liquidityTotal = liquidityTotal - liquidity; - poolManager.lock( - address(this), + poolManager.unlock( abi.encodeCall(this.lockAcquiredWithdraw, (epochInfo.currency0, epochInfo.currency1, amount0, amount1, to)) ); @@ -405,11 +401,11 @@ contract LimitOrder is BaseHook { address to ) external selfOnly { if (token0Amount > 0) { - poolManager.burn(currency0, token0Amount); + poolManager.burn(address(this), currency0.toId(), token0Amount); poolManager.take(currency0, to, token0Amount); } if (token1Amount > 0) { - poolManager.burn(currency1, token1Amount); + poolManager.burn(address(this), currency1.toId(), token1Amount); poolManager.take(currency1, to, token1Amount); } } diff --git a/contracts/hooks/examples/TWAMM.sol b/contracts/hooks/examples/TWAMM.sol index 4fd5dd74..07d18f9d 100644 --- a/contracts/hooks/examples/TWAMM.sol +++ b/contracts/hooks/examples/TWAMM.sol @@ -64,14 +64,14 @@ contract TWAMM is BaseHook, ITWAMM { return Hooks.Permissions({ beforeInitialize: true, afterInitialize: false, - beforeModifyPosition: true, - afterModifyPosition: false, + beforeAddLiquidity: true, + beforeRemoveLiquidity: true, + afterAddLiquidity: false, + afterRemoveLiquidity: false, beforeSwap: true, afterSwap: false, beforeDonate: false, - afterDonate: false, - noOp: false, - accessLock: false + afterDonate: false }); } @@ -87,14 +87,24 @@ contract TWAMM is BaseHook, ITWAMM { return BaseHook.beforeInitialize.selector; } - function beforeModifyPosition( + function beforeAddLiquidity( address, PoolKey calldata key, - IPoolManager.ModifyPositionParams calldata, + IPoolManager.ModifyLiquidityParams calldata, bytes calldata ) external override poolManagerOnly returns (bytes4) { executeTWAMMOrders(key); - return BaseHook.beforeModifyPosition.selector; + return BaseHook.beforeAddLiquidity.selector; + } + + function beforeRemoveLiquidity( + address, + PoolKey calldata key, + IPoolManager.ModifyLiquidityParams calldata, + bytes calldata + ) external override poolManagerOnly returns (bytes4) { + executeTWAMMOrders(key); + return BaseHook.beforeRemoveLiquidity.selector; } function beforeSwap(address, PoolKey calldata key, IPoolManager.SwapParams calldata, bytes calldata) @@ -134,7 +144,7 @@ contract TWAMM is BaseHook, ITWAMM { /// @inheritdoc ITWAMM function executeTWAMMOrders(PoolKey memory key) public { PoolId poolId = key.toId(); - (uint160 sqrtPriceX96,,) = poolManager.getSlot0(poolId); + (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(poolId); State storage twamm = twammStates[poolId]; (bool zeroForOne, uint160 sqrtPriceLimitX96) = _executeTWAMMOrders( @@ -142,8 +152,8 @@ contract TWAMM is BaseHook, ITWAMM { ); if (sqrtPriceLimitX96 != 0 && sqrtPriceLimitX96 != sqrtPriceX96) { - poolManager.lock( - address(this), abi.encode(key, IPoolManager.SwapParams(zeroForOne, type(int256).max, sqrtPriceLimitX96)) + poolManager.unlock( + abi.encode(key, IPoolManager.SwapParams(zeroForOne, type(int256).max, sqrtPriceLimitX96)) ); } } @@ -300,7 +310,7 @@ contract TWAMM is BaseHook, ITWAMM { IERC20Minimal(Currency.unwrap(token)).safeTransfer(to, amountTransferred); } - function lockAcquired(address, /*sender*/ bytes calldata rawData) + function unlockCallback(bytes calldata rawData) external override poolManagerOnly diff --git a/contracts/hooks/examples/VolatilityOracle.sol b/contracts/hooks/examples/VolatilityOracle.sol index 657c9fae..a4409f7c 100644 --- a/contracts/hooks/examples/VolatilityOracle.sol +++ b/contracts/hooks/examples/VolatilityOracle.sol @@ -1,15 +1,14 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {IDynamicFeeManager} from "@uniswap/v4-core/src/interfaces/IDynamicFeeManager.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; -import {FeeLibrary} from "@uniswap/v4-core/src/libraries/FeeLibrary.sol"; +import {SwapFeeLibrary} from "@uniswap/v4-core/src/libraries/SwapFeeLibrary.sol"; import {BaseHook} from "../../BaseHook.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; -contract VolatilityOracle is BaseHook, IDynamicFeeManager { - using FeeLibrary for uint24; +contract VolatilityOracle is BaseHook { + using SwapFeeLibrary for uint24; error MustUseDynamicFee(); @@ -34,14 +33,14 @@ contract VolatilityOracle is BaseHook, IDynamicFeeManager { return Hooks.Permissions({ beforeInitialize: true, afterInitialize: false, - beforeModifyPosition: false, - afterModifyPosition: false, + beforeAddLiquidity: false, + beforeRemoveLiquidity: false, + afterAddLiquidity: false, + afterRemoveLiquidity: false, beforeSwap: false, afterSwap: false, beforeDonate: false, - afterDonate: false, - noOp: false, - accessLock: false + afterDonate: false }); } diff --git a/contracts/interfaces/IMulticall.sol b/contracts/interfaces/IMulticall.sol index dfa9db24..e80d7a17 100644 --- a/contracts/interfaces/IMulticall.sol +++ b/contracts/interfaces/IMulticall.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; /// @title Multicall interface /// @notice Enables calling multiple methods in a single call to the contract diff --git a/contracts/interfaces/IPeripheryPayments.sol b/contracts/interfaces/IPeripheryPayments.sol index f3c24660..5fab998b 100644 --- a/contracts/interfaces/IPeripheryPayments.sol +++ b/contracts/interfaces/IPeripheryPayments.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; diff --git a/contracts/interfaces/IV4Router.sol b/contracts/interfaces/IV4Router.sol index d59680be..ca2d5b3c 100644 --- a/contracts/interfaces/IV4Router.sol +++ b/contracts/interfaces/IV4Router.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import "forge-std/console.sol"; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; diff --git a/contracts/lens/Quoter.sol b/contracts/lens/Quoter.sol index aceee007..a26b8e27 100644 --- a/contracts/lens/Quoter.sol +++ b/contracts/lens/Quoter.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.20; import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; -import {ILockCallback} from "@uniswap/v4-core/src/interfaces/callback/ILockCallback.sol"; +import {IUnlockCallback} from "@uniswap/v4-core/src/interfaces/callback/IUnlockCallback.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; @@ -14,7 +14,7 @@ import {IQuoter} from "../interfaces/IQuoter.sol"; import {PoolTicksCounter} from "../libraries/PoolTicksCounter.sol"; import {PathKeyLib} from "../libraries/PathKey.sol"; -contract Quoter is IQuoter, ILockCallback { +contract Quoter is IQuoter, IUnlockCallback { using Hooks for IHooks; using PoolIdLibrary for PoolKey; @@ -50,7 +50,7 @@ contract Quoter is IQuoter, ILockCallback { override returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded) { - try manager.lock(address(this), abi.encodeWithSelector(this._quoteExactInputSingle.selector, params)) {} + try manager.unlock(abi.encodeWithSelector(this._quoteExactInputSingle.selector, params)) {} catch (bytes memory reason) { return _handleRevertSingle(reason); } @@ -65,7 +65,7 @@ contract Quoter is IQuoter, ILockCallback { uint32[] memory initializedTicksLoadedList ) { - try manager.lock(address(this), abi.encodeWithSelector(this._quoteExactInput.selector, params)) {} + try manager.unlock(abi.encodeWithSelector(this._quoteExactInput.selector, params)) {} catch (bytes memory reason) { return _handleRevert(reason); } @@ -79,7 +79,7 @@ contract Quoter is IQuoter, ILockCallback { { if (params.sqrtPriceLimitX96 == 0) amountOutCached = params.exactAmount; - try manager.lock(address(this), abi.encodeWithSelector(this._quoteExactOutputSingle.selector, params)) {} + try manager.unlock(abi.encodeWithSelector(this._quoteExactOutputSingle.selector, params)) {} catch (bytes memory reason) { if (params.sqrtPriceLimitX96 == 0) delete amountOutCached; return _handleRevertSingle(reason); @@ -96,18 +96,18 @@ contract Quoter is IQuoter, ILockCallback { uint32[] memory initializedTicksLoadedList ) { - try manager.lock(address(this), abi.encodeWithSelector(this._quoteExactOutput.selector, params)) {} + try manager.unlock(abi.encodeWithSelector(this._quoteExactOutput.selector, params)) {} catch (bytes memory reason) { return _handleRevert(reason); } } - /// @inheritdoc ILockCallback - function lockAcquired(address lockCaller, bytes calldata data) external returns (bytes memory) { + /// @inheritdoc IUnlockCallback + function unlockCallback(bytes calldata data) external returns (bytes memory) { if (msg.sender != address(manager)) { revert InvalidLockAcquiredSender(); } - if (lockCaller != address(this)) { + if (msg.sender != address(this)) { revert InvalidLockCaller(); } @@ -179,7 +179,7 @@ contract Quoter is IQuoter, ILockCallback { for (uint256 i = 0; i < pathLength; i++) { (PoolKey memory poolKey, bool zeroForOne) = PathKeyLib.getPoolAndSwapDirection(params.path[i], i == 0 ? params.exactCurrency : prevCurrencyOut); - (, int24 tickBefore,) = manager.getSlot0(poolKey.toId()); + (, int24 tickBefore,,) = manager.getSlot0(poolKey.toId()); (BalanceDelta curDeltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap( poolKey, @@ -208,7 +208,7 @@ contract Quoter is IQuoter, ILockCallback { /// @dev quote an ExactInput swap on a pool, then revert with the result function _quoteExactInputSingle(QuoteExactSingleParams memory params) public selfOnly returns (bytes memory) { - (, int24 tickBefore,) = manager.getSlot0(params.poolKey.toId()); + (, int24 tickBefore,,) = manager.getSlot0(params.poolKey.toId()); (BalanceDelta deltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap( params.poolKey, @@ -246,7 +246,7 @@ contract Quoter is IQuoter, ILockCallback { params.path[i - 1], i == pathLength ? params.exactCurrency : prevCurrencyIn ); - (, int24 tickBefore,) = manager.getSlot0(poolKey.toId()); + (, int24 tickBefore,,) = manager.getSlot0(poolKey.toId()); (BalanceDelta curDeltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap( poolKey, @@ -275,7 +275,7 @@ contract Quoter is IQuoter, ILockCallback { /// @dev quote an ExactOutput swap on a pool, then revert with the result function _quoteExactOutputSingle(QuoteExactSingleParams memory params) public selfOnly returns (bytes memory) { - (, int24 tickBefore,) = manager.getSlot0(params.poolKey.toId()); + (, int24 tickBefore,,) = manager.getSlot0(params.poolKey.toId()); (BalanceDelta deltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap( params.poolKey, params.zeroForOne, @@ -313,7 +313,7 @@ contract Quoter is IQuoter, ILockCallback { }), hookData ); - (sqrtPriceX96After, tickAfter,) = manager.getSlot0(poolKey.toId()); + (sqrtPriceX96After, tickAfter,,) = manager.getSlot0(poolKey.toId()); } /// @dev return either the sqrtPriceLimit from user input, or the max/min value possible depending on trade direction diff --git a/contracts/libraries/Oracle.sol b/contracts/libraries/Oracle.sol index 822f356f..2c3906ec 100644 --- a/contracts/libraries/Oracle.sol +++ b/contracts/libraries/Oracle.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; /// @title Oracle /// @notice Provides price and liquidity data useful for a wide variety of system designs diff --git a/contracts/libraries/PoolGetters.sol b/contracts/libraries/PoolGetters.sol index e3cb318b..5542e6ff 100644 --- a/contracts/libraries/PoolGetters.sol +++ b/contracts/libraries/PoolGetters.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {Pool} from "@uniswap/v4-core/src/libraries/Pool.sol"; diff --git a/contracts/libraries/UniswapV4ERC20.sol b/contracts/libraries/UniswapV4ERC20.sol index fdd93ba4..8b5d41ca 100644 --- a/contracts/libraries/UniswapV4ERC20.sol +++ b/contracts/libraries/UniswapV4ERC20.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {ERC20} from "solmate/tokens/ERC20.sol"; import {Owned} from "solmate/auth/Owned.sol"; diff --git a/foundry.toml b/foundry.toml index 620d06a6..068c477a 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,15 +1,14 @@ [profile.default] src = 'contracts' out = 'foundry-out' -solc_version = '0.8.20' -via_ir = true +solc_version = '0.8.24' optimizer_runs = 1000000 +via_ir = true ffi = true fs_permissions = [{ access = "read-write", path = ".forge-snapshots/"}] -cancun = true +evm_version = "cancun" [profile.ci] fuzz_runs = 100000 -solc = "./lib/v4-core/bin/solc-static-linux" # See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/lib/v4-core b/lib/v4-core index 83557113..86495abc 160000 --- a/lib/v4-core +++ b/lib/v4-core @@ -1 +1 @@ -Subproject commit 83557113a0425eb3d81570c30e7a5ce550037149 +Subproject commit 86495abc6947e97d67289f677d3d138f17853820 diff --git a/test/FullRange.t.sol b/test/FullRange.t.sol index 3d3f6800..c7f30c42 100644 --- a/test/FullRange.t.sol +++ b/test/FullRange.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol"; @@ -13,7 +13,7 @@ import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; -import {PoolModifyPositionTest} from "@uniswap/v4-core/src/test/PoolModifyPositionTest.sol"; +import {PoolModifyLiquidityTest} from "@uniswap/v4-core/src/test/PoolModifyLiquidityTest.sol"; import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {UniswapV4ERC20} from "../contracts/libraries/UniswapV4ERC20.sol"; @@ -34,7 +34,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { int24 tickSpacing, IHooks hooks ); - event ModifyPosition( + event ModifyLiquidity( PoolId indexed poolId, address indexed sender, int24 tickLower, int24 tickUpper, int256 liquidityDelta ); event Swap( @@ -65,7 +65,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { MockERC20 token2; FullRangeImplementation fullRange = FullRangeImplementation( - address(uint160(Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_MODIFY_POSITION_FLAG | Hooks.BEFORE_SWAP_FLAG)) + address(uint160(Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG | Hooks.BEFORE_SWAP_FLAG)) ); PoolId id; @@ -127,7 +127,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { emit Initialize(id, testKey.currency0, testKey.currency1, testKey.fee, testKey.tickSpacing, testKey.hooks); snapStart("FullRangeInitialize"); - initializeRouter.initialize(testKey, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(testKey, SQRT_RATIO_1_1, ZERO_BYTES); snapEnd(); (, address liquidityToken) = fullRange.poolInfo(id); @@ -139,11 +139,11 @@ contract TestFullRange is Test, Deployers, GasSnapshot { PoolKey memory wrongKey = PoolKey(key.currency0, key.currency1, 0, TICK_SPACING + 1, fullRange); vm.expectRevert(FullRange.TickSpacingNotDefault.selector); - initializeRouter.initialize(wrongKey, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(wrongKey, SQRT_RATIO_1_1, ZERO_BYTES); } function testFullRange_addLiquidity_InitialAddSucceeds() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); uint256 prevBalance0 = key.currency0.balanceOf(address(this)); uint256 prevBalance1 = key.currency1.balanceOf(address(this)); @@ -169,7 +169,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_addLiquidity_InitialAddFuzz(uint256 amount) public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); if (amount < LOCKED_LIQUIDITY) { vm.expectRevert(FullRange.LiquidityDoesntMeetMinimum.selector); fullRange.addLiquidity( @@ -244,7 +244,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_addLiquidity_SwapThenAddSucceeds() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); uint256 prevBalance0 = key.currency0.balanceOf(address(this)); uint256 prevBalance1 = key.currency1.balanceOf(address(this)); @@ -298,7 +298,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_addLiquidity_FailsIfTooMuchSlippage() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); fullRange.addLiquidity( FullRange.AddLiquidityParams( @@ -323,7 +323,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { function testFullRange_swap_TwoSwaps() public { PoolKey memory testKey = key; - initializeRouter.initialize(testKey, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(testKey, SQRT_RATIO_1_1, ZERO_BYTES); fullRange.addLiquidity( FullRange.AddLiquidityParams( @@ -352,8 +352,8 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_swap_TwoPools() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); - initializeRouter.initialize(key2, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key2, SQRT_RATIO_1_1, ZERO_BYTES); fullRange.addLiquidity( FullRange.AddLiquidityParams( @@ -408,7 +408,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_removeLiquidity_InitialRemoveFuzz(uint256 amount) public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); fullRange.addLiquidity( FullRange.AddLiquidityParams( @@ -456,7 +456,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_removeLiquidity_FailsIfNoLiquidity() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); (, address liquidityToken) = fullRange.poolInfo(id); UniswapV4ERC20(liquidityToken).approve(address(fullRange), type(uint256).max); @@ -468,7 +468,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_removeLiquidity_SucceedsWithPartial() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); uint256 prevBalance0 = key.currency0.balanceOfSelf(); uint256 prevBalance1 = key.currency1.balanceOfSelf(); @@ -503,7 +503,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_removeLiquidity_DiffRatios() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); uint256 prevBalance0 = key.currency0.balanceOf(address(this)); uint256 prevBalance1 = key.currency1.balanceOf(address(this)); @@ -571,7 +571,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_removeLiquidity_RemoveAllFuzz(uint256 amount) public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); (, address liquidityToken) = fullRange.poolInfo(id); if (amount <= LOCKED_LIQUIDITY) { @@ -626,7 +626,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { vm.prank(address(2)); token1.approve(address(fullRange), type(uint256).max); - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); (, address liquidityToken) = fullRange.poolInfo(id); // Test contract adds liquidity @@ -704,7 +704,7 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } function testFullRange_removeLiquidity_SwapRemoveAllFuzz(uint256 amount) public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); (, address liquidityToken) = fullRange.poolInfo(id); if (amount <= LOCKED_LIQUIDITY) { @@ -752,13 +752,13 @@ contract TestFullRange is Test, Deployers, GasSnapshot { } } - function testFullRange_BeforeModifyPositionFailsWithWrongMsgSender() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + function testFullRange_BeforeModifyLiquidityFailsWithWrongMsgSender() public { + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); vm.expectRevert(FullRange.SenderMustBeHook.selector); - modifyPositionRouter.modifyPosition( + modifyLiquidityRouter.modifyLiquidity( key, - IPoolManager.ModifyPositionParams({tickLower: MIN_TICK, tickUpper: MAX_TICK, liquidityDelta: 100}), + IPoolManager.ModifyLiquidityParams({tickLower: MIN_TICK, tickUpper: MAX_TICK, liquidityDelta: 100}), ZERO_BYTES ); } diff --git a/test/GeomeanOracle.t.sol b/test/GeomeanOracle.t.sol index aa5e5c6d..6d110397 100644 --- a/test/GeomeanOracle.t.sol +++ b/test/GeomeanOracle.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; import {GetSender} from "./shared/GetSender.sol"; @@ -12,7 +12,7 @@ import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; import {TestERC20} from "@uniswap/v4-core/src/test/TestERC20.sol"; import {CurrencyLibrary, Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; -import {PoolModifyPositionTest} from "@uniswap/v4-core/src/test/PoolModifyPositionTest.sol"; +import {PoolModifyLiquidityTest} from "@uniswap/v4-core/src/test/PoolModifyLiquidityTest.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {Oracle} from "../contracts/libraries/Oracle.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; @@ -21,14 +21,13 @@ contract TestGeomeanOracle is Test, Deployers { using PoolIdLibrary for PoolKey; int24 constant MAX_TICK_SPACING = 32767; - uint160 constant SQRT_RATIO_2_1 = 112045541949572279837463876454; TestERC20 token0; TestERC20 token1; GeomeanOracleImplementation geomeanOracle = GeomeanOracleImplementation( address( uint160( - Hooks.BEFORE_INITIALIZE_FLAG | Hooks.AFTER_INITIALIZE_FLAG | Hooks.BEFORE_MODIFY_POSITION_FLAG + Hooks.BEFORE_INITIALIZE_FLAG | Hooks.AFTER_INITIALIZE_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG | Hooks.BEFORE_SWAP_FLAG ) ) @@ -57,21 +56,21 @@ contract TestGeomeanOracle is Test, Deployers { key = PoolKey(currency0, currency1, 0, MAX_TICK_SPACING, geomeanOracle); id = key.toId(); - modifyPositionRouter = new PoolModifyPositionTest(manager); + modifyLiquidityRouter = new PoolModifyLiquidityTest(manager); token0.approve(address(geomeanOracle), type(uint256).max); token1.approve(address(geomeanOracle), type(uint256).max); - token0.approve(address(modifyPositionRouter), type(uint256).max); - token1.approve(address(modifyPositionRouter), type(uint256).max); + token0.approve(address(modifyLiquidityRouter), type(uint256).max); + token1.approve(address(modifyLiquidityRouter), type(uint256).max); } function testBeforeInitializeAllowsPoolCreation() public { - initializeRouter.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_1_1, ZERO_BYTES); } function testBeforeInitializeRevertsIfFee() public { vm.expectRevert(GeomeanOracle.OnlyOneOraclePoolAllowed.selector); - initializeRouter.initialize( + manager.initialize( PoolKey(Currency.wrap(address(token0)), Currency.wrap(address(token1)), 1, MAX_TICK_SPACING, geomeanOracle), SQRT_RATIO_1_1, ZERO_BYTES @@ -80,7 +79,7 @@ contract TestGeomeanOracle is Test, Deployers { function testBeforeInitializeRevertsIfNotMaxTickSpacing() public { vm.expectRevert(GeomeanOracle.OnlyOneOraclePoolAllowed.selector); - initializeRouter.initialize( + manager.initialize( PoolKey(Currency.wrap(address(token0)), Currency.wrap(address(token1)), 0, 60, geomeanOracle), SQRT_RATIO_1_1, ZERO_BYTES @@ -88,7 +87,7 @@ contract TestGeomeanOracle is Test, Deployers { } function testAfterInitializeState() public { - initializeRouter.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); GeomeanOracle.ObservationState memory observationState = geomeanOracle.getState(key); assertEq(observationState.index, 0); assertEq(observationState.cardinality, 1); @@ -96,7 +95,7 @@ contract TestGeomeanOracle is Test, Deployers { } function testAfterInitializeObservation() public { - initializeRouter.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); Oracle.Observation memory observation = geomeanOracle.getObservation(key, 0); assertTrue(observation.initialized); assertEq(observation.blockTimestamp, 1); @@ -105,7 +104,7 @@ contract TestGeomeanOracle is Test, Deployers { } function testAfterInitializeObserve0() public { - initializeRouter.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); + manager.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); uint32[] memory secondsAgo = new uint32[](1); secondsAgo[0] = 0; (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s) = @@ -116,11 +115,11 @@ contract TestGeomeanOracle is Test, Deployers { assertEq(secondsPerLiquidityCumulativeX128s[0], 0); } - function testBeforeModifyPositionNoObservations() public { - initializeRouter.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); - modifyPositionRouter.modifyPosition( + function testBeforeModifyLiquidityNoObservations() public { + manager.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); + modifyLiquidityRouter.modifyLiquidity( key, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( TickMath.minUsableTick(MAX_TICK_SPACING), TickMath.maxUsableTick(MAX_TICK_SPACING), 1000 ), ZERO_BYTES @@ -138,12 +137,12 @@ contract TestGeomeanOracle is Test, Deployers { assertEq(observation.secondsPerLiquidityCumulativeX128, 0); } - function testBeforeModifyPositionObservation() public { - initializeRouter.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); + function testBeforeModifyLiquidityObservation() public { + manager.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); geomeanOracle.setTime(3); // advance 2 seconds - modifyPositionRouter.modifyPosition( + modifyLiquidityRouter.modifyLiquidity( key, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( TickMath.minUsableTick(MAX_TICK_SPACING), TickMath.maxUsableTick(MAX_TICK_SPACING), 1000 ), ZERO_BYTES @@ -161,8 +160,8 @@ contract TestGeomeanOracle is Test, Deployers { assertEq(observation.secondsPerLiquidityCumulativeX128, 680564733841876926926749214863536422912); } - function testBeforeModifyPositionObservationAndCardinality() public { - initializeRouter.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); + function testBeforeModifyLiquidityObservationAndCardinality() public { + manager.initialize(key, SQRT_RATIO_2_1, ZERO_BYTES); geomeanOracle.setTime(3); // advance 2 seconds geomeanOracle.increaseCardinalityNext(key, 2); GeomeanOracle.ObservationState memory observationState = geomeanOracle.getState(key); @@ -170,9 +169,9 @@ contract TestGeomeanOracle is Test, Deployers { assertEq(observationState.cardinality, 1); assertEq(observationState.cardinalityNext, 2); - modifyPositionRouter.modifyPosition( + modifyLiquidityRouter.modifyLiquidity( key, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( TickMath.minUsableTick(MAX_TICK_SPACING), TickMath.maxUsableTick(MAX_TICK_SPACING), 1000 ), ZERO_BYTES diff --git a/test/LimitOrder.t.sol b/test/LimitOrder.t.sol index 94cca602..a15ddda3 100644 --- a/test/LimitOrder.t.sol +++ b/test/LimitOrder.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; import {GetSender} from "./shared/GetSender.sol"; @@ -63,7 +63,7 @@ contract TestLimitOrder is Test, Deployers { function testGetTickLowerLastWithDifferentPrice() public { PoolKey memory differentKey = PoolKey(Currency.wrap(address(token0)), Currency.wrap(address(token1)), 3000, 61, limitOrder); - initializeRouter.initialize(differentKey, SQRT_RATIO_10_1, ZERO_BYTES); + manager.initialize(differentKey, SQRT_RATIO_10_1, ZERO_BYTES); assertEq(limitOrder.getTickLowerLast(differentKey.toId()), 22997); } @@ -197,7 +197,7 @@ contract TestLimitOrder is Test, Deployers { ); assertEq(limitOrder.getTickLowerLast(id), 60); - (, int24 tick,) = manager.getSlot0(id); + (, int24 tick,,) = manager.getSlot0(id); assertEq(tick, 60); (bool filled,,, uint256 token0Total, uint256 token1Total,) = limitOrder.epochInfos(Epoch.wrap(1)); diff --git a/test/Oracle.t.sol b/test/Oracle.t.sol index 04157e16..88a12e59 100644 --- a/test/Oracle.t.sol +++ b/test/Oracle.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol"; import {Test} from "forge-std/Test.sol"; diff --git a/test/Quoter.t.sol b/test/Quoter.t.sol index 056b0818..2ba809dd 100644 --- a/test/Quoter.t.sol +++ b/test/Quoter.t.sol @@ -12,7 +12,7 @@ import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol"; import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol"; import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; -import {PoolModifyPositionTest} from "@uniswap/v4-core/src/test/PoolModifyPositionTest.sol"; +import {PoolModifyLiquidityTest} from "@uniswap/v4-core/src/test/PoolModifyLiquidityTest.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol"; @@ -36,7 +36,7 @@ contract QuoterTest is Test, Deployers { Quoter quoter; - PoolModifyPositionTest positionManager; + PoolModifyLiquidityTest positionManager; MockERC20 token0; MockERC20 token1; @@ -51,7 +51,7 @@ contract QuoterTest is Test, Deployers { function setUp() public { deployFreshManagerAndRouters(); quoter = new Quoter(address(manager)); - positionManager = new PoolModifyPositionTest(manager); + positionManager = new PoolModifyLiquidityTest(manager); // salts are chosen so that address(token0) < address(token2) && address(1) < address(token2) bytes32 salt1 = "ffff"; @@ -115,11 +115,11 @@ contract QuoterTest is Test, Deployers { assertEq(initializedTicksLoaded, 2); } - // nested self-call into lockAcquired reverts + // nested self-call into unlockCallback reverts function testQuoter_callLockAcquired_reverts() public { vm.expectRevert(IQuoter.InvalidLockAcquiredSender.selector); vm.prank(address(manager)); - quoter.lockAcquired(address(quoter), abi.encodeWithSelector(quoter.lockAcquired.selector, address(this), "0x")); + quoter.unlockCallback(abi.encodeWithSelector(quoter.unlockCallback.selector, address(this), "0x")); } function testQuoter_quoteExactInput_0to2_2TicksLoaded() public { @@ -538,12 +538,12 @@ contract QuoterTest is Test, Deployers { } function setupPool(PoolKey memory poolKey) internal { - initializeRouter.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES); MockERC20(Currency.unwrap(poolKey.currency0)).approve(address(positionManager), type(uint256).max); MockERC20(Currency.unwrap(poolKey.currency1)).approve(address(positionManager), type(uint256).max); - positionManager.modifyPosition( + positionManager.modifyLiquidity( poolKey, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( MIN_TICK, MAX_TICK, calculateLiquidityFromAmounts(SQRT_RATIO_1_1, MIN_TICK, MAX_TICK, 1000000, 1000000).toInt256() @@ -553,28 +553,28 @@ contract QuoterTest is Test, Deployers { } function setupPoolMultiplePositions(PoolKey memory poolKey) internal { - initializeRouter.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES); MockERC20(Currency.unwrap(poolKey.currency0)).approve(address(positionManager), type(uint256).max); MockERC20(Currency.unwrap(poolKey.currency1)).approve(address(positionManager), type(uint256).max); - positionManager.modifyPosition( + positionManager.modifyLiquidity( poolKey, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( MIN_TICK, MAX_TICK, calculateLiquidityFromAmounts(SQRT_RATIO_1_1, MIN_TICK, MAX_TICK, 1000000, 1000000).toInt256() ), ZERO_BYTES ); - positionManager.modifyPosition( + positionManager.modifyLiquidity( poolKey, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( -60, 60, calculateLiquidityFromAmounts(SQRT_RATIO_1_1, -60, 60, 100, 100).toInt256() ), ZERO_BYTES ); - positionManager.modifyPosition( + positionManager.modifyLiquidity( poolKey, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( -120, 120, calculateLiquidityFromAmounts(SQRT_RATIO_1_1, -120, 120, 100, 100).toInt256() ), ZERO_BYTES @@ -583,32 +583,32 @@ contract QuoterTest is Test, Deployers { function setupPoolWithZeroTickInitialized(PoolKey memory poolKey) internal { PoolId poolId = poolKey.toId(); - (uint160 sqrtPriceX96,,) = manager.getSlot0(poolId); + (uint160 sqrtPriceX96,,,) = manager.getSlot0(poolId); if (sqrtPriceX96 == 0) { - initializeRouter.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES); } MockERC20(Currency.unwrap(poolKey.currency0)).approve(address(positionManager), type(uint256).max); MockERC20(Currency.unwrap(poolKey.currency1)).approve(address(positionManager), type(uint256).max); - positionManager.modifyPosition( + positionManager.modifyLiquidity( poolKey, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( MIN_TICK, MAX_TICK, calculateLiquidityFromAmounts(SQRT_RATIO_1_1, MIN_TICK, MAX_TICK, 1000000, 1000000).toInt256() ), ZERO_BYTES ); - positionManager.modifyPosition( + positionManager.modifyLiquidity( poolKey, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( 0, 60, calculateLiquidityFromAmounts(SQRT_RATIO_1_1, 0, 60, 100, 100).toInt256() ), ZERO_BYTES ); - positionManager.modifyPosition( + positionManager.modifyLiquidity( poolKey, - IPoolManager.ModifyPositionParams( + IPoolManager.ModifyLiquidityParams( -120, 0, calculateLiquidityFromAmounts(SQRT_RATIO_1_1, -120, 0, 100, 100).toInt256() ), ZERO_BYTES diff --git a/test/TWAMM.t.sol b/test/TWAMM.t.sol index 17ed64a1..80bac156 100644 --- a/test/TWAMM.t.sol +++ b/test/TWAMM.t.sol @@ -12,7 +12,7 @@ import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol"; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; -import {PoolModifyPositionTest} from "@uniswap/v4-core/src/test/PoolModifyPositionTest.sol"; +import {PoolModifyLiquidityTest} from "@uniswap/v4-core/src/test/PoolModifyLiquidityTest.sol"; import {PoolSwapTest} from "@uniswap/v4-core/src/test/PoolSwapTest.sol"; import {PoolDonateTest} from "@uniswap/v4-core/src/test/PoolDonateTest.sol"; import {Deployers} from "@uniswap/v4-core/test/utils/Deployers.sol"; @@ -43,9 +43,9 @@ contract TWAMMTest is Test, Deployers, GasSnapshot { uint256 earningsFactorLast ); - // address constant TWAMMAddr = address(uint160(Hooks.AFTER_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_MODIFY_POSITION_FLAG)); + // address constant TWAMMAddr = address(uint160(Hooks.AFTER_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG)); TWAMM twamm = TWAMM( - address(uint160(Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_MODIFY_POSITION_FLAG)) + address(uint160(Hooks.BEFORE_INITIALIZE_FLAG | Hooks.BEFORE_SWAP_FLAG | Hooks.BEFORE_ADD_LIQUIDITY_FLAG | Hooks.BEFORE_REMOVE_LIQUIDITY_FLAG)) ); // TWAMM twamm; address hookAddress; @@ -74,15 +74,15 @@ contract TWAMMTest is Test, Deployers, GasSnapshot { (poolKey, poolId) = initPool(currency0, currency1, twamm, 3000, SQRT_RATIO_1_1, ZERO_BYTES); - token0.approve(address(modifyPositionRouter), 100 ether); - token1.approve(address(modifyPositionRouter), 100 ether); + token0.approve(address(modifyLiquidityRouter), 100 ether); + token1.approve(address(modifyLiquidityRouter), 100 ether); token0.mint(address(this), 100 ether); token1.mint(address(this), 100 ether); - modifyPositionRouter.modifyPosition(poolKey, IPoolManager.ModifyPositionParams(-60, 60, 10 ether), ZERO_BYTES); - modifyPositionRouter.modifyPosition(poolKey, IPoolManager.ModifyPositionParams(-120, 120, 10 ether), ZERO_BYTES); - modifyPositionRouter.modifyPosition( + modifyLiquidityRouter.modifyLiquidity(poolKey, IPoolManager.ModifyLiquidityParams(-60, 60, 10 ether), ZERO_BYTES); + modifyLiquidityRouter.modifyLiquidity(poolKey, IPoolManager.ModifyLiquidityParams(-120, 120, 10 ether), ZERO_BYTES); + modifyLiquidityRouter.modifyLiquidity( poolKey, - IPoolManager.ModifyPositionParams(TickMath.minUsableTick(60), TickMath.maxUsableTick(60), 10 ether), + IPoolManager.ModifyLiquidityParams(TickMath.minUsableTick(60), TickMath.maxUsableTick(60), 10 ether), ZERO_BYTES ); } @@ -92,7 +92,7 @@ contract TWAMMTest is Test, Deployers, GasSnapshot { assertEq(twamm.lastVirtualOrderTimestamp(initId), 0); vm.warp(10000); - initializeRouter.initialize(initKey, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(initKey, SQRT_RATIO_1_1, ZERO_BYTES); assertEq(twamm.lastVirtualOrderTimestamp(initId), 10000); } @@ -361,8 +361,8 @@ contract TWAMMTest is Test, Deployers, GasSnapshot { token0.approve(address(twamm), 100e18); token1.approve(address(twamm), 100e18); - modifyPositionRouter.modifyPosition( - poolKey, IPoolManager.ModifyPositionParams(-2400, 2400, 10 ether), ZERO_BYTES + modifyLiquidityRouter.modifyLiquidity( + poolKey, IPoolManager.ModifyLiquidityParams(-2400, 2400, 10 ether), ZERO_BYTES ); vm.warp(10000); diff --git a/test/V4Router.t.sol b/test/V4Router.t.sol index 684512e0..edd5e233 100644 --- a/test/V4Router.t.sol +++ b/test/V4Router.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol"; @@ -11,7 +11,7 @@ import {MockERC20} from "solmate/test/utils/mocks/MockERC20.sol"; import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; -import {PoolModifyPositionTest} from "@uniswap/v4-core/src/test/PoolModifyPositionTest.sol"; +import {PoolModifyLiquidityTest} from "@uniswap/v4-core/src/test/PoolModifyLiquidityTest.sol"; import {IV4Router} from "../contracts/interfaces/IV4Router.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {V4RouterImplementation} from "./shared/implementation/V4RouterImplementation.sol"; @@ -22,7 +22,7 @@ import {HookEnabledSwapRouter} from "./utils/HookEnabledSwapRouter.sol"; contract V4RouterTest is Test, Deployers, GasSnapshot { using CurrencyLibrary for Currency; - PoolModifyPositionTest positionManager; + PoolModifyLiquidityTest positionManager; V4RouterImplementation router; MockERC20 token0; @@ -40,7 +40,7 @@ contract V4RouterTest is Test, Deployers, GasSnapshot { deployFreshManagerAndRouters(); router = new V4RouterImplementation(manager); - positionManager = new PoolModifyPositionTest(manager); + positionManager = new PoolModifyLiquidityTest(manager); token0 = new MockERC20("Test0", "0", 18); token0.mint(address(this), 2 ** 128); @@ -358,10 +358,10 @@ contract V4RouterTest is Test, Deployers, GasSnapshot { } function setupPool(PoolKey memory poolKey) internal { - initializeRouter.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES); + manager.initialize(poolKey, SQRT_RATIO_1_1, ZERO_BYTES); MockERC20(Currency.unwrap(poolKey.currency0)).approve(address(positionManager), type(uint256).max); MockERC20(Currency.unwrap(poolKey.currency1)).approve(address(positionManager), type(uint256).max); - positionManager.modifyPosition(poolKey, IPoolManager.ModifyPositionParams(-887220, 887220, 200 ether), "0x"); + positionManager.modifyLiquidity(poolKey, IPoolManager.ModifyLiquidityParams(-887220, 887220, 200 ether), "0x"); } function toCurrency(MockERC20 token) internal pure returns (Currency) { diff --git a/test/shared/GetSender.sol b/test/shared/GetSender.sol index d1709219..ff4d06d2 100644 --- a/test/shared/GetSender.sol +++ b/test/shared/GetSender.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; contract GetSender { function sender() external view returns (address) { diff --git a/test/shared/implementation/FullRangeImplementation.sol b/test/shared/implementation/FullRangeImplementation.sol index 63592f5c..ab9c06d2 100644 --- a/test/shared/implementation/FullRangeImplementation.sol +++ b/test/shared/implementation/FullRangeImplementation.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {BaseHook} from "../../../contracts/BaseHook.sol"; import {FullRange} from "../../../contracts/hooks/examples/FullRange.sol"; diff --git a/test/shared/implementation/GeomeanOracleImplementation.sol b/test/shared/implementation/GeomeanOracleImplementation.sol index 0c964671..b13ae46d 100644 --- a/test/shared/implementation/GeomeanOracleImplementation.sol +++ b/test/shared/implementation/GeomeanOracleImplementation.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {BaseHook} from "../../../contracts/BaseHook.sol"; import {GeomeanOracle} from "../../../contracts/hooks/examples/GeomeanOracle.sol"; diff --git a/test/shared/implementation/LimitOrderImplementation.sol b/test/shared/implementation/LimitOrderImplementation.sol index c0f5a5f8..490b38b5 100644 --- a/test/shared/implementation/LimitOrderImplementation.sol +++ b/test/shared/implementation/LimitOrderImplementation.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {BaseHook} from "../../../contracts/BaseHook.sol"; import {LimitOrder} from "../../../contracts/hooks/examples/LimitOrder.sol"; diff --git a/test/shared/implementation/OracleImplementation.sol b/test/shared/implementation/OracleImplementation.sol index 7eefe3d3..dacf26ed 100644 --- a/test/shared/implementation/OracleImplementation.sol +++ b/test/shared/implementation/OracleImplementation.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {Oracle} from "../../../contracts/libraries/Oracle.sol"; diff --git a/test/shared/implementation/TWAMMImplementation.sol b/test/shared/implementation/TWAMMImplementation.sol index 27a9e10c..1eb56154 100644 --- a/test/shared/implementation/TWAMMImplementation.sol +++ b/test/shared/implementation/TWAMMImplementation.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {BaseHook} from "../../../contracts/BaseHook.sol"; import {TWAMM} from "../../../contracts/hooks/examples/TWAMM.sol"; diff --git a/test/shared/implementation/V4RouterImplementation.sol b/test/shared/implementation/V4RouterImplementation.sol index aac7fde4..a256df4b 100644 --- a/test/shared/implementation/V4RouterImplementation.sol +++ b/test/shared/implementation/V4RouterImplementation.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; import {IERC20Minimal} from "@uniswap/v4-core/src/interfaces/external/IERC20Minimal.sol"; diff --git a/test/utils/HookEnabledSwapRouter.sol b/test/utils/HookEnabledSwapRouter.sol index 54832b4a..8b18d342 100644 --- a/test/utils/HookEnabledSwapRouter.sol +++ b/test/utils/HookEnabledSwapRouter.sol @@ -36,7 +36,7 @@ contract HookEnabledSwapRouter is PoolTestBase { bytes memory hookData ) external payable returns (BalanceDelta delta) { delta = abi.decode( - manager.lock(address(this), abi.encode(CallbackData(msg.sender, testSettings, key, params, hookData))), + manager.unlock(abi.encode(CallbackData(msg.sender, testSettings, key, params, hookData))), (BalanceDelta) ); @@ -44,7 +44,7 @@ contract HookEnabledSwapRouter is PoolTestBase { if (ethBalance > 0) CurrencyLibrary.NATIVE.transfer(msg.sender, ethBalance); } - function lockAcquired(address, /*sender*/ bytes calldata rawData) external returns (bytes memory) { + function unlockCallback(bytes calldata rawData) external returns (bytes memory) { require(msg.sender == address(manager)); CallbackData memory data = abi.decode(rawData, (CallbackData));