Any Solana protocol can verify it's inside a VAEA flash loan โ without consuming any CPI depth. 99 bytes. ~2K CU. Zero overhead.
๐ก Tip
Zero-CPI is live on Solana Devnet. The vaea-flash-ctx crate is ready for integration. Program ID: HoYiwkNB7a3gmZXEkTqLkborNDc976vKEUAzBm8YpK5E.
Overview
Today, if a Solana protocol wants to accept flash-loaned funds, it has no way to verify that a flash loan is active. Our Zero-CPI pattern solves this by letting any program read VAEA's FlashState PDA + perform instruction introspection โ without a single CPI call to VAEA.
Protocol developers will simply add vaea-flash-ctx to their Cargo.toml and call one function:
toml
[dependencies]
vaea-flash-ctx = "0.1"
The Problem
Solana has a hard CPI depth limit of 4. When a protocol calls VAEA via CPI, it consumes precious depth:
text
Classic CPI approach โ depth consumed:
Protocol.execute() โ Level 1
โ CPI: VAEA.begin_flash() โ Level 2 (system_program โ Level 3)
โ CPI: Jupiter.route() โ Level 2 (AMM.swap โ Level 3, token โ Level 4 โ )
โ CPI: VAEA.end_flash() โ Level 2 (system_program โ Level 3)
Problem: Jupiter โ AMM โ token_program uses 3 levels FROM the protocol.
If the protocol itself was called via CPI โ depth EXCEEDED. โ
Zero-CPI Pattern
Instead of CPI, the protocol simply reads the VAEA FlashState PDA as a read-only account and uses instruction introspection to verify the flash loan context. Zero CPI to VAEA โ full 4-level budget for the protocol's own logic.
rust
// Inside your program โ zero CPI to VAEA
pub fn my_self_liquidate(ctx: Context<SelfLiq>) -> Result<()> {
// Verify flash loan context โ reads PDA + sysvar, ZERO CPI
let flash = vaea_flash_ctx::verify(
&ctx.accounts.flash_state,
&ctx.accounts.sysvar_ix,
)?;
// Access loan details:
// flash.amount = borrowed amount
// flash.token_mint = what was borrowed
// flash.fee = fee that will be paid
// Your protocol keeps FULL CPI budget for its own logic:
marginfi::cpi::repay(...)?; // Level 1โ2โ3
jupiter::cpi::route(...)?; // Level 1โ2โ3โ4 โ WORKS!
Ok(())
}
CPI Depth Comparison
Scenario
Classic CPI
Zero-CPI (VAEA)
Protocol โ Marginfi repay โ token_program
3 levels โ
3 levels โ
Protocol โ Jupiter โ AMM โ token_program
4 levels โ ๏ธ
3 levels โ
ProtocolA โ ProtocolB โ Jupiter โ AMM
5 levels โ
4 levels โ
Protocol โ Sanctum โ AMM โ token_program
4 levels โ ๏ธ
3 levels โ
Our pattern saves 1 full CPI level vs classic CPI, making synthetic routes and nested protocol calls viable.
Integration Example
The transaction structure with Zero-CPI:
rust
TX: [
IX 1: VAEA.begin_flash_protocol(token, amount)
IX 2: YourProtocol.execute(flash_state_pda) โ reads PDA, zero CPI
IX 3: VAEA.end_flash_protocol()
]
// Your protocol's Accounts struct:
#[derive(Accounts)]
pub struct MyFlashAction<'info> {
/// The VAEA FlashState PDA โ read-only verification
/// CHECK: verified by vaea_flash_ctx::verify()
pub flash_state: AccountInfo<'info>,
/// Instructions sysvar โ for introspection
pub sysvar_instructions: AccountInfo<'info>,
// ... your other accounts
}
โ Owner Check
flash_state.owner == VAEA_PROGRAM_ID
โ PDA Derivation
Verify seeds match [b"flash_p", payer, caller]
โ Forward Introspection
end_flash_protocol exists AFTER current IX
โ Backward Introspection
begin_flash_protocol exists BEFORE current IX
โน๏ธ Note
The vaea-flash-ctx crate is production-ready in the VAEA monorepo. All packages (@vaea/flash on npm, vaea-flash-sdk on crates.io, vaea-flash on PyPI) will be published after mainnet validation. View on GitHub.