# Unbonding validator random selection can be predicted

Anchor's unbonding picks a validator via XorShiftRng seeded with predictable block height, letting a validator steer unstakes away from itself and capture all bond rewards.

- Payout: Audit contest
- Severity: medium
- Program: Anchor
- Found by: cmichel
- Disclosed: 2023-01-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-02-anchor-findings/issues/29
- Library page: https://bugbountylibrary.com/r/c4%3A2022-02-anchor%3AM-08
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:oracle-manipulation

**Target:** CosmWasm bAsset hub contract (pick_validator / unbond)
**Root cause:** pick_validator seeds XorShiftRng with block_height + iteration_index, which is predictable, so the chosen validator to unstake from is deterministic and attacker-computable.
**Steps:**
1. Read `pick_validator`: `let mut rng = XorShiftRng::seed_from_u64(block_height + iteration_index); let random_index = rng.gen_range(0, deletable_delegations.len());`
2. Attacker calls `execute_bond(amount, validator = A)` to stake to their own validator A.
3. Precompute the RNG output for the next block height to learn which validator unbond would pick.
4. If it is not A, call `unbond`; stake is removed from another validator while A's stake stays intact.
5. Repeat until all Anchor bonds are staked to A.
**How found:** Code review of the unbonding path spotted block height used as an RNG seed, a trivially predictable value, and reasoned that validator selection directly affects reward distribution.
**Exploitation:** Validator bonds to itself, then repeatedly unbonds only when the predictable RNG selects a different validator, draining stake from others while retaining its own bonded amount; over iterations all platform stake concentrates on the attacker's validator, capturing rewards.
**Escalation:** Iterating the bond/unbond cycle scales the attack until the attacker's validator holds essentially all Anchor bond stake.
**Insight:** When a contract uses block height/timestamp as an RNG seed, check whether the outcome gates a value-bearing choice (like which validator/stake is touched) that the caller can retry or skip based on the predicted result.
