Smart Contract Security Part 1 — Reentrancy Attacks
Author: Benjamin Chai
Note: this article provides a basic overview of reentrancy attacks and how they occur on smart contracts, no previous solidity experience is required.
Overview of Blockchain Landscape
The groundbreaking innovation provided by Blockchain and cryptocurrencies have spawned a paradigm shift in digital economies. By providing a decentralized framework for monetary transactions and code execution, blockchain technology has resulted in a wide variety of decentralized applications (DAPPs) and platforms, disrupting some of the largest and most established industries: finance (DeFi), art (NFTs), and gaming (GameFi). Such disruption has eliminated middlemen in a trustless manner (increasing profits to users), torn down barriers to entry (blockchains are global and permission-less networks), and dramatically increased efficiency of online transactions (from 3–5 day payment processing periods to minutes).
Security of Smart Contracts
Unfortunately, with all of the benefits comes some cons. While the cryptographic nature of blockchains provide a high level of security to the underlying blockchains themselves, the infrastructure for blockchain applications remain in infancy, providing security vulnerabilities largely irrelevant to web 2.0 firms. Such vulnerabilities have resulted in unprecedented hacks, with singular attacks resulting in dozens, if not hundreds of millions of dollars being stolen. In 2022 alone, hacks have resulted in over 2 billions dollars worth of cryptocurrency being stolen. In order to understand why cryptocurrency hacks are so prevalent and damaging, it is first necessary to understand onchain DAPP infrastructure.
Decentralized application infrastructure operates on-chain through smart contracts. Smart contracts are blockchain transactions containing executable code that can be used to create automated programs. Smart contracts enable onchain computation, allowing decentralized applications to integrate processes with monetary transfers. Despite the utility and functionality of smart contracts, they present a variety of risks typically not associated with web 2 apps. As previously mentioned, blockchains are open and permission-less, meaning anyone can interact with blockchains and decentralized applications. Given that decentralized application smart contracts are often public facing on blockchains, smart contract code is often open source or visible on blockchain explorers, allowing users to check the validity of the contracts they are interacting with. Such transparency provides benefits, particularly trustlessness, but also presents risk. Anyone at any time can interact with DAPP smart contracts, allowing individuals to call functions and pass in data to said smart contracts. The open source and accessible nature of smart contracts make a hacker’s job much easier, allowing them to view and openly interact with smart contracts to launch attacks. Such transparency and openness is typically not found in web 2 applications which may have internally operated and private backends processes. The free range of smart contracts have provided hackers the opportunity to execute multiple attacks, most notably reentracy attacks.
Reentrancy Attacks
Perhaps the most infamous of any smart contract attack is the notorious reentrancy attack. In computer science, a program is considered reentrant if it can be “reentered”, meaning it can be interrupted during execution and accept alternative invocations. This means multiple invocations are able to run simultaneously to produce multiple outputs, even if a previous invocation has been paused, allowing reentrant programs to accept additional input prior to producing a previous output. In the case of solidity, reentrancy occurs through fallback functions. Fallback functions are executed when a contract receives eth but no accompanying call with a valid function identifier, or a function is called without expected data inputs. In such cases, fallback functions make sense in that they help protect users who may interact with a smart contract incorrectly to return their funds. However, fallback functions present a number of risks. Fallback functions may execute arbitrary logic, allowing hackers to create malicious fallback functions. Assuming the target smart contract allows external fallback functions to execute without accompanying immediate blockchain state changes, reentrancy attacks can occur. Most notably, reentrancy attacks can occur with the withdrawal function of a smart contract.
For more clarity, lets take a look at an example. Let’s say that a smart contract has a withdrawal function with the following configuration.
Although this may seem complicated, this function can be summarized in terms of three processes:
- Checking the balance: uint bal = balances [msg.sender];
- Sending the withdrawn amount: (bool sent, ) = msg.sender.call{value: bal} (‘’’);
- Adjusting user’s balance on the contract to reflect the withdrawal: Balances [msg.sender] = 0;
All of these processes execute sequentially from 1–3. However, a state change is only executed upon completion of the entire function, meaning all three processes must occur before the blockchain records a state change. Thus, a small window of time exists between the contract sending the funds and the contract updating balance, allowing for the possibility of a reentrancy attack. As previously mentioned, fallback functions occur when eth is received without expected inputs, thus the attacker can configure an external malicious contract such that the eth received from the withdrawal triggers a fallback function. Fallback functions may also allow arbitrary logic, allowing an attacker to configure the fallback function as another withdrawal call. Such a fallback function can execute another withdrawal before the target contract’s update is balanced. The subsequent withdrawal can yet again trigger the malicious fallback function, effectively allowing the attacker to drain the target contract’s balance through a recursive reentrancy attack. The following diagram presents the exact workflow of said reentrancy attack.
Impact of Reentrancy Attacks
Despite their relative simplicity, Reentrancy attacks have been the attack vector for numerous hacks, most infamously the DAO Hack. In 2016, community members and investors banded together to create a revolutionary digital organization utilizing Ethereum infrastructure. The DAO was the first iteration of DAOs, or decentralized autonomous organizations, and sought to provide investments through smart contracts. The DAO accumulated over 150 million dollars of ether (worth billions now) a groundbreaking sum at the time. However, due to vulnerabilities in the smart contract code, a reentrancy attack occurred, not unlike that outlined in this paper, siphoning off 60 million dollars in ether. The attack was a pivotal moment in Ethereum's history, resulting in a controversial hard fork to recover the lost funds. Since then, dozens of reentrancy attacks have occurred on protocols, adding to the damages caused by reentrancy attacks.
Mitigating Reentrancy Attack Risk
Despite the numerous past reentrancy attacks, there is good news: reentrancy attacks can be prevented. Perhaps the best guard against a reentrancy attack, is ensuring that a state update occurs prior to making any external calls or interacting with external contracts. A state update prior to interacting with external contracts prevents an external fallback function from successfully executing, or reentering, without the target contract being updated accordingly. For instance, the balance of an attacker after an initial withdrawal would be updated accordingly, preventing recursive malicious withdrawals. Another solution is to implement modifiers, effectively locking a function while it is still executing so that no attackers may reenter.
Conclusion
Despite the variety of past reentrancy attacks, developers can rest assured that solutions do exist to prevent such attacks. However, reentrancy attacks are but one example of hacks that can occur on smart contracts. Likewise, a variety of cybersecurity concerns exist outside of smart contracts, particularly private key security. In addition, many DAPPs include centralized components within their tech stack, providing another layer of security concerns unrelated to blockchain. In light of the vast amounts of personal data and money operating through digital solutions, it is important for any tech firm, whether they be Web 3.0 or Web 2.0, to be cognizant and prepare accordingly for any cybersecurity risk.