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

ERC DelegateProxy #897

Merged
merged 6 commits into from
Apr 22, 2018
Merged

ERC DelegateProxy #897

merged 6 commits into from
Apr 22, 2018

Conversation

izqui
Copy link
Contributor

@izqui izqui commented Feb 22, 2018

Preamble

EIP: <to be assigned>
Title: ERC Proxy
Author: Manuel Araoz (Zeppelin), Jorge Izquierdo (Aragon)
Type: Standard Track
Category: ERC
Status: Draft
Created: 2018-02-21

Simple Summary

Proxy contracts are being increasingly used as both as an upgradeability mechanism
and a way to save gas when deploying many instances of a particular contract. This
standard proposes a set of interfaces for proxies to signal how they work and what
their main implementation is.

Abstract

Using proxies that delegate their own logic to another contract is becoming an
increasingly popular technique for both smart contract upgradeability and creating
cheap clone contracts.

We don't believe there is value in standardizing any particular implementation
of a DelegateProxy, given its simplicity, but we believe there is a lot of value
in agreeing on an interface all proxies use that allows for a standard way to
operate with proxies.

An example implementation of a DelegateProxy can be found in aragonOS or zeppelinOS.

Standardized interface

interface ERCProxy {
  function proxyType() public pure returns (uint256 proxyTypeId);
  function implementation() public view returns (address codeAddr);
}

Code address (implementation())

The returned code address is the address the proxy would delegate calls to at that
moment in time, for that message.

Proxy Type (proxyType())

Checking the proxy type is the way to check whether a contract is a proxy at all.
When a contract fails to return to this method or it returns 0, it can be assumed
that the contract is not a proxy.

It also allows for communicating a bit more of information about how the proxy
operates. It is a pure function, therefore making it effectively constant as
it cannot return a different value depending on state changes.

  • Forwarding proxy (id = 1): The proxy will always forward to the same code
    address. The following invariant should always be true: once the proxy returns
    a non-zero code address, that code address should never change.

  • Upgradeable proxy (id = 2): The proxy code address can be changed depending
    on some arbitrary logic implemented either at the proxy level or in its forwarded
    logic.

Benefits

  • Source code verification: right now when checking the code of a proxy in explorers
    like Etherscan, it just shows the code in the proxy itself but not the actual
    code of the contract. By standardizing this construct, they will be able to show
    both the actual ABI and code for the contract.

Copyright

Copyright and related rights waived via CC0.

@sohkai
Copy link

sohkai commented Feb 22, 2018

Wondering if implementation() should also include a bytes calldata parameter in the event the proxy changes which implementation to use based on the input.

Maybe this isn't a good use case for this ERC though, most proxies are 1-1 (rather than 1-many).

@izqui
Copy link
Contributor Author

izqui commented Feb 23, 2018

That's a good point @sohkai, things like ether-router would need this to work.

I think we could make implementation() required and then implementationFor(bytes calldata) an optional function for proxies in which that is relevant.

@maurelian
Copy link
Contributor

maurelian commented Feb 23, 2018

This previous ERC is worth looking at for historical context: #121 Proxy Standard. Although, I think there is some need to disambiguate the term Proxy.

This ERC seems to be specifically about "proxies that delegate their own logic to another contract".

Whereas the uPort proxy is moreso a "proxy that forwards transactions and calls from any ethereum account".

Would it make sense to call this a "Contract Proxy" or "Computational Proxy"?

@yondonfu
Copy link

I agree with @maurelian - another example of a contract that is a "proxy", but would not fit the description of this interface is the 0x TokenTransferProxy.

Perhaps the standard interface could be named ERCDelegateProxy to convey to users that a contract implementing this interface is acting specifically as a proxy that delegates business logic to another contract while still using its own storage. Contract implementations of ERCDelegateProxy could be named ForwardingDelegateProxy (for proxies that always delegate to the same contract) and UpgradeableDelegateProxy (for proxies that can swap out the implementation contract that they delegate to).

@nicksavers nicksavers added the ERC label Feb 25, 2018
@izqui
Copy link
Contributor Author

izqui commented Feb 26, 2018

I agree on the name change to DelegateProxy, that is how we call them internally for our own implementation. Regarding other proxy types like uPort's, I think it would be beneficial for those to have a more descriptive name such as AccountProxy.

@izqui izqui changed the title ERC Proxy ERC DelegateProxy Feb 26, 2018
@jbaylina
Copy link
Contributor

I would consider defining an EIP820 Interface.
Using the EIP820 has the advantage that the proxy does not have to implement the ERCProxy code in the same proxy contract. This will save a lot of gas in proxies that share the same code and type, because the implementation of the interface can be done by a singleton contract shared by all the proxies of the same type.

@veox
Copy link
Contributor

veox commented Mar 2, 2018

@maurelian:

I think there is some need to disambiguate the term Proxy.

@zigguratt has called the particular kind discussed here a dispatcher.

@zigguratt
Copy link

I agree with @maurelian here (and thanks, @veox). There are a couple of different things that could be called proxies. That's exactly why I referred to my implementation as a dispatcher. At the same time, it has the ability to upgrade the contract that it represents.

The idea of swapping out a contract behind a dispatcher/proxy/delegate is a dangerous one. We discussed this at ConsenSys just a couple of day ago. My take on the subject was this (not including uPort's idea of a proxy):

So in the end a proxy or dispatcher should be almost a shield around the contract that it represents, somehow ensuring that if there are any changes made to its sub-contract the changes are clear and very public. But that doesn't stop anyone from using a very simple proxy that does none of that, and at some point swaps out its sub-contract with something nefarious.

This has been on my mind since I implemented my dispatcher. There's actually no way to stop someone from acting badly with a proxy. There would have to be some sort of EVM support, I suspect.

I would love to be proven wrong, believe me.

@Arachnid
Copy link
Contributor

This is a courtesy notice to let you know that the format for EIPs has been modified slightly. If you want your draft merged, you will need to make some small changes to how your EIP is formatted:

  • Frontmatter is now contained between lines with only a triple dash ('---')
  • Headers in the frontmatter are now lowercase.

If your PR is editing an existing EIP rather than creating a new one, this has already been done for you, and you need only rebase your PR.

In addition, a continuous build has been setup, which will check your PR against the rules for EIP formatting automatically once you update your PR. This build ensures all required headers are present, as well as performing a number of other checks.

Please rebase your PR against the latest master, and edit your PR to use the above format for frontmatter. For convenience, here's a sample header you can copy and adapt:

---
eip: <num>
title: <title>
author: <author>
type: [Standards Track|Informational|Meta]
category: [Core|Networking|Interface|ERC] (for type: Standards Track only)
status: Draft
created: <date>
---

@izqui
Copy link
Contributor Author

izqui commented Apr 15, 2018

Your comment got somewhat lost and I just saw it. Thanks for the heads-up @Arachnid, it should be good now.

@izqui
Copy link
Contributor Author

izqui commented Apr 22, 2018

Is anything more required from us before it can be merged @Arachnid?

@Arachnid Arachnid merged commit cf2d761 into ethereum:master Apr 22, 2018
Arachnid pushed a commit to Arachnid/EIPs that referenced this pull request May 2, 2018
* Add ERCProxy draft

* Add missing links

* Re-format EIP897

* ERC897: add reference to implementations
@xinbenlv
Copy link
Contributor

Hi Jorge(@izqui ), the new rule is pull request can't be the "discussions-to" destination, could you mind update EIP-897 to find an official home for its discussion, given it's still in draft status?

@Ishmaello
Copy link

Hi. I'm searching ABI for the implementation contract at 0x4ef5123a30e4CFeC02B3E2F5Ce97F1328B29f7de

Copy link

@lmitchell19125 lmitchell19125 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lance from Philadelphia here

@singularityasitoken
Copy link

Goodnight,

I would like to assemble a team for projects to create cryptocurrencies, tokens and Blockchain and digital banking. Partners and Partners for the Project.

Shall we talk?

@singularityasitoken
Copy link

CONTACT US AT SINGULARITY ASI INSTAGRAM

@lmitchell19125
Copy link

lmitchell19125 commented Jul 16, 2023 via email

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

Successfully merging this pull request may close these issues.