In solidity, integer types have maximum values. For example:
uint8
=> 255
uint16
=> 65535
uint24
=> 16777215
uint256
=> (2^256) - 1
Overflow and underflow bugs can occur when you exceed the maximum value (overflow) or when you go below the minimum value (underflow). When you exceed the maximum value, you go back down to zero, and when you go below the minimum value, it brings you back up to the maximum value.
Since smaller integer types like: uint8
, uint16
, etc. have smaller maximum values, it can be easier to cause an overflow, thus they should be used with greater caution.
Older contracts often made use of the SafeMath library, to avoid over/underflows, but in solidity >=v0.8.0, SafeMath logic is built in by default. It's important to consider that regardless of SafeMath logic being used, either built-in or used manually in older contracts, over/underflows still trigger reverts, which may result in denial of service of important functionality or other unexpected effects. Built-in SafeMath logic may also be avoided with unchecked
blocks, see docs for more info.