# OpenZeppelin Contracts 4.0 Beta

**URL:** <https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878>\
**Category:** Announcements\
**Created:** [February 22, 2021, 10:16pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878 "2021-02-22T22:16:10Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [February 22, 2021, 10:16pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/1 "2021-02-22T22:16:10Z")

</div>

![](https://us1.discourse-cdn.com/flex022/uploads/zeppelin/original/2X/2/21aa93949967ecd6b3ff0048b2f1d8cee0e69cd8.png)

Due to the new built-in overflow checks in Solidity 0.8, which mark the end of the `SafeMath` era, this upcoming release of OpenZeppelin Contracts is a new major version of the library.

We used this opportunity to include a few small breaking changes that we had in the backlog. We’re putting out a beta release to ask for feedback on these changes, and to ask if there are any other breaking changes that people think should be included.

If you want to support the project check out the notes below, try out the code, and let us know your thoughts!

* * *

These are the breaking changes that will be included in Contracts 4.0.

## Reorganized Repository

The most visible change you will find is that some of the contracts were moved to different directories in the repository and npm package.

The reasoning behind this change was that the previous organization was not very good for discoverability of all of the features we offer, and in many cases could be confusing for new users learning about the project and how to use it.

Not all files were moved, but those that were will require users to change their import paths after upgrading to 4.0. In order to mitigate the impact of this breaking change, we’re also including a script that can be run with `npx openzeppelin-contracts-migrate-imports` after upgrading, that will automatically adjust import paths in Solidity files.

_Check out the [`contracts`](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/release-v4.0/contracts) directory on GitHub and navigate around._

## Storage Optimizations

Given the current high gas prices and upcoming opcode repricing in the [Berlin hard fork](https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/berlin.md), we turned our attention to a few places where storage usage could be optimized or entirely removed. These changes result in cheaper deployment and lower runtime costs.

If there are any other optimizations we’ve missed, make sure to let us know so we can include them in the release.

### ERC20 Decimals

The decimals number used to be kept in storage and was configurable through an internal `_setDecimals` function. Both the storage variable and internal function are now removed, and customization of a token’s decimals is now done by overriding the `decimals` function.

This is a pattern we intend to use more in order to avoid the usage of storage variables for customizing contract behavior.

_Check out [`ERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/release-v4.0/contracts/token/ERC20) on GitHub._

### ERC165

Similarly, supported ERC165 interfaces were kept in storage in order to offer an internal `_registerInterface` function that made things simple to set up. We’ve now changed this so that storage is no longer used, and instead the functionality is implemented through Solidity overrides. Users are encouraged to do the same for any additional supported interfaces, but the old storage-based implementation is still available as `ERC165Storage`.

_Check out [`ERC165`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/utils/introspection/ERC165.sol) and [`ERC165Storage`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/utils/introspection/ERC165Storage.sol) on GitHub._

### ERC721 Enumerability and URIs

Our implementation of the ERC721 token (an NFT) was made enumerable by default in version 3.0.0, with no way to opt out of it. This was controversial because it adds to deployment and runtime costs. We’ve now removed enumerability from the base contract and made it an optional extension.

The metadata extension is still included in our base ERC721 contract, just as ERC20 metadata in our base ERC20 token. These extensions are technically optional but universally included in all tokens. We include them by default so that users don’t have to deal with more inheritance to get the basic requirements set up.

One part of the ERC721 metadata extension that was not well optimized was the fact that token URIs (of which there is one per token id of an NFT) were kept in storage individually. We’ve changed this so that the default behavior does not rely on storage. There is now an internal `_baseURI()` function that can be overriden to return a string. If this string is available, it will be concatenated with the token ID to generate the token URI. This default behavior can be entirely overriden if a different one is required.

_Check out [`ERC721`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/token/ERC721/ERC721.sol) and [`ERC721Enumerable`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/token/ERC721/extensions/ERC721Enumerable.sol) on GitHub._

### AccessControl Enumerability

We think [`AccessControl`](https://docs.openzeppelin.com/contracts/3.x/api/access#AccessControl) is a great choice for projects that need to grow beyond the `Ownable` pattern. It allows defining separate roles for the different tasks in a contract that require authorization, and it provides a lot of flexibility as to how those roles are managed, supporting a hierarchy of roles if necessary.

This contract used to come with enumerability built in (of addresses assigned to each role), with a cost that may have discouraged its use. We decided to make it simpler by removing the default of on-chain enumerability.

The information can still be obtained off-chain by consuming the log of events of a contract. If on-chain enumerability is required, there is a separate `AccessControlEnumerable` contract that implements it.

_Check out [`AccessControl`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/access/AccessControl.sol) and [`AccessControlEnumerable`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/access/AccessControlEnumerable.sol)._

## Meta Transactions (GSN v2)

The OpenGSN team has been busy working on GSNv2, and GSNv1 was put in maintenance mode. Thus, we’ve removed our contracts for GSNv1 integration and begun adding support for GSNv2.

The new version is a more modular system and requires a lot less code. The core is in [`ERC2771Context`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/metatx/ERC2771Context.sol), while [`MinimalForwarder`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/metatx/MinimalForwarder.sol) is a utility contract that can assist during testing of a GSNv2-based system.

* * *

## SafeMath

As I mentioned at the beginning, Solidity 0.8 marks the end of the `SafeMath` era, as overflow checks are now built into the compiler.

You will find that `SafeMath` is still in the repository, athough it is now just a wrapper over the built-in overflow checks. The library was kept to ease the transition, but we encourage users on Solidity 0.8 to remove `SafeMath` from their contracts and rely on the compiler checks exclusively. We may fully remove it from the repository in a future major release.

_See the discussion at [https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2465](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2465)._

* * *

## Get Started

Remember this is a beta release and there may be small breaking changes before the stable release.

- Check out the [release branch on GitHub](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/release-v4.0).
- Install from npm with `npm install @openzeppelin/contracts@next`,  
or the upgradeable version with `npm install @openzeppelin/contracts-upgradeable@next`
- See the [Contracts 4.0 Timeline](https://forum.openzeppelin.com/t/contracts-4-0-timeline/5774).

Leave your comments below.

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [March 1, 2021, 5:00pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/2 "2021-03-01T17:00:23Z")

</div>

2 posts were split to a new topic: [How to implement ERC721 batchBuy](https://forum.openzeppelin.com/t/how-to-implement-erc721-batchbuy/6030)

---

<div class="post-metadata">

**Author:** ![barakman](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/barakman/32/855_2.png) [@barakman](https://forum.openzeppelin.com/u/barakman)\
**Post date:** [March 2, 2021, 9:20pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/3 "2021-03-02T21:20:57Z")

</div>

Note that while it is indeed ‘ **the end of the `SafeMath` era** ’, there are still cases in which developers would want to avoid using the (now safe) arithmetic operators, by encapsulating their designated piece of code within an `unchecked` clause, where **cheaper** (unsafe) arithmetic is applied instead.  
For example, when implementing [an efficient non-integer-exponentiation](https://github.com/bancorprotocol/contracts-solidity/blob/master/solidity/contracts/converter/BancorFormula.sol#L748-L825).  
There are simpler examples, like [binary log](https://github.com/bancorprotocol/contracts-solidity/blob/master/solidity/contracts/converter/BancorFormula.sol#L702-L725), [square root](https://github.com/bancorprotocol/contracts-solidity/blob/master/solidity/contracts/utility/MathEx.sol#L8-L22), and in fact - every arithmetic computation in your code which you’ve implemented **without** using `SafeMath` because you knew that it was inherently safe. Even the simplest `for` loop with a 256-bit counter which would never overflow, now becomes more expensive as a result of the `++` operator being safe.  
There’s a fair chance that many developers would just put their entire code under `unchecked`, while continuing to use `SafeMath` where necessary (i.e., wherever it is used in “close proximity” with natural arithmetic, and it is easier to just use it rather than “toggling” the `unchecked` option over and over).  
In that sense, it is debatable that this new feature of Solc 0.8 is a pure advantage.

---

<div class="post-metadata">

**Author:** ![frangio](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/frangio/32/15251_2.png) [@frangio](https://forum.openzeppelin.com/u/frangio)\
**Post date:** [March 3, 2021, 2:58pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/4 "2021-03-03T14:58:52Z")

</div>

I agree it is debatable and I hope it’s a debate we have together with the Solidity team in order to push the language forward toward cheaper and safer patterns.

In the meantime, using `unchecked` + `SafeMath` sounds like a reasonable alternative an it’s one of the reasons the `SafeMath` library is still included in 4.0.

---

<div class="post-metadata">

**Author:** ![Amxx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/amxx/32/668_2.png) [@Amxx](https://forum.openzeppelin.com/u/Amxx)\
**Post date:** [March 3, 2021, 6:10pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/5 "2021-03-03T18:10:01Z")

</div>

# 4.0.0-beta.1 update

We just released the second preview of Contracts 4.0. This update includes some changes that have been requested by users. Some gas optimizations are also included.

## Changes

#### ERC20

The [`ERC20Capped`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/token/ERC20/extensions/ERC20Capped.sol) extensions now enforces the check directly in the `_mint` function, thus removing the addition gas cost this extension used to have on transfers.

#### ERC721

A new extension, [`ERC721URIStorage`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/token/ERC721/extensions/ERC721URIStorage.sol) re-implements the `tokenURI` mechanism that used to be part of the simple [`ERC721`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.4/contracts/token/ERC721/ERC721.sol) implementation in the 3.x releases. In particular, this includes the internal `_setTokenURI` method that allows for custom URIs.

#### ERC777

Optimization of the constructor gas cost for the [ERC777](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/token/ERC777/ERC777.sol).

#### Proxy

`proxy/UpgradeableProxy` has been moved and renamed to [`proxy/ERC1967/ERC1967Proxy.sol`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/contracts/proxy/ERC1967/ERC1967Proxy.sol). This is done to prepare the path to more proxy patterns such as ERC1822’s UUPS.

## Get Started

Remember this is a beta release and there may be small breaking changes before the stable release.

- Check out the [release branch on GitHub](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/release-v4.0).
- Install from npm with `npm install @openzeppelin/contracts@next` ,  
or the upgradeable version with `npm install @openzeppelin/contracts-upgradeable@next`
- See the [Contracts 4.0 Timeline](https://forum.openzeppelin.com/t/contracts-4-0-timeline/5774).

Leave your comments below.

---

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [March 5, 2021, 1:39am UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/6 "2021-03-05T01:39:45Z")

</div>

A post was split to a new topic: [Is it safe to upgrade from OpenZeppelin Contracts Upgradeable 3.4.0 to 4.0.0](https://forum.openzeppelin.com/t/is-it-safe-to-upgrade-from-openzeppelin-contracts-upgradeable-3-4-0-to-4-0-0/6103)

---

<div class="post-metadata">

**Author:** ![Amxx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/amxx/32/668_2.png) [@Amxx](https://forum.openzeppelin.com/u/Amxx)\
**Post date:** [March 9, 2021, 2:58pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/7 "2021-03-09T14:58:38Z")

</div>

# 4.0.0-rc.0 update

The release candidate for 4.0 is out. We hope to release it officially during the 4th week of March.

- The [Contracts 4.0 Timeline](https://forum.openzeppelin.com/t/contracts-4-0-timeline/5774) has been updated accordingly.
- See the [changelog](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.0/CHANGELOG.md) for more information.

---

<div class="post-metadata">

**Author:** ![Amxx](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/amxx/32/668_2.png) [@Amxx](https://forum.openzeppelin.com/u/Amxx)\
**Post date:** [March 25, 2021, 3:04pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/8 "2021-03-25T15:04:23Z")

</div>

**4.0.0 is out** 🚀

---

<div class="post-metadata">

**Author:** ![spalladino](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/spalladino/32/22_2.png) [@spalladino](https://forum.openzeppelin.com/u/spalladino)\
**Post date:** [July 15, 2021, 12:58pm UTC](https://forum.openzeppelin.com/t/openzeppelin-contracts-4-0-beta/5878/9 "2021-07-15T12:58:31Z")

</div>

A post was split to a new topic: [Using ETHless meta-txs](https://forum.openzeppelin.com/t/using-ethless-meta-txs/12524)
