4

According to Solidity documentation:

Prior to Solidity 0.8.0, arithmetic operations would always wrap in case of under- or overflow leading to widespread use of libraries that introduce additional checks.

Since Solidity 0.8.0, all arithmetic operations revert on over- and underflow by default, thus making the use of these libraries unnecessary.

Source: https://docs.soliditylang.org/en/v0.8.0/control-structures.html#checked-or-unchecked-arithmetic

We have using OpenZeppelin's Counters library from some time ago. The Counter's code, is designed to avoid overflows when managing numbers, but I think that we do not need it anymore from Solidity 8. With this approach we have a cleaner code without external libraries.

Am I missing something, or could be putting my code at risk by managing counters just like regular uints, without worrying about overflow?

Taking the OpenZeppelin's ERC721 example:

// contracts/GameItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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;

    constructor() ERC721("GameItem", "ITM") {}

    function awardItem(address player, string memory tokenURI)
        public
        returns (uint256)
    {
        uint256 newItemId = _tokenIds.current();
        _mint(player, newItemId);
        _setTokenURI(newItemId, tokenURI);

        _tokenIds.increment();
        return newItemId;
    }
}

We could replace it with:

    // contracts/GameItem.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    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 _tokenIds;
    
        constructor() ERC721("GameItem", "ITM") {}
    
        function awardItem(address player, string memory tokenURI)
            public
            returns (uint256)
        {
            //uint256 newItemId = _tokenIds.current();
            _mint(player, newItemId);
            _setTokenURI(newItemId, tokenURI);
    
            //_tokenIds.increment();
            _tokenIds++; //Regular uint management
            return newItemId;
        }
    }

1 Answer 1

0

There are no practical benefits anymore. If you check the latest implementation of the Counters library, you'll notice there's no overflow checking at the code level at all. Prior to solidity 0.8, SafeMath was indeed used in the library. My assumption is that its primary purpose is to make the OpenZeppelin contract wizard easier to work with since you literally tick boxes on what features you need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.