Open In App

Reentrancy Attack in Smart Contracts

Improve
Improve
Like Article
Like
Save
Share
Report

Reentrancy attack in solidity repeatedly withdraws funds from the smart contract and transfers them. The article focuses on discussing Reentrancy Attacks in Smart Contracts. It occurs when a function makes an external call to another untrusted contract. The article focuses on discussing reentrancy attacks in smart contracts.

The following topics will be discussed here:

  1. What is a Reentrancy Attack?
  2. Example of Reentrancy Attack
  3. How Does Reentrancy Attack Work?
  4. Types of Reentrancy Attack
  5. Reentrancy Smart Contract Attack Examples
  6. Is the Reentrancy Attack Still a Significant Problem?
  7. How to Protect Smart Contracts Against a Reentrancy Attack?

Let’s start discussing each of these topics in detail.

What is a Reentrancy Attack?

Reentrancy is a type of attack that can occur in smart contracts that allow untrusted external code to be executed within the contract. This can happen when a smart contract calls an external contract, and the external contract then calls back into the original contract, potentially causing an infinite loop. A reentrancy attack is a method of exploiting a vulnerability in a smart contract that allows an attacker to repeatedly call a function in the contract, causing an infinite loop and potentially stealing funds.

  • A simple example of a reentrancy attack is a contract that allows users to deposit funds and then withdraw those funds later. Suppose the contract does not properly check for reentrancy. In that case, an attacker could call the deposit function multiple times in a row before calling the withdraw function, effectively stealing funds from the contract.
  • One way to prevent reentrancy attacks is to use a mutex, or mutual exclusion, lock to prevent multiple calls to the same function from occurring at the same time. Another way is to use a guard condition, where a flag is set before external function calls and checked after.

Example of a Reentrancy Attack

The standard reentrancy attack is where an attacker repeatedly calls a function in a contract, causing an infinite loop and potentially stealing funds. A user interacts with the Vulnerable Smart Contract to deposit funds. 

  • The Malicious Contract then repeatedly calls the deposit function of the Vulnerable Smart Contract, depositing funds into the attacker’s own account. 
  • The Malicious Contract then calls the withdraw function of the Vulnerable Smart Contract, withdrawing the deposited funds.
  • Because the deposit function of the Vulnerable Smart Contract is not properly protected against reentrancy, the attacker is able to repeatedly call the deposit function before calling the withdraw function, effectively stealing funds from the contract.

How Does Reentrancy Attack Work?

Below is an example to explain the working of a reentrancy attack:

  • An attacker finds a smart contract that allows users to deposit funds and withdraw them at a later time.
  • The attacker creates a malicious contract Contract B that repeatedly calls the deposit function of the vulnerable contract Contract A, depositing funds into the attacker’s own account.
  • The attacker then calls the withdraw function of the vulnerable contract, withdrawing the deposited funds.
  • Because the deposit function of the vulnerable contract is not properly protected against reentrancy, the attacker is able to repeatedly call the deposit function before calling the withdraw function, effectively stealing funds from the contract.
  • The attacker continues to repeat the attack until they have stolen as many funds as they desire.
Reentrancy attack Working

 

Below is an example of a simple smart contract that is vulnerable to reentrancy attacks:

Solidity




// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0; 
/// @title A contract for demonstrate payable functions and addresses
/// @author Jitendra Kumar
/// @notice For now, this contract just show how payable functions and addresses can receive ether into the contract
contract Reentrancy {
    mapping(address => uint) public balance;
 
    function deposit() public payable {
        balance[msg.sender] += msg.value;
    }
 
    function withdraw() public payable {
        require(balance[msg.sender] >= msg.value);
        payable(msg.sender).transfer(msg.value);
        balance[msg.sender] -= msg.value;
    }
}


Explanation: In this contract, the deposit function allows users to deposit funds into their account and the withdraw function allows users to withdraw their deposited funds. However, the contract does not properly check for reentrancy, so an attacker could create a malicious contract that repeatedly calls the deposit function before calling the withdraw function, effectively stealing funds from the contract.

Below is an example of how the contract can be modified to prevent reentrancy attacks:

Solidity




// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0; 
/// @title A contract for demonstrate Reentrancy Attack
/// @author Jitendra Kumar
/// @notice For now, this contract just show how to protect Smart Contracts against a Reentrancy Attack
contract Reentrancy {
     
    mapping(address => uint) public balance;
    bool public reentrancyLock;
 
    function deposit() public payable {
        require(!reentrancyLock);
        reentrancyLock = true;
        balance[msg.sender] += msg.value;
        reentrancyLock = false;
    }
 
    function withdraw() public payable{
        require(balance[msg.sender] >= msg.value);
        payable(msg.sender).transfer(msg.value);
        balance[msg.sender] -= msg.value;
    }
}


Explanation: In this example, a reentrancyLock variable is added to the contract. The deposit function now checks if the reentrancyLock variable is true before allowing the deposit to occur. If the variable is true, the deposit will not occur and the attacker will not be able to steal funds. The reentrancyLock variable is set to true before the deposit and set back to false after, this way the contract can only be called once at a time.
It’s important to note that this is a simplified example and in real-world scenarios, contracts should be audited by experts and tested extensively to ensure they are secure.

Types of Reentrancy Attack

There are several types of reentrancy attacks, including:

  • Frontrunning attack: It is an attack where an attacker monitors the blockchain for transactions that will call a vulnerable contract, and then quickly submits a transaction that calls the same contract before the original transaction is processed.
  • Timestamp dependency attack: It is an attack where an attacker manipulates the timestamp of a block to cause a vulnerable contract to execute in a way that is favorable to the attacker.
  • Recursive call attack: It is an attack where an attacker calls a vulnerable contract multiple times in a row, causing the contract to execute an unintended function or execute the same function multiple times.
  • Cross-function call attack: In this attack where an attacker calls multiple functions in a vulnerable contract in a specific order to cause unintended behavior.

All these types of attacks can be prevented by using different techniques like mutex or guard condition as I mentioned earlier.

Reentrancy Smart Contract Attacks Examples

  • DAO Hack: The DAO (Decentralized Autonomous Organization) smart contract was a decentralized investment fund built on the Ethereum blockchain. An attacker discovered a vulnerability in the DAO smart contract that allowed them to repeatedly call the “split” function, which allowed investors to withdraw their funds from the DAO before the contract had a chance to update the internal balances. The attacker was able to use this vulnerability to repeatedly call the split function and drain the DAO of approximately $50 million worth of Ether (ETH).
  • Lendf.me Protocol: Lendf.me is a decentralized lending platform built on the Ethereum blockchain. In 2019 an attacker discovered a vulnerability in the smart contract that allowed them to repeatedly borrow and repay the same loan over and over again, while also manipulating the price of the underlying assets to increase the amount of the loan. The attacker was able to exploit this vulnerability to borrow and repay a single loan multiple times, stealing more than $350,000 worth of cryptocurrency assets from the platform.
  • Cream Finance: Cream Finance is a DeFi platform that allows users to lend and borrow assets. In 2020 an attacker discovered a vulnerability in the smart contract that allowed them to repeatedly borrow and repay the same loan over and over again, while also manipulating the price of the underlying assets to increase the amount of the loan. The attacker was able to exploit this vulnerability to borrow and repay a single loan multiple times, stealing more than $30 million worth of cryptocurrency assets from the platform.
  • BurgerSwap: BurgerSwap is a decentralized exchange built on the Binance Smart Chain. In 2021 an attacker discovered a vulnerability in the smart contract that allowed them to repeatedly borrow and repay the same loan over and over again, while also manipulating the price of the underlying assets to increase the amount of the loan. The attacker was able to exploit this vulnerability to borrow and repay a single loan multiple times, stealing more than $2 million worth of cryptocurrency assets from the platform.
  • SurgeBNB: SurgeBNB is a decentralized exchange built on the Binance Smart Chain. In 2021 an attacker discovered a vulnerability in the smart contract that allowed them to repeatedly borrow and repay the same loan over and over again, while also manipulating the price of the underlying assets to increase the amount of the loan. The attacker was able to exploit this vulnerability to borrow and repay a single loan multiple times, stealing more than $30 million worth of cryptocurrency assets from the platform.
  • Siren Protocol: Siren Protocol is a decentralized finance platform built on the Ethereum blockchain. In 2021 an attacker discovered a vulnerability in the smart contract that allowed them to repeatedly borrow and repay the same loan over and over again, while also manipulating the price of the underlying assets to increase the amount of the loan. The attacker was able to exploit this vulnerability to borrow and repay a single loan multiple times, stealing more than $30 million worth of cryptocurrency assets from the platform.

Is the Reentrancy Attack Still a Significant Problem?

Reentrancy attacks are still a significant problem in the smart contract ecosystem. Though many smart contract platforms and development frameworks have built-in protections against reentrancy, it still remains an ongoing threat to smart contract security. As new smart contracts and decentralized applications are developed, it’s important for developers to thoroughly test and audit their contracts to ensure they are protected against reentrancy attacks.

How to Protect Smart Contracts Against a Reentrancy Attack?

  • Use a Mutex or Mutual Exclusion Lock: A mutex lock is used to prevent multiple calls to the same function from occurring at the same time. When a function is called, the mutex lock is set, and other calls to the same function will be blocked until the lock is released.
  • Use a Guard Condition: A guard condition is a flag that is set before external function calls and checked after. If the flag is set, the contract will not execute the external call and prevent reentrancy.
  • Check the Call Stack Depth: Checking the call stack depth is a way to ensure that the contract is not being called recursively. If the call stack depth exceeds a certain threshold, the contract will stop executing.
  • Use the “require” statement: Using the “require” statement can be used to check the state of the contract before allowing a function to execute.
  • Continuous Monitoring and Updating: Smart contracts should be continuously monitored for any vulnerabilities and updated as soon as new vulnerabilities are discovered.
  • It’s important to note that these are just some examples of the ways to protect smart contracts against a reentrancy attack and that smart contracts must be audited by experts and tested extensively to ensure they are secure.
  • To set the gas limits for the transactions so, you can use call method (which allow you to set the gas limit).
  • To update the state variables in the Smart Contract before calling the external functions or external contracts.  

Conclusion

In conclusion, reentrancy attacks have been a critical issue in smart contract development, as they can lead to loss of funds, compromise the integrity of smart contracts, and cause systemic failures. Therefore, it’s important to be aware of the potential vulnerabilities and take steps to prevent them, such as using the techniques I mentioned before, such as a mutex or guard condition.



Last Updated : 06 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads