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

Incorrect conversion of Collateral Amount to USD

Summary

The conversions between collateral amount and USD doesn't take care of the decimals of the collateral token. This leads to incorrect value associated with the collateral making some collateral worth more and some worth less thereby breaking the value of the coin.

Vulnerability Details

The conversions between collateral amount and USD doesn't handle the different decimals associated with each collateral.

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;
}
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);
}

WETH has 18 decimals while WBTC has 8 decimals on Ethereum.

Impact

A user who deposits a collateral with lower number of decimals can only mint fewer tokens compared to a user who deposits a collateral with higher number of decimals even if both tokens amount to the same value. This will break the model of the system where it is assumed that the stablecoin tokens can be minted according to the underlying USD value of the collateral.

Tools Used

Manual Review

Recommendations

Factor in the decimals of the collateral by replacing collateral amount with

(collateral_amount * 10e18) / (10**collateral_decimals)

Eg:

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 * 10e18) / (PRECISION * 10eCOLLATERAL_DECIMALS);
}

Support

FAQs

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