Vulnerability: All transactions to claim assets from the vault will revert in some situations due to double subtraction of the claimed assets in market position allocations calculation.
Severity: medium

Description:
When `assets` are claimed from the vault (Vault.update(0,0,x) called), the vault rebalances its collateral. There is an issue with market positions allocation calculations: the `assets` ("total position") subtract claimed amount twice. This leads to revert in case this incorrect `assets` amount is less than `minAssets` (caused by market's minPosition). In situations when the vault can't redeem due to some market's position being at the `minPosition` (because of the market's skew, which disallows makers to reduce their positions), this will lead to all users being unable to claim any `assets` which were already redeemed and settled.\\n`Vault.update` rebalances collateral by calling _manage:\\n```\\n_manage(context, depositAssets, claimAmount, !depositAssets.isZero() || !redeemShares.isZero());\\n```\\n\\nIn the rebalance calculations, collateral and assets (assets here stands for "total vault position") are calculated as following:\\n```\\n  UFixed6 collateral = UFixed6Lib.unsafeFrom(strategy.totalCollateral).add(deposit).unsafeSub(withdrawal);\\n  UFixed6 assets = collateral.unsafeSub(ineligable);\\n\\n  if (collateral.lt(strategy.totalMargin)) revert StrategyLibInsufficientCollateralError();\\n  if (assets.lt(strategy.minAssets)) revert StrategyLibInsufficientAssetsError();\\n```\\n\\n`ineligable` is calculated as following:\\n```\\nfunction _ineligable(Context memory context, UFixed6 withdrawal) private pure returns (UFixed6) {\\n    // assets eligable for redemption\\n    UFixed6 redemptionEligable = UFixed6Lib.unsafeFrom(context.totalCollateral)\\n        .unsafeSub(withdrawal)\\n        .unsafeSub(context.global.assets)\\n        .unsafeSub(context.global.deposit);\\n\\n    return redemptionEligable\\n        // approximate assets up for redemption\\n        .mul(context.global.redemption.unsafeDiv(context.global.shares.add(context.global.redemption)))\\n        // assets pending claim\\n        .add(context.global.assets)\\n        // assets withdrawing\\n        .add(withdrawal);\\n}\\n```\\n\\nNotice that `ineligable` adds `withdrawal` in the end (which is the assets claimed by the user). Now back to collateral and assets calculation:\\n`collateral = totalCollateral + deposit - withdrawal`\\n`assets = collateral - ineligable = collateral - (redemptionEligable * redemption / (redemption + shares) + global.assets + withdrawal)`\\n`assets = totalCollateral + deposit - withdrawal - [redemptionIneligable] - global.assets - withdrawal`\\n`assets = totalCollateral + deposit - [redemptionIneligable] - global.assets - 2 * withdrawal`\\nSee that `withdrawal` (assets claimed by the user) is subtracted twice in assets calculations. This means that assets calculated are smaller than it should. In particular, assets might become less than minAssets thus reverting in the following line:\\n```\\n  if (assets.lt(strategy.minAssets)) revert StrategyLibInsufficientAssetsError();\\n```\\n\\nPossible scenario for this issue to cause inability to claim funds:\\nSome vault market's has a high skew (|long - short|), which means that minimum maker position is limited by the skew.\\nUser redeems large amount from the vault, reducing vault's position in that market so that market maker ~= |long - short|. This means that further redeems from the vault are not possible because the vault can't reduce its position in the market.\\nAfter that, the user tries to claim what he has redeemed, but all attempts to redeem will revert (both for this user and for any other user that might want to claim)\\nThe scenario above is demonstrated in the test, change the following test in test/integration/vault/Vault.test.ts:\\n```\\n    it('simple deposits and redemptions', async () => {\\n// rest of code\\n      // Now we should have opened positions.\\n      // The positions should be equal to (smallDeposit + largeDeposit) * leverage originalOraclePrice.\\n      expect(await position()).to.equal(\\n        smallDeposit.add(largeDeposit).mul(leverage).mul(4).div(5).div(originalOraclePrice),\\n      )\\n      expect(await btcPosition()).to.equal(\\n        smallDeposit.add(largeDeposit).mul(leverage).div(5).div(btcOriginalOraclePrice),\\n      )\\n\\n      /*** remove all lines after this and replace with the following code: ***/\\n\\n      var half = smallDeposit.add(largeDeposit).div(2).add(smallDeposit);\\n      await vault.connect(user).update(user.address, 0, half, 0)\\n\\n      await updateOracle()\\n      await vault.connect(user2).update(user2.address, smallDeposit, 0, 0) // this will create min position in the market\\n      await vault.connect(user).update(user.address, 0, 0, half) // this will revert even though it's just claiming\\n    })\\n```\\n\\nThe last line in the test will revert, even though it's just claiming assets. If the pre-last line is commented out (no "min position" created in the market), it will work normally.

Impact:
In certain situations (redeem not possible from the vault due to high skew in some underlying market) claiming assets from the vault will revert for all users, temporarily (and sometimes permanently) locking user funds in the contract.

Recommended mitigation:
Remove `add(withdrawal)` from `_ineligable` calculation in the vault.