You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
FLO-22: maxWithdraw() View Function Incorrectly Caps Credit Position Withdrawals #231
The maxWithdraw() pure math helper calculates the maximum amount of a token a user can withdraw while maintaining a specific target health factor. For users holding a credit balance in the requested token, the function correctly computes the risk-adjusted deltaTokens but artificially caps the return value at the token's current trueBalance. This fails to account for the protocol's ability to seamlessly flip a credit balance into a debit balance, a behavior explicitly supported by the core accounting logic. Because Pool.availableBalance() relies directly on this helper when pullFromTopUpSource is false, external integrations and frontends will query artificially suppressed liquidity limits. The actual state-mutating withdrawal logic correctly handles flipping the balance via the internal computeAvailableWithdrawal() function, meaning this is strictly a view-layer discrepancy that impacts UI/UX but not protocol solvency. Exploit Scenario:
A user holds a massively overcollateralized position backed by 100,000 USDC.
The user also has a small credit balance of 1 FLOW in the exact same position.
A frontend queries Pool.availableBalance() to display to the user how much FLOW they can safely borrow against their USDC.
The maxWithdraw() helper evaluates the FLOW credit balance, sets maxPossible to 1 FLOW, and artificially caps the returned available balance to 1 FLOW.
The frontend erroneously informs the user that their borrowing power is exhausted, misleading the user and severely degrading the application's usability, even though submitting a manual transaction to borrow 1,000 FLOW would mathematically succeed.
Recommendation
Refactor the maxWithdraw() function to align with the core accounting logic found in computeAvailableWithdrawal(). When evaluating a credit balance, the function should return the sum of the entire trueBalance (which brings the balance to zero) plus the newly allowed debt capacity (which flips the balance to a debit) that the remaining effective collateral can support at the target health factor.
Activity