# Users could shift tokens on Staker with more than he has staked

Staker.shiftTokens only checked each side's stake individually, so repeated calls before a price update let a user shift more tokens than staked, including others' tokens.

- Payout: Audit contest
- Severity: high
- Program: Float Capital
- Found by: shw
- Disclosed: 2021-09-16
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-08-floatcapital-findings/issues/141
- Library page: https://bugbountylibrary.com/r/c4%3A2021-08-floatcapital%3AH-03
- Tags: area:web3 domain:web3 impact:integrity kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Staker.sol shiftTokens staking contract function
**Root cause:** shiftTokens validated only the per-side next-price shift amounts against the user's stake, not the sum of long and short shift-away amounts, so multiple calls before the next price update each passed the check.
**Steps:**
1. Call `shiftTokens` with a shift-away amount equal to the user's staked balance on one side.
2. Before the next price update, call `shiftTokens` again with another shift-away amount up to the same balance.
3. Repeat; each call passes the L885 check because `userNextPrice_amountStakedSyntheticToken_toShiftAwayFrom_long`/`_short` are not summed against the stake balance.
4. Accumulated shifts exceed the user's actual stake, moving tokens not belonging to them.
**How found:** Code review of the shiftTokens stake check at Staker.sol#L885, noticing the check compared each shift-away variable separately rather than their sum, and that no state update between calls prevented repetition before the next price update.
**Exploitation:** A malicious user repeatedly calls shiftTokens within one price epoch to shift the entire staker's tokens to one side, including tokens not belonging to them. Direct theft fails at execution on the user level, but the manipulation yields personal gain such as improving the user's FLT issuance rate or other economic advantage.
**Escalation:** Repeated calls within a single price-update window scale the shifted amount arbitrarily, affecting all stakers' tokens rather than just the caller's.
**Insight:** When a function validates a per-epoch pending amount against a balance, check whether the pending accumulators are summed and whether repeated calls within the same epoch can each pass the check before state settles.

