Leverage calculation is wrong
Leverage calculation is wrong which will lead to unfair liquidations or over leveraged positions depending on price movements.\\n`_calculate_leverage` miscalculate the leverage by using `_debt_value + _margin_value` as numerator instead of `_position_value` :\\nVault.vy#L465-L477\\n```\\ndef _calculate_leverage(\\n    _position_value: uint256, _debt_value: uint256, _margin_value: uint256\\n) -> uint256:\\n    if _position_value <= _debt_value:\\n        # bad debt\\n        return max_value(uint256)\\n\\n\\n    return (\\n        PRECISION\\n        * (_debt_value + _margin_value)\\n        / (_position_value - _debt_value)\\n        / PRECISION\\n    )\\n```\\n\\nThe three inputs of the function `_position_value`, `_debt_value` and `_margin_value` are all determined by a chainlink oracle price feed. `_debt_value` represents the value of the position's debt share converted to debt amount in USD. `_margin_value` represents the current value of the position's initial margin amount in USD. `_position_value` represents the current value of the position's initial position amount in USD.\\nThe problem with the above calculation is that `_debt_value + _margin_value` does not represent the value of the position. The leverage is the ratio between the current value of the position and the current margin value. `_position_value - _debt_value` is correct and is the current margin value, but `_debt_value + _margin_value` doesn't represent the current value of the position since there is no guarantee that the debt token and the position token have correlated price movements.\\nExample: debt token: ETH, position token: BTC.\\nAlice uses 1 ETH of margin to borrow 14 ETH (2k USD/ETH) and get 1 BTC (30k USD/BTC) of position token. Leverage is 14.\\nThe next day, the price of ETH in USD is still 2k USD/ETH but BTC price in USD went down from 30k to 29k USD/BTC. Leverage is now (_position_value == 29k) / (_position_value == 29k - _debt_value == 28k) = 29, instead of what is calculated in the contract: (_debt_value == 28k + _margin_value == 2k) / (_position_value == 29k - _debt_value == 28k) = 30.
Consider modifying the code like this:\\n```\\ndef _calculate_leverage(\\n    _position_value: uint256, _debt_value: uint256, _margin_value: uint256\\n) -> uint256:\\n    if _position_value <= _debt_value:\\n        # bad debt\\n        return max_value(uint256)\\n\\n\\n    return (\\n        PRECISION\\n-       * (_debt_value + _margin_value)\\n+       * (_position_value)\\n        / (_position_value - _debt_value)\\n        / PRECISION\\n    )\\n```\\n\\nEscalate for 10 USDC. My report shows why the current used formula is wrong as it does not take into account that debt tokens and position tokens are not necessarily tokens with correlated prices. The duplicate #100 shows in another way that the formula fail to calculate the leverage of a position correctly. The impact is the same, but my report highlight `_debt_value + _margin_value != _position_value`, the same way that the debt against a house is not equal to the market value of this house (also described in another way in #156). The definition of leverage used in the code is not correct and will lead to unfair liquidations or over leveraged positions, which is definitely high severity.\\nUnexpected and unfair liquidation could cause loss to users. Since the issue roots from the formula, the loss could be long term, result in accumulated fund loss for users, can can be deemed as "material loss of funds".\\nBased on the above, high severity might be appropriate.\\nUnstoppable-DeFi\\nhrishibhat\\n@Unstoppable-DeFi based on the above escalation it seems to be a high issue. Is there any other reason this should not be a high-severity issue?\\nhrishibhat\\nResult: High Has duplicates Considering this issue a valid high\\nsherlock-admin2\\nEscalations have been resolved successfully!\\nEscalation status:\\ntwicek: accepted
Leverage calculation is wrong which will lead to unfair liquidations or over leveraged positions depending on price movements.
```\\ndef _calculate_leverage(\\n    _position_value: uint256, _debt_value: uint256, _margin_value: uint256\\n) -> uint256:\\n    if _position_value <= _debt_value:\\n        # bad debt\\n        return max_value(uint256)\\n\\n\\n    return (\\n        PRECISION\\n        * (_debt_value + _margin_value)\\n        / (_position_value - _debt_value)\\n        / PRECISION\\n    )\\n```\\n