Summary
Market can allow leverage higher than 2x, and this is design choice. But the check owedAmount > totalDenom in isLiquidateable function doesn't allow leverage higher than 2x.
Root Cause
positionLeverage is calculated and checked in _checkWithinlimits function when open leverage.
function _checkWithinlimits(Position memory up) internal {
...
@> uint256 positionLeverage = (up.initCollateralValue + up.borrowedAmount) * 1e18 / up.initCollateralValue;
require(positionLeverage <= vp.maxTimesLeverage && positionLeverage <= maxLevTimes, "too high x leverage");
...
}Opening leverage also checks whether the position is liquidateable. isLiquidateable checks if owedAmount > totalDenom and returns true (indicating liquidation).
function isLiquidateable(uint256 _id) public view returns (bool liquidateable) {
...
uint256 totalValueUSD = _calculateTokenValues(pos.token0, pos.token1, userBal0, userBal1, price);
uint256 bPrice = IPriceFeed(pricefeed).getPrice(pos.denomination);
uint256 totalDenom = totalValueUSD * (10 ** ERC20(pos.denomination).decimals()) / bPrice;
uint256 bIndex = ILendingPool(lendingPool).getCurrentBorrowingIndex(pos.denomination);
uint256 owedAmount = pos.borrowedAmount * bIndex / pos.borrowedIndex;
/// here we make a calculation what would be the necessary collateral
/// if we had the same borrowed amount, but at max leverage. Check docs for better explanation why.
uint256 base = owedAmount * 1e18 / (vp.maxTimesLeverage - 1e18);
base = base < pos.initCollateralValue ? base : pos.initCollateralValue;
@> if (owedAmount > totalDenom || totalDenom - owedAmount < vp.minCollateralPct * base / 1e18) return true;
else return false;
}When open leverage, owedAmount is equal to borrowedAmount and totalDenom is equal to initCollateralValue. To be not liquidateable, owedAmount <= totalDenom should be satisfied, and this means that positionLeverage is always smaller than 2x.
Root cause is contradiction between high-leverage and liquidation check of position. This means that the define of positionLeverage could be incorrect or liquidation check could be incorrect.
Impact
Market doesn't allow leverage higher than 2x
Mitigation
Update the positionLeverage check logic or isLiquidateable function logic.