Flash Loans are special transactions that allow the borrowing of an asset, as long as the borrowed amount (and a fee) is returned before the end of the transaction (also called One Block Borrows). These transactions do not require a user to supply collateral prior to engaging in the transaction. There is no real world analogy to Flash Loans, so it requires some basic understanding of how state is managed within blocks in blockchains.
Flash Loans are an advanced concept aimed at developers. You must have a good understanding of EVM, programming, and smart contracts to be able to use this feature.
Flash-loan allows users to access liquidity of the pool (only for reserves for which borrow is enabled) for one transaction as long as the amount taken plus fee is returned or (if allowed) debt position is opened by the end of the transaction.
Spark Protocol offers two options for flash loans:
flashLoan: Allows borrower to access liquidity of multiple reserves in single flashLoan transaction. The borrower also has an option to open stable or variabled rate debt position backed by supplied collateral or credit delegation in this case. NOTE: flash loan fee is waived for approved
flashBorrowers(managed by ACLManager)
flashLoanSimple: Allows borrower to access liquidity of single reserve for the transaction. In this case flash loan fee is not waived nor can borrower open any debt position at the end of the transaction. This method is gas efficient for those trying take advantage of simple flash loan with single reserve asset.
For developers, a helpful mental model to consider when developing your solution:
- 2.After some sanity checks, the
Pooltransfers the requested
reservesto your contract, then calls
- 3.Your contract, now holding the flash loaned
amount(s), executes any arbitrary operation in its code.
- If you are performing a flashLoanSimple, then when your code has finished, you approve Pool for flash loaned amount + fee.
- If you are performing flashLoan, then for all the reserves either depending on
interestRateModepassed for the asset, either the Pool must be approved for flash loaned amount + fee or must or sufficient collateral or credit delegation should be available to open debt position.
- If the amount owing is not available (due to a lack of balance or approval or insufficient collateral for debt), then the transaction is reverted.
- 4.All of the above happens in 1 transaction (hence in a single ethereum block).
Spark Protocol Flash Loans are already used with Spark Protocol for liquidity swap feature. Other examples in the wild include:
- Arbitrage between assets, without needing to have the principal amount to execute the arbitrage.
- Liquidating borrow positions, without having to repay the debt of the positions and using discounted collateral claimed to payoff flashLoan amount + fee.
Flashloan fee can be shared by the LPs (liquidity providers) and the protocol treasury. The
FLASHLOAN_PREMIUM_TOTALrepresents the total fee paid by the borrowers of which:
- Fee to LP:
FLASHLOAN_PREMIUM_TOTAL - FLASHLOAN_PREMIUM_TO_PROTOCOL
- Fee to Protocol:
FLASHLOAN_PREMIUM_TO_PROTOCOLis set to 0.
Also note that since the owed amounts will be pulled from your contract, your contract must give allowance to the
Poolto pull those funds to pay back the flash loan amount + premiums.
To call either of the two flash loan methods on the Pool, we need to pass in the relevant parameters. There are 3 ways you can do this.
- 2.From a different contractSimilar to sending a transaction from an EOA as above, ensure the
receiverAddressis your contract address from step 1.\
- 3.From the same contractIf you want to use the same contract as in step 1, use
receiverAddressparameter in the flash loan method.
Once you have performed your logic with the flash loaned assets (in your
executeOperation()function), you will need to pay back the flash loaned amounts if you used
flashLoan()for any of the assets in
- Paying back a flash loaned assetEnsure your contract has the relevant amount + premium to payback the borrowed asset. You can calculate this by taking the sum of the relevant entry in the
premiumsarray passed into the
executeOperation()function.\You do not need to transfer the owed amount back to the
Pool. The funds will be automatically pulled at the conclusion of your operation.
- Incurring a debt (i.e. not immediately paying back)If you initially used a
mode=2for any of the assets in the
modesparameter, then the address passed in for
onBehalfOfwill incur the debt if the
onBehalfOfaddress has previously approved the
msg.senderto incur debts on their behalf.This means that you can have some assets that are paid back immediately, while other assets incur a debt.