27

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

4 Answers 4

40

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

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 calculating, 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 prove that 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.

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.

0
18
  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.
1
  • 2
    uint256 i = 0; is unnecessary, uint256 i; is slightly cheaper, and unchecked{ ++i; } is cheaper than unchecked{ i++; } ;)
    – scibuff
    Aug 2 at 21:28
3

Simple Answer: To save gas, as the code inside unchecked{"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.

1

an unchecked block can be used:

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract C {
      function f(uint a, uint b) pure public returns (uint) {
      // This subtraction will wrap on underflow.
      unchecked { return a - b; }
       }
      function g(uint a, uint b) pure public returns (uint) {
      // This subtraction will revert on underflow.
     return a - b;
     }
}

The call to f(2, 3) will return 2**256-1, while g(2, 3) will cause a failing assertion.

The unchecked block can be used everywhere inside a block, but not as a replacement for a block. It also cannot be nested.

The setting only affects the statements that are syntactically inside the block. Functions called from within an unchecked block do not inherit the property.

Your Answer

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

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