# withdrawal request override

Derby MainVault withdrawalRequest guard checks withdrawalRequestPeriod==0, which passes during initial rebalancingPeriod 0, letting repeated requests burn shares and overwrite withdrawalAllowance.

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

**Target:** MainVault.withdrawalRequest (Solidity yield vault)
**Root cause:** The 'Already a request' guard requires user.withdrawalRequestPeriod == 0, but the sentinel value is also 0 before the first rebalance, so the guard never trips and each call overwrites withdrawalAllowance while burning additional shares.
**Steps:**
1. Deploy vault, user deposits 10_000 USDC; totalSupply=10_000
2. Set exchangeRate to 0.9 via setExchangeRateTEST
3. Call `withdrawalRequest(5_000)` twice; both succeed, burning 5_000 shares each
4. Observe withdrawalAllowance=4_500 but totalSupply=0; first request's allowance lost
5. Advance rebalancing period and set reserved funds, then withdrawAllowance yields only 4_500 USDC
**How found:** Code reading of the withdrawalRequest guard: noticed the require checks withdrawalRequestPeriod==0, which is indistinguishable from the unset state when rebalancingPeriod is still 0, then extended an existing test to confirm double-call behavior.
**Exploitation:** User (or a tricked user) calls withdrawalRequest multiple times before the first rebalance; each call burns shares and overwrites withdrawalAllowance, so previously requested value is silently lost while shares are destroyed.
**Insight:** When a struct field doubles as both a sentinel for 'unset' and a real value (period index), check whether the real value can legitimately equal the sentinel at initialization; test the zero-state of every stateful guard.
