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

users may get liquidated more than expected

Summary

There is no precision scaling for tokenAmountFromDebtCovered, this cause huge amount of user's collateral get liquidated.

Vulnerability Details

For liquidating a user whose health factor is below the minimum health factor, users can call liquidate function.

this function will take a debt amount in USDC from caller in order to liquidate the target user and it calls getTokenAmountFromUsd function to calculate the collateral that can be liquidated, here is getTokenAmountFromUsd:

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

As you can see it returns the price with 18 decimals, after that liquidate function calculate bonusCollateraland add the returned value from getTokenAmountFromUsd with bonusCollateral to get value that should be paid to liquidator (collaterlal of target user)

uint256 bonusCollateral = (tokenAmountFromDebtCovered * LIQUIDATION_BONUS) / LIQUIDATION_PRECISION;
uint256 totalCollateralToRedeem = tokenAmountFromDebtCovered + bonusCollateral;

After this calculations it sends totalCollateralToRedeem from target user's collateral to liquidator with help of _redeemCollateral function.

But the problem is if the token that liquidator want to receive in return (collateral token) has not 18 decimals the totalCollateralToRedeem value will be incorrect since it has 18 decimals.

Impact

If liquidator wants to liquidate the target user's WBTC (WBTC has 8 decimals) the target user will lose alots of WBTC because the totalCollateralToRedeem has 18 decimals.

Imagine the value that target should be liquidated is 1 WBTC:

expected totalCollateralToRedeem: 100000000 (8 decimals)

actual value of totalCollateralToRedeem : 1000000000000000000 (18 decimals)

then target will get liquidated by 10000000000 WBTC not 1

Tools Used

Manual Analysis

Recommendations

You should scale precision of tokenAmountFromDebtCovered to token's precision in order to code work correctly, it should look like this:

uint256 tokenAmountFromDebtCovered = getTokenAmountFromUsd(collateral, debtToCover);
+ uint8 decimals = IERC20(collateral).decimals()
+ if(decimals != 18){
+ tokenAmountFromDebtCovered = (tokenAmountFromDebtCovered * (10 ** decimals)) / 1e18;
+ }
uint256 bonusCollateral = (tokenAmountFromDebtCovered * LIQUIDATION_BONUS) / LIQUIDATION_PRECISION;
uint256 totalCollateralToRedeem = tokenAmountFromDebtCovered + bonusCollateral;
_redeemCollateral(user, msg.sender, collateral, totalCollateralToRedeem);

Support

FAQs

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