Updating existing dapp to use `openzeppelin-contracts` instead of `openzeppelin-solidity`

Hi everyone - I’m in the process of updating an existing dapp to use the openzeppelin-contracts library. We’ve been working on the dapp for the last year or so and are currently using importing OZ base contracts as "import "openzeppelin-solidity/contracts/.." etc.

Upon installing the @openzeppelin/contracts package, I go ahead and update how the OZ base contracts are imported.

Example: I change import "openzeppelin-solidity/contracts/math/SafeMath.sol"; to import "@openzeppelin/contracts/math/SafeMath.sol";

After doing so when I try to compile my contracts I get these Declaration Errors that don’t make much sense. Here’s an example of one:

DeclarationError: Identifier already declared.

import "./tokens/PoolToken.sol";

^------------------------------^

@openzeppelin/contracts/math/SafeMath.sol:16:1: The previous declaration is here:

library SafeMath {

^ (Relevant source part starts here and spans across multiple lines).

Anyone happen to have thoughts?

:computer: Environment

Truffle v5.0.41 (core: 5.0.41)
Solidity v0.5.8 (solc-js)
Node v11.0.0
Web3.js v1.2.1
1 Like

Hi @dougiebuckets,

It appears that SafeMath is being imported from both openzeppelin-solidity and @openzeppelin/contracts causing the Identifier already declared.

I assume PoolToken.sol imports from openzeppelin-solidity whilst the contract importing PoolToken imports from @openzeppelin/contracts.

Suggest that you check for imports from openzeppelin-solidity.

@abcoathup Thanks for taking a look.

I’ve gone ahead and replaced all openzeppelin-solidity imports with @openzeppelin/contracts instead of doing them one by one and I’m still getting a strange Declaration Error (see below). It’s saying the previous declaration is in the Context.sol contract which we’re not using / importing anywhere within our dapp?

DeclarationError: Identifier already declared.
import "./PoolContract.sol";
^--------------------------^
@openzeppelin/contracts/GSN/Context.sol:13:1: The previous declaration is here:
contract Context {
^ (Relevant source part starts here and spans across multiple lines).

Perhaps worth noting, the PoolContract.sol is upgradeable. This is how we’re importing OZ base contracts into our PoolContract.sol to account for upgradability:

import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "@openzeppelin/contracts-ethereum-package/contracts/ownership/Ownable.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";

Any other thoughts? Appreciate your help.

@abcoathup The issue we’re encountering is similar to this one, Are ERC20 tokens already GSN capable? I’m now realizing that many of the @openzeppelin/contracts inherit from Context.sol (hence why that’s being compiled and showing up in the Declaration Error). However, we’re not trying to make any of our contracts GSN recipients.

We’re simply upgrading to @openzeppelin/contracts from openzeppelin-solidity for stability - i.e., so our contracts don’t break unexpectedly when upgrading to a newer minor version.

Given we’re not planning on doing anything w/ GSN, should we continue to rely on openzeppelin-solidity instead @openzeppelin/contracts?

1 Like

Hi @dougiebuckets,

The issue is importing from both @openzeppelin/contracts-ethereum-package and @openzeppelin/contracts.

Whilst there are plans to have a single @openzeppelin/contracts library for standard and upgradeable contracts (Planning the demise of OpenZeppelin Contracts' evil twin) and to support upgradeable and non-upgradeable contracts in the same project, in the short term it might be easier to have your upgradeable contract in a separate project.

Hi @dougiebuckets,

How did you get on with this?

I think we’re going to have to continue using openzeppelin-solidity for the time being until there is a single @openzeppelin/contracts library for standard and upgradeable contracts. Appreciate your help, @abcoathup

1 Like