# Spending multiple Unbonding transactions is not supported by the Staking indexer

Babylon staking indexer's getSpentUnbondingTx returns only the first spent unbonding UTXO per Bitcoin tx, leaving other spent unbonding txs marked unspent in the offchain DB.

- Payout: Contest reward
- Severity: high
- Program: Babylon
- Credited: zigtur
- Disclosed: 2024-08-04
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_babylon_may2024.pdf#3.1.2
- Library page: https://bugbountylibrary.com/r/cantina%3Ababylon_may2024%3A3.1.2
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:high tech:go technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Staking indexer (indexer.go) processing confirmed Bitcoin blocks
**Root cause:** getSpentUnbondingTx iterates tx inputs and returns on the first matching unbonding tx, so a single Bitcoin transaction spending multiple unbonding UTXOs only updates one; HandleConfirmedBlock then skips the rest.
**Steps:**
1. Read getSpentUnbondingTx in indexer.go#L683-L691: loop over `tx.TxIn`, return `unbondingTx, i` on first match.
2. Construct a Bitcoin tx with multiple inputs each spending a distinct unbonding transaction UTXO (e.g. several stakes unbonding via Timelock path).
3. Broadcast and confirm the tx; indexer processes it in HandleConfirmedBlock.
4. Observe only the first unbonding tx is marked spent; remaining unbonding txs retain unspent status in the offchain DB.
**How found:** Code review of the indexer's input-scanning loop; noticed the early `return` inside the `for i, txIn := range tx.TxIn` loop only yields one unbonding tx despite Bitcoin txs allowing many inputs.
**Insight:** When auditing indexers/parsers over Bitcoin-style txs, check loops that `return` on first match instead of collecting all matches—multi-input txs routinely spend several tracked UTXOs at once.
