Decentralized Finance (DeFi) has emerged as a revolutionary concept in the blockchain and cryptocurrency world, aiming to create a financial system that is open to everyone and operates without any central authority. However, this innovation comes with its own set of vulnerabilities, which have been exploited in various incidents over the years. This set of articles delves into these vulnerabilities, the notable exploits and incidents that occurred as a result, as well as some mitigation tips.
A vulnerability is a weakness or flaw in a system, such as software, network, or protocol, that could be exploited. It represents a potential risk but doesn't imply that an attack has occurred. An exploit, on the other hand, is the actual act of taking advantage of a vulnerability to gain unauthorized access or cause harm.
DeFi vulnerabilities can be categorized into traditional software vulnerabilities and crypto-economic vulnerabilities. Traditional ones are akin to classic software issues and can be mitigated using established techniques. Crypto-economic vulnerabilities, on the other hand, are unique to blockchain systems and rises from the decentralized nature of Web3. In the first article of this set, we focus on the traditional smart contract vulnerabilities.
1. Classic Web3 vulnerabilities
Ultimately, smart contracts are code that must be compiled, making them susceptible to common programming errors and vulnerabilities. This article provides an overview of such vulnerabilities that have been exploited in the DeFi sector.
1.1. Re-entrancy
Re-entrancy exploit occurs when an attacker is able to make new calls to a victim contract within a previous execution context. It was famously exploited in the DAO Attack of 2016, where an attacker withdrew 3.6 million Ether by recursively calling a withdrawal function.
Real-world exploits
- The DAO Attack (2016): One of the most famous examples is the attack on The DAO (Decentralized Autonomous Organization) on Ethereum. The attacker exploited a re-entrancy vulnerability in The DAO’s smart contract. By recursively calling the withdrawal function, the attacker was able to withdraw 3.6 million Ether, leading to a significant drop in Ether’s value and eventually resulting in Ethereum’s hard fork.
Mitigation
- Checks-Effects-Interactions Pattern: Ensuring that all effects (like state changes) and interactions (external calls to other contracts) are handled correctly. The key is to make all state changes before calling external contracts.
- Using Re-entrancy Guard: Implementing modifiers in smart contracts that prevent reentrant calls.
- Pull Over Push for Payments: Instead of pushing Ether to an address, it’s safer to let recipients withdraw Ether themselves.
1.2. Timestamp Dependency
The Timestamp Dependency arises when a smart contract’s logic is dependent on the timestamp or block time of the blockchain. This vulnerability is significant because block timestamps can be slightly manipulated by miners, potentially leading to exploitative behaviors.
In blockchain networks like Ethereum, each block has a timestamp that indicates when it was mined. Smart contracts can access this timestamp and use it for various functions, like calculating time periods, determining deadlines, or triggering specific contract actions.
The key issue with relying on block timestamps is that they are not completely accurate and can be influenced by miners. Miners, to a certain degree, can manipulate the timestamp of the blocks they mine. This vulnerability arises when transactions depend on specific timestamps, allowing attackers to manipulate outcomes.
Real-world exploits
- SmartBillions Lottery Hack (2017): SmartBillions, a lottery game on Ethereum, was exploited due to its reliance on block timestamps to generate random numbers. An attacker could influence the outcome by carefully choosing the timestamp when mining a block, though this requires the attacker to be a miner or colluding with one.
Mitigation
- Avoiding Block Timestamps: Refraining from using block timestamps for critical contract functionalities, especially those that can be manipulated by miners.
- Using External Time Oracle: Implementing a reliable external time oracle can provide more secure time data than block timestamps.
1.3. Batch-Overflow
The core of the batch overflow issue is an integer overflow. In programming, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside the range that can be represented with a given number of bits. Solidity uses unsigned integers for certain operations. These integers cannot represent negative numbers, and if an operation results in a value higher than the maximum representable value, it wraps around to zero and starts counting up again. This can lead to unexpected and potentially exploitable behavior.
Batch processing functions are used to execute multiple transfers or operations in a single transaction. If these functions don’t properly handle the arithmetic involved (especially with respect to checking for overflows), it can result in vulnerabilities. An attacker can exploit this vulnerability by passing carefully crafted parameters to a batch processing function. By causing an integer overflow, the attacker can manipulate the contract into issuing an extraordinarily large number of tokens or performing unintended actions, which can lead to severe consequences like theft of funds or manipulation of contract state.
Real-world exploits
- BeautyChain (BEC) Token Attack (2018): Attackers generated an extremely large amount of BEC tokens due to an overflow issue in a batch transfer function, which led to a price drop and several exchanges delisting the token.
Mitigation
- Safe Math Libraries: Utilizing libraries like OpenZeppelin’s SafeMath to perform arithmetic operations safely. These libraries help in handling overflows and underflows effectively.
- Thorough Testing and Auditing: Rigorous testing, including automated testing and code audits, can help in detecting overflow-related vulnerabilities before deployment.
1.4. Unchecked-send (Gasless-send)
The “Unchecked-send” or “Gasless-send” vulnerability in Solidity arises from the improper handling of Ether transfers in Ethereum smart contracts. This vulnerability is particularly relevant when using the send
or transfer
methods for sending Ether. Here’s an overview of this vulnerability:
In Solidity, there are three main ways to transfer Ether from a smart contract to an external address: send
, transfer
, and call
. Each method behaves differently in terms of gas usage and error handling. The send
method is used for sending Ether, but it only provides a limited amount of gas (2300 gas) to the receiving contract. This limited gas is enough for basic operations, like emitting an event, but not for more complex computations.
Unchecked-send Vulnerability: The vulnerability arises when a contract uses the send
method to transfer Ether but fails to check whether the transfer was successful. Since send
does not throw an error (it returns false
on failure), ignoring its return value can lead to a situation where the contract behaves as if the transfer was successful, even when it wasn’t. If a contract incorrectly assumes that the Ether transfer was successful, it could lead to inconsistent contract states or vulnerabilities where an attacker might be able to withdraw funds multiple times or exploit the contract logic.
Gasless-send Vulnerability: The term “Gasless-send” refers to a similar issue where the gas stipend provided to the receiving contract is insufficient for it to perform its operations. If the receiving contract needs to perform any state-changing operation or a computation that requires more than 2300 gas, the transaction will fail. This can be exploited in some scenarios to cause a denial of service (DoS) attack.
Real-world exploits
- Parity Wallet Freeze (2017): A user accidentally exploited the unchecked-send vulnerability in Parity’s multi-sig wallet, leading to the freezing of over $150 million worth of Ether. The vulnerability was in the wallet’s logic that failed to properly check the return value of a
delegatecall
, which allowed an attacker to become the owner of the wallet and subsequently destroy it.
Mitigation
- Checking Return Values: Always check the return values of calls and handle failures appropriately.
- Using Transfer and Send: Prefer using
transfer
andsend
for Ether transfers, as they automatically revert on failure.
1.5. Logic Bugs
In addition to specific technical vulnerabilities, there have been incidents in DeFi stemming from flaws in business or financial logic. This section delves into some of these notable incidents, examining their causes and impacts.
Real-world exploits
- Nomad Hack (August 2022). The Nomad token bridge was exploited due to a smart contract upgrade error, resulting in a loss of about $190 million. The upgrade mistakenly initialized the value of trusted roots to 0x00, which led to all messages being automatically viewed as proven, making the exploit easy to execute.
- Solana Wallet Hack (August 2022).Hackers drained funds from about 8,000 wallets on Solana, stealing around $8 million. The cause was linked to compromised private keys created, imported, or used in Slope mobile wallet applications.
- BNB Chain Hack (October 2022). The hack, which resulted in a loss of $570 million, was due to a bug in the bridge’s smart contract. This allowed the hacker to forge transactions and transfer money to their own wallet.
- Acala Hack (August 2022). A bug in a liquidity pool was exploited, resulting in the minting of 1.28 billion aUSD tokens by error. The attack devalued the stablecoin to $0.01, and Acala had to freeze the hacker-minted tokens and switch the network to maintenance mode.
Mitigation
- Regular Security Audits: Conducting thorough security audits by reputable firms can identify and rectify vulnerabilities.
- Monitoring and Real-time Analysis: Implementing tools for continuous monitoring of contract behavior and transaction patterns.
- Educating Developers and Users: Raising awareness about common vulnerabilities and safe practices in the DeFi space.
- Testing and Bug Bounties: Encouraging bug bounty programs to incentivize the discovery and reporting of vulnerabilities.
In this article, we explored DeFi challenges through the lens of traditional software engineering. In the upcoming article, we will delve into DeFi vulnerabilities from a crypto-economic perspective.