# Owner of a pool may prevent any taxes being withdrawn

Pool owner registers a malicious reward token that reverts on transfer to globalBeneficiary, blocking withdrawTaxes and locking all taxes.

- Payout: Contest reward
- Severity: medium
- Program: FactoryDAO
- Credited: AuditsAreUS
- Disclosed: 2022-08-02
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-05-factorydao-findings/issues/52
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-factorydao%3AM-17
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** FactoryDAO pool tax withdrawal contract (withdrawTaxes/addPool)
**Root cause:** withdrawTaxes loops over all rewardTokens and requires every transfer to succeed; a single reverting token (attacker-controlled via addPool) reverts the whole batch, and taxes are zeroed before transfer.
**Steps:**
1. Pool owner calls `addPool()` with a `rewardTokenAddresses` entry pointing to a malicious ERC20 contract.
2. Malicious token's `transfer(to, amount)` reverts when `to == globalBeneficiary`.
3. Taxes accrue in `taxes[poolId][i]` from normal pool activity.
4. `globalBeneficiary` calls `withdrawTaxes(poolId)`; loop sets `taxes[poolId][i]=0` then calls `transfer(globalBeneficiary, tax)` which reverts.
5. `success` becomes false, `require(success)` reverts entire tx; taxes remain locked.
**How found:** Code review of withdrawTaxes: noticed the loop requires all transfers to succeed and that reward tokens are attacker-supplied at addPool, so a reverting token can DoS the batch.
**Exploitation:** Owner deploys a token whose transfer reverts only for the globalBeneficiary address, registers it as a reward token at pool creation, then lets taxes accumulate; every withdrawTaxes call reverts, permanently locking taxed tokens in the contract while the pool otherwise functions.
**Insight:** When a batch loop requires every external call to succeed and the token list is attacker-controlled, a single reverting token bricks the whole function; also note taxes are zeroed before transfer, so a revert loses accounting.
