# In ERC20Boost.sol, a user can be attached to a gauge and have no boost balance.

Deprecated-gauge boost allocation is skipped in updateUserBoost, letting a user transfer boost tokens yet keep boosting a reintroduced gauge, double-allocating boost.

- Payout: Contest reward
- Severity: medium
- Program: Maia DAO Ecosystem
- Credited: AlexCzm
- Disclosed: 2023-09-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-05-maia-findings/issues/656
- Library page: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-13
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:evm tech:solidity vuln:accounting-error vuln:business-logic

**Target:** ERC20Boost.sol gauge boost accounting
**Root cause:** updateUserBoost only considers non-deprecated gauges, so a user's getUserBoost drops to zero while their per-gauge userGaugeBoost for the deprecated gauge persists; transfer's notAttached check then passes.
**Steps:**
1. Alice calls `attach()` on gaugeA; getUserBoost[alice] = balanceOf(alice).
2. Owner removes gaugeA into `_deprecatedGauges`.
3. Alice calls `updateUserBoost()`; deprecated gaugeA is skipped so getUserBoost[alice] = 0.
4. `freeGaugeBoost(alice)` = balanceOf - 0, so `transfer()` passes notAttached and Alice moves tokens out.
5. Owner re-adds gaugeA via `addGauge(gaugeA)`; Alice's stale userGaugeBoost still boosts gaugeA despite zero balance.
**How found:** Code reading of updateUserBoost's deprecated-gauge skip versus the interface comment stating all _userGauges should be iterated.
**Exploitation:** User transfers out boost tokens while retaining stale per-gauge boost allocation; on gauge reintroduction the same tokens are effectively counted for multiple addresses.
**Insight:** When accounting loops filter out deprecated/disabled entries, check whether per-entry state persists and can be re-activated later, desyncing a cached aggregate from the underlying balance.
