# Spearbit finding "It is possible to exercise TAP option an extra time compared to lock duration" not fixed

TapiocaOptionBroker lets a staker exercise the TAP option twice for a single lock epoch by timing participation and exercise around epoch boundaries.

- Payout: Contest reward
- Severity: medium
- Program: Tapioca DAO
- Credited: immeas
- Disclosed: 2024-05-23
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-02-tapioca-findings/issues/175
- Library page: https://bugbountylibrary.com/r/c4%3A2024-02-tapioca%3AM-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:incomplete-fix technique:regression vuln:business-logic vuln:reward-distribution

**Target:** TapiocaOptionBroker.sol (oTAP option exercise / epoch accounting)
**Root cause:** Exercise eligibility is checked against epoch timing rather than the position's actual lock window, so a position locked just before an epoch end can exercise in the next epoch and again after the following epoch trigger, yielding two payoffs for one epoch of staking.
**Steps:**
1. Lock tOLP with `_lockDuration = 7 days + 10 minutes` at `epoch2 - 5 minutes` and call `tOB.participate(tOLPId)`.
2. Warp to `epoch2` and call `tOB.newEpoch()`.
3. Warp to `epoch3 - 5 minutes` and call `tOB.exerciseOption(tOLPId, paymentToken, 0)` (first payoff).
4. Warp to `epoch3`, call `tOB.newEpoch()`, then warp to `epoch3 + 10 minutes` and call `tOB.exerciseOption(tOLPId, paymentToken, 0)` again (second payoff).
5. Call `tOB.exitPosition(tOLPId)` and `tOLP.unlock(...)` to exit.
**How found:** Follow-up on prior C4 #189 and a Spearbit report; researcher noticed the mitigation from PR #155 was lost in the audited codebase and reproduced the double-exercise with a Foundry test.
**Exploitation:** Attacker locks a minimal position just before an epoch boundary with a lock duration slightly longer than one epoch, exercises the option near the end of the next epoch, then exercises again shortly after the following epoch trigger, collecting two oTAP payoffs for roughly one epoch of staking and diluting long-term stakers' rewards.
**Insight:** When a fix for a timing/epoch-boundary bug is merged, re-verify it survived later refactors; epoch-boundary accounting bugs recur when eligibility uses current epoch instead of the position's recorded lock window.
