Using OpenZeppelin Contracts and Upgrade Safe versions in the same project

UPDATE:

I fixed it by forking the upgradeable smart contracts repository (OpenZeppelin/openzeppelin-contracts-ethereum-package) and adding a UpgradeSafe suffix to all smart contracts, libraries and interfaces.

See the repository here: stoll/openzeppelin-contracts-ethereum-package.


Hello, @abcoathup

I’m continuing this thread (Are upgradable and non upgradable contracts in the same truffle project supported?), as I have a similar use case, but with a different perspective:

I’m creating an upgradeable dApp wherein people need to deploy ERC-20 tokens through a function.

I have 3 smart contracts:
Dapp.sol - My dApp smart contract.
GovernanceToken.sol - Used for governing the dApp. Upgradeable ERC-777 token.
DappERC20Token.sol - ERC-20 smart contract, which users deploy instances of through our dApp. Non-upgradeable ERC-20 token.

So I actually need to have a function where I call:

DappERC20 newDappToken = new DappERC20(name, symbol); 

Compiling causes a clash, since SafeMath.sol is used in both ERC20 and ERC777Upgradeable. Here’s my error:

Compilation errors: 
contracts/Dapp.sol:7:1: DeclarationError: Identifier already declared.
import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol";
^------------------------------------------------------------------------------------^
@openzeppelin/contracts/math/SafeMath.sol:18:1: The previous declaration is here:
library SafeMath {
^ (Relevant source part starts here and spans across multiple lines).

contracts/Dapp.sol:8:1: DeclarationError: Identifier already declared.
import "./DappERC20Token.sol";
^-------------------------^
@openzeppelin/contracts-ethereum-package/contracts/utils/Address.sol:6:1: The previous declaration is here:
library Address {
^ (Relevant source part starts here and spans across multiple lines).

contracts/Dapp.sol:8:1: DeclarationError: Identifier already declared.
import "./DappERC20Token.sol";
^-------------------------^
@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol:6:1: The previous declaration is here:
interface IERC20 {
^ (Relevant source part starts here and spans across multiple lines).

contracts/Dapp.sol:9:1: DeclarationError: Identifier already declared.
import "./GovernanceToken.sol";
^-----------------------------^
@openzeppelin/contracts/math/SafeMath.sol:18:1: The previous declaration is here:
library SafeMath {
^ (Relevant source part starts here and spans across multiple lines).
1 Like

Hi @stoll,

I am sorry that you have this issue and that you are having to fork the upgrade safe version of OpenZeppelin Contracts.

I have created an issue for this: https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/issues/102

There are plans to improve the upgrade safe fork of OpenZeppelin Contracts, see: The Future of contracts-ethereum-package

1 Like

Great, thanks, @abcoathup . Will keep using my repo until a fix is published, and keep my eyes open :slight_smile:

1 Like

Hi @stoll, sorry about this issue. We plan on suffixing all contracts in the upcoming OpenZeppelin Contracts Upgrade Safe package.

In the meantime, I think you should be able to work around it by using Solidity’s “selective” import statement:

import { DappERC20 } from "./DappERC20Token.sol";

This will avoid bringing into scope the clashing symbols.

1 Like