Possible to liquidate past the debt outstanding above the min borrow without liquidating the entire debt outstanding
It is possible to liquidate past the debt outstanding above the min borrow without liquidating the entire debt outstanding. Thus, leaving accounts with small debt that are not profitable to unwind if it needs to liquidate.\\n```\\nFile: VaultValuation.sol\\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```\\n\\n`depositUnderlyingInternal` is always a positive value (Refer to comment on Line 250) that represents the amount of underlying deposited by the liquidator\\n`h.debtOutstanding[currencyIndex]` is always a negative value representing debt outstanding of a specific currency in a vault account\\n`minBorrowSize` is always a positive value that represents the minimal borrow size of a specific currency (It is stored as uint32 in storage)\\nIf liquidating past the debt outstanding above the min borrow, then the entire debt outstanding must be liquidated.\\nAssume the following scenario:\\n`depositUnderlyingInternal` = `70 USDC`\\n`h.debtOutstanding[currencyIndex]` = `-100 USDC`\\n`minBorrowSize` = `50 USDC`\\nIf the liquidation is successful, the vault account should be left with `-30 USDC` debt outstanding because `70 USDC` has been paid off by the liquidator. However, this should not happen under normal circumstances because the debt outstanding (-30) does not meet the minimal borrow size of `50 USDC` and the liquidation should revert/fail.\\nThe following piece of validation logic attempts to ensure that all outstanding debt is liquidated if post-liquidation debt does not meet the minimal borrowing size.\\n```\\nrequire(\\n    h.debtOutstanding[currencyIndex].sub(depositUnderlyingInternal) < minBorrowSize,\\n    "Must Liquidate All Debt"\\n);\\n```\\n\\nPlugging in the values from our scenario to verify if the code will revert if the debt outstanding does not meet the minimal borrow size.\\n```\\nrequire(\\n (-100 USDC - 70 USDC) < 50 USDC\\n);\\n===>\\nrequire(\\n (-170 USDC) < 50 USDC\\n);\\n===>\\nrequire(true) // no revert\\n```\\n\\nThe above shows that it is possible for someone to liquidate past the debt outstanding above the min borrow without liquidating the entire debt outstanding. This shows that the math formula in the code is incorrect and not working as intended.
Update the formula to as follows:\\n```\\nrequire(\\n// Remove the line below\\n   h.debtOutstanding[currencyIndex].sub(depositUnderlyingInternal) < minBorrowSize,\\n// Add the line below\\n   h.debtOutstanding[currencyIndex].neg().sub(depositUnderlyingInternal) > minBorrowSize,\\n    "Must Liquidate All Debt"\\n);\\n```\\n\\nPlugging in the values from our scenario again to verify if the code will revert if the debt outstanding does not meet the minimal borrow size.\\n```\\nrequire(\\n ((-100 USDC).neg() - 70 USDC) > 50 USDC\\n);\\n===>\\nrequire(\\n (100 USDC - 70 USDC) > 50 USDC\\n);\\n===>\\nrequire(\\n (30 USDC) > 50 USDC\\n);\\n===>\\nrequire(false) // revert\\n```\\n\\nThe above will trigger a revert as expected when the debt outstanding does not meet the minimal borrow size.
A liquidation can bring an account below the minimum debt. Accounts smaller than the minimum debt are not profitable to unwind if it needs to liquidate (Reference)\\nAs a result, liquidators are not incentivized to liquidate those undercollateralized positions. This might leave the protocol with bad debts, potentially leading to insolvency if the bad debts accumulate.
```\\nFile: VaultValuation.sol\\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```\\n