Dough Finance - Lack of Input Data Verification
On July 12, 2024, Dough Finance experienced an exploit resulting in an estimated loss of $1.8 million. A design flaw in the ConnectorDeleverageParaswap contract allowed an attacker to trigger DoughDsa to withdraw collateral from Aave and transfer it to the attacker.
Overview
Attacker:
https://etherscan.io/address/0x67104175fc5fabbdb5a1876c3914e04b94c71741
Vulnerable Contract:
https://etherscan.io/address/0x9f54e8eAa9658316Bb8006E03FFF1cb191AafBE6
Transaction attack:
https://etherscan.io/tx/0x92cdcc732eebf47200ea56123716e337f6ef7d5ad714a2295794fdc6031ebb2e
Exploit Analysis
Following the transaction, the attacker checked the debt balance of the Vault in Aave and flashloaned USDC from Balancer to repay the Vault.
The transaction then called ConnectorDeleverageParaswap to trigger a flashloan request with specific actions in the swapData.
The connector initiated the flashloan from the pool and handled the response in the executeOperation function.
In a deep dive into the executeOperation function in the ConnectorDeleverage contract:
The function parses input from the pool contract, which contains swapData from the attack contract. The deloopAllCollateral function loops through all attacker payloads and calls them. There is a high risk that the pool and connector deleverage contracts trust each other and do not verify user input before executing calls.
Following the next instructions:
There are two arbitrary calls from this loop: vault.executeAction and weth.transferFrom. In the first action, the vault:
The vault contract follows the ConnectorDeleverageParaswap instructions, calls Aave, and withdraws 596 WETH (staked balance used as collateral).
In the next instructions, the ConnectorDeleverageParaswap follows the swapData to transfer all vault balance to the attack contract. With these funds, the attacker can swap to USDC, repay the flashloan, and acquire substantial project assets.
Root cause:
The primary vulnerability lies in the ConnectorDeleverageParaswap contract's failure to validate user input before executing arbitrary calls within the deloopAllCollaterals function. This oversight allows attackers to manipulate the vault, causing it to withdraw all collateral and transfer it to the attacker's contract.
Lesson learned
As developers, it's essential to adhere to the principle of "never trusting any input," even from partners and supporting contracts. Particularly with arbitrary calls, user input can manipulate your contract, withdraw funds, or even destroy the contract.
Additionally, it is strongly recommended to conduct comprehensive security audits for all projects, whether they involve smart contracts, backends, wallets, or decentralized applications (dApps).