Solidity Security Vulnerabilities: Arithmetic Over/Under Flows

Prior to v0.8.1, Solidity contracts were vulnerable to over/underflow attacks. This vulnerability caused mathematical operations of +, – and * to be exploited if the attacker can control the value of at least one operand. A demo for over/underflow behaviour is provided below:

// SPDX-License-Identifier: MIT
pragma solidity 0.6.10;

contract Test
{
    // Overflow: Passing (255, 1) will return 0
    function add(uint8 x, uint8 y) pure public returns(uint8)
    {
        return x + y;
    }
    
    // Underflow: Passing (0, 1) will return 255
    function sub(uint8 x, uint8 y) pure public returns(uint8)
    {
        return x - y;
    }  
}

To see the vulnerability in action, lets see the contract from one of the Ethernaut Challenges:

pragma solidity ^0.4.18;

contract Token {

  mapping(address => uint) balances;
  uint public totalSupply;

  function Token(uint _initialSupply) {
    balances[msg.sender] = totalSupply = _initialSupply;
  }

  function transfer(address _to, uint _value) public returns (bool) {
    require(balances[msg.sender] - _value >= 0);
    balances[msg.sender] -= _value;
    balances[_to] += _value;
    return true;
  }

  function balanceOf(address _owner) public constant returns (uint balance) {
    return balances[_owner];
  }
}

The transfer() is vulnerable to over/underflow attack as the attacker controls the value of _value. If a sender with zero Token balance in the contract calls the transfer() with, say _value = 1:

// 0-1 = 115792089237316195423570985008687907853269984665640564039457584007913129639935 > 0 so evaluates to true
require(balances[msg.sender] – _value >= 0);

// balances[msg.sender] = 0 – 1 = 115792089237316195423570985008687907853269984665640564039457584007913129639935. That’s a lot of free token.
balances[msg.sender] -= _value;

// balances[_to] = 0 + 1
balances[_to] += _value;

Again, this vulnerability can not be exploited with Solidity 0.8.1^ as the transaction would just revert upon detecting an over/underflow.