# Polygon Consensus Bypass Bugfix Review

Migrating delegation from an unstaked validator double-subtracted staking power in Polygon's StakeManager, letting an attacker shrink total stake below the 2/3 threshold and forge checkpoints to drain the deposit manager.

- Payout: $75,000
- Severity: high
- Program: Polygon
- Credited: Niv Yehezkel
- Disclosed: 2022-02-21
- Write-up quality: 8/10
- Original: https://immunefi.com/blog/bug-fix-reviews/polygon-consensus-bypass-bugfix-review/
- Library page: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-polygon-consensus-bypass-bugfix-review
- Tags: domain:web3 impact:funds-loss impact:integrity kind:bounty platform:blog platform:immunefi sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic

**Target:** StakeManager / ValidatorShare staking contracts on Ethereum
**Root cause:** migrateOut calls updateValidatorState(validatorId, -amount) which runs updateTimeline(-amount) reducing total staking power even when the source validator has already unstaked, so the delegated amount is subtracted twice.
**Steps:**
1. Create a validator via `stakeFor()` and call `buyVoucher()` with a large delegated amount.
2. Wait for an open validator slot via the on-chain auction.
3. Call `migrateDelegation()` to move stake into that validator, then unstake the validator so `validatorState.amount` is decremented again.
4. Wait for a checkpoint so the slot reopens; repeat to repeatedly subtract the same delegated amount from total staking power.
5. Once total staking power is low enough, submit malicious checkpoints to bypass the 2/3 majority check.
**How found:** Researcher traced accounting in updateTimeline/updateValidatorState across migrateOut and unstake paths and noticed the delegated amount is subtracted on migration and again on unstake, without checking whether the source validator is still staking.
**Exploitation:** Attacker repeatedly migrates delegation out of unstaked validators to double-decrement total staking power, lowering the 2/3 consensus threshold until a single validator can pass checkpoints, then submits malicious checkpoints faking withdrawals to drain the deposit manager and claim Heimdall fees. Requires an open validator slot, high capital, and flashbots payments to hold the slot across 30-45 min checkpoint intervals.
**Escalation:** Iterating the migrate/unstake cycle scales the staking-power reduction until consensus threshold is bypassed, enabling deposit manager drain, unlimited withdrawals, and DoS.
**Insight:** In staking/accounting contracts, audit every path that mutates a global aggregate (total stake, total shares) for double-counting when an entity transitions state (unstake) and later triggers another decrement via migration or withdrawal; check ordering of state checks vs aggregate updates.
