9 Most Common Smart Contract Vulnerabilities Found By Blaize
Smart contracts are specialized programs stored on a blockchain typically used to automate the execution of an agreement so that all parties can be certain of the outcome without the need to trust one another or any intermediaries. A smart contract guarantees that its execution will correspond exactly to the logic that was originally written in it. And after the execution of said predetermined logic, the final state on the network will stay immutable.
But unfortunately, the correct execution of the smart contract code cannot guarantee its complete safety. In fact, analysis of existing smart contracts shows that a significant part of them are indeed vulnerable. In this article, we will talk about the most common smart contract security issues and weaknesses and the ways to deal with them to boost the security of your protocol.
Here at Blaize, we have been dealing with vulnerabilities and preventing smart contract exploits for over five years. During this time, we’ve deployed 400+ smart contracts and audited 120+ more for such well-known companies as 1inch, PEAKDEFI, and Aurora. Our professional audits have saved our customers over $100M from potential hacker attacks.
HOW SMART CONTRACT VULNERABILITIES AFFECT USERS
Money loss is undoubtedly the most visible consequence of a hack since it’s easy to calculate how much the protocol and its users have lost. However, another less obvious but, at times, much more impactful effect of any exploit is loss of credibility.
All smart contracts security vulnerabilities eventually lead to exploits, which negatively affects the reputation of the protocol, its owners, and the project team. Moreover, it lowers the overall level of trust to the industry, creating more concern and doubt.
That’s why it is essential to take good care of smart contract security. And one of the crucial steps in doing so is a security audit. A proper security audit done by a reputable, experienced company will allow you to detect any possible risks and vulnerabilities in your smart contracts and efficiently eliminate them. Thus, you will boost the security of your protocol and prevent potential exploits.
Smart contracts vulnerabilities
Vulnerabilities in smart contracts are serious enough for several reasons:
- Most of the smart contracts deal with financial assets.
- Errors in smart contracts, once published, cannot be corrected due to the immutable nature of the blockchain.
- Changes in blockchain’s state generated by transactions of faulty or fraudulent contracts cannot be rolled back.
We are sure that you understand all the risks associated with bugs and other smart contract vulnerabilities, considering the unsettling statistics of recent years.
In Q1 2022 alone, the DeFi industry lost over $1.6B due to exploits, surpassing the total amount stolen in 2020 and 2021 combined. Some of the protocols got hacked because of a simple code error, others – due to inefficient contract logic or incorrect calculations.
Find out more about DeFi security in our article: How to Prevent Your DeFi Project From Hacking.
As we have mentioned before, any smart contract vulnerability can be detected by an experienced team during a smart contract audit. Here’s a brief list of the most common risks Blaize experts check the protocol for:
- unsafe type inference;
- timestamp dependence;
- implicit visibility level;
- gas limit and loops;
- transaction-ordering dependence;
- unchecked external call – unchecked math;
- DoS with block gas limit;
- DoS with (unexpected) throw;
- byte array vulnerabilities;
- malicious libraries;
- style guide violation;
- ERC20 API violation;
- uninitialized state/storage/local variables;
- compile version not fixed.
Below, we’ll elaborate on the several most widespread issues with smart contracts that our team encounters while conducting smart contract security audits.
See the full list of smart contract security services on the Blaize.Security webpage.
THE LIST OF THE MOST COMMON SMART CONTRACT SECURITY ISSUES
01. Indirect execution of unknown code
The possibility of indirect execution is there due to the presence of the fallback function feature in smart contracts. There are several reasons why this function can be called:
- Calling a function of another contract using ABI. If there is a typo in the signature string passed for encoding, or a function with such a signature does not exist, then the fallback function will be called.
- Deposit to another contract generates a call to its fallback function.
- Calling a function of another contract using the API. If the developer makes a mistake when declaring the interface of the called contract (for example, mixes up the type of a parameter), the fallback function will be called.
Reentrancy is one of the common Ethereum smart contract vulnerabilities.
The thing is that in Ethereum, calls to functions of other smart contracts occur synchronously. That is, the calling code waits for the end of the execution of the external method before continuing its own work. This can cause the called contract to use the intermediate state of the calling contract.
This situation is not always obvious during the development process if all the possible fraudulent actions on the part of the called contract are not taken into account.
Let’s consider the following example.
Suppose there is a vulnerable contract that tops up the balance of the caller by 10 Gwei one time and writes its address into a variable to avoid double-spending. At each next call, the contract checks whether the balance has been topped up at this address earlier, in which case another deposit does not occur.
In order to steal all the Gwei available on this contract, one should simply re-enter the pay function before the address is written into the variable. Since the call function is used for deposit, re-entry can be performed by writing the appropriate logic in the fallback function of the fraudulent contract.
For a successful attack, the malefactor needs to place such a contract on the network and call the pay function of the vulnerable contract, passing the address of the fraudulent contract as an argument.
Read also: Basics of Liquidity Vampire Attacks.
03. Incorrect calculation of the output token amount
Another smart contract weakness can be found in some modern DeFi smart contracts that deal with enormous amounts of money depicted in tokens or ETH value.
In such protocols, a lot of operations in contract logic are connected with tokens’ transfers to and from the contract. It creates a wide field for different mistakes connected to correct percentages, fees, and profits calculations.
The most common errors include the following:
- incorrect decimals handling, especially when dealing with such a token as USDT;
- incorrect order of operation during fees calculations, which leads to a significant accuracy loss;
- the accuracy constant that was actually forgotten in the math operations.
All these errors lead to the loss of user funds or even tokens locked forever. Thus, one of the tasks of the contracts’ auditor is to check the correctness of the math operation. Such checks are also implemented in the most modern automated tools and static analyzers.
04. Interface/naming issues
An example of these smart contract risks is the Rubixi smart contract.
Rubixi was a Ponzi game, in which the owner could transfer the fees accumulated in the financial pyramid to themselves.
Usually, the owner is set in the constructor of the contract, which is called when it is created. The same logic was implemented in the Rubixi’s smart contract.
It should be noted that in the Solidity versions prior to 0.4.22, constructors were defined as functions with the same name as the name of the contract. At some point, the contract was renamed from Dynamic Pyramid to Rubixi, but the developer forgot to change the name of the constructor. This way, anyone who called the Dynamic Pyramid function could become the owner of a contract and steal the accumulated funds.
05. Dependency on the order of execution
The state of the contract is determined by the values of its variables, which are changed by calling its functions. Calling a smart contract function is the same transaction as a transaction of ETH or ERC-20 token transfer. These transactions are finalized by the network only after the next block creation is complete.
Thus, when the user sends a transaction to call a contract function, they cannot be sure that the transaction will be executed in the same state of the contract in which it was at the time of sending. This can happen because other transactions in the same block have changed the state of the contract.
Moreover, miners have some freedom in ordering transactions when forming a block, as well as in choosing to include a particular transaction in a block. In some cases, the impossibility of determining the state of the contract, in which the transaction will be executed, can cause another smart contract weakness.
It also becomes especially dangerous to interact with contracts written in such a way that their behavior can be changed over time.
06. Time component
Sometimes, the logic of smart contracts can be time-dependent. The time for a contract is only available in the context of a transaction. The timestamp of a transaction, in turn, is equal to the label of the block that it is included in. Thus, consistency with the state of a smart contract is achieved.
However, this also creates an opportunity for the miner to abuse their position due to some freedom in setting a timestamp for the block. So, the miner has some advantage over other parties to a contract that they could exploit to their own benefit.
07. Using the blockhash function
Using the blockhash function is a way of hacking smart contracts similar to the timestamp dependency. It is not recommended to use it for important components for the same reason as the timestamp dependency because miners can manipulate these functions and change the withdrawal of funds in their own favor. This is especially noticeable when the block hash is used as a source of randomness.
08. Incorrectly handled exceptions
There are many situations where an exception can be thrown in Solidity, but the way these exceptions are handled is not always the same. Exception handling is based on interactions between contracts. Thus, contracts are vulnerable to attacks from malicious users, and if these exceptions are not handled properly, transactions will be rolled back.
09. Incorrect work with ERC20 token
There is a well-known OpenZeppelin implementation of the ERC-20 token that is overused in modern protocols. In most cases, it is completely applicable, and its functionality is enough for correct financial operations. Yet, there is a place for custom implementations of a token standard. Thus, it creates a place for discrepancies between the newly created token and actual ERC20 standard – small inconsistencies like missing return value in transfer() function.
Even though such errors might be very small, they may lead to the non-functional method of the contract since it will not be able to recognize the interface. It is a tiny mistake, almost not noticeable during testing, but in production, it leads to stuck funds and blocked contracts.
BLAIZE.TECH EXPERIENCE DEALING WITH SMART CONTRACT VULNERABILITIES
Over the course of the last 5 years, the Blaize team has conducted over 120 audits and found 250+ vulnerabilities in 500K+ lines of code. We also specialise in NFT development. Our efforts have saved protocols over $100M that would be potentially lost due to hacker attacks.
Unfortunately, we cannot publish all our cases due to client’s privacy, but you can still see multiple case studies on our website. Make sure to look them through – you’ll find a few familiar names (including Aurora, 1inch, Solana, Celo, Tron, etc.).
THE BOTTOM LINE
Writing a completely secure smart contract is a complex and painstaking task. Yet, however perfect the contract may seem, it still requires a thorough security audit before being published on the network.
The reason for that is many smart contract vulnerabilities that can be easily overseen even by experienced developers. Yet, even minor bugs may lead to massive protocol exploits and money loss. That is why we highly recommend you conduct at least two smart contract audits to boost your protocol security and prevent potential hacks.
If you are looking for a reputable auditor, let’s work together! Blaize experts have done over 120 smart contract audits. We have found 250+ vulnerabilities and saved over $100M for such well-known projects as 1inch, PEAKDEFI, and Aurora. Let’s build secure projects together!
What are the most common smart contract security vulnerabilities?
The most common smart contract weaknesses include unsafe type inference, timestamp dependency, reentrancy, implicit visibility level, gas limit and loops, and much more. See the full list in the article above.
How do I boost the security of my smart contracts?
To boost your protocol security, we highly recommend you hire a reputable team of auditors to conduct a smart contract audit. This way, you’ll be able to find vulnerabilities in smart contracts and eliminate them before deploying the contract, thus, preventing a potential hack.
What is a smart contract audit?
A smart contract audit is a thorough analysis of the protocol’s smart contracts in order to find and eliminate any potential threats and vulnerabilities. A proper audit should include not only automatic testing but also manual testing, business logic review, a detailed review of the code against all known vulnerabilities, comprehensive recommendations on how to eliminate bugs and vulnerabilities, and much more.
How can I find security vulnerabilities in Ethereum smart contracts?
You should hire reputable contractors to conduct a couple of smart contract security audits. As a result, you will get a report containing all detected vulnerabilities and recommendations on how to eliminate them.
How to eliminate all smart contract vulnerabilities?
When hiring an experienced team of smart contract auditors, you get an elaborate report containing all detected vulnerabilities and recommendations on their elimination.