# Attacker can prevent rewards from being issued to gauges for a given epoch in TapiocaOptionBroker

Anyone can frontrun newEpoch() with a permissionless emitForWeek() call, making it return 0 and zeroing gauge rewards for that epoch.

- Payout: Contest reward
- Severity: high
- Program: Tapioca DAO
- Credited: Ruhum
- Disclosed: 2023-11-16
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-07-tapioca-findings/issues/541
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-tapioca%3AH-52
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** TapiocaOptionBroker.newEpoch / TapOFT.emitForWeek (Solidity contracts)
**Root cause:** emitForWeek() is permissionless and returns 0 on subsequent calls within the same week; newEpoch() uses that return value as the epoch's reward amount, so a pre-call makes it distribute zero.
**Steps:**
1. Attacker observes pending newEpoch() tx (epoch duration elapsed).
2. Attacker frontruns with `tapOFT.emitForWeek()`, setting emissionForWeek[week] > 0.
3. newEpoch() then calls emitForWeek() which returns 0 due to `if (emissionForWeek[week] > 0) return 0;`.
4. `_emitToGauges(0)` assigns 0 TAP to all gauges for that epoch.
**How found:** Code reading of emitForWeek()'s early-return-on-already-emitted logic combined with newEpoch() consuming its return value; recognized the permissionless call as a frontrunnable griefing vector.
**Exploitation:** Attacker repeatedly frontruns newEpoch() each epoch with a cheap emitForWeek() call, delaying gauge reward distribution indefinitely; rewards roll into later epochs and users whose locks expire in the skipped window lose eligibility.
**Escalation:** Sustained griefing across multiple epochs shifts rewards to later lock holders, denying rewards to users whose locks expire during the attack window.
**Insight:** When a permissionless state-mutating function returns a value consumed by another flow, check whether an attacker can pre-call it to force a degenerate return (0/empty) and starve the dependent flow.
