# Users are able to front-run bad debt settlements to avoid insurance costs

Users front-run public settleBadDebt() by withdrawing insurance shares first, dodging their share of seized bad-debt costs.

- Payout: Audit contest
- Severity: medium
- Program: Hubble
- Found by: kirk-baird
- Disclosed: 2022-06-02
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-02-hubble-findings/issues/59
- Library page: https://bugbountylibrary.com/r/c4%3A2022-02-hubble%3AM-11
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:race-condition

**Target:** InsuranceFund.sol / MarginAccount.settleBadDebt()
**Root cause:** seizeBadDebt() is triggered by a public settleBadDebt() call visible in the mempool, and withdraw() lets holders exit immediately before the obligation is settled, so they avoid the cost of the seizure.
**Steps:**
1. Observe pending `MarginAccount.settleBadDebt()` tx in mempool
2. Submit `InsuranceFund.withdraw(allShares)` with higher gas fee
3. Withdraw tx mines first, burning shares and returning `balance()*shares/totalSupply()` vusd
4. settleBadDebt() then calls `seizeBadDebt(amount)`, adding pendingObligation against remaining holders
**How found:** Reading InsuranceFund.sol, noticed seizeBadDebt() is invoked via a public settleBadDebt() and that withdraw() has no timelock, enabling mempool front-running.
**Exploitation:** Attacker holds insurance shares, watches mempool for settleBadDebt(), front-runs with a higher-gas withdraw() to exit before bad debt is socialized, keeping prior funding payments while avoiding the seizure cost.
**Insight:** When a loss/settlement is triggered by a public function, any exit path (withdraw, redeem, unstake) without a delay is front-runnable; check ordering between public settlement triggers and share redemption.
