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

Use packed stack-based version of Slot0 structure #613

Merged
merged 23 commits into from
May 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
Original file line number Diff line number Diff line change
@@ -1 +1 @@
153625
153643
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
331641
331635
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity with empty hook.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
286634
286628
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity with native token.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
143835
143853
Original file line number Diff line number Diff line change
@@ -1 +1 @@
302153
302147
2 changes: 1 addition & 1 deletion .forge-snapshots/initialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
62194
61902
2 changes: 1 addition & 1 deletion .forge-snapshots/poolManager bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22083
21934
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
187083
187101
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity with empty hook.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
123451
123469
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity with native token.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
120238
120256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
104914
104932
2 changes: 1 addition & 1 deletion .forge-snapshots/simple addLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
167756
167750
Original file line number Diff line number Diff line change
@@ -1 +1 @@
98511
98529
2 changes: 1 addition & 1 deletion .forge-snapshots/simple removeLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
90877
90895
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap with native.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
117344
117057
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
132505
132218
2 changes: 1 addition & 1 deletion .forge-snapshots/swap CA custom curve + swap noop.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
134660
134432
2 changes: 1 addition & 1 deletion .forge-snapshots/swap CA fee on unspecified.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
183643
183356
Original file line number Diff line number Diff line change
@@ -1 +1 @@
112984
112697
2 changes: 1 addition & 1 deletion .forge-snapshots/swap against liquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
124327
124040
2 changes: 1 addition & 1 deletion .forge-snapshots/swap burn 6909 for input.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
136380
136081
2 changes: 1 addition & 1 deletion .forge-snapshots/swap burn native 6909 for input.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
125508
125221
2 changes: 1 addition & 1 deletion .forge-snapshots/swap mint native output as 6909.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
147569
147270
2 changes: 1 addition & 1 deletion .forge-snapshots/swap mint output as 6909.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
164359
164072
Original file line number Diff line number Diff line change
@@ -1 +1 @@
223152
222578
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with dynamic fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
148560
148273
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with hooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
124339
124052
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with lp fee and protocol fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
180754
180456
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with return dynamic fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
156425
156132
2 changes: 1 addition & 1 deletion .forge-snapshots/update dynamic fee in before swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
159033
158735
60 changes: 26 additions & 34 deletions src/libraries/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {TickMath} from "./TickMath.sol";
import {SqrtPriceMath} from "./SqrtPriceMath.sol";
import {SwapMath} from "./SwapMath.sol";
import {BalanceDelta, toBalanceDelta, BalanceDeltaLibrary} from "../types/BalanceDelta.sol";
import {Slot0} from "../types/Slot0.sol";
import {ProtocolFeeLibrary} from "./ProtocolFeeLibrary.sol";
import {LiquidityMath} from "./LiquidityMath.sol";
import {LPFeeLibrary} from "./LPFeeLibrary.sol";
Expand Down Expand Up @@ -64,20 +65,6 @@ library Pool {
/// @notice Thrown when trying to swap with max lp fee and specifying an output amount
error InvalidFeeForExactOut();

struct Slot0 {
// the current price
uint160 sqrtPriceX96;
// the current tick
int24 tick;
// protocol fee, expressed in hundredths of a bip
// upper 12 bits are for 1->0, and the lower 12 are for 0->1
// the maximum is 1000 - meaning the maximum protocol fee is 0.1%
// the protocolFee is taken from the input first, then the lpFee is taken from the remaining input
uint24 protocolFee;
// used for the lp fee, either static at initialize or dynamic via hook
uint24 lpFee;
}

// info stored for each initialized individual tick
struct TickInfo {
// the total position liquidity that references this tick
Expand Down Expand Up @@ -112,23 +99,24 @@ library Pool {
internal
returns (int24 tick)
{
if (self.slot0.sqrtPriceX96 != 0) revert PoolAlreadyInitialized();
if (self.slot0.sqrtPriceX96() != 0) revert PoolAlreadyInitialized();

tick = TickMath.getTickAtSqrtPrice(sqrtPriceX96);

self.slot0 = Slot0({sqrtPriceX96: sqrtPriceX96, tick: tick, protocolFee: protocolFee, lpFee: lpFee});
self.slot0 = Slot0.wrap(bytes32(0)).setSqrtPriceX96(sqrtPriceX96).setTick(tick).setProtocolFee(protocolFee)
.setLpFee(lpFee);
}

function setProtocolFee(State storage self, uint24 protocolFee) internal {
if (self.isNotInitialized()) revert PoolNotInitialized();

self.slot0.protocolFee = protocolFee;
self.slot0 = self.slot0.setProtocolFee(protocolFee);
}

/// @notice Only dynamic fee pools may update the lp fee.
function setLPFee(State storage self, uint24 lpFee) internal {
if (self.isNotInitialized()) revert PoolNotInitialized();
self.slot0.lpFee = lpFee;
self.slot0 = self.slot0.setLpFee(lpFee);
}

struct ModifyLiquidityParams {
Expand Down Expand Up @@ -218,7 +206,8 @@ library Pool {
}

if (liquidityDelta != 0) {
(int24 tick, uint160 sqrtPriceX96) = (self.slot0.tick, self.slot0.sqrtPriceX96);
Slot0 _slot0 = self.slot0;
(int24 tick, uint160 sqrtPriceX96) = (_slot0.tick(), _slot0.sqrtPriceX96());
if (tick < tickLower) {
// current tick is below the passed range; liquidity can only become in range by crossing from left to
// right, when we'll need _more_ currency0 (it's becoming more valuable) so user must provide it
Expand Down Expand Up @@ -297,25 +286,28 @@ library Pool {
internal
returns (BalanceDelta result, uint256 feeForProtocol, uint24 swapFee, SwapState memory state)
{
Slot0 memory slot0Start = self.slot0;
Slot0 slot0Start = self.slot0;
bool zeroForOne = params.zeroForOne;

uint128 liquidityStart = self.liquidity;
uint256 protocolFee =
zeroForOne ? slot0Start.protocolFee.getZeroForOneFee() : slot0Start.protocolFee.getOneForZeroFee();
zeroForOne ? slot0Start.protocolFee().getZeroForOneFee() : slot0Start.protocolFee().getOneForZeroFee();

state.amountSpecifiedRemaining = params.amountSpecified;
state.amountCalculated = 0;
state.sqrtPriceX96 = slot0Start.sqrtPriceX96;
state.tick = slot0Start.tick;
state.sqrtPriceX96 = slot0Start.sqrtPriceX96();
state.tick = slot0Start.tick();
state.feeGrowthGlobalX128 = zeroForOne ? self.feeGrowthGlobal0X128 : self.feeGrowthGlobal1X128;
state.liquidity = liquidityStart;

// if the beforeSwap hook returned a valid fee override, use that as the LP fee, otherwise load from storage
slot0Start.lpFee =
params.lpFeeOverride.isOverride() ? params.lpFeeOverride.removeOverrideAndValidate() : slot0Start.lpFee;
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice thank you!

uint24 lpFee = params.lpFeeOverride.isOverride()
? params.lpFeeOverride.removeOverrideAndValidate()
: slot0Start.lpFee();

swapFee = protocolFee == 0 ? slot0Start.lpFee : uint24(protocolFee).calculateSwapFee(slot0Start.lpFee);
swapFee = protocolFee == 0 ? lpFee : uint24(protocolFee).calculateSwapFee(lpFee);
}

bool exactInput = params.amountSpecified < 0;

Expand All @@ -326,15 +318,15 @@ library Pool {
if (params.amountSpecified == 0) return (BalanceDeltaLibrary.ZERO_DELTA, 0, swapFee, state);

if (zeroForOne) {
if (params.sqrtPriceLimitX96 >= slot0Start.sqrtPriceX96) {
revert PriceLimitAlreadyExceeded(slot0Start.sqrtPriceX96, params.sqrtPriceLimitX96);
if (params.sqrtPriceLimitX96 >= slot0Start.sqrtPriceX96()) {
revert PriceLimitAlreadyExceeded(slot0Start.sqrtPriceX96(), params.sqrtPriceLimitX96);
}
if (params.sqrtPriceLimitX96 <= TickMath.MIN_SQRT_PRICE) {
revert PriceLimitOutOfBounds(params.sqrtPriceLimitX96);
}
} else {
if (params.sqrtPriceLimitX96 <= slot0Start.sqrtPriceX96) {
revert PriceLimitAlreadyExceeded(slot0Start.sqrtPriceX96, params.sqrtPriceLimitX96);
if (params.sqrtPriceLimitX96 <= slot0Start.sqrtPriceX96()) {
revert PriceLimitAlreadyExceeded(slot0Start.sqrtPriceX96(), params.sqrtPriceLimitX96);
}
if (params.sqrtPriceLimitX96 >= TickMath.MAX_SQRT_PRICE) {
revert PriceLimitOutOfBounds(params.sqrtPriceLimitX96);
Expand Down Expand Up @@ -439,7 +431,7 @@ library Pool {
}
}

(self.slot0.tick, self.slot0.sqrtPriceX96) = (state.tick, state.sqrtPriceX96);
self.slot0 = slot0Start.setTick(state.tick).setSqrtPriceX96(state.sqrtPriceX96);

// update liquidity if it changed
if (liquidityStart != state.liquidity) self.liquidity = state.liquidity;
Expand Down Expand Up @@ -495,7 +487,7 @@ library Pool {
{
TickInfo storage lower = self.ticks[tickLower];
TickInfo storage upper = self.ticks[tickUpper];
int24 tickCurrent = self.slot0.tick;
int24 tickCurrent = self.slot0.tick();

unchecked {
if (tickCurrent < tickLower) {
Expand Down Expand Up @@ -544,7 +536,7 @@ library Pool {

if (liquidityGrossBefore == 0) {
// by convention, we assume that all growth before a tick was initialized happened _below_ the tick
if (tick <= self.slot0.tick) {
if (tick <= self.slot0.tick()) {
info.feeGrowthOutside0X128 = self.feeGrowthGlobal0X128;
info.feeGrowthOutside1X128 = self.feeGrowthGlobal1X128;
}
Expand Down Expand Up @@ -583,7 +575,7 @@ library Pool {
}

function isNotInitialized(State storage self) internal view returns (bool) {
return self.slot0.sqrtPriceX96 == 0;
return self.slot0.sqrtPriceX96() == 0;
}

/// @notice Clears tick data
Expand Down
Loading
Loading