LMPVault.updateDebtReporting could underflow because of subtraction before addition
`debt = totalDebt - prevNTotalDebt + afterNTotalDebt` where prevNTotalDebt equals `(destInfo.currentDebt * originalShares) / Math.max(destInfo.ownedShares, 1)` and the key to finding a scenario for underflow starts by noting that each value deducted from totalDebt is calculated as `cachedCurrentDebt.mulDiv(sharesToBurn, cachedDvShares, Math.Rounding.Up)`\\nLMPDebt\\n```\\n// rest of code\\nL292    totalDebtBurn = cachedCurrentDebt.mulDiv(sharesToBurn, cachedDvShares, Math.Rounding.Up);\\n// rest of code\\nL440    uint256 currentDebt = (destInfo.currentDebt * originalShares) / Math.max(destInfo.ownedShares, 1);\\nL448    totalDebtDecrease = currentDebt;\\n```\\n\\nLet: `totalDebt = destInfo.currentDebt = destInfo.debtBasis = cachedCurrentDebt = cachedDebtBasis = 11` `totalSupply = destInfo.ownedShares = cachedDvShares = 10`\\nThat way: `cachedCurrentDebt * 1 / cachedDvShares = 1.1` but totalDebtBurn would be rounded up to 2\\n`sharesToBurn` could easily be 1 if there was a loss that changes the ratio from `1:1.1` to `1:1`. Therefore `currentDvDebtValue = 10 * 1 = 10`\\n```\\nif (currentDvDebtValue < updatedDebtBasis) {\\n    // We are currently sitting at a loss. Limit the value we can pull from\\n    // the destination vault\\n    currentDvDebtValue = currentDvDebtValue.mulDiv(userShares, totalVaultShares, Math.Rounding.Down);\\n    currentDvShares = currentDvShares.mulDiv(userShares, totalVaultShares, Math.Rounding.Down);\\n}\\n\\n// Shouldn't pull more than we want\\n// Or, we're not in profit so we limit the pull\\nif (currentDvDebtValue < maxAssetsToPull) {\\n    maxAssetsToPull = currentDvDebtValue;\\n}\\n\\n// Calculate the portion of shares to burn based on the assets we need to pull\\n// and the current total debt value. These are destination vault shares.\\nsharesToBurn = currentDvShares.mulDiv(maxAssetsToPull, currentDvDebtValue, Math.Rounding.Up);\\n```\\n\\nSteps\\ncall redeem 1 share and previewRedeem request 1 `maxAssetsToPull`\\n2 debt would be burn\\nTherefore totalDebt = 11-2 = 9\\ncall another redeem 1 share and request another 1 `maxAssetsToPull`\\n2 debts would be burn again and\\ntotalDebt would be 7, but prevNTotalDebt = 11 * 8 // 10 = 8\\nUsing 1, 10 and 11 are for illustration and the underflow could occur in several other ways. E.g if we had used `100,001`, `1,000,010` and `1,000,011` respectively.
Add before subtracting. ETH in circulation is not enough to cause an overflow.\\n```\\n- debt = totalDebt - prevNTotalDebt + afterNTotalDebt\\n+ debt = totalDebt + afterNTotalDebt - prevNTotalDebt\\n```\\n
_updateDebtReporting could underflow and break a very important core functionality of the protocol. updateDebtReporting is so critical that funds could be lost if it doesn't work. Funds could be lost both when the vault is in profit or at loss.\\nIf in profit, users would want to call updateDebtReporting so that they get more asset for their shares (based on the profit).\\nIf in loss, the whole vault asset is locked and withdrawals won't be successful because the Net Asset Value is not supposed to reduce by such action (noNavDecrease modifier). Net Asset Value has reduced because the loss would reduce totalDebt, but the only way to update the totalDebt record is by calling updateDebtReporting. And those impacted the most are those with large funds. The bigger the fund, the more NAV would decrease by withdrawals.
```\\n// rest of code\\nL292    totalDebtBurn = cachedCurrentDebt.mulDiv(sharesToBurn, cachedDvShares, Math.Rounding.Up);\\n// rest of code\\nL440    uint256 currentDebt = (destInfo.currentDebt * originalShares) / Math.max(destInfo.ownedShares, 1);\\nL448    totalDebtDecrease = currentDebt;\\n```\\n