-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Severity: Low
Files Affected
cadence/contracts/FlowALPv1.cdc
Description
Positions in the protocol rely on minHealth and maxHealth thresholds to determine when automatic rebalancing should occur. The _queuePositionForUpdateIfNecessary() function is responsible for evaluating a position's health and adding it to the positionsNeedingUpdates array if it falls outside these configured bounds. However, when a position owner updates their thresholds via the setMinHealth() or setMaxHealth() functions, the contract only updates the internal state variables. It fails to evaluate if the new bounds instantly render the position eligible for rebalancing. Because the position is not marked for an update, the asynchronous asyncUpdate() function will ignore it, delaying automated topups or drawdowns until a subsequent state-changing operation forces the queue evaluation. Exploit Scenario:
- A user holds an overcollateralized position with a current health factor of 1.6 and a configured maxHealth of 1.7, meaning no automatic drawdown is currently required.
- The user decides they want to extract their excess liquidity into their configured draw-down sink, so they call setMaxHealth() to lower their maximum health bound to 1.5.
- The contract successfully updates the boundary but does not queue the position for an update, leaving the excess collateral trapped in the position instead of initiating the push.
- The automated asynchronous update loop completely bypasses the user's position, requiring them to manually submit a rebalance() transaction to extract their funds.
Recommendation
We suggest adding a Pool function that allows Position resources to trigger _queuePositionForUpdateIfNecessary() during the health bound update logic.
Parent Issue: #209