TransparentUpgradeableProxy

Git Source

Inherits: ERC1967Proxy

*This contract implements a proxy that is upgradeable through an associated {ProxyAdmin} instance. To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand:

  1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches the {ITransparentUpgradeableProxy-upgradeToAndCall} function exposed by the proxy itself.

  2. If the admin calls the proxy, it can call the upgradeToAndCall function but any other call won't be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error indicating the proxy admin cannot fallback to the target implementation. These properties mean that the admin account can only be used for upgrading the proxy, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. For this reason, the proxy deploys an instance of {ProxyAdmin} and allows upgrades only if they come through it. You should think of the ProxyAdmin instance as the administrative interface of the proxy, including the ability to change who can trigger upgrades by transferring ownership. NOTE: The real interface of this proxy is that defined in ITransparentUpgradeableProxy. This contract does not inherit from that interface, and instead upgradeToAndCall is implicitly implemented using a custom dispatch mechanism in _fallback. Consequently, the compiler will not produce an ABI for this contract. This is necessary to fully implement transparency without decoding reverts caused by selector clashes between the proxy and the implementation. NOTE: This proxy does not inherit from {Context} deliberately. The {ProxyAdmin} of this contract won't send a meta-transaction in any way, and any other meta-transaction setup should be made in the implementation contract. IMPORTANT: This contract avoids unnecessary storage reads by setting the admin only during construction as an immutable variable, preventing any changes thereafter. However, the admin slot defined in ERC-1967 can still be overwritten by the implementation logic pointed to by this proxy. In such cases, the contract may end up in an undesirable state where the admin slot is different from the actual admin. WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler will not check that there are no selector conflicts, due to the note above. A selector clash between any new function and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could render the upgradeToAndCall function inaccessible, preventing upgradeability and compromising transparency.*

State Variables

ADMIN

address private immutable ADMIN;

Functions

constructor

Initializes an upgradeable proxy managed by an instance of a {ProxyAdmin} with an initialOwner, backed by the implementation at _logic, and optionally initialized with _data as explained in {ERC1967Proxy-constructor}.

constructor(address _logic, address initialOwner, bytes memory _data) ERC1967Proxy(_logic, _data);

_proxyAdmin

Returns the admin of this proxy.

function _proxyAdmin() internal virtual returns (address);

_fallback

If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior.

function _fallback() internal virtual override;

_dispatchUpgradeToAndCall

*Upgrade the implementation of the proxy. See {ERC1967Utils-upgradeToAndCall}. Requirements:

  • If data is empty, msg.value must be zero.*

function _dispatchUpgradeToAndCall() private;

Errors

ProxyDeniedAdminAccess

The proxy caller is the current admin, and can't fallback to the proxy target.

error ProxyDeniedAdminAccess();