Skip to content

Commit

Permalink
Remove mandatory viaIR (Uniswap#872)
Browse files Browse the repository at this point in the history
* scoping to avoid IR

* pick 4 variables to pack

* save 12 gas

* micro gas savings i hate it here

* cursed micro optimizations

* what im calling good enough 😭

* cleanup deadcode

* reorganize comments

* wip move feeGrowth to step

* remove swapstart

* gas things
  • Loading branch information
saucepoint authored Sep 5, 2024
1 parent 9e8515f commit 18b223c
Show file tree
Hide file tree
Showing 40 changed files with 76 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
144627
144651
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
170916
170947
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 @@
274194
274218
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 @@
135120
135141
Original file line number Diff line number Diff line change
@@ -1 +1 @@
292819
292843
2 changes: 1 addition & 1 deletion .forge-snapshots/donate gas with 1 token.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
106321
106333
2 changes: 1 addition & 1 deletion .forge-snapshots/donate gas with 2 tokens.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
145736
145754
2 changes: 1 addition & 1 deletion .forge-snapshots/erc20 collect protocol fees.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
57439
57442
2 changes: 1 addition & 1 deletion .forge-snapshots/extsload getFeeGrowthGlobals.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
774
777
2 changes: 1 addition & 1 deletion .forge-snapshots/extsload getPositionInfo.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
949
952
2 changes: 1 addition & 1 deletion .forge-snapshots/extsload getTickFeeGrowthOutside.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
774
777
2 changes: 1 addition & 1 deletion .forge-snapshots/extsload getTickInfo.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
949
952
2 changes: 1 addition & 1 deletion .forge-snapshots/initialize.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
60021
60025
2 changes: 1 addition & 1 deletion .forge-snapshots/native collect protocol fees.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
59723
59726
2 changes: 1 addition & 1 deletion .forge-snapshots/poolManager bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24044
24073
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
141204
141229
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 @@
130579
130597
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 @@
112523
112535
Original file line number Diff line number Diff line change
@@ -1 +1 @@
98838
98850
2 changes: 1 addition & 1 deletion .forge-snapshots/simple addLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
161383
161395
Original file line number Diff line number Diff line change
@@ -1 +1 @@
92974
92983
2 changes: 1 addition & 1 deletion .forge-snapshots/simple removeLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
85087
85096
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 @@
108369
108515
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
123186
123335
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 @@
126821
124663
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 @@
154631
154783
Original file line number Diff line number Diff line change
@@ -1 +1 @@
105493
105637
2 changes: 1 addition & 1 deletion .forge-snapshots/swap against liquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
116558
116705
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 @@
129116
129269
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 @@
118569
118725
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 @@
139603
139747
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 @@
155027
155176
Original file line number Diff line number Diff line change
@@ -1 +1 @@
206132
206425
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 @@
139207
139356
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with hooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
132195
132343
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 @@
169398
169603
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 @@
145534
145683
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 @@
147814
147966
38 changes: 20 additions & 18 deletions src/PoolManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -150,25 +150,27 @@ contract PoolManager is IPoolManager, ProtocolFees, NoDelegateCall, ERC6909Claim
bytes calldata hookData
) external onlyWhenUnlocked noDelegateCall returns (BalanceDelta callerDelta, BalanceDelta feesAccrued) {
PoolId id = key.toId();
Pool.State storage pool = _getPool(id);
pool.checkPoolInitialized();

key.hooks.beforeModifyLiquidity(key, params, hookData);

BalanceDelta principalDelta;
(principalDelta, feesAccrued) = pool.modifyLiquidity(
Pool.ModifyLiquidityParams({
owner: msg.sender,
tickLower: params.tickLower,
tickUpper: params.tickUpper,
liquidityDelta: params.liquidityDelta.toInt128(),
tickSpacing: key.tickSpacing,
salt: params.salt
})
);
{
Pool.State storage pool = _getPool(id);
pool.checkPoolInitialized();

key.hooks.beforeModifyLiquidity(key, params, hookData);

BalanceDelta principalDelta;
(principalDelta, feesAccrued) = pool.modifyLiquidity(
Pool.ModifyLiquidityParams({
owner: msg.sender,
tickLower: params.tickLower,
tickUpper: params.tickUpper,
liquidityDelta: params.liquidityDelta.toInt128(),
tickSpacing: key.tickSpacing,
salt: params.salt
})
);

// fee delta and principal delta are both accrued to the caller
callerDelta = principalDelta + feesAccrued;
// fee delta and principal delta are both accrued to the caller
callerDelta = principalDelta + feesAccrued;
}

// event is emitted before the afterModifyLiquidity call to ensure events are always emitted in order
emit ModifyLiquidity(id, msg.sender, params.tickLower, params.tickUpper, params.liquidityDelta, params.salt);
Expand Down
34 changes: 18 additions & 16 deletions src/libraries/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,14 @@ library Pool {
uint256 amountOut;
// how much fee is being paid in
uint256 feeAmount;
// the global fee growth of the input token. updated in storage at the end of swap
uint256 feeGrowthGlobalX128;
}

struct SwapParams {
int256 amountSpecified;
int24 tickSpacing;
bool zeroForOne;
int256 amountSpecified;
uint160 sqrtPriceLimitX96;
uint24 lpFeeOverride;
}
Expand All @@ -281,22 +283,19 @@ library Pool {
Slot0 slot0Start = self.slot0;
bool zeroForOne = params.zeroForOne;

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

// the amount remaining to be swapped in/out of the input/output asset. initially set to the amountSpecified
int256 amountSpecifiedRemaining = params.amountSpecified;
// the amount swapped out/in of the output/input asset. initially set to 0
int256 amountCalculated = 0;
// the global fee growth of the input token. updated in storage at the end of swap
uint256 feeGrowthGlobalX128 = zeroForOne ? self.feeGrowthGlobal0X128 : self.feeGrowthGlobal1X128;
// initialize to the current sqrt(price)
result.sqrtPriceX96 = slot0Start.sqrtPriceX96();
// initialize to the current tick
result.tick = slot0Start.tick();
// initialize to the current liquidity
result.liquidity = liquidityStart;
result.liquidity = self.liquidity;

// if the beforeSwap hook returned a valid fee override, use that as the LP fee, otherwise load from storage
// lpFee, swapFee, and protocolFee are all in pips
Expand All @@ -308,11 +307,10 @@ library Pool {
swapFee = protocolFee == 0 ? lpFee : uint16(protocolFee).calculateSwapFee(lpFee);
}

bool exactInput = params.amountSpecified < 0;

// a swap fee totaling MAX_SWAP_FEE (100%) makes exact output swaps impossible since the input is entirely consumed by the fee
if (swapFee >= SwapMath.MAX_SWAP_FEE) {
if (!exactInput) {
// if exactOutput
if (params.amountSpecified > 0) {
InvalidFeeForExactOut.selector.revertWith();
}
}
Expand Down Expand Up @@ -340,6 +338,7 @@ library Pool {
}

StepComputations memory step;
step.feeGrowthGlobalX128 = zeroForOne ? self.feeGrowthGlobal0X128 : self.feeGrowthGlobal1X128;

// continue swapping as long as we haven't used the entire input/output and haven't reached the price limit
while (!(amountSpecifiedRemaining == 0 || result.sqrtPriceX96 == params.sqrtPriceLimitX96)) {
Expand Down Expand Up @@ -368,7 +367,8 @@ library Pool {
swapFee
);

if (!exactInput) {
// if exactOutput
if (params.amountSpecified > 0) {
unchecked {
amountSpecifiedRemaining -= step.amountOut.toInt256();
}
Expand Down Expand Up @@ -398,7 +398,8 @@ library Pool {
if (result.liquidity > 0) {
unchecked {
// FullMath.mulDiv isn't needed as the numerator can't overflow uint256 since tokens have a max supply of type(uint128).max
feeGrowthGlobalX128 += UnsafeMath.simpleMulDiv(step.feeAmount, FixedPoint128.Q128, result.liquidity);
step.feeGrowthGlobalX128 +=
UnsafeMath.simpleMulDiv(step.feeAmount, FixedPoint128.Q128, result.liquidity);
}
}

Expand All @@ -410,8 +411,8 @@ library Pool {
// if the tick is initialized, run the tick transition
if (step.initialized) {
(uint256 feeGrowthGlobal0X128, uint256 feeGrowthGlobal1X128) = zeroForOne
? (feeGrowthGlobalX128, self.feeGrowthGlobal1X128)
: (self.feeGrowthGlobal0X128, feeGrowthGlobalX128);
? (step.feeGrowthGlobalX128, self.feeGrowthGlobal1X128)
: (self.feeGrowthGlobal0X128, step.feeGrowthGlobalX128);
int128 liquidityNet =
Pool.crossTick(self, step.tickNext, feeGrowthGlobal0X128, feeGrowthGlobal1X128);
// if we're moving leftward, we interpret liquidityNet as the opposite sign
Expand All @@ -435,17 +436,18 @@ library Pool {
self.slot0 = slot0Start.setTick(result.tick).setSqrtPriceX96(result.sqrtPriceX96);

// update liquidity if it changed
if (liquidityStart != result.liquidity) self.liquidity = result.liquidity;
if (self.liquidity != result.liquidity) self.liquidity = result.liquidity;

// update fee growth global
if (!zeroForOne) {
self.feeGrowthGlobal1X128 = feeGrowthGlobalX128;
self.feeGrowthGlobal1X128 = step.feeGrowthGlobalX128;
} else {
self.feeGrowthGlobal0X128 = feeGrowthGlobalX128;
self.feeGrowthGlobal0X128 = step.feeGrowthGlobalX128;
}

unchecked {
if (zeroForOne != exactInput) {
// "if currency1 is specified"
if (zeroForOne != (params.amountSpecified < 0)) {
swapDelta = toBalanceDelta(
amountCalculated.toInt128(), (params.amountSpecified - amountSpecifiedRemaining).toInt128()
);
Expand Down

0 comments on commit 18b223c

Please sign in to comment.