UUPS Proxies: Tutorial (Solidity + JavaScript)

Hello, first, thanks for this great tutorial, nicely detailed :slightly_smiling_face:
I was thinking about the following :
Once the Factory and the Core are deployed, does the Core is linked to the Factory ?
Can someone else create a Factory and attach to the Core contract ?
If yes, how to prevent that ?
Thanks for your precisions.

@Coineo What do you mean by Factory and Core?

@frangio Hello, thanks for your reply.
I mean the Core contract is where the logic is stored, while the "factory" is where the data are stored.

The term we use for what you call "factory" is "proxy", and for "core" we use "implementation".

There is nothing you can do to prevent someone from attaching a proxy to your implementation contract (short of some legal licensing strategy). But it also shouldn't cause any issues if someone does this.

1 Like

Hi @frangio please I need help verifying my proxy contract on cronoscan https://cronoscan.com/address/0x59cd2E492FF59dE3D99C0E034E85c7E51d420643 .

@nonseodion Have you see the section about proxies in our verification guide?

There are instructions.

Thanks for the help I just saw it, I am having an issue with the ABI encoded arguments for the constructor. Cronoscan says " Error! Invalid constructor arguments provided. Please verify that they are in ABI-encoded format"

One thing that's really confusing is where the ERC1967 admin is used in all of this. Is the idea that it can optionally be used in _authorizeUpgrade? Seems like there's no benefit to binding this storage space to the proxy itself, though.

ERC1967 admin is not used in the UUPS pattern. It could be used but it's not needed in the same way as for Transparent Proxies.

how deploy manually an uups contract ? in my case I use an EVM chain (Hydra) incompatible with Hardhat, and I think I can't call constructor with argurments.

1 Like

Is initialize() is only meant to be called once for the entire proxy's lifecycle? If new variables are introduced in a new upgraded implementation, what is the right pattern for initializing them?

1 Like

Call initialize on the new logic contract.
You can call initialize once by contract, so you can't call it anymore on the proxy contract, but you can call it once on new logic contract deployed

What do you mean? The initialize would be called through the proxy if an upgrade happens.

You can pass data on upgrade to call your logic contract with initialize info

@youtpout You need to deploy the implementation contract and then an instance of ERC1967Proxy

@leeren It's a good question. For testing you will probably want to have an initialize() function where you initialize all available variables. But for upgrading you will need a new method, something like initializeV2 where you only initialize the new things.

1 Like

Thanks, that clears it all up.

Hello I resolve my problem, it's just because I didn't reattach my proxy to my market contract in hardhat, so hardhat didn't recognize the method called.

Great tutorial! In your example, what is the significance of adding the initializer modifier to the constructor function?

@frangio Also another follow up question. If I understand this correctly, functions of the proxy itself (not the implementation contract) can only be called by ProxyAdmin. How can we get the ProxyAdmin object? I have only seen docs on using the Upgrade Plugin (i.e. the upgradeProxy function) to update a proxy's implementation.

Edit: nvm I think Error: No ProxyAdmin was found in the network manifest - #2 by ericglau answered my question. For those who might have the same question: for uups standard, there is no ProxyAdmin, and the deployer of the proxy can directly call those proxy admin functions (e.g. updating implementations)

1 Like