Openzeppelin upgrades - new instance in a contract

Hi Team,

I am writing new smart contracts and need to follow upgradability principles.

I got a factory contract that should create 3-4 contracts inside it.

contract Factory {
   
    function create() public {
       Contract1 c1 = new Contract1();
       Contract2 c2 = new Contract2();
       Contract3 c3 = new Contract3();   
   }

}

Now, openzeppelin upgrade docs mention that I shouldn't be creating new instances inside smart contract and what I should be doing instead is passing the addresses to the create function above of already deployed contracts. In my case, that's a big problem, because this is a factory contract and it's the one that should be deploying new instances. It's a bad idea and I can't do to deploy contract1, contract2, contract3 separatelly, because I just showed an easy scenario and my case is a little bit complex. Here is where i read in the docs. https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable

Thanks a lot in advance for any help...

The only way I can think of in this case is to use TransparentUpgradeableProxy and the below code would go in the factory function. WDYT ?

TransparentUpgradeableProxy voting = new TransparentUpgradeableProxy(voting, msg.sender, abi.encodeWithSelector(Voting.initialize.selector, votingSettings));

I'm missing some context here. Do you want your factory to be upgradeable? Do you want contracts 1, 2, and 3 to be upgradeable?

@frangio

Case 1.

Mainly, I want contract1, contract2, contract3 to be upgradable. Using openzeppelin upgrades plugin, I don't see the way how it can be achieved if I got a factory contract that deploys those 1,2,3 contracts. so my way of above seems really easy for me to understand. WDYT ?

Case 2.

What if I want my factory to be upgradable as well alongside those 1,2,3 contracts ? I guess, for factory, I'd use openzeppelin upgrades plugin with deployProxy and in the factory contract's function, I'd still have TransparentUpgradeableProxy voting = new TransparentUpgradeableProxy(voting, msg.sender, abi.encodeWithSelector(Voting.initialize.selector, votingSettings)); the following. What do you think ?

Thanks a lot.

Yes, that sounds exactly right!

Check out this thread, there are some factory code samples: