# The rewards are incorrectly calculated in CurveDepositToken and ConvexDepositToken

CurveDepositToken/ConvexDepositToken claim rewards without first calling allocateNewEmissions, so weeklyEmissions[week] is 0 and BoostCalculator halves the payout.

- Payout: Contest reward
- Severity: medium
- Program: Bima
- Credited: etherSky
- Disclosed: 2025-02-05
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_bima_december2024.pdf#3.2.5
- Library page: https://bugbountylibrary.com/r/cantina%3Abima_december2024%3A3.2.5
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:reward-distribution

**Target:** Solidity vault reward-claim path (CurveDepositToken/ConvexDepositToken, BoostCalculator)
**Root cause:** claimReward calls vault.transferAllocatedTokens without first invoking allocateNewEmissions, so weeklyEmissions[currentWeek] is still 0; _getBoostedAmount then hits the fullDecay<=previousAmount branch and returns amount/2.
**Steps:**
1. Deploy MockCurveDepositToken implementing IEmissionReceiver, register via `bimaVault.registerReceiver(token,1)`.
2. User1 locks tokens and votes MAX_POINTS for emissionId 1.
3. `vm.warp(block.timestamp + 5 weeks)` to pass INIT_BS_GRACE_WEEKS.
4. Call `curveDepositToken.fetchRewards()` to populate weeklyEmissions up to current week.
5. `vm.warp(block.timestamp + 1 weeks)` to enter a new week with weeklyEmissions[week]==0.
6. Call `curveDepositToken.claimRewards()` -> `vault.transferAllocatedTokens` -> `_transferAllocated` reads `weeklyEmissions[week]=0` -> `_getBoostedAmount` returns amount/2.
7. Compare with path that first calls `bimaVault.allocateNewEmissions(emissionId)` before claiming.
**How found:** Code-reading: noticed TroveManager always calls allocateNewEmissions before transferAllocatedTokens, but CurveDepositToken/ConvexDepositToken do not, then traced _getBoostedAmount's zero-emissions branch to the halving behavior.
**Exploitation:** Any depositor claiming in a week where allocateNewEmissions hasn't been called receives half their boosted rewards; no attacker capital needed, loss is passive to the claimant.
**Insight:** When a shared calculator depends on lazily-updated per-week state, check every caller that consumes it for a missing state-refresh call; the reference caller (TroveManager) reveals the required ordering.
