diff --git a/src/interfaces/IQuoter.sol b/src/interfaces/IQuoter.sol index 8f113f4c..befc166a 100644 --- a/src/interfaces/IQuoter.sol +++ b/src/interfaces/IQuoter.sol @@ -7,7 +7,7 @@ import {PathKey} from "../libraries/PathKey.sol"; /// @title Quoter Interface /// @notice Supports quoting the delta amounts for exact input or exact output swaps. -/// @notice For each pool also tells you the number of initialized ticks loaded and the sqrt price of the pool after the swap. +/// @notice For each pool also tells you the sqrt price of the pool after the swap. /// @dev These functions are not marked view because they rely on calling non-view functions and reverting /// to compute the result. They are also not gas efficient and should not be called on-chain. interface IQuoter { @@ -46,10 +46,9 @@ interface IQuoter { /// hookData arbitrary hookData to pass into the associated hooks /// @return deltaAmounts Delta amounts resulted from the swap /// @return sqrtPriceX96After The sqrt price of the pool after the swap - /// @return initializedTicksLoaded The number of initialized ticks that the swap loaded function quoteExactInputSingle(QuoteExactSingleParams memory params) external - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded); + returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After); /// @notice Returns the delta amounts along the swap path for a given exact input swap /// @param params the params for the quote, encoded as 'QuoteExactParams' @@ -58,14 +57,9 @@ interface IQuoter { /// exactAmount The desired input amount /// @return deltaAmounts Delta amounts along the path resulted from the swap /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path - /// @return initializedTicksLoadedList List of the initialized ticks that the swap loaded for each pool in the path function quoteExactInput(QuoteExactParams memory params) external - returns ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ); + returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList); /// @notice Returns the delta amounts for a given exact output swap of a single pool /// @param params The params for the quote, encoded as `QuoteExactSingleParams` @@ -76,10 +70,9 @@ interface IQuoter { /// hookData arbitrary hookData to pass into the associated hooks /// @return deltaAmounts Delta amounts resulted from the swap /// @return sqrtPriceX96After The sqrt price of the pool after the swap - /// @return initializedTicksLoaded The number of initialized ticks that the swap loaded function quoteExactOutputSingle(QuoteExactSingleParams memory params) external - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded); + returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After); /// @notice Returns the delta amounts along the swap path for a given exact output swap /// @param params the params for the quote, encoded as 'QuoteExactParams' @@ -88,12 +81,7 @@ interface IQuoter { /// exactAmount The desired output amount /// @return deltaAmounts Delta amounts along the path resulted from the swap /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path - /// @return initializedTicksLoadedList List of the initialized ticks that the swap loaded for each pool in the path function quoteExactOutput(QuoteExactParams memory params) external - returns ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ); + returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList); } diff --git a/src/lens/Quoter.sol b/src/lens/Quoter.sol index 4f974194..4480ed64 100644 --- a/src/lens/Quoter.sol +++ b/src/lens/Quoter.sol @@ -8,7 +8,6 @@ import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; import {IQuoter} from "../interfaces/IQuoter.sol"; -import {PoolTicksCounter} from "../libraries/PoolTicksCounter.sol"; import {PathKey, PathKeyLibrary} from "../libraries/PathKey.sol"; import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; import {SafeCallback} from "../base/SafeCallback.sol"; @@ -21,15 +20,14 @@ contract Quoter is IQuoter, SafeCallback { /// @dev cache used to check a safety condition in exact output swaps. uint128 private amountOutCached; - /// @dev min valid reason is 6-words long (192 bytes) + /// @dev min valid reason is 5-words long (160 bytes) /// @dev int128[2] includes 32 bytes for offset, 32 bytes for length, and 32 bytes for each element - /// @dev Plus sqrtPriceX96After padded to 32 bytes and initializedTicksLoaded padded to 32 bytes - uint256 internal constant MINIMUM_VALID_RESPONSE_LENGTH = 192; + /// @dev Plus sqrtPriceX96After padded to 32 bytes + uint256 internal constant MINIMUM_VALID_RESPONSE_LENGTH = 160; struct QuoteResult { int128[] deltaAmounts; uint160[] sqrtPriceX96AfterList; - uint32[] initializedTicksLoadedList; } struct QuoteCache { @@ -37,8 +35,6 @@ contract Quoter is IQuoter, SafeCallback { uint128 prevAmount; int128 deltaIn; int128 deltaOut; - int24 tickBefore; - int24 tickAfter; Currency prevCurrency; uint160 sqrtPriceX96After; } @@ -54,7 +50,7 @@ contract Quoter is IQuoter, SafeCallback { /// @inheritdoc IQuoter function quoteExactInputSingle(QuoteExactSingleParams memory params) public - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded) + returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After) { try poolManager.unlock(abi.encodeCall(this._quoteExactInputSingle, (params))) {} catch (bytes memory reason) { @@ -65,11 +61,7 @@ contract Quoter is IQuoter, SafeCallback { /// @inheritdoc IQuoter function quoteExactInput(QuoteExactParams memory params) external - returns ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) + returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) { try poolManager.unlock(abi.encodeCall(this._quoteExactInput, (params))) {} catch (bytes memory reason) { @@ -80,7 +72,7 @@ contract Quoter is IQuoter, SafeCallback { /// @inheritdoc IQuoter function quoteExactOutputSingle(QuoteExactSingleParams memory params) public - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded) + returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After) { try poolManager.unlock(abi.encodeCall(this._quoteExactOutputSingle, (params))) {} catch (bytes memory reason) { @@ -92,11 +84,7 @@ contract Quoter is IQuoter, SafeCallback { /// @inheritdoc IQuoter function quoteExactOutput(QuoteExactParams memory params) public - returns ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) + returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) { try poolManager.unlock(abi.encodeCall(this._quoteExactOutput, (params))) {} catch (bytes memory reason) { @@ -126,44 +114,35 @@ contract Quoter is IQuoter, SafeCallback { function _handleRevertSingle(bytes memory reason) private pure - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded) + returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After) { reason = validateRevertReason(reason); - (deltaAmounts, sqrtPriceX96After, initializedTicksLoaded) = abi.decode(reason, (int128[], uint160, uint32)); + (deltaAmounts, sqrtPriceX96After) = abi.decode(reason, (int128[], uint160)); } - /// @dev parse revert bytes from a potentially multi-hop quote and return the delta amounts, sqrtPriceX96After, and initializedTicksLoaded + /// @dev parse revert bytes from a potentially multi-hop quote and return the delta amounts, and sqrtPriceX96After function _handleRevert(bytes memory reason) private pure - returns ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) + returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) { reason = validateRevertReason(reason); - (deltaAmounts, sqrtPriceX96AfterList, initializedTicksLoadedList) = - abi.decode(reason, (int128[], uint160[], uint32[])); + (deltaAmounts, sqrtPriceX96AfterList) = abi.decode(reason, (int128[], uint160[])); } /// @dev quote an ExactInput swap along a path of tokens, then revert with the result function _quoteExactInput(QuoteExactParams calldata params) public selfOnly returns (bytes memory) { uint256 pathLength = params.path.length; - QuoteResult memory result = QuoteResult({ - deltaAmounts: new int128[](pathLength + 1), - sqrtPriceX96AfterList: new uint160[](pathLength), - initializedTicksLoadedList: new uint32[](pathLength) - }); + QuoteResult memory result = + QuoteResult({deltaAmounts: new int128[](pathLength + 1), sqrtPriceX96AfterList: new uint160[](pathLength)}); QuoteCache memory cache; for (uint256 i = 0; i < pathLength; i++) { (PoolKey memory poolKey, bool zeroForOne) = params.path[i].getPoolAndSwapDirection(i == 0 ? params.exactCurrency : cache.prevCurrency); - (, cache.tickBefore,,) = poolManager.getSlot0(poolKey.toId()); - (cache.curDeltas, cache.sqrtPriceX96After, cache.tickAfter) = _swap( + (cache.curDeltas, cache.sqrtPriceX96After) = _swap( poolKey, zeroForOne, -int256(int128(i == 0 ? params.exactAmount : cache.prevAmount)), @@ -180,21 +159,16 @@ contract Quoter is IQuoter, SafeCallback { cache.prevAmount = zeroForOne ? uint128(cache.curDeltas.amount1()) : uint128(cache.curDeltas.amount0()); cache.prevCurrency = params.path[i].intermediateCurrency; result.sqrtPriceX96AfterList[i] = cache.sqrtPriceX96After; - result.initializedTicksLoadedList[i] = - PoolTicksCounter.countInitializedTicksLoaded(poolManager, poolKey, cache.tickBefore, cache.tickAfter); } - bytes memory r = - abi.encode(result.deltaAmounts, result.sqrtPriceX96AfterList, result.initializedTicksLoadedList); - assembly { - revert(add(0x20, r), mload(r)) + bytes memory encodedResult = abi.encode(result.deltaAmounts, result.sqrtPriceX96AfterList); + assembly ("memory-safe") { + revert(add(0x20, encodedResult), mload(encodedResult)) } } /// @dev quote an ExactInput swap on a pool, then revert with the result function _quoteExactInputSingle(QuoteExactSingleParams calldata params) public selfOnly returns (bytes memory) { - (, int24 tickBefore,,) = poolManager.getSlot0(params.poolKey.toId()); - - (BalanceDelta deltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap( + (BalanceDelta deltas, uint160 sqrtPriceX96After) = _swap( params.poolKey, params.zeroForOne, -int256(int128(params.exactAmount)), @@ -207,11 +181,9 @@ contract Quoter is IQuoter, SafeCallback { deltaAmounts[0] = -deltas.amount0(); deltaAmounts[1] = -deltas.amount1(); - uint32 initializedTicksLoaded = - PoolTicksCounter.countInitializedTicksLoaded(poolManager, params.poolKey, tickBefore, tickAfter); - bytes memory result = abi.encode(deltaAmounts, sqrtPriceX96After, initializedTicksLoaded); - assembly { - revert(add(0x20, result), mload(result)) + bytes memory encodedResult = abi.encode(deltaAmounts, sqrtPriceX96After); + assembly ("memory-safe") { + revert(add(0x20, encodedResult), mload(encodedResult)) } } @@ -219,11 +191,8 @@ contract Quoter is IQuoter, SafeCallback { function _quoteExactOutput(QuoteExactParams calldata params) public selfOnly returns (bytes memory) { uint256 pathLength = params.path.length; - QuoteResult memory result = QuoteResult({ - deltaAmounts: new int128[](pathLength + 1), - sqrtPriceX96AfterList: new uint160[](pathLength), - initializedTicksLoadedList: new uint32[](pathLength) - }); + QuoteResult memory result = + QuoteResult({deltaAmounts: new int128[](pathLength + 1), sqrtPriceX96AfterList: new uint160[](pathLength)}); QuoteCache memory cache; uint128 curAmountOut; @@ -235,9 +204,7 @@ contract Quoter is IQuoter, SafeCallback { params.path[i - 1], i == pathLength ? params.exactCurrency : cache.prevCurrency ); - (, cache.tickBefore,,) = poolManager.getSlot0(poolKey.toId()); - - (cache.curDeltas, cache.sqrtPriceX96After, cache.tickAfter) = + (cache.curDeltas, cache.sqrtPriceX96After) = _swap(poolKey, !oneForZero, int256(uint256(curAmountOut)), 0, params.path[i - 1].hookData); // always clear because sqrtPriceLimitX96 is set to 0 always @@ -251,13 +218,10 @@ contract Quoter is IQuoter, SafeCallback { cache.prevAmount = !oneForZero ? uint128(-cache.curDeltas.amount0()) : uint128(-cache.curDeltas.amount1()); cache.prevCurrency = params.path[i - 1].intermediateCurrency; result.sqrtPriceX96AfterList[i - 1] = cache.sqrtPriceX96After; - result.initializedTicksLoadedList[i - 1] = - PoolTicksCounter.countInitializedTicksLoaded(poolManager, poolKey, cache.tickBefore, cache.tickAfter); } - bytes memory r = - abi.encode(result.deltaAmounts, result.sqrtPriceX96AfterList, result.initializedTicksLoadedList); - assembly { - revert(add(0x20, r), mload(r)) + bytes memory encodedResult = abi.encode(result.deltaAmounts, result.sqrtPriceX96AfterList); + assembly ("memory-safe") { + revert(add(0x20, encodedResult), mload(encodedResult)) } } @@ -266,8 +230,7 @@ contract Quoter is IQuoter, SafeCallback { // if no price limit has been specified, cache the output amount for comparison inside the _swap function if (params.sqrtPriceLimitX96 == 0) amountOutCached = params.exactAmount; - (, int24 tickBefore,,) = poolManager.getSlot0(params.poolKey.toId()); - (BalanceDelta deltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap( + (BalanceDelta deltas, uint160 sqrtPriceX96After) = _swap( params.poolKey, params.zeroForOne, int256(uint256(params.exactAmount)), @@ -281,11 +244,9 @@ contract Quoter is IQuoter, SafeCallback { deltaAmounts[0] = -deltas.amount0(); deltaAmounts[1] = -deltas.amount1(); - uint32 initializedTicksLoaded = - PoolTicksCounter.countInitializedTicksLoaded(poolManager, params.poolKey, tickBefore, tickAfter); - bytes memory result = abi.encode(deltaAmounts, sqrtPriceX96After, initializedTicksLoaded); - assembly { - revert(add(0x20, result), mload(result)) + bytes memory encodedResult = abi.encode(deltaAmounts, sqrtPriceX96After); + assembly ("memory-safe") { + revert(add(0x20, encodedResult), mload(encodedResult)) } } @@ -297,7 +258,7 @@ contract Quoter is IQuoter, SafeCallback { int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes calldata hookData - ) private returns (BalanceDelta deltas, uint160 sqrtPriceX96After, int24 tickAfter) { + ) private returns (BalanceDelta deltas, uint160 sqrtPriceX96After) { deltas = poolManager.swap( poolKey, IPoolManager.SwapParams({ @@ -311,7 +272,7 @@ contract Quoter is IQuoter, SafeCallback { if (amountOutCached != 0 && amountOutCached != uint128(zeroForOne ? deltas.amount1() : deltas.amount0())) { revert InsufficientAmountOut(); } - (sqrtPriceX96After, tickAfter,,) = poolManager.getSlot0(poolKey.toId()); + (sqrtPriceX96After,,,) = poolManager.getSlot0(poolKey.toId()); } /// @dev return either the sqrtPriceLimit from user input, or the max/min value possible depending on trade direction diff --git a/src/libraries/PoolTicksCounter.sol b/src/libraries/PoolTicksCounter.sol deleted file mode 100644 index c101a22f..00000000 --- a/src/libraries/PoolTicksCounter.sol +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -pragma solidity ^0.8.0; - -import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol"; -import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; -import {PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; -import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol"; - -/// @title Pool Ticks Counter -/// @notice Functions for counting the number of initialized ticks between two ticks -library PoolTicksCounter { - using PoolIdLibrary for PoolKey; - using StateLibrary for IPoolManager; - - struct TickCache { - int16 wordPosLower; - int16 wordPosHigher; - uint8 bitPosLower; - uint8 bitPosHigher; - bool tickBeforeInitialized; - bool tickAfterInitialized; - } - - /// @notice Count the number of initialized ticks between two ticks - /// @dev This function counts the number of initialized ticks that would incur a gas cost between tickBefore and tickAfter. - /// When tickBefore and/or tickAfter themselves are initialized, the logic over whether we should count them depends on the - /// direction of the swap. If we are swapping upwards (tickAfter > tickBefore) we don't want to count tickBefore but we do - /// want to count tickAfter. The opposite is true if we are swapping downwards. - /// @param self the IPoolManager - /// @param key the PoolKey of the pool - /// @param tickBefore the tick before the swap - /// @param tickAfter the tick after the swap - /// @return initializedTicksLoaded the number of initialized ticks loaded - function countInitializedTicksLoaded(IPoolManager self, PoolKey memory key, int24 tickBefore, int24 tickAfter) - internal - view - returns (uint32 initializedTicksLoaded) - { - TickCache memory cache; - - { - // Get the key and offset in the tick bitmap of the active tick before and after the swap. - int16 wordPos = int16((tickBefore / key.tickSpacing) >> 8); - uint8 bitPos = uint8(uint24((tickBefore / key.tickSpacing) % 256)); - - int16 wordPosAfter = int16((tickAfter / key.tickSpacing) >> 8); - uint8 bitPosAfter = uint8(uint24((tickAfter / key.tickSpacing) % 256)); - - // In the case where tickAfter is initialized, we only want to count it if we are swapping downwards. - // If the initializable tick after the swap is initialized, our original tickAfter is a - // multiple of tick spacing, and we are swapping downwards we know that tickAfter is initialized - // and we shouldn't count it. - uint256 bmAfter = self.getTickBitmap(key.toId(), wordPosAfter); - cache.tickAfterInitialized = - ((bmAfter & (1 << bitPosAfter)) > 0) && ((tickAfter % key.tickSpacing) == 0) && (tickBefore > tickAfter); - - // In the case where tickBefore is initialized, we only want to count it if we are swapping upwards. - // Use the same logic as above to decide whether we should count tickBefore or not. - uint256 bmBefore = self.getTickBitmap(key.toId(), wordPos); - cache.tickBeforeInitialized = - ((bmBefore & (1 << bitPos)) > 0) && ((tickBefore % key.tickSpacing) == 0) && (tickBefore < tickAfter); - - if (wordPos < wordPosAfter || (wordPos == wordPosAfter && bitPos <= bitPosAfter)) { - cache.wordPosLower = wordPos; - cache.bitPosLower = bitPos; - cache.wordPosHigher = wordPosAfter; - cache.bitPosHigher = bitPosAfter; - } else { - cache.wordPosLower = wordPosAfter; - cache.bitPosLower = bitPosAfter; - cache.wordPosHigher = wordPos; - cache.bitPosHigher = bitPos; - } - } - - // Count the number of initialized ticks crossed by iterating through the tick bitmap. - // Our first mask should include the lower tick and everything to its left. - uint256 mask = type(uint256).max << cache.bitPosLower; - while (cache.wordPosLower <= cache.wordPosHigher) { - // If we're on the final tick bitmap page, ensure we only count up to our - // ending tick. - if (cache.wordPosLower == cache.wordPosHigher) { - mask = mask & (type(uint256).max >> (255 - cache.bitPosHigher)); - } - - uint256 bmLower = self.getTickBitmap(key.toId(), cache.wordPosLower); - uint256 masked = bmLower & mask; - initializedTicksLoaded += countOneBits(masked); - cache.wordPosLower++; - // Reset our mask so we consider all bits on the next iteration. - mask = type(uint256).max; - } - - if (cache.tickAfterInitialized) { - initializedTicksLoaded -= 1; - } - - if (cache.tickBeforeInitialized) { - initializedTicksLoaded -= 1; - } - - return initializedTicksLoaded; - } - - /// @notice Count the number of set bits in a uint256 - /// @param x the uint256 to count the bits of - function countOneBits(uint256 x) private pure returns (uint16) { - uint16 bits = 0; - while (x != 0) { - bits++; - x &= (x - 1); - } - return bits; - } -} diff --git a/test/Quoter.t.sol b/test/Quoter.t.sol index b01d9c88..074ea99d 100644 --- a/test/Quoter.t.sol +++ b/test/Quoter.t.sol @@ -84,8 +84,7 @@ contract QuoterTest is Test, Deployers { uint256 expectedAmountOut = 9871; uint160 expectedSqrtPriceX96After = 78461846509168490764501028180; - (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded) = quoter - .quoteExactInputSingle( + (int128[] memory deltaAmounts, uint160 sqrtPriceX96After) = quoter.quoteExactInputSingle( IQuoter.QuoteExactSingleParams({ poolKey: key02, zeroForOne: true, @@ -97,7 +96,6 @@ contract QuoterTest is Test, Deployers { assertEq(uint128(-deltaAmounts[1]), expectedAmountOut); assertEq(sqrtPriceX96After, expectedSqrtPriceX96After); - assertEq(initializedTicksLoaded, 2); } function testQuoter_quoteExactInputSingle_OneForZero_MultiplePositions() public { @@ -105,8 +103,7 @@ contract QuoterTest is Test, Deployers { uint256 expectedAmountOut = 9871; uint160 expectedSqrtPriceX96After = 80001962924147897865541384515; - (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded) = quoter - .quoteExactInputSingle( + (int128[] memory deltaAmounts, uint160 sqrtPriceX96After) = quoter.quoteExactInputSingle( IQuoter.QuoteExactSingleParams({ poolKey: key02, zeroForOne: false, @@ -118,7 +115,6 @@ contract QuoterTest is Test, Deployers { assertEq(uint128(-deltaAmounts[0]), expectedAmountOut); assertEq(sqrtPriceX96After, expectedSqrtPriceX96After); - assertEq(initializedTicksLoaded, 2); } // nested self-call into unlockCallback reverts @@ -133,15 +129,10 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token2); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(uint128(-deltaAmounts[1]), 9871); assertEq(sqrtPriceX96AfterList[0], 78461846509168490764501028180); - assertEq(initializedTicksLoadedList[0], 2); } function testQuoter_quoteExactInput_0to2_2TicksLoaded_initialiedAfter() public { @@ -152,15 +143,10 @@ contract QuoterTest is Test, Deployers { // -120 is an initialized tick for this pool. We check that we don't count it. IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 6200); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(uint128(-deltaAmounts[1]), 6143); assertEq(sqrtPriceX96AfterList[0], 78757224507315167622282810783); - assertEq(initializedTicksLoadedList[0], 1); } function testQuoter_quoteExactInput_0to2_1TickLoaded() public { @@ -171,15 +157,10 @@ contract QuoterTest is Test, Deployers { // -60 is an initialized tick for this pool. We check that we don't count it. IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 4000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(uint128(-deltaAmounts[1]), 3971); assertEq(sqrtPriceX96AfterList[0], 78926452400586371254602774705); - assertEq(initializedTicksLoadedList[0], 1); } function testQuoter_quoteExactInput_0to2_0TickLoaded_startingNotInitialized() public { @@ -187,15 +168,10 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token2); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(uint128(-deltaAmounts[1]), 8); assertEq(sqrtPriceX96AfterList[0], 79227483487511329217250071027); - assertEq(initializedTicksLoadedList[0], 0); } function testQuoter_quoteExactInput_0to2_0TickLoaded_startingInitialized() public { @@ -204,15 +180,10 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token2); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(uint128(-deltaAmounts[1]), 8); assertEq(sqrtPriceX96AfterList[0], 79227817515327498931091950511); - assertEq(initializedTicksLoadedList[0], 1); } function testQuoter_quoteExactInput_2to0_2TicksLoaded() public { @@ -220,15 +191,10 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token0); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(-deltaAmounts[1], 9871); assertEq(sqrtPriceX96AfterList[0], 80001962924147897865541384515); - assertEq(initializedTicksLoadedList[0], 2); } function testQuoter_quoteExactInput_2to0_2TicksLoaded_initialiedAfter() public { @@ -239,15 +205,10 @@ contract QuoterTest is Test, Deployers { // 120 is an initialized tick for this pool. We check that we don't count it. IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 6250); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(-deltaAmounts[1], 6190); assertEq(sqrtPriceX96AfterList[0], 79705728824507063507279123685); - assertEq(initializedTicksLoadedList[0], 2); } function testQuoter_quoteExactInput_2to0_0TickLoaded_startingInitialized() public { @@ -257,15 +218,10 @@ contract QuoterTest is Test, Deployers { IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 200); // Tick 0 initialized. Tick after = 1 - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(-deltaAmounts[1], 198); assertEq(sqrtPriceX96AfterList[0], 79235729830182478001034429156); - assertEq(initializedTicksLoadedList[0], 0); } // 2->0 starting not initialized @@ -274,15 +230,10 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token0); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 103); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(-deltaAmounts[1], 101); assertEq(sqrtPriceX96AfterList[0], 79235858216754624215638319723); - assertEq(initializedTicksLoadedList[0], 0); } function testQuoter_quoteExactInput_2to1() public { @@ -290,14 +241,9 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token1); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(-deltaAmounts[1], 9871); assertEq(sqrtPriceX96AfterList[0], 80018067294531553039351583520); - assertEq(initializedTicksLoadedList[0], 0); } function testQuoter_quoteExactInput_0to2to1() public { @@ -306,22 +252,15 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token1); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactInput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactInput(params); assertEq(-deltaAmounts[2], 9745); assertEq(sqrtPriceX96AfterList[0], 78461846509168490764501028180); assertEq(sqrtPriceX96AfterList[1], 80007846861567212939802016351); - assertEq(initializedTicksLoadedList[0], 2); - assertEq(initializedTicksLoadedList[1], 0); } function testQuoter_quoteExactOutputSingle_0to1() public { - (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded) = quoter - .quoteExactOutputSingle( + (int128[] memory deltaAmounts, uint160 sqrtPriceX96After) = quoter.quoteExactOutputSingle( IQuoter.QuoteExactSingleParams({ poolKey: key01, zeroForOne: true, @@ -333,12 +272,10 @@ contract QuoterTest is Test, Deployers { assertEq(deltaAmounts[0], 9981); assertEq(sqrtPriceX96After, SQRT_PRICE_100_102); - assertEq(initializedTicksLoaded, 0); } function testQuoter_quoteExactOutputSingle_1to0() public { - (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint32 initializedTicksLoaded) = quoter - .quoteExactOutputSingle( + (int128[] memory deltaAmounts, uint160 sqrtPriceX96After) = quoter.quoteExactOutputSingle( IQuoter.QuoteExactSingleParams({ poolKey: key01, zeroForOne: false, @@ -350,7 +287,6 @@ contract QuoterTest is Test, Deployers { assertEq(deltaAmounts[1], 9981); assertEq(sqrtPriceX96After, SQRT_PRICE_102_100); - assertEq(initializedTicksLoaded, 0); } function testQuoter_quoteExactOutput_0to2_2TicksLoaded() public { @@ -358,15 +294,10 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token2); IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 15000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 15273); assertEq(sqrtPriceX96AfterList[0], 78055527257643669242286029831); - assertEq(initializedTicksLoadedList[0], 2); } function testQuoter_quoteExactOutput_0to2_1TickLoaded_initialiedAfter() public { @@ -375,15 +306,10 @@ contract QuoterTest is Test, Deployers { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 6143); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 6200); assertEq(sqrtPriceX96AfterList[0], 78757225449310403327341205211); - assertEq(initializedTicksLoadedList[0], 1); } function testQuoter_quoteExactOutput_0to2_1TickLoaded() public { @@ -392,15 +318,10 @@ contract QuoterTest is Test, Deployers { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 4000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 4029); assertEq(sqrtPriceX96AfterList[0], 78924219757724709840818372098); - assertEq(initializedTicksLoadedList[0], 1); } function testQuoter_quoteExactOutput_0to2_0TickLoaded_startingInitialized() public { @@ -411,15 +332,10 @@ contract QuoterTest is Test, Deployers { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 100); // Tick 0 initialized. Tick after = 1 - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 102); assertEq(sqrtPriceX96AfterList[0], 79224329176051641448521403903); - assertEq(initializedTicksLoadedList[0], 1); } function testQuoter_quoteExactOutput_0to2_0TickLoaded_startingNotInitialized() public { @@ -428,15 +344,10 @@ contract QuoterTest is Test, Deployers { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 10); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 12); assertEq(sqrtPriceX96AfterList[0], 79227408033628034983534698435); - assertEq(initializedTicksLoadedList[0], 0); } function testQuoter_quoteExactOutput_2to0_2TicksLoaded() public { @@ -444,16 +355,10 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token0); IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 15000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 15273); assertEq(sqrtPriceX96AfterList[0], 80418414376567919517220409857); - assertEq(initializedTicksLoadedList.length, 1); - assertEq(initializedTicksLoadedList[0], 2); } function testQuoter_quoteExactOutput_2to0_2TicksLoaded_initialiedAfter() public { @@ -462,16 +367,10 @@ contract QuoterTest is Test, Deployers { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 6223); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 6283); assertEq(sqrtPriceX96AfterList[0], 79708304437530892332449657932); - assertEq(initializedTicksLoadedList.length, 1); - assertEq(initializedTicksLoadedList[0], 2); } function testQuoter_quoteExactOutput_2to0_1TickLoaded() public { @@ -479,16 +378,10 @@ contract QuoterTest is Test, Deployers { tokenPath.push(token0); IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 6000); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 6055); assertEq(sqrtPriceX96AfterList[0], 79690640184021170956740081887); - assertEq(initializedTicksLoadedList.length, 1); - assertEq(initializedTicksLoadedList[0], 1); } function testQuoter_quoteExactOutput_2to1() public { @@ -497,16 +390,10 @@ contract QuoterTest is Test, Deployers { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 9871); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 10000); assertEq(sqrtPriceX96AfterList[0], 80018020393569259756601362385); - assertEq(initializedTicksLoadedList.length, 1); - assertEq(initializedTicksLoadedList[0], 0); } function testQuoter_quoteExactOutput_0to2to1() public { @@ -516,20 +403,13 @@ contract QuoterTest is Test, Deployers { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 9745); - ( - int128[] memory deltaAmounts, - uint160[] memory sqrtPriceX96AfterList, - uint32[] memory initializedTicksLoadedList - ) = quoter.quoteExactOutput(params); + (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList) = quoter.quoteExactOutput(params); assertEq(deltaAmounts[0], 10000); assertEq(deltaAmounts[1], 0); assertEq(deltaAmounts[2], -9745); assertEq(sqrtPriceX96AfterList[0], 78461888503179331029803316753); assertEq(sqrtPriceX96AfterList[1], 80007838904387594703933785072); - assertEq(initializedTicksLoadedList.length, 2); - assertEq(initializedTicksLoadedList[0], 2); - assertEq(initializedTicksLoadedList[1], 0); } function createPoolKey(MockERC20 tokenA, MockERC20 tokenB, address hookAddr)