fix: Test coverage: Kraiken + VWAPTracker to 100% (#283)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2baa913435
commit
e9370c143e
2 changed files with 162 additions and 0 deletions
|
|
@ -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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue