# Malicious emissionToken could poison rewards for a market

A reverting or blacklisting emission token makes sendReward revert, blocking all reward claims for a market and permanently locking accrued rewards.

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

**Target:** MultiRewardDistributor reward disbursement (Solidity contract)
**Root cause:** disburseBorrowerRewardsInternal/disburseSupplierRewardsInternal loop over all emission configs and call sendReward, which does token.safeTransfer; a single reverting transfer (malicious or blacklisting token like USDC/USDT) reverts the whole claim transaction.
**Steps:**
1. Deploy MaliciousToken whose balanceOf returns type(uint256).max and transfer reverts `No transfer for you`.
2. Admin adds it via `_addEmissionConfig(mToken, address(this), address(token), 1e18, 1e18, block.timestamp + 365 days)`.
3. Accrue rewards over time, then call `comptroller.claimReward()`.
4. Claim reverts with `No transfer for you`; no rewards paid for any emission config of that market.
**How found:** Code review of the emission loop: noticed sendReward's safeTransfer is not isolated per config, so one revert aborts the entire disbursement for the user.
**Exploitation:** Any accrued rewards for the poisoned emissionConfig become permanently unclaimable; setting reward speed to 0 only stops further accrual, not the locked balance. Triggerable by a censorable token (USDC/USDT) blacklisting a rewards holder.
**Insight:** In multi-token reward loops, one failing external transfer aborts all payouts; check whether censorable/blacklisting tokens (USDC/USDT) or upgradeable tokens can be emission tokens and whether per-config try/catch or config removal exists.

