Skip to content

Commit

Permalink
tickSpacingToMaxLiquidityPerTick not the same as v3 (#666)
Browse files Browse the repository at this point in the history
* tickSpacingToMaxLiquidityPerTick not the same as v3

* comment to make clear

* make tickSpacingToMaxLiquidityPerTick equivalent to v3

* add comment

* delete unnecessary stuff
  • Loading branch information
dianakocsis authored May 24, 2024
1 parent 9affea6 commit f265610
Show file tree
Hide file tree
Showing 14 changed files with 57 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
149347
149323
2 changes: 1 addition & 1 deletion .forge-snapshots/addLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
326051
326027
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 @@
280165
280141
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 @@
139553
139529
Original file line number Diff line number Diff line change
@@ -1 +1 @@
297525
297501
2 changes: 1 addition & 1 deletion .forge-snapshots/poolManager bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20003
19986
Original file line number Diff line number Diff line change
@@ -1 +1 @@
102789
102765
2 changes: 1 addition & 1 deletion .forge-snapshots/simple addLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
165281
165257
Original file line number Diff line number Diff line change
@@ -1 +1 @@
197
173
Original file line number Diff line number Diff line change
@@ -1 +1 @@
197
173
Original file line number Diff line number Diff line change
@@ -1 +1 @@
197
173
22 changes: 15 additions & 7 deletions src/libraries/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -561,13 +561,21 @@ library Pool {
/// @dev Executed within the pool constructor
/// @param tickSpacing The amount of required tick separation, realized in multiples of `tickSpacing`
/// e.g., a tickSpacing of 3 requires ticks to be initialized every 3rd tick i.e., ..., -6, -3, 0, 3, 6, ...
/// @return The max liquidity per tick
function tickSpacingToMaxLiquidityPerTick(int24 tickSpacing) internal pure returns (uint128) {
unchecked {
return uint128(
(type(uint128).max * uint256(int256(tickSpacing)))
/ uint256(int256(TickMath.MAX_TICK * 2 + tickSpacing))
);
/// @return result The max liquidity per tick
function tickSpacingToMaxLiquidityPerTick(int24 tickSpacing) internal pure returns (uint128 result) {
// Equivalent to:
// int24 minTick = (TickMath.MIN_TICK / tickSpacing) * tickSpacing;
// int24 maxTick = (TickMath.MAX_TICK / tickSpacing) * tickSpacing;
// uint24 numTicks = uint24((maxTick - minTick) / tickSpacing) + 1;
// return type(uint128).max / numTicks;
int24 MAX_TICK = TickMath.MAX_TICK;
int24 MIN_TICK = TickMath.MIN_TICK;
// tick spacing will never be 0 since TickMath.MIN_TICK_SPACING is 1
assembly {
let minTick := mul(sdiv(MIN_TICK, tickSpacing), tickSpacing)
let maxTick := mul(sdiv(MAX_TICK, tickSpacing), tickSpacing)
let numTicks := add(sdiv(sub(maxTick, minTick), tickSpacing), 1)
result := div(sub(shl(128, 1), 1), numTicks)
}
}

Expand Down
12 changes: 6 additions & 6 deletions test/Tick.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -116,35 +116,35 @@ contract TickTest is Test, GasSnapshot {
function testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForLowFee() public pure {
uint128 maxLiquidityPerTick = tickSpacingToMaxLiquidityPerTick(LOW_TICK_SPACING);

assertEq(maxLiquidityPerTick, 1917565579412846627735051215301243);
assertEq(maxLiquidityPerTick, 1917569901783203986719870431555990);
checkCantOverflow(LOW_TICK_SPACING, maxLiquidityPerTick);
}

function testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForMediumFee() public pure {
uint128 maxLiquidityPerTick = tickSpacingToMaxLiquidityPerTick(MEDIUM_TICK_SPACING);

assertEq(maxLiquidityPerTick, 11505069308564788430434325881101413); // 113.1 bits
assertEq(maxLiquidityPerTick, 11505743598341114571880798222544994);
checkCantOverflow(MEDIUM_TICK_SPACING, maxLiquidityPerTick);
}

function testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForHighFee() public pure {
uint128 maxLiquidityPerTick = tickSpacingToMaxLiquidityPerTick(HIGH_TICK_SPACING);

assertEq(maxLiquidityPerTick, 38347205785278154309959589375342946); // 114.7 bits
assertEq(maxLiquidityPerTick, 38350317471085141830651933667504588);
checkCantOverflow(HIGH_TICK_SPACING, maxLiquidityPerTick);
}

function testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForMinTickSpacing() public pure {
uint128 maxLiquidityPerTick = tickSpacingToMaxLiquidityPerTick(TickMath.MIN_TICK_SPACING);

assertEq(maxLiquidityPerTick, 191757530477355301479181766273477); // 126 bits
assertEq(maxLiquidityPerTick, 191757530477355301479181766273477);
checkCantOverflow(TickMath.MIN_TICK_SPACING, maxLiquidityPerTick);
}

function testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueForMaxTickSpacing() public pure {
uint128 maxLiquidityPerTick = tickSpacingToMaxLiquidityPerTick(TickMath.MAX_TICK_SPACING);

assertEq(maxLiquidityPerTick, 6169404334338910476561253576012511949);
assertEq(maxLiquidityPerTick, 6186952125835244790243174680577603844);
checkCantOverflow(TickMath.MAX_TICK_SPACING, maxLiquidityPerTick);
}

Expand All @@ -158,7 +158,7 @@ contract TickTest is Test, GasSnapshot {
function testTick_tickSpacingToMaxLiquidityPerTick_returnsTheCorrectValueFor2302() public pure {
uint128 maxLiquidityPerTick = tickSpacingToMaxLiquidityPerTick(2302);

assertEq(maxLiquidityPerTick, 440854192570431170114173285871668350); // 118 bits
assertEq(maxLiquidityPerTick, 441351967472034323558203122479595605);
checkCantOverflow(2302, maxLiquidityPerTick);
}

Expand Down
39 changes: 25 additions & 14 deletions test/libraries/Pool.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ pragma solidity ^0.8.20;

import {Test} from "forge-std/Test.sol";
import {Vm} from "forge-std/Vm.sol";
import {Pool} from "src/libraries/Pool.sol";
import {PoolManager} from "src/PoolManager.sol";
import {Position} from "src/libraries/Position.sol";
import {TickMath} from "src/libraries/TickMath.sol";
import {TickBitmap} from "src/libraries/TickBitmap.sol";
import {LiquidityAmounts} from "test/utils/LiquidityAmounts.sol";
import {Constants} from "test/utils/Constants.sol";
import {BalanceDelta} from "src/types/BalanceDelta.sol";
import {Slot0} from "src/types/Slot0.sol";
import {SafeCast} from "src/libraries/SafeCast.sol";
import {ProtocolFeeLibrary} from "src/libraries/ProtocolFeeLibrary.sol";
import {LPFeeLibrary} from "src/libraries/LPFeeLibrary.sol";

contract PoolTest is Test {
import {Pool} from "../../src/libraries/Pool.sol";
import {PoolManager} from "../../src/PoolManager.sol";
import {Position} from "../../src/libraries/Position.sol";
import {TickMath} from "../../src/libraries/TickMath.sol";
import {TickBitmap} from "../../src/libraries/TickBitmap.sol";
import {LiquidityAmounts} from "../../test/utils/LiquidityAmounts.sol";
import {Constants} from "../../test/utils/Constants.sol";
import {BalanceDelta} from "../../src/types/BalanceDelta.sol";
import {Slot0} from "../../src/types/Slot0.sol";
import {SafeCast} from "../../src/libraries/SafeCast.sol";
import {ProtocolFeeLibrary} from "../../src/libraries/ProtocolFeeLibrary.sol";
import {LPFeeLibrary} from "../../src/libraries/LPFeeLibrary.sol";
import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol";

contract PoolTest is Test, GasSnapshot {
using Pool for Pool.State;
using LPFeeLibrary for uint24;
using ProtocolFeeLibrary for uint24;
Expand Down Expand Up @@ -166,4 +167,14 @@ contract PoolTest is Test {
}
}
}

function test_fuzz_tickSpacingToMaxLiquidityPerTick(int24 tickSpacing) public pure {
vm.assume(tickSpacing > 0);
// v3 math
int24 minTick = (TickMath.MIN_TICK / tickSpacing) * tickSpacing;
int24 maxTick = (TickMath.MAX_TICK / tickSpacing) * tickSpacing;
uint24 numTicks = uint24((maxTick - minTick) / tickSpacing) + 1;
// assert that the result is the same as the v3 math
assertEq(type(uint128).max / numTicks, Pool.tickSpacingToMaxLiquidityPerTick(tickSpacing));
}
}

0 comments on commit f265610

Please sign in to comment.