-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Severity: High
Files Affected
cadence/contracts/FlowALPv1.cdc
Description
The _rebalancePositionNoLock() function attempts to restore an undercollateralized position to its target health by pulling tokens from the user's configured topUpSource. However, it blindly deposits whatever amount it successfully withdraws into the position without verifying if the newly added funds are actually sufficient to bring the position's health back above the liquidation threshold. If the topUpSource contains insufficient funds to completely save the position, the protocol still drains the available backup tokens and traps them in the doomed position. This forces the user to expose their backup funds to liquidators who will subsequently seize the newly added collateral alongside the original collateral. Exploit Scenario:
- A user's position becomes severely undercollateralized due to a market crash, dropping their health factor to 0.8.
- The user has a topUpSource configured, but its remaining balance is only enough to bring the position's health up to a maximum of 0.95.
- The protocol's asynchronous update loop triggers _rebalancePositionNoLock(), which pulls the entire remaining balance from the user's topUpSource and deposits it directly into the position.
- Because the health is still strictly below 1.0, an external liquidator instantly calls manualLiquidation() and liquidates the position, causing the user to lose both their original collateral and their entire backup fund to the liquidator.
Recommendation
Implement a pre-flight check using the source's minimumAvailable() function to ensure it contains enough funds to restore the position to a healthy state (health >= 1.0) before initiating the withdrawal. If the source lacks sufficient funds to save the position from liquidation, the protocol should skip the withdrawal entirely to preserve the user's remaining external assets.
Parent Issue: #209