github.com/klaytn/klaytn@v1.12.1/contracts/system_contracts/lib/Initializable.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/Initializable.sol
    18  // Sources flattened with hardhat v2.13.0 https://hardhat.org
    19  
    20  // File @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol@v4.9.3
    21  
    22  // SPDX-License-Identifier: MIT
    23  
    24  pragma solidity ^0.8.1;
    25  
    26  /**
    27   * @dev Collection of functions related to the address type
    28   */
    29  library AddressUpgradeable {
    30      /**
    31       * @dev Returns true if `account` is a contract.
    32       *
    33       * [IMPORTANT]
    34       * ====
    35       * It is unsafe to assume that an address for which this function returns
    36       * false is an externally-owned account (EOA) and not a contract.
    37       *
    38       * Among others, `isContract` will return false for the following
    39       * types of addresses:
    40       *
    41       *  - an externally-owned account
    42       *  - a contract in construction
    43       *  - an address where a contract will be created
    44       *  - an address where a contract lived, but was destroyed
    45       *
    46       * Furthermore, `isContract` will also return true if the target contract within
    47       * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
    48       * which only has an effect at the end of a transaction.
    49       * ====
    50       *
    51       * [IMPORTANT]
    52       * ====
    53       * You shouldn't rely on `isContract` to protect against flash loan attacks!
    54       *
    55       * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
    56       * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
    57       * constructor.
    58       * ====
    59       */
    60      function isContract(address account) internal view returns (bool) {
    61          // This method relies on extcodesize/address.code.length, which returns 0
    62          // for contracts in construction, since the code is only stored at the end
    63          // of the constructor execution.
    64  
    65          return account.code.length > 0;
    66      }
    67  
    68      /**
    69       * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
    70       * `recipient`, forwarding all available gas and reverting on errors.
    71       *
    72       * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
    73       * of certain opcodes, possibly making contracts go over the 2300 gas limit
    74       * imposed by `transfer`, making them unable to receive funds via
    75       * `transfer`. {sendValue} removes this limitation.
    76       *
    77       * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
    78       *
    79       * IMPORTANT: because control is transferred to `recipient`, care must be
    80       * taken to not create reentrancy vulnerabilities. Consider using
    81       * {ReentrancyGuard} or the
    82       * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
    83       */
    84      function sendValue(address payable recipient, uint256 amount) internal {
    85          require(address(this).balance >= amount, "Address: insufficient balance");
    86  
    87          (bool success, ) = recipient.call{ value: amount }("");
    88          require(success, "Address: unable to send value, recipient may have reverted");
    89      }
    90  
    91      /**
    92       * @dev Performs a Solidity function call using a low level `call`. A
    93       * plain `call` is an unsafe replacement for a function call: use this
    94       * function instead.
    95       *
    96       * If `target` reverts with a revert reason, it is bubbled up by this
    97       * function (like regular Solidity function calls).
    98       *
    99       * Returns the raw returned data. To convert to the expected return value,
   100       * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
   101       *
   102       * Requirements:
   103       *
   104       * - `target` must be a contract.
   105       * - calling `target` with `data` must not revert.
   106       *
   107       * _Available since v3.1._
   108       */
   109      function functionCall(address target, bytes memory data) internal returns (bytes memory) {
   110          return functionCallWithValue(target, data, 0, "Address: low-level call failed");
   111      }
   112  
   113      /**
   114       * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
   115       * `errorMessage` as a fallback revert reason when `target` reverts.
   116       *
   117       * _Available since v3.1._
   118       */
   119      function functionCall(
   120          address target,
   121          bytes memory data,
   122          string memory errorMessage
   123      ) internal returns (bytes memory) {
   124          return functionCallWithValue(target, data, 0, errorMessage);
   125      }
   126  
   127      /**
   128       * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
   129       * but also transferring `value` wei to `target`.
   130       *
   131       * Requirements:
   132       *
   133       * - the calling contract must have an ETH balance of at least `value`.
   134       * - the called Solidity function must be `payable`.
   135       *
   136       * _Available since v3.1._
   137       */
   138      function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
   139          return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
   140      }
   141  
   142      /**
   143       * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
   144       * with `errorMessage` as a fallback revert reason when `target` reverts.
   145       *
   146       * _Available since v3.1._
   147       */
   148      function functionCallWithValue(
   149          address target,
   150          bytes memory data,
   151          uint256 value,
   152          string memory errorMessage
   153      ) internal returns (bytes memory) {
   154          require(address(this).balance >= value, "Address: insufficient balance for call");
   155          (bool success, bytes memory returndata) = target.call{ value: value }(data);
   156          return verifyCallResultFromTarget(target, success, returndata, errorMessage);
   157      }
   158  
   159      /**
   160       * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
   161       * but performing a static call.
   162       *
   163       * _Available since v3.3._
   164       */
   165      function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
   166          return functionStaticCall(target, data, "Address: low-level static call failed");
   167      }
   168  
   169      /**
   170       * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
   171       * but performing a static call.
   172       *
   173       * _Available since v3.3._
   174       */
   175      function functionStaticCall(
   176          address target,
   177          bytes memory data,
   178          string memory errorMessage
   179      ) internal view returns (bytes memory) {
   180          (bool success, bytes memory returndata) = target.staticcall(data);
   181          return verifyCallResultFromTarget(target, success, returndata, errorMessage);
   182      }
   183  
   184      /**
   185       * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
   186       * but performing a delegate call.
   187       *
   188       * _Available since v3.4._
   189       */
   190      function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
   191          return functionDelegateCall(target, data, "Address: low-level delegate call failed");
   192      }
   193  
   194      /**
   195       * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
   196       * but performing a delegate call.
   197       *
   198       * _Available since v3.4._
   199       */
   200      function functionDelegateCall(
   201          address target,
   202          bytes memory data,
   203          string memory errorMessage
   204      ) internal returns (bytes memory) {
   205          (bool success, bytes memory returndata) = target.delegatecall(data);
   206          return verifyCallResultFromTarget(target, success, returndata, errorMessage);
   207      }
   208  
   209      /**
   210       * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
   211       * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
   212       *
   213       * _Available since v4.8._
   214       */
   215      function verifyCallResultFromTarget(
   216          address target,
   217          bool success,
   218          bytes memory returndata,
   219          string memory errorMessage
   220      ) internal view returns (bytes memory) {
   221          if (success) {
   222              if (returndata.length == 0) {
   223                  // only check isContract if the call was successful and the return data is empty
   224                  // otherwise we already know that it was a contract
   225                  require(isContract(target), "Address: call to non-contract");
   226              }
   227              return returndata;
   228          } else {
   229              _revert(returndata, errorMessage);
   230          }
   231      }
   232  
   233      /**
   234       * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
   235       * revert reason or using the provided one.
   236       *
   237       * _Available since v4.3._
   238       */
   239      function verifyCallResult(
   240          bool success,
   241          bytes memory returndata,
   242          string memory errorMessage
   243      ) internal pure returns (bytes memory) {
   244          if (success) {
   245              return returndata;
   246          } else {
   247              _revert(returndata, errorMessage);
   248          }
   249      }
   250  
   251      function _revert(bytes memory returndata, string memory errorMessage) private pure {
   252          // Look for revert reason and bubble it up if present
   253          if (returndata.length > 0) {
   254              // The easiest way to bubble the revert reason is using memory via assembly
   255              /// @solidity memory-safe-assembly
   256              assembly {
   257                  let returndata_size := mload(returndata)
   258                  revert(add(32, returndata), returndata_size)
   259              }
   260          } else {
   261              revert(errorMessage);
   262          }
   263      }
   264  }
   265  
   266  // File @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol@v4.9.3
   267  
   268  pragma solidity ^0.8.2;
   269  
   270  /**
   271   * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
   272   * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
   273   * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
   274   * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
   275   *
   276   * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
   277   * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
   278   * case an upgrade adds a module that needs to be initialized.
   279   *
   280   * For example:
   281   *
   282   * [.hljs-theme-light.nopadding]
   283   * ```solidity
   284   * contract MyToken is ERC20Upgradeable {
   285   *     function initialize() initializer public {
   286   *         __ERC20_init("MyToken", "MTK");
   287   *     }
   288   * }
   289   *
   290   * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
   291   *     function initializeV2() reinitializer(2) public {
   292   *         __ERC20Permit_init("MyToken");
   293   *     }
   294   * }
   295   * ```
   296   *
   297   * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
   298   * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
   299   *
   300   * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
   301   * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
   302   *
   303   * [CAUTION]
   304   * ====
   305   * Avoid leaving a contract uninitialized.
   306   *
   307   * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
   308   * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
   309   * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
   310   *
   311   * [.hljs-theme-light.nopadding]
   312   * ```
   313   * /// @custom:oz-upgrades-unsafe-allow constructor
   314   * constructor() {
   315   *     _disableInitializers();
   316   * }
   317   * ```
   318   * ====
   319   */
   320  abstract contract Initializable {
   321      /**
   322       * @dev Indicates that the contract has been initialized.
   323       * @custom:oz-retyped-from bool
   324       */
   325      uint8 private _initialized;
   326  
   327      /**
   328       * @dev Indicates that the contract is in the process of being initialized.
   329       */
   330      bool private _initializing;
   331  
   332      /**
   333       * @dev Triggered when the contract has been initialized or reinitialized.
   334       */
   335      event Initialized(uint8 version);
   336  
   337      /**
   338       * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
   339       * `onlyInitializing` functions can be used to initialize parent contracts.
   340       *
   341       * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
   342       * constructor.
   343       *
   344       * Emits an {Initialized} event.
   345       */
   346      modifier initializer() {
   347          bool isTopLevelCall = !_initializing;
   348          require(
   349              (isTopLevelCall && _initialized < 1) ||
   350                  (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
   351              "Initializable: contract is already initialized"
   352          );
   353          _initialized = 1;
   354          if (isTopLevelCall) {
   355              _initializing = true;
   356          }
   357          _;
   358          if (isTopLevelCall) {
   359              _initializing = false;
   360              emit Initialized(1);
   361          }
   362      }
   363  
   364      /**
   365       * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
   366       * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
   367       * used to initialize parent contracts.
   368       *
   369       * A reinitializer may be used after the original initialization step. This is essential to configure modules that
   370       * are added through upgrades and that require initialization.
   371       *
   372       * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
   373       * cannot be nested. If one is invoked in the context of another, execution will revert.
   374       *
   375       * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
   376       * a contract, executing them in the right order is up to the developer or operator.
   377       *
   378       * WARNING: setting the version to 255 will prevent any future reinitialization.
   379       *
   380       * Emits an {Initialized} event.
   381       */
   382      modifier reinitializer(uint8 version) {
   383          require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
   384          _initialized = version;
   385          _initializing = true;
   386          _;
   387          _initializing = false;
   388          emit Initialized(version);
   389      }
   390  
   391      /**
   392       * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
   393       * {initializer} and {reinitializer} modifiers, directly or indirectly.
   394       */
   395      modifier onlyInitializing() {
   396          require(_initializing, "Initializable: contract is not initializing");
   397          _;
   398      }
   399  
   400      /**
   401       * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
   402       * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
   403       * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
   404       * through proxies.
   405       *
   406       * Emits an {Initialized} event the first time it is successfully executed.
   407       */
   408      function _disableInitializers() internal virtual {
   409          require(!_initializing, "Initializable: contract is initializing");
   410          if (_initialized != type(uint8).max) {
   411              _initialized = type(uint8).max;
   412              emit Initialized(type(uint8).max);
   413          }
   414      }
   415  
   416      /**
   417       * @dev Returns the highest version that has been initialized. See {reinitializer}.
   418       */
   419      function _getInitializedVersion() internal view returns (uint8) {
   420          return _initialized;
   421      }
   422  
   423      /**
   424       * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
   425       */
   426      function _isInitializing() internal view returns (bool) {
   427          return _initializing;
   428      }
   429  }