# Attacker can prevent the system from entering step 5 during the rebalancing period

pushVaultAmounts lacks idempotency, so anyone can re-call it for a chain and inflate fundsReceived past activeVaults, blocking the vault from entering step 5 and halting rebalancing.

- Payout: Contest reward
- Severity: high
- Program: Derby
- Credited: cergyk
- Disclosed: 2022-10-17
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-01-derby-judging/issues/98
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-derby%3AH-12
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** XChainController.pushVaultAmounts / sendXChainAmount (cross-chain rebalancing state machine)
**Root cause:** pushVaultAmounts has no per-chain sent flag, so calling it again for the same chain increments vaultStage.fundsReceived beyond activeVaults, breaking the equality check required to advance to step 5.
**Steps:**
1. System is in step 3 of rebalancing with N active vaults/chains.
2. Off-chain keeper calls `pushVaultAmounts(_vaultNumber, _chain)` for each chain, incrementing fundsReceived toward activeVaults.
3. Attacker calls `pushVaultAmounts(_vaultNumber, _chain)` again for any chain (e.g. a chain needing no withdrawal, which increments immediately).
4. fundsReceived becomes activeVaults + 1, so the `fundsReceived == activeVaults` condition for step 5 never holds.
**How found:** Reviewer read the step-3 state machine and noticed fundsReceived is incremented inside sendXChainAmount with no guard against re-invocation for the same chain, then reasoned that a duplicate call pushes the counter past activeVaults.
**Exploitation:** Attacker front-runs or follows the keeper's pushVaultAmounts calls with a duplicate call for a chain that increments fundsReceived synchronously (no withdrawal needed), permanently desyncing the counter and stalling the vault's rebalancing.
**Insight:** In multi-step keeper-driven state machines, counters incremented per-chain are attacker-touchable if the entry function is permissionless and not idempotent; check whether equality-gated stage transitions can be overshot by replaying a single step.
