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).
unchecked
approach. The current state of affairs motivates devs to write implementations that are more complex than what they should be.