2

The docs on Solidity v0.8.0 Breaking Changes mention that overflows are now checked by default:

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

But it is unclear whether the modulo operation (%) classifies as an arithmetic operation. As per the docs:

It is not possible to disable the check for division by zero or modulo by zero using the unchecked block.

So my guess is that modulo shouldn't be faster in unchecked arithmetic. Is that correct?

2

Yes, modulo is cheaper in unchecked arithmetic! Take the following code:

pragma solidity ^0.8.0;

contract Modulos {
    function foo(uint256 x, uint256 y) external view returns (uint256 result, uint256 gasUsed) {
        uint256 startGas = gasleft();
        result = x % y;
        gasUsed = startGas - gasleft();
    }
    
    function bar(uint256 x, uint256 y) external view returns (uint256 result, uint256 gasUsed) {
        uint256 startGas = gasleft();
        unchecked {
            result = x % y;
            gasUsed = startGas - gasleft();
        }
    }
   
}

Passing 11 and 3 as x and y, respectively, yields the following gas costs:

  • 72 gas for foo
  • 23 gas for bar

You can test for yourself on Remix. I am not sure why this is the case - as per my explanation in the question body, I was expecting no difference in gas costs.

Side-node: You can also work with the assembly mod operation:

contract Modulos {
    function baz(uint256 x, uint256 y) external view returns (uint256 result, uint256 gasUsed) {
        uint256 startGas = gasleft();
        assembly {
            result := mod(x, y)
        }
        gasUsed = startGas - gasleft();
    }
}

This costs as much as the unchecked arithmetic (23 gas).

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.