diff --git a/contracts/amm/spread/SpreadCloseSwapService.sol b/contracts/amm/spread/SpreadCloseSwapService.sol index 7de46a1cf..b6e1117a4 100644 --- a/contracts/amm/spread/SpreadCloseSwapService.sol +++ b/contracts/amm/spread/SpreadCloseSwapService.sol @@ -79,16 +79,26 @@ contract SpreadCloseSwapService is ISpreadCloseSwapService { actualTimeWeightedNotionalToSave = 0; swapTimePast = 0; } + // @dev Ensure denominator is at least 1% of tenor to prevent near-zero division + // that could cause uint96 overflow in SpreadStorageLibs.saveTimeWeightedNotionalForAssetAndTenor + uint256 denominator = tenorInSeconds - swapTimePast; + uint256 minDenominator = tenorInSeconds / 100; + if (minDenominator == 0) { + minDenominator = 1; + } + if (denominator < minDenominator) { + denominator = minDenominator; + } if (direction == 0) { timeWeightedNotional.lastUpdateTimePayFixed = lastOpenSwap.openSwapTimestamp; timeWeightedNotional.timeWeightedNotionalPayFixed = (actualTimeWeightedNotionalToSave * tenorInSeconds) / - (tenorInSeconds - swapTimePast); + denominator; } else { timeWeightedNotional.lastUpdateTimeReceiveFixed = lastOpenSwap.openSwapTimestamp; timeWeightedNotional.timeWeightedNotionalReceiveFixed = (actualTimeWeightedNotionalToSave * tenorInSeconds) / - (tenorInSeconds - swapTimePast); + denominator; } } else { if (direction == 0) {