Upgradable contracts- UUPS- cannot upgrade enum

Hello team openzeppelin,
I hope everyone is doing great.
I had an issue while trying to upgrade my SM using UUPS pattern. It is not really an issue; more like it's just how it works. Wanted to share it here, hoping that there is maybe a way around this...
Here is the code of my upgradable smart contract,
It is a simple contract that keeps track of the type of the contract(ERC721 or ERC1155) and the address of the contract to interact with.
There will be only one address for each type.
The issue is basically, if I want to upgrade my contract, and in the upgraded contract I want to add more types in the enum, that wont be possible and compilation would fail.
If I declare a new enum (with a different name and all the new types) I will also need to declare new function signatures for my functions.
I most importantly wanted to keep same function signature of getContractByType fct but that seems to not be possible once I declare a new enum.

Thank you in advance for any feedbacks or any possible workarounds for this, :pray:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;

// Open Zeppelin libraries for controlling upgradability and access.
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

import "hardhat/console.sol";

contract MyRegistry is Initializable, UUPSUpgradeable, OwnableUpgradeable {
    enum CollectionType {
        ERC721,
        ERC1155
    }

    mapping(CollectionType => address) private contractByType;

    function initialize() public initializer {
        ///@dev as there is no constructor, we need to initialise the OwnableUpgradeable explicitly
        __Ownable_init();
    }

    ///@dev required by the OZ UUPS module
    function _authorizeUpgrade(address) internal override onlyOwner {}

    function addContract(
        CollectionType _collectionType,
        address _contractAddress
    ) public virtual onlyOwner {
        require(
            contractByType[_collectionType] == address(0),
            "Contract is already set for this type"
        );
        contractByType[_collectionType] = _contractAddress;
    }

    function getContractByType(
        CollectionType _type
    ) public view virtual returns (address) {
        return contractByType[_type];
    }

    ///@dev returns the contract version
    function registryVersion() external pure virtual returns (uint256) {
        return 1;
    }
}

After doing more research it seems that It's better to move away from enums if I want to upgrade them..
I think it is possible to upgrade structs based on this article which is great!
My new implementation uses a struct instead of enum

    struct CollectionsTypes {
        uint256 id;
        string name;
        address collectionAddress; 
    }

Did you actually try and get an error?

What error did you see?

It should be possible to just add new options in the enum, as long as you add them at the end.

Hi @frangio,

Thanks a lot for getting back to me!

Yes I did, I have tried to write a V2 upgraded contract for the first version with enum and for the second version with struct.
Here is the code for the V2 contract - enum version:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;

// Open Zeppelin libraries for controlling upgradability and access.
import "./MyRegistry.sol";
import "hardhat/console.sol";

contract MyRegistryV2 is MyRegistry {
    enum CollectionType {
        ERC721,
        ERC1155,
        SBT
    }

    ///@dev returns the contract version
    function registryVersion() external pure override returns (uint256) {
        return 2;
    }
}

When I compile the code with hardhat here is what I get

╰─❯ npx hardhat compile
DeclarationError: Identifier already declared.
  --> contracts/MyRegistry.sol:13:5:
   |
13 |     enum CollectionType {
   |     ^ (Relevant source part starts here and spans across multiple lines).
Note: The previous declaration is here:
 --> contracts/MyRegistryV2.sol:9:5:
  |
9 |     enum CollectionType {
  |     ^ (Relevant source part starts here and spans across multiple lines).

It says that identifier is already declared.
Actually I tried to create an upgraded contract for the version where I have a struct instead of enum,
And even though I added the new field at the end of the struct, I got the same error on compilation, saying that the Identifier is already declared.
Did I miss something?
Really appreciate your feedback! :pray:

Sorry totally missed this message.

I see, but this is a compilation error it's not related to upgrades. You have to edit the enum definition in-place.