Simplify UUPSUpgradeable along the lines of ERC1822 (#3021)

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
Hadrien Croubois
2022-01-13 19:46:55 +01:00
committed by GitHub
parent 3458c1e854
commit e192fac276
12 changed files with 191 additions and 88 deletions

View File

@ -3,6 +3,7 @@
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822.sol";
import "../ERC1967/ERC1967Upgrade.sol";
/**
@ -17,7 +18,7 @@ import "../ERC1967/ERC1967Upgrade.sol";
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is ERC1967Upgrade {
abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
@ -34,6 +35,27 @@ abstract contract UUPSUpgradeable is ERC1967Upgrade {
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
_;
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate that the this implementation remains valid after an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
return _IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
@ -43,7 +65,7 @@ abstract contract UUPSUpgradeable is ERC1967Upgrade {
*/
function upgradeTo(address newImplementation) external virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, new bytes(0), false);
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
}
/**
@ -56,7 +78,7 @@ abstract contract UUPSUpgradeable is ERC1967Upgrade {
*/
function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallSecure(newImplementation, data, true);
_upgradeToAndCallUUPS(newImplementation, data, true);
}
/**