Learn how to perform FlashLoan using Aave
DeFi interest has exploded over the last 3 years. The users grew by 300,000 since early 2022, less than half the increase during the same period in 2021.
Therefore, if you’re new to DeFi, I would highly encourage you to dive into DeFi and explore it.
In DeFi, one of the most important topics we have is Flashloans. There are numerous tutorials out there explaining Defi and Flashloans.
Read my previous article on Uniswap’s Flashloan execution where I described Flashloan in a very descriptive way.
Flashloan is a special kind of loan where a borrower can borrow an asset as long as they return the borrowed amount and some interest before the transaction ends.
If the loan is not repaid in the same transaction, the transaction fails overall and is reverted.
Why Flashloans?
- Flash loans give you the ability to borrow as much as you want, so you can make a decent profit if you find assets with a considerable price difference.
- Flash loans allow you to pay back the loan and release the collateral so you can use it for other purposes.
Considering all these factors, lets write our Flashloan contract using Aave.
Aave is a decentralized non-custodial liquidity protocol where users can participate as depositors or borrowers.
Depositors provide liquidity to the market to earn a passive income, while borrowers are able to borrow in an overcollateralized or undercollateralized fashion.
Read more about Aave here
So let us begin with our smart contract!!
1. Create a project and install dependencies
1.1: Use the following commands on your CLI to initialize your project.
mkdir flashloan-with-aave && cd flashloan-with-aave
1.2: Run the command npx hardhat
on your CLI and choose Create a Javascript Object
; choose yes
for all the options.
2. Coding the Staking Smart Contract
2.1: Create a file named FlashLoan.sol
in the contracts
folder.
2.2: We will start with defining the Solidity Version (this will determine the Solidity Compiler, which we will also use in our hardhat.confing.js
file).
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@aave/core-v3/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";contract FlashLoanExample { }
As you’ll notice, we have imported some contracts from openzeppelin as well as aave, in order to use them in our contract.
Make sure you install them as dependencies. Use the following code for it.
npm install @openzeppelin/contracts @aave/core-v3
2.3 We are going to inherit from FlashLoanReceiverBase which is allowing us to set up our contract as the receiver for the flash loan.
contract FlashLoanExample is FlashLoanSimpleReceiverBase { }
2.4 Next up, we’re going to define our constructor that takes in the address of the Pool Contract. We’re going to use IPoolAddressProvider
as a struct type to do our job!
Then we will call the constructor of FlashLoanSimpleReceiverBase
and pass in the address of the provider.
constructor(IPoolAddressesProvider provider)
FlashLoanSimpleReceiverBase(provider) {}
2.5 Now, in order to perform the flashswap, we are going to create 2 functions for it.
- createFlashLoan(): This function takes in the asset and amount for the flashloan as the parameter.
- We will define the receiver address as equal to the current contract address.
- To perform the flash loan on aave protocol, we need to call the Lending Pool interface and pass in some parameters:
- receiver is the address of the contract that is going to receive the token that we want to borrow
- assets are array of tokens that we want to borrow
- amount will store the amount of tokens we want to borrow
- any extra data can be stored inside params
- referralCode will be equal to 0 since there’s no middle man for the execution of this transaction.
function createFlashLoan(address asset, uint amount) external {
address receiver = address(this);
bytes memory params = "";
uint16 referralCode = 0;
POOL.flashLoanSimple(
receiver,
asset,
amount,
params,
referralCode
);
}
2. executeOperation(): This is the function called by the aave protocol when we will call the POOL interface. This function will going to pass in several parameter:
- assets and amount that we requested to borrow
- premium is the fees that we need to pay back for borrowing
- initiator is the address that executed the flash loan
- and lastly, params stores any other additional data
- Then we will store the amount that we borrowed including its fees inside the variable amountOwing.
- Then we will approve aave to spend from this contract the amount that we borrowed plus the fee.
This completes our FlashLoan contract!!
Your final contract should look similar to this:
Now, its time to test our contract!
3. Test out the FlashLoan contract
To test our contract, there are certain steps that we need to follow:
3.1 We will call the function to get the instance of our contract.
Then, we are going to impersonate the account on Polygon Mainnet with the address of DAI_WHALE, which will provide us with the DAI token it has on the mainnet.
If impersonating an account on mainnet sounds new to you, read my article on how I performed a transaction using Vitalik’s account.
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [DAI_WHALE],
});
3.2 Next up, we will create a signer in order to pay off the loan with premium
const signer = await ethers.getSigner(DAI_WHALE);
await token
.connect(signer)
.transfer(_flashLoanExample.address, BALANCE_AMOUNT_DAI);
3.3 Lastly, we will perform the flash loan and ensuring that the remaining balance of FlashLoan contract is less than the amount it initially started with.
const tx = await _flashLoanExample.createFlashLoan(DAI, 1000);
await tx.wait();
const remainingBalance = await token.balanceOf(_flashLoanExample.address);
expect(remainingBalance.lt(BALANCE_AMOUNT_DAI)).to.be.true;
And that’s it! We are all set to perform our Flashloan!
Your script should be similar to this:
To test out our contract, we are going to use BuildBear.
4. Use BuildBear Node to perform FlashLoan
3.1: Creating a Private Testnet on BuildBear 🐻❄️ *(why BuildBear, you ask? Have a look over here: **Where Localhost Fails and *Win Web3 Hackathons, using BuildBear Testnet’s analytics)
3.1.1: Visit the BuildBear App. Once you login with your Github account, you will see a page similar to the image added below
Here we have to create a simple node for our Flashloan testing so we will click on the create an endpoint and we will be redirected to the node configuration page. For this article, we will be forking the polygon mainnet.
So we will provide the polygon mainnet RPC and then simply click on the create
button as shown below.
Congratulations! You have created your private testnet node!
Your page should be updated to something similar to the following:
Click on the RPC URL (either copy of click to view) to get the RPC to your private testnet.
3.2: In order to perform transactions, we need funds from faucet. Don’t worry! We don’t have to find random faucets to get test ether.
Click on the Open Faucet option and add your choose your account.
After that, click on the Add to Metamask option in the right corner of the faucet page.
Your metamask would be provided with 1,000 BB ETH immediately.
3.3: Update thehardhat.config.js
to the following:
In the networks, we have created a network called mainnet and added our RPC URL there.
3.4 To test our contract, open your terminal and use the following command to perform the test: npx hardhat test --network mainnet
This will run a test where a flash loan is executed and checking that the remaining balance of FlashLoan
contract is less than the amount it initially started with, the amount will be less because the contract had to pay a premium on the loaned amount.
The amount will be less because the contract had to pay a premium on the loaned amount
3.5 After that, you can see your transaction on BuildBear.
And can thoroughly trace out the transaction using the advanced tab.
You can check my FlashLoan Transaction for reference here
Congratulations! If you were able to make it till the end 😊
To learn more about BuildBear, read here docs
Get the above Github code from here
If you appreciate what we are doing, please follow us on Twitter and Join the Telegram group if you haven’t done yet.
And please give us a clap 👏 if you like our work.
Author:
Pari Tomar (Twitter || LinkedIn), always open to feedback and learning.
BTW, if you would know anyone who would be keen to working with BuildBear. Please have a look over here!!!