๐Ÿ“ฆ FlashState PDA

FlashState PDA

The FlashState PDA is the core data structure that makes Zero-CPI verification possible. It's created by begin_flash, read by your program, and closed by end_flash โ€” all within a single transaction.

Account Layout (99 bytes)

OffsetSizeFieldTypeDescription
08discriminatoru8[8]Anchor account discriminator
832payerPubkeyBorrower public key
4032token_mintPubkeyBorrowed token mint address
728amountu64Amount borrowed (native units)
808fee_lamportsu64VAEA fee (native units)
881source_tieru80 = SDK, 1 = UI, 2 = Protocol
898slot_createdu64Slot when begin_flash executed
971bumpu8PDA bump seed
981versionu8Schema version (currently 1)

PDA Derivation

The FlashState PDA is derived from three seeds:

rust
seeds = [b"flash", payer.key().as_ref(), token_mint.key().as_ref()]
bump = flash_state.bump

// Program ID: HoYiwkNB7a3gmZXEkTqLkborNDc976vKEUAzBm8YpK5E

This means each (payer, token_mint) pair produces a unique PDA. A borrower cannot have two simultaneous flash loans for the same token.

Lifecycle

StepInstructionFlashState PDA
1begin_flashCreated โ€” rent paid by payer, 99 bytes allocated
2Your instruction(s)Exists โ€” your program reads it via verify()
3end_flashClosed โ€” rent refunded to payer, account deleted

The PDA is ephemeral โ€” it exists only for the duration of the transaction. After end_flash, the account no longer exists on-chain. It cannot be replayed or reused.

Why 99 Bytes?

99 bytes is the minimum viable state for flash loan verification. For comparison:

ProtocolState SizeAccounts/IX
VAEA FlashState99 B5
Marginfi flash loan state~4,000 B11
Kamino flash loan state~2,000 B11
Jupiter Lend state~1,200 B9

Smaller state = less rent = lower transaction cost. The rent for 99 bytes (~0.001 SOL) is reclaimed when the PDA is closed at end_flash.

Deriving from Client (TypeScript)

If you need to derive the FlashState PDA address from your frontend or bot (e.g., to pass it to your program):

typescript
import { deriveFlashStatePDA } from '@vaea/flash';
import { PublicKey } from '@solana/web3.js';

const pda = deriveFlashStatePDA(
  walletPubkey,
  new PublicKey('So11111111111111111111111111111111111111112') // SOL mint
);

// Pass pda as the flash_state account in your instruction

Reading from Client (TypeScript)

You can read an active FlashState PDA from TypeScript using the SDK:

typescript
import { readFlashState } from '@vaea/flash';

const state = await readFlashState(connection, pda);

if (state) {
  console.log('Active loan:', state.amount, 'of', state.tokenMint.toString());
  console.log('Fee:', state.fee);
  console.log('Slot:', state.slotCreated);
}
โ„น๏ธ Note
The FlashState PDA is read-only for your program. Only the VAEA program can create or close it. This is enforced by Solana's ownership model โ€” only the owner program can modify an account's data.
โš ๏ธ Devnet Only
Mainnet โ€” April 2026
๐Ÿ”