# User can initiate withdraw for previous epoch if rebase hasn't been called since end of epoch

Unstake() with _trigger=false skips rebase(), so a stale epoch.number lets a user record a withdrawal in the prior epoch and withdraw before funds are available.

- Payout: Contest reward
- Severity: medium
- Program: Yieldy
- Credited: 0x52
- Disclosed: 2022-09-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-06-yieldy-findings/issues/28
- Library page: https://bugbountylibrary.com/r/c4%3A2022-06-yieldy%3AM-06
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Yieldy staking/unstaking contract (Tokemak integration)
**Root cause:** Unstake() lets the caller set _trigger=false to skip rebase(), so epoch.number can be stale relative to the Tokemak epoch; the withdrawal expiry is computed from that stale epoch.
**Steps:**
1. Observe epoch has ended but rebase() not yet called, so epoch.number is stale.
2. Call `unstake(amount, false)` to skip rebase().
3. Withdrawal expiry is set using the stale epoch.number, placing the withdrawal in the previous epoch.
4. Withdraw before funds are actually available in the contract.
**How found:** Code reading of Unstake()'s optional rebase trigger and reasoning that epoch.number could lag the Tokemak epoch when rebase is skipped.
**Exploitation:** User calls unstake with _trigger=false right after an epoch ends, before rebase updates epoch.number, causing their withdrawal to be attributed to the prior epoch and enabling early withdrawal of unstaked assets.
**Insight:** When a state-sync function (rebase) is caller-optional, check every path that reads the synced state (epoch.number) for staleness windows right after epoch boundaries.
