github.com/klaytn/klaytn@v1.12.1/contracts/system_contracts/lib/UUPSUpgradeable.sol (about)

     1  // Copyright 2023 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The klaytn library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  //
    17  // This flattened solidity file is from openzeppelin-upgradeable/proxy/utils/UUPSUpgradeable.sol
    18  // Sources flattened with hardhat v2.13.0 https://hardhat.org
    19  
    20  // File @openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol@v4.9.3
    21  
    22  // SPDX-License-Identifier: MIT
    23  // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
    24  
    25  pragma solidity ^0.8.0;
    26  
    27  // Manually import this to avoid identifier collision.
    28  import "./Initializable.sol";
    29  
    30  /**
    31   * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
    32   * proxy whose upgrades are fully controlled by the current implementation.
    33   */
    34  interface IERC1822ProxiableUpgradeable {
    35      /**
    36       * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
    37       * address.
    38       *
    39       * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
    40       * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
    41       * function revert if invoked through a proxy.
    42       */
    43      function proxiableUUID() external view returns (bytes32);
    44  }
    45  
    46  // File @openzeppelin/contracts-upgradeable/interfaces/IERC1967Upgradeable.sol@v4.9.3
    47  
    48  // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)
    49  
    50  pragma solidity ^0.8.0;
    51  
    52  /**
    53   * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
    54   *
    55   * _Available since v4.8.3._
    56   */
    57  interface IERC1967Upgradeable {
    58      /**
    59       * @dev Emitted when the implementation is upgraded.
    60       */
    61      event Upgraded(address indexed implementation);
    62  
    63      /**
    64       * @dev Emitted when the admin account has changed.
    65       */
    66      event AdminChanged(address previousAdmin, address newAdmin);
    67  
    68      /**
    69       * @dev Emitted when the beacon is changed.
    70       */
    71      event BeaconUpgraded(address indexed beacon);
    72  }
    73  
    74  // File @openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol@v4.9.3
    75  
    76  // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
    77  
    78  pragma solidity ^0.8.0;
    79  
    80  /**
    81   * @dev This is the interface that {BeaconProxy} expects of its beacon.
    82   */
    83  interface IBeaconUpgradeable {
    84      /**
    85       * @dev Must return an address that can be used as a delegate call target.
    86       *
    87       * {BeaconProxy} will check that this address is a contract.
    88       */
    89      function implementation() external view returns (address);
    90  }
    91  
    92  // File @openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol@v4.9.3
    93  
    94  // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
    95  // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
    96  
    97  pragma solidity ^0.8.0;
    98  
    99  /**
   100   * @dev Library for reading and writing primitive types to specific storage slots.
   101   *
   102   * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
   103   * This library helps with reading and writing to such slots without the need for inline assembly.
   104   *
   105   * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
   106   *
   107   * Example usage to set ERC1967 implementation slot:
   108   * ```solidity
   109   * contract ERC1967 {
   110   *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
   111   *
   112   *     function _getImplementation() internal view returns (address) {
   113   *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
   114   *     }
   115   *
   116   *     function _setImplementation(address newImplementation) internal {
   117   *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
   118   *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
   119   *     }
   120   * }
   121   * ```
   122   *
   123   * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
   124   * _Available since v4.9 for `string`, `bytes`._
   125   */
   126  library StorageSlotUpgradeable {
   127      struct AddressSlot {
   128          address value;
   129      }
   130  
   131      struct BooleanSlot {
   132          bool value;
   133      }
   134  
   135      struct Bytes32Slot {
   136          bytes32 value;
   137      }
   138  
   139      struct Uint256Slot {
   140          uint256 value;
   141      }
   142  
   143      struct StringSlot {
   144          string value;
   145      }
   146  
   147      struct BytesSlot {
   148          bytes value;
   149      }
   150  
   151      /**
   152       * @dev Returns an `AddressSlot` with member `value` located at `slot`.
   153       */
   154      function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
   155          /// @solidity memory-safe-assembly
   156          assembly {
   157              r.slot := slot
   158          }
   159      }
   160  
   161      /**
   162       * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
   163       */
   164      function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
   165          /// @solidity memory-safe-assembly
   166          assembly {
   167              r.slot := slot
   168          }
   169      }
   170  
   171      /**
   172       * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
   173       */
   174      function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
   175          /// @solidity memory-safe-assembly
   176          assembly {
   177              r.slot := slot
   178          }
   179      }
   180  
   181      /**
   182       * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
   183       */
   184      function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
   185          /// @solidity memory-safe-assembly
   186          assembly {
   187              r.slot := slot
   188          }
   189      }
   190  
   191      /**
   192       * @dev Returns an `StringSlot` with member `value` located at `slot`.
   193       */
   194      function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
   195          /// @solidity memory-safe-assembly
   196          assembly {
   197              r.slot := slot
   198          }
   199      }
   200  
   201      /**
   202       * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
   203       */
   204      function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
   205          /// @solidity memory-safe-assembly
   206          assembly {
   207              r.slot := store.slot
   208          }
   209      }
   210  
   211      /**
   212       * @dev Returns an `BytesSlot` with member `value` located at `slot`.
   213       */
   214      function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
   215          /// @solidity memory-safe-assembly
   216          assembly {
   217              r.slot := slot
   218          }
   219      }
   220  
   221      /**
   222       * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
   223       */
   224      function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
   225          /// @solidity memory-safe-assembly
   226          assembly {
   227              r.slot := store.slot
   228          }
   229      }
   230  }
   231  
   232  // File @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol@v4.9.3
   233  
   234  // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)
   235  
   236  pragma solidity ^0.8.2;
   237  
   238  /**
   239   * @dev This abstract contract provides getters and event emitting update functions for
   240   * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
   241   *
   242   * _Available since v4.1._
   243   */
   244  abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {
   245      function __ERC1967Upgrade_init() internal onlyInitializing {}
   246  
   247      function __ERC1967Upgrade_init_unchained() internal onlyInitializing {}
   248  
   249      // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
   250      bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
   251  
   252      /**
   253       * @dev Storage slot with the address of the current implementation.
   254       * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
   255       * validated in the constructor.
   256       */
   257      bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
   258  
   259      /**
   260       * @dev Returns the current implementation address.
   261       */
   262      function _getImplementation() internal view returns (address) {
   263          return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
   264      }
   265  
   266      /**
   267       * @dev Stores a new address in the EIP1967 implementation slot.
   268       */
   269      function _setImplementation(address newImplementation) private {
   270          require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
   271          StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
   272      }
   273  
   274      /**
   275       * @dev Perform implementation upgrade
   276       *
   277       * Emits an {Upgraded} event.
   278       */
   279      function _upgradeTo(address newImplementation) internal {
   280          _setImplementation(newImplementation);
   281          emit Upgraded(newImplementation);
   282      }
   283  
   284      /**
   285       * @dev Perform implementation upgrade with additional setup call.
   286       *
   287       * Emits an {Upgraded} event.
   288       */
   289      function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
   290          _upgradeTo(newImplementation);
   291          if (data.length > 0 || forceCall) {
   292              AddressUpgradeable.functionDelegateCall(newImplementation, data);
   293          }
   294      }
   295  
   296      /**
   297       * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
   298       *
   299       * Emits an {Upgraded} event.
   300       */
   301      function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {
   302          // Upgrades from old implementations will perform a rollback test. This test requires the new
   303          // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
   304          // this special case will break upgrade paths from old UUPS implementation to new ones.
   305          if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {
   306              _setImplementation(newImplementation);
   307          } else {
   308              try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {
   309                  require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
   310              } catch {
   311                  revert("ERC1967Upgrade: new implementation is not UUPS");
   312              }
   313              _upgradeToAndCall(newImplementation, data, forceCall);
   314          }
   315      }
   316  
   317      /**
   318       * @dev Storage slot with the admin of the contract.
   319       * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
   320       * validated in the constructor.
   321       */
   322      bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
   323  
   324      /**
   325       * @dev Returns the current admin.
   326       */
   327      function _getAdmin() internal view returns (address) {
   328          return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
   329      }
   330  
   331      /**
   332       * @dev Stores a new address in the EIP1967 admin slot.
   333       */
   334      function _setAdmin(address newAdmin) private {
   335          require(newAdmin != address(0), "ERC1967: new admin is the zero address");
   336          StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
   337      }
   338  
   339      /**
   340       * @dev Changes the admin of the proxy.
   341       *
   342       * Emits an {AdminChanged} event.
   343       */
   344      function _changeAdmin(address newAdmin) internal {
   345          emit AdminChanged(_getAdmin(), newAdmin);
   346          _setAdmin(newAdmin);
   347      }
   348  
   349      /**
   350       * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
   351       * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
   352       */
   353      bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
   354  
   355      /**
   356       * @dev Returns the current beacon.
   357       */
   358      function _getBeacon() internal view returns (address) {
   359          return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
   360      }
   361  
   362      /**
   363       * @dev Stores a new beacon in the EIP1967 beacon slot.
   364       */
   365      function _setBeacon(address newBeacon) private {
   366          require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
   367          require(
   368              AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
   369              "ERC1967: beacon implementation is not a contract"
   370          );
   371          StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
   372      }
   373  
   374      /**
   375       * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
   376       * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
   377       *
   378       * Emits a {BeaconUpgraded} event.
   379       */
   380      function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
   381          _setBeacon(newBeacon);
   382          emit BeaconUpgraded(newBeacon);
   383          if (data.length > 0 || forceCall) {
   384              AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
   385          }
   386      }
   387  
   388      /**
   389       * @dev This empty reserved space is put in place to allow future versions to add new
   390       * variables without shifting down storage in the inheritance chain.
   391       * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
   392       */
   393      uint256[50] private __gap;
   394  }
   395  
   396  // File @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol@v4.9.3
   397  
   398  // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)
   399  
   400  pragma solidity ^0.8.0;
   401  
   402  /**
   403   * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
   404   * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
   405   *
   406   * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
   407   * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
   408   * `UUPSUpgradeable` with a custom implementation of upgrades.
   409   *
   410   * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
   411   *
   412   * _Available since v4.1._
   413   */
   414  abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
   415      function __UUPSUpgradeable_init() internal onlyInitializing {}
   416  
   417      function __UUPSUpgradeable_init_unchained() internal onlyInitializing {}
   418  
   419      /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
   420      address private immutable __self = address(this);
   421  
   422      /**
   423       * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
   424       * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
   425       * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
   426       * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
   427       * fail.
   428       */
   429      modifier onlyProxy() {
   430          require(address(this) != __self, "Function must be called through delegatecall");
   431          require(_getImplementation() == __self, "Function must be called through active proxy");
   432          _;
   433      }
   434  
   435      /**
   436       * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
   437       * callable on the implementing contract but not through proxies.
   438       */
   439      modifier notDelegated() {
   440          require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
   441          _;
   442      }
   443  
   444      /**
   445       * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
   446       * implementation. It is used to validate the implementation's compatibility when performing an upgrade.
   447       *
   448       * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
   449       * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
   450       * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
   451       */
   452      function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
   453          return _IMPLEMENTATION_SLOT;
   454      }
   455  
   456      /**
   457       * @dev Upgrade the implementation of the proxy to `newImplementation`.
   458       *
   459       * Calls {_authorizeUpgrade}.
   460       *
   461       * Emits an {Upgraded} event.
   462       *
   463       * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
   464       */
   465      function upgradeTo(address newImplementation) public virtual onlyProxy {
   466          _authorizeUpgrade(newImplementation);
   467          _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
   468      }
   469  
   470      /**
   471       * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
   472       * encoded in `data`.
   473       *
   474       * Calls {_authorizeUpgrade}.
   475       *
   476       * Emits an {Upgraded} event.
   477       *
   478       * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
   479       */
   480      function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
   481          _authorizeUpgrade(newImplementation);
   482          _upgradeToAndCallUUPS(newImplementation, data, true);
   483      }
   484  
   485      /**
   486       * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
   487       * {upgradeTo} and {upgradeToAndCall}.
   488       *
   489       * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
   490       *
   491       * ```solidity
   492       * function _authorizeUpgrade(address) internal override onlyOwner {}
   493       * ```
   494       */
   495      function _authorizeUpgrade(address newImplementation) internal virtual;
   496  
   497      /**
   498       * @dev This empty reserved space is put in place to allow future versions to add new
   499       * variables without shifting down storage in the inheritance chain.
   500       * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
   501       */
   502      uint256[50] private __gap;
   503  }