Is my existing implementation initializable?

Is my implementation contract initializable?

With regards to initializing the implementation contract, within my initialize function, I have these functions and modifiers:

function initialize(   
        address _contractOwner
    ) external initializer {
// supposed to be called once while initializing.
    // one of the contracts that inherits this contract follows proxy pattern
    // so it is not possible to do this in a constructor
    function _initializeEIP712() internal initializer {
  modifier initializer() {
        bool isTopLevelCall = !_initializing;
            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        _initialized = 1;
        if (isTopLevelCall) {
            _initializing = true;
        if (isTopLevelCall) {
            _initializing = false;
            emit Initialized(1);

Since there is _initializeEIP712() which also includes an initialize modifier, I cannot call initialize on an already deployed implementation contract. Would that mean that my implementation contract is protected and a malicious actor will be unable to initialize the implementation contract?

Additional context: I tried initializing the implementation contract (currently initialized==0), but I receive an error message of 'Initializable: contract is already initialized' when I try to initialize the implementation contract (for security purposes). I believe that it is due to having _initializeEIP712(); within the initialize function.

From my understanding this is the reason why the implementation contract above will not be initializable.

  1. The first initialize will have (isTopLevelCall && _initialized < 1) as true since it is a top level call and initialized is 0.

  2. And the second initialize within _initializeEIP712() will return the error "Initializable: contract is already initialized" because it is not true for both cases (since the implementation contract is deployed and isContract(address(this)) will return true.

Note: The proxy can be deployed and initialized using hardhat upgrades.deployProxy() just that the implementation contract cannot be initialized.

Some kind inputs from the experts here will be helpful. Thanks.

@WilsonOfTheJungle Parent contracts should use the onlyInitializing modifier. See for an example.

Those initializers still only run in the context of the proxy. For the implementation contract's context, you should still have a constructor to lock the implementation from initialization. As of Contracts v4.6.0, the recommended way is:

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {

@ericglau thanks for the response.

Understand the best practices and that parent contracts should use onlyInitializing modifier and to use _disableInitializers() within the constructor.

But currently, the implementation contract with the following initialize function is deployed and from a security perspective, I would want to initialize the implementation contract.

So, I would just like to know if the implementation contract is initializable. From my understanding, as _initializeEIP712(); is present within initialize(), can I safely say that the implementation contract is un-intializable so it is 'safe'?

Your assessment sounds correct to me. You can try calling initialize() on the implementation and it should revert as you described.