Is storing OpenZeppelin contracts in local dir. safe when using oz-cli?

I’m using OpenZeppelin upgrades and contracts-ethereum-package contracts and importing them into my contracts from node_modules (example below).

import "@openzeppelin/upgrades/contracts/Initializable.sol";

I’m trying to use the static analyzer Slither, but it requires the contracts imported to be located in the local directory. I could (and prefer) to copy them into the local directory so I know code/versions aren’t changing, use Slither, etc.

Is it safe to copy the OpenZeppelin contracts I’m using from the node_modules folder to the local directory that stores all the projects other smart contracts if I’m using the oz-cli to manage my deployments, upgrades, management, etc.?
Furthermore, I wish to make some minor changes to the OpenZeppelin contracts I’m using.

My question is, if I’m using oz-cli for the SDLC will it respect the changes I make to the OpenZeppelin contracts I’m using (assuming I change the import to reference the locally stored, compiler changed versions). Or, will it continue to reference and deploy the version of the OpenZeppelin contracts I’m using in my project from node_modules (un-changed) and make Proxy versions of those?
I believe I read somewhere the “link” command from oz-cli re-uses already deployed versions/bytecode of the OpenZeppelin contracts to point Proxy contracts too.

Thanks for any clarification!

:computer: Environment

I’m currently using:

  • @openzeppelin/cli@2.8.0
  • @openzeppelin/contracts-ethereum-package@2.5.0
  • @openzeppelin/upgrades@2.8.0
  • Truffle@5.0.2


:1234: Code to reproduce

1 Like

Hi @dyno,

Welcome to the community :wave:

If you are deploying upgradeable contracts using the OpenZeppelin CLI then you have three contracts, the proxy, the logic contract and the proxy admin contract.

The CLI deploys precompiled versions of the proxy and proxy admin contracts.

If you wish to extend OpenZeppelin Contracts (for upgradeable contracts this needs to be OpenZeppelin Contracts Ethereum Package) then you should inherit rather than modifying the contract source code.

The documentation has the following note:

To keep your system secure, you should always use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself.

Coming back to your questions:

I suggest creating an issue on on how you can run Slither when inheriting from OpenZeppelin Contracts. I checked the Slither documentation and issues briefly.

To ensure versions don’t change for OpenZeppelin Contracts Ethereum Package you could save the exact version to use with npm (--save-exact).

This is not recommended. (see the quote from the documentation above). It also only effects your logic contract and not the precompiled proxy and proxy admin.

This is not recommended. OpenZeppelin contracts should be extended through inheritance (see the documentation:

What changes do you want to make?

The OpenZeppelin CLI deploys precompiled versions of the proxy and proxy admin, so you can only use them as is with the CLI.

Whilst you could create local copies of OpenZeppelin Contracts Ethereum Package contracts, this is not recommended.

Feel free to ask all the questions that you need.

Hi @abcoathup, thanks for the warm welcome!

Ok, I understand. The proxy and proxy admin contracts are the only constant contracts used - this makes sense and I have no desire to alter either.

Sorry, I should have been more specific in regards to what minor changes I wanted to make. The “OpenZeppelin Contracts Ethereum Package” version I’m using uses the compiler ^0.5.0. I want to change this to strictly use compiler 0.5.11.
I will not be making any actual logic/storage changes to the contracts, only changing (and restricting) the compiler version (and extending through inheritance).

For this reason, I don’t wish to use the node_modules version, as a fresh install will change the compiler used in the OpenZeppelin contracts back to ^0.5.0, and instead wish to keep a local directory in the project.

I understand the CLI will not deploy the version of the ERC20 contract from node_modules, but the version in my local contracts directory which extends and adds logic to the OpenZeppelin contract. Furthermore, if I do create local copies of the contract, the CLI will still reference only my local contracts directory come compilation and deploy time.

Thanks for the quick and in-depth reply! Please let me know if changing the compiler pragma as I am is considered an acceptable change.

1 Like

Hi @Dyno,

The recommendation is still the same:

To keep your system secure, you should always use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself.

As you are extending contracts, you can specify the exact compiler version in the contract inheriting from OpenZeppelin Contracts Ethereum Package.

You can also specify the compiler version to use in the OpenZeppelin CLI.

Hi @Dyno,

OpenZeppelin Contracts Ethereum Package v3.0 has been released.

Hi @abcoathup,

Ok, thanks for the clarification!

Cool, I’ll check out the v3.0 release. Congratulations on releasing it!

Thanks again, I appreciate your quick responses!

1 Like