Skip to content

Latest commit

 

History

History
 
 

DFXFinance

DFX Finance

Step-by-step

  1. Request a Flashloan
  2. Deposit the received amount in the loan callback

Detailed Description

As there is no reentrancy protection in the flashloan function and token balances are checked to determine if the loan was paid back, the attacker simply asked for a loan and deposited the amount requested to mint shares inside the loan callback.

    function flash(
        address recipient,
        uint256 amount0,
        uint256 amount1,
        bytes calldata data
    ) external transactable noDelegateCall isNotEmergency {
        ...
        ...
        uint256 balance0After = IERC20(derivatives[0]).balanceOf(address(this));
        uint256 balance1After = IERC20(derivatives[1]).balanceOf(address(this));

        require(balance0Before.add(fee0) <= balance0After, 'Curve/insufficient-token0-returned');
        require(balance1Before.add(fee1) <= balance1After, 'Curve/insufficient-token1-returned');
    }

Because the balance checked after executing the flashloan callback was satisfied, the loan succeded. Then, the attacker simply called withdraw and stole the loan amount.

Possible mitigations

  • Use reentrancy protection for flashloans
  • Check if the flashloan key checks could be manipuladed by side-entering the contract and if so, evaluate its impact. Whenever a risk arises, add a reentrancy mutex to the vulnerable functions and to the flashLoan itself.

Diagrams and graphs

Overview

overview

Class

class

Sources and references