# Malicious validators can flood stake/unstake requests to DoS confirmChange preventing other validators from claiming their collateral

Malicious validators spam 1-wei stake/unstake requests so confirmChange loops over unbounded change sets and OOGs, blocking others' collateral withdrawals.

- Payout: Audit contest
- Severity: medium
- Program: Recall
- Found by: kodyvim
- Disclosed: 2026-03-13
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-02-recall#m-04
- Library page: https://bugbountylibrary.com/r/c4%3A2025-02-recall%3AM-04
- Tags: area:web3 domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** SubnetActor staking/checkpointing contracts (SubnetActorManagerFacet, SubnetActorCheckpointingFacet, LibStaking)
**Root cause:** confirmChange iterates every staking change from startConfigurationNumber to configurationNumber with no bound on change-set size, and stake/unstake accept arbitrarily small amounts, so an attacker can inflate the loop until it exceeds block gas.
**Steps:**
1. Bootstrap a collateral-mode subnet so unstake routes through LibStaking.withdraw (queued) instead of withdrawWithConfirm.
2. As a validator, submit many stake/unstake requests of 1 wei each, each appending a StakingChange to the change set.
3. When a checkpoint is submitted, submitCheckpoint calls LibStaking.confirmChange(checkpoint.nextConfigurationNumber).
4. confirmChange loops `for (i = start; i <= configurationNumber; i++)` over all queued changes; with enough entries the loop exceeds block gas and reverts OOG.
5. Checkpoint submission keeps failing, so Withdraw changes are never confirmed and releaseQueue never releases collateral.
**How found:** Code reading of unstake branching on s.bootstrapped and tracing submitCheckpoint into confirmChange's unbounded loop over changeSet entries; noticed no minimum amount and no iteration cap.
**Exploitation:** Attacker with validator status floods the change set with minimal-value stake/unstake ops; every checkpoint confirmation then OOGs, permanently blocking confirmWithdraw/releaseStake for honest validators so their collateral stays locked.
**Insight:** When a checkpoint/commit function loops over a user-growable queue, check whether entry creation is cheap and unbounded — a 1-wei deposit is enough to make the confirmation loop unpassable and freeze queued withdrawals.

