# PublicVault.processEpoch calculates withdrawReserve incorrectly; Users can lose funds

PublicVault.processEpoch zeroes withdrawReserve when totalAssets() <= expected auction proceeds, so withdrawing LPs lose their share of vault funds.

- Payout: Contest reward
- Severity: high
- Program: Astaria
- Credited: rvierdiiev
- Disclosed: 2023-05-22
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-astaria-findings/issues/157
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-astaria%3AH-18
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** PublicVault.processEpoch / WithdrawProxy accounting
**Root cause:** When totalAssets() <= expected auction proceeds, withdrawReserve is set to 0 instead of totalAssets()*liquidationWithdrawRatio, leaving withdrawing LPs' funds stranded in the vault.
**Steps:**
1. Deploy PublicVault with LPs; trigger withdrawal so WithdrawProxy is created for the epoch.
2. Ensure an auction is in progress so WithdrawProxy.getExpected() > 0.
3. Set totalAssets() <= expected (e.g. totalAssets=5 ETH, expected=5 ETH, withdraw ratio 100%).
4. Call processEpoch(): branch sets s.withdrawReserve = 0.
5. Observe withdrawing LPs receive nothing while funds remain in vault.
**How found:** Code review of processEpoch's withdrawReserve branch, reasoning that at 100% withdraw ratio all assets should flow to the WithdrawProxy but the totalAssets() <= expected branch zeroes the reserve.
**Exploitation:** Withdrawing LPs at 100% ratio receive zero from the vault when totalAssets() <= expected; their share stays in the vault and is effectively lost to them.
**Insight:** In epoch-based vault accounting, audit the boundary branch where expected external proceeds exceed current assets: zeroing the reserve strands LP principal even though the ratio says 100% should be paid out.
