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.
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.