Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Quoter) Avoid IR #93

Merged
merged 10 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .forge-snapshots/FullOracleObserve0After5Seconds.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2687
1922
2 changes: 1 addition & 1 deletion .forge-snapshots/FullOracleObserve200By13.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22933
20282
2 changes: 1 addition & 1 deletion .forge-snapshots/FullOracleObserve200By13Plus5.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
23180
20520
2 changes: 1 addition & 1 deletion .forge-snapshots/FullOracleObserve5After5Seconds.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2738
2034
2 changes: 1 addition & 1 deletion .forge-snapshots/FullOracleObserveOldest.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
21892
19330
2 changes: 1 addition & 1 deletion .forge-snapshots/FullOracleObserveOldestAfter5Seconds.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22191
19612
2 changes: 1 addition & 1 deletion .forge-snapshots/FullOracleObserveZero.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2070
1483
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeAddInitialLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
407968
393062
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeAddLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
201962
187418
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeFirstSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
153306
136762
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeInitialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1112212
1059719
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeRemoveLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
197519
180886
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeRemoveLiquidityAndRebalance.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
379147
373831
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeSecondSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
111940
97479
2 changes: 1 addition & 1 deletion .forge-snapshots/FullRangeSwap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
151523
135037
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleGrow10Slots.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
254660
232968
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleGrow10SlotsCardinalityGreater.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
245360
223657
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleGrow1Slot.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
54869
32853
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleGrow1SlotCardinalityGreater.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
45569
23553
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleInitialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
72316
51321
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6492
5397
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleObserveCurrentTime.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2070
1483
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2070
1483
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleObserveLast20Seconds.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
86878
73451
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleObserveLatestEqual.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2070
1483
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleObserveLatestTransform.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2687
1922
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleObserveMiddle.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6684
5572
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleObserveOldest.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6193
5115
2 changes: 1 addition & 1 deletion .forge-snapshots/OracleObserveSinceMostRecent.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3382
2537
2 changes: 1 addition & 1 deletion .forge-snapshots/TWAMMSubmitOrder.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
145648
122817
16 changes: 6 additions & 10 deletions contracts/hooks/examples/LimitOrder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,6 @@ contract LimitOrder is BaseHook {
uint128 liquidity = epochInfo.liquidity[msg.sender];
if (liquidity == 0) revert ZeroLiquidity();
delete epochInfo.liquidity[msg.sender];
uint128 liquidityTotal = epochInfo.liquidityTotal;
epochInfo.liquidityTotal = liquidityTotal - liquidity;

uint256 amount0Fee;
uint256 amount1Fee;
Expand All @@ -309,12 +307,12 @@ contract LimitOrder is BaseHook {
address(this),
abi.encodeCall(
this.lockAcquiredKill,
(key, tickLower, -int256(uint256(liquidity)), to, liquidity == liquidityTotal)
(key, tickLower, -int256(uint256(liquidity)), to, liquidity == epochInfo.liquidityTotal)
)
),
(uint256, uint256, uint256, uint256)
);

epochInfo.liquidityTotal -= liquidity;
unchecked {
epochInfo.token0Total += amount0Fee;
epochInfo.token1Total += amount1Fee;
Expand Down Expand Up @@ -378,15 +376,13 @@ contract LimitOrder is BaseHook {
if (liquidity == 0) revert ZeroLiquidity();
delete epochInfo.liquidity[msg.sender];

uint256 token0Total = epochInfo.token0Total;
uint256 token1Total = epochInfo.token1Total;
uint128 liquidityTotal = epochInfo.liquidityTotal;

amount0 = FullMath.mulDiv(token0Total, liquidity, liquidityTotal);
amount1 = FullMath.mulDiv(token1Total, liquidity, liquidityTotal);
amount0 = FullMath.mulDiv(epochInfo.token0Total, liquidity, liquidityTotal);
amount1 = FullMath.mulDiv(epochInfo.token1Total, liquidity, liquidityTotal);

epochInfo.token0Total = token0Total - amount0;
epochInfo.token1Total = token1Total - amount1;
epochInfo.token0Total -= amount0;
epochInfo.token1Total -= amount1;
epochInfo.liquidityTotal = liquidityTotal - liquidity;

poolManager.lock(
Expand Down
107 changes: 65 additions & 42 deletions contracts/lens/Quoter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ contract Quoter is IQuoter, ILockCallback {
/// @dev int128[2] + sqrtPriceX96After padded to 32bytes + intializeTicksLoaded padded to 32bytes
uint256 internal constant MINIMUM_VALID_RESPONSE_LENGTH = 96;

struct QuoteResult {
int128[] deltaAmounts;
uint160[] sqrtPriceX96AfterList;
uint32[] initializedTicksLoadedList;
}

struct QuoteCache {
BalanceDelta curDeltas;
uint128 prevAmount;
int128 deltaIn;
int128 deltaOut;
int24 tickBefore;
int24 tickAfter;
Currency prevCurrency;
uint160 sqrtPriceX96After;
}

/// @dev Only this address may call this function
modifier selfOnly() {
if (msg.sender != address(this)) revert NotSelf();
Expand Down Expand Up @@ -151,39 +168,42 @@ contract Quoter is IQuoter, ILockCallback {
function _quoteExactInput(QuoteExactParams memory params) public selfOnly returns (bytes memory) {
uint256 pathLength = params.path.length;

int128[] memory deltaAmounts = new int128[](pathLength + 1);
uint160[] memory sqrtPriceX96AfterList = new uint160[](pathLength);
uint32[] memory initializedTicksLoadedList = new uint32[](pathLength);
Currency prevCurrencyOut;
uint128 prevAmountOut;
QuoteResult memory result = QuoteResult({
deltaAmounts: new int128[](pathLength + 1),
sqrtPriceX96AfterList: new uint160[](pathLength),
initializedTicksLoadedList: new uint32[](pathLength)
});
QuoteCache memory cache;

for (uint256 i = 0; i < pathLength; i++) {
(PoolKey memory poolKey, bool zeroForOne) =
params.path[i].getPoolAndSwapDirection(i == 0 ? params.exactCurrency : prevCurrencyOut);
(, int24 tickBefore,) = manager.getSlot0(poolKey.toId());
params.path[i].getPoolAndSwapDirection(i == 0 ? params.exactCurrency : cache.prevCurrency);
(, cache.tickBefore,) = manager.getSlot0(poolKey.toId());

(BalanceDelta curDeltas, uint160 sqrtPriceX96After, int24 tickAfter) = _swap(
(cache.curDeltas, cache.sqrtPriceX96After, cache.tickAfter) = _swap(
poolKey,
zeroForOne,
int256(int128(i == 0 ? params.exactAmount : prevAmountOut)),
int256(int128(i == 0 ? params.exactAmount : cache.prevAmount)),
0,
params.path[i].hookData
);

(int128 deltaIn, int128 deltaOut) =
zeroForOne ? (curDeltas.amount0(), curDeltas.amount1()) : (curDeltas.amount1(), curDeltas.amount0());
deltaAmounts[i] += deltaIn;
deltaAmounts[i + 1] += deltaOut;

prevAmountOut = zeroForOne ? uint128(-curDeltas.amount1()) : uint128(-curDeltas.amount0());
prevCurrencyOut = params.path[i].intermediateCurrency;
sqrtPriceX96AfterList[i] = sqrtPriceX96After;
initializedTicksLoadedList[i] =
PoolTicksCounter.countInitializedTicksLoaded(manager, poolKey, tickBefore, tickAfter);
(cache.deltaIn, cache.deltaOut) = zeroForOne
? (cache.curDeltas.amount0(), cache.curDeltas.amount1())
: (cache.curDeltas.amount1(), cache.curDeltas.amount0());
result.deltaAmounts[i] += cache.deltaIn;
result.deltaAmounts[i + 1] += cache.deltaOut;

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(manager, poolKey, cache.tickBefore, cache.tickAfter);
}
bytes memory result = abi.encode(deltaAmounts, sqrtPriceX96AfterList, initializedTicksLoadedList);
bytes memory r =
abi.encode(result.deltaAmounts, result.sqrtPriceX96AfterList, result.initializedTicksLoadedList);
assembly {
revert(add(0x20, result), mload(result))
revert(add(0x20, r), mload(r))
}
}

Expand Down Expand Up @@ -216,42 +236,45 @@ contract Quoter is IQuoter, ILockCallback {
function _quoteExactOutput(QuoteExactParams memory params) public selfOnly returns (bytes memory) {
uint256 pathLength = params.path.length;

int128[] memory deltaAmounts = new int128[](pathLength + 1);
uint160[] memory sqrtPriceX96AfterList = new uint160[](pathLength);
uint32[] memory initializedTicksLoadedList = new uint32[](pathLength);
Currency prevCurrencyIn;
uint128 prevAmountIn;
QuoteResult memory result = QuoteResult({
deltaAmounts: new int128[](pathLength + 1),
sqrtPriceX96AfterList: new uint160[](pathLength),
initializedTicksLoadedList: new uint32[](pathLength)
});
QuoteCache memory cache;
uint128 curAmountOut;

for (uint256 i = pathLength; i > 0; i--) {
curAmountOut = i == pathLength ? params.exactAmount : prevAmountIn;
curAmountOut = i == pathLength ? params.exactAmount : cache.prevAmount;
amountOutCached = curAmountOut;

(PoolKey memory poolKey, bool oneForZero) = PathKeyLib.getPoolAndSwapDirection(
params.path[i - 1], i == pathLength ? params.exactCurrency : prevCurrencyIn
params.path[i - 1], i == pathLength ? params.exactCurrency : cache.prevCurrency
);

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

(BalanceDelta curDeltas, uint160 sqrtPriceX96After, int24 tickAfter) =
(cache.curDeltas, cache.sqrtPriceX96After, cache.tickAfter) =
_swap(poolKey, !oneForZero, -int256(uint256(curAmountOut)), 0, params.path[i - 1].hookData);

// always clear because sqrtPriceLimitX96 is set to 0 always
delete amountOutCached;
(int128 deltaIn, int128 deltaOut) =
!oneForZero ? (curDeltas.amount0(), curDeltas.amount1()) : (curDeltas.amount1(), curDeltas.amount0());
deltaAmounts[i - 1] += deltaIn;
deltaAmounts[i] += deltaOut;

prevAmountIn = !oneForZero ? uint128(curDeltas.amount0()) : uint128(curDeltas.amount1());
prevCurrencyIn = params.path[i - 1].intermediateCurrency;
sqrtPriceX96AfterList[i - 1] = sqrtPriceX96After;
initializedTicksLoadedList[i - 1] =
PoolTicksCounter.countInitializedTicksLoaded(manager, poolKey, tickBefore, tickAfter);
(cache.deltaIn, cache.deltaOut) = !oneForZero
? (cache.curDeltas.amount0(), cache.curDeltas.amount1())
: (cache.curDeltas.amount1(), cache.curDeltas.amount0());
result.deltaAmounts[i - 1] += cache.deltaIn;
result.deltaAmounts[i] += cache.deltaOut;

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(manager, poolKey, cache.tickBefore, cache.tickAfter);
}
bytes memory result = abi.encode(deltaAmounts, sqrtPriceX96AfterList, initializedTicksLoadedList);
bytes memory r =
abi.encode(result.deltaAmounts, result.sqrtPriceX96AfterList, result.initializedTicksLoadedList);
assembly {
revert(add(0x20, result), mload(result))
revert(add(0x20, r), mload(r))
}
}

Expand Down
Loading
Loading