• Tuyet Duong, PhD

Smart Contract Security Pitfalls Across Multiple Blockchain Ecosystems

A Bitcoin and an Ethereum coin side by side in front of an analysis on a computer screen

With the increasing popularity of crypto and blockchain, more and more capital from both retail and institutional investors is being invested into crypto. Even during the current ‘crypto winter’ of 2022, the total value locked in Defi (Decentralized Finance) is 83.43B at the time of writing this post (down from 240B in Dec 2021). Regardless, this still represents a lot of money at risk of loss if not properly protected. But – can smart contracts be hacked? Unfortunately, yes. Smart contract disadvantages like this do exist. This risk has been unfortunately realized in the many cryptocurrency hacks transpiring in the past few years.

Top 10 Most Recent Cryptocurrency Hacks

The biggest crypto hack to date was the Ronin Network hack in which the attacker stole $624M from the network. Worth noting, the Ronin Network was not audited prior to the hack. Almost all of the top-10 crypto hacks on the rekt’s board were not audited prior to being hacked. Moreover, even if they are audited by reputable auditing firms, this does not mean that there are no vulnerabilities missed during the limited-time audit period or that there will not be vulnerabilities introduced in future updates/commits.

Top 6 Most Common Smart Contract Security Pitfalls

To that effect, we developed a general list of common smart contract security pitfalls based on our experience working across chains such as Solana, Ethereum, Cardano, Algorand, Cosmos (and many more) as well as multiple NFT marketplaces.

1. Lack of input validations

Input validation is crucial to smart contracts and a lot of exploits were only possible because of missing just one single input check. Specifically, input validations are of significant importance to blockchains such as Solana or Algorand. In Solana, input read-only accounts should always be verified because Solana runtime only ensures that read-only accounts are not modified but it does not enforce account authenticity. It is trivial for a malicious user to create accounts with arbitrary data and then pass these accounts to the program in place of valid accounts.

