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

In `getTokenAmountFromUsd`, `price` is treated as in 8 decimals that will force to return incorrect amount usd amount for given token leading to loss of funds

Summary

It has been mentioned by Protocol members that they will be using any token as a collateral as long as token/usd pricefeed is available in chainlink pricefeed.

But at many places it is hardcoded that token/usd pricefeed always return price in 8 decimals.
There are many tokens that don't return price in 8 decimals on different chains
e.g On Mainnet - LDO / USD
Avalanche - AAPL / USD , AMZN / USD,Calculated SAVAX / USD, GOOGL / USD NFLX / USD, TSLA / USD
Arbitrum - PEPE / USD
Optimism - PEPE / USD

for these tokens pricefeed would not return price in 8 decimals causing incorrect values

Vulnerability Details

See Summary

File: src/DSCEngine.sol
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();
// ($10e18 * 1e18) / ($2000e8 * 1e10)
return (usdAmountInWei * PRECISION) / (uint256(price) * ADDITIONAL_FEED_PRECISION);
}
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
return ((uint256(price) * ADDITIONAL_FEED_PRECISION) * amount) / PRECISION;
}

https://github.com/Cyfrin/2023-07-foundry-defi-stablecoin/blob/main/src/DSCEngine.sol#L340C1-L348C6
https://github.com/Cyfrin/2023-07-foundry-defi-stablecoin/blob/main/src/DSCEngine.sol#L361C5-L368C1

Impact

most of the time getTokenAmountFromUsd will return zero as these will returns price in 18 decimals making denominatore of the order of (1018) * (1010)= 10**28 and getUsdValue will return more than expected usd value

Tools Used

Manual Review

Recommendations

  1. One solution can be only allow tokens which returns price in 8 decimal

but as it intented to use for most of the tokens

  1. Rathar than using hardcoded 8 decimals use returns price and scale into 18 decimal

Support

FAQs

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