# Vault.withdraw sometimes burns too many shares

Vault.withdraw burns the full requested shares even when the controller returns less than the fair-share amount, shortchanging the withdrawer.

- Payout: Audit contest
- Severity: medium
- Program: yAxis
- Found by: cmichel
- Disclosed: 2021-11-10
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-09-yaxis-findings/issues/121
- Library page: https://bugbountylibrary.com/r/c4%3A2021-09-yaxis%3AM-03
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error

**Target:** Solidity Vault.withdraw / controller withdrawal
**Root cause:** When the controller cannot supply the full _toWithdraw, _amount is reduced to _balance.add(_diff) but _shares is not recomputed, so the user burns shares for a below-fair-share payout.
**Steps:**
1. Call `Vault.withdraw(_amount)` where vault balance is insufficient and controller returns `_diff < _toWithdraw`.
2. Observe `_amount = _balance.add(_diff)` lowers payout but `_shares` stays at the original fair-share value.
3. User receives fewer output tokens than their shares entitled them to; excess shares burned.
**How found:** Code review of the withdraw branch comparing _diff vs _toWithdraw and noticing _shares was not recomputed after _amount was reduced.
**Exploitation:** Trigger a withdrawal while the strategy has incurred a loss so the controller returns less than requested; the withdrawer absorbs the loss on the full share amount.
**Insight:** In share-based vaults, whenever the payout amount is adjusted downward mid-function, re-derive the shares to burn from the actual payout; audit every branch where _amount and _shares can diverge.
