Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Invalid

Decimal Mismatch in Health Factor Calculation

01. Relevant GitHub Links

02. Summary

The LendingPool contract’s calculateHealthFactor function calculates a user’s health factor using a fixed assumption of 18 decimals. This can lead to incorrect results if reserveAssetToken does not actually have 18 decimals. Consequently, users might be liquidated at the wrong time or fail to be liquidated when they should.

03. Vulnerability Details

In LendingPool::initiateLiquidation, the protocol checks if a user’s account is unhealthy by comparing healthFactor with healthFactorLiquidationThreshold. The calculateHealthFactor function is implemented as:

/**
* @notice Calculates the user's health factor
* @param userAddress The address of the user
* @return The health factor (in RAY)
*/
function calculateHealthFactor(
address userAddress
) public view returns (uint256) {
uint256 collateralValue = getUserCollateralValue(userAddress);
uint256 userDebt = getUserDebt(userAddress);
if (userDebt < 1) return type(uint256).max;
uint256 collateralThreshold = collateralValue.percentMul(
liquidationThreshold
);
@> return (collateralThreshold * 1e18) / userDebt;
}

This assumes reserveAssetToken is always 18-decimal. If it has different decimals, the calculation will be inaccurate. Although healthFactorLiquidationThreshold can be changed, the real issue is the hardcoded 1e18 multiplier in the health factor logic.

Also, the comment says that The health factor is returned in RAY, but it is not actually returned in RAY.

Additionally, the default value of healthFactorLiquidationThreshold here is 1e18, which is tailored for when reserveAssetToken is 1e18. However, reserveAssetToken can be a stable coin with a different decimal. However, this doesn't matter much because you can change the value of healthFactorLiquidationThreshold later.

04. Impact

  • If the token has fewer than 18 decimals, the user’s health factor might be computed as too high, preventing necessary liquidations.

  • If the token has more than 18 decimals, the health factor might be computed as too low, triggering premature liquidations.

05. Tools Used

Manual Code Review and Foundry

06. Recommended Mitigation

Use the actual decimals of reserveAssetToken when calculating healthFactor.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!