You Might Not Need SafeMath Anymore after Solidify 0.8

What is SafeMath

SafeMath library that has been developed by OpenZeppelin was a famous module to be imported from most of smart contracts to avoid overflow and underflow.

pragma solidity ^x.x.x;

import "@openzeppelin-solidity/contracts/utils/math/SafeMath.sol";

contract C {
    using SafeMath for uint;
}

That library offers arithmetic operations that can be wrapped for mathmatical operations like addition and multiply.

Solidity 0.8 checks overflow/underflow by default

However, from v0.8 compiler version, all arithmetic operations perform overflow and underflow checks by default. The following code will trigger a panic from v0.8.

contract C {
    function f() public pure {
        uint x = 0;
        x--;
    }
}

In other words, if you are using >= 0.8, there might not need to import and use the SafeMath library anymore.

unchecked Blocks

However, the story goes on. There are some cases that we'd like to turn off that behaviour, according to the release note.

Since checked arithmetic uses more gas, as discussed in the previous section, and because there are times when you really want the wrapping behaviour, for example when implementing cryptographic routines...

You can use unchecked keyword to re-enable the previous "wrapping" or "modulo" arithmetic as follows:

contract C {
    function f() public pure returns (uint) {
        uint x = 0;
        unchecked { x--; }
        return x;
    }
}

SafeMath with Solidity v0.8

The latest SafeMath library, which is v4.7.3 as of writing this article, comes with abstraction methods for them.

It has try{Add,Sub,Mul,Div,Mod} operations, that relies on unchecked keyword that is available after v0.8.

library SafeMath
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }
}

As you can see the source code, tryAdd() for example returns (bool, uint256) multiple values. You can use those try methods when you are interested in some edge cases that arithmetic operations overflow/underflow, and handle both cases.

Conclusion

In summary, if you are worried only about overflow and underflow, the default compiler behaviour might be enough with >= 0.8 Solidity compiler.

But if you are interested in handling overflow and underflow cases, SafeMath libary might give you a simple yet beautiful abstract methods for doing that.

October 29, 2022