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.
In LendingPool::initiateLiquidation, the protocol checks if a user’s account is unhealthy by comparing healthFactor with healthFactorLiquidationThreshold. The calculateHealthFactor function is implemented as:
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.
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.
Manual Code Review and Foundry
Use the actual decimals of reserveAssetToken when calculating healthFactor.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.