# Is the modulo operation cheaper in unchecked arithmetic?

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?

• Note to my future self: open a discussion in the Solidity forum to suggest making the default arithmetic checks cheaper than the `unchecked` approach. The current state of affairs motivates devs to write implementations that are more complex than what they should be. Oct 10, 2021 at 14:10

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).