Solidity Security By Example #06: Integer Overflow
Originally published in Valix Consulting’s Medium.
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 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 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
-
Attacker balance manipulation
-
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:
-
Call:
ethersRequired = attack.getEthersRequired()
To calculate the number of Ethers required to complete a “buy” attack. -
Call:
attack.attackBuy() and supplies the ethersRequired
To exploit the overflow — spending a few Ethers but taking vast MOON tokens in return. -
Call:
attack.attackSell()
To steal Ethers locked in theInsecureMoonToken
contract.
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. 👨🔧
-
Applying the standard OpenZeppelin’s SafeMath library for arithmetic operations (for the Solidity below v0.8)
-
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.
Originally published in Valix Consulting’s Medium.