Differences between actual and cached total assets can be arbitraged
The actual total amount of assets that are owned by a LMPVault on-chain can be derived via the following formula:\\n$$ totalAssets_{actual} = \\sum_{n=1}^{x}debtValue(DV_n) $$\\nWhen `LMPVault.totalAssets()` function is called, it returns the cached total assets of the LMPVault instead.\\n$$ totalAssets_{cached} = totalIdle + totalDebt $$\\n```\\nFile: LMPVault.sol\\n    function totalAssets() public view override returns (uint256) {\\n        return totalIdle + totalDebt;\\n    }\\n```\\n\\nThus, the $totalAssets_{cached}$ will deviate from $totalAssets_{actual}$. This difference could be arbitraged or exploited by malicious users for their gain.\\nCertain actions such as `previewDeposit`, `previewMint`, `previewWithdraw,` and `previewRedeem` functions rely on the $totalAssets_{cached}$ value while other actions such as `_withdraw` and `_calcUserWithdrawSharesToBurn` functions rely on $totalAssets_{actual}$ value.\\nThe following shows one example of the issue.\\nThe `previewDeposit(assets)` function computed the number of shares to be received after depositing a specific amount of assets:\\n$$ shareReceived = \\frac{assets_{deposited}}{totalAssets_{cached}} \\times totalSupply $$\\nAssume that $totalAssets_{cached} < totalAssets_{actual}$, and the values of the variables are as follows:\\n$totalAssets_{cached}$ = 110 WETH\\n$totalAssets_{actual}$ = 115 WETH\\n$totalSupply$ = 100 shares\\nAssume Bob deposited 10 WETH when the total assets are 110 WETH (when $totalAssets_{cached} < totalAssets_{actual}$), he would receive:\\n$$ \\begin{align} shareReceived &= \\frac{10 ETH}{110 ETH} \\times 100e18\\ shares \\ &= 9.090909091e18\\ shares \\end{align} $$\\nIf a user deposited 10 WETH while the total assets are updated to the actual worth of 115 WETH (when $totalAssets_{cached} == totalAssets_{actual}$, they would receive:\\n$$ \\begin{align} shareReceived &= \\frac{10 ETH}{115 ETH} \\times 100e18\\ shares \\ &= 8.695652174e18\\ shares \\ \\end{align} $$\\nTherefore, Bob is receiving more shares than expected.\\nIf Bob redeems all his nine (9) shares after the $totalAssets_{cached}$ has been updated to $totalAssets_{actual}$, he will receive 10.417 WETH back.\\n$$ \\begin{align} assetsReceived &= \\frac{9.090909091e18\\ shares}{(100e18 + 9.090909091e18)\\ shares} \\times (115 + 10)\\ ETH \\ &= \\frac{9.090909091e18\\ shares}{109.090909091e18\\ shares} \\times 125 ETH \\ &= 10.41666667\\ ETH \\end{align} $$\\nBob profits 0.417 WETH simply by arbitraging the difference between the cached and actual values of the total assets. Bob gains is the loss of other vault shareholders.\\nThe $totalAssets_{cached}$ can be updated to $totalAssets_{actual}$ by calling the permissionless `LMPVault.updateDebtReporting` function. Alternatively, one could also perform a sandwich attack against the `LMPVault.updateDebtReporting` function by front-run it to take advantage of the lower-than-expected price or NAV/share, and back-run it to sell the shares when the price or NAV/share rises after the update.\\nOne could also reverse the attack order, where an attacker withdraws at a higher-than-expected price or NAV/share, perform an update on the total assets, and deposit at a lower price or NAV/share.
Consider updating $totalAssets_{cached}$ to $totalAssets_{actual}$ before any withdrawal or deposit to mitigate this issue.
Loss assets for vault shareholders. Attacker gains are the loss of other vault shareholders.
```\\nFile: LMPVault.sol\\n    function totalAssets() public view override returns (uint256) {\\n        return totalIdle + totalDebt;\\n    }\\n```\\n