Many vulnerabilities in smart contracts were surprising and there is no reason to believe that there will not be further exploits. As long as investors decide to invest large sums of money in complex, but poorly tested code, we will continue to see new incidents with devastating consequences. Methods for the formal verification of smart contracts are not yet mature. As new classes of vulnerabilities continue to be found, developers need to stay up to date and new tools need to be developed to find them. These top 10 are likely to evolve rapidly until Smart Contracts have reached a level of stability.
The reentrancy attack occurs when external calls to a contract are allowed to make new calls to the source contract before the first execution is completed. For a function, this means that the contract status can change in the middle of execution by calling an untrusted contract or using a low-level function with an external address.
As a rule, one accesses the functionality of a contract via its public or external functions. While insecure visibility settings offer attackers simple ways to access the private values or logic of a contract, access restrictions are sometimes more subtle. These vulnerabilities can occur when contracts use the obsolete tx.origin to validate the user.
Integer overflows and underflows are not a new class of vulnerabilities, but they are particularly dangerous in smart contracts where unsigned integers are common and most developers are used to simple int types (which are often just signed integers).
One of the deeper features of Solidity are the low-level functions call(), callcode(), delegatecall() and send(). Their error detection behavior differs significantly from other solidity functions in that they do not propagate (or flash) and do not completely reverse the current execution. Instead, they return a Boolean value set to false, and the code continues to execute. If the return value of such low-level calls is not checked, it can lead to failures and other unwanted results.
While other types of applications can eventually recover, a single attack can put smart contracts offline forever. Many paths lead to denials of service, including malicious behavior as the recipient of a transaction, artificially increasing the gas required to calculate a function, abusing access controls to access private components of smart contracts, and the use of mix-ups. This attack class comprises many different variants and is likely to evolve strongly in the coming years.
Randomness is difficult to achieve in Ethereum. While Solidity provides functions and variables that can access seemingly unpredictable values, they are usually either more public than they appear or exposed to the influence of miners. Because this source of randomness is predictable to some extent, malicious users can generally replicate it and attack the function based on its unpredictability.
Because Miners are always rewarded with gas fees for executing code on behalf of external addresses (EOA), users can set higher fees to validate their transactions faster. Because the Ethereum blockchain is public, anyone can see the content of other people's outstanding transactions. This means that if a particular user reveals the solution to a puzzle or other valuable secret, a malicious user can steal the solution and copy his transaction with higher fees to prevent the original solution. If Smart Contracts developers are not careful, this situation can lead to practical and devastating front attacks.
From the blocking of a token sale to the release of funds at a certain point in time for a game, smart contracts sometimes have to rely on the current time. This is usually done via block.timestamp or its alias in solidarity. Since the miner of a transaction has a certain amount of leeway in reporting the time of dismantling, good smart contracts avoid relying heavily on the announced time. Note that block.timestamp is also sometimes (incorrectly) used to generate random numbers, as described in 6).
Short address attacks are a side effect because the EVM itself accepts wrong padding. Attackers can exploit this by using specially designed addresses to get poorly encoded clients to miscode arguments before including them in transactions. Although this vulnerability has not yet been exploited, it is good evidence of problems arising from the interaction between clients and the Ethereum blockchain.
Ethereum is still in its infancy. The main language for the development of Smart Contracts, Solidity, has yet to reach a stable version, and the tools of the ecosystem are still experimental, so our expertise and experience in testing is particularly important.