Skip to content

Commit

Permalink
Optimize fee pips calculation in SwapMath
Browse files Browse the repository at this point in the history
Refactored the SwapMath module to optimize fee pips calculation. This was achieved by caching the feePips value to prevent redundant typecasts. This reduces computational overhead and may improve performance.
  • Loading branch information
shuhuiluo committed May 27, 2024
1 parent 83a5278 commit 41b4ce6
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
10 changes: 5 additions & 5 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,12 @@ SqrtPriceMathTest:testGas_GetNextSqrtPriceFromInput() (gas: 303466)
SqrtPriceMathTest:testGas_GetNextSqrtPriceFromInput_Og() (gas: 285701)
SqrtPriceMathTest:testGas_GetNextSqrtPriceFromOutput() (gas: 286328)
SqrtPriceMathTest:testGas_GetNextSqrtPriceFromOutput_Og() (gas: 269021)
SwapMathTest:testFuzz_ComputeSwapStep(uint160,uint160,uint128,int256,uint24) (runs: 65546, μ: 27026, ~: 27110)
SwapMathTest:testFuzz_ComputeSwapStepExactIn(uint160,uint160,uint128,uint256,uint24) (runs: 65546, μ: 29078, ~: 29027)
SwapMathTest:testFuzz_ComputeSwapStepExactOut(uint160,uint160,uint128,uint256,uint24) (runs: 65546, μ: 28605, ~: 28507)
SwapMathTest:testFuzz_ComputeSwapStep(uint160,uint160,uint128,int256,uint24) (runs: 65546, μ: 27023, ~: 27110)
SwapMathTest:testFuzz_ComputeSwapStepExactIn(uint160,uint160,uint128,uint256,uint24) (runs: 65546, μ: 29070, ~: 29020)
SwapMathTest:testFuzz_ComputeSwapStepExactOut(uint160,uint160,uint128,uint256,uint24) (runs: 65546, μ: 28608, ~: 28507)
SwapMathTest:testFuzz_getSqrtPriceTarget(bool,uint160,uint160) (runs: 65546, μ: 3503, ~: 3503)
SwapMathTest:testGas_ComputeSwapStep() (gas: 514575)
SwapMathTest:testGas_ComputeSwapStepExactIn() (gas: 534678)
SwapMathTest:testGas_ComputeSwapStep() (gas: 514269)
SwapMathTest:testGas_ComputeSwapStepExactIn() (gas: 533978)
SwapMathTest:testGas_ComputeSwapStepExactIn_Og() (gas: 563266)
SwapMathTest:testGas_ComputeSwapStepExactOut() (gas: 482433)
SwapMathTest:testGas_ComputeSwapStepExactOut_Og() (gas: 557512)
Expand Down
21 changes: 14 additions & 7 deletions src/SwapMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,23 @@ library SwapMath {
uint24 feePips
) internal pure returns (uint160 sqrtRatioNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount) {
unchecked {
uint256 _feePips = feePips; // cast once and cache
bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96;
uint256 feeComplement = MAX_FEE_PIPS - feePips;
bool exactOut = amountRemaining < 0;

if (!exactOut) {
uint256 amountRemainingLessFee = FullMath.mulDiv(uint256(amountRemaining), feeComplement, MAX_FEE_PIPS);
uint256 amountRemainingLessFee = FullMath.mulDiv(
uint256(amountRemaining),
MAX_FEE_PIPS - _feePips,
MAX_FEE_PIPS
);
amountIn = zeroForOne
? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true)
: SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true);
if (amountRemainingLessFee >= amountIn) {
// `amountIn` is capped by the target price
sqrtRatioNextX96 = sqrtRatioTargetX96;
feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement);
feeAmount = FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips);
} else {
// exhaust the remaining amount
amountIn = amountRemainingLessFee;
Expand Down Expand Up @@ -100,7 +104,7 @@ library SwapMath {
amountIn = zeroForOne
? SqrtPriceMath.getAmount0Delta(sqrtRatioNextX96, sqrtRatioCurrentX96, liquidity, true)
: SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioNextX96, liquidity, true);
feeAmount = FullMath.mulDivRoundingUp(amountIn, feePips, feeComplement);
feeAmount = FullMath.mulDivRoundingUp(amountIn, _feePips, MAX_FEE_PIPS - _feePips);
}
}
}
Expand All @@ -123,16 +127,19 @@ library SwapMath {
uint256 feePips
) internal pure returns (uint160 sqrtRatioNextX96, uint256 amountIn, uint256 amountOut) {
bool zeroForOne = sqrtRatioCurrentX96 >= sqrtRatioTargetX96;
uint256 feeComplement = UnsafeMath.sub(MAX_FEE_PIPS, feePips);
uint256 amountRemainingLessFee = FullMath.mulDiv(amountRemaining, feeComplement, MAX_FEE_PIPS);
uint256 amountRemainingLessFee = FullMath.mulDiv(
amountRemaining,
UnsafeMath.sub(MAX_FEE_PIPS, feePips),
MAX_FEE_PIPS
);
amountIn = zeroForOne
? SqrtPriceMath.getAmount0Delta(sqrtRatioTargetX96, sqrtRatioCurrentX96, liquidity, true)
: SqrtPriceMath.getAmount1Delta(sqrtRatioCurrentX96, sqrtRatioTargetX96, liquidity, true);
if (amountRemainingLessFee >= amountIn) {
// `amountIn` is capped by the target price
sqrtRatioNextX96 = sqrtRatioTargetX96;
// add the fee amount
amountIn = FullMath.mulDivRoundingUp(amountIn, MAX_FEE_PIPS, feeComplement);
amountIn = FullMath.mulDivRoundingUp(amountIn, MAX_FEE_PIPS, UnsafeMath.sub(MAX_FEE_PIPS, feePips));
} else {
// exhaust the remaining amount
amountIn = amountRemaining;
Expand Down

0 comments on commit 41b4ce6

Please sign in to comment.