This guide aims to dissect the top 10 solidity issues to help you understand the vulnerabilities and help you to avoid them.
Even though Solidity is a fairly new addition to the programming world, the widespread adoption of it will give you a clear idea of how popular this programming language is. However, due to the craze of overusing this language to develop smart contracts, many often overlook the underlying issues that Solidity brings. Even now, there are many developers who don’t understand these solidity vulnerabilities and continue to use it as it is, thereby creating major loopholes to exploit.
Here, we will go through the top 10 solidity issues and help you understand how to use this new programming language to your advantage. This article mainly aims to guide developers to prevent them from ever repeating history.
Enroll Now: Ethereum Development Fundamentals Course
What Is Solidity?
Let’s start with the definition of Solidity before moving further into the Solidity issues. Solidity is actually a programming language that is object-oriented and specifically for developing smart contracts. More so, smart contracts are a type of automated contracts within a blockchain environment that governs the behavior of Ethereum accounts and states.
In reality, it’s designed using ECMAScript syntax so that blockchain developers find it familiar to use it. However, it comes with variadic return types and static typing, unlike ECMAScript. But there are certain differences between Solidity and other EVM targeted languages like Mutan and Serpent. In Solidity, you’ll find that it supports arbitrarily hierarchical structs and Mapping. More so, the contracts also use C3 linearization to support multiple inheritances.
Furthermore, it also contains an application binary interface or ABI, which will facilitate type-safe functions for every contract. More so, it also includes “Natural Language Specification”, where a more user-centric description of the contracts is included. As you can see, it’s a very complex type of programming language.
However, it’s not picture perfect. There are certain Solidity vulnerabilities within the functions of this language in the Ethereum blockchain. If you don’t know about them, it will be harder to use this new language. Therefore, we will discuss the solidity issues below in order to educate you about the matter.
Top 10 Solidity Issues
Solidity is a great programming language, and many experts are fascinated with the structure and usage facilities it offers. However, you need to address some certain solidity vulnerabilities before you move to use it for a smart contract.
Please include attribution to 101blockchains.com with this graphic. <a href='https://101blockchains.com/blockchain-infographics/'> <img src='https://101blockchains.com/wp-content/uploads/2021/05/top-10-solidity-issues.png' alt='top 10 solidity issues' border='0' /> </a>
Unchecked External Call
This is a major solidity issue. In reality, you can initiate external calls in Solidity using various methods. The most commonly used function is the transfer function that can send Ether to any external account. But there are other ways to do it as well. For example, you can use the call() and send() function to do it as well. Mainly, developers use the call() function for more versatile external calls.
Unfortunately, the send and call function will only return a Boolean value which will tell you whether the call was successful or not. But if these functions face any exceptions, in which case they can’t perform the task, they only return a false value rather than reverting. So, if you don’t check the return value, you won’t know if the transaction was a success or not. Therefore, most of the time, the developer may just expect to get a revert rather than checking the value.
Thus, it’s completely necessary to check the return value of the unsuccessful transfers.
It’s another major solidity issue that many blockchain developers don’t notice. In reality, Ethereum smart contracts come with a special feature that can call or even use codes from other external contracts. Typically, contracts use Ether and send Ether to other external contract addresses.
However, to perform all of these functions, the contract needs to use an external call. Actually, these external calls don’t have adequate safety features; thus, the hacker can attack these codes and ensure to execute more tasks with the contract calling it. Therefore, the code can re-enter the contract, misuse the information, or even send tokens to other addresses.
In reality, this is exactly what happened in the DAO attack. Mainly this attack can happen when you send Ether to an unknown contract. Here, the attacker can create a malicious program in an external address, and this will introduce the fallback function.
Therefore, when a contract sends any amount of Ether to that address, it will start the malicious program. So, now the vulnerable contract will start to perform functions that the user did not approve of. More so, this program can also recall certain functions to execute the similar transfer of funds over and over again until the user has nothing left.
Watch our on-demand webinar on approaches to overcome issues for enterprise blockchains now!
Costly Loops and Gas Limit
Another solidity is the costly loops problem. As you already know that computational power in the Ethereum blockchain is not for free. You need to pay Ether to buy Gas in order to get the amount of computational power for your transaction to execute. So, if you can somehow reduce the number of computational steps, it will also save time and even save you a lot of money.
Well, adding loops into the program is one way to increasing the costs. In reality, an array already comes with a lot of loops. However, if the elements increase, more integration is required to complete that specific loop. So, if an attacker can include infinite loops, he/she can single-handedly exhaust all available Ethereum Gas.
In this case, the attacker can influence the elements of the array length, which will create a DOS issue and won’t allow the system to jump out of the loop. More so, it will ensure that the contract is stalled as every contract comes with a Gas limit. Even though this solidity issue is not as prominent as other issues, more than 8% of smart contracts seem to have this problem.
Clearing mappings is a huge solidity issue due to having some limitations of this programing language. In reality, the Solidity type mapping offers a key-value data structure, which is storage-only for blockchain platforms. Thus, it will not track all the keys with a value other than zero.
For that, you can’t clean a mapping without adding any extra information. More so, in a dynamic storage array, if you want to use Mapping as the base type, if you delete or even pop the array, that won’t affect the Mapping. More so, if you use Mapping in a struct’s member field as a type in a dynamic storage array, here the Mapping will also be ignored even if you delete the array.
Another one of the issues with Solidity is the floating-point issues. Solidity does not support any floating- or fixed-point numbers even now. Therefore, to represent these floating points, you need to use an integer type in the Solidity. In reality, many developers can make errors or create loopholes if they can’t implement this correctly. Therefore, developers need to implement their very own fixed-point data type using the standard integer data type.
Well, the process is not easy and quite complex and can pose a lot of problems if not pulled off correctly. More so, the 256 bits Ethereum Virtual Machine can create a lot of issues for the data types as types shorter than 32 bytes are assembled together into the 32 bytes slot. Therefore, it affects the precision of any calculations as you can’t expect a proper rounding when you perform any division before multiplication. More so, it won’t allow you to harness the various smart contract use cases for your platform.
There are tons of issues with Solidity, and among them, another issue is unexpected Ether. Usually, when you are sending Ether to an address, it needs to execute the fallback function or other functions needed for the contract. However, there are certain exceptions to these rules. In this case, the Ether can stay in the contract without executing any code. Thus, contracts that rely on programs for every single Ether transaction are vulnerable because it can send Ether forcibly to another contract.
Typically, there are 2 ways one can send Ether forcibly to another contract, and it will not use any payable function for that. These are – Pre-sent Ether and Self-destruct methods. In most cases, the blockchain developers don’t realize that you can accept or even obtain Ether via other means aside from the payable function. Typically, it can lead to contracts having a false Ether balance, and it will lead to vulnerability. It’s best to check the current Ether stored in the contract when before calling any functions.
Here’s a guide to enterprise blockchain risk assessment which will help you assess and mange security risks of your platform.
Relying On tx.origin
tx.origin is another one of the issues with Solidity. This one is a global variable and will scan the call stack and give you the address of the account that sent the transaction. The problem is that if you use this variable for authentication purposes, it can make your smart contracts vulnerable. Therefore, there is a heavy chance that your contract will face a phishing attack. Basically, the attacker can trick the user into using the tx.origin variable to authenticate the attacker to the contract.
Here, the attacker can hide the function withdrawAll() within the tx.origin variable and create a malicious code for the phishable contract. Usually, the attacker will deploy the code and convince the user to send some Ether to this contract. The user will think that it’s a typical authentication contract and will send the Ether to the contract (attackers address disguised within the contract). Thus, once the victim does that, it will invoke a fallback function which will call the withdrawAll() function. As a result, all the funds from the victim will go to the attacker’s address. Thus, users should not depend on tx.origin for authentication purpose only as it’s one of the major blockchain risks.
In Solidity, the functions have visibility to the public unless you are assigning how anyone can call that function. Therefore, the visibility can determine who can call the function – external users, derived contracts, internal users, etc. Typically, there are four types of visibility specifiers. Thus, any function which is default to public viewing can be called by users externally. In reality, many times, the developers tend to use incorrect specifiers, which will severely damage the integrity of the smart contract.
As the default is public, so always make sure to specify the visibility if you want to change it. For example, if you are offering a reward to users who can perform a certain task make sure to keep the visibility of the function private. If it’s public, then any user can just see the function and call it and take the reward without performing any single task. It’s really easy to misuse this type of blockchain security concerns as many newcomers don’t understand the concept fully. Therefore, it can become one of the dangerous solidity security issues if not checked in time.
Overflow and Underflow
Overflow and underflow are one of the prominent solidity security issues at this moment. In reality, Ethereum Virtual Machine can only support a fixed size for integer data types. So, it will mean that blockchain professionals can only use a certain range of number to represent an integer variable. For example, in unit8, you can only store values from [0,255]. So, here, if you want to store 256, you will only get 0 as a result. Thus, using variables in Solidity needs to take precautions as attackers can exploit this issue. Typically, the underflow or overflow issues happen when you are trying to store a value that is out of the data type’s range.
In reality, an underflow issue occurs when you are trying to subtract 1 from a unit8 variable that had 0 as the initial value. In this case, it will only return the number 255. On the other hand, if you are trying to add a value that is larger than the data type’s range will create an overflow issue. So, if you are adding 257 to a unit8 0 value, it will give you a result of 1. Mainly it can create vulnerabilities, and attackers can use it to misuse the code and even create unexpected logic that results in an infinite loop. Let’s check out the next issues with Solidity.
Another one of the major solidity security issues is the timestamp problem. In reality, blockchain timestamps are one of the most important elements in blockchain applications. You can use it for various purposes, for example, locking funds, setting a timer for funds to be released, entropy for numbers, state-changing conditions and so on.
However, a miner has the freedom to change the timestamp, which is risky if they’re using it incorrectly in the smart contract. In times of any rewards, with the use of enough Ether in the contract, the miner can change the timestamp and win the reward along with the pooled Ether. Obviously, it’s not a fair trade.
Now that you know about the top 10 solidity vulnerabilities, you can start your learning process. In reality, Solidity is a fairly new type of programming language, so it’s bound to have some form of issues. However, it’s best to solve or avoid this type of loopholes as they can create vulnerabilities for your contract and platform. The best way to do this is to educate yourself about the ins and outs of Ethereum and how everything works. We recommend starting with our Ethereum development course to learn more about these issues and the probable solutions.