# Index mismatch on vouchers and vouchees might lead to invalid borrower-voucher-staker association

Removing a voucher overwrote the wrong vouchee's voucherIndex when the borrower had one voucher but the staker had many, corrupting borrower-staker associations.

- Payout: Contest reward
- Severity: medium
- Program: Union
- Credited: weeeh_
- Disclosed: 2023-02-07
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-02-union-judging/issues/4
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-union%3AM-6
- Tags: domain:web3 impact:integrity kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:access-control vuln:accounting-error

**Target:** UserManager.sol voucher/vouchee accounting
**Root cause:** updateTotalStaked/removal logic writes vouchees[staker][0].voucherIndex = 0 assuming the borrower's voucher sits at index 0, without checking vouchers[borrower].length or matching the borrower, so it overwrites another borrower's vouchee entry.
**Steps:**
1. Have staker with vouchees[staker].length > 1 where vouchees[staker][0].borrower != target borrower.
2. Ensure target borrower has exactly one voucher (vouchers[borrower].length == 1).
3. Trigger voucher removal path at UserManager.sol L583-L607.
4. Observe vouchees[staker][0].voucherIndex overwritten to 0, corrupting the wrong borrower's association.
**How found:** Manual code review (vim) of the voucher removal loop; noticed the unconditional write of voucherIndex=0 to vouchees[staker][0] without verifying it belongs to the borrower being removed.
**Insight:** When maintaining parallel index arrays (vouchers vs vouchees), verify the element at the assumed index actually references the entity being mutated before overwriting its back-pointer; single-element arrays are a common trigger for index-0 assumptions.
