<!-- canonical: https://0xsimao.com/findings/titles-publishing-protocol-incompatibility-upgradeability-titles-graph -->

# Incompatibility of Upgradeability Pattern in TitlesGraph Contract

Medium · Sherlock · Referential NFT publishing · 22nd April 2024

Finding M-14 of the TITLES Publishing Protocol competition.

- Protocol: https://audits.sherlock.xyz/contests/326
- Codebase: https://github.com/0xsimao/2024-04-titles/tree/d7f60952df22da00b772db5d3a8272a988546089
- Source: https://github.com/sherlock-audit/2024-04-titles-judging/issues/445

---

## 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

https://github.com/sherlock-audit/2024-04-titles/blob/main/wallflower-contract-v2/src/TitlesCore.sol#L44-L49

```solidity
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:
```solidity
address graphImplementation = address(new TitlesGraph());
graph = TitlesGraph(payable(LibClone.deployERC1967(graphImplementation)));
graph.initialize(address(this), msg.sender);
```
