Skip to content

OpenZeppelin Contracts 3.4

It’s time for a new release of OpenZeppelin Contracts, and this one is packed with new features!

ERC777 Security Fix

Based on a report by @ritzdorf and @antonper we’ve fixed a potential reentrancy issue in custom extensions to our ERC777 contract.

While the plain ERC777 contract we provide is safe against reentrancy, users who extended this contract with a custom _beforeTokenTransfer function may be vulnerable to a reentrancy attack if this function writes to a storage variable. These users should update to version 3.4 and will no longer have this issue. Read more in the pull request.

If you’re affected and would like assistance, reach out to

Virtual View Functions

After careful analysis we’ve settled in favor of allowing users to override the view functions we define. This kind of flexibility allows extending our contracts in ways that we don’t anticipate, and has been requested by users for quite some time, but should be used with caution.

In many cases overriding a function will not imply that other functions in the contract will automatically adapt to the overridden definitions. For example, overriding ERC20.balanceOf does not guarantee that that balance is available for transferring. However, it will generally be possible to obtain the desired behavior by overriding other functions in the contract, in this case ERC20._transfer . Understand that this limitation was necessary to keep the contracts simple and consistent, but it means that the responsibility to ensure correctness when functions are overriden will be on the users and not on the OpenZeppelin maintainers. People who wish to override should consult the source code to fully understand the impact it will have, and should consider whether they need to override additional functions to achieve the desired behavior. As always, feel free to ask for help in the OpenZeppelin Forum and we’ll be happy to help.

ERC20 Permit

One of the issues with the ERC20 token standard is the usability problem posed by the approve and transferFrom mechanism.

These two functions allow trusted contracts such as decentralized exchanges to manage a user’s tokens on their behalf. The problem is that the user needs ETH in order to call approve, which adds a complex onboarding process for people who are new to Ethereum. There have been several proposals to solve this usability problem, and one that has seen adoption by protocols such as Maker and Uniswap is EIP-2612: ERC20 permit. This EIP proposes a permit function that acts like the approve function but which can be called by anyone that presents a specific message signed by the token owner. This signature can be produced for free off-chain.

This release includes ERC20Permit, an implementation of the EIP. We’ve paid special attention to making sure the implementation is gas efficient and safe in the event of a chain fork.

Note that the EIP is still in Draft state, thus it is found in the drafts directory. The practical consequence is that future updates to the EIP could result in breaking changes.

Beacon Proxy

We’ve added a new proxy pattern called “beacon proxies”, which is well suited for use cases where a large number of proxies share the same implementation, since they can all be upgraded simultaneously.

In this pattern, popularized by Dharma, the proxy contract doesn’t hold the implementation address in storage like the standard UpgradeableProxy, but the address of an UpgradeableBeacon contract, which is where the implementation address is actually stored and retrieved from. The upgrade operations that change the implementation contract address are then sent to the beacon instead of to the proxy contract, and all proxies that follow that beacon are automatically upgraded.

Minimal Proxy (Clones)

Lastly, this release also includes an implementation of the minimal proxy pattern of EIP-1167, also known as clone contracts. This new Clones library allows the creation of cheap contract clones that use a minimal non-upgradeable proxy. It also includes the ability to create these contracts at deterministic addresses by using create2.


If you just want to get started, you can install this release from npm with npm install @openzeppelin/contracts.

We have a few separate variants for other specific use cases.

  • If you want to use Solidity 0.7, you may prefer to install @openzeppelin/contracts@solc-0.7
  • If you’re building upgradeable contracts, you should install @openzeppelin/contracts-upgradeable
  • For the combination of upgradeable contracts and Solidity 0.7, use @openzeppelin/contracts-upgradeable@solc-0.7

To learn more about the upgradeable variant of OpenZeppelin Contracts read our recent announcement: