# A whale user is able to cause freeze of funds of other users by bypassing withdraw limit

WithdrawHook resets period counters without enforcing limits on the first withdraw, letting a whale drain reserves and freeze other users' withdrawals.

- Payout: Contest reward
- Severity: high
- Program: prePO
- Credited: Trust
- Disclosed: 2023-01-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-prepo-findings/issues/310
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-prepo%3AH-02
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** WithdrawHook.sol / Collateral.sol withdraw limit logic
**Root cause:** When the period has elapsed, the hook resets lastGlobalPeriodReset/lastUserPeriodReset and assigns the full requested amount to the counter without checking it against the per-period limit, so the first withdraw in a period is unbounded.
**Steps:**
1. Collateral holds 10,000 USDC reserve; withdraw limit is 150 USDC per user per period.
2. Alpha (12,000 USDC collateral) waits until both global and user periods have expired.
3. Alpha calls `withdraw(10000e18)`; hook enters the reset branch, sets counters to the full amount, no limit check.
4. Alpha receives 10,000 USDC, emptying reserves.
5. Victim Vic's `withdraw(150e18)` now fails/reverts due to insufficient reserves — funds frozen.
**How found:** Code review of WithdrawHook: noticed the if-branch on period expiry only resets timestamps and assigns the amount to the counter, with the limit require only in the else branch, making the first call per period unbounded.
**Exploitation:** Attacker times a withdraw to coincide with expiry of both global and user period windows, then withdraws an amount exceeding the per-period limit in a single call; the reset branch skips the require check, draining the collateral reserve so subsequent legitimate withdrawals cannot be served.
**Insight:** When auditing rate-limit logic, check the period-reset branch separately from the accumulation branch — a reset that assigns the current amount instead of zero skips the limit check for the first caller each window.
