test(libraries): add math library unit tests

This commit is contained in:
dualfroz committed 2026-08-27 11:44:00 +02:00
1 parent b2ec603567
commit da99c14cdd
2 files changed
+160

No files matched your search

+90
View File
@@ -0,0 +1,90 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.36;
import {Test} from "forge-std/Test.sol";
import {TickMath} from "../src/libraries/TickMath.sol";
import {SqrtPriceMath} from "../src/libraries/SqrtPriceMath.sol";
import {SwapMath} from "../src/libraries/SwapMath.sol";
import {FullMath} from "../src/libraries/FullMath.sol";
contract ClMathTest is Test {
uint160 private constant priceAtTickZero = 79228162514264337593543950336;
function testSqrtRatioAtKnownTicks() public pure {
assertEq(TickMath.getSqrtRatioAtTick(0), priceAtTickZero);
assertEq(TickMath.getSqrtRatioAtTick(TickMath.minTick), TickMath.minSqrtRatio);
assertEq(TickMath.getSqrtRatioAtTick(TickMath.maxTick), TickMath.maxSqrtRatio);
}
function testTickAtKnownRatios() public pure {
assertEq(TickMath.getTickAtSqrtRatio(priceAtTickZero), 0);
assertEq(TickMath.getTickAtSqrtRatio(TickMath.minSqrtRatio), TickMath.minTick);
}
function testSqrtRatioMonotonic() public pure {
assertGt(TickMath.getSqrtRatioAtTick(1), TickMath.getSqrtRatioAtTick(0));
assertLt(TickMath.getSqrtRatioAtTick(-1), TickMath.getSqrtRatioAtTick(0));
assertGt(TickMath.getSqrtRatioAtTick(500000), TickMath.getSqrtRatioAtTick(499999));
}
function testFuzzTickRoundTrip(int24 tick) public pure {
tick = int24(bound(tick, TickMath.minTick, TickMath.maxTick));
uint160 ratio = TickMath.getSqrtRatioAtTick(tick);
if (ratio >= TickMath.maxSqrtRatio) return;
int24 recovered = TickMath.getTickAtSqrtRatio(ratio);
assertEq(recovered, tick);
}
function testFuzzTickAtRatioWithinBounds(uint160 ratio) public pure {
ratio = uint160(bound(ratio, TickMath.minSqrtRatio, TickMath.maxSqrtRatio - 1));
int24 tick = TickMath.getTickAtSqrtRatio(ratio);
assertGe(TickMath.getSqrtRatioAtTick(tick), TickMath.minSqrtRatio == 0 ? 0 : 0);
assertLe(TickMath.getSqrtRatioAtTick(tick), ratio);
assertGt(TickMath.getSqrtRatioAtTick(tick + 1), ratio);
}
function testAmount1DeltaKnown() public pure {
uint160 a = TickMath.getSqrtRatioAtTick(0);
uint160 b = TickMath.getSqrtRatioAtTick(120);
uint256 delta = SqrtPriceMath.getAmount1Delta(a, b, 1e18, false);
assertEq(delta, FullMath.mulDiv(1e18, b - a, 0x1000000000000000000000000));
}
function testAmount0DeltaSymmetric() public pure {
uint160 a = TickMath.getSqrtRatioAtTick(-60);
uint160 b = TickMath.getSqrtRatioAtTick(60);
uint256 up = SqrtPriceMath.getAmount0Delta(a, b, 5e18, true);
uint256 down = SqrtPriceMath.getAmount0Delta(a, b, 5e18, false);
assertGe(up, down);
assertLe(up - down, 1);
}
function testComputeSwapStepExactInReachesTarget() public pure {
uint160 current = TickMath.getSqrtRatioAtTick(0);
uint160 target = TickMath.getSqrtRatioAtTick(-600);
(uint160 next, uint256 amountIn, uint256 amountOut, uint256 feeAmount) =
SwapMath.computeSwapStep(current, target, 1e21, 1e24, 3000);
assertEq(next, target);
assertGt(amountIn, 0);
assertGt(amountOut, 0);
assertGt(feeAmount, 0);
}
function testComputeSwapStepPartialFill() public pure {
uint160 current = TickMath.getSqrtRatioAtTick(0);
uint160 target = TickMath.getSqrtRatioAtTick(-600);
(uint160 next,, uint256 amountOut,) = SwapMath.computeSwapStep(current, target, 1e21, 1e15, 3000);
assertGt(next, target);
assertLt(next, current);
assertGt(amountOut, 0);
}
function testFuzzComputeSwapStepFeeBound(uint128 liquidity, uint128 amount) public pure {
liquidity = uint128(bound(liquidity, 1e12, 1e30));
int256 amountIn = int256(uint256(bound(amount, 1, 1e30)));
uint160 current = TickMath.getSqrtRatioAtTick(0);
uint160 target = TickMath.getSqrtRatioAtTick(-887000);
(, uint256 stepIn,, uint256 feeAmount) = SwapMath.computeSwapStep(current, target, liquidity, amountIn, 3000);
assertLe(stepIn + feeAmount, uint256(amountIn));
}
}