Proxyis ProxyStorage, ProxyGovernance¶
The Proxy contract implements delegation of calls to other contracts (implementations), with proper forwarding of return values and revert reasons. This pattern allows retaining the contract storage while replacing implementation code.
The following operations are supported by the proxy contract:
addImplementation: Defines a new implementation, the data with which it should be initialized and whether this will be the last version of implementation.
upgradeTo: Once an implementation is added, the governor may upgrade to that implementation only after a safety time period has passed (time lock), the current implementation is not the last version and the implementation is not frozen (see
removeImplementation: Any announced implementation may be removed. Removing an implementation is especially important once it has been used for an upgrade in order to avoid an additional unwanted revert to an older version.
The only entity allowed to perform the above operations is the proxy governor (see
Every implementation is required to have an initialize function that replaces the constructor of a normal contract. Furthermore, the only parameter of this function is an array of bytes (data) which may be decoded arbitrarily by the initialize function. It is up to the implementation to ensure that this function cannot be run more than once if so desired.
When an implementation is added (
addImplementation) the initialization data is also announced, allowing users of the contract to analyze the full effect of an upgrade to the new implementation. During an
upgradeTo, the data is provided again and only if it is identical to the announced data is the upgrade performed by pointing the proxy to the new implementation and calling its initialize function with this data.
It is the responsibility of the implementation not to overwrite any storage belonging to the proxy (ProxyStorage). In addition, upon upgrade, the new implementation is assumed to be backward compatible with previous implementations with respect to the storage used until that point.
addImplementation(address newImplementation, bytes calldata data, bool finalize)¶