Flash Loan

Atomic flash loans with configurable fees and LP share-based liquidity pools

Pending Anchor 0.32
Program ID 2chVPk6DV21qWuyUA2eHAzATdFSHM7ykv1fVX7Gv6nor
Default Fee 9 bps (0.09%)
Cluster Devnet

Instructions

IX initialize_pool

Creates a new lending pool for a specific SPL token mint.

ParameterTypeDescription
fee_basis_pointsu16Flash loan fee in basis points (9 = 0.09%)
IX deposit

Deposits tokens into the lending pool, receiving LP shares proportional to the pool value.

ParameterTypeDescription
amountu64Amount of tokens to deposit
IX withdraw

Burns LP shares and returns the proportional token amount (including accrued fees).

ParameterTypeDescription
shares_to_burnu64Number of LP shares to redeem
IX borrow_flash_loan

Borrows tokens atomically from the pool. Creates a receipt PDA that must be closed by repay_flash_loan within the same transaction.

ParameterTypeDescription
amountu64Amount of tokens to borrow
IX repay_flash_loan

Repays the borrowed amount plus fee. Closes the receipt PDA and refunds rent to the borrower. Fee accrues to the pool, increasing LP share value.

ParameterTypeDescription
No parameters — reads amount and fee from receipt PDA
IX update_pool_config

Admin-only instruction to update pool fee or pause/unpause the pool.

ParameterTypeDescription
new_fee_basis_pointsOption<u16>New fee (0–10000 bps)
is_activeOption<bool>Pause or unpause the pool

Accounts

LendingPool

FieldTypeDescription
adminPubkeyPool creator and admin authority
token_mintPubkeySPL token mint for this pool
vaultPubkeyPDA-owned token vault
total_depositsu64Total deposits (grows with fees)
total_sharesu64Total LP shares issued
total_fees_earnedu64Lifetime fee counter
fee_basis_pointsu16Fee rate (9 = 0.09%)
is_activeboolWhether the pool accepts loans
bumpu8PDA bump seed

DepositReceipt

FieldTypeDescription
poolPubkeyLending pool this deposit belongs to
depositorPubkeyDepositor's wallet
sharesu64LP shares owned
last_deposit_tsi64Timestamp of last deposit
bumpu8PDA bump seed

FlashLoanReceipt

FieldTypeDescription
poolPubkeyPool being borrowed from
borrowerPubkeyBorrower's wallet
amountu64Amount borrowed
feeu64Fee owed
bumpu8PDA bump seed

PDA Derivation

lending_pool
seeds = [b"lending_pool", token_mint]
pool_vault
seeds = [b"pool_vault", pool]
deposit_receipt
seeds = [b"deposit_receipt", pool, depositor]
flash_loan_receipt
seeds = [b"flash_loan_receipt", pool, borrower]

Error Codes

InvalidFee Fee must be between 0 and 10000 basis points
InsufficientLiquidity Not enough tokens in the pool for the requested loan
InvalidAmount Flash loan amount must be greater than zero
PoolPaused Pool is paused by admin
Unauthorized Signer does not match expected authority
MintMismatch Token mint does not match pool's token mint
MathOverflow Arithmetic overflow
InsufficientShares Not enough LP shares for withdrawal

Usage Example

import { getProgram, findLendingPoolPda, findFlashLoanReceiptPda } from "./src";

const flashLoan = getProgram("flashLoan", provider);

// Derive PDAs
const [poolPda] = findLendingPoolPda(tokenMint);
const [receiptPda] = findFlashLoanReceiptPda(poolPda, borrower.publicKey);

// Borrow + repay in same transaction
const borrowIx = await flashLoan.methods
  .borrowFlashLoan(new BN(1_000_000))
  .accounts({ pool: poolPda, vault, borrowerTokenAccount, borrower: borrower.publicKey })
  .instruction();

// ... your arbitrage/swap logic here ...

const repayIx = await flashLoan.methods
  .repayFlashLoan()
  .accounts({ pool: poolPda, flashLoanReceipt: receiptPda, vault, borrowerTokenAccount })
  .instruction();

// Submit as single atomic transaction
const tx = new Transaction().add(borrowIx, /* swap ixs */, repayIx);