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? – BinGoBinBin Aug 9 '17 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 '17 at 2:48
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, privacy policy and cookie policy