# withdrawProtocolFees() Possible malicious or accidental withdrawal of all rewards

BoostAggregator.withdrawProtocolFees passes protocolRewards (often 0) to claimReward, which treats 0 as 'claim all', draining user rewards.

- Payout: Contest reward
- Severity: high
- Program: Maia DAO Ecosystem
- Credited: bin2chen
- Disclosed: 2023-09-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-05-maia-findings/issues/731
- Library page: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AH-06
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** BoostAggregator.withdrawProtocolFees / UniswapV3Staker.claimReward
**Root cause:** claimReward treats amountRequested==0 as 'withdraw entire rewards[msg.sender]' rather than zero; withdrawProtocolFees passes protocolRewards which may be 0, so the aggregator's full reward balance is swept.
**Steps:**
1. Owner calls `withdrawProtocolFees(to)` when `protocolRewards==0`.
2. Inside, `uniswapV3Staker.claimReward(to, 0)` is invoked with msg.sender = BoostAggregator.
3. claimReward sees amountRequested==0, skips the `amountRequested != 0` branch, sets `rewards[msg.sender]=0` and transfers the full balance to `to`.
4. User rewards held by the aggregator are lost; a malicious owner can repeat to sweep all rewards.
**How found:** Code reading of withdrawProtocolFees passing protocolRewards into claimReward, then tracing claimReward's branch logic to notice amountRequested==0 means 'claim everything'.
**Exploitation:** Owner (or accidental zero-value call) invokes withdrawProtocolFees; the 0 amount is interpreted as 'claim all', transferring the aggregator's entire staker reward balance to an owner-chosen address.
**Insight:** When a callee uses 0 as a sentinel for 'max/all', any caller forwarding a possibly-zero stored balance silently converts a no-op into a full sweep; audit every pass-through of a value that doubles as a sentinel.
