Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: medium
Invalid

Decimal Precision Loss in Price Calculations

Summary

The contract does not validate or handle decimal precision of price values returned from ChainlinkPriceFeeds, which could lead to loss of precision during price calculations.

Vulnerability Details

The consult() and consultIn18Decimals() functions directly use the int256 price returned from Chainlink without checking its decimal precision against the recorded decimals value.

function consult(address token) public view whenNotPaused returns (int256, uint8) {
address _feed = feeds[token];
if (_feed == address(0)) revert Errors.NoTokenPriceFeedAvailable();
ChainlinkResponse memory chainlinkResponse = _getChainlinkResponse(_feed);
ChainlinkResponse memory prevChainlinkResponse = _getPrevChainlinkResponse(_feed, chainlinkResponse.roundId);
if (_chainlinkIsFrozen(chainlinkResponse, token)) revert Errors.FrozenTokenPriceFeed();
if (_chainlinkIsBroken(chainlinkResponse, prevChainlinkResponse, token)) revert Errors.BrokenTokenPriceFeed();
return (chainlinkResponse.answer, chainlinkResponse.decimals);
}
function consultIn18Decimals(address token) external view whenNotPaused returns (uint256) {
(int256 _answer, uint8 _decimals) = consult(token);
return _answer.toUint256() * 1e18 / (10 ** _decimals);
}

For example, if a price is returned with only 2 decimal places of precision but recorded as having 8 decimal places, calculations using that price could lose significant precision.

Specifically, the price deviation calculation in _badPriceDeviation() performs division and multiplication on the raw int256 price values. Any loss of trailing zeros due to unequal decimals could skew the percentage deviation calculated.

Even if the recorded decimals are correct, the contract makes no effort to scale price values to a common decimal place before calculations. This risks mathematical errors over multiple calculation steps

Impact

Loss of decimal precision in price values could cause calculated percentages like maximum deviations to be inaccurate.
This could allow price feeds that should fail validity checks to still be considered valid due to flaws in the calculation logic.
Over time, repeated calculations on imprecise values risk drifting calculated results like historical price averages.

Tools Used

Manual Reveiw

Recommendations

Validate recorded decimals against the number of decimal places actually present in returned int256 price values

Perform price calculations using a common scaling factor to homogenize decimals before mathematical operations

Add decimal place verification whenever prices are retrieved, not just on initial recording

Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.