How to Secure Your Smart Contracts (Part 2)

Arithmetic overflows and underflows

Alex Roan
Alex Roan
Mar 26 · 3 min read
Image for post
Image for post
Photo by Antoine Dautry on Unsplash

Prerequisites: A basic understanding of the Ethereum blockchain and smart contracts.

Introduction

This is part 2 of a series on securing your Smart Contracts. Part 1 discussed reentrancy and owner-logic theft attacks.

Here, we’ll go through arithmetic overflows and underflows, a type of logic weakness that can sometimes creep into our code. We’ll describe what they mean, examples of how they might appear, and how to prevent them from appearing in our smart contracts.

What Are They?

To understand arithmetic over- and underflows, we must first understand the data types in which they appear.

Ethereum Virtual Machine (EVM) integers are always of a fixed size. For example, unit8 can only store values between (and including) 0 and 255. Trying to store the value 256 in a uint8 variable will result in a value of 0. This is ripe for exploitation if no checks are made before execution.

Underflows

An underflow can appear when a value is subtracted from an integer, where the current value of that integer is less than the value being subtracted. For example:

uint8 myValue = 2;
uint8 subValue = 3;
uint8 result = myValue - subValue;

Here, our result variable would not equal -1 as we think it should; result would equal 255.

Counting backward from 2, the EVM goes 1 … 0 … 255. This is known as an underflow.

Overflows

An overflow is the opposite of an underflow. It can appear when a value is added to an integer variable, where the result is greater than the maximum limit of that variable’s data type. For example:

uint8 myValue = 254;
uint8 addValue = 3;
uint8 result = myValue + addValue;

Here, our result variable does not equal 257 as we think it should. It gets calculated to 1 because 255 is the maximum value of uint8.

Counting upward from 254, the EVM goes … 255 … 0 … 1. This is known as an overflow.

Example

Consider this piece of Solidity code, and before scrolling to the explanation, can you spot the problem?

mapping(address => uint) balances;function withdraw(uint _value) external {
require(balances[msg.sender] - _value >= 0);
balances[msg.sender] -= _value;
msg.sender.transfer(_value);
}

The require statement requires that the balance of the sender minus the withdraw value is greater than or equal to 0. This makes sense to us logically since we don’t want to allow anyone to withdraw more than they have in their balance. However, this is vulnerable to underflow exploitation.

If the attacker had two Ether stored in the contract and attempted to withdraw ten, the require statement would allow it. This is because the subtraction would cause the result of balances[msg.sender] — _value to be greater than or equal to 0 by underflowing to the maximum. Because the integer is unsigned, the require statement will always pass as long as the msg.sender has a balance.

By this logic, anyone who has deposited a balance at any point can completely rinse the contract of funds.

Preventative Measures

Always use libraries that provide safer functions to perform basic arithmetic. OpenZeppelin’s SafeMath library is the most commonly used in the Solidity community. It provides functions for addition, subtraction, multiplication, division, and modulus.

The library is thoroughly scrutinized by the community before being released, so we can have confidence in its ability to prevent arithmetic logic bugs. Here’s an example of how to use SafeMath’s sub() function instead of using the minus arithmetic operator in our smart contract:

using SafeMath for uint;function withdraw(uint _value) external {
require(balances[msg.sender].sub(_value) >= 0);
balances[msg.sender] -= _value;
msg.sender.transfer(_value);
}

In this scenario, the require statement would fail if we attempted to withdraw more than our balance. This is because the sub() function requires the balance be greater than or equal to _value.

Better Programming

Advice for programmers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store