The UUPSUpgradeable pattern is a commonly used proxy pattern in Solidity that allows for upgradeable smart contracts.
UUPS was introduced by @OpenZeppelin as an alternative to the older Transparent Proxy Pattern. It allows for more control over upgrades and minimizes the complexity of the proxy setup.
Separation of Logic and Data:
The UUPS pattern uses two contracts: a Proxy Contract and an Implementation Contract.
The Proxy Contract holds all the state variables and delegates calls to the Implementation Contract, where the logic resides.
This separation allows the Implementation Contract to be upgraded without affecting the proxy’s storage layout.
Upgradeable Implementation:
Unlike the Transparent Proxy, UUPS keeps the upgrade logic within the Implementation Contract itself. The upgradeTo function in the Implementation Contract facilitates the upgrade:
UUPS was introduced by @OpenZeppelin as an alternative to the older Transparent Proxy Pattern. It allows for more control over upgrades and minimizes the complexity of the proxy setup.
Separation of Logic and Data:
The UUPS pattern uses two contracts: a Proxy Contract and an Implementation Contract.
The Proxy Contract holds all the state variables and delegates calls to the Implementation Contract, where the logic resides.
This separation allows the Implementation Contract to be upgraded without affecting the proxy’s storage layout.
Upgradeable Implementation:
Unlike the Transparent Proxy, UUPS keeps the upgrade logic within the Implementation Contract itself. The upgradeTo function in the Implementation Contract facilitates the upgrade:
the implementation slot is therefore changed:
The UUPS pattern incorporates access control to prevent unauthorized upgrades, typically with an onlyOwner modifier or OpenZeppelin’s AccessControl.
In the standard UUPSUpgradeable contract, this function is unguarded:
This means, to ensure that upgrades are only allowed for privileged addresses, this function must be overridden, including the necessary modifier
Advantages:
The core advantage of the UUPS pattern is that implementations can be made immutable in future versions via simply overriding the _authorizeUpgrade function which then prevents any implementation updates, or by simply removing UUPSUpgradeable inheritance from the future implementation.