Category: Coding Mistakes
Unhandled edge case in the twap
function of PriceHistoryLib
Low Severity
Low Impact
Low Likelihood
Description
If there is only one PriceSnapshot
in history and its timestamp is equal to block.timestamp
, the elapsedTime
variable will be zero. This causes the twap
function to fail due to a division-by-zero error.
function twap(PriceHistory storage history, uint256 twapInterval) internal view returns (uint256) {
uint256 idx = history.snapshots.length;
if (idx == 0) return 0;
PriceSnapshot memory currentSnapshot = history.snapshots[--idx];
uint256 targetTime = block.timestamp - twapInterval;
uint256 timePeriod = block.timestamp - currentSnapshot.timestamp;
uint256 elapsedTime = timePeriod;
uint256 weightedPrice = currentSnapshot.price * timePeriod;
uint256 previousTime = currentSnapshot.timestamp;
while (currentSnapshot.timestamp > targetTime) {
//[...]
}
return weightedPrice / elapsedTime;
}
Impact
If this division-by-zero error occurs, the settleFunding
function, which calls the twap
function, will also fail. Consequently, the admin cannot update the funding rate in this specific case.
Recommendations
We recommend returning the price value instead of reverting in this specific case to make the twap
function more robust.