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

Optimize position and factor out logic to compute compressed tick in TickBitmap #654

Merged
merged 5 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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/addLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
329444
329428
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 @@
284085
284069
Original file line number Diff line number Diff line change
@@ -1 +1 @@
299632
299616
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22504
22496
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5513
5505
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2578
2488
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2578
2488
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2556
2475
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2865
2784
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2556
2475
2 changes: 1 addition & 1 deletion .forge-snapshots/poolManager bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
23738
23656
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity CA fee.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
184931
184915
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 @@
120975
120959
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 @@
117750
117734
2 changes: 1 addition & 1 deletion .forge-snapshots/removeLiquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
120963
120947
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 @@
117339
117109
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
132578
132348
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 @@
184809
184579
Original file line number Diff line number Diff line change
@@ -1 +1 @@
113800
113651
2 changes: 1 addition & 1 deletion .forge-snapshots/swap against liquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
125221
125072
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 @@
137207
137049
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 @@
126323
126242
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 @@
148385
148295
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 @@
165202
164972
Original file line number Diff line number Diff line change
@@ -1 +1 @@
224701
224322
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 @@
149469
149239
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with hooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
125233
125084
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 @@
181791
181561
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 @@
160022
159792
30 changes: 22 additions & 8 deletions src/libraries/TickBitmap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,29 @@ library TickBitmap {
/// @param tickSpacing The tick spacing of the pool
error TickMisaligned(int24 tick, int24 tickSpacing);

/// @dev round towards negative infinity
function compress(int24 tick, int24 tickSpacing) internal pure returns (int24 compressed) {
// compressed = tick / tickSpacing;
// if (tick < 0 && tick % tickSpacing != 0) compressed--;
assembly {
compressed :=
sub(
sdiv(tick, tickSpacing),
// if (tick < 0 && tick % tickSpacing != 0) then tick % tickSpacing < 0, vice versa
Copy link
Contributor

Choose a reason for hiding this comment

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

nice

slt(smod(tick, tickSpacing), 0)
)
}
}

/// @notice Computes the position in the mapping where the initialized bit for a tick lives
/// @param tick The tick for which to compute the position
/// @return wordPos The key in the mapping containing the word in which the bit is stored
/// @return bitPos The bit position in the word where the flag is stored
function position(int24 tick) internal pure returns (int16 wordPos, uint8 bitPos) {
unchecked {
wordPos = int16(tick >> 8);
bitPos = uint8(int8(tick & (256 - 1)));
assembly {
// signed arithmetic shift right
wordPos := sar(8, tick)
bitPos := and(tick, 0xff)
}
}

Expand Down Expand Up @@ -51,8 +66,7 @@ library TickBitmap {
bool lte
) internal view returns (int24 next, bool initialized) {
unchecked {
int24 compressed = tick / tickSpacing;
if (tick < 0 && tick % tickSpacing != 0) compressed--; // round towards negative infinity
int24 compressed = compress(tick, tickSpacing);

if (lte) {
(int16 wordPos, uint8 bitPos) = position(compressed);
Expand All @@ -68,7 +82,7 @@ library TickBitmap {
: (compressed - int24(uint24(bitPos))) * tickSpacing;
} else {
// start from the word of the next tick, since the current tick state doesn't matter
(int16 wordPos, uint8 bitPos) = position(compressed + 1);
(int16 wordPos, uint8 bitPos) = position(++compressed);
// all the 1s at or to the left of the bitPos
uint256 mask = ~((1 << bitPos) - 1);
uint256 masked = self[wordPos] & mask;
Expand All @@ -77,8 +91,8 @@ library TickBitmap {
initialized = masked != 0;
// overflow/underflow is possible, but prevented externally by limiting both tickSpacing and tick
next = initialized
? (compressed + 1 + int24(uint24(BitMath.leastSignificantBit(masked) - bitPos))) * tickSpacing
: (compressed + 1 + int24(uint24(type(uint8).max - bitPos))) * tickSpacing;
? (compressed + int24(uint24(BitMath.leastSignificantBit(masked) - bitPos))) * tickSpacing
: (compressed + int24(uint24(type(uint8).max - bitPos))) * tickSpacing;
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions test/libraries/TickBitmap.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ contract TickBitmapTest is Test, GasSnapshot {
}
}

function test_fuzz_compress(int24 tick, int24 tickSpacing) public pure {
tickSpacing = int24(bound(tickSpacing, 1, type(int24).max));
int24 compressed = tick / tickSpacing;
if (tick < 0 && tick % tickSpacing != 0) compressed--;
assertEq(TickBitmap.compress(tick, tickSpacing), compressed);
}

function test_fuzz_position(int24 tick) public pure {
(int16 wordPos, uint8 bitPos) = TickBitmap.position(tick);
assertEq(wordPos, tick >> 8);
assertEq(bitPos, uint8(int8(tick % 256)));
}

function test_isInitialized_isFalseAtFirst() public view {
assertEq(isInitialized(1), false);
}
Expand Down
Loading