The LendingPool contract allows liquidation of healthy positions due to precision loss in health factor calculations. When a borrower's position has a health factor above 1.0 (indicating safe collateralization), the contract still permits liquidation due to mathematical rounding errors in the division operations.
The key issue is in the final calculation where standard division is used instead of the protocol's WadRayMath
library. This creates inconsistency since the rest of the protocol uses ray math (27 decimals) for precise calculations. The percentMul
operation maintains precision, but it's lost in the final division step.
The health factor calculation in LendingPool performs raw division without proper scaling, leading to precision loss that incorrectly flags healthy positions as eligible for liquidation.
Imagine a homeowner who has responsibly borrowed against their property, maintaining a healthy 120% collateralization ratio. Despite their prudent position, they could still face liquidation due to a subtle mathematical flaw in the LendingPool's health factor calculations.
The core issue lies in how the protocol determines borrower safety. When calculating the health factor, the LendingPool performs division operations that lose precision at crucial decimal points. This seemingly minor rounding error has major consequences, it can make a safe 1.2 health factor appear to be below the critical 1.0 threshold.
Here's how an opportunistic liquidator could exploit this:
They would scan for borrowers with health factors just above 1.0, targeting positions that should be completely safe. The liquidator calls initiateLiquidation() on these positions. Due to the precision loss in calculateHealthFactor(), the contract incorrectly flags these healthy positions as eligible for liquidation. The borrower's collateral gets liquidated at a discount, despite maintaining proper safety margins.
The real-world impact is substantial, borrowers who diligently maintained safe collateral ratios could lose their positions to liquidators. This is equivalent to a bank foreclosing on a mortgage that's current on payments, simply due to a spreadsheet rounding error.
Looking at these numbers.
Borrower's true health factor: 1.2 (120% collateralization)
Protocol's calculated value: 0.99999... (due to precision loss)
Result: Position liquidatable despite being 20% over-collateralized
This fundamentally undermines the protocol's risk management system and could affect any borrower maintaining a health factor between 1.0 and approximately 1.3.
Attack Flow
Attacker identifies a borrower with health factor slightly above 1.0 (e.g. 1.2)
Calls initiateLiquidation()
on this position
Due to precision loss, the health factor check passes
The healthy position gets liquidated despite adequate collateralization
From LendingPool.sol
Attack Flow
Attacker identifies a borrower with health factor slightly above 1.0 (e.g. 1.2)
Calls initiateLiquidation()
on this position
Due to precision loss, the health factor check passes
The healthy position gets liquidated despite adequate collateralization
This vulnerability enables premature liquidation of properly collateralized positions, potentially causing significant losses for borrowers who maintained adequate collateral ratios.
Implement precise fixed-point arithmetic using WadRayMath
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.