PDA Bump Seed Reuse Remediation
How to fix reuse of bump seeds across multiple PDA derivations.
PDA Bump Seed Reuse Remediation
Overview
Related Detector: PDA Bump Seed Reuse
PDA bump seed reuse occurs when the same bump value is shared across PDA derivations with different seed patterns. The fix is to derive and store a separate canonical bump for each PDA type.
Recommended Fix
Before (Vulnerable)
let bump = account_data.bump;
let vault = create_program_address(&[b"vault", user, &[bump]], pid)?;
let meta = create_program_address(&[b"meta", user, &[bump]], pid)?; // Same bump!
After (Fixed)
let (vault, vault_bump) = find_program_address(&[b"vault", user], pid);
let (meta, meta_bump) = find_program_address(&[b"meta", user], pid);
account_data.vault_bump = vault_bump;
account_data.meta_bump = meta_bump;
Alternative Mitigations
1. Anchor seeds with per-account bumps
#[account(seeds = [b"vault", user.key().as_ref()], bump = vault.bump)]
pub vault: Account<'info, Vault>,
#[account(seeds = [b"meta", user.key().as_ref()], bump = meta.bump)]
pub meta: Account<'info, Metadata>,
2. Store bumps in a config struct
#[account]
pub struct PdaConfig {
pub vault_bump: u8,
pub escrow_bump: u8,
pub metadata_bump: u8,
}
Common Mistakes
Mistake 1: Using a single bump field for all PDAs
#[account]
pub struct State {
pub bump: u8, // WRONG: one bump for all PDAs
}
Each PDA type needs its own bump field.
Mistake 2: Hardcoding bump values
let bump: u8 = 255; // WRONG: hardcoded, not canonical
Always use find_program_address to derive canonical bumps.