Vulnerability: inflate initial share price by initial depositor
Severity: medium

Description:
initial deposit can be front-runned by non-whitelist address to inflate share price evading the `training` block, then all users after the first (the attacker) will receive no shares in return for their deposit.\\n`training` block inside `deposit` function intended to be set as true right after deployment. This `training` variable is to make sure the early depositor address is in the whitelist, thus negating any malicious behaviour (especially the first initial depositor)\\n```\\nFile: MainVault.sol\\n  function deposit(\\n    uint256 _amount,\\n    address _receiver\\n  ) external nonReentrant onlyWhenVaultIsOn returns (uint256 shares) {\\n    if (training) {\\n      require(whitelist[msg.sender]);\\n      uint256 balanceSender = (balanceOf(msg.sender) * exchangeRate) / (10 ** decimals());\\n      require(_amount + balanceSender <= maxTrainingDeposit);\\n    }\\n```\\n\\nFirst initial depositor issue is pretty well-known issue in vault share-based token minting for initial deposit which is susceptible to manipulation. This issue arise when the initial vault balance is 0, and initial depositor (attacker) can manipulate this share accounting by donating small amount, thus inflate the share price of his deposit. There are a lot of findings about this initial depositor share issue.\\nEven though the `training` block is (probably) written to mitigate this initial deposit, but since the execution of setting the `training` to be true is not in one transaction, then it's possible to be front-runned by attacker. Then this is again, will make the initial deposit susceptible to attack.\\nThe attack vector and impact is the same as TOB-YEARN-003, where users may not receive shares in exchange for their deposits if the total asset amount has been manipulated through a large “donation”.\\nThe initial exchangeRate is a fixed value set on constructor which is not related to totalSupply, but later it will use this totalSupply\\n```\\nFile: MainVault.sol\\n    exchangeRate = _uScale;\\n// rest of code\\n  function setXChainAllocationInt(\\n    uint256 _amountToSend,\\n    uint256 _exchangeRate,\\n    bool _receivingFunds\\n  ) internal {\\n    amountToSendXChain = _amountToSend;\\n    exchangeRate = _exchangeRate;\\n\\n    if (_amountToSend == 0 && !_receivingFunds) settleReservedFunds();\\n    else if (_amountToSend == 0 && _receivingFunds) state = State.WaitingForFunds;\\n    else state = State.SendingFundsXChain;\\n  }\\n\\nFile: XChainController.sol\\n    uint256 totalUnderlying = getTotalUnderlyingVault(_vaultNumber) - totalWithdrawalRequests;\\n    uint256 totalSupply = getTotalSupply(_vaultNumber);\\n\\n    uint256 decimals = xProvider.getDecimals(vault);\\n    uint256 newExchangeRate = (totalUnderlying * (10 ** decimals)) / totalSupply;\\n```\\n

Impact:
initial depositor can inflate share price, other user (next depositor) can lost their asset

Recommended mitigation:
The simplest way around for this is just set the initial `training` to be `true` either in the variable definition or set it in constructor, so the initial depositor will be from the whitelist.\\nor, more common solution for this issue is, require a minimum size for the first deposit and burn a portion of the initial shares (or transfer it to a secure address)