# When _dp2pdtoken.athbalance() is increased, the power of almost all pools becomes stale

Booster uses a global athBalance denominator that only updates on stake/withdraw, so when one pool raises athBalance, other pools keep stale inflated boosters and rewards are misdistributed.

- Payout: Contest reward
- Severity: high
- Program: Goat
- Credited: cccz
- Disclosed: 2024-06-12
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_goat_mar2024.pdf#3.1.5
- Library page: https://bugbountylibrary.com/r/cantina%3Agoat_mar2024%3A3.1.5
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:high tech:solidity technique:source-review vuln:business-logic vuln:reward-distribution

**Target:** Staking/reward pool booster calculation (_reCalBooster, _dP2PDToken.athBalance)
**Root cause:** Booster = 1 + balance/athBalance, but athBalance is a global max that changes when any pool stakes; other pools' boosters are only recomputed on their own stake/withdraw, so they retain values computed against an outdated denominator.
**Steps:**
1. Observe `_reCalBooster` computes `newBooster = calBooster(balanceOf(account), athBalance, maxBooster)`.
2. Set athBalance=1000, poolA balance=500 (booster 1.5), poolB balance=1000 (booster 2.0).
3. PoolB owner stakes 500 DCT → poolB balance=1500, athBalance=1500.
4. PoolA booster should become 1+500/1500=1.33 but stays 1.5 until poolA stakes/withdraws.
5. Reward distribution uses stale boosters across nearly all pools.
**How found:** Code reading of the booster recalculation path: noticed athBalance is a mutable global denominator but _reCalBooster is only invoked on per-account stake/withdraw, implying cross-pool staleness.
**Insight:** When a formula divides by a global maximum/aggregate that other actors can raise, check whether every dependent entity is lazily recomputed only on its own state change — stale denominators silently inflate relative shares.
