# Deposited funds are locked in inactive vaults

Derby MainVault blocks withdrawalRequest on inactive vaults, so depositors whose vault got zero allocations cannot queue withdrawals and funds stay locked.

- Payout: Contest reward
- Severity: medium
- Program: Derby
- Credited: Ch_301
- Disclosed: 2022-10-17
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-01-derby-judging/issues/318
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AM-10
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** MainVault / XChainController yield-optimiser vault contracts
**Root cause:** XChainController marks a vault inactive when it receives 0 allocations, and MainVault's onlyWhenVaultIsOn modifier gates withdrawalRequest, so users holding shares in an inactive vault cannot queue a withdrawal for the next rebalancing.
**Steps:**
1. Gamer allocations route 0 to a vault during rebalancing; XChainController sets it inactive (`XChainController.sol#L229-L235`).
2. User holding vault shares calls `withdrawalRequest(...)` on MainVault.
3. Call reverts due to `onlyWhenVaultIsOn` modifier (`MainVault.sol#L149-L151`).
4. `withdraw` also reverts (no funds held) and `withdrawAllowance` requires an existing request, so no exit path exists until allocations return.
**How found:** Code reading of the vault lifecycle: noticed deposit/withdraw being gated on active vaults is sensible, but withdrawalRequest being gated is not, since it only queues a future withdrawal and should remain available to let users exit.
**Insight:** When auditing state-gated modifiers, check each gated function individually: exit/queue functions (withdrawal requests) often must stay callable in the 'inactive' state even when deposit and immediate-withdraw are correctly blocked.
