Smart contract attacks usually exploit a vulnerability in a smart contract source code which leads to some serious financial losses. Therefore, ensuring that the smart contract is clean from any ...
The only things that truly do not change in a smart contract even with proxies concepts are state variables. However, not carefully using them in a smart contract could lead to some serious vulnerabilities. One of those vulnerabilities is called state variables shadowing. Therefore, what is smart contract shadowing state variables vulnerability?
Smart contract shadowing state variables vulnerability happens when the same variable is declared in two places in the contract. This behavior results in important data alteration which could have a dangerous impact on the business logic. This vulnerability only exists in older versions of solidity built using compiler versions lower than 0.6.0.
In this blog post, I am going to explain in detail and with technical examples why this vulnerability exists and what its impact is. In addition, I am going to explain how you can detect it in your code and how to prevent it. So, if you are interested, just keep reading.
Smart contract shadowing state variables vulnerability happens when the same variable is declared in two places in the contract. Here is an example to better understand this vulnerability:
As you can see ParentContract has a declared variable called var1 and ChildContract has also the same variable declared but with a different initial value. As ChildContract inherits from ParentContract, you will be able to call the add() function to increment the var1 variable. However, the question that you may ask at this level is what var1 variable would be used?
The answer to this question is var1 declared in the ParentContract. Therefore, in complex smart contracts, this behavior may not be noticed which may result in some serious financial losses. What makes this vulnerability really very dangerous is that it cannot be fixed even with proxies, once the contract is deployed and stat variables declared the only way to fix this issue is by performing a social migration.
With a newer version of solidity compilers, it is really difficult to find a vulnerable contract as the compiling process fails once it detects this kind of vulnerability.
Let’s take a look at the following smart contract:
This example was taken from the swcregistry.
If you take a look at the hardcap variable in the tokensale smart contract, you will see that it was declared with 10000 ether. However, the same variable was also declared in the Presale smart contract with 1000 ether. Moreover, Presale inherits from Tokensale. Therefore, the call to fetchCap() function in Tokensale smart contract will retrieve 10000 ether rather than the supposed 1000 ether.
Depending on the context in which this smart contract was used, this behavior may cause financial losses to the smart contract owners.
The impact of this vulnerability depends on where the shadowed variable is used. It is really difficult to correctly estimate the impact of this vulnerability if you don’t have a global view of where this variable is used in the smart contract and its inheritance.
However, usually, this type of vulnerability could lead to either financial losses or even in some cases full control of the smart contract.
Smart contract shadowing state variables vulnerabilities is one of the most dangerous vulnerabilities as it is very hard to detect them. This is actually because declaring two variables with the same name as described in this blog post is considered normal in older versions of solidity and it is actually. The only problem here is that developers need to be very careful of what they are doing with it.
However, to detect this vulnerability you can either use automated tools like those described in this blog post or try to perform a manual code review.
Detecting the shadowing state variable using the manual analysis is pretty simple, all you need to do is to look for variables with the same name. Then try to see if those vulnerabilities are declared in smart contracts that inherit from each other.
Once those variables are identified you should work closely with the developer to see if the second declaration of those variables is intended for some reason or made unconsciously. If it was not supposed to be there then you should investigate further to see if this declaration has an impact on the smart contract business logic.
Usually, having two variables declared with the same name, will have an impact on the business logic. All you need to do is to find where.
To prevent the smart contract shadowing state variables vulnerability, developers should avoid using the same name for two different variables. However, the easiest way to prevent this vulnerability is to use solidity compilers that are higher than 0.6.0.
Compilers higher than 0.6.0 are able to detect this vulnerability and stop compilation. This actually avoids the deployment of vulnerable contracts from the beginning.
We will work on the same example presented in the previous section, and try to fix the already spotted vulnerability.
Vulnerable smart contract:
As I said in the previous sections the hardcap second declaration is what creates the shadowing state variable vulnerability. Therefore, to fix this smart contract all we need to do is to remove that and put it in the constructor without declaring the variable once again. Or, if the existence of a second variable is needed, then we should rename that variable.
Here is the fixed version of that contract:
As you can see the hardcap variable was reinitiated in the constructor. Doing so will change the value of the variable declared in Tokensale.
Due to the improvement of the solidity compilers, developers are able to detect this kind of vulnerability early during the compilation phase. Therefore, newly developed smart contracts cannot be vulnerable to this type of vulnerability. However, shadowing state variables vulnerability still exists in the smart contract as many of them are developed and deployed with older versions of solidity.
In addition, the immunity aspect of smart contracts results in keeping smart contracts deployed in the Blockchain vulnerable forever.
Written by: Z. Oualid
I am a Cyber Security Expert, I have worked with many companies around the globe to secure their applications and their networks. I am certified OSCP and OSCE which are the most recognized and hard technical certifications in the industry of cybersecurity. I am also a Certifed Ethical hacker (CEH). I hope you enjoy my articles :).
In the intricate landscape of cybersecurity, understanding the concept of malware artifacts is paramount for safeguarding digital environments. All malwares has their own digitale signature that is represented by their [...]