Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Initializable to have onlyInitialized modifier and isInitialized function #1541

Open
3sGgpQ8H opened this issue May 21, 2020 · 5 comments
Open
Labels
kind:feature Brand new feature to implement topic:upgrades.js Related to OpenZeppelin Upgrades

Comments

@3sGgpQ8H
Copy link

Currently, storage variable initialized is declared as private in Initializable smart contract.
It is common situation, that some functions of an initializable smart contract (probably all the function except for initialize) may only be called when smart contract is properly initialized. However, currently there is no easy way to enforce this. I suggest to add two things to Initializable smart contract: onlyInitialized modifier that will revert unless smart contract is initialized, and internal function isInitialized that will return true in case smart contract is initialized, and false otherwise.

These simple improvements will make Initializable smart contract much more useful and should not break backward compatibility.

@abcoathup
Copy link
Contributor

Hi @3sGgpQ8H ! Thanks for the suggestion, it is really appreciated.

The project owner should review your suggestion during the next week.

Please wait until we have discussed this idea before writing any code or submitting a Pull Request, so we can go through the design beforehand. We don’t want you to waste your time!

@abcoathup abcoathup added the kind:enhancement Enhancement to an existing feature label May 22, 2020
@frangio frangio added kind:feature Brand new feature to implement topic:upgrades.js Related to OpenZeppelin Upgrades and removed kind:enhancement Enhancement to an existing feature labels May 26, 2020
@frangio
Copy link
Contributor

frangio commented May 26, 2020

Thank you for the suggestion @3sGgpQ8H.

I'm not sure there exists a scenario where one would want to allow a function call before initialization. The way we currently enforce that no functions are called before initialization is that the initializer is called in the same transaction that creates the proxy. This is what we would recommend to anyone using proxies even if they don't use our tools specifically. In that scenario, manually adding the onlyInitialized modifier doesn't add any value at all, in fact it will add friction by making it more difficult to use functionality during initialization.

Can you share your specific use case so we can evaluate in context whether this is something that more people may find useful? So far I don't see us wanting to add the feature.

@3sGgpQ8H
Copy link
Author

3sGgpQ8H commented May 27, 2020

If this is enforced by Proxy, then why do we need Initialiizable at all? Basically, what Initializable does, it guarantees that initializer will not be called more than once. Also, as you said, Proxy guarantees that initializer will be called at least once at the deployment. As a result, initializer is guaranteed to be called exactly once before any other function. This is exactly what we want to guarantee. However, from architectural point of view, it would be better, if Proxy would guarantee this on its own, without any assistance from the contract is wraps.

@frangio
Copy link
Contributor

frangio commented May 28, 2020

Interesting questions! For initializer functions I don't see how it would be possible for Proxy to guarantee they're called exactly once. The reason is that an initializer function can have any function selector so the proxy has no way of telling it apart from a normal function call.

There is an alternative to initializer functions that can guarantee exactly-once initialization: initializer contracts, as I proposed them in my article Towards Frictionless Upgradeability. However, this idea was never implemented in practice (that I know of) because it's more complicated.

The gist of the idea is that the constructor of Proxy can have an extra parameter which is an initializer contract, and it will perform a delegatecall into that contract. This guarantees exactly-once initialization.

I encourage you to experiment with the approach if you're interested.

@3sGgpQ8H
Copy link
Author

3sGgpQ8H commented May 29, 2020

But Proxy anyway has to know initializer selector to be able to call it on deployment.
Though, currently it is not guaranteed, that a function being called by a Proxy on deployment is actually the function marked with initializer modifier.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
kind:feature Brand new feature to implement topic:upgrades.js Related to OpenZeppelin Upgrades
Projects
None yet
Development

No branches or pull requests

3 participants