Users can get around MaxLTV because of lack of strategyId validation
When a user withdraws some of their underlying token, there is a check to ensure they still meet the Max LTV requirements. However, they are able to arbitrarily enter any `strategyId` that they would like for this check, which could allow them to exceed the LTV for their real strategy while passing the approval.\\nWhen a user calls `IchiVaultSpell.sol#reducePosition()`, it removes some of their underlying token from the vault, increasing the LTV of any loans they have taken.\\nAs a result, the `_validateMaxLTV(strategyId)` function is called to ensure they remain compliant with their strategy's specified LTV:\\n```\\nfunction _validateMaxLTV(uint256 strategyId) internal view {\\n    uint256 debtValue = bank.getDebtValue(bank.POSITION_ID());\\n    (, address collToken, uint256 collAmount, , , , , ) = bank\\n        .getCurrentPositionInfo();\\n    uint256 collPrice = bank.oracle().getPrice(collToken);\\n    uint256 collValue = (collPrice * collAmount) /\\n        10**IERC20Metadata(collToken).decimals();\\n\\n    if (\\n        debtValue >\\n        (collValue * maxLTV[strategyId][collToken]) / DENOMINATOR\\n    ) revert EXCEED_MAX_LTV();\\n}\\n```\\n\\nTo summarize, this check:\\nPulls the position's total debt value\\nPulls the position's total value of underlying tokens\\nPulls the specified maxLTV for this strategyId and underlying token combination\\nEnsures that `underlyingTokenValue * maxLTV > debtValue`\\nBut there is no check to ensure that this `strategyId` value corresponds to the strategy the user is actually invested in, as we can see the `reducePosition()` function:\\n```\\nfunction reducePosition(\\n    uint256 strategyId,\\n    address collToken,\\n    uint256 collAmount\\n) external {\\n    doWithdraw(collToken, collAmount);\\n    doRefund(collToken);\\n    _validateMaxLTV(strategyId);\\n}\\n```\\n\\nHere is a quick proof of concept to explain the risk:\\nLet's say a user deposits 1000 DAI as their underlying collateral.\\nThey are using a risky strategy (let's call it strategy 911) which requires a maxLTV of 2X (ie maxLTV[911][DAI] = 2e5)\\nThere is another safer strategy (let's call it strategy 411) which has a maxLTV of 5X (ie maxLTV[411][DAI] = 4e5)\\nThe user takes the max loan from the risky strategy, borrowing $2000 USD of value.\\nThey are not allowed to take any more loans from that strategy, or remove any of their collateral.\\nThen, they call `reducePosition()`, withdrawing 1600 DAI and entering `411` as the strategyId.\\nThe `_validateMaxLTV` check will happen on `strategyId = 411`, and will pass, but the result will be that the user now has only 400 DAI of underlying collateral protecting $2000 USD worth of the risky strategy, violating the LTV.
Issue Users can get around MaxLTV because of lack of strategyId validation\\nSince the collateral a position holds will always be the vault token of the strategy they have used, you can validate the `strategyId` against the user's collateral, as follows:\\n```\\naddress positionCollToken = bank.positions(bank.POSITION_ID()).collToken;\\naddress positionCollId = bank.positions(bank.POSITION_ID()).collId;\\naddress unwrappedCollToken = IERC20Wrapper(positionCollToken).getUnderlyingToken(positionCollId);\\nrequire(strategies[strategyId].vault == unwrappedCollToken, "wrong strategy");\\n```\\n
Users can get around the specific LTVs and create significantly higher leverage bets than the protocol has allowed. This could cause the protocol to get underwater, as the high leverage combined with risky assets could lead to dramatic price swings without adequate time for the liquidation mechanism to successfully protect solvency.
```\\nfunction _validateMaxLTV(uint256 strategyId) internal view {\\n    uint256 debtValue = bank.getDebtValue(bank.POSITION_ID());\\n    (, address collToken, uint256 collAmount, , , , , ) = bank\\n        .getCurrentPositionInfo();\\n    uint256 collPrice = bank.oracle().getPrice(collToken);\\n    uint256 collValue = (collPrice * collAmount) /\\n        10**IERC20Metadata(collToken).decimals();\\n\\n    if (\\n        debtValue >\\n        (collValue * maxLTV[strategyId][collToken]) / DENOMINATOR\\n    ) revert EXCEED_MAX_LTV();\\n}\\n```\\n