diff --git a/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap b/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap index 4991aadb..6bf2a2fc 100644 --- a/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap +++ b/.forge-snapshots/Quoter_exactInputSingle_oneForZero_multiplePositions.snap @@ -1 +1 @@ -149088 \ No newline at end of file +147574 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap b/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap index e5627475..3db18e7f 100644 --- a/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap +++ b/.forge-snapshots/Quoter_exactInputSingle_zeroForOne_multiplePositions.snap @@ -1 +1 @@ -154572 \ No newline at end of file +153033 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap b/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap index 06e1cd8c..6c17678a 100644 --- a/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap +++ b/.forge-snapshots/Quoter_exactOutputSingle_oneForZero.snap @@ -1 +1 @@ -83716 \ No newline at end of file +82272 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap b/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap index d6dbd4be..fc23876a 100644 --- a/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap +++ b/.forge-snapshots/Quoter_exactOutputSingle_zeroForOne.snap @@ -1 +1 @@ -88524 \ No newline at end of file +87066 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap index 4c00c495..1037859a 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_1TickLoaded.snap @@ -1 +1 @@ -127764 \ No newline at end of file +125376 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap index 287ba61d..4fc87472 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_initializedAfter.snap @@ -1 +1 @@ -152656 \ No newline at end of file +150285 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap b/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap index e4a3fc7d..d6995e55 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_oneHop_startingInitialized.snap @@ -1 +1 @@ -86679 \ No newline at end of file +84308 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap b/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap index 6656c916..383f0ac8 100644 --- a/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap +++ b/.forge-snapshots/Quoter_quoteExactInput_twoHops.snap @@ -1 +1 @@ -210976 \ No newline at end of file +207585 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap index 70adf0b9..675b2093 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_1TickLoaded.snap @@ -1 +1 @@ -147458 \ No newline at end of file +145077 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap index ac5a8933..e5b91ef0 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_2TicksLoaded.snap @@ -1 +1 @@ -177595 \ No newline at end of file +175214 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap index 012cb790..7d83e832 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_initializedAfter.snap @@ -1 +1 @@ -147526 \ No newline at end of file +145145 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap index cbec599b..48826398 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_oneHop_startingInitialized.snap @@ -1 +1 @@ -124225 \ No newline at end of file +121844 \ No newline at end of file diff --git a/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap b/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap index d8c5ead7..3f1771b0 100644 --- a/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap +++ b/.forge-snapshots/Quoter_quoteExactOutput_twoHops.snap @@ -1 +1 @@ -251247 \ No newline at end of file +247853 \ No newline at end of file diff --git a/src/interfaces/IQuoter.sol b/src/interfaces/IQuoter.sol index 01cd6eb7..fc9ea66b 100644 --- a/src/interfaces/IQuoter.sol +++ b/src/interfaces/IQuoter.sol @@ -43,22 +43,22 @@ interface IQuoter { /// exactAmount The desired input amount /// sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// hookData arbitrary hookData to pass into the associated hooks - /// @return deltaAmounts Delta amounts resulted from the swap + /// @return amountOut The output quote for the exactIn swap /// @return sqrtPriceX96After The sqrt price of the pool after the swap function quoteExactInputSingle(QuoteExactSingleParams memory params) external - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint256 gasEstimate); + returns (uint256 amountOut, uint160 sqrtPriceX96After, uint256 gasEstimate); /// @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' /// currencyIn The input currency of the swap /// path The path of the swap encoded as PathKeys that contains currency, fee, tickSpacing, and hook info /// exactAmount The desired input amount - /// @return deltaAmounts Delta amounts along the path resulted from the swap + /// @return amountOut The output quote for the exactIn swap /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path function quoteExactInput(QuoteExactParams memory params) external - returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList, uint256 gasEstimate); + returns (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList, uint256 gasEstimate); /// @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` @@ -67,20 +67,20 @@ interface IQuoter { /// exactAmount The desired output amount /// sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// hookData arbitrary hookData to pass into the associated hooks - /// @return deltaAmounts Delta amounts resulted from the swap + /// @return amountIn The input quote for the exactOut swap /// @return sqrtPriceX96After The sqrt price of the pool after the swap function quoteExactOutputSingle(QuoteExactSingleParams memory params) external - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint256 gasEstimate); + returns (uint256 amountIn, uint160 sqrtPriceX96After, uint256 gasEstimate); /// @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' /// currencyOut The output currency of the swap /// path The path of the swap encoded as PathKeys that contains currency, fee, tickSpacing, and hook info /// exactAmount The desired output amount - /// @return deltaAmounts Delta amounts along the path resulted from the swap + /// @return amountIn The input quote for the exactOut swap /// @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path function quoteExactOutput(QuoteExactParams memory params) external - returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList, uint256 gasEstimate); + returns (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList, uint256 gasEstimate); } diff --git a/src/lens/Quoter.sol b/src/lens/Quoter.sol index c5a75a9a..e5ab9e12 100644 --- a/src/lens/Quoter.sol +++ b/src/lens/Quoter.sol @@ -22,11 +22,6 @@ contract Quoter is IQuoter, SafeCallback { /// @dev cache used to check a safety condition in exact output swaps. uint128 private amountOutCached; - struct QuoteResult { - int128[] deltaAmounts; - uint160[] sqrtPriceX96AfterList; - } - /// @dev Only this address may call this function. Used to mimic internal functions, using an /// external call to catch and parse revert reasons modifier selfOnly() { @@ -39,53 +34,53 @@ contract Quoter is IQuoter, SafeCallback { /// @inheritdoc IQuoter function quoteExactInputSingle(QuoteExactSingleParams memory params) external - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint256 gasEstimate) + returns (uint256 amountOut, uint160 sqrtPriceX96After, uint256 gasEstimate) { uint256 gasBefore = gasleft(); try poolManager.unlock(abi.encodeCall(this._quoteExactInputSingle, (params))) {} catch (bytes memory reason) { gasEstimate = gasBefore - gasleft(); - (deltaAmounts, sqrtPriceX96After) = reason.parseReturnDataSingle(); + (amountOut, sqrtPriceX96After) = reason.parseReturnDataSingle(); } } /// @inheritdoc IQuoter function quoteExactInput(QuoteExactParams memory params) external - returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList, uint256 gasEstimate) + returns (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList, uint256 gasEstimate) { uint256 gasBefore = gasleft(); try poolManager.unlock(abi.encodeCall(this._quoteExactInput, (params))) {} catch (bytes memory reason) { gasEstimate = gasBefore - gasleft(); - (deltaAmounts, sqrtPriceX96AfterList) = reason.parseReturnData(); + (amountOut, sqrtPriceX96AfterList) = reason.parseReturnData(); } } /// @inheritdoc IQuoter function quoteExactOutputSingle(QuoteExactSingleParams memory params) external - returns (int128[] memory deltaAmounts, uint160 sqrtPriceX96After, uint256 gasEstimate) + returns (uint256 amountIn, uint160 sqrtPriceX96After, uint256 gasEstimate) { uint256 gasBefore = gasleft(); try poolManager.unlock(abi.encodeCall(this._quoteExactOutputSingle, (params))) {} catch (bytes memory reason) { gasEstimate = gasBefore - gasleft(); if (params.sqrtPriceLimitX96 == 0) delete amountOutCached; - (deltaAmounts, sqrtPriceX96After) = reason.parseReturnDataSingle(); + (amountIn, sqrtPriceX96After) = reason.parseReturnDataSingle(); } } /// @inheritdoc IQuoter function quoteExactOutput(QuoteExactParams memory params) external - returns (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList, uint256 gasEstimate) + returns (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList, uint256 gasEstimate) { uint256 gasBefore = gasleft(); try poolManager.unlock(abi.encodeCall(this._quoteExactOutput, (params))) {} catch (bytes memory reason) { gasEstimate = gasBefore - gasleft(); - (deltaAmounts, sqrtPriceX96AfterList) = reason.parseReturnData(); + (amountIn, sqrtPriceX96AfterList) = reason.parseReturnData(); } } @@ -101,8 +96,7 @@ contract Quoter is IQuoter, SafeCallback { function _quoteExactInput(QuoteExactParams calldata params) external selfOnly returns (bytes memory) { uint256 pathLength = params.path.length; - QuoteResult memory result = - QuoteResult({deltaAmounts: new int128[](pathLength + 1), sqrtPriceX96AfterList: new uint160[](pathLength)}); + uint160[] memory sqrtPriceX96AfterList = new uint160[](pathLength); BalanceDelta swapDelta; uint128 amountIn = params.exactAmount; Currency inputCurrency = params.exactCurrency; @@ -112,21 +106,14 @@ contract Quoter is IQuoter, SafeCallback { pathKey = params.path[i]; (PoolKey memory poolKey, bool zeroForOne) = pathKey.getPoolAndSwapDirection(inputCurrency); - (swapDelta, result.sqrtPriceX96AfterList[i]) = + (swapDelta, sqrtPriceX96AfterList[i]) = _swap(poolKey, zeroForOne, -int256(int128(amountIn)), 0, pathKey.hookData); - if (zeroForOne) { - result.deltaAmounts[i] += -swapDelta.amount0(); - result.deltaAmounts[i + 1] += -swapDelta.amount1(); - amountIn = uint128(swapDelta.amount1()); - } else { - result.deltaAmounts[i] += -swapDelta.amount1(); - result.deltaAmounts[i + 1] += -swapDelta.amount0(); - amountIn = uint128(swapDelta.amount0()); - } + amountIn = zeroForOne ? uint128(swapDelta.amount1()) : uint128(swapDelta.amount0()); inputCurrency = pathKey.intermediateCurrency; } - bytes memory encodedResult = abi.encode(result.deltaAmounts, result.sqrtPriceX96AfterList); + // amountIn after the loop actually holds the amountOut of the trade + bytes memory encodedResult = abi.encode(amountIn, sqrtPriceX96AfterList); encodedResult.revertWith(); } @@ -140,12 +127,10 @@ contract Quoter is IQuoter, SafeCallback { params.hookData ); - int128[] memory deltaAmounts = new int128[](2); - - deltaAmounts[0] = -deltas.amount0(); - deltaAmounts[1] = -deltas.amount1(); + // the output delta of a swap is positive + uint256 amountOut = params.zeroForOne ? uint128(deltas.amount1()) : uint128(deltas.amount0()); - bytes memory encodedResult = abi.encode(deltaAmounts, sqrtPriceX96After); + bytes memory encodedResult = abi.encode(amountOut, sqrtPriceX96After); encodedResult.revertWith(); } @@ -153,8 +138,7 @@ contract Quoter is IQuoter, SafeCallback { function _quoteExactOutput(QuoteExactParams calldata params) external selfOnly returns (bytes memory) { uint256 pathLength = params.path.length; - QuoteResult memory result = - QuoteResult({deltaAmounts: new int128[](pathLength + 1), sqrtPriceX96AfterList: new uint160[](pathLength)}); + uint160[] memory sqrtPriceX96AfterList = new uint160[](pathLength); BalanceDelta swapDelta; uint128 amountOut = params.exactAmount; Currency outputCurrency = params.exactCurrency; @@ -166,25 +150,18 @@ contract Quoter is IQuoter, SafeCallback { (PoolKey memory poolKey, bool oneForZero) = pathKey.getPoolAndSwapDirection(outputCurrency); - (swapDelta, result.sqrtPriceX96AfterList[i - 1]) = + (swapDelta, sqrtPriceX96AfterList[i - 1]) = _swap(poolKey, !oneForZero, int256(uint256(amountOut)), 0, pathKey.hookData); // always clear because sqrtPriceLimitX96 is set to 0 always delete amountOutCached; - if (!oneForZero) { - result.deltaAmounts[i - 1] += -swapDelta.amount0(); - result.deltaAmounts[i] += -swapDelta.amount1(); - amountOut = uint128(-swapDelta.amount0()); - } else { - result.deltaAmounts[i - 1] += -swapDelta.amount1(); - result.deltaAmounts[i] += -swapDelta.amount0(); - amountOut = uint128(-swapDelta.amount1()); - } + amountOut = oneForZero ? uint128(-swapDelta.amount1()) : uint128(-swapDelta.amount0()); outputCurrency = pathKey.intermediateCurrency; } - bytes memory encodedResult = abi.encode(result.deltaAmounts, result.sqrtPriceX96AfterList); + // amountOut after the loop exits actually holds the amountIn of the trade + bytes memory encodedResult = abi.encode(amountOut, sqrtPriceX96AfterList); encodedResult.revertWith(); } @@ -202,12 +179,11 @@ contract Quoter is IQuoter, SafeCallback { ); if (amountOutCached != 0) delete amountOutCached; - int128[] memory deltaAmounts = new int128[](2); - deltaAmounts[0] = -deltas.amount0(); - deltaAmounts[1] = -deltas.amount1(); + // the input delta of a swap is negative so we must flip it + uint256 amountIn = params.zeroForOne ? uint128(-deltas.amount0()) : uint128(-deltas.amount1()); - bytes memory encodedResult = abi.encode(deltaAmounts, sqrtPriceX96After); + bytes memory encodedResult = abi.encode(amountIn, sqrtPriceX96After); encodedResult.revertWith(); } diff --git a/src/libraries/RevertBytes.sol b/src/libraries/RevertBytes.sol index e045f57e..3c9a24d6 100644 --- a/src/libraries/RevertBytes.sol +++ b/src/libraries/RevertBytes.sol @@ -7,10 +7,9 @@ library RevertBytes { /// @notice error thrown when invalid revert bytes are thrown by the quote error UnexpectedRevertBytes(bytes revertData); - /// @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 - uint256 internal constant MINIMUM_VALID_RESPONSE_LENGTH = 160; + /// @dev min valid reason is 2-words long (64 bytes) + /// @dev amountUnspecified and sqrtPriceX96After + uint256 internal constant MINIMUM_VALID_RESPONSE_LENGTH = 64; /// @notice reverts, where the revert data is the provided bytes /// @dev called when quoting, at the end of simulating a swap, to revert with the swap information as the revert reason @@ -32,15 +31,15 @@ library RevertBytes { /// @notice validates a received revert reason from a single-hop swap. /// Then, if valid, decodes it into the information generated by a quote - function parseReturnDataSingle(bytes memory reason) internal pure returns (int128[] memory, uint160) { + function parseReturnDataSingle(bytes memory reason) internal pure returns (uint256, uint160) { reason.validateRevertReason(); - return abi.decode(reason, (int128[], uint160)); + return abi.decode(reason, (uint256, uint160)); } /// @notice validates a received revert reason from a multi-hop swap. /// Then, if valid, decodes it into the information generated by a quote - function parseReturnData(bytes memory reason) internal pure returns (int128[] memory, uint160[] memory) { + function parseReturnData(bytes memory reason) internal pure returns (uint256, uint160[] memory) { reason.validateRevertReason(); - return abi.decode(reason, (int128[], uint160[])); + return abi.decode(reason, (uint256, uint160[])); } } diff --git a/test/Quoter.t.sol b/test/Quoter.t.sol index 552295d8..3535789d 100644 --- a/test/Quoter.t.sol +++ b/test/Quoter.t.sol @@ -85,7 +85,7 @@ contract QuoterTest is Test, Deployers, GasSnapshot { uint256 expectedAmountOut = 9871; uint160 expectedSqrtPriceX96After = 78461846509168490764501028180; - (int128[] memory deltaAmounts, uint160 sqrtPriceX96After,) = quoter.quoteExactInputSingle( + (uint256 amountOut, uint160 sqrtPriceX96After,) = quoter.quoteExactInputSingle( IQuoter.QuoteExactSingleParams({ poolKey: key02, zeroForOne: true, @@ -96,7 +96,7 @@ contract QuoterTest is Test, Deployers, GasSnapshot { ); snapLastCall("Quoter_exactInputSingle_zeroForOne_multiplePositions"); - assertEq(uint128(-deltaAmounts[1]), expectedAmountOut); + assertEq(amountOut, expectedAmountOut); assertEq(sqrtPriceX96After, expectedSqrtPriceX96After); } @@ -105,7 +105,7 @@ contract QuoterTest is Test, Deployers, GasSnapshot { uint256 expectedAmountOut = 9871; uint160 expectedSqrtPriceX96After = 80001962924147897865541384515; - (int128[] memory deltaAmounts, uint160 sqrtPriceX96After,) = quoter.quoteExactInputSingle( + (uint256 amountOut, uint160 sqrtPriceX96After,) = quoter.quoteExactInputSingle( IQuoter.QuoteExactSingleParams({ poolKey: key02, zeroForOne: false, @@ -116,7 +116,7 @@ contract QuoterTest is Test, Deployers, GasSnapshot { ); snapLastCall("Quoter_exactInputSingle_oneForZero_multiplePositions"); - assertEq(uint128(-deltaAmounts[0]), expectedAmountOut); + assertEq(amountOut, expectedAmountOut); assertEq(sqrtPriceX96After, expectedSqrtPriceX96After); } @@ -132,9 +132,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token2); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10000); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); - assertEq(uint128(-deltaAmounts[1]), 9871); + assertEq(amountOut, 9871); assertEq(sqrtPriceX96AfterList[0], 78461846509168490764501028180); } @@ -146,9 +146,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { // -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,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); - assertEq(uint128(-deltaAmounts[1]), 6143); + assertEq(amountOut, 6143); assertEq(sqrtPriceX96AfterList[0], 78757224507315167622282810783); } @@ -160,11 +160,11 @@ contract QuoterTest is Test, Deployers, GasSnapshot { // -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,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); snapLastCall("Quoter_quoteExactInput_oneHop_1TickLoaded"); - assertEq(uint128(-deltaAmounts[1]), 3971); + assertEq(amountOut, 3971); assertEq(sqrtPriceX96AfterList[0], 78926452400586371254602774705); } @@ -173,9 +173,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token2); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); - assertEq(uint128(-deltaAmounts[1]), 8); + assertEq(amountOut, 8); assertEq(sqrtPriceX96AfterList[0], 79227483487511329217250071027); } @@ -185,9 +185,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token2); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); - assertEq(uint128(-deltaAmounts[1]), 8); + assertEq(amountOut, 8); assertEq(sqrtPriceX96AfterList[0], 79227817515327498931091950511); } @@ -196,9 +196,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token0); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10000); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); - assertEq(-deltaAmounts[1], 9871); + assertEq(amountOut, 9871); assertEq(sqrtPriceX96AfterList[0], 80001962924147897865541384515); } @@ -210,11 +210,11 @@ contract QuoterTest is Test, Deployers, GasSnapshot { // 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,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); snapLastCall("Quoter_quoteExactInput_oneHop_initializedAfter"); - assertEq(-deltaAmounts[1], 6190); + assertEq(amountOut, 6190); assertEq(sqrtPriceX96AfterList[0], 79705728824507063507279123685); } @@ -225,11 +225,11 @@ contract QuoterTest is Test, Deployers, GasSnapshot { IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 200); // Tick 0 initialized. Tick after = 1 - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); snapLastCall("Quoter_quoteExactInput_oneHop_startingInitialized"); - assertEq(-deltaAmounts[1], 198); + assertEq(amountOut, 198); assertEq(sqrtPriceX96AfterList[0], 79235729830182478001034429156); } @@ -239,9 +239,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token0); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 103); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); - assertEq(-deltaAmounts[1], 101); + assertEq(amountOut, 101); assertEq(sqrtPriceX96AfterList[0], 79235858216754624215638319723); } @@ -250,8 +250,8 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token1); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10000); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); - assertEq(-deltaAmounts[1], 9871); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); + assertEq(amountOut, 9871); assertEq(sqrtPriceX96AfterList[0], 80018067294531553039351583520); } @@ -261,17 +261,17 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token1); IQuoter.QuoteExactParams memory params = getExactInputParams(tokenPath, 10000); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); + (uint256 amountOut, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactInput(params); snapLastCall("Quoter_quoteExactInput_twoHops"); - assertEq(-deltaAmounts[2], 9745); + assertEq(amountOut, 9745); assertEq(sqrtPriceX96AfterList[0], 78461846509168490764501028180); assertEq(sqrtPriceX96AfterList[1], 80007846861567212939802016351); } function testQuoter_quoteExactOutputSingle_0to1() public { - (int128[] memory deltaAmounts, uint160 sqrtPriceX96After,) = quoter.quoteExactOutputSingle( + (uint256 amountIn, uint160 sqrtPriceX96After,) = quoter.quoteExactOutputSingle( IQuoter.QuoteExactSingleParams({ poolKey: key01, zeroForOne: true, @@ -282,12 +282,12 @@ contract QuoterTest is Test, Deployers, GasSnapshot { ); snapLastCall("Quoter_exactOutputSingle_zeroForOne"); - assertEq(deltaAmounts[0], 9981); + assertEq(amountIn, 9981); assertEq(sqrtPriceX96After, SQRT_PRICE_100_102); } function testQuoter_quoteExactOutputSingle_1to0() public { - (int128[] memory deltaAmounts, uint160 sqrtPriceX96After,) = quoter.quoteExactOutputSingle( + (uint256 amountIn, uint160 sqrtPriceX96After,) = quoter.quoteExactOutputSingle( IQuoter.QuoteExactSingleParams({ poolKey: key01, zeroForOne: false, @@ -298,7 +298,7 @@ contract QuoterTest is Test, Deployers, GasSnapshot { ); snapLastCall("Quoter_exactOutputSingle_oneForZero"); - assertEq(deltaAmounts[1], 9981); + assertEq(amountIn, 9981); assertEq(sqrtPriceX96After, SQRT_PRICE_102_100); } @@ -307,11 +307,11 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token2); IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 15000); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); snapLastCall("Quoter_quoteExactOutput_oneHop_2TicksLoaded"); - assertEq(deltaAmounts[0], 15273); + assertEq(amountIn, 15273); assertEq(sqrtPriceX96AfterList[0], 78055527257643669242286029831); } @@ -321,10 +321,10 @@ contract QuoterTest is Test, Deployers, GasSnapshot { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 6143); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); snapLastCall("Quoter_quoteExactOutput_oneHop_initializedAfter"); - assertEq(deltaAmounts[0], 6200); + assertEq(amountIn, 6200); assertEq(sqrtPriceX96AfterList[0], 78757225449310403327341205211); } @@ -334,10 +334,10 @@ contract QuoterTest is Test, Deployers, GasSnapshot { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 4000); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); snapLastCall("Quoter_quoteExactOutput_oneHop_1TickLoaded"); - assertEq(deltaAmounts[0], 4029); + assertEq(amountIn, 4029); assertEq(sqrtPriceX96AfterList[0], 78924219757724709840818372098); } @@ -349,10 +349,10 @@ contract QuoterTest is Test, Deployers, GasSnapshot { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 100); // Tick 0 initialized. Tick after = 1 - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); snapLastCall("Quoter_quoteExactOutput_oneHop_startingInitialized"); - assertEq(deltaAmounts[0], 102); + assertEq(amountIn, 102); assertEq(sqrtPriceX96AfterList[0], 79224329176051641448521403903); } @@ -362,9 +362,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 10); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); - assertEq(deltaAmounts[0], 12); + assertEq(amountIn, 12); assertEq(sqrtPriceX96AfterList[0], 79227408033628034983534698435); } @@ -373,9 +373,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token0); IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 15000); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); - assertEq(deltaAmounts[0], 15273); + assertEq(amountIn, 15273); assertEq(sqrtPriceX96AfterList[0], 80418414376567919517220409857); } @@ -385,9 +385,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 6223); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); - assertEq(deltaAmounts[0], 6283); + assertEq(amountIn, 6283); assertEq(sqrtPriceX96AfterList[0], 79708304437530892332449657932); } @@ -396,9 +396,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { tokenPath.push(token0); IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 6000); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); - assertEq(deltaAmounts[0], 6055); + assertEq(amountIn, 6055); assertEq(sqrtPriceX96AfterList[0], 79690640184021170956740081887); } @@ -408,9 +408,9 @@ contract QuoterTest is Test, Deployers, GasSnapshot { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 9871); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); - assertEq(deltaAmounts[0], 10000); + assertEq(amountIn, 10000); assertEq(sqrtPriceX96AfterList[0], 80018020393569259756601362385); } @@ -421,13 +421,11 @@ contract QuoterTest is Test, Deployers, GasSnapshot { IQuoter.QuoteExactParams memory params = getExactOutputParams(tokenPath, 9745); - (int128[] memory deltaAmounts, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); + (uint256 amountIn, uint160[] memory sqrtPriceX96AfterList,) = quoter.quoteExactOutput(params); snapLastCall("Quoter_quoteExactOutput_twoHops"); - assertEq(deltaAmounts[0], 10000); - assertEq(deltaAmounts[1], 0); - assertEq(deltaAmounts[2], -9745); + assertEq(amountIn, 10000); assertEq(sqrtPriceX96AfterList[0], 78461888503179331029803316753); assertEq(sqrtPriceX96AfterList[1], 80007838904387594703933785072); }