fix: Test coverage: Kraiken + VWAPTracker to 100% (#283)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-02-26 05:12:48 +00:00
parent 2baa913435
commit e9370c143e
2 changed files with 162 additions and 0 deletions

View file

@ -445,4 +445,81 @@ contract VWAPTrackerTest is Test {
// Verify mathematical consistency
assertEq(minPriceForOverflow, minProductForOverflow / maxReasonableFee, "Price calculation correct");
}
// ========================================
// SINGLE-TRANSACTION OVERFLOW PROTECTION
// ========================================
/**
* @notice Test the ultra-rare single-transaction overflow protection (lines 36-41 of VWAPTracker)
* @dev Uses a price so large that price * volume exceeds type(uint256).max / 2 without
* itself overflowing uint256. This exercises the cap-and-recalculate branch.
*/
function testSingleTransactionOverflowProtection() public {
// Choose price such that price * (fee * 100) > type(uint256).max / 2
// but the multiplication itself does NOT overflow uint256.
//
// price = type(uint256).max / 200, fee = 2
// volume = fee * 100 = 200
// volumeWeightedPrice = (type(uint256).max / 200) * 200
// = type(uint256).max - (type(uint256).max % 200) safely below max
// >> type(uint256).max / 2 triggers the guard
uint256 extremePrice = type(uint256).max / 200;
uint256 largeFee = 2;
vwapTracker.recordVolumeAndPrice(extremePrice, largeFee);
// After the cap: volumeWeightedPrice = type(uint256).max / 2
// volume = (type(uint256).max / 2) / extremePrice
uint256 cappedVWP = type(uint256).max / 2;
uint256 expectedVolume = cappedVWP / extremePrice;
assertEq(
vwapTracker.cumulativeVolumeWeightedPriceX96(), cappedVWP, "Single-tx overflow: cumulative VWAP should be capped"
);
assertEq(vwapTracker.cumulativeVolume(), expectedVolume, "Single-tx overflow: volume should be recalculated from cap");
// VWAP should equal the extreme price (capped numerator / recalculated denominator)
assertEq(vwapTracker.getVWAP(), extremePrice, "VWAP should equal the extreme price after cap");
}
// ========================================
// MAXIMUM COMPRESSION FACTOR (>1000x) TEST
// ========================================
/**
* @notice Test that compressionFactor is capped at 1000 when historical data is very large
* @dev Sets cumulativeVolumeWeightedPriceX96 to type(uint256).max / 100 so that
* compressionFactor = (max/100) / (max/10^6) + 1 = 10000 + 1 > 1000 capped to 1000.
*/
function testMaxCompressionFactorCapped() public {
// maxSafeValue = type(uint256).max / 10^6
// compressionFactor = largeVWAP / maxSafeValue + 1 = (max/100)/(max/10^6) + 1 = 10^4 + 1
// Since 10^4 + 1 > 1000, it must be capped to 1000.
uint256 largeVWAP = type(uint256).max / 100;
uint256 largeVolume = 10 ** 20;
vm.store(address(vwapTracker), bytes32(uint256(0)), bytes32(largeVWAP));
vm.store(address(vwapTracker), bytes32(uint256(1)), bytes32(largeVolume));
vwapTracker.recordVolumeAndPrice(SAMPLE_PRICE_X96, SAMPLE_FEE);
uint256 compressionFactor = 1000; // capped from 10001
uint256 newVolume = SAMPLE_FEE * 100;
uint256 newVWP = SAMPLE_PRICE_X96 * newVolume;
uint256 expectedCumulativeVWAP = largeVWAP / compressionFactor + newVWP;
uint256 expectedCumulativeVolume = largeVolume / compressionFactor + newVolume;
assertEq(
vwapTracker.cumulativeVolumeWeightedPriceX96(),
expectedCumulativeVWAP,
"Max compression: cumulative VWAP should be compressed by exactly 1000"
);
assertEq(
vwapTracker.cumulativeVolume(),
expectedCumulativeVolume,
"Max compression: cumulative volume should be compressed by exactly 1000"
);
}
}