# How the new ProxyAdmin will work

**URL:** https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172
**Category:** General
**Tags:** proxies, design
**Created:** [January 9, 2019, 7:16pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172 "2019-01-09T19:16:40Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![spalladino](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/spalladino/32/22_2.png) [@spalladino](https://forum.openzeppelin.com/u/spalladino)
#### Post date: [January 9, 2019, 7:16pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/1 "2019-01-09T19:16:40Z")

</div>

Together with @jcarpanelli we are starting work on a new feature to overcome some of the usability challenges that come up around the usage of transparent proxies, and we wanted to open the discussion on how this new feature would fit within the ZeppelinOS client and libraries.

[https://github.com/zeppelinos/zos/issues/419](https://github.com/zeppelinos/zos/issues/419)

# The story so far

But first, a quick reminder on the **two different modes** we have for running a ZeppelinOS project.

## Current default mode

By default, the ZeppelinOS CLI keeps track of all the implementation contracts that are deployed when running `zos push` in per-network json files. This way, when you create a proxy, the CLI just looks up the address for the implementation on the json file, and creates a proxy that is backed by it. Upgrades are issued directly to the proxy by the sender account.

```bash
zos add MyContract 
// Adds the contract to the project

zos push --network mainnet 
// Deploys MyContract to mainnet
// Updates zos.mainnet.json with its address

zos create MyContract --network mainnet
// Looks up the address of MyContract in zos.mainnet.json
// Creates a new proxy backed by that address
// Saves the address of the new proxy on zos.mainnet.json

```

In this mode, the proxies are created and owned by the sender account, which is [problematic](https://blog.zeppelinos.org/the-transparent-proxy-pattern/) when the same accounts wants to interact with the created instance.

```js
MyContract.deployed().myMethod({ from: accounts[0] })
// Fails since the default account is the owner of the proxy

```

## Published mode

Alternatively, a ZeppelinOS project can be **published** via the `zos publish` command. This deploys [a set of contracts](https://docs.zeppelinos.org/docs/architecture.html) (App, Package, and Directory) that keep the structure of your project on-chain. The Directory keeps track by name of all the implementation contracts deployed on the current version, the Package keeps one Directory per version, and the App keeps track of all the Packages used (you'll have more than one if you `link`ed an EVM package as a dependency).

```auto
App 1--n Package 1--n Directory 1--n Implementation

```

Publishing your project is only mandatory if you want to share it as an EVM package. Otherwise, ZeppelinOS works simply on the default mode.

In this mode, the App contract not only keeps track of the Packages that comprise the project, but also **acts as the owner of all proxies created**. It provides methods to `create` a new proxy and `upgrade` an existing one.

```bash
zos add MyContract 
// Adds the contract to the project

zos push --network mainnet --publish
// Creates App, Package, and Directory contracts
// Deploys MyContract to mainnet
// Registers MyContract in Directory
// Updates zos.mainnet.json with all deployed addresses

zos create MyContract --network mainnet
// Requests the App contract to create a new "MyContract"
// Saves the address of the new proxy on zos.mainnet.json

```

Note that, since the App is the admin of the proxies, the user's default account can safely interact with the created proxies. Whenever the user needs to manage the proxies, they do it via the App.

```bash
zos update MyContract --network mainnet
// Looks up the address of MyContract proxy in zos.mainnet.json
// Sends a request to App to update that address to the latest "MyContract"

```

## Summing up

- By default, the user's account is the admin of all proxies created, and manages them directly.
- When published, the App contract is the admin of the proxies, and the user's account is the owner of the App.

## SimpleProject and AppProject

As a side note, both these modes are accessible via the programmatic interface as well. The default mode can be replicated in javascript using the `SimpleProject` class.

```js
const project = new SimpleProject('MyProject', { from: accounts[0] });
// Setup new project

await project.setImplementation(MyContract);
// Deploy an instance of MyContract implementation contract and track its address

const proxy = await project.createProxy(MyContract);
// Creates a new proxy backed by the deployed MyContract instance
// The proxy is owned by the sender address, account[0]

```

While the published mode is handled by the `AppProject` class:

```js
const project = AppProject.deploy('MyProject', '0.1', { from: accounts[0] });
// Deploys new App, Package, and Provider contracts

await project.setImplementation(MyContract);
// Deploy an instance of MyContract implementation contract
// Registers it in the Provider contract

const proxy = await project.createProxy(MyContract);
// Sends a tx to App.create('MyContract'), to create a new proxy
// The proxy is owned by the App contract

```

# The new ProxyAdmin

The idea of the new feature we are working on is to have a small contract `ProxyAdmin` that takes over the responsibility of owning proxies from the user's account **and** from the App contract. This contract would only have a method to `upgrade` a proxy given its address, and would be owned by the user's account.

This way, the user goes through the ProxyAdmin contract for managing their proxies, instead of interacting directly with them. This allows the user account to interact directly with the proxies, since it is not its admin.

_Question: Do we like the name for the ProxyAdmin?_

## Default and published modes revisited

This new component would now be included on **both** the default and the published mode:

- In default mode, the user account no longer is the admin of the proxies. The user account is now the owner of the ProxyAdmin, who in turn is the admin of the proxies
- In published mode, the App no longer is the admin of the proxies. The user account is now the owner of the ProxyAdmin, who in turn is the admin of the proxies. This allows us to remove the upgrade methods from the App.

This means that there is no way from the CLI to manage the proxies directly, since a ProxyAdmin will always be deployed.

_Question: are we fine with this? Do we want to keep a non-default super-lightweight mode in which the users can still manage the proxies directly, and deal themselves with using different accounts for proxy management and interaction? I'd say no, to avoid cluttering the CLI with too many different modes._

## ProxyAdminProject

For low-level programmatic usage, the SimpleProject would keep behaving exactly the same way as before. The AppProject, on the other hand, would incorporate the new ProxyAdmin for being the admin the proxies, instead of having the App contract in that role.

We would also introduce a new `ProxyAdminProject` that has the same behaviour as the new CLI default mode: it keeps track of all implementation contracts off-chain, but delegates the admin management of the proxies to a ProxyAdmin instance.

This would allow users of the programmatic interface to manage proxies themselves via the SimpleProject, and also to be able to achieve the same behaviour as in the CLI via the new ProxyAdminProject. The rationale for this decision is that users that rely on the programmatic interface have more knowledge of the system, and can easier manage the quirks of using two different accounts for interacting with their proxies.

_Question: Are we fine with keeping 3 different projects, even if one is not used from the CLI? Do we like the new name for the new project?_

## Migrations

The new ProxyAdmin implies a breaking change with respect to the old architecture, both for default and published mode. This means that we'd need to migrate the old projects to the new format, which could be easily detected via the `zosversion` entry on the json files.

The migration would entail the same for both kind of projects: deploying a new ProxyAdmin, and transferring the administration of them from the user account or the App (depending on the project kind) to it.

Instead of adding a new command for the migration, whenever the user attempts to perform a network-related operation (such as create or upgrade), he's notified by the CLI that the structure is incompatible and needs to migrate. If the user accepts, the migration proceeds; if not, the command execution is aborted.

```bash
$ zos create MyContract --network mainnet
> An old version of the ZeppelinOS project is detected on mainnet, and needs to be migrated to the latest one.
> Do you want to proceed? [y/n/h]

// if yes
> Migrating...
> Deploying new ProxyAdmin
> Transferring ownership of 0x123 to proxy admin at 0x456
> Transferring ownership of 0x124 to proxy admin at 0x456
> Migration successful
> Proceeding with original command
> Creating instance of MyContract
> Instance of MyContract created at 0x125

// if no
> Migration cancelled. Aborting.

// if help
> The new version uses a thin ProxyAdmin contract to manage all upgradeable contract instances. This avoids issues with using the same account for managing the upgradeable contracts and interacting with them. All proxies currently managed by your account 0x1234 [or your App 0x12345] will now be managed by the ProxyAdmin, which will be owned only by you.
> Do you want to proceed? [y/n/h]

```

_Question: Are we fine with forcing users to migrate? An alternative would be to maintain support for the old modes, but this means much more complexity to maintain in the project. As for the method for enforcing the migration, are we fine with it?_

# Wrapping up

The restriction to avoid using the same account for managing a proxy and interacting with it has been the source of much confusion so far. The ProxyAdmin acts as a very small forwarding agent to prevent this issue, by taking over the responsibility of being the admin in all scenarios. We'd appreciate your feedback on this new feature!

---

<div class="post-metadata">

### Author: ![jcarpanelli](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/jcarpanelli/32/109_2.png) [@jcarpanelli](https://forum.openzeppelin.com/u/jcarpanelli)
#### Post date: [January 9, 2019, 8:50pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/2 "2019-01-09T20:50:07Z")

</div>

I think this is great 🙂!

> [@spalladino](#):
>
> _Question: Are we fine with keeping 3 different projects, even if one is not used from the CLI? Do we like the new name for the new project?_

I'm fine with having these three different projects for now, but we should somehow track if anybody is using `SimpleProject` and if it's necessary to keep it in the long term. Regarding the new project class name, we could think about a more descriptive name rather than `ProxyAdminProject`, but OTOH it's pretty consistent with the actual naming we have:  
`AppProject` - `App` and `PackageProject` - `Package`, where `App` and `Package` are the JS/TS interfaces for the `App` and the `Package` contracts.

> [@spalladino](#):
>
> Instead of adding a new command for the migration, whenever the user attempts to perform a network-related operation (such as create or upgrade), he’s notified by the CLI that the structure is incompatible and needs to migrate. If the user accepts, the migration proceeds; if not, the command execution is aborted.

I agree this might be the friendliest way to _suggest_ a migration. Also, having a `migrate` command could be somewhat bizarre, as it can easily be confused with truffle's concept of migration.

> [@spalladino](#):
>
> $ zos create MyContract --network mainnet \> An old version of the ZeppelinOS project is detected on mainnet, and needs to be migrated to the latest one. \> Do you want to proceed? [y/n/h]

It will also be a good opportunity to introduce interactive commands 🙂.

> [@spalladino](#):
>
> Question: Are we fine with forcing users to migrate? An alternative would be to maintain support for the old modes, but this means much more complexity to maintain in the project. As for the method for enforcing the migration, are we fine with it?

I would prefer to force them to migrate rather than leaving them the choice, as advanced users will be able to manage their proxies without the `ProxyAdmin` or the `App` contracts using `SimpleProject`.

---

<div class="post-metadata">

### Author: ![maraoz](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/maraoz/32/30_2.png) [@maraoz](https://forum.openzeppelin.com/u/maraoz)
#### Post date: [January 9, 2019, 9:46pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/3 "2019-01-09T21:46:51Z")

</div>

> [@spalladino](#):
>
> _Question: Do we like the name for the ProxyAdmin?_

YES! It's literal and fully explains what the contract does. @elopio thoughts?

> [@spalladino](#):
>
> The user account is now the owner of the ProxyAdmin, who in turn is the admin of the proxies

As I told you in an offline conversation, I'm slightly in favor of having 1 `ProxyAdmin` per proxy. Depends on which implementation is easier, as the DX wouldn't change, if I understand correctly. Not strongly against having the `ProxyAdmin` manage multiple proxies, but in that case maybe the name should be `ProxiesAdmin`? (yuck)

> [@spalladino](#):
>
> This means that there is no way from the CLI to manage the proxies directly, since a ProxyAdmin will always be deployed.
> 
> _Question: are we fine with this? Do we want to keep a non-default super-lightweight mode in which the users can still manage the proxies directly, and deal themselves with using different accounts for proxy management and interaction? I’d say no, to avoid cluttering the CLI with too many different modes._

CLI should always have the easiest user experience. I wouldn't worry about hardcore users in the CLI, they can always use `zos-lib` directly and manage proxies manually.

> [@spalladino](#):
>
> Question: Are we fine with keeping 3 different projects, even if one is not used from the CLI? Do we like the new name for the new project?

I didn't quite get why we need a new project type. What function would this contract provide?

> [@spalladino](#):
>
> The migration would entail the same for both kind of projects: deploying a new ProxyAdmin, and transferring the administration of them from the user account or the App (depending on the project kind) to it.

Can't we make the new scheme backwards-compatible? i.e: that the calls to the `ProxyAdmin` contract have the same names as the calls to `Proxy`, so that when users upgrade to the new CLI, everything still works without the `ProxyAdmin`? I know this is hacky but if it works I'm ok with it (it's only for the few users we have today).  
Otherwise, migration plan looks good. (I wouldn't support the old scheme, it's ok to force migration I think -- maybe just to be sure we can ask a few users if they'd be ok?).

---

<div class="post-metadata">

### Author: ![spalladino](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/spalladino/32/22_2.png) [@spalladino](https://forum.openzeppelin.com/u/spalladino)
#### Post date: [January 10, 2019, 6:23pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/4 "2019-01-10T18:23:06Z")

</div>

> [@maraoz](#):
>
> As I told you in an offline conversation, I’m slightly in favor of having 1 `ProxyAdmin` per proxy. Depends on which implementation is easier, as the DX wouldn’t change, if I understand correctly.

Both are straightforward to implement. I'd say that a singleton admin is easier, as it is more similar to the App we have today. And besides, it implies greater gas savings, which is something we want to keep in mind for our proxies.

> [@maraoz](#):
>
> I didn’t quite get why we need a new project type. What function would this contract provide?

The idea is to have the following projects:

- AppProject: Involves ProxyAdmin, App, Package, Directory, Proxies
- ProxyAdminProject: Involves ProxyAdmin, Proxies
- SimpleProject: Involves just Proxies

> [@maraoz](#):
>
> Can’t we make the new scheme backwards-compatible? i.e: that the calls to the `ProxyAdmin` contract have the same names as the calls to `Proxy` , so that when users upgrade to the new CLI, everything still works without the `ProxyAdmin`?

Not sure it can be done without having some code in the CLI to explicitly manage this case. It wouldn't be much, but it implies keeping support for old behaviours. I'll see if I can find a way around this.

---

<div class="post-metadata">

### Author: ![maraoz](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/maraoz/32/30_2.png) [@maraoz](https://forum.openzeppelin.com/u/maraoz)
#### Post date: [January 10, 2019, 6:39pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/5 "2019-01-10T18:39:20Z")

</div>

> [@spalladino](#):
>
> ProxyAdminProject

why would someone use that? I still don't understand. Aren't programmatic use-cases all covered by `SimpleProject` or `AppProject`?

---

<div class="post-metadata">

### Author: ![spalladino](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/spalladino/32/22_2.png) [@spalladino](https://forum.openzeppelin.com/u/spalladino)
#### Post date: [January 10, 2019, 7:49pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/6 "2019-01-10T19:49:04Z")

</div>

> [@maraoz](#):
>
> why would someone use that? I still don’t understand. Aren’t programmatic use-cases all covered by `SimpleProject` or `AppProject` ?

Not if you want the `Project` instance to set up ProxyAdmin(s) on your behalf. You'd need to set them up manually when using a `SimpleProject`.

---

<div class="post-metadata">

### Author: ![elopio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/elopio/32/4037_2.png) [@elopio](https://forum.openzeppelin.com/u/elopio)
#### Post date: [January 16, 2019, 5:37am UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/7 "2019-01-16T05:37:25Z")

</div>

> [@maraoz](#):
>
> YES! It’s literal and fully explains what the contract does. @elopio thoughts?

Agree.

Back in the day I argued that maybe we shouldn't hide everything from users, because the `create` command was not clear to me. I suggested renaming it to `create-proxy`. I still think this is one of the causes of confusion when trying to call the created contracts. Maybe, with this change and a nice message printed after `create` is executed, things will be clearer for users.

👍 thanks for the exploration and the explanation @spalladino.

---

<div class="post-metadata">

### Author: ![spalladino](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/spalladino/32/22_2.png) [@spalladino](https://forum.openzeppelin.com/u/spalladino)
#### Post date: [January 16, 2019, 3:27pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/8 "2019-01-16T15:27:08Z")

</div>

Thanks folks! Any feedback on naming for ProxyAdminProject? It would be the facade on zos-lib for managing a project that creates proxies managed by an instance of ProxyAdmin. We thought about ManagedProject, but I’m still not sold.

---

<div class="post-metadata">

### Author: ![elopio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/elopio/32/4037_2.png) [@elopio](https://forum.openzeppelin.com/u/elopio)
#### Post date: [January 19, 2019, 2:54am UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/9 "2019-01-19T02:54:05Z")

</div>

I prefer `ProxyAdminProject` over `ManagedProject`. In here `managed` would hide the fact that there’s a proxy, and doesn’t add a lot of signification.

On a separate note, if all of them are projects, it comes to mind the idea of a hierarchy. Like saying that `ProxyAdminProject` is an specialization of the `SimpleProject`. Is this the case?

---

<div class="post-metadata">

### Author: ![jeffanthony](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/jeffanthony/32/17408_2.png) [@jeffanthony](https://forum.openzeppelin.com/u/jeffanthony)
#### Post date: [January 19, 2019, 3:57am UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/10 "2019-01-19T03:57:08Z")

</div>

I also prefer `ProxyManagedProject` but I’m not convinced code changes would deter the confusion in question. I understood the issue with the Proxy deployment the second time I went through the tutorial. It may simply require more attention, perhaps an alert box around it, in the documentation.

---

<div class="post-metadata">

### Author: ![spalladino](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/spalladino/32/22_2.png) [@spalladino](https://forum.openzeppelin.com/u/spalladino)
#### Post date: [January 21, 2019, 3:43pm UTC](https://forum.openzeppelin.com/t/how-the-new-proxyadmin-will-work/172/11 "2019-01-21T15:43:14Z")

</div>

> [@elopio](#):
>
> On a separate note, if all of them are projects, it comes to mind the idea of a hierarchy. Like saying that `ProxyAdminProject` is an specialization of the `SimpleProject` . Is this the case?

Kind-of. Both of them share a base class, but it's not that one extends from the other. We will definitely want to add a section to explain the differences between the three of them.

> [@jeffanthony](#):
>
> I also prefer `ProxyManagedProject` but I’m not convinced code changes would deter the confusion in question. I understood the issue with the Proxy deployment the second time I went through the tutorial. It may simply require more attention, perhaps an alert box around it, in the documentation.

I agree that this does not solve the confusion, and we still need to do more work on the docs to make it clear. That said, it does change the happy-path so you don't hit this issue immediately as you start using zOS, which was a big deterrent for many users.
