# 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 {

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.