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

Token price in USD will be wrong when the token’s USD price feed is `decimals != 8`

Summary

The response from the Chainlink Oracle price feed always assumes 8 decimals, However, there are certain tokens where USD feed has different decimals.

Vulnerability Details

In the current implementation, the price conversion is hard coded to work when price feed decimals are 8.
((uint256(price) * ADDITIONAL_FEED_PRECISION) * amount) / PRECISION

However, there are tokens with USD price feed's decimals != 8 (e.g.: AMPL / USD feed decimals = 18)

(AMPL / USD) Price Feed - https://etherscan.io/address/0xe20CA8D7546932360e37E9D72c1a47334af57706

Instances

https://github.com/Cyfrin/2023-07-foundry-defi-stablecoin/blob/main/src/DSCEngine.sol#L347

https://github.com/Cyfrin/2023-07-foundry-defi-stablecoin/blob/main/src/DSCEngine.sol#L366

Impact

When the price feed with decimals != 8 is set, can lead to incorrect conversion and potentially draining all of the funds.

Tools Used

Manual Review / Foundry

Recommendations

Add a check for price feed decimals in the OracleLib library to prevent the precision loss, or add a check in the constructor and only allow price feeds with 8 decimals.

constructor(address[] memory tokenAddresses, address[] memory priceFeedAddresses, address dscAddress) {
// USD Price Feeds
if (tokenAddresses.length != priceFeedAddresses.length) {
revert DSCEngine__TokenAddressesAndPriceFeedAddressesMustBeSameLength();
}
// For example ETH / USD, BTC / USD, MKR / USD, etc
for (uint256 i = 0; i < tokenAddresses.length; i++) {
+ if (AggregatorV3Interface(priceFeedAddresses[i]).decimals() != 8) {
+ revert DSCEngine__PriceFeedDecimals();
+ }
s_priceFeeds[tokenAddresses[i]] = priceFeedAddresses[i];
s_collateralTokens.push(tokenAddresses[i]);
}
i_dsc = DecentralizedStableCoin(dscAddress);
}

Support

FAQs

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