Browse Source

Remove utils/Counters.sol (#4289)

Co-authored-by: Francisco Giordano <fg@frang.io>
Hadrien Croubois 2 years ago
parent
commit
2ee1da12c4

+ 2 - 1
CHANGELOG.md

@@ -2,8 +2,9 @@
 
 ### Removals
 
-The following contracts were removed:
+The following contracts and libraries were removed:
 
+- `Counters`
 - `ERC20Snapshot`
 - `ERC20VotesComp`
 - `GovernorVotesComp`

+ 3 - 4
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;
     }
 }
 

+ 0 - 43
contracts/utils/Counters.sol

@@ -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;
-    }
-}

+ 9 - 10
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]++;
+        }
     }
 }

+ 0 - 3
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}}

+ 5 - 8
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;
     }
 }
 ----

+ 0 - 2
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.

+ 0 - 84
test/utils/Counters.test.js

@@ -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');
-      });
-    });
-  });
-});

+ 1 - 1
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');
   });