# Players can call rebalanceBasket before rewards have been pushed to the game

Game.sol allows rebalanceBasket before currentReward is settled, letting a user profit when reward is negative or causing others to lose rewards.

- Payout: Contest reward
- Severity: medium
- Program: Derby
- Credited: evan
- Disclosed: 2022-10-17
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-01-derby-judging/issues/259
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AM-21
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:reward-distribution

**Target:** Game.sol / MainVault.sol rebalancing flow
**Root cause:** pushAllocationsToVaults resets isXChainRebalancing and re-enables rebalanceBasket, but currentReward for the period is only pushed at the end of the rebalancing process, so reward math uses currentReward=0.
**Steps:**
1. Call `pushAllocationsToController` to start rebalancing (increments rebalancingPeriod).
2. Immediately call `pushAllocationsToVaults` for vaults on all chains, resetting `isXChainRebalancing`.
3. Call `rebalanceBasket` while `currentReward` is still 0.
4. Reward calculation uses wrong currentReward; if actual reward is negative, attacker gets inflated reward.
**How found:** Code reading of the rebalancing state machine: noticed receiveProtocolAllocations is callable regardless of vault state, pushAllocationsToVaults resets isXChainRebalancing, and rebalancingPeriod increments at start while currentReward is only set at the end.
**Exploitation:** Attacker front-runs reward settlement: triggers pushAllocationsToController then pushAllocationsToVaults across chains to re-enable rebalanceBasket, then calls rebalanceBasket while currentReward=0. If the true reward is negative, attacker receives a higher payout than deserved; unaware users calling in the window get wrong rewards.
**Insight:** In multi-step async state machines, check whether a guard flag (isXChainRebalancing) is reset before all dependent state (currentReward) is populated; the window between phase transitions is exploitable.
