Update initializer modifier to prevent reentrancy during initialization (#3006)
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
@ -3,6 +3,8 @@
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "../../utils/Address.sol";
|
||||
|
||||
/**
|
||||
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
|
||||
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
|
||||
@ -45,7 +47,10 @@ abstract contract Initializable {
|
||||
* @dev Modifier to protect an initializer function from being invoked twice.
|
||||
*/
|
||||
modifier initializer() {
|
||||
require(_initializing || !_initialized, "Initializable: contract is already initialized");
|
||||
// If the contract is initializing we ignore whether _initialized is set in order to support multiple
|
||||
// inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
|
||||
// contract may have been reentered.
|
||||
require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized");
|
||||
|
||||
bool isTopLevelCall = !_initializing;
|
||||
if (isTopLevelCall) {
|
||||
@ -59,4 +64,17 @@ abstract contract Initializable {
|
||||
_initializing = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
|
||||
* {initializer} modifier, directly or indirectly.
|
||||
*/
|
||||
modifier onlyInitializing() {
|
||||
require(_initializing, "Initializable: contract is not initializing");
|
||||
_;
|
||||
}
|
||||
|
||||
function _isConstructor() private view returns (bool) {
|
||||
return !Address.isContract(address(this));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user