Malicious users could lock in the NAV/Share of the DV to cause the loss of fees
The `_collectFees` function only collects fees whenever the NAV/Share exceeds the last NAV/Share.\\nDuring initialization, the `navPerShareHighMark` is set to `1`, effectively `1` ETH per share (1:1 ratio). Assume the following:\\nIt is at the early stage, and only a few shares (0.5 shares) were minted in the LMPVault\\nThere is a sudden increase in the price of an LP token in a certain DV (Temporarily)\\n`performanceFeeBps` is 10%\\nIn this case, the debt value of DV's shares will increase, which will cause LMPVault's debt to increase. This event caused the `currentNavPerShare` to increase to `1.4` temporarily.\\nSomeone calls the permissionless `updateDebtReporting` function. Thus, the profit will be `0.4 ETH * 0.5 Shares = 0.2 ETH`, which is small due to the number of shares (0.5 shares) in the LMPVault at this point. The fee will be `0.02 ETH` (~40 USD). Thus, the fee earned is very little and almost negligible.\\nAt the end of the function, the `navPerShareHighMark` will be set to `1.4`, and the highest NAV/Share will be locked forever. After some time, the price of the LP tokens fell back to its expected price range, and the `currentNavPerShare` fell to around `1.05`. No fee will be collected from this point onwards unless the NAV/Share is raised above `1.4`.\\nIt might take a long time to reach the `1.4` threshold, or in the worst case, the spike is temporary, and it will never reach `1.4` again. So, when the NAV/Share of the LMPVault is 1.0 to `1.4`, the protocol only collects `0.02 ETH` (~40 USD), which is too little.\\n```\\nfunction _collectFees(uint256 idle, uint256 debt, uint256 totalSupply) internal {\\n    address sink = feeSink;\\n    uint256 fees = 0;\\n    uint256 shares = 0;\\n    uint256 profit = 0;\\n\\n    // If there's no supply then there should be no assets and so nothing\\n    // to actually take fees on\\n    if (totalSupply == 0) {\\n        return;\\n    }\\n\\n    uint256 currentNavPerShare = ((idle + debt) * MAX_FEE_BPS) / totalSupply;\\n    uint256 effectiveNavPerShareHighMark = navPerShareHighMark;\\n\\n    if (currentNavPerShare > effectiveNavPerShareHighMark) {\\n        // Even if we aren't going to take the fee (haven't set a sink)\\n        // We still want to calculate so we can emit for off-chain analysis\\n        profit = (currentNavPerShare - effectiveNavPerShareHighMark) * totalSupply;\\n        fees = profit.mulDiv(performanceFeeBps, (MAX_FEE_BPS ** 2), Math.Rounding.Up);\\n        if (fees > 0 && sink != address(0)) {\\n            // Calculated separate from other mints as normal share mint is round down\\n            shares = _convertToShares(fees, Math.Rounding.Up);\\n            _mint(sink, shares);\\n            emit Deposit(address(this), sink, fees, shares);\\n        }\\n        // Set our new high water mark, the last nav/share height we took fees\\n        navPerShareHighMark = currentNavPerShare;\\n        navPerShareHighMarkTimestamp = block.timestamp;\\n        emit NewNavHighWatermark(currentNavPerShare, block.timestamp);\\n    }\\n    emit FeeCollected(fees, sink, shares, profit, idle, debt);\\n}\\n```\\n
Issue Malicious users could lock in the NAV/Share of the DV to cause the loss of fees\\nConsider implementing a sophisticated off-chain algorithm to determine the right time to lock the `navPerShareHighMark` and/or restrict the access to the `updateDebtReporting` function to only protocol-owned addresses.
Loss of fee. Fee collection is an integral part of the protocol; thus the loss of fee is considered a High issue.
```\\nfunction _collectFees(uint256 idle, uint256 debt, uint256 totalSupply) internal {\\n    address sink = feeSink;\\n    uint256 fees = 0;\\n    uint256 shares = 0;\\n    uint256 profit = 0;\\n\\n    // If there's no supply then there should be no assets and so nothing\\n    // to actually take fees on\\n    if (totalSupply == 0) {\\n        return;\\n    }\\n\\n    uint256 currentNavPerShare = ((idle + debt) * MAX_FEE_BPS) / totalSupply;\\n    uint256 effectiveNavPerShareHighMark = navPerShareHighMark;\\n\\n    if (currentNavPerShare > effectiveNavPerShareHighMark) {\\n        // Even if we aren't going to take the fee (haven't set a sink)\\n        // We still want to calculate so we can emit for off-chain analysis\\n        profit = (currentNavPerShare - effectiveNavPerShareHighMark) * totalSupply;\\n        fees = profit.mulDiv(performanceFeeBps, (MAX_FEE_BPS ** 2), Math.Rounding.Up);\\n        if (fees > 0 && sink != address(0)) {\\n            // Calculated separate from other mints as normal share mint is round down\\n            shares = _convertToShares(fees, Math.Rounding.Up);\\n            _mint(sink, shares);\\n            emit Deposit(address(this), sink, fees, shares);\\n        }\\n        // Set our new high water mark, the last nav/share height we took fees\\n        navPerShareHighMark = currentNavPerShare;\\n        navPerShareHighMarkTimestamp = block.timestamp;\\n        emit NewNavHighWatermark(currentNavPerShare, block.timestamp);\\n    }\\n    emit FeeCollected(fees, sink, shares, profit, idle, debt);\\n}\\n```\\n