Summary
testReturnJumps asserts currentReturn / previousReturn ~= 1.025, but the actual ratio is ~0.975 since higher tick means higher price and lower return. The test only passes due to the 10% tolerance.
Vulnerability Detail
function testReturnJumps() public pure {
for (uint256 i = 220; i <= 770; i++) {
uint256 previousReturn = _return(TickLib.tickToPrice(i - 1));
uint256 currentReturn = _return(TickLib.tickToPrice(i));
assertApproxEqRel(
currentReturn.mulDivDown(1e18, previousReturn), 1.025e18, 0.1e18, ...
);
}
}_return(price) = 1e18 / price - 1, which is 1/price - 1. Since tickToPrice is monotonically increasing, a higher tick gives a higher price and a lower return. Therefore currentReturn / previousReturn = 1/1.025 ~= 0.9756, not 1.025.
The assertion passes because |0.9756 - 1.025| / 1.025 ~= 4.8%, which is within the 10% relative tolerance.
Impact
The test does not verify what it intends to. The expected value should be ~0.9756e18 (i.e. 1/1.025), or the ratio should be flipped to previousReturn / currentReturn.
Code Snippet
Tool Used
Manual Review
Recommendation
Fix the assertion to check the correct ratio:
assertApproxEqRel(
previousReturn.mulDivDown(1e18, currentReturn), 1.025e18, 0.01e18, ...
);