# Arithmetic Overflows and Underflows in Ethereum Virtual Machine

Ethereum Virtual Machine (EVM), defines a constant size for all data types and so for the integers. Thus, a variable is used to store an integer, there is a specific range of numbers this variable can take. For example, a **uint8 **variable, can store numbers between **0 and 255**.

**Overflow**

Arithmetic Overflow is a condition that occurs when an operation produces a result that is greater than a given register or storage location can store or represent.

Consider we are having a **uint8 **variable called *sum*. This variable can take values from 0 to 255 as the scope of a uin8 variables is [0, 255]. The variable *sum *is the sum of the variable *a *(where *a = 0*) and *b *(where *b = 257*).

If we add *a *and *b *we get *sum = a + b => sum = 0 + 257 => sum = 257*. At that point notice that sum = 257 ∉[0, 255]. In order to store this value in the *sum* variable we have to **wrap around** the number 257 and convert it into a number which exists inside the scope [0, 255]. For this process we use the following formula:

**(number To Be Added — maximum) + minimum — 1**

By using this formula we have *sum = (257–255) + 0–1 => sum = 1* ∈ [0, 255]. So, after 257 wrapped around it converted into 1 which belongs in the scope of [0, 255]. Now the value 1 can normally stored into *sum *variable.

This condition is called **overflow**. When an overflow occurs the EVM uses the **wrap around** process so it can store the value into the variable.

**Underflow**

We can now follow the same process when an underflow occurs. Consider again we are having a **uint8** variable called *sub*. This variable can take values from 0 to 255. The variable sub is the subtraction of the variable *a *(where *a = 0*) minus *b* (where *b = 1*).

If we now subtract *a *from *b *we get *sub = a — b => sum = 0–1 => sub = -1*. At that point notice that *sub = -1* ∉ [0, 255]. In order to store this value in the *sub *variable we have to **wrap around** again the number -1. For this process we use the following formula:

**maximum + (minimum — numberToBeSubtracted) + 1**

By using this formula we have s*ub = 255 + (0–1) +1 => sub = 255* ∈ [0, 255]. So, after -1 wrapped around it converted into 255 which belongs in the scope of [0, 255]. Now the value 255 can normally stored into *sum *variable.

The following table shows how **uint8 **values are converted after the wrap around process.

**The Vulnerability**

This vulnerability can occur when a mathematical equation uses a fixed size variable to store a value which is out of its range. **Token **contract uses the *transfer *function to check if the user has the required balance in order to transfer the desired amount to an address.

Consider that the user has a zero balance and willing to transfer 100 ether. When **line 11** inside *transfer *function executed the following will happen.

*balances[msg.sender]-value = 0–100 = -100*

Notice that we have a **uint8 **variable so -100 ∉[0, 255]. So we have an **underflow**. As we told before the wrap around process will be executed so value -100 will be converted into 156. Now 156 ∈ [0, 255] and the following will happen.

*balances[msg.sender]-value = 156 = -100 ≥ 0 = True*

So what the malicious user has done here is that successfully transferred 100 ether from a **zero balance** account.

**Preventative Technique**

To avoid this type of attack we can use in our code mathematical libraries. Those libraries replace every operator with fixed functions.

One of the most popular libraries for this reason is the **Safe Math Library** from **Open Zeppelin**. This library replace all the mathematical operators with functions and whenever an underflow or overflow occurs the function throws an error and the program terminates without cause any confusion.

So, now if we use Safe Math Library, the code Token Contract will be the following.

When **line 11** executed and an underflow occurred, the function will throw an error and the program will terminate.