Flash Loans
Flash loans are uncollateralized loans that you borrow and repay within the same programmable transaction block (PTB). Users can borrow flash loans in the base or quote asset from any DeepBookV3 pool. Flash loans return a FlashLoan hot potato (struct with no abilities), which must be returned back to the pool by the end of the call. The transaction is atomic, so the entire transaction fails if the loan is not returned.
The quantity borrowed can be the maximum amount that the pool owns. Borrowing from a pool and trading in the same pool can result in failures because trading requires the movement of funds. If the funds are borrowed, then there are no funds to move.
How flash loans work in DeepBookV3
DeepBookV3 flash loans follow a borrow-use-return pattern enforced by Move's hot potato mechanism:
- Borrow: call
borrow_flashloan_baseorborrow_flashloan_quoteon a pool. The function returns the requested assets and aFlashLoanhot potato object. - Use: use the borrowed assets within the same PTB. Common use cases include arbitrage between pools, collateral swaps, and liquidations.
- Return: call
return_flashloan_baseorreturn_flashloan_quotebefore the PTB completes. The pool unwraps theFlashLoanhot potato only if all three of its checks pass. If you do not return the assets, the entire transaction reverts.
DeepBook charges no fee on flash loans, and the return call takes no amount parameter. It reads the amount off the FlashLoan itself and enforces three conditions:
- The returned coin holds exactly the borrowed amount, otherwise the call aborts with
EIncorrectQuantityReturned. If your strategy leaves you holding more than you borrowed, split the repayment amount off first and keep the remainder. - The loan goes back to the pool it came from (
EIncorrectLoanPool). - The loan goes back in the asset it was borrowed in (
EIncorrectTypeReturned).
Because every step executes within a single PTB, flash loans carry no default risk. Either the full borrow-and-repay cycle completes, or nothing happens.
When to use flash loans
Flash loans are useful in any scenario where you need temporary capital within a single transaction:
- Arbitrage: borrow assets, trade across pools to capture a price difference, return the loan, and keep the profit.
- Collateral swaps: replace one collateral type with another in a lending protocol without requiring upfront capital.
- Liquidations: liquidate an undercollateralized position using borrowed funds, then repay from the liquidation proceeds.
Example: borrow and return base assets in a PTB
The following TypeScript example shows how to structure a flash loan transaction using the Sui TypeScript SDK. It borrows base assets from a pool, performs an operation with the borrowed coin, then returns the assets before the PTB closes.
import { Transaction } from "@mysten/sui/transactions";
const tx = new Transaction();
// 1. Borrow base assets from the pool
const [baseCoin, flashLoan] = tx.moveCall({
target: `${DEEPBOOK_PACKAGE_ID}::pool::borrow_flashloan_base`,
arguments: [
tx.object(POOL_ID),
tx.pure.u64(BORROW_AMOUNT),
],
typeArguments: [BASE_TYPE, QUOTE_TYPE],
});
// 2. Use baseCoin here, for example by passing it to an arbitrage function
// ...
// 3. Split the exact borrowed amount back out, keeping any profit
const [repayment] = tx.splitCoins(baseCoin, [tx.pure.u64(BORROW_AMOUNT)]);
// 4. Return the base assets and the FlashLoan hot potato.
// return_flashloan_base takes no amount: the coin must hold exactly
// what you borrowed.
tx.moveCall({
target: `${DEEPBOOK_PACKAGE_ID}::pool::return_flashloan_base`,
arguments: [
tx.object(POOL_ID),
repayment,
flashLoan,
],
typeArguments: [BASE_TYPE, QUOTE_TYPE],
});
// 5. Send the remainder (your profit, or a zero-value coin) back to yourself.
// Every coin a PTB produces must be used, or the transaction aborts.
tx.transferObjects([baseCoin], signer.toSuiAddress());
await client.signAndExecuteTransaction({ signer, transaction: tx });
Replace DEEPBOOK_PACKAGE_ID, POOL_ID, BORROW_AMOUNT, BASE_TYPE, and QUOTE_TYPE with values for your target pool. The same pattern applies to quote asset flash loans using borrow_flashloan_quote and return_flashloan_quote.
API
The Pool exposes the following endpoints for flash loans. Each borrow function returns a FlashLoan hot potato (struct with no abilities), which must be returned back to the pool by the end of the call. The transaction is atomic, so the entire transaction fails if the loan is not returned.
Borrow flash loan base
Borrow base assets from the Pool. The function returns a hot potato, forcing the borrower to return the assets within the same transaction. The quantity borrowed can be the maximum amount that the pool owns.
packages/deepbook/sources/pool.move. You probably need to run `pnpm prebuild` and restart the site.Borrow flash loan quote
Borrow quote assets from the Pool. The function returns a hot potato, forcing the borrower to return the assets within the same transaction. Borrowing from a pool and trading in the same pool can result in failures because trading requires the movement of funds. If the funds are borrowed, then there are no funds to move.
packages/deepbook/sources/pool.move. You probably need to run `pnpm prebuild` and restart the site.Retrieve flash loan base
Return the flash loaned base assets to the Pool. The pool unwraps the FlashLoan object only if you return the assets, otherwise the transaction fails.
packages/deepbook/sources/pool.move. You probably need to run `pnpm prebuild` and restart the site.Retrieve flash loan quote
Return the flash loaned quote assets to the Pool. FlashLoan object is unwrapped only if the assets are returned,
otherwise the transaction fails. Because the transaction is atomic, failing to return the borrowed assets by the end of the call fails the entire transaction.
packages/deepbook/sources/pool.move. You probably need to run `pnpm prebuild` and restart the site.