# updateCommitmentBorrowers does not delete all existing users

Deleting an EnumerableSet mapping in updateCommitmentBorrowers fails to clear stored addresses, so removed borrowers can still accept commitments and take loans.

- Payout: Contest reward
- Severity: medium
- Program: Teller
- Credited: cducrest-brainbot
- Disclosed: 2023-03-20
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-03-teller-judging/issues/88
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-03-teller%3AM-3
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** LenderCommitmentForwarder.updateCommitmentBorrowers (Solidity contract)
**Root cause:** Solidity `delete` on a struct containing a mapping (EnumerableSet.AddressSet) does not clear the underlying mapping, so previously added borrowers persist after the list is supposedly reset.
**Steps:**
1. Lender adds borrowers 0x1, 0x2 via updateCommitmentBorrowers
2. Lender calls updateCommitmentBorrowers with new list [0x3, 0x4]
3. `delete commitmentBorrowersList[_commitmentId]` does not erase the inner mapping
4. Check `commitmentBorrowersList[id].contains(0x1)` returns true
5. Removed borrower 0x1 calls acceptCommitment and still obtains a loan
**How found:** Code reading of updateCommitmentBorrowers; recognized that EnumerableSet is a struct with a mapping and that `delete` cannot clear mappings, then wrote a minimal Foundry test to confirm stale entries persist.
**Exploitation:** A borrower previously on the allowlist who was removed by the lender can still call acceptCommitment on the commitment and receive a loan, bypassing the lender's intent to revoke access.
**Insight:** Any `delete` on a struct/array element that transitively contains a mapping silently leaves the mapping intact; audit allowlist-reset functions for EnumerableSet/EnumerableMap and verify with a two-round add/delete/add test.
