# Funds unutilized for rewards may get stranded in BribeRewarder

BribeRewarder lacks a sweep function, so reward tokens unutilized due to zero voters or rounding stay permanently stranded in the contract.

- Payout: Contest reward
- Severity: high
- Program: Magicsea
- Credited: 0uts1der
- Disclosed: 2024-07-15
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2024-06-magicsea-judging/issues/172
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-06-magicsea%3AH-6
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high technique:source-review vuln:business-logic vuln:precision-loss vuln:reward-distribution

**Target:** BribeRewarder.sol staking reward contract
**Root cause:** fundAndBribe/bribe require funding for all periods upfront, but _calculateRewards uses emissionsPerSecond = amountPerPeriod/duration (rounds down) and skips periods with no voters; no sweep function exists to recover leftover tokens.
**Steps:**
1. Briber calls `fundAndBribe()`/`bribe()` funding amountPerPeriod x periods, passing the balance check at BribeRewarder.sol#L241.
2. If a pool gets no voters in a period, or `_amountPerPeriod / duration` rounds down in `_calculateRewards`, part of the funded tokens are never distributed.
3. No sweep/recovery function exists on BribeRewarder (unlike BaseRewarder.sol#L208), so leftover tokens are locked forever.
**How found:** Code review of the funding check versus the reward calculation: noticed the upfront full-funding requirement combined with integer division rounding and per-period voter dependence, then checked for a recovery path and found none.
**Insight:** When a contract requires upfront funding for a maximum/estimated amount, always check whether the actual payout path can consume the full amount (rounding, zero-participant periods) and whether a sweep exists for the remainder.