For example, this checks whether the input token program account is the expected account: token_program_info.key != spl_token::id() makes sure that no users can pass a fake token program which will be authorized and called later on by the caller program/smart contract.

  if *token_program_info.key != spl_token::id() {
           "Only the SPL token program is currently supported, expected {}, received {}",
       return Err(ProgramError::IncorrectProgramId);

In Algorand, TEAL code should validate as many transaction fields as possible. Things not checked could become set to anything. For example, contracts should always verify that the received asset is the expected one whether it is ALGO (the native token) or ASA (Algorand Standard Assets) via txn.type_enum().

Example hack: Tinyman hack

Tinyman is a decentralized trading protocol utilizing the fast and secure framework of Algorand and it was exploited for $3M in Jan 2022. This attack was possible solely because of missing asset type checks. “In a burn operation, the type of the fourth transaction in the transaction group and the asset IDs supplied in the third and fourth transactions of the group were not checked to ensure that they had the expected values.”

2. Authorization and authentication Issues

Authorization and authentication are still often misunderstood and confused - authentication and authorization not only sound and look similar but are also closely related.

  • Authentication is about proving your identity. This could mean entering a username and password or providing a signature.

For example, it is recommended to not use the tx.origin for authentication purposes in Ethereum. tx.origin returns address which initiated the current transaction. Using the variable for authorization could make a contract vulnerable if an authorized account calls into a malicious contract. On the other hand msg.sender returns the address which originated the current message call and should be used instead.

Authorization is about checking if you have the right permissions. Once you are authenticated, the application should verify if you are allowed to access a specific resource or operation, typically based on your role in the application.

Authorization is especially important to cross-chain bridges. A cross-chain bridge or a blockchain bridge enables the transfer of tokens, assets, smart contract instructions, or data between blockchains. There are privileged roles and smart contracts that can trigger transfers of different assets. The authorization privileges must be modeled properly to ensure the security of blockchain bridges.

Example hack: Poly Network hack

The Poly Network exploit was an attack conducted by anonymous hackers on August 10, 2021. The attack transferred over $610M in digital cryptocurrency to be transferred to the hackers. According to cybersecurity firm SlowMist, the hack was made possible by a mismanagement of the access rights between two important Poly smart contracts: EthCrossChainManager and EthCrossChainData. In this case, this event did not occur due to the leakage of the keeper’s private key.

3. Arithmetic errors

Arithmetic errors are often overlooked and ignored but these types of errors can lead to severe exploits such as loss of funds. Due to the lack of floating point support, smart contracts generally represent values as integers. What many developers do not seem to appreciate is the lack of precision when integer arithmetic is performed incorrectly. For example, multiply_ratio function from cosmoswasm_sdk rounds decimal numbers down and lose precision in the process; therefore, developers should not assume that (B / C) * D == (B * D/ C) .

Example hack: Solana Spl-token-lending program bug

In December 2021, Neodyme team disclosed a critical bug in the token-lending contract of the Solana Program Library (SPL) and the total TVL at risk was about $2.6B. This is an arithmetic bug where the program rounds up the number of exchange tokens. As a result, users can get more tokens than they should have. This was overlooked and ignored initially because it is not worth the effort to attack as “whoever exploits this will have paid 5000 times as much for the transaction fee.” However, it turned out that the attacker can gain a significant amount of high value currencies like Bitcoin.

4. Blockchain- or language-specific vulnerabilities

There is also a class of vulnerabilities that only exist on a particular blockchain or programming language. For example, a reentrancy attack is one of the most destructive attacks on Ethereum. A reentrancy attack occurs when a function makes an external call to another untrusted contract. Then the untrusted contract makes a recursive call back to the original function before the original function execution is able to complete. Here is an example of the reentrancy vulnerability.

  mapping (address => uint) private userBalances;
    function withdrawBalance() public {
        uint amountToWithdraw = userBalances[msg.sender];
        (bool success, ) = msg.sender.call.value(amountToWithdraw)(""); // At this point, the caller's code is executed, and can call withdrawBalance again
        userBalances[msg.sender] = 0;

Other blockchains eliminated this type of vulnerability from the core layer. For example, external calls to other contracts can only be executed after the caller contract has finished in cosmoswasm, or reentrancy is limited to direct self recursion, capped at a fixed depth in Solana.

For programing language specific vulnerabilities, Rust (in release mode) and Solidity do not prevent Integer overflow/underflow. If overflow occurs, Rust performs two’s complement wrapping. Values greater than the maximum value the type can hold “wrap around” to the minimum of the values the type can hold. In the case of a u8, the value 256 becomes 0, the value 257 becomes 1, and so on.

Example hack: The DAO hack

The DAO was a popular decentralized investment fund based on smart contracts. After raising $150 million worth of Ether (ETH) through a token sale in 2016, the DAO was hacked due to the reentrancy vulnerability. In the first few hours of the attack, 3.6 million ETH were stolen (the equivalent of $70 million at the time). The Ethereum blockchain decided to hard fork to restore the stolen funds but not all parties agreed with this decision, which resulted in the network splitting into two distinct blockchains: Ethereum and Ethereum Classic.

5. Logic errors

This vulnerability is about application specific errors and can occur in any of the blockchains out there today. This includes but is not limited to:

  • Incorrect/faulty formulas

  • Incorrect checks

  • Design errors

Developers often assume things happen in a certain way, but in reality it may not follow those assumptions and lead to vulnerabilities. This kind of vulnerability is often the result of a very quick development process for complex smart contracts with a lot of changes and updates.

Example hack: Port Finance bug

In March 2022, a whitehat reported a critical vulnerability in Port Finance via Immunefi. The total value at risk was about $20M–$25M. This is a logic vulnerability in which the designed withdrawal formula is faulty. More specifically, the maximum withdrawal amount is bound by the total user deposit value to multiple reserve pools instead of the deposit to the reserve corresponding to the withdrawn collateral. Thus, malicious users can drain their token deposit to the pool with a high liquidation bonus_rate before they pay off their borrow in full.

6. Third-party vulnerabilities

Vulnerabilities in third-party applications/services are also common and often overlooked. For example, oracles are third-party service providers that supply blockchains with external or real-world data such as price feeds, statistics, etc. Price feeds are by far the most exploited oracle data since they allow attackers to steal millions of funds from DeFi platforms.

Example hack: Mirror Protocol Exploit

Mirror is a DeFi protocol powered by smart contracts on the Terra Classic chain that enables the creation of synthetic assets called Mirrored Assets (mAssets). An exploit on Mirror Protocol led by a bug in the LUNC pricing oracle resulted in a loss of at least $2 million. The hack was possible due to an error in the configuration of price oracles. The oracles were reporting the price of the new Terra 2.0 $LUNA coin (~$9.80) instead of the original Terra Classic $LUNC coin (~$0.0001).

Control Smart Contract Security Pitfalls with FYEO

Blockchain and Crypto are becoming increasingly popular in the last few years. However, these blockchain projects are often developed very quickly with minimum to no consideration for security. This often leads to hundreds of million-dollar hacks. Blockchain security is still in its early state and needs more attention and research as these systems become more interconnected and complex. Thus, blockchain security should be an ongoing process and considered during the entire design and development of every smart contract.