12

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.

To obtain the previous behaviour, an unchecked block can be used:

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

My question is double:

  1. Why could I want to have behaviour that can lead to over/underflow?
  2. We have been using SafeMath to avoid over/underflow issues: Now it is not neccessary?
1
  • I would really love to know the answer to these questions as well.. from what I know, it's not needed to use SafeMath any Lee, but for some reason there's a new SafeMath library for 0.8.0+
    – Adrian D.
    Dec 26, 2021 at 18:42

3 Answers 3

16

Answer 1) We never want behavior that leads to over/underflow*. The reason the "unchecked" keyword exists is to allow Solidity developers to write more efficient programs. The default "checked" behavior costs more gas when adding/diving/multiplying, because under-the-hood those checks are implemented as a series of opcodes that, prior to performing the actual arithmetic, check for under/overflow and revert if it is detected. So if you're a Solidity developer who needs to do some math in 0.8.0 or greater, and you can statically determine there is no possible way for your arithmetic to under/overflow (maybe because you have your own "if" statement which checks that the numbers being added are never greater than, say, 100), then you can surround the arithmetic in an "unchecked" block.

tl;dr: "unchecked" exists in order to save gas

Answer 2) Correct. You do not need to include SafeMath in any of your contracts compiled using version 0.8.0 and above, because now the compiler implements what SafeMath does.

*The only reason I can think of for wanting this behavior is for educational reasons: If I'm writing an intro to Solidity book and I'd like to show how modular arithmetic works, I would like under/overflow to occur so I can show students how it works.

4
  1. One reason you might use unchecked is when looping through the elements of an array. Consider for example:
uint256 length = array.length;
for(uint256 i = 0; i < length; i++) {
  doSomething(array[i]);
}

Each time i++ is called under/overflow checks are made. But we're already constraining i by length, i < length, making those under/overflow checks unnecessary. So, we can rewrite the loop like this and potentially save significant gas:

uint256 length = array.length;
for(uint256 i = 0; i < length;) {
  doSomething(array[i]);
  unchecked{ i++; }
}
  1. That's right. SafeMath is not necessary for pragma >= 0.8.0.
0

Simple answer: To save gas, as the code inside unchechked{"Some Code"} isn't verified for underflow/overflow error cases.

However, that means you could cause a critical error or leave a security loop that someone might exploit.

Therefore I would advise caution if you are doing it. But you will see it often enough in Libraries like OpenZeppelin etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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