# Rewards for initial period may be lost in BathBuddy contract

BathBuddy starts reward accrual at notifyRewardAmount before any BathToken holders exist, so rewards for the pre-participation period are stranded in the contract.

- Payout: Contest reward
- Severity: medium
- Program: Rubicon
- Credited: adriro
- Disclosed: 2025-02-17
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-04-rubicon-findings/issues/1295
- Library page: https://bugbountylibrary.com/r/c4%3A2023-04-rubicon%3AM-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:reward-distribution

**Target:** BathBuddy staking rewards contract (Solidity)
**Root cause:** notifyRewardAmount sets lastUpdateTime and periodFinish immediately, so rewardRate accrues from that timestamp even when totalSupply is zero; no one can claim the pre-participation accrual.
**Steps:**
1. Owner calls `setRewardsDuration(duration, rewardToken)` and funds contract with `rewardAmount`.
2. Owner calls `notifyRewardAmount(rewardAmount, rewardToken)`; lastUpdateTime = now, periodFinish = now + duration.
3. Warp to startTime + duration/2; call `getReward(rewardToken, address(0))` to checkpoint state.
4. Mint BathTokens to Alice (first participant).
5. Warp to startTime + duration; call `getReward(rewardToken, alice)`.
6. Assert: Alice receives rewardAmount/2; rewardAmount/2 remains stuck in BathBuddy.
**How found:** Code review of notifyRewardAmount's rate/period accounting; recognized the Synthetix-style staking rewards edge case where accrual begins before any staker exists, then confirmed with a Foundry PoC.
**Insight:** In Synthetix-derived reward contracts, check whether lastUpdateTime/periodFinish are set at notify time versus first-stake time; if accrual starts with zero totalSupply, the pre-participation share is permanently stranded.
