Summary
The TitlesGraph contract is designed to be upgradeable, utilizing the UUPSUpgradeable pattern. However, it's instantiated via a constructor in the TitlesCore contract setup.
Vulnerability Detail
In the TitlesCore contract, TitlesGraph is instantiated directly using a constructor rather than being set up as a proxy. This could lead to unexpected behavior when attempting to upgrade the contract, as the proxy would not have access to the initialized state variables or might interact incorrectly with uninitialized storage.
Impact
Inability to leverage the upgradeability.
Code Snippet
graph = new TitlesGraph(address(this), msg.sender);Tool used
Manual Review
Recommendation
Deploy the TitlesGraph contract without initializing state in the constructor. Deploy a proxy that points to the deployed TitlesGraph implementation. Correct approach using a proxy pattern for upgradeable contracts:
address graphImplementation = address(new TitlesGraph());
graph = TitlesGraph(payable(LibClone.deployERC1967(graphImplementation)));
graph.initialize(address(this), msg.sender);