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.
Recipe
// Hold: token CPI deposit to vault ATA owned by vault PDA
// Release: verify conditions -> invoke_signed transfer outWhen to reach for this:
- Marketplace escrow.
- Stake or lock tokens.
- Protocol treasury vaults.
Working Example
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:
- State updated before token CPI.
- PDA authority signs transfer.
- Amount validated against escrow record.
Deep Dive
SOL vs SPL
SOL: system transfer + PDA lamports. SPL: token account + mint checks.
ATA
Use associated token addresses for users.
Rust Notes
// Verify mint match source/dest token accounts.Gotchas
- Release before state update - Reentrancy double payout.. Fix: CEI ordering.
- Shared global vault PDA - One bug drains all.. Fix: Per-user seeds.
- Wrong mint - Steal wrong token type.. Fix: Unpack mint field.
- Escrow without cancel - Stuck funds.. Fix: Timeout cancel path.
- Authority not PDA verified - Fake escrow signer.. Fix: Derive and compare PDA.
Alternatives
| 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 |
FAQs
SOL escrow?
PDA holds lamports.
Partial release?
Supported with state.
Fees on release?
Split in same ix.
Close escrow?
Return rent after empty.
NFT escrow?
Add metadata checks.
Anchor escrow examples?
Study constraints.
Cancel who?
Buyer/seller/admin per rules.
Time lock?
Clock sysvar.
Audit?
Critical.
Token-2022?
Correct program id.
Surfpool?
Full flow test.
Insurance?
Protocol risk separate.
Related
- PDAs as Authorities - Authority
- CPI to SPL Token - Transfers
- Reentrancy & Safety - Ordering
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.