Vault & Escrow
Vaults and escrows custody SOL or SPL tokens under PDA authority until program rules release them. Correct patterns validate parties, use canonical bumps, and apply checks-effects-interactions before CPI.
Search across all documentation pages
Vaults and escrows custody SOL or SPL tokens under PDA authority until program rules release them. Correct patterns validate parties, use canonical bumps, and apply checks-effects-interactions before CPI.
// Hold: token CPI deposit to vault ATA owned by vault PDA
// Release: verify conditions -> invoke_signed transfer outWhen to reach for this:
pub fn release(bump: u8, escrow_auth: &AccountInfo, source: &AccountInfo, dest: &AccountInfo, token_program: &AccountInfo, amount: u64) -> ProgramResult {
// 1. verify escrow state Open and expiry
// 2. mark Filled in account data BEFORE CPI
let ix = spl_token::instruction::transfer(token_program.key, source.key, dest.key, escrow_auth.key, &[], amount)?;
invoke_signed(&ix, &[source.clone(), dest.clone(), escrow_auth.clone(), token_program.clone()], &[&[b"escrow", &[bump]]])
}What this demonstrates:
SOL: system transfer + PDA lamports. SPL: token account + mint checks.
Use associated token addresses for users.
// Verify mint match source/dest token accounts.| Alternative | Use When | Don't Use When |
|---|---|---|
| Third-party escrow program | Battle-tested | Composability |
| Wallet multisig | Human custody | Automation |
| Lightning/SOL native locks | Different stack | N/A |
PDA holds lamports.
Supported with state.
Split in same ix.
Return rent after empty.
Add metadata checks.
Study constraints.
Buyer/seller/admin per rules.
Clock sysvar.
Critical.
Correct program id.
Full flow test.
Protocol risk separate.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026