Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Proxy singleton #10115

Open
pegahcarter opened this issue Apr 11, 2024 · 2 comments
Open

Proposal: Proxy singleton #10115

pegahcarter opened this issue Apr 11, 2024 · 2 comments

Comments

@pegahcarter
Copy link
Contributor

Introduction

When deploying a new proxy, the owner is set within the constructor. This owner has sole access to upgrade the proxy.

Description

It is impossible for a deployer to atomically initialize proxy storage upon proxy creation if the proxy is designated to be owned by another address (ie. msig). This introduces technical debt for op-stack chains who want to follow upgrades with top notch security.

By design, every proxy is designated to be initialized with an implementation. Therefore, we should be able to create the proxy, set the owner, AND upgrade the proxy within one execution trace.

I propose the team creates a Proxy singleton which creates and initializes the proxy from a single function call. Something like gnosis singleton would probably work.

Reference

constructor(address _admin) {
_changeAdmin(_admin);
}

@tynes
Copy link
Contributor

tynes commented Apr 25, 2024

We have been working on a related idea in #9985

This would need to be fully specified in the specs repo before it could be considered for inclusion in the codebase :)

@pegahcarter
Copy link
Contributor Author

pegahcarter commented Apr 25, 2024

That's great! It would be a real convenience if every set of L1 contracts for a given L2 were deterministic. It would probably help with bridging back to L1 as well.

What I was suggesting is more like this:

function deployProxyAndInitialize(
    address _owner,
    address _implementation,
    bytes memory _data
) returns (Proxy iProxy) {
    iProxy = new Proxy(msg.sender);
    iProxy.upgradeToAndCall({ _implementation: _implementation, _data: _data });
    if (_owner != msg.sender) {
        iProxy.changeAdmin(_owner);
    }
}

And then there is no risk of a rogue deployer or dangling initialize().

Until foundry offers atomic deployments (foundry-rs/foundry#7452) it would be beneficial to use an alternative method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants