Spurious issue from non-upgradeable Initializable.sol

I have a similar issue when I migrated my code to another repository. Any luck in fixing this?

Did not test... but for me it looks like there is somewhere an import from the not-upgradeable version of Address.sol...

It should use:

@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol

Thanks for the reply but I don't have any upgradeable version in any imports and only use upgradeable version in the imports. The contracts and tests work in one repository and I have trouble when I moved them to another repository with other contracts

This is the import section of the contract

// SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

I have found the bug and it is due to another contract in my repo using Initializable from @openzeppelin-contract.

I have a contract ContractA which uses UUPS and imports Initializable.sol in @openzepellin-upgradeable and another contract ContractB which imports Initializable.sol in @openzepellin

When I try to deploy in test I got the following weird error

Error: Contract `ContractName` is not upgrade safe

@openzeppelin/contracts/utils/Address.sol:191: Use of delegatecall is not allowed

I debugged the validation code and found this

Basically it was pulling the Initializable from @openzeppelin/contracts instead of @openzeppelin/contracts-upgradeable even though the contract is importing the correct Initializable

Temp workaround:
work around was to change existing contract to use Initializable from @openzeppelin/contracts

Actual Fix:
Either rename Initializable in @openzeppelin/contracts-upgradeable or to change the validation method to also include the entire path including library like @openzeppelin/contracts-upgradeable/Initializable when resolving the contract name

I didn't understand your post. Please share more of the Solidity code. It doesn't sound like there is a problem in the library, at least not the problem you describe. You should always use @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol if you're writing upgradeable contracts.

@frangio The problem is that there is a conflict when you have two contracts one using Upgradeable contract and another not using the upgradeable contract.
ContractA is using UUPS and @openzeppelin/upgradeable-contract

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

ContractA is Initializable {
//code goes here
}

Note ContractA only imports and uses contracts in @openzeppelin/contracts-upgradeable but during deploy when the validation retrieves all inherited contracts it incorrectly retrieves the Initializable from @openzeppelin/contracts instead of @openzeppelin/contracts-upgradeable because there is another totally unrelated contract in a different folder importing Initializable from @openzeppelin/contracts

I have even provided the screen shot of the validation method during debugging the deployment of ContractA that only imports upgradeable library contracts from @openzeppelin/contracts-upgradeable

Contract B is an old contract that is already using the existing Initializable proxy in @openzeppelin/contracts

ContractB is not supposed to be upgradeable and just using the

pragma solidity 0.8.14;
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";

ContractB is Initializable {
//code goes here
}

Now when ContractA is deployed instead of resolving the Initializable from @openzeppelin/contracts-upgradeable the Initializable from @openzeppelin/contracts is getting resolved incorrectly

I had to modify the older contract which is just a normal proxy to use the Initializable from @openzeppelin/contracts-upgradeable to fix the issue

It would be a really bad experience for developers and would result in lost developer productivity

I would advice you to reopen the bug instead of closing it without fixing the issue.

Please let me know if you are still not understanding the issue and I can explain in more detail

Are you using Hardhat or Truffle?

Hardhat and included that information in the bug :slight_smile:

Can you share a repository where we can reproduce the problem? This should definitely not be happening on Hardhat.

I am positive this is not an issue with https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable which is why I closed the issue you opened.

Sure, Let me try to reproduce the issue in a different repo and send it to you by tomorrow

1 Like