DeFi Flashloans Explained: How to Borrow Millions in uncollateralized loans (UniswapV2 + Foundry Examples

Ah, Flashloans. With great power comes great responsibility.

What if I told you that you could borrow millions of dollars worth of tokens as a loan for free… However, there is one catch. You’ll have to pay back the loan within the same transaction.

Welcome to the revolutionary world of DeFi and Flash loans.

What is a Flashloan?

Flashloans are uncollateralized loans in which a user can borrow large amounts of available funds that must be repaid (plus any fees) by the end of the transaction. If the loan cannot be paid based on the “lending conditions” of the Lending Smart Contract, the transaction will revert.

Pioneered by the DeFi protocol Aave in 2020, Flashloans have since been adopted by many other protocols and DEX’s (Decentralized Exchanges) such as Uniswap and Balancer.

In Traditional financial markets, this type of lending does not exist. Borrowers are often required to put up collateral in order to receive a loan e.g. a Car or Home. Whereby banks use this collateral as security to cover their losses. (known as Secured Loans)

However, in DeFi we can borrow millions in uncollateralized loans to perform a trade and pay it back (plus any fees). This is the Marvel of Flashloans. No proof of income, No verification, just a decentralized, trustless protocol that requires the borrowed assets to be paid back within the same block transaction.

Flashloans in Uniswap – How Flashloans Benefits Borrowers and Lenders:

  1. A Decentralised Exchange such as UniswapV2 allows lenders/ liquidity providers to supply liquidity (in the form of ERC20 tokens) to a pool. e.g. WETH/DAI pair.
  2. Uniswap allows any user the ability to access the available funds in the pool via Flashloan.
  3. A User (Flashloan borrower) can borrow large amounts of available tokens from the same pool/exchange in the form of a loan to be used elsewhere. e.g Arbitrage Trading.
  4. The original token amount is returned back to the pool (+ an additional 0.3% Swap Fee)
  5. The Flash loan borrower Pays a 0.3% Swap Fee for interacting with the Pool.
  6. As a result, the additional fee increases the pool value, with the additional swap fees distributed to the original lender/providers who contributed to the pool—benefiting both liquidity providers and the Flashloan borrower – by accessing a high amount of capital at a relatively low fee.

Note: All these series of operations occurred in a single transaction. We’ll explain this in detail.

This article details Flashloans from a high-level overview. Further, we’ll take a deep dive into developing an Arbitrage Flashloan Contract (written in Solidity + Foundry),


Article Breakdown:

Flashloans Explained Uniswap Foundry - Flashloan Simplified
High-Level Overview – Flash Loan Interaction Flow

The above diagram outlines a typical transaction flow a flashloan follows: (Note this occurs all within a single transaction)

  1. A Borrower executes the Flashloan Borrow Contract.
  2. A (Flashloan Receiver/ Borrower) Smart Contract borrows a large number of tokens from via a flash loan (Lender) contract.
  3. The Lender contract sends the tokens and calls a function receiveFlashloan in the Borrower contract.
  4. Within this recieveFlashloan do something i.e _tradeStrategy() with the loan and transfer the tokens back to the lender.
  5. The Lender Contract checks if the tokens lent have been received (+ any fees).
  6. The transaction is committed to the Blockchain. Assuming Step 3 was a profitable arbitrage trade. The contract’s flashloan operation led to a profitable trade.

As you may have observed in step 4 _tradeStrategy(), the borrower can do whatever they like with the funds, so long as Lender (Contract) is paid back. This ability to execute an intermediate call allows for some interesting use cases, such as the following:

  • Arbitrage Trading – Execute profitable trades based on price discrepancies between exchanges.
  • Yield Farming – Maximise token/ user rewards.
  • Collateral Swapping – Swapping tokens as collateral for existing loans.
  • DeFi Security Exploits – Oracle Attack / Price Manipulation. (More on this later).

If you’re thinking about it: You can’t run away with the funds!

As mentioned, the contract issuing the loan expects the tokens to be paid back via callback recieveFlashloan. Failure to pay would cause the payment to revert, leaving you out of pocket in gas fees.

Flashloans Explained Uniswap Foundry - Etherscan transaction flow
Flashloan – Series of Transfers on Etherscan (in a single transaction)

So, what is meant by “as long as tokens are paid back in the same transaction”?

In traditional finance, a transaction can be as seen as a single operation. I.e Bob transfers £50 to Alice. (this is what you see on your Bank Balance)

In the context of a blockchain, a single transaction can consist of a series of operations that takes place one after another. i.e:

  1. Bob Borrows 500 ETH Flash Loan from Uniswap
  2. Bob exchanges ETH → DAI on Exchange A
  3. Bob exchanges the DAI → ETH on Exchange B
  4. Bob Pays back the loan (+ fee). (…Bob makes a good profit and retires).

*Provided the gas is within gas limit, the above successful set of operations is all included under a single transaction.

This is what makes flashloans so powerful. So far as we pay back the loan within the same transaction, the borrower contract can do anything with the loaned tokens.*

Uniswap is one of many DeFi platforms that offer flash loans to users. In the context of UniswapV2, a user can access the token reserve and borrow a large number of tokens from the pool to be used elsewhere, e.g., high-volume arbitrage trade, yield farming, or even exploit other DeFi security vulnerabilities. The cost for the service: (0.3%) fee of the borrowed amount.

Arbitrage Trading with Flashloan

Flashloans Explained Uniswap Foundry - Etherscan Flow Summary
Flash Loan – Arbitrage Trade attack

Flashloan High-Level Flow

Below highlights, a “simplified” Flashloan Overview of what a Flashloan looks like this in the context of Arbitrage Trading.

Flashloans Explained Uniswap Foundry - Uniswap Flashswap High Level Diagram
Uniswap Flashloan Overview – Interacting with UniswapV2Call

Note this happens all within one transaction. Failure in any of the steps will cause the transaction to revert.

  1. Bob develops a Smart Contract (Borrowing Contract) to interact with a Lender offering Flashloans e.g. Uniswap.
  2. The Borrowing Contract calls a function to borrow a large number of tokens (10,000 WETH) from the Flashloan Lender (Lender Contract). e.g. borrowFlashloan() .
  3. The Lender Contract then optimistically sends tokens to the borrowing contract and calls a specific function after e.g. receiveFlashloan()
  4. The (Borrower Contract) is expected to have implemented the receiveFlashloan()
  5. Within the recieveFlashloan() the borrower is expected to do whatever they want with the tokens (i.e high-volume Arbitrage Trading) and transfer the tokens back to the Lender Contract.
  6. The Lender contract checks whether all tokens have been transferred back from the borrower contract typically checking if balanceAfterSendingTokens >= balanceBeforeSendingTokens (as there may be some fees added). Once the conditions are all met, the transaction can be successfully added to a block.
  7. A Flashloan has been completed. Bob has made a pretty penny. By leveraging 10,000 WETH Tokens to make an arbitrage trade, send all borrowed tokens back, and profit from the difference.

Although some Flashloan offers this service for free, it’s more common to find protocols that would charge a fee. Typically a percentage of the total loan. For example, Uniswap charges 0.3% in swap fees per swap.

DeFi Exploits with Flashloans

Flashloans (although in their relative infancy) have been used in many other use cases spanning further than Arbitrage trading.

Leading to Flashloans gaining a more controversial reputation, whereby these loans have been used for more malicious purposes to fund various types of DeFi Protocols exploits.

Oracle Manipulation:

With known hacks such as Inverse Finance exploit for $1.2M, a hacker can borrow large amounts of funds to manipulate/destabilize the oracle price. Only to eventually to purchase the same tokens for a cheaper price value – often draining funds from the protocol.

Flashloans Explained Uniswap Foundry - bZx Exploit annotated
Etherscan Flashloan Analysis (Credits PeckShield)

Other examples include Flashloan Attacks via Arbitrage Routes. On February 2020, the bZx team disclosed an “exploit” in which an attacker borrowed 10,000 ETH from dYdX, and manipulated an oracle conversion rate of 1 BTC = 61.4 WETH. As a result, the attacker used flashloan to net 71 ETH plus a few other positions. (~ $355,880 as of the time of exploit)

Through a series of steps: Borrow, Hoard, Margin Pump, and Dump, and finally Flashloan Repay.

Hackers Exploit Transaction: https://etherscan.io/tx/0xb5c8bd9430b6cc87a0e2fe110ece6bf527fa4f170a4bc8cd032f768fc5219838

As a result, an attacker can leverage millions of dollars to exploit a protocol. Their only expense being the swap + gas fees. During the development of a protocol, a thorough smart contract audit is strongly advised before launching to mitigate high-risk vulnerabilities / loss of funds.

Flashloan Examples Solidity – High-Level Overview

Flashloans Explained Uniswap Foundry - UniswapV2Call Solidity
Flashloan Receiver Contract – UniswapV2Call() Implementation

The following section takes a high-level overview of how a Flashloan can be implemented with Solidity. If you’re interested in executing flashloan, I’ve developed a UniswapV2 Flashloan Repo with Foundry Test.

Below illustrates a simplified flash loan developed in Solidity:

The following consist of two contracts:

  • The Borrower – The Smart contract requesting the large token amount via Flashloans.
  • The Lender Contract – The Smart Contract offers loans, expecting the tokens to paid back.
function flashLoan(uint256 amount) external nonReentrant {
        uint256 balanceBefore = liquidityToken.balanceOf(address(this));
        if (amount > balanceBefore) {
            revert NotEnoughTokenBalance();
        }
        if (!msg.sender.isContract()) {
            revert CallerIsNotContract();
        }
        liquidityToken.transfer(msg.sender, amount);
	
	// the receiving contract is expected to implement receiveFlashLoan() 
	//i.e doYourStuffAndPayMeBack
        msg.sender.functionCall(abi.encodeWithSignature("receiveFlashLoan(uint256)", 
        amount));
        if (liquidityToken.balanceOf(address(this)) < balanceBefore) {
            revert FlashLoanNotPaidBack();
        }
    }

Credits: Damn Vulnerable Defi (Do not use in prod.)

The Borrower Smart Contract which implements the receiveFlashloan would look something like this:

function receiveFlashLoan(uint256 amount) public {
        // stuffHappensHereAndPayBackTheLoan
        // ... make high arbitrage trade ...
        // ... send the token back e.g. via safeTransfer();
    }

In the context of UniswapV2, a user can access a flash loan via IUniswaV2Calle.sol, whereby the receiving function would be required to implement the following interface. And, of course, return back the tokens + a fee ;).

interface IUniswapV2Callee {
    function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
}

For more context on how UniswapV2 works. Have a look at UniswapV2 Code Walkthrough Tutorial. Alternatively, Jeiwan’s Uniswap Clone Tutorial, has a great example of building a Flashloan contract to interact with an education Uniswap Exchange Pool (ZuniSwap)

UniswapV2 Flashloan + Foundry Repo

Unidwap Foundry Flashloan Tests
Uniswap Flashloan Tests in Foundry

As a proof of concept of performing flash loan trades, I’ve developed a Uniswap Flashloan GitHub Repo whereby you can interact with flashloans on a fork of Ethereum Mainnet.

The Uniswap Flashloan Repo includes a Foundry test environment to simulate trades and router helpers to interact with Uniswap via UniswapV2Router in order to swapTokens, fund WETH, etc – to develop a profitable flash loan trade strategy. We’ll cover the solidity flashloan development in another article.

Well that perfectly segues to a literal million dollar question…

How easy is it to make a profitable Flashloan Strategy

Flashloans are a powerful tool that gives anyone the ability to take a large amount in uncollateralized loans.

Taking the use case of flashloans to make profitable arbitrage trades:

This can be highly competitive, with many flash loan traders having a strong technical background in quant and arbitrage trading. Leading to the following:

  1. Loss of Alpha Decay as other bots catch on you your trade strategy
  2. Front Runners – A profitable trade can be ‘sniped’ from the Mempool
    • Although solutions such as MEV Flashbots attempt to solve this issue
  3. Loss in failed trades leading to you paying gas fees.

The best way to interact with flashloans is to come from the perspective of a smart contract researcher.

Summary:

Flashloans – A Future of Permissionless Loans, a powerful tool still in its infancy.

To wrap up, flashloans allow any user to access a large amount of available tokens to borrow, without the need for user verification or collateral. This form of uncollateralized loans has the potential to launch a series of future DeFi services to be built on top of that does not exist in traditional finance markets.

However, with all new innovations. Flashloans can be used to fund DeFi security exploits, to the tune of millions of dollars drained from a pool. This comes to the article’s opening statement: with great power comes great responsibility.

As a way to make Flashloans more accessible, a Uniswap-Foundry repo has been available for users to interact, experiment, and deploy their own flashloan strategies. Consider contributing to the Repo.