Dforce Network Hack Analysis
The DeFi ecosystem has seen rapid growth and innovation, attracting not just legitimate users but also hackers and attackers looking for vulnerabilities to exploit. One such incident occurred on February 10th when dForce network, a prominent DeFi aggregator platform, fell victim to a sophisticated attack that utilized a read-only reentrancy vulnerability. The attacker managed to exploit the platform and make a profit of approximately $3.65 million. This hack analysis will provide an in-depth look at the attack and its impact on the dForce platform and its users.
Hack Impact
The attack on dForce network had significant consequences for the platform and its users. By exploiting a reentrancy vulnerability in the wstETH/ETH pool on Curve and the dForce wstETH/ETH Vault, the attacker was able to manipulate the virtual price of the pool, which in turn affected the oracle used by the dForce wstETH/ETH Vault. This manipulation allowed the attacker to liquidate other users’ positions in the vault, ultimately profiting by around $3.65 million.
As a result of the attack, dForce had to pause all vaults to prevent further exploitation and conduct a thorough investigation to identify the root cause of the vulnerability. While the hacked funds were eventually returned to the dForce network’s multisigs by the attacker, the incident still serves as a cautionary tale for the DeFi ecosystem, highlighting the importance of security and proper auditing in an industry that is still evolving and prone to vulnerabilities.
Unmasking the Stealthy Nature of Read-Only Reentrancy Attacks: A Simple Analogy
A read-only reentrancy attack occurs when an attacker manipulates a smart contract to gain more rewards than they should by calling a function before the contract’s state is updated. To understand this, let’s consider an analogy with a bank scenario.
Imagine a bank calculates a bonus for each user based on the total deposits in the bank. An attacker exploits a read-only reentrancy vulnerability to manipulate the bank’s calculations to gain more bonus units. Here’s how it works:
- Step 1: Attacker deposits 1000 units into the target contract (e.g., a bank), which already has a total of 9000 units. This results in a temporarily inflated total deposit of 10,000 units.
- Step 2: The bank calculates a bonus based on the total deposits. Suppose the bonus is 1% of the total deposits for each user.
If the attacker initiates a withdrawal before the funds are deducted, their bonus would be calculated based on the inflated total deposit of 10,000 units (1% of 10,000 = 100 bonus units).
If the attacker initiates a withdrawal after the funds are deducted, their bonus would be calculated based on the actual total deposit of 9000 units (1% of 9000 = 90 bonus units).
- Step 3: Attacker triggers the withdrawal process before the funds are deducted, exploiting the read-only reentrancy vulnerability.
- Step 4: The attacker receives the inflated bonus of 100 units, along with their original deposit of 1000 units, for a total of 1100 units.
By exploiting the read-only reentrancy vulnerability, the attacker gains an additional 10 units (100 – 90) compared to what they would have received if they had initiated the withdrawal after the funds were deducted. This example demonstrates how read-only reentrancy attacks can be used to gain an unfair advantage in a smart contract system.
Delving into Key Functions of Read-Only Reentrancy Attacks
In this section, we’ll explain the purpose of two critical functions involved in read-only reentrancy attacks: remove_liquidity and get_virtual_price. Understanding these functions will help us explore the steps an attacker follows to exploit the vulnerability and make a profit.
The Remove Liquidity Function
The remove_liquidity function is responsible for withdrawing coins from the pool. The withdrawal amounts are determined based on the current deposit ratios. This function takes two parameters: _amount, which is the quantity of LP tokens to burn in the withdrawal, and min_amounts, which are the minimum amounts of underlying coins to receive. The function returns a list of the amounts of coins that were withdrawn.
The main purpose of this function is to allow users to withdraw their funds from the liquidity pool by burning LP tokens. During this process, the function ensures that the withdrawal amounts meet the minimum expected amounts, and updates the pool’s balances accordingly
The Get Virtual Price Function
The get_virtual_price function calculates the current virtual price of the pool’s LP token. This virtual price is useful for determining profits. The function returns the LP token’s virtual price normalized to 1e18.
By calling this function, users can gauge the value of their LP tokens in the liquidity pool. The virtual price represents the overall value of the pool’s assets, and when balanced, it is equal to the product of the number of tokens and their individual prices.
Understanding these functions is essential for grasping the mechanics of a read-only reentrancy attack. In the following sections, we’ll explain how an attacker manipulates these functions to exploit the vulnerability and make a profit.
Exploiting Read-Only Reentrancy Attack: Steps Involved
In this section, we will explain the steps an attacker takes to exploit a read-only reentrancy attack using the provided reference steps. The attacker manipulates the remove_liquidity and get_virtual_price functions to make a profit.
Step 1: Obtaining Initial Funds and Acquiring LP Tokens
The attacker obtains an initial fund of 68,000 ETH through nine flash loan attacks.
They add liquidity to the wstETH/ETH pool on Curve, to acquire 65,000 wstETHCRV LP tokens.
Step 2: Staking LP Tokens and Receiving Rewards
The attacker stakes 1,900 wstETHCRV to receive 1,900 wstETHCRV-gauge and 2.08 million USX.
Step 3: Triggering the Fallback Function
The attacker calls the remove_liquidity function, which triggers the raw_call(msg.sender) attack contract.
The attack contract, in turn, calls vMUSX.liquidateBorrow to perform two liquidations.
Step 4: Manipulating Virtual Prices and Liquidating Other Users
During the callback, the LP token total supply has not been updated, resulting in an incorrect price calculation. The attacker uses the get_virtual_price method to retrieve the manipulated price when calling the liquidateBorrow function on vMUSX.
Step 5: Completing the Attack and Making a Profit
The attacker calls the remove_liquidity function to extract the profitable liquidity funds.
They convert the funds into ETH, repay the flash loan, and exit the market with a profit.
At the core of this vulnerability lies the manipulation of the remove_liquidity and get_virtual_price functions. The attacker exploits the process of transferring native tokens before burning LP tokens when removing liquidity in the wstETH/ETH Pool. This triggers the callback for receiving native tokens, allowing the attacker to manipulate virtual prices and liquidate other users for profit.
Recommendations for Enhanced Security
To prevent read-only reentrancy attacks, developers should consider the following measures:
Reordering of operations
Make sure to update the state variables, like the LP token total supply, before making external calls or transfers. By updating the state first, the potential for reentrancy is minimized.
Check-effects-interactions pattern
Adhere to the check-effects-interactions pattern, where you perform checks and validations first, followed by updating state variables, and finally interacting with external contracts. This pattern can help prevent issues arising from reentrancy attacks.
Transactions involved
Attacker’s address: 0xe0d551017c0111ac11108641771897aa33b2817c
Attacker’s contract: 0xee29b6aee6e4783db176946e4e8f1e5fdcd446a7
Attack transaction ARBI: 0x5db5c2
Attacker transaction OP: 0x6c19762186
Conclusion
The dForce network hack serves as a vital reminder of the importance of smart contract security and thorough auditing processes. By exploiting a read-only reentrancy vulnerability in the wstETH/ETH pool, the attacker was able to manipulate virtual prices and liquidate other users for profit. This incident highlights the need for a comprehensive understanding of the underlying code and potential attack vectors when developing and deploying smart contracts.
To protect your DeFi project and mitigate the risk of such attacks, it is crucial to conduct rigorous audits with a reputable and experienced auditing firm. BlockApex.io is a trusted partner in this space, providing comprehensive smart contract auditing services that identify vulnerabilities and ensure the security of your DeFi application. By engaging with BlockApex.io, you can be confident that your smart contract code is secure and resilient against potential exploits, safeguarding your users and your project’s reputation.
Explore more Hack Analysis: