# When withdrawalBatchDuration is set to zero lenders can withdraw more then allocated to a batch

With withdrawalBatchDuration=0, a lender can execute a withdrawal and a later lender joining the same batch withdraws again, exceeding the batch's normalizedAmountPaid.

- Payout: Contest reward
- Severity: high
- Program: Wildcat Protocol
- Credited: 0xCiphky
- Disclosed: 2023-12-11
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-10-wildcat-findings/issues/410
- Library page: https://bugbountylibrary.com/r/c4%3A2023-10-wildcat%3AH-04
- 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:** WildcatMarketWithdrawals.sol withdrawal batch accounting
**Root cause:** With withdrawalBatchDuration=0, executeWithdrawal is allowed in the same block the batch is still open, so scaledTotalAmount grows after normalizedAmountPaid was already paid out, letting later lenders claim a pro-rata share of already-distributed funds.
**Steps:**
1. Set withdrawalBatchDuration=0 in market parameters.
2. Alice deposits 2e18, Bob 1e18, borrow 1e18.
3. Alice calls `queueWithdrawal(1e18)` then `executeWithdrawal(alice, block.timestamp)` — receives 1e18 (normalizedAmountPaid=1e18, scaledTotalAmount=1e18).
4. Bob calls `queueWithdrawal(1e18)` in the same batch (scaledTotalAmount becomes 2e18, normalizedAmountPaid stays 1e18).
5. Bob calls `executeWithdrawal(bob, block.timestamp)` — receives 5e17 via `mulDiv(1e18, 1e18, 2e18)`.
6. Assert aliceWithdrawn + bobWithdrawn (1.5e18) > normalizedAmountPaid (1e18).
**How found:** Reasoned that with zero batch duration the batch is executable while still accepting new scaled amounts, so the pro-rata denominator (scaledTotalAmount) changes after normalizedAmountPaid was distributed; confirmed with a Foundry test.
**Exploitation:** Any lender can queue and immediately execute a withdrawal; a subsequent lender joining the same still-open batch receives a pro-rata share of funds already paid out, draining assets reserved for other batches.
**Insight:** When a time-window parameter can be zero, check whether the 'closed/expired' boundary still permits mutation of the accounting denominator after payouts — the pro-rata divisor must be frozen before any execution.
