# Some tokens enable the direct draining of all approved ERC20Votes tokens

ERC20MultiDelegate ignores transferFrom's bool return, so a non-reverting ERC20Votes token lets an attacker mint fake delegate balances and drain all proxy-held tokens.

- Payout: Audit contest
- Severity: medium
- Program: ENS
- Found by: Dravee
- Disclosed: 2023-12-04
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2023-10-ens#m-01
- Library page: https://bugbountylibrary.com/r/c4%3A2023-10-ens%3AM-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:accounting-error vuln:business-logic

**Target:** ERC20MultiDelegate.sol delegateMulti/_reimburse/_processDelegation
**Root cause:** transferFrom return values are not checked with require, so a token returning false instead of reverting silently fails while internal ERC1155 accounting still credits the caller.
**Steps:**
1. Deploy a MockERC20Votes whose transferFrom returns false instead of reverting on failure.
2. Alice approves ERC20MultiDelegate for max and calls `delegateMulti([], [1,2,3], [100,100,100])`; transfers silently fail but delegateToken balances for IDs 1-3 become 100.
3. Alice calls `delegateMulti([1,2,3], [], [0,10,20])` using the fake balances as sources.
4. Proxies 1-3 are drained of their ERC20Votes balances to Alice; her token balance becomes 5+10+20.
**How found:** Started from a bot-race finding about unsafe transferFrom on non-standard ERC20 tokens; argued ERC20Votes inherits ERC20's bool-returning transferFrom, so a compliant-but-non-reverting token is possible, then built a mock to demonstrate.
**Exploitation:** Attacker needs an ERC20Votes token whose transferFrom returns false rather than reverting. First call mints arbitrary ERC1155 delegate balances for free; second call redeems those fake balances against real proxy contracts, pulling their ERC20Votes tokens to the attacker.
**Escalation:** Chained free-mint accounting bug (bug 1) into full draining of all deployed proxies' approved ERC20Votes balances.
**Insight:** When a contract wraps ERC20Votes/ERC20 transfers, check whether the bool return is required; a token that returns false instead of reverting turns silent transfer failure into free internal accounting credits that can be redeemed against pooled balances.

