diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d2853cf887..2fc4cc5e348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ ### Removals -The following contracts were removed: +The following contracts and libraries were removed: +- `Counters` - `ERC20Snapshot` - `ERC20VotesComp` - `GovernorVotesComp` diff --git a/contracts/mocks/proxy/UUPSUpgradeableMock.sol b/contracts/mocks/proxy/UUPSUpgradeableMock.sol index 83e6ef465b3..567f3b536b9 100644 --- a/contracts/mocks/proxy/UUPSUpgradeableMock.sol +++ b/contracts/mocks/proxy/UUPSUpgradeableMock.sol @@ -3,17 +3,16 @@ pragma solidity ^0.8.19; import "../../proxy/utils/UUPSUpgradeable.sol"; -import "../../utils/Counters.sol"; contract NonUpgradeableMock { - Counters.Counter internal _counter; + uint256 internal _counter; function current() external view returns (uint256) { - return Counters.current(_counter); + return _counter; } function increment() external { - return Counters.increment(_counter); + ++_counter; } } diff --git a/contracts/utils/Counters.sol b/contracts/utils/Counters.sol deleted file mode 100644 index 2c695184005..00000000000 --- a/contracts/utils/Counters.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) - -pragma solidity ^0.8.19; - -/** - * @title Counters - * @author Matt Condon (@shrugs) - * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number - * of elements in a mapping, issuing ERC721 ids, or counting request ids. - * - * Include with `using Counters for Counters.Counter;` - */ -library Counters { - struct Counter { - // This variable should never be directly accessed by users of the library: interactions must be restricted to - // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add - // this feature: see https://github.com/ethereum/solidity/issues/4637 - uint256 _value; // default: 0 - } - - function current(Counter storage counter) internal view returns (uint256) { - return counter._value; - } - - function increment(Counter storage counter) internal { - unchecked { - counter._value += 1; - } - } - - function decrement(Counter storage counter) internal { - uint256 value = counter._value; - require(value > 0, "Counter: decrement overflow"); - unchecked { - counter._value = value - 1; - } - } - - function reset(Counter storage counter) internal { - counter._value = 0; - } -} diff --git a/contracts/utils/Nonces.sol b/contracts/utils/Nonces.sol index a908234ee61..04b884797e1 100644 --- a/contracts/utils/Nonces.sol +++ b/contracts/utils/Nonces.sol @@ -1,21 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import "./Counters.sol"; - /** * @dev Provides tracking nonces for addresses. Nonces will only increment. */ abstract contract Nonces { - using Counters for Counters.Counter; - - mapping(address => Counters.Counter) private _nonces; + mapping(address => uint256) private _nonces; /** * @dev Returns an address nonce. */ function nonces(address owner) public view virtual returns (uint256) { - return _nonces[owner].current(); + return _nonces[owner]; } /** @@ -23,9 +19,12 @@ abstract contract Nonces { * * Returns the current value and increments nonce. */ - function _useNonce(address owner) internal virtual returns (uint256 current) { - Counters.Counter storage nonce = _nonces[owner]; - current = nonce.current(); - nonce.increment(); + function _useNonce(address owner) internal virtual returns (uint256) { + // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be + // decremented or reset. This guarantees that the nonce never overflows. + unchecked { + // It is important to do x++ and not ++x here. + return _nonces[owner]++; + } } } diff --git a/contracts/utils/README.adoc b/contracts/utils/README.adoc index 07cee64270c..aa5182bd1af 100644 --- a/contracts/utils/README.adoc +++ b/contracts/utils/README.adoc @@ -10,7 +10,6 @@ The {Address}, {Arrays}, {Base64} and {Strings} libraries provide more operation For new data types: - * {Counters}: a simple way to get a counter that can only be incremented, decremented or reset. Very useful for ID generation, counting contract activity, among others. * {EnumerableMap}: like Solidity's https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] type, but with key-value _enumeration_: this will let you know how many entries a mapping has, and iterate over them (which is not possible with `mapping`). * {EnumerableSet}: like {EnumerableMap}, but for https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets]. Can be used to store privileged accounts, issued IDs, etc. @@ -75,8 +74,6 @@ Ethereum contracts have no native concept of an interface, so applications must {{Base64}} -{{Counters}} - {{Strings}} {{ShortStrings}} diff --git a/docs/modules/ROOT/pages/erc721.adoc b/docs/modules/ROOT/pages/erc721.adoc index 695f4435580..6d839c81e5d 100644 --- a/docs/modules/ROOT/pages/erc721.adoc +++ b/docs/modules/ROOT/pages/erc721.adoc @@ -17,11 +17,9 @@ Here's what a contract for tokenized items might look like: pragma solidity ^0.8.19; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; -import "@openzeppelin/contracts/utils/Counters.sol"; contract GameItem is ERC721URIStorage { - using Counters for Counters.Counter; - Counters.Counter private _tokenIds; + uint256 private _nextTokenId; constructor() ERC721("GameItem", "ITM") {} @@ -29,12 +27,11 @@ contract GameItem is ERC721URIStorage { public returns (uint256) { - uint256 newItemId = _tokenIds.current(); - _mint(player, newItemId); - _setTokenURI(newItemId, tokenURI); + uint256 tokenId = _nextTokenId++; + _mint(player, tokenId); + _setTokenURI(tokenId, tokenURI); - _tokenIds.increment(); - return newItemId; + return tokenId; } } ---- diff --git a/docs/modules/ROOT/pages/utilities.adoc b/docs/modules/ROOT/pages/utilities.adoc index efe59efcdff..0b178d9fec5 100644 --- a/docs/modules/ROOT/pages/utilities.adoc +++ b/docs/modules/ROOT/pages/utilities.adoc @@ -97,8 +97,6 @@ If you need support for more powerful collections than Solidity's native arrays [[misc]] == Misc -Want to keep track of some numbers that increment by 1 every time you want another one? Check out xref:api:utils.adoc#Counters[`Counters`]. This is useful for lots of things, like creating incremental identifiers, as shown on the xref:erc721.adoc[ERC721 guide]. - === Base64 xref:api:utils.adoc#Base64[`Base64`] util allows you to transform `bytes32` data into its Base64 `string` representation. diff --git a/test/utils/Counters.test.js b/test/utils/Counters.test.js deleted file mode 100644 index 6fb89922d36..00000000000 --- a/test/utils/Counters.test.js +++ /dev/null @@ -1,84 +0,0 @@ -const { expectRevert } = require('@openzeppelin/test-helpers'); - -const { expect } = require('chai'); - -const Counters = artifacts.require('$Counters'); - -contract('Counters', function () { - beforeEach(async function () { - this.counter = await Counters.new(); - }); - - it('starts at zero', async function () { - expect(await this.counter.$current(0)).to.be.bignumber.equal('0'); - }); - - describe('increment', function () { - context('starting from 0', function () { - it('increments the current value by one', async function () { - await this.counter.$increment(0); - expect(await this.counter.$current(0)).to.be.bignumber.equal('1'); - }); - - it('can be called multiple times', async function () { - await this.counter.$increment(0); - await this.counter.$increment(0); - await this.counter.$increment(0); - - expect(await this.counter.$current(0)).to.be.bignumber.equal('3'); - }); - }); - }); - - describe('decrement', function () { - beforeEach(async function () { - await this.counter.$increment(0); - expect(await this.counter.$current(0)).to.be.bignumber.equal('1'); - }); - context('starting from 1', function () { - it('decrements the current value by one', async function () { - await this.counter.$decrement(0); - expect(await this.counter.$current(0)).to.be.bignumber.equal('0'); - }); - - it('reverts if the current value is 0', async function () { - await this.counter.$decrement(0); - await expectRevert(this.counter.$decrement(0), 'Counter: decrement overflow'); - }); - }); - context('after incremented to 3', function () { - it('can be called multiple times', async function () { - await this.counter.$increment(0); - await this.counter.$increment(0); - - expect(await this.counter.$current(0)).to.be.bignumber.equal('3'); - - await this.counter.$decrement(0); - await this.counter.$decrement(0); - await this.counter.$decrement(0); - - expect(await this.counter.$current(0)).to.be.bignumber.equal('0'); - }); - }); - }); - - describe('reset', function () { - context('null counter', function () { - it('does not throw', async function () { - await this.counter.$reset(0); - expect(await this.counter.$current(0)).to.be.bignumber.equal('0'); - }); - }); - - context('non null counter', function () { - beforeEach(async function () { - await this.counter.$increment(0); - expect(await this.counter.$current(0)).to.be.bignumber.equal('1'); - }); - it('reset to 0', async function () { - await this.counter.$reset(0); - expect(await this.counter.$current(0)).to.be.bignumber.equal('0'); - }); - }); - }); -}); diff --git a/test/utils/Nonces.test.js b/test/utils/Nonces.test.js index a09cddb1f2a..4a01bb1bc8d 100644 --- a/test/utils/Nonces.test.js +++ b/test/utils/Nonces.test.js @@ -19,7 +19,7 @@ contract('Nonces', function (accounts) { expect(await this.nonces.nonces(sender)).to.be.bignumber.equal('0'); const { receipt } = await this.nonces.$_useNonce(sender); - expectEvent(receipt, 'return$_useNonce', { current: '0' }); + expectEvent(receipt, 'return$_useNonce', ['0']); expect(await this.nonces.nonces(sender)).to.be.bignumber.equal('1'); });