UUPSUpgradeable.sol 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. import "../ERC1967/ERC1967Upgrade.sol";
  4. /**
  5. * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
  6. * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
  7. *
  8. * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
  9. * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
  10. * `UUPSUpgradeable` with a custom implementation of upgrades.
  11. *
  12. * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
  13. *
  14. * _Available since v4.1._
  15. */
  16. abstract contract UUPSUpgradeable is ERC1967Upgrade {
  17. /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
  18. address private immutable __self = address(this);
  19. /**
  20. * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
  21. * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
  22. * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
  23. * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
  24. * fail.
  25. */
  26. modifier onlyProxy() {
  27. require(address(this) != __self, "Function must be called through delegatecall");
  28. require(_getImplementation() == __self, "Function must be called through active proxy");
  29. _;
  30. }
  31. /**
  32. * @dev Upgrade the implementation of the proxy to `newImplementation`.
  33. *
  34. * Calls {_authorizeUpgrade}.
  35. *
  36. * Emits an {Upgraded} event.
  37. */
  38. function upgradeTo(address newImplementation) external virtual onlyProxy {
  39. _authorizeUpgrade(newImplementation);
  40. _upgradeToAndCallSecure(newImplementation, new bytes(0), false);
  41. }
  42. /**
  43. * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
  44. * encoded in `data`.
  45. *
  46. * Calls {_authorizeUpgrade}.
  47. *
  48. * Emits an {Upgraded} event.
  49. */
  50. function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {
  51. _authorizeUpgrade(newImplementation);
  52. _upgradeToAndCallSecure(newImplementation, data, true);
  53. }
  54. /**
  55. * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
  56. * {upgradeTo} and {upgradeToAndCall}.
  57. *
  58. * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
  59. *
  60. * ```solidity
  61. * function _authorizeUpgrade(address) internal override onlyOwner {}
  62. * ```
  63. */
  64. function _authorizeUpgrade(address newImplementation) internal virtual;
  65. }