Solidity Security By Example #06: Integer Overflow

Phuwanai Thummavet
Valix Consulting
Published in
4 min readOct 5, 2022

By Phuwanai Thummavet

Smart contract security is one of the biggest impediments toward the mass adoption of the blockchain. For this reason, we are proud to present this series of articles regarding Solidity smart contract security to educate and improve the knowledge in this domain to the public.

Integer overflow might be one of the most commonly known issues in the smart contract security field. This article will explore how the integer overflow happens and how to prevent it when developing your smart contracts. Enjoy reading. 😊

You can find all related source code at 👉 https://github.com/serial-coder/solidity-security-by-example/tree/main/06_integer_overflow.

Disclaimer:

The smart contracts in this article are used to demonstrate vulnerability issues only. Some contracts are vulnerable, some are simplified for minimal, some contain malicious code. Hence, do not use the source code in this article in your production.

Nonetheless, feel free to contact Valix Consulting for your smart contract consulting and auditing services.🕵

Table of Contents

  • The Vulnerability
  • The Attack
  • The Solutions
  • Summary

The Vulnerability

The following presents the InsecureMoonToken contract that allows a user to buy or sell MOON tokens. The MOON is a non-divisible token (token decimals = 0) pegged with 1 Ether. In other words, 1 MOON token will always have a fixed value of 1 Ether. Therefore, you can buy or sell 1, 2, 3, or 46 tokens but not 33.5.

Exactly, the InsecureMoonToken contract is vulnerable to integer overflow. Can you catch up on the issue? 👀

The integer overflow occurs in line 16 in the buy function.

Consider the case that an attacker inputs some tremendous amount of _tokenToBuy into the buy function. What would happen?

Figure 1. How the overflow occurs

Figure 1 draws on how the overflow occurs. In the case of 2 * 2²⁵⁵, the computed value would circle back to 0, as you can see.

Consider the require(msg.value == _tokenToBuy * TOKEN_PRICE, “Ether received and Token amount to buy mismatch”); statement. With the overflow, an attacker can buy a large amount of MOON tokens (_tokenToBuy) by spending only a few Ethers (msg.value).

Moreover, the attacker can even steal all Ethers locked in the InsecureMoonToken contract with a single sell transaction. OMG! 🙀

Possible Attacks

  1. Attacker balance manipulation
  2. Stealing all Ethers in a single transaction

The Attack

The following is the Attack contract in which an attacker can steal Ethers locked in the InsecureMoonToken contract.

To exploit the InsecureMoonToken, an attacker has to perform the following actions:

  1. Call: ethersRequired = attack.getEthersRequired()
    To calculate the number of Ethers required to complete a “buy” attack.
  2. Call: attack.attackBuy() and supplies the ethersRequired
    To exploit the overflow — spending a few Ethers but taking vast MOON tokens in return.
  3. Call: attack.attackSell()
    To steal Ethers locked in the InsecureMoonToken contract.
Figure 2. The attack result

The result of the attack is shown in Figure 2. As you can see, the attacker could steal 30 Ethers (10 and 20 Ethers were deposited by User1 and User2, respectively) by spending only 0.415 Ethers in exchange. 🤑

Another result of the attack, furthermore, the Attack contract’s balance recorded by the InsecureMoonToken was manipulated enormously. 😈

Note that you may notice that the 0.415 Ethers deposited by the attacker were locked and could not withdraw any longer since the MOON is a non-divisible token with 0 decimals. In other words, you cannot sell 0.415 MOONs for 0.415 Ethers.

In fact, the attacker can do some other trick by submitting another 0.585 Ethers to lock into the contract. This way, the attacker could withdraw 1 Ether being locked by exchanging it with 1 MOON 😎. Surely, we will explain that trick in the future article of this series. Stay tuned! 🤳

The Solutions

There are two preventive solutions to fix the overflow issue. 👨‍🔧

  1. Applying the standard OpenZeppelin’s SafeMath library for arithmetic operations (for the Solidity below v0.8)
  2. Using the Solidity v0.8+ (Solidity v0.8+ came up with the built-in underflow and overflow detection mechanism on arithmetic operations)

The FixedMoonToken contract above is the fixed version of the InsecureMoonToken. The contract applies the SafeMath library to prevent any underflow or overflow issues in lines 46, 50, 56, and 58.

The library used in the code is just a simplified version for brevity’s sake. Please refer to this link for the latest OpenZeppelin’s SafeMath library.

Summary

In this article, you have discovered the integer overflow vulnerability in the smart contract, how an attacker exploits it, and the solutions to fix the issue. We hope you have learned something interesting. And, see you in the following articles.

Again, you can find all related source code at 👉 https://github.com/serial-coder/solidity-security-by-example/tree/main/06_integer_overflow.

Author Details

Phuwanai Thummavet (serial-coder), Lead Blockchain Security Auditor and Consultant | Blockchain Architect and Developer.

See the author’s profile.

About Valix Consulting

Valix Consulting is a blockchain and smart contract security firm offering a wide range of cybersecurity consulting services. Our specialists, combined with technical expertise with industry knowledge and support staff, strive to deliver consistently superior quality services.

For any business inquiries, please get in touch with us via Twitter, Facebook, or info@valix.io.

--

--

Phuwanai Thummavet
Valix Consulting

Blockchain | Coding | Hacking — I’m a full-time bug collector. Most of the time I bring some bugs to life. Visit my website: www.serial-coder.com