-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Severity: Medium
Files Affected
cadence/contracts/FlowALPv1.cdc
Description
In computeAdjustedBalancesAfterWithdrawal(), when a withdrawal wipes out all collateral in a token and flips the balance to debt (the else branch), the function subtracts this token's effective collateral contribution from the total: // line 2133-2134 effectiveCollateralAfterWithdrawal = balanceSheet.effectiveCollateral - (trueCollateral * withdrawPrice2) * collateralFactor The intent is to remove this one token's contribution from the total effective collateral (since all of it is consumed). In theory, (trueCollateral * price) * collateralFactor should be exactly the contribution this token added to balanceSheet.effectiveCollateral, so the subtraction should yield the effective collateral from all other tokens (>= 0). However, balanceSheet.effectiveCollateral was computed in a separate code path (_getUpdatedBalanceSheet) by summing trueBalance * price * factor across all tokens. Each multiplication introduces intermediate rounding in UFix128. When the same token's contribution is recomputed locally here, the intermediate rounding may produce a slightly different value. If the local recomputation rounds up by even 1 unit relative to what was included in the sum, the subtraction underflows. Since UFix128 is unsigned, an underflow panics and reverts the transaction. This function is called by fundsRequiredForTargetHealthAfterWithdrawing (used by withdrawAndPull at line 2944), meaning the underflow would block: User withdrawals that flip a credit balance to debit Rebalancing operations that depend on withdrawal health simulation Any withdrawAndPull with pullFromTopUpSource: true where the required deposit is computed via this path
Recommendation
Floor the subtraction at zero to prevent underflow.
Parent Issue: #209