Smart Contracts Security: Exploring Common Bugs

The need for secure Smart Contracts becomes increasingly important as the world continues to adopt blockchain technology and decentralized applications.

Smart contracts are digital contracts that automatically enforce the rules and regulations of an agreement. They are at the core of many blockchain-based applications, such as DeFi, NFTs, and more.

However, smart contracts are not immune to vulnerabilities, and hackers can exploit these vulnerabilities to steal funds or compromise the integrity of the network.

As a vulnerability researcher in Web3 security, I have learned various techniques and tools to perform Smart Contract audits and identify vulnerabilities.

In this article, I will share some of these techniques and tools that can help you to find vulnerabilities in smart contracts.

What are Smart Contracts?

Smart contracts are self-executing contracts programmed to perform specific actions automatically when certain conditions are met.

They are used to facilitate transactions without involving intermediaries. Smart contracts are stored on a blockchain network, which makes them decentralized, transparent, and immutable.

Solidity is the programming language used to develop smart contracts on the Ethereum blockchain. It is similar to other programming languages like C++ and JavaScript but has unique features that make it well-suited for smart contract development.

Manual Code Review

One of the most critical steps in auditing Smart contracts is performing a manual code review. This process involves carefully analyzing the code and identifying any potential vulnerabilities. In addition, it is essential to understand the smart contract’s coding language and the platform it runs.

During a manual code review, I typically look for issues such as integer overflow and underflow, re-entrancy attacks, access control vulnerabilities, and logic errors. I also check if the code follows best practices and industry standards.

Automated Scanners

Automated scanners can be an effective tool for identifying known vulnerabilities in smart contracts. Several scanners, such as Mythril, Oyente, and Slither, can automatically detect issues such as re-entrancy attacks, uninitialized variables, and more.

While automated scanners can save time, They can only detect known vulnerabilities and may miss new or undiscovered ones. Therefore, exploring other tools that should be used in a smart contract audit is better.

Fuzzing

It is most exciting to me when vulnerability research involves Fuzzing. Fuzzing is a technique used to find vulnerabilities in software by providing unexpected inputs to a program and observing its behavior. This technique can also be applied to smart contracts by providing unexpected inputs to the contract and observing its execution.

Fuzzing can be an effective way to identify vulnerabilities such as buffer overflows and other unexpected behaviors. However, it requires a deep understanding of the contract’s functionality and the ability to create effective inputs.

Formal Verification

Formal verification is a process of mathematically proving that a program or system meets certain specifications. It involves using logic and mathematics for reasoning about the correctness of the code.

Formal verification can be a powerful tool for smart contract audits, as it can provide a high degree of confidence that the contract behaves as intended. However, it requires a significant amount of expertise and can be time-consuming.

Threat Modeling

Threat modeling is a process of identifying potential threats to a system and determining the impact of those threats.

It involves analyzing the system architecture and identifying potential attack vectors.

Threat modeling can effectively identify vulnerabilities in a smart contract by considering the potential threats and the likelihood of those threats being exploited. It can also help prioritize vulnerabilities based on their impact.

Exploring Common Bugs

Reentrancy Vulnerability

One common Solidity bug is the Reentrancy Vulnerability. In smart contracts, re-entrancy attacks occur when a contract is called multiple times before the initial call is completed.

The DAO hack in 2016 is one of the most famous examples of a Reentrancy Vulnerability, which resulted in the theft of over $50 million worth of Ether.

This can allow an attacker to repeatedly execute a function, drain funds, or exploit other vulnerabilities.

This code snippet demonstrates a re-entrancy vulnerability:

contract Reentrancy {
    mapping(address => uint256) public balances;

    function withdraw(uint256 amount) public {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");
    }
}

In this code, an attacker can call the withdraw function and then immediately call it again before the initial call has been completed, causing the balance to be deducted multiple times.

This can cause unexpected behavior and enable attackers to drain funds or perform other malicious actions.

Integer Overflow and Underflow Vulnerability

Another common Solidity bug is the Integer Overflow and Underflow Vulnerability. Integer overflow and underflow are common vulnerabilities in smart contracts that occur when an arithmetic operation results in a value that is too large or too small to be represented by the variable type.

This can cause unexpected behavior and lead to security vulnerabilities. Sometimes, this can allow an attacker to gain unauthorized access or perform other malicious actions. For example, in the batchOverflow vulnerability discovered in 2018, an attacker could generate large numbers of tokens by exploiting an integer overflow vulnerability in the smart contract.

This code snippet demonstrates an integer overflow vulnerability:

contract IntegerOverflow {
    uint256 public balance;

    function deposit(uint256 amount) public {
        balance += amount;
    }
}

In this code, if the amount variable is set to a large enough value, it could cause an integer overflow, resulting in the balance variable being assigned to an unexpected value.

Access Control Vulnerabilities

Access control vulnerabilities are a common type of vulnerability in smart contracts that occurs when there is a failure to control access to sensitive functions or data properly.

This can allow an attacker to perform unauthorized actions or access sensitive information. This code snippet demonstrates an access control vulnerability:

contract AccessControl {
    address public owner;

    function changeOwner(address newOwner) public {
        require(msg.sender == owner, "Unauthorized");
        owner = newOwner;
    }
}

In this code, the changeOwner function can only be called by the current owner, but there is no mechanism to prevent the owner from being changed to an unauthorized address.

Time-Dependent vulnerability

There is another bug that is common to solidity called the Time-Dependent vulnerability. Time-dependent vulnerabilities occur when a contract’s behavior or state changes depending on the current time or block number. This occurs when a smart contract relies on a timestamp to execute certain functions or unlock certain features.

By manipulating the contract’s state or behavior at specific times, attackers can exploit these vulnerabilities. If an attacker can manipulate the timestamp, they may be able to gain unauthorized access or perform other malicious actions.

The Parity Wallet hack in 2017 is an example of a Time-Dependent Vulnerability, which resulted in the loss of over $30 million worth of Ether. This code snippet demonstrates a Time-Dependent vulnerability:

contract Vulnerable {
    uint public unlockTime;

    function withdraw() public {
        require(block.timestamp >= unlockTime);
        // withdraw funds
    }
}

In this example, the withdraw function allows users to withdraw funds after a certain time has passed, as specified by the unlockTime variable. However, an attacker can manipulate the contract’s state by changing the system time on their device and withdrawing funds before the unlockTime.

Misuse of external contract calls

Misuse of external contract calls occurs when a contract calls an external contract without properly verifying the contract’s behavior or state. When external calls are not implemented carefully, they can lead to severe vulnerabilities.

This code snippet demonstrates the Misuse of external contract calls:

contract Vulnerable {
    function transfer(address payable recipient, uint amount) public {
        require(recipient != address(this));
        recipient.transfer(amount);
    }
}

In this example, the transfer function allows users to transfer funds to an external contract. However, it doesn’t verify the behavior or state of the external contract before transferring the funds.

An attacker can create a malicious contract that reverts or performs unexpected behavior when receiving funds, causing unexpected behavior in the original contract.

Conclusion

In conclusion, Smart contract audits are essential to ensure the security of blockchain-based applications. Solidity is a powerful programming language for smart contract development but is also prone to certain bugs and vulnerabilities.

A successful Smart contract audit requires a combination of manual code review, automated scanners, Fuzzing, formal verification, and threat modeling.

Smart contract auditors should carefully review the code and test different scenarios to identify and mitigate these vulnerabilities. It’s also important to stay up-to-date with the latest vulnerabilities and techniques attackers use to identify and exploit vulnerabilities in smart contracts.

Related Posts

Static Code Analysis for PHP: Finding Bugs Quickly and Accurately

PHP is one of the web’s most widely used server-side scripting languages. It is a popular choice for building dynamic web applications because of its ease of use, flexibility, and speed.

Read more

Building Better ROP Chains for Windows: A Guide to Good Gadgets

Return-Oriented Programming (ROP) is a technique used to bypass security mechanisms in modern operating systems by chaining together small code sequences called “gadgets” already present in the program’s memory.

Read more

Springboot Security: The Secret Gold Mine

What is Spring Framework? The Spring Framework (Spring) is an open-source application framework that provides infrastructure support for developing Java applications.

Read more