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

Refactor swap logic and add getSqrtPriceTarget function #662

Merged
merged 2 commits into from
May 21, 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/poolManager bytecode size.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
21647
21575
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 @@
116560
116430
2 changes: 1 addition & 1 deletion .forge-snapshots/simple swap.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
131721
131591
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 @@
182859
182729
Original file line number Diff line number Diff line change
@@ -1 +1 @@
112368
112303
2 changes: 1 addition & 1 deletion .forge-snapshots/swap against liquidity.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
123711
123646
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 @@
135713
135638
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 @@
124966
124901
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 @@
146970
146895
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 @@
163575
163445
Original file line number Diff line number Diff line change
@@ -1 +1 @@
221752
221557
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 @@
147776
147646
2 changes: 1 addition & 1 deletion .forge-snapshots/swap with hooks.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
123723
123658
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 @@
179956
179826
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 @@
155635
155505
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 @@
158238
158108
6 changes: 1 addition & 5 deletions src/libraries/Pool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,7 @@ library Pool {
// compute values to swap to the target tick, price limit, or point where input/output amount is exhausted
(state.sqrtPriceX96, step.amountIn, step.amountOut, step.feeAmount) = SwapMath.computeSwapStep(
state.sqrtPriceX96,
(
zeroForOne
? step.sqrtPriceNextX96 < params.sqrtPriceLimitX96
: step.sqrtPriceNextX96 > params.sqrtPriceLimitX96
) ? params.sqrtPriceLimitX96 : step.sqrtPriceNextX96,
SwapMath.getSqrtPriceTarget(zeroForOne, step.sqrtPriceNextX96, params.sqrtPriceLimitX96),
state.liquidity,
state.amountSpecifiedRemaining,
swapFee
Expand Down
23 changes: 23 additions & 0 deletions src/libraries/SwapMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ import {SqrtPriceMath} from "./SqrtPriceMath.sol";
/// @title Computes the result of a swap within ticks
/// @notice Contains methods for computing the result of a swap within a single tick price range, i.e., a single tick.
library SwapMath {
/// @notice Computes the sqrt price target for the next swap step
/// @param zeroForOne The direction of the swap, true for currency0 to currency1, false for currency1 to currency0
/// @param sqrtPriceNextX96 The Q64.96 sqrt price for the next initialized tick
/// @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this value
/// after the swap. If one for zero, the price cannot be greater than this value after the swap
/// @return sqrtPriceTargetX96 The price target for the next swap step
function getSqrtPriceTarget(bool zeroForOne, uint160 sqrtPriceNextX96, uint160 sqrtPriceLimitX96)
internal
pure
returns (uint160 sqrtPriceTargetX96)
{
assembly {
// a flag to toggle between sqrtPriceNextX96 and sqrtPriceLimitX96
// when zeroForOne == true, nextOrLimit reduces to sqrtPriceNextX96 >= sqrtPriceLimitX96
// sqrtPriceTargetX96 = max(sqrtPriceNextX96, sqrtPriceLimitX96)
// when zeroForOne == false, nextOrLimit reduces to sqrtPriceNextX96 < sqrtPriceLimitX96
// sqrtPriceTargetX96 = min(sqrtPriceNextX96, sqrtPriceLimitX96)
let nextOrLimit := xor(lt(sqrtPriceNextX96, sqrtPriceLimitX96), zeroForOne)
let symDiff := xor(sqrtPriceNextX96, sqrtPriceLimitX96)
sqrtPriceTargetX96 := xor(sqrtPriceLimitX96, mul(symDiff, nextOrLimit))
Copy link
Contributor

Choose a reason for hiding this comment

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

🤯 woah thats cool

}
}

/// @notice Computes the result of swapping some amount in, or amount out, given the parameters of the swap
/// @dev If the swap's amountSpecified is negative, the combined fee and input amount will never exceed the absolute value of the remaining amount.
/// @param sqrtPriceCurrentX96 The current sqrt price of the pool
Expand Down
12 changes: 12 additions & 0 deletions test/libraries/SwapMath.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ contract SwapMathTest is Test, GasSnapshot {
uint160 private constant SQRT_PRICE_1010_100 = 251791039410471229173201122529;
uint160 private constant SQRT_PRICE_10000_100 = 792281625142643375935439503360;

function test_fuzz_getSqrtPriceTarget(bool zeroForOne, uint160 sqrtPriceNextX96, uint160 sqrtPriceLimitX96)
public
pure
{
assertEq(
SwapMath.getSqrtPriceTarget(zeroForOne, sqrtPriceNextX96, sqrtPriceLimitX96),
(zeroForOne ? sqrtPriceNextX96 < sqrtPriceLimitX96 : sqrtPriceNextX96 > sqrtPriceLimitX96)
? sqrtPriceLimitX96
: sqrtPriceNextX96
);
}

function test_computeSwapStep_exactAmountIn_oneForZero_thatGetsCappedAtPriceTargetIn() public pure {
uint160 priceTarget = SQRT_PRICE_101_100;
uint160 price = SQRT_PRICE_1_1;
Expand Down
Loading