PositionsManager implementation contract state could be corrupted and possibly destructed.
Bug Description PositionsManager can be directly called (not through proxy) and its market/position state arbitrarily mutated. Its external functions don't verify a valid poolTokenAddress so a user supplied contract is accepted and trusted. Storage declared in MorphoStorage is zero-initialized including the contract addresses. _updateP2PIndexes() is called which invokes interestRatesManager's updateP2PIndexes, but since interestRatesManager pointer is zero the delegatecall will return True and not do anything. Attacker can manipulate the storage and using the enteredMarkets mapping to array which can be populated arbitrarily by reaching _enterMarketIfNeeded, may be able to perform storage collision attack and replace the interestRatesManager pointer with a controlled address, which will call selfdestruct.
Impact Attacker may be able to shut down the system until a new PositionsManager is deployed and plugged in by triggering delegatecall from PositionsManager to a contract which selfdestructs.
Difficulty to Exploit: Medium
Weakness: Data Validation, uninitialized data
in functionDelegateCall assert that _target is not zero address.
add access control checks in PositionsManager as it contains a dangerous delegatecall.
Morpho said since there is so straightforward way to control the delegatecall() target, they will not fix it. I think this approach is not responsible because as documented on their website, the data structures which manage the P2P borrow/supply is subject to change which will make it easy from uninitialized state to control the delegatecall. They only happen to be safe right now because 0.8 solidity does not permit setting list's length arbitrarily.