15,000 USDC
View results
Submission Details
Severity: medium
Valid

All of the USD pair price feeds doesn't have 8 decimals

Summary

DSCEngine contract assumes all of the USD pair chinlink price feeds have 8 decimals but there are certain token's USD feed has a different decimals

Vulnerability Details

In the getTokenAmountFromUsd and getUsdValue functions price of tokens are calculated with chainlink price feeds and the function assumed that all of USD pairs has 8 decimals but there are certain tokens which they have different decimals.

For example AMPL / USD feed has 18 decimals

So if some tokens's price feed has not 8 decimals it will break a lots of things in the contract

Impact

Since returned value of this two functions is used for health factor and liquidation process it will cause loss of funds for users and protocol

Tools Used

Manual Analysis

Recommendations

Consider calling decimals() function on the price feed contract to get the correct decimals and calculate the value based on the returned decimals

function getTokenAmountFromUsd(address token, uint256 usdAmountInWei) public view returns (uint256) {
// price of ETH (token)
// $/ETH ETH ??
// $2000 / ETH. $1000 = 0.5 ETH
AggregatorV3Interface priceFeed = AggregatorV3Interface(s_priceFeeds[token]);
(, int256 price,,,) = priceFeed.staleCheckLatestRoundData();
+ uint8 decimals = priceFeed.decimals();
+ uint256 priceWithDecimals = (uint256(price) * 1e18) / (10 ** decimals);
- return (usdAmountInWei * PRECISION) / (uint256(price) * ADDITIONAL_FEED_PRECISION);
+ return (usdAmountInWei * PRECISION) / priceWithDecimals;
}
function getUsdValue(address token, uint256 amount) public view returns (uint256) {
AggregatorV3Interface priceFeed = AggregatorV3Interface(s_priceFeeds[token]);
(, int256 price,,,) = priceFeed.staleCheckLatestRoundData();
// 1 ETH = $1000
// The returned value from CL will be 1000 * 1e8
+ uint8 decimals = priceFeed.decimals();
+ uint256 priceWithDecimals = (uint256(price) * 1e18) / (10 ** decimals);
- return ((uint256(price) * ADDITIONAL_FEED_PRECISION) * amount) / PRECISION;
+ return (priceWithDecimals * amount) / PRECISION;
}

Support

FAQs

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