Solidity Security By Example #11: Denial of Service With Induction Variable Overflow
Originally published in Valix Consulting’s Medium.
Smart contract security is one of the biggest impediments to 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.
Induction variable overflow can happen when a smart contract developer declares some variable with a too-small data type. Subsequently, the vulnerable contract cannot operate expectedly or even be exploited.
This article will explain how a smart contract vulnerable to the induction variable overflow can incur an unexpected denial-of-service (DoS) issue and how to prevent it. Enjoy reading. 😊
You can find all related source code at 👉 https://github.com/serial-coder/solidity-security-by-example/tree/main/11_denial_of_service_with_induction_variable _overflow.
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 code below presents the
VulnerableSimpleAirdrop contract that facilitates an airdrop launcher to quickly transfer an Ether airdrop to multiple receivers in only one transaction through the
transferAirdrops function (lines 17–30).
To transfer an airdrop, the contract must be deployed with at least 1 Ether (line 8), and only a registered launcher can successfully execute the
transferAirdrops function (lines 9, 12–15, and 17).
VulnerableSimpleAirdrop contract is vulnerable. Can you detect any issues? 👀
We would like to note that the
VulnerableSimpleAirdropcontract got two vulnerabilities that are considered out of scope in this article.
First is an integer overflow vulnerability that can bypass the
requirecheck in lines 20–23. In case you might be interested, please refer to our past article. 🕵️♂️
Second is a denial-of-service with revert vulnerability in line 27. We also described its vulnerability details in our past article. 🕵️♂️
The induction variable overflow occurs in line 26 in the
Consider the following Figure to understand the vulnerability in more detail.
transferAirdrops function loops over the
_receivers array (lines 26–29) to transfer an airdrop to each receiver in line 27 (Steps 1–4). But if the length of the
_receivers array is greater than 255, an overflow will occur since the variable
i is declared as uint8 in line 26. 🤔
As a result, the loop will be restarted at index 0 repeatedly (Step 5). Consequently, the transaction will consume all gas and be reverted eventually, leading to an unexpected denial-of-service (DoS) issue, even if an airdrop launcher would set the transaction’s gas limit to the block gas limit. Oh My!! 👻
More specifically, the array indexes 256 and beyond would never be reached due to the out-of-range of the uint8 data type. 🎃
Below is the
IssueSimulation contract that can simulate the
VulnerableSimpleAirdrop contract’s induction variable overflow vulnerability.
To simulate the vulnerability, for instance, we can execute the
issueSimulation.simulateIssue(address(vulnerableSimpleAirdrop), 1 wei) function (lines 10–20 above).
issueSimulation.simulateIssue() function will generate a mock-up set of 300 airdrop receivers (lines 8 and 14–17). Then, the function will invoke the
vulnerableSimpleAirdrop.transferAirdrops(_amount, receivers) function (line 19).
Please have a look at Figure 2 below for the vulnerability simulation result.
As you can see, the generated array of 300 dummy airdrop receivers caused the induction variable overflow issue. Ultimately, the airdrop transaction was reverted due to exceeding the block gas limit error. 👾
If you are interested in more about the denial-of-service vulnerability regarding the block gas limit, please check out our past article. 🕵️♂️
FixedSimpleAirdrop contract is the improved version of the
VulnerableSimpleAirdrop contract. 👨🔧
To remediate the induction variable overflow vulnerability on the
transferAirdrops function, the associated variable
i was changed its data type from
uint8 to the larger data type
uint256 (line 28 above).
uint256 data type, the variable
i will support any length of the
_receivers array as long as the transaction’s gas used is neither reached the gas limit set by an airdrop launcher nor reached the block gas limit of the blockchain network.
Please do not use the
FixedSimpleAirdropcontract in your production. The contract is just a proof of concept of how to fix the induction variable overflow vulnerability only.
Nevertheless, the contract still implants other security vulnerabilities as mentioned in the
In this article, you have learned how the induction variable overflow vulnerability can cause an unexpected denial-of-service (DoS) issue in the smart contract.
We demonstrated how the DoS issue could occur and how to fix the issue. We hope you enjoy our article and hope to see you again in the forthcoming article.
Again, you can find all related source code at 👉 https://github.com/serial-coder/solidity-security-by-example/tree/main/11_denial_of_service_with_induction_variable _overflow.
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, industry knowledge, and support staff, strive to deliver consistently superior quality services.
For any business inquiries, please contact us via Twitter, Facebook, or firstname.lastname@example.org.
Originally published in Valix Consulting’s Medium.