# Bribe Rewards Struck In Contract If Deposited During First Epoch

Bribe rewards deposited during epoch 0 are keyed to Day 1 but deliverBribes only ever reads the current epoch, so they are permanently stuck.

- Payout: Contest reward
- Severity: high
- Program: Velodrome Finance
- Credited: xiaoming90
- Disclosed: 2022-08-08
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2022-05-velodrome-findings/issues/168
- Library page: https://bugbountylibrary.com/r/c4%3A2022-05-velodrome%3AH-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Bribe/Gauge/Voter reward distribution contracts
**Root cause:** notifyRewardAmount keys rewards to getEpochStart(block.timestamp) = current epoch start + BRIBE_LAG, but Gauge.deliverBribes only reads tokenRewardsPerEpoch for the current epoch's bribeStart, and Voter.distribute never calls deliverBribes in epoch 0 because claimable[_gauge] is 0 until VELO emissions start in epoch 3.
**Steps:**
1. Deploy fresh Bribe/Gauge; current epoch is epoch 0 (Day 0).
2. Briber calls `Bribe.notifyRewardAmount(DAI, amount)`; adjustedTstamp = Day 1, stored in `tokenRewardsPerEpoch[DAI][Day 1]`.
3. On Day 6 call `Voter.distribute(gauge)`; `claimable[gauge]` is 0 (Minter emissions start epoch 3), so `Gauge.deliverBribes()` is skipped.
4. In epoch 1+, `deliverBribes` computes bribeStart = Day 9 and reads `tokenRewardsPerEpoch[DAI][Day 9]`, never Day 1.
5. Rewards remain in Bribe contract with no rescue path.
**How found:** Code-reading of the epoch-keying in notifyRewardAmount vs deliverBribes, combined with tracing that claimable[_gauge] stays zero until Minter emissions begin in epoch 3, so deliverBribes is never invoked during epoch 0.
**Escalation:** Permissionless deployment of new Bribe/Gauge pairs means every newly deployed pair repeats the loss for anyone adding rewards immediately.
**Insight:** When reward accounting keys deposits by a computed epoch-start timestamp, verify every read path uses the same key derivation and that the distribution trigger can actually fire in the deposit's epoch; check bootstrap epochs where emission/claimable counters are still zero.
