# Adversary can permanently break percentage tier bounties by funding certain ERC20 tokens then refunding

Depositing a non-zero-revert ERC20 into a percentage tier bounty then refunding leaves a zero-balance token entry, bricking all payouts permanently.

- Payout: Contest reward
- Severity: high
- Program: Openq
- Credited: tsvetanovv
- Disclosed: 2023-01-30
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-02-openq-judging/issues/267
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-openq%3AH-4
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** TieredPercentageBountyV1 smart contract (closeCompetition/claim payout)
**Root cause:** closeCompetition records fundingTotals=0 for a refunded token but keeps it in tokenAddresses; payout loop then calls transfer(0) which reverts on tokens that disallow zero-value transfers, and fundingTotals cannot be reset.
**Steps:**
1. Create a percentage tier bounty and deposit an ERC20 that reverts on zero-value transfers (e.g. LEND-style token).
2. Refund the deposit so the token balance is 0 but the token remains in tokenAddresses.
3. Call closeCompetition: fundingTotals for that token is set to 0.
4. Any claimant calls claim; loop iterates tokenAddresses and calls `transfer(claimant, 0)` on the zero-balance token, which reverts.
5. All payouts revert permanently since fundingTotals cannot be re-set.
**How found:** Code review of closeCompetition and payout loop; noticed fundingTotals can be zero for a token still in tokenAddresses, and that some ERC20s revert on zero-value transfers.
**Exploitation:** Attacker funds a percentage tier bounty with a zero-transfer-reverting ERC20, refunds it to leave a 0-balance token entry, then closeCompetition locks fundingTotals=0; every subsequent claim reverts, bricking payouts and trapping other funders' tokens.
**Escalation:** Chained with refund-breaking methods to permanently trap user funds.
**Insight:** When a contract iterates a stored token list to pay out, check whether entries can persist with zero balance and whether the transfer helper guards against zero amounts—tokens that revert on 0 transfers turn a stale list entry into a permanent DoS.
