# `XChainController::sendFundsToVault` can be griefed and leave `XChainController` in a bad state

Repeated calls to XChainController.sendFundsToVault reset vault state prematurely, desyncing controller from vaults and blocking rebalancing.

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

**Target:** XChainController cross-chain rebalancing contract
**Root cause:** sendFundsToVault lacks a check that a chain/vault was already processed, so any caller can trigger the state reset for a vaultNumber before all chains have received funds.
**Steps:**
1. Set up state after '4.5) Trigger vaults to transfer funds to xChainController' in xChaincontroller.test.ts
2. Call `xChainController.sendFundsToVault(vaultNumber, slippage, 10000, 0, {value:0})` four times
3. Observe `getFundsReceivedState(vaultNumber)` returns 0 and vault3.state() == 3
4. Further `sendFundsToVault` with relayerFee reverts with 'Not all funds received'
**How found:** Reviewers noticed the function transitions state without tracking which chains/vaults were already processed, then reproduced by calling it multiple times in the hardhat test.
**Exploitation:** Attacker repeatedly calls sendFundsToVault for a vaultNumber, forcing the funds-received state to reset before all chains are processed; guardian admin resets can be frontrun, halting rebalancing for affected vaults.
**Insight:** In multi-chain state machines, check per-chain/per-vault completion flags before allowing a global state reset; any permissionless transition function is a griefing surface if it can be called out of order.
