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 }