3

Say I have a smart contract with variable of type uint256. I write a function to increment this variable.

How does the EVM handle trying to increment the variable to store values beyond 256 bits?

The Solidity docs say the following:

Number literal expressions retain arbitrary precision until they are converted to a non-literal type (i.e. by using them together with a non-literal expression). This means that computations do not overflow and divisions do not truncate in number literal expressions.

So apparently it won't overflow, so what does it do?

2
  • 1
    Maybe this helps you.Is it possible to overflow uints? Aug 9, 2017 at 5:38
  • The wording is slightly confusing. It should say something like "This means that literal expressions can not overflow...". See also the example just below, (2**800 + 1) - 2**800, which is larger than any data type.
    – jordanpg
    Dec 30, 2017 at 2:48

3 Answers 3

1

Non-literal expressions overflow. I think a 'literal' expression is something like 1223424234. That won't overflow, I suppose, because it won't even compile. A non literal expression (a = 1213232; b = 121231231 -- a and b are really large) will overflow if a+b is larger than largest uint256. At least this is my read.

1

It depends on the version of Solidity you are using.

Solidity v0.8 and above

Overflows and underflows are checked by default. As per the changelog:

Checks for overflow are very common, so we made them the default to increase readability of code, even if it comes at a slight increase of gas costs.

More specifically:

Arithmetic overflow will use error data equal to a function call to Panic(uint256) with an error code specific to the circumstances.

Therefore, the following code will revert:

pragma solidity ^0.8.0;

function foo() external pure returns (uint256) {
    uint256 a = type(uint256).max;
    uint256 b = 1;
    uint256 c = a + b; // Reverts
    return c;
}

Solidity v0.7 and below

Overflows and underflows are NOT checked by default. The same code snippet returns 0.

pragma solidity ^0.7.0;

function foo() external pure returns (uint256) {
    uint256 a = type(uint256).max;
    uint256 b = 1;
    uint256 c = a + b; // Does NOT revert
    return c; // Equal to 0
}

To ensure that your program behaves correctly, you should use a math library like SafeMath.sol or CarefulMath.sol.

0

Solidity 0.8.x will feature what is called checked arithmetic:

https://blog.soliditylang.org/2020/10/28/solidity-0.8.x-preview/

It disallows allows integer overflows or underflows within the code block.

Your Answer

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