# Stakers can have their funds locked for an extended period not related to the performance of their borrowers

cancelVouch swaps the last vouch into the removed slot, breaking FIFO order so prepayments repay newer lenders first, locking older stakers' funds.

- Payout: Contest reward
- Severity: medium
- Program: Union Finance
- Credited: hyh
- Disclosed: 2022-11-04
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2022-10-union-finance-judging/issues/114
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-10-union-finance%3AM-4
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** UserManager.sol vouch array / updateLocked prepayment logic
**Root cause:** cancelVouch removes a vouch by moving the last array element into the removed index, destroying the FIFO ordering that updateLocked relies on to allocate repayments.
**Steps:**
1. Borrower Alice has vouchers array [Jade(1st), Mike(2nd), ..., Bob(5th)] in FIFO order.
2. Jade is repaid in full and calls `cancelVouch(Jade, Alice)`; last element Bob is moved into index 0.
3. Array becomes [Bob, Mike, ...]; Bob (newest, 10k DAI) now precedes Mike (oldest, 1k DAI).
4. Alice repays interest in full, triggering `updateLocked(Alice, amount, false)` which iterates vouchers from index 0.
5. Repayment unlocks Bob's vouch first; Mike's funds stay locked until Bob is fully repaid.
**How found:** Code reading of cancelVouch's swap-and-pop array removal against updateLocked's assumption that array index proxies loan age/FIFO; noticed the ordering invariant was violated by a standard removal pattern.
**Exploitation:** Any staker calls the ordinary cancelVouch on a fully-unlocked old vouch; the swap moves a large recent vouch ahead of older ones, redirecting subsequent borrower repayments to the newer lender and freezing older stakers' capital.
**Escalation:** Repeated cancellations and new vouches can randomize the queue entirely, so a borrower willing to repay a specific lender cannot, and older stakers may face permanent freeze if the borrower defaults before their turn.
**Insight:** When an array's index encodes business meaning (age, priority, FIFO), audit every removal/insertion path for swap-and-pop or reordering that silently breaks that invariant; check all consumers of the array order.
