22

SafeMath was commonly used to revert the transaction on overflow and underflow, instead of allowing the number to wrap around. The solidity 0.8.0 release notes state:

Code Generator: All arithmetic is checked by default. These checks can be disabled using unchecked { ... }.

Does this mean SafeMath is now completely obsolete when compiling with solc >= 0.8.0, or are there still situations where it can be useful?

2
  • 1
    Can be useful if you add to it your own safe-implementation of the ** operator, with your implementation being more gas-efficient than solc 0.8's safe-implementation of this operator (same goes for each one of the other arithmetic operators of course, though doubtfully you could implement any of those in a better way than solc 0.8). Commented Dec 21, 2020 at 10:58
  • 1
    I believe that they implemented a safe-version of the ** operator, which is optimized for base 2 and base 10, under the assumption that most usages of this operator are for these two bases. So for example, if your system requires this operator for other bases, then you may come up with a better safe-implementation of it. Commented Dec 21, 2020 at 11:00

5 Answers 5

14

The Solidity v0.8.0 Breaking Changes Docs says:

Checks for overflow are very common, so we made them the default to increase readability of code, even if it comes at a slight increase of gas costs.

And Checking the GitHub commits for SafeMath.sol I found this commit made on February 2021 were they added the comment:

NOTE: SafeMath is no longer needed starting with Solidity 0.8. The compiler now has built in overflow checking.

The comment was later Reviewed in this other commit, with the title Review wording of SafeMath need in Solidity 0.8, and changed to:

NOTE: SafeMath is generally not needed starting with Solidity 0.8, since the compiler now has built in overflow checking.

Checking the first commit linked, we can also see a comment made in the SignedSafeMath.sol contract that said:

Signed math operations that revert on error.

I think that's like saying they are checking for overflows.

Also, the wording changes seems to be aligned with the other answer here, noticing that you may reuse safemath as library to improve operation cost for example, as the default one is more expensive now according to the docs, or to improve the ** operator for bases different to 2 or 10.

But it does seems that SafeMath is indeed generally not needed starting with Solidity 0.8

Also the top comment in the safemath library now says:

CAUTION This version of SafeMath should only be used with Solidity 0.8 or later, because it relies on the compiler's built in overflow checks.

Now the add function is :

function add(uint256 a, uint256 b) internal pure returns (uint256) {
    return a + b;
}

And an earlier implementation was:

 function add(uint a, uint b) internal pure returns (uint) {
    uint c = a + b;
    require(c >= a, "SafeMath: addition overflow");

    return c;
}
6

From the Solidity 0.8.0 Release Announcement about the exponentiation operator (**):

We hope that we found a rather efficient implementation and would also appreciate your feedback about that!

For many special cases, we actually implemented it using the exp opcode instead of our own implementation. More specifically, exponentiation operations that use a literal number as base will use the exp opcode directly. There are also specialized code paths for bases that are variables with small value. For bases up to 306, if the exponent is smaller than a hard-coded safe upper bound, it will use the exp opcode directly. If the base or the exponent is too large, it might fall back to the loop-based implementation.

In addition to all of the above (although not directly stated in this announcement), I believe that they have designed their safe-implementation of this operator to be optimized specifically for bases 2 and 10, which are the most commonly used bases.

So if your system requires this operator for other bases, OR if you happen to come up with a better (more gas-efficient) safe implementation of it, then it might be useful for you to add it in your SafeMath library.

Of course, the same goes for each one of the other arithmetic operators supported by the language, though I doubt that you could safe-implement any of them in a better way than solc 0.8.

1
  • 23
    I don't understand how this is a useful answer to the question? The OP is asking whether they can safely ditch SafeMath, but you are focusing on performance rather than security, and your position seems to be effectively "SafeMath could still be useful if you could safely modify it to outperform solc, but I doubt you can". Huh? Commented Apr 4, 2021 at 10:03
3

Yes. You can drop it like it's hot. You very likely do not need it.

SafeMath is now completely obsolete when compiling with solc >= 0.8.0, or are there still situations where it can be useful?

Well, just because something seems useless doesn't mean it's actually useless or has no potential future use. Everything can be useful.

Solidity 0.8.0 changelog:

Arithmetic operations revert on underflow and overflow. You can use unchecked { ... } to use the previous wrapping behaviour.

Checks for overflow are very common, so we made them the default to increase readability of code, even if it comes at a slight increase of gas costs.

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Dec 13, 2021 at 22:03
3

One situation where the old SafeMath might be useful with solidity >=0.8.0 (which is what the original question is about) is to get a revert reason string while keeping an easy to read code (adding a small gas overhead at deployment):

unchecked {
    balance.sub(value, "Balance too low");
}

Which would be, without safemath, something a bit longer (as in the OpenZeppelin ERC-20 implementation):

require(balance > value, "Balance too low");
unchecked {
    balance -= value;
}

Do not use the latest Safemath version to do so though, as it would lead to not checking for under/overflow at all.

2

If you have a smart contract in >=0.8.0, you do not need SafeMath anymore and you can ditch it from your imports.

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Oct 23, 2021 at 2:18

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.