# LinearDistributor.declareReward can revert due to dependency of balance

Attacker donates collateral tokens to LinearDistributor, inflating balance so _forfeit's require fails and declareReward reverts, causing temporary or permanent DOS.

- Payout: Contest reward
- Severity: medium
- Program: Malt Protocol
- Credited: hansfriese
- Disclosed: 2023-05-01
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-02-malt-findings/issues/35
- Library page: https://bugbountylibrary.com/r/c4%3A2023-02-malt%3AM-03
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:dos

**Target:** LinearDistributor reward contract (Solidity)
**Root cause:** declareReward computes forfeited = balance - bufferRequirement from the live token balance and requires it <= declaredBalance; an unsolicited token transfer inflates balance, breaking the invariant and reverting _forfeit.
**Steps:**
1. Attacker transfers collateral tokens directly to LinearDistributor, raising collateralToken.balanceOf(address(this))
2. declareReward runs: distributed = linearBondedValue*netVest/vestingBondedValue, capped at balance, then transferred to rewardMine
3. Re-read balance; if balance > bufferRequirement, net = balance - bufferRequirement is passed to _forfeit(net)
4. _forfeit requires net <= declaredBalance; inflated balance makes net exceed declaredBalance, reverting declareReward
5. If donation covers the full vesting reward amount, distributed never drains balance below bufferRequirement, making the revert permanent
**How found:** Code reading of declareReward/_forfeit: noticed forfeited amount is derived from live balance rather than tracked accounting, so any external balance increase breaks the require.
**Exploitation:** Attacker spends capital to donate collateral tokens to the distributor contract, blocking reward declaration; continued attack requires escalating capital as vesting progresses.
**Insight:** When a contract derives an internal accounting quantity (forfeited = balance - buffer) from balanceOf, unsolicited token transfers become an attack surface; check every require that compares a balance-derived value against stored state.
