# PermissionlessBasicPoolFactory's withdraw can become frozen on zero reward token transfers

PermissionlessBasicPoolFactory.withdraw transfers all reward tokens unconditionally; a revert-on-zero-transfer ERC20 with zero accrued reward blocks user exit, freezing deposits.

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

**Target:** PermissionlessBasicPoolFactory withdraw() reward transfer loop
**Root cause:** withdraw() unconditionally calls transfer() for every reward token even when the computed reward amount is zero; tokens that revert on zero-value transfers cause the whole withdraw to revert.
**Steps:**
1. Deploy/register a pool whose rewardTokens include an ERC20 that reverts on zero-value transfers (e.g. d-xo weird-erc20 revert-on-zero).
2. Deposit into the pool via the deposit path.
3. Immediately call `withdraw(poolId, receiptId)` before any reward accrues (or with rewardsWeiPerSecondPerToken set to 0).
4. Observe `IERC20(pool.rewardTokens[i]).transfer(receipt.owner, 0)` reverts, reverting the entire withdraw and trapping funds.
**How found:** Code reading of withdraw()'s reward loop noting the unconditional transfer call and no zero-amount guard, combined with knowledge of weird-ERC20 tokens that revert on zero-value transfers.
**Exploitation:** A pool creator sets rewardsWeiPerSecondPerToken to zero for a reward token that reverts on zero transfers; every user's withdraw() reverts, permanently freezing all deposits in that pool. Even without malice, a user cannot exit immediately after deposit before rewards accrue.
**Insight:** When a contract loops over arbitrary user-supplied token arrays and transfers computed amounts, check whether zero amounts are possible and whether the token set is attacker-chosen; revert-on-zero tokens turn a benign zero into a permanent fund freeze.
