Partial liquidations are not possible
Due to an incorrect implementation of `VaultValuation.getLiquidationFactors()`, Notional requires that a liquidator reduces an account's debt below `minBorrowSize`. This does not allow liquidators to partially liquidate a vault account into a healthy position and opens up the protocol to an edge case where an account is always ineligible for liquidation.\\nWhile `VaultValuation.getLiquidationFactors()` might allow for the resultant outstanding debt to be below the minimum borrow amount and non-zero, `deleverageAccount()` will revert due to `checkMinBorrow` being set to `true`. Therefore, the only option is for liquidators to wipe the outstanding debt entirely but users can set up their vault accounts such that that `maxLiquidatorDepositLocal` is less than each of the vault currency's outstanding debt.\\n```\\nFile: VaultValuation.sol\\n        int256 maxLiquidatorDepositLocal = _calculateDeleverageAmount(\\n            vaultConfig,\\n            h.vaultShareValueUnderlying,\\n            h.totalDebtOutstandingInPrimary.neg(),\\n            h.debtOutstanding[currencyIndex].neg(),\\n            minBorrowSize,\\n            exchangeRate,\\n            er.rateDecimals\\n        );\\n\\n        // NOTE: deposit amount is always positive in this method\\n        if (depositUnderlyingInternal < maxLiquidatorDepositLocal) {\\n            // If liquidating past the debt outstanding above the min borrow, then the entire\\n            // debt outstanding must be liquidated.\\n\\n            // (debtOutstanding - depositAmountUnderlying) is the post liquidation debt. As an\\n            // edge condition, when debt outstanding is discounted to present value, the account\\n            // may be liquidated to zero while their debt outstanding is still greater than the\\n            // min borrow size (which is normally enforced in notional terms -- i.e. non present\\n            // value). Resolving this would require additional complexity for not much gain. An\\n            // account within 20% of the minBorrowSize in a vault that has fCash discounting enabled\\n            // may experience a full liquidation as a result.\\n            require(\\n                h.debtOutstanding[currencyIndex].sub(depositUnderlyingInternal) < minBorrowSize,\\n                "Must Liquidate All Debt"\\n            );\\n        } else {\\n            // If the deposit amount is greater than maxLiquidatorDeposit then limit it to the max\\n            // amount here.\\n            depositUnderlyingInternal = maxLiquidatorDepositLocal;\\n        }\\n```\\n\\nIf `depositUnderlyingInternal >= maxLiquidatorDepositLocal`, then the liquidator's deposit is capped to `maxLiquidatorDepositLocal`. However, `maxLiquidatorDepositLocal` may put the vault account's outstanding debt below the minimum borrow amount but not to zero.\\nHowever, because it is not possible to partially liquidate the account's debt, we reach a deadlock where it isn't possible to liquidate all outstanding debt and it also isn't possible to liquidate debt partially. So even though it may be possible to liquidate an account into a healthy position, the current implementation doesn't always allow for this to be true.
`VaultValuation.getLiquidationFactors()` must be updated to allow for partial liquidations.\\n```\\nFile: VaultValuation.sol\\n        if (depositUnderlyingInternal < maxLiquidatorDepositLocal) {\\n            // If liquidating past the debt outstanding above the min borrow, then the entire\\n            // debt outstanding must be liquidated.\\n\\n            // (debtOutstanding - depositAmountUnderlying) is the post liquidation debt. As an\\n            // edge condition, when debt outstanding is discounted to present value, the account\\n            // may be liquidated to zero while their debt outstanding is still greater than the\\n            // min borrow size (which is normally enforced in notional terms -- i.e. non present\\n            // value). Resolving this would require additional complexity for not much gain. An\\n            // account within 20% of the minBorrowSize in a vault that has fCash discounting enabled\\n            // may experience a full liquidation as a result.\\n            require(\\n                h.debtOutstanding[currencyIndex].neg().sub(depositUnderlyingInternal) >= minBorrowSize,\\n                         || h.debtOutstanding[currencyIndex].neg().sub(depositUnderlyingInternal) == 0\\n                "Must Liquidate All Debt"\\n            );\\n        } else {\\n            // If the deposit amount is greater than maxLiquidatorDeposit then limit it to the max\\n            // amount here.\\n            depositUnderlyingInternal = maxLiquidatorDepositLocal;\\n        }\\n```\\n
Certain vault positions will never be eligible for liquidation and hence Notional may be left with bad debt. Liquidity providers will lose funds as they must cover the shortfall for undercollateralised positions.
```\\nFile: VaultValuation.sol\\n        int256 maxLiquidatorDepositLocal = _calculateDeleverageAmount(\\n            vaultConfig,\\n            h.vaultShareValueUnderlying,\\n            h.totalDebtOutstandingInPrimary.neg(),\\n            h.debtOutstanding[currencyIndex].neg(),\\n            minBorrowSize,\\n            exchangeRate,\\n            er.rateDecimals\\n        );\\n\\n        // NOTE: deposit amount is always positive in this method\\n        if (depositUnderlyingInternal < maxLiquidatorDepositLocal) {\\n            // If liquidating past the debt outstanding above the min borrow, then the entire\\n            // debt outstanding must be liquidated.\\n\\n            // (debtOutstanding - depositAmountUnderlying) is the post liquidation debt. As an\\n            // edge condition, when debt outstanding is discounted to present value, the account\\n            // may be liquidated to zero while their debt outstanding is still greater than the\\n            // min borrow size (which is normally enforced in notional terms -- i.e. non present\\n            // value). Resolving this would require additional complexity for not much gain. An\\n            // account within 20% of the minBorrowSize in a vault that has fCash discounting enabled\\n            // may experience a full liquidation as a result.\\n            require(\\n                h.debtOutstanding[currencyIndex].sub(depositUnderlyingInternal) < minBorrowSize,\\n                "Must Liquidate All Debt"\\n            );\\n        } else {\\n            // If the deposit amount is greater than maxLiquidatorDeposit then limit it to the max\\n            // amount here.\\n            depositUnderlyingInternal = maxLiquidatorDepositLocal;\\n        }\\n```\\n