An inactive vault can disrupt rebalancing of active vaults
An inactive vault can send its total underlying amount to the `XChainController` and disrupt rebalancing of active vaults by increasing the `underlyingReceived` counter:\\nif `pushVaultAmounts` is called before `underlyingReceived` overflows, rebalancing of one of the active vault may get stuck since the vault won't receive XChain allocations;\\nif `pushVaultAmounts` after all active vaults and at least one inactive vault has reported their underlying amounts, rebalancing of all vaults will get stuck.\\nRebalancing of vaults starts when Game.pushAllocationsToController is called. The function sends the allocations made by gamers to the `XChainController`. `XChainController` receives them in the receiveAllocationsFromGame function. In the settleCurrentAllocation function, a vault is marked as inactive if it has no allocations and there are no new allocations for the vault. `receiveAllocationsFromGameInt` remembers the number of active vaults.\\nThe next step of the rebalancing process is reporting vault underlying token balances to the `XChainController` by calling MainVault.pushTotalUnderlyingToController. As you can see, the function can be called in an inactive vault (the only modifier of the function, `onlyWhenIdle`, doesn't check that `vaultOff` is false). `XChainController` receives underlying balances in the setTotalUnderlying function: notice that the function increases the number of balances it has received.\\nNext step is the XChainController.pushVaultAmounts function, which calculates how much tokens each vault should receive after gamers have changed their allocations. The function can be called only when all active vaults have reported their underlying balances:\\n```\\nmodifier onlyWhenUnderlyingsReceived(uint256 _vaultNumber) {\\n  require(\\n    vaultStage[_vaultNumber].underlyingReceived == vaultStage[_vaultNumber].activeVaults,\\n    "Not all underlyings received"\\n  );\\n  _;\\n}\\n```\\n\\nHowever, as we saw above, inactive vaults can also report their underlying balances and increase the `underlyingReceived` counter-if this is abused mistakenly or intentionally (e.g. by a malicious actor), vaults may end up in a corrupted state. Since all the functions involved in rebalancing are not restricted (including `pushTotalUnderlyingToController` and pushVaultAmounts), a malicious actor can intentionally disrupt accounting of vaults or block a rebalancing.
In the `MainVault.pushTotalUnderlyingToController` function, consider disallowing inactive vaults (vaults that have `vaultOff` set to true) report their underlying balances.
If an inactive vault reports its underlying balances instead of an active vault (i.e. `pushVaultAmounts` is called when `underlyingReceived` is equal activeVaults), the active vault will be excluded from rebalancing and it won't receive updated allocations in the current period. Since the rebalancing interval is 2 weeks, the vault will lose the increased yield that might've been generated thanks to new allocations.\\nIf an inactive vault reports its underlying balances in addition to all active vaults (i.e. `pushVaultAmounts` is called when `underlyingReceived` is greater than activeVaults), then `pushVaultAmounts` will always revert and rebalancing will get stuck.
```\\nmodifier onlyWhenUnderlyingsReceived(uint256 _vaultNumber) {\\n  require(\\n    vaultStage[_vaultNumber].underlyingReceived == vaultStage[_vaultNumber].activeVaults,\\n    "Not all underlyings received"\\n  );\\n  _;\\n}\\n```\\n