# Dust-sized debt can turn a very safe account into a MathOverflow denial of service

Dust-sized debt plus large collateral makes health-factor exceed u128::MAX, panicking all HF-dependent flows and locking an overcollateralized account.

- Payout: Contest reward
- Severity: medium
- Program: K2
- Credited: YradAngel
- Disclosed: 2026-08-20
- Write-up quality: 7/10
- Original: https://code4rena.com/reports/2026-04-k2#m-37
- Library page: https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-37
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:rust technique:source-review vuln:accounting-error vuln:business-logic vuln:dos

**Target:** Soroban lending router health-factor calculation (calculation.rs / operations.rs)
**Root cause:** calculate_health_factor_u256 narrows a U256 HF to u128 with unwrap_or_else panic; only total_debt_base==0 returns the u128::MAX sentinel, so tiny nonzero debt with huge collateral overflows instead of saturating.
**Steps:**
1. Supply collateral below the overflow boundary so post-borrow HF is representable.
2. Borrow one raw unit of an 18-decimal asset (total_debt_base=1).
3. Supply additional collateral; supply path skips HF check since more collateral can't reduce solvency.
4. Next HF read computes collateral*threshold*WAD/bps/debt > u128::MAX and panics with MathOverflow.
5. Observe get_user_account_data, withdraw, borrow, set_user_use_reserve_as_coll, swap_collateral, liquidation_call all revert.
**How found:** Code reading of calculate_health_factor_u256 spotted the discontinuity between debt=0 returning u128::MAX and debt=1 panicking on overflow; then reasoned that supply doesn't check HF, making the overflow state reachable incrementally.
**Exploitation:** Attacker/user creates dust debt then tops up collateral past the u128 boundary, bricking all HF-dependent operations on their own account; recovery only via repaying dust through a path not requiring HF read.
**Insight:** When a sentinel value (u128::MAX) represents 'infinite' in one branch, check whether neighboring nonzero states can exceed the type and revert instead of saturating; also check which write paths skip the derived-value check (supply) to reach the overflow state incrementally.
