diff --git a/.forge-snapshots/BinNativePancakeSwapV4Test#test_v4BinSwap_ExactInSingle_NativeIn.snap b/.forge-snapshots/BinNativePancakeSwapV4Test#test_v4BinSwap_ExactInSingle_NativeIn.snap index e698b19..e241edf 100644 --- a/.forge-snapshots/BinNativePancakeSwapV4Test#test_v4BinSwap_ExactInSingle_NativeIn.snap +++ b/.forge-snapshots/BinNativePancakeSwapV4Test#test_v4BinSwap_ExactInSingle_NativeIn.snap @@ -1 +1 @@ -145907 \ No newline at end of file +145982 \ No newline at end of file diff --git a/.forge-snapshots/BinNativePancakeSwapV4Test#test_v4BinSwap_ExactInSingle_NativeOut_RouterRecipient.snap b/.forge-snapshots/BinNativePancakeSwapV4Test#test_v4BinSwap_ExactInSingle_NativeOut_RouterRecipient.snap index 13ea203..7a5cf79 100644 --- a/.forge-snapshots/BinNativePancakeSwapV4Test#test_v4BinSwap_ExactInSingle_NativeOut_RouterRecipient.snap +++ b/.forge-snapshots/BinNativePancakeSwapV4Test#test_v4BinSwap_ExactInSingle_NativeOut_RouterRecipient.snap @@ -1 +1 @@ -122802 \ No newline at end of file +122905 \ No newline at end of file diff --git a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactInSingle.snap b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactInSingle.snap index 174998c..028a4ef 100644 --- a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactInSingle.snap +++ b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactInSingle.snap @@ -1 +1 @@ -146869 \ No newline at end of file +146944 \ No newline at end of file diff --git a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactIn_MultiHop.snap b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactIn_MultiHop.snap index ae5dabf..06443ee 100644 --- a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactIn_MultiHop.snap +++ b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactIn_MultiHop.snap @@ -1 +1 @@ -178278 \ No newline at end of file +178353 \ No newline at end of file diff --git a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactIn_SingleHop.snap b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactIn_SingleHop.snap index 17fc682..87c0046 100644 --- a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactIn_SingleHop.snap +++ b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactIn_SingleHop.snap @@ -1 +1 @@ -148663 \ No newline at end of file +148738 \ No newline at end of file diff --git a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactOut_MultiHop.snap b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactOut_MultiHop.snap index 1bc9c0c..e61095b 100644 --- a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactOut_MultiHop.snap +++ b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactOut_MultiHop.snap @@ -1 +1 @@ -182089 \ No newline at end of file +182159 \ No newline at end of file diff --git a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactOut_SingleHop.snap b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactOut_SingleHop.snap index e2ad321..cb48d03 100644 --- a/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactOut_SingleHop.snap +++ b/.forge-snapshots/BinPancakeSwapV4Test#test_v4BinSwap_ExactOut_SingleHop.snap @@ -1 +1 @@ -153006 \ No newline at end of file +153076 \ No newline at end of file diff --git a/.forge-snapshots/BinPancakeSwapV4Test#test_v4ClSwap_ExactOutSingle.snap b/.forge-snapshots/BinPancakeSwapV4Test#test_v4ClSwap_ExactOutSingle.snap index b64a453..04b5f6d 100644 --- a/.forge-snapshots/BinPancakeSwapV4Test#test_v4ClSwap_ExactOutSingle.snap +++ b/.forge-snapshots/BinPancakeSwapV4Test#test_v4ClSwap_ExactOutSingle.snap @@ -1 +1 @@ -151202 \ No newline at end of file +151291 \ No newline at end of file diff --git a/.forge-snapshots/CLNativePancakeSwapV4Test#test_v4ClSwap_ExactInSingle_NativeIn.snap b/.forge-snapshots/CLNativePancakeSwapV4Test#test_v4ClSwap_ExactInSingle_NativeIn.snap index 53e2d33..afb341f 100644 --- a/.forge-snapshots/CLNativePancakeSwapV4Test#test_v4ClSwap_ExactInSingle_NativeIn.snap +++ b/.forge-snapshots/CLNativePancakeSwapV4Test#test_v4ClSwap_ExactInSingle_NativeIn.snap @@ -1 +1 @@ -172507 \ No newline at end of file +172582 \ No newline at end of file diff --git a/.forge-snapshots/CLNativePancakeSwapV4Test#test_v4ClSwap_ExactInSingle_NativeOut.snap b/.forge-snapshots/CLNativePancakeSwapV4Test#test_v4ClSwap_ExactInSingle_NativeOut.snap index c82ee89..581658f 100644 --- a/.forge-snapshots/CLNativePancakeSwapV4Test#test_v4ClSwap_ExactInSingle_NativeOut.snap +++ b/.forge-snapshots/CLNativePancakeSwapV4Test#test_v4ClSwap_ExactInSingle_NativeOut.snap @@ -1 +1 @@ -174511 \ No newline at end of file +174586 \ No newline at end of file diff --git a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactInSingle.snap b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactInSingle.snap index b7868d8..ef5e57a 100644 --- a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactInSingle.snap +++ b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactInSingle.snap @@ -1 +1 @@ -181873 \ No newline at end of file +181948 \ No newline at end of file diff --git a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactIn_MultiHop.snap b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactIn_MultiHop.snap index 597920d..d49e626 100644 --- a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactIn_MultiHop.snap +++ b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactIn_MultiHop.snap @@ -1 +1 @@ -247743 \ No newline at end of file +247830 \ No newline at end of file diff --git a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactIn_SingleHop.snap b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactIn_SingleHop.snap index 0072dcd..cb2505b 100644 --- a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactIn_SingleHop.snap +++ b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactIn_SingleHop.snap @@ -1 +1 @@ -183378 \ No newline at end of file +183465 \ No newline at end of file diff --git a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOutSingle.snap b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOutSingle.snap index e453451..8df078e 100644 --- a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOutSingle.snap +++ b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOutSingle.snap @@ -1 +1 @@ -185675 \ No newline at end of file +185764 \ No newline at end of file diff --git a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOut_MultiHop.snap b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOut_MultiHop.snap index 5784df7..8446f8f 100644 --- a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOut_MultiHop.snap +++ b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOut_MultiHop.snap @@ -1 +1 @@ -250542 \ No newline at end of file +250612 \ No newline at end of file diff --git a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOut_SingleHop.snap b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOut_SingleHop.snap index 5c6fe35..ebbb9d7 100644 --- a/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOut_SingleHop.snap +++ b/.forge-snapshots/CLPancakeSwapV4Test#test_v4ClSwap_ExactOut_SingleHop.snap @@ -1 +1 @@ -187221 \ No newline at end of file +187291 \ No newline at end of file diff --git a/.forge-snapshots/PancakeSwapV2Test#test_v2Swap_exactOutput0For1.snap b/.forge-snapshots/PancakeSwapV2Test#test_v2Swap_exactOutput0For1.snap index 75fce7e..b0ac48d 100644 --- a/.forge-snapshots/PancakeSwapV2Test#test_v2Swap_exactOutput0For1.snap +++ b/.forge-snapshots/PancakeSwapV2Test#test_v2Swap_exactOutput0For1.snap @@ -1 +1 @@ -100775 \ No newline at end of file +117028 \ No newline at end of file diff --git a/.forge-snapshots/StableSwapTest#test_stableSwap_ExactInput0For1.snap b/.forge-snapshots/StableSwapTest#test_stableSwap_ExactInput0For1.snap index 96cbd62..cf74b44 100644 --- a/.forge-snapshots/StableSwapTest#test_stableSwap_ExactInput0For1.snap +++ b/.forge-snapshots/StableSwapTest#test_stableSwap_ExactInput0For1.snap @@ -1 +1 @@ -193236 \ No newline at end of file +193217 \ No newline at end of file diff --git a/.forge-snapshots/StableSwapTest#test_stableSwap_ExactInput1For0.snap b/.forge-snapshots/StableSwapTest#test_stableSwap_ExactInput1For0.snap index e6b8e24..0055f2d 100644 --- a/.forge-snapshots/StableSwapTest#test_stableSwap_ExactInput1For0.snap +++ b/.forge-snapshots/StableSwapTest#test_stableSwap_ExactInput1For0.snap @@ -1 +1 @@ -192692 \ No newline at end of file +192673 \ No newline at end of file diff --git a/.forge-snapshots/UniversalRouterBytecodeSize.snap b/.forge-snapshots/UniversalRouterBytecodeSize.snap index baa08c6..218c26b 100644 --- a/.forge-snapshots/UniversalRouterBytecodeSize.snap +++ b/.forge-snapshots/UniversalRouterBytecodeSize.snap @@ -1 +1 @@ -23397 \ No newline at end of file +23464 \ No newline at end of file diff --git a/.forge-snapshots/V3ToV4MigrationNativeTest#test_v4CLPositionmanager_Mint_Native.snap b/.forge-snapshots/V3ToV4MigrationNativeTest#test_v4CLPositionmanager_Mint_Native.snap index 674c397..87b8a5a 100644 --- a/.forge-snapshots/V3ToV4MigrationNativeTest#test_v4CLPositionmanager_Mint_Native.snap +++ b/.forge-snapshots/V3ToV4MigrationNativeTest#test_v4CLPositionmanager_Mint_Native.snap @@ -1 +1 @@ -607626 \ No newline at end of file +606007 \ No newline at end of file diff --git a/.forge-snapshots/V3ToV4MigrationTest#test_v4BinPositionmanager_BinAddLiquidity.snap b/.forge-snapshots/V3ToV4MigrationTest#test_v4BinPositionmanager_BinAddLiquidity.snap index 604564b..2ef41c2 100644 --- a/.forge-snapshots/V3ToV4MigrationTest#test_v4BinPositionmanager_BinAddLiquidity.snap +++ b/.forge-snapshots/V3ToV4MigrationTest#test_v4BinPositionmanager_BinAddLiquidity.snap @@ -1 +1 @@ -594494 \ No newline at end of file +593395 \ No newline at end of file diff --git a/.forge-snapshots/V3ToV4MigrationTest#test_v4BinPositionmanager_BinAddLiquidity_Native.snap b/.forge-snapshots/V3ToV4MigrationTest#test_v4BinPositionmanager_BinAddLiquidity_Native.snap index 6081009..0570d7a 100644 --- a/.forge-snapshots/V3ToV4MigrationTest#test_v4BinPositionmanager_BinAddLiquidity_Native.snap +++ b/.forge-snapshots/V3ToV4MigrationTest#test_v4BinPositionmanager_BinAddLiquidity_Native.snap @@ -1 +1 @@ -570249 \ No newline at end of file +569221 \ No newline at end of file diff --git a/.forge-snapshots/V3ToV4MigrationTest#test_v4CLPositionmanager_Mint.snap b/.forge-snapshots/V3ToV4MigrationTest#test_v4CLPositionmanager_Mint.snap index e6b160d..df4f50e 100644 --- a/.forge-snapshots/V3ToV4MigrationTest#test_v4CLPositionmanager_Mint.snap +++ b/.forge-snapshots/V3ToV4MigrationTest#test_v4CLPositionmanager_Mint.snap @@ -1 +1 @@ -631883 \ No newline at end of file +630193 \ No newline at end of file diff --git a/lib/pancake-v4-periphery b/lib/pancake-v4-periphery index cfc2125..5a904ec 160000 --- a/lib/pancake-v4-periphery +++ b/lib/pancake-v4-periphery @@ -1 +1 @@ -Subproject commit cfc2125fb47219bbb6dd8d0cdeb8cb5ffe195c53 +Subproject commit 5a904ecdd6b445fc88d600bcf659209f534ad589 diff --git a/src/base/Dispatcher.sol b/src/base/Dispatcher.sol index ea6a441..9fbfb6f 100755 --- a/src/base/Dispatcher.sol +++ b/src/base/Dispatcher.sol @@ -16,6 +16,7 @@ import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol" import {IERC721Permit} from "pancake-v4-periphery/src/pool-cl/interfaces/IERC721Permit.sol"; import {ActionConstants} from "pancake-v4-periphery/src/libraries/ActionConstants.sol"; import {BaseActionsRouter} from "pancake-v4-periphery/src/base/BaseActionsRouter.sol"; +import {CalldataDecoder} from "pancake-v4-periphery/src/libraries/CalldataDecoder.sol"; /// @title Decodes and Executes Commands /// @notice Called by the UniversalRouter contract to efficiently decode and execute a singular command @@ -29,6 +30,7 @@ abstract contract Dispatcher is Lock { using BytesLib for bytes; + using CalldataDecoder for bytes; error InvalidCommandType(uint256 commandType); error BalanceTooLow(); @@ -293,8 +295,7 @@ abstract contract Dispatcher is } else { // 0x21 <= command if (command == Commands.EXECUTE_SUB_PLAN) { - bytes calldata _commands = inputs.toBytes(0); - bytes[] calldata _inputs = inputs.toBytesArray(1); + (bytes calldata _commands, bytes[] calldata _inputs) = inputs.decodeCommandsAndInputs(); (success, output) = (address(this)).call(abi.encodeCall(Dispatcher.execute, (_commands, _inputs))); } else if (command == Commands.STABLE_SWAP_EXACT_IN) { // equivalent: abi.decode(inputs, (address, uint256, uint256, bytes, bytes, bool)) diff --git a/src/libraries/BytesLib.sol b/src/libraries/BytesLib.sol index 426d1ed..0b51305 100755 --- a/src/libraries/BytesLib.sol +++ b/src/libraries/BytesLib.sol @@ -4,8 +4,11 @@ pragma solidity ^0.8.0; import {Constants} from "./Constants.sol"; +import {CalldataDecoder} from "pancake-v4-periphery/src/libraries/CalldataDecoder.sol"; library BytesLib { + using CalldataDecoder for bytes; + error SliceOutOfBounds(); /// @notice Returns the address starting at byte 0 @@ -35,57 +38,11 @@ library BytesLib { } } - /// @notice Decode the `_arg`-th element in `_bytes` as a dynamic array - /// @dev The decoding of `length` and `offset` is universal, - /// whereas the type declaration of `res` instructs the compiler how to read it. - /// @param _bytes The input bytes string to slice - /// @param _arg The index of the argument to extract - /// @return length Length of the array - /// @return offset Pointer to the data part of the array - function toLengthOffset(bytes calldata _bytes, uint256 _arg) - internal - pure - returns (uint256 length, uint256 offset) - { - uint256 relativeOffset; - assembly { - // The offset of the `_arg`-th element is `32 * arg`, which stores the offset of the length pointer. - // shl(5, x) is equivalent to mul(32, x) - let lengthPtr := add(_bytes.offset, calldataload(add(_bytes.offset, shl(5, _arg)))) - length := calldataload(lengthPtr) - offset := add(lengthPtr, 0x20) - relativeOffset := sub(offset, _bytes.offset) - } - if (_bytes.length < length + relativeOffset) revert SliceOutOfBounds(); - } - - /// @notice Decode the `_arg`-th element in `_bytes` as `bytes` - /// @param _bytes The input bytes string to extract a bytes string from - /// @param _arg The index of the argument to extract - function toBytes(bytes calldata _bytes, uint256 _arg) internal pure returns (bytes calldata res) { - (uint256 length, uint256 offset) = toLengthOffset(_bytes, _arg); - assembly { - res.length := length - res.offset := offset - } - } - /// @notice Decode the `_arg`-th element in `_bytes` as `address[]` /// @param _bytes The input bytes string to extract an address array from /// @param _arg The index of the argument to extract function toAddressArray(bytes calldata _bytes, uint256 _arg) internal pure returns (address[] calldata res) { - (uint256 length, uint256 offset) = toLengthOffset(_bytes, _arg); - assembly { - res.length := length - res.offset := offset - } - } - - /// @notice Decode the `_arg`-th element in `_bytes` as `bytes[]` - /// @param _bytes The input bytes string to extract a bytes array from - /// @param _arg The index of the argument to extract - function toBytesArray(bytes calldata _bytes, uint256 _arg) internal pure returns (bytes[] calldata res) { - (uint256 length, uint256 offset) = toLengthOffset(_bytes, _arg); + (uint256 length, uint256 offset) = _bytes.toLengthOffset(_arg); assembly { res.length := length res.offset := offset @@ -96,10 +53,16 @@ library BytesLib { /// @param _bytes The input bytes string to extract an uint array from /// @param _arg The index of the argument to extract function toUintArray(bytes calldata _bytes, uint256 _arg) internal pure returns (uint256[] calldata res) { - (uint256 length, uint256 offset) = toLengthOffset(_bytes, _arg); + (uint256 length, uint256 offset) = _bytes.toLengthOffset(_arg); assembly { res.length := length res.offset := offset } } + + /// @notice Equivalent to abi.decode(bytes, bytes[]) + /// @param _bytes The input bytes string to extract an parameters from + function decodeCommandsAndInputs(bytes calldata _bytes) internal pure returns (bytes calldata, bytes[] calldata) { + return _bytes.decodeActionsRouterParams(); + } } diff --git a/src/modules/pancakeswap/v3/V3SwapRouter.sol b/src/modules/pancakeswap/v3/V3SwapRouter.sol index 74f5087..3a5b492 100755 --- a/src/modules/pancakeswap/v3/V3SwapRouter.sol +++ b/src/modules/pancakeswap/v3/V3SwapRouter.sol @@ -11,11 +11,13 @@ import {UniversalRouterHelper} from "../../../libraries/UniversalRouterHelper.so import {RouterImmutables} from "../../../base/RouterImmutables.sol"; import {Permit2Payments} from "../../Permit2Payments.sol"; import {ERC20} from "solmate/src/tokens/ERC20.sol"; +import {CalldataDecoder} from "pancake-v4-periphery/src/libraries/CalldataDecoder.sol"; /// @title Router for PancakeSwap v3 Trades abstract contract V3SwapRouter is RouterImmutables, Permit2Payments, IPancakeV3SwapCallback { using UniversalRouterHelper for bytes; using BytesLib for bytes; + using CalldataDecoder for bytes; using SafeCast for uint256; error V3InvalidSwap(); diff --git a/test/V3ToV4Migration.t.sol b/test/V3ToV4Migration.t.sol index 4bac469..19e5048 100644 --- a/test/V3ToV4Migration.t.sol +++ b/test/V3ToV4Migration.t.sol @@ -123,7 +123,7 @@ contract V3ToV4MigrationTest is BasePancakeSwapV4, OldVersionHelper, BinLiquidit _approvePermit2ForCurrency(address(this), currency0, address(binPositionManager), permit2); _approvePermit2ForCurrency(address(this), currency1, address(binPositionManager), permit2); - clPositionManager = new CLPositionManager(vault, clPoolManager, permit2); + clPositionManager = new CLPositionManager(vault, clPoolManager, permit2, 100_000); _approvePermit2ForCurrency(address(this), currency0, address(clPositionManager), permit2); _approvePermit2ForCurrency(address(this), currency1, address(clPositionManager), permit2); diff --git a/test/V3ToV4MigrationNative.t.sol b/test/V3ToV4MigrationNative.t.sol index a7361c3..b0c5a4e 100644 --- a/test/V3ToV4MigrationNative.t.sol +++ b/test/V3ToV4MigrationNative.t.sol @@ -92,7 +92,7 @@ contract V3ToV4MigrationNativeTest is BasePancakeSwapV4, OldVersionHelper, BinLi binPositionManager = new BinPositionManager(vault, binPoolManager, permit2); _approvePermit2ForCurrency(address(this), currency1, address(binPositionManager), permit2); - clPositionManager = new CLPositionManager(vault, clPoolManager, permit2); + clPositionManager = new CLPositionManager(vault, clPoolManager, permit2, 100_000); _approvePermit2ForCurrency(address(this), currency1, address(clPositionManager), permit2); clPoolKey = PoolKey({ diff --git a/test/v4/CLNativePancakeSwapV4.t.sol b/test/v4/CLNativePancakeSwapV4.t.sol index 32fdc41..c2a8047 100644 --- a/test/v4/CLNativePancakeSwapV4.t.sol +++ b/test/v4/CLNativePancakeSwapV4.t.sol @@ -64,7 +64,7 @@ contract CLNativePancakeSwapV4Test is BasePancakeSwapV4 { token1 = MockERC20(Currency.unwrap(currency1)); - positionManager = new CLPositionManager(vault, poolManager, permit2); + positionManager = new CLPositionManager(vault, poolManager, permit2, 100_000); _approvePermit2ForCurrency(address(this), currency1, address(positionManager), permit2); RouterParameters memory params = RouterParameters({ diff --git a/test/v4/CLPancakeSwapV4.t.sol b/test/v4/CLPancakeSwapV4.t.sol index eba5265..d84e195 100644 --- a/test/v4/CLPancakeSwapV4.t.sol +++ b/test/v4/CLPancakeSwapV4.t.sol @@ -70,7 +70,7 @@ contract CLPancakeSwapV4Test is BasePancakeSwapV4 { token1 = MockERC20(Currency.unwrap(currency1)); token2 = MockERC20(Currency.unwrap(currency2)); - positionManager = new CLPositionManager(vault, poolManager, permit2); + positionManager = new CLPositionManager(vault, poolManager, permit2, 100_000); _approvePermit2ForCurrency(address(this), currency0, address(positionManager), permit2); _approvePermit2ForCurrency(address(this), currency1, address(positionManager), permit2); _approvePermit2ForCurrency(address(this), currency2, address(positionManager), permit2);