Handling imports with Truffe-Upgrades: Initializer Identifier not found or not unique

I did encounter the following error message:

    DeclarationError: Identifier not found or not unique.
  --> /C/Users/sound/Desktop/OZUpgradeable/contracts/MemeSale.sol:50:18:
50 |         ) public initializer {
   |                  ^^^^^^^^^^^

:computer: Environment

Solidity 0.8.0


I have a custom contract that I redesigned to being upgrade safe. I also did this to 3 other contracts from the project which I then import into the first one. One of the imported contracts also inherits from an ERC1155Upgradeable. NOTE that, I do not inherit from the 3 imported contracts but declare instances of them in the logic.

I hope this makes sense. I provided the relating code below. I got rid of the error message by directly inheriting from Initializable, but I wonder if this is the right way to go and have a bunch of questions, as I need to really understand why the error came up and how to handle such a project:

  • Did the error occur because the imported contracts do also have initializer modifiers?
  • How will this setup behave?
  • Do I have to worry about having clashes between all the initialize functions of all these upgrade-safe contracts?
  • Also, will it be wise to consider re-designing EIP712 and EIP712Domain upgrade-safe too???

Lots of questions I know :sweat_smile: I am open to book 1 on 1 coaching with anyone of you feels inspired to coach me in-depth about upgradeable setups like this!

Any help much appreciated! :pray:

:1234: Code to reproduce


// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {EIP712Domain} from "./EIP712Domain.sol";

import {EIP712} from "./EIP712.sol";

import "../node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

import "./ContractA.sol";

import "./ContractB.sol";

import "./ContractC.sol";

 //Here I did inherit from Initalizable, is this best practice?
contract ContractD is EIP712Domain, Initializable{  

    //Excluded constant state vars declaration for sake of readability.... 

    //Here come the instances of the imported Contracts
    ContractA public contractA;

    ContractB public contractB;

    ContractB public contractB;

    //Excluded Events for sake of readability

    //Here comes the INITIALIZER
    function initialize(

        address contractA,

        address payable contractB,

        address contractC,

        string memory version

        ) public initializer {

         contractA = ContractA(contractAAddress);

        contractB = ContractB(contractBAddress);

        contractC = ContractC(contractCAddress);

        DOMAIN_SEPARATOR = EIP712.makeDomainSeparator(





   //removed functions for sake of readability and to avoid TLDR
   Some functions of this contract of course then use the instances of contractA, contractB and 
   contractC. I need to deepen my understanding of the behaviour of this setup and find out 
   why I got the error message included at the top of this post
1 Like

Why do you import like this from the node module rather than the package name?
Did you try with

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

I would also try to bring the Initializable declaration in front of the others as this is the only difference I can see compared to what I tested with.

1 Like

Because that is how the folder structure looks like when you install truffle-upgrades via node package manager…

1 Like

I only refer to “@openzeppelin…” If it can’t find this package you would get that kind of error.

the node process know where the node modules are so i was wondering why you wrote it like that. Depending on which folder you work from might affect the relative path and raise that error to.

I would try to remove the other contract that is Initializer as well.

Contract A is Initializer

contract B is Contract A should work. this is the way the docs present it so maybe your error is from there as well.


I will try. Thanks for the advice

1 Like