Vulnerability: MainVault.rebalanceXChain doesn't check that savedTotalUnderlying >= reservedFunds
Severity: medium

Description:
MainVault.rebalanceXChain doesn't check that savedTotalUnderlying >= reservedAmount. Because of that, shortage can occur, if vault will lose some underlying during cross chain calls and reservedFundswill not be present in the vault.\\n`reservedFunds` is the amount that is reserved to be withdrawn by users. It's increased by `totalWithdrawalRequests` amount every cycle, when `setXChainAllocation` is called.\\n`setXChainAllocation` call is initiated by xController. This call provides vault with information about funds. In case if vault should send funds to the xController, then `SendingFundsXChain` state is set, aslo amount to send is stored.\\n```\\n  function rebalanceXChain(uint256 _slippage, uint256 _relayerFee) external payable {\\n    require(state == State.SendingFundsXChain, stateError);\\n\\n\\n    if (amountToSendXChain > getVaultBalance()) pullFunds(amountToSendXChain);\\n    if (amountToSendXChain > getVaultBalance()) amountToSendXChain = getVaultBalance();\\n\\n\\n    vaultCurrency.safeIncreaseAllowance(xProvider, amountToSendXChain);\\n    IXProvider(xProvider).xTransferToController{value: msg.value}(\\n      vaultNumber,\\n      amountToSendXChain,\\n      address(vaultCurrency),\\n      _slippage,\\n      _relayerFee\\n    );\\n\\n\\n    emit RebalanceXChain(vaultNumber, amountToSendXChain, address(vaultCurrency));\\n\\n\\n    amountToSendXChain = 0;\\n    settleReservedFunds();\\n  }\\n```\\n\\nAs you can see, function just pulls needed funds from providers if needed and sends them to xController. It doesn't check that after that amount that is held by vault is enough to cover `reservedFunds`. Because of that next situation can occur.\\n1.Suppose that vault has 1000 tokens as underlying amount. 2.reservedFunds is 200. 3.xController calculated that vault should send 800 tokens to xController(vault allocations is 0) and 200 should be still in the vault in order to cover `reservedFunds`. 4.when vault is going to send 800 tokens(between `setXChainAllocation` and `rebalanceXChain` call), then loss happens and totalUnderlying becomes 800, so currently vault has only 800 tokens in total. 5.vault sends this 800 tokens to xController and has 0 to cover `reservedFunds`, but actually he should leave this 200 tokens in the vault in this case.\\n```\\n    if (amountToSendXChain > getVaultBalance()) pullFunds(amountToSendXChain);\\n    if (amountToSendXChain > getVaultBalance()) amountToSendXChain = getVaultBalance();\\n```\\n\\nI think that this is incorrect approach for withdrawing of funds as there is a risk that smth will happen with underlying amount in the providers, so it will be not enough to cover `reservedFunds` and calculations will be broken, users will not be able to withdraw. Same approach is done in `rebalance` function, which pulls `reservedFunds` after depositing to all providers. I guess that correct approach is not to touch `reservedFunds` amount. In case if you need to send amount to xController, then you need to withdraw it directly from provider. Of course if you have `getVaultBalance` that is bigger than `reservedFunds + amountToSendXChain`, then you can send them directly, without pulling.

Impact:
Reserved funds protection can be broken

Recommended mitigation:
You need to check that after you send funds to xController it's enough funds to cover `reservedFunds`.