Flash Loans

Published by Mario Oettler on

Definition: A flash loan is a loan on a blockchain that is paid out and repaid in a single transaction. If the repay fails, the flash loan is not paid out at all. This means there is no risk for the lender. A flash loan doesn’t require collateralization which makes it very easy to use.

Flash loans can be used to fund arbitrage transactions. But they can also be used for price manipulation attacks.

How Flash Loans Work

In this topic, we will have a look into the working principles of a flash loan.

Sequence Flow of a Flash Loan

Therefore, we will first look at a sequence diagram that shows the interaction between the flash loan provider (lender), the borrower, the ERC-20 token contract, and a decentralized exchange. The idea is that the borrower borrows an ERC-20 token from the lender. He uses these tokens to trade on a decentralized exchange. After the trade is finished, he returns the tokens to the lender. All this is done in a single transaction. And if at any point an error occurs or the repayment fails, the whole transaction is rolled back.

The steps are as follows:

  1. The EOA of the borrower creates a transaction to their borrower smart contract.
  2. This smart contract makes a call to the flash loan contract. It submits the amount and the recipient of the flash loan (typically, it is the borrower contract)
  3. The flash loan contract calls the function transfer() in the ERC20 FL-Token contract. It passes the amount and the receiver as parameters.
  4. When this is done, the flash loan contract calls the operation() method in the receiver contract.
  5. The receiver contract then performs any operations it wants. If that is done, it calls the approve() function of the ERC20 FL-Token and approves the flash loan contract the amount + fee.
  6. The flash loan contract then checks whether or not the amount + fee were approved. If the condition is met, it returns true. Otherwise, it reverts. In case of a revert, no tokens are transferred to the receiver since the state changes made in this function call frame are rolled back. The borrower receives a false as return value or it reverts too depending on the implementation of the call.

The following sequence chart shows the control flow. The nested functions mean that the function is executed within the call frame of the outer function. Bold arrows are message calls (2, 3, 5, 6) and dashed arrows (4, 7, 8, 9) are returns of the control flow. The bold dotted arrow (1) is a transaction.

Sequence diagram of a flash loan.

Structure of a flash loan smart contract

A basic flash loan smart contract is fairly simple. It consists of a function flashLoan() with three conditions or tasks.

  1. Transfer token to borrower,
  2. Inform borrower about successful transfer,
  3. Check if repay was successful.

The borrower calls the function flashLoan() together with necessary parameters like the ERC20 token address, the requested amount, additional data, and the address of the receiving smart contract (=borrower smart contract).

See the following code snippet taken from EIP3156.

https://github.com/albertocuestacanada/ERC3156/blob/main/contracts/reference/FlashLender.sol

function flashLoan(

IERC3156FlashBorrower receiver,

address token,

uint256 amount,

bytes calldata data

) external override returns(bool) {

require(

supportedTokens[token],

"FlashLender: Unsupported currency"

);

uint256 _fee = _flashFee(token, amount);

require(

IERC20(token).transfer(address(receiver), amount),

"FlashLender: Transfer failed"

);

require(

receiver.onFlashLoan(msg.sender, token, amount, _fee, data) == CALLBACK_SUCCESS,

"FlashLender: Callback failed"

);

require(

IERC20(token).transferFrom(address(receiver), address(this), amount + _fee),

"FlashLender: Repay failed"

);

return true;

}

After calling the function flashLoan(), the flash loan contract transfers the ERC20 token to the borrower by calling the transfer() function in the ERC20 token contract. If the transfer was successful, the lender informs the borrower by calling the onFlashLoan() function of the borrower’s smart contract.

Informing the borrower is necessary because the transfer would go unnoticed otherwise by the borrower. The borrower could, in this case, not use the funds in the same transaction.

Moreover, informing the borrower hands over the flow control to him. The borrower can now use the borrowed token to do some arbitrage deals or whatever it wants. Before it returns the flow control to the lender, it must grant an allowance with the right amount in the ERC20 token to the lender.

In the last step, the lender transfers the allowance back to its own address by calling the transferFrom() function in the ERC20 token contract and checks if this transfer was successful.

If any of these steps fails, the whole transaction is rolled back and the token has never been transferred to the borrower in the first place.

Profitability of a Flash Loan

Liquidity Provider receives a fee every time a borrower receives a loan. Borrowers incur the following costs.

  • Loan Fees (or interest) for borrowing the money
  • Gas cost for executing the transaction
  • Fees for any service funded with the loan

Taking out a flash loan is profitable if the costs are lower than the profit. Borrowers can use flash loans to engage in arbitrage transactions.

Categories:

if()