If you are an old player in the crypto industry, then the infamous DAO hack must have been on your radar. The DAO hack of 2016 was probably one of the most severe attacks in blockchain history caused by Reentrancy.
In fact, in April 2022, OLA finance powering Voltage finance experienced exploitation for over $4.67mn in a Re-entrancy attack. The attacker used a re-entrant vulnerability in the ERC677 token standard to commit financial fraud.
An attack committed by a smart contract over another led to an additional scam to the list of crypto-heists taking over the blockchain space for some time now.
This article will discuss the Re-entrancy attack, including its working, type, and ways of saving your smart contract from them.
Additional Resource: What is Dao?
Table of Contents
What is a Reentrancy attack?
Re-entrancy or an unsafe external call happens when Contract X calls Contract Y. A vice-versa call occurred before Contract X could update the first call on its state, leading to unexpected behavior.
We know this might be a little confusing so let’s look through an example:
Consider two functions in a smart contract- deposit and withdrawal
- The deposit function shoots up the user account on receiving crypto
- On the other hand, the Withdrawal function performs three tasks in a row, including:
- Checking the user balance
- Send funds
- Updates the balance sheet
Consider the following schematic explaining the scenario mentioned above:
How Does Reentrancy Attack Work?
To explain the working of a reentrancy attack, let us take you through an example of hacking a Solidity contract using the same vulnerability.
- Consider a contract X, calling Contract Y. Now reentrancy occurs when contract Y calls X while X is still executing its call to Y.
- Contract X keeps a record of how much it owes to other contracts, and it has a record of the balance it owes to contract Y.
Look at the diagram below to understand how the transaction occurs in this case.
- Look at step 3 of contract X’s withdrawal function. Before step 3 gets executed, the fallback function of Y makes another call to the withdrawal function of X.
- This could keep on iterating until the contract X balance comes to Zero. It eventually leads to contract Y draining all the Ether from contract X.
- One of the significant challenges of calling external contracts is that they may take over the control flow and change the data that the calling function wasn’t expecting. The reentrancy vulnerability had functions calling themselves repeatedly before ending the first call.
Now that we know what reentrancy is and how it is executed, let’s look at the different types of the same.
Must Read: RE-ENTRANCY REAL USE CASE
Types of Reentrancy Attack
Reentrancy attacks are classified into two types: single function and cross-function reentrancy.
1. Attack on Single Function Reentrancy
The most basic and easily preventable smart contract attack happens when the vulnerable function is the same one the attacker recursively attempts to call. The scenario explained above is an example of a single-function reentrancy attack.
2. Attack on Cross-Functional Reentry
These attacks are harder to detect. A cross-function reentrancy attack is possible when a vulnerable function shares a state with another function that has a desirable effect for the attacker.
At this instant, execution of the attacker’s code on the external call to withdraw balance calls transfer() function. Since their balance is not yet reset to zero, they can transfer the tokens despite receiving the withdrawal amount.
How can a Reentrancy Attack Harm Smart Contracts?
Reentrancy is one of the most devastating attacks with the potential to drain off your smart contract financially. It exploits Vulnerable patterns of calling external contracts and can be particularly damaging, draining all of the funds in your contract if not appropriately handled. Also, it is one of the primary reasons for the crypto-heists happening for some time now.
Reentrancy is a loophole the attacker exploits through another smart contract by repeatedly calling a vulnerable function. All this happens before the vulnerable smart contract can update its state variables.
How to Protect Smart Contracts from a Reentrancy Attack?
There are a few steps that you can take to prevent your smart contract from reentrancy attack:
- Observe the examples given above. Here the balance updating step happens after sending Ether to another contract Y. Swapping the execution of these functions, i.e., updating balance before transferring. Also, implement checks-effects-interactions patterns.
- Get your smart contract audited before deploying it on the mainnet. A smart contract audit provides an additional layer of security to your code, considerably reducing the chances of hacking.
- Another way of saving your smart contract from reentrants is a reentrancy guard. Look at the next section to know what a reentrancy guard is.
What is a Reentrancy guard?
A reentrancy guard is a modifier that can be applied to the withdrawal function. Locking the contract prevents the execution of more than one function simultaneously.
You can eliminate the risk of recursive calls made at your withdrawal function using the reentrancy guard approach.
It’s crucial to exercise caution while making calls to external smart contracts. This is due to the possibility that they could end up running malicious code in the original contract.
Reentrancy Guard is OpenZeppelin’s way of implementing the mutex or the lock function. Mutex locks the contract against the cross-function reentrancy to prevent the exploitation of the withdrawal function using a recursive call.
Reentrancy guard is the modifier provided by the openzeppelin’s library, applying to a function called reentrant that guards function with a mutex.
Invoking external contracts always introduces security risks. But in reentrancy, the real issue is updating the global state following an external call.
The attacker can call the withdraw function recursively, draining the entire contract by transferring funds before updating the balance.
Reentrancy is not new and probably the most exploited bug by Web3.0 hackers. Smart contract Auditing is one way to prevent yourself from missing out on the reentrant vulnerability. A thorough review from Web3 security experts can provide a security shield to your code, preventing it from being susceptible to hackers.