Skip to content

Commit c43f0f1

Browse files
fix amountOutCached
1 parent 88cbff3 commit c43f0f1

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

contracts/lens/Quoter.sol

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0-or-later
22
pragma solidity ^0.8.20;
33

4+
import "forge-std/console2.sol";
45
import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol";
56
import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
67
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
@@ -20,7 +21,7 @@ contract Quoter is IQuoter, ILockCallback {
2021
using PathKeyLib for PathKey;
2122

2223
/// @dev cache used to check a safety condition in exact output swaps.
23-
uint256 private amountOutCached;
24+
uint128 private amountOutCached;
2425

2526
// v4 Singleton contract
2627
IPoolManager public immutable manager;
@@ -239,22 +240,23 @@ contract Quoter is IQuoter, ILockCallback {
239240
uint32[] memory initializedTicksLoadedList = new uint32[](pathLength);
240241
Currency prevCurrencyIn;
241242
uint128 prevAmountIn;
243+
uint128 curAmountOut;
242244

243245
for (uint256 i = pathLength; i > 0; i--) {
246+
curAmountOut = i == pathLength ? params.exactAmount : prevAmountIn;
247+
amountOutCached = curAmountOut;
248+
244249
(PoolKey memory poolKey, bool oneForZero) = PathKeyLib.getPoolAndSwapDirection(
245250
params.path[i - 1], i == pathLength ? params.exactCurrency : prevCurrencyIn
246251
);
247252

248253
(, int24 tickBefore,) = manager.getSlot0(poolKey.toId());
249254

250-
(BalanceDelta curDeltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap(
251-
poolKey,
252-
!oneForZero,
253-
-int256(int128(i == pathLength ? params.exactAmount : prevAmountIn)),
254-
0,
255-
params.path[i - 1].hookData
256-
);
255+
(BalanceDelta curDeltas, uint160 sqrtPriceX96After, int24 tickAfter) =
256+
_swap(poolKey, !oneForZero, -int256(uint256(curAmountOut)), 0, params.path[i - 1].hookData);
257257

258+
// always clear because sqrtPriceLimitX96 is set to 0 always
259+
delete amountOutCached;
258260
(int128 deltaIn, int128 deltaOut) =
259261
!oneForZero ? (curDeltas.amount0(), curDeltas.amount1()) : (curDeltas.amount1(), curDeltas.amount0());
260262
deltaAmounts[i - 1] += deltaIn;
@@ -304,7 +306,7 @@ contract Quoter is IQuoter, ILockCallback {
304306
function _swap(
305307
PoolKey memory poolKey,
306308
bool zeroForOne,
307-
int256 amountSpecified,
309+
int256 amountSpecified, // exactInput = amountSpecified > 0
308310
uint160 sqrtPriceLimitX96,
309311
bytes memory hookData
310312
) private returns (BalanceDelta deltas, uint160 sqrtPriceX96After, int24 tickAfter) {
@@ -318,7 +320,7 @@ contract Quoter is IQuoter, ILockCallback {
318320
hookData
319321
);
320322
// only exactOut case
321-
if (amountOutCached != 0 && amountOutCached != uint256(int256(-deltas.amount1()))) {
323+
if (amountOutCached != 0 && amountOutCached != uint128(zeroForOne ? -deltas.amount1() : -deltas.amount0())) {
322324
revert InsufficientAmountOut();
323325
}
324326
(sqrtPriceX96After, tickAfter,) = manager.getSlot0(poolKey.toId());

0 commit comments

Comments
 (0)