Nine Pitfalls of Ethereum Smart Contracts to Be Avoided:

A Clear Explanation of Vulnerabilities

The Ethereum network was launched in 2015 and remains today one of the most advanced blockchain platforms from the technological point of view. The main advantage of Ethereum lies in the ability for users to create and implement smart contracts for the creation of a wide variety of transactions within the blockchain environment. These smart contracts are the backbone of blockchain growth, but they are not without vulnerabilities. Creating solid, durable smart contracts requires thought, planning and practice and when any one of these elements is missing, smart contracts can open the floodgates for attacks and malicious behaviour on the blockchain.

Key Features of Smart Contracts

Two key features of smart contracts are that there are no standards and that, once they are deployed, they are irrevocable. This means proficiency in developing smart contracts is something that is best learned before the smart contract itself goes on chain. It needs to be clear that poorly developed smart contracts will often function despite flaws and this is the key source of vulnerabilities with smart contracts on the blockchain today.

In this article, we’ll highlight some of the most common vulnerabilities and how they are exploited.

Vulnerability 1: Call to the Unknown

The Call to the Unknown vulnerability arises from the fallback function in Solidity that may cause harm under certain conditions. The fallback function may be invoked when a caller of one smart contract sends a request (an action named a call, delegatecall, send or direct call) that invokes certain functions or transfers ether to another smart contract. The most well known case of a Call to the Unknown vulnerability was when an attacker stole $60M from TheDAO smart contract. Here is an approximation of TheDAO smart contract:

To exploit the fallback function and divert funds, the attacker created a smart contract:

Vulnerability 2: Reentrancy

Reentrancy is another vulnerability that precipitated the above mentioned problem of TheDAO smart contract. The reentrancy vulnerability is consists in the structure of the fallback function allowing an attacker to repeatedly invoke the caller function. As a result the reentrancy vulnerability opens the gateway to loss of gas and funds stored on the smart contract.

Vulnerability 3: Exception Disorder

Exception Disorder is a vulnerability arising in Solidity based smart contracts under several conditions:

when there is a shortage of gas

when encountering a call stack limit

during the execution of a throw command

The manner in which Solidity behaves with exceptions often differs and this is the cause of the exception disorder vulnerability. Because of this vulnerability, Solidity does not check errors of send or call requests and this leads to the reversal of a transaction and gas loss.

For example, let’s assume that there is a transaction which consists of a sequence of several calls. During the execution of this transaction, an exception disorder vulnerability appears and is handled by Solidity as follows:

If every part of the sequence is a direct call, then the execution of the smart contract stops and every effect of the call is reverted. The transaction is voided, but all gas allocated for the transaction is consumed.

If at least one component of a sequence is call, send or delegatecall, the exception disorder spreads along the entire sequence and every effect of the requested contract is reverted until the exception reaches the call request. After this, the execution of the transaction starts again and continues in a loop until all gas allocated by the call request is consumed.

To set the limit on gas allocated to the call request, the following code is useful:

c.call.gas(g)(bytes4(sha3(“ping(uint256)”)),n)

The exception disorder vulnerability may open a window for malicious behavior, as it was in the case of the GovernMental Ponzi scheme. The function of GovernMental is to send a certain amount of ether to a Ponzi scheme smart contract and wait 12 hours. In the event that during this time nobody joins the pyramid, the last contributor is enabled to claim all the funds from the smart contract. The owner of GovernMental smart contract can use the exception disorder vulnerability of the smart contract to avoid paying out the winning sum to its participants.

Vulnerability 4: Gasless Send

The cause of gasless send vulnerability is the out-of-gas exception. This exception appears when transferring ether via the send function to a callee with an expensive fallback function limited to a 2300 unit maximum of gas. In cases where the out-of-gas exception is not handled properly, malicious users can pretend that they have already sent ether to the recipient while actually retaining the amount of send in a wallet. The best example of the gasless send vulnerability is the King of the Ether Throne game. The goal of this game is for users to send a certain amount of ether to the KotET smart contract to become a new king of the throne. One part of the funds sent goes to the smart contract and another part is sent to the previous king as a compensation for disenthronment. The owner of KotET game managed to design the smart contract in such a way that the compensation was not sent to the previous king but was kept by the owner of the game.

Vulnerability 5: Keeping Secrets

This vulnerability emerges when a user tries to conceal some information in a field of a smart contract by marking it as private. To do this, the designer must send a relevant transaction to miners. In line with the transparency of blockchain, the content of such a transaction may be reviewed by any interested person and information in a private field can easily be revealed. To guarantee concealment of information in private fields, it is necessary to apply such cryptographical techniques as timed commitments.

The keeping secrets vulnerability can often be detected in blockchain multiplayer online games. Let us assume that there is a smart contract for an odds and evens game with simplest rules: each of the two players should propose a number and if the sum of this numbers is even, the first players wins and the second loses.

Here is a smart contract for such a game:

The smart contract stores the bets of the participants in a concealed private field named players. To start a game, each player should send 1 ether to the smart contract. As soon as each player joins the game, the smart contract specifies the winner via andTheWinnerIs command and sends 1.8 ether to him. The remaining 0.2 ether is kept as a fee and collected by the owner via the getProfit function.

A malicious user can explain the keeping secrets vulnerability to orchestrate an attack that allows them to always win the game. To do this, th attacker joins the game as the second player and waits until the first player selects a number. Then, the attacker verifies the recently made transaction on blockchain, finds the number selected by the first player and proposes an appropriate number to win the game. This is a warning that the private field isn’t really private to those who know how to perform checks on smart contracts quickly with advanced tools.

Vulnerability 6: Timestamp Dependance

To conduct any operation on blockchain, for example to transfer ether, a smart contract receives a timestamp that specifies the time when the block was generated. If a malicious miner has an interest in executing a smart contract for some attack or scam, he can manipulate the timestamp for the generated block suitable to his own purpose. This timestamp dependence vulnerability was exploited by the owners of the GovernMental pyramid described above. The malicious miner generated a block for his transaction with the modified timestamp that delayed his transaction to be the final one and in this way he won the funds from the smart contract.

Vulnerability 7: Generating Randomness

Many smart contracts, such as those made to create lotteries or online games, generate random numbers to maintain their activity. To generate a random number, it is required to send an appropriate transaction to the blockchain. A malicious miner can exploit this potential to arrange the generated block with a particular transaction that matches the outcome of the randomly generated number and use this technique for his own purposes.

Vulnerability 8: Dangerous DelegateCall

The structure of a delegatecall request is almost the same as the structure of a call request. The only difference between the two is that for delegatecall, the code of the callee address is executed in the same way as the code of the caller contract. So, if the argument of the delegatecall request is set as msg.data, an attacker can create the msg.data with such a function signature so that he can make the victim’s smart contract perform a call for whatever function it provides.

As shown in line 6, the Wallet contract contains a delegatecall with msg.data as its parameter. This gives an attacker the possibility to call any public function of _walletLibrary with the data of Wallet. So the attacker calls the initWallet function (line 10) of the _walletLibrary smart contract and becomes the owner the wallet contract. As the new owner of the wallet contract, the attacker can steal te ether from the victim address. This Dangerous delegatecall vulnerability has already resulted in the loss of over $30 million in crypto funds from blockchain users.

Vulnerability 9: Overflow and Underflow

The counting system in Solidity resembles a mechanical odometer — if you add 1 to the maximum value (256 bits or ²²⁵⁶-1), it will flip over and the result will be 0, a value that will cause an overflow. Also, if you subtract 1 from 0 (the unsigned number in Solidity), the result will flip back and be the maximum value ²²⁵⁶-1, and an underflow will occur.

Both Overflow and Underflow vulnerabilities are quite dangerous, but the case of underflow is more advantageous for an attacker seeking to exploit this feature. For example, exploiting the underflow vulnerability, an attacker can spend more tokens than he has, his balance will reach the maximum value and the values will flip back to the maximum value. For example, when he has 999 tokens and spends 1000 tokens, his balance increases to ²²⁵⁶-1 tokens.

The best way to secure a smart contract against this vulnerability is to use OpenZeppelin’s SaveMath library:

We see that the vulnerabilities of smart contracts are in some cases subtle and in other cases more dangerous if the creator of a smart contract is unaware of the basic structure of blocks and contract limitations. Exploiting these vulnerabilities can lead not only to isolated instances of individuals getting scammed or robbed, but that, as in the case of TheDAO, they can also have global consequences. That’s why it is very important for smart contract creators to pay attention to these vulnerabilities when designing smart contracts — many of these vulnerabilities can be avoided simply by being aware of the way smart contracts work.