# User loses collateral converted to pendingBalance when cash() or list() is called

In Tessera's OptimisticListingSeaport, cash() and list() overwrite pendingBalances with '=' instead of '+=', erasing prior collateral owed to the proposer.

- Payout: Contest reward
- Severity: high
- Program: Tessera
- Credited: Trust
- Disclosed: 2023-04-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-tessera-findings/issues/44
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-tessera%3AH-07
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error

**Target:** OptimisticListingSeaport Solidity module (cash/list/propose)
**Root cause:** cash() and list() assign pendingBalances[_vault][proposer] = collateral with '=' instead of '+=', discarding any pre-existing pending balance from earlier proposals.
**Steps:**
1. Call `propose()` so pendingBalances[vault][proposer] = x.
2. Call `propose()` again with improved proposal, pendingBalances becomes 1.5x.
3. Proposal succeeds and listing purchases the NFT.
4. Call `cash()`; line sets pendingBalances = collateral (0.5x), overwriting the accumulated 1.5x.
5. x collateral value remains stuck in contract, user loses it.
**How found:** Code review of the pendingBalances update sites; noticed propose() uses '+=' while cash() and list() use '=', an inconsistency implying overwrite of prior balances.
**Exploitation:** Proposer accumulates pending balance across multiple proposals, then a cash()/list() call resets the balance to only the current collateral, stranding the earlier amount in the contract.
**Insight:** When auditing accounting state, diff every write site of the same mapping: an '=' where siblings use '+=' signals an overwrite bug that silently strands user funds.
