Skip to Content

Flash Loans

Veil supports native flash loans: borrow any amount up to the pool’s free liquidity, use the funds within the same Solana transaction, and return them — plus a fee — before the transaction ends. If repayment is missing or insufficient, the entire transaction reverts.

Fee: amount × flash_fee_bps / 10_000 (default 0.09%, configurable by admin)

Fee split: 90% to LPs (added to total_deposits) · 10% to protocol (accumulated_fees)

FlashBorrow and FlashRepay must appear in the same transaction. A FlashBorrow instruction without a FlashRepay in the same transaction will cause the transaction to revert on submission (the pool validator rejects state where flash_loan_amount > 0 at end-of-transaction through Solana’s atomic execution model).


FlashBorrow

Discriminator: 0x06

Transfer amount tokens from the pool vault to the borrower. Records the in-flight amount and fee in pool.flash_loan_amount. Rejects if another flash loan is already active on this pool.

Accounts

#NameFlagsDescription
0borrowersigner, writable
1borrower_tokenwritableReceives the borrowed tokens
2vaultwritablePool vault (source)
3poolwritableflash_loan_amount is set to amount
4pool_authorityreadonlyPDA that signs the vault transfer
5token_programreadonly

Instruction Data

OffsetSizeFieldDescription
01discriminator0x06
18amountTokens to borrow (u64 LE)

Errors

  • FlashLoanActive — a flash loan is already in progress on this pool
  • InsufficientLiquidity — requested amount exceeds available liquidity
  • ZeroAmount — amount is zero
  • PoolPaused — pool is paused

FlashRepay

Discriminator: 0x07

Return the borrowed tokens plus the fee. Distributes the fee between LPs and the protocol treasury, then clears pool.flash_loan_amount.

Accounts

#NameFlagsDescription
0borrowersigner, writable
1borrower_tokenwritableSource token account (repays principal + fee)
2vaultwritablePool vault (destination)
3poolwritable
4token_programreadonly

Instruction Data

OffsetSizeFieldDescription
01discriminator0x07
18amountTokens to repay including fee (u64 LE)

The required repayment is pool.flash_loan_amount + fee. Any amount below this returns FlashLoanRepayInsufficient.

Errors

  • FlashLoanNotActive — no flash loan is in progress
  • FlashLoanRepayInsufficientamount < principal + fee

Usage Pattern

import { flashBorrowIx, flashRepayIx, } from './lib/veil/instructions'; const loanAmount = 1_000_000n; // 1 USDC (6 decimals) const fee = (loanAmount * 9n) / 10_000n; // 0.09% = 900 const repayAmount = loanAmount + fee; // Your custom instruction that uses the borrowed funds const myInstruction = buildMyArbitrageInstruction(loanAmount); const tx = new Transaction() .add(flashBorrowIx(borrower, borrowerToken, vault, pool, poolAuthority, loanAmount)) .add(myInstruction) .add(flashRepayIx(borrower, borrowerToken, vault, pool, repayAmount)); await sendAndConfirmTransaction(connection, tx, [borrowerKeypair]);

Fee Calculation

function flashFee(amount: bigint, feeRateBps: bigint): bigint { return (amount * feeRateBps) / 10_000n; } function flashFeeSplit(fee: bigint): { lp: bigint; protocol: bigint } { const protocol = fee / 10n; return { lp: fee - protocol, protocol }; }
Last updated on