# MuteAmplifier.sol: rescueTokens function does not prevent fee tokens from being transferred

MuteAmplifier.rescueTokens lets owner withdraw fee0/fee1 tokens owed to stakers, causing payout/withdraw transfers to revert on insufficient balance.

- Payout: Contest reward
- Severity: medium
- Program: Mute.io
- Credited: HollaDieWaldfee
- Disclosed: 2023-04-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-03-mute-findings/issues/18
- Library page: https://bugbountylibrary.com/r/c4%3A2023-03-mute%3AM-08
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:accounting-error

**Target:** MuteAmplifier.sol staking contract rescueTokens
**Root cause:** rescueTokens only guards lpToken and muteToken balances, not the pair's fee0/fee1 tokens that back accrued staker rewards; reward accounting uses _totalWeightFee0 independent of actual token balance.
**Steps:**
1. Owner calls `rescueTokens(fee0Token, owner, amount)` where amount exceeds excess beyond totalFees0-totalClaimedFees0
2. fee0 tokens leave contract; _totalWeightFee0 unchanged
3. Staker calls `payout`/`withdraw`; fee0 computed from _totalWeightFee0
4. safeTransfer of fee0 reverts due to insufficient balance, blocking payout/withdraw
**How found:** Code review of rescueTokens guard logic: noticed only lpToken and muteToken are protected, while update() accrues fee0/fee1 rewards that also must remain in contract.
**Exploitation:** Privileged owner withdraws fee tokens backing staker rewards via rescueTokens, leaving contract undercollateralized so stakers' payout/withdraw calls revert until users top up the contract.
**Insight:** When auditing rescue/sweep functions, enumerate every token balance the contract owes to users (accrued fees, rewards) not just the primary stake tokens; check that reward accounting variables are backed by actual balances.
