PDA System Collision Remediation
How to fix weak PDA seed patterns that could collide with system addresses.
PDA System Collision Remediation
Overview
Related Detector: PDA System Collision
PDA system collision vulnerabilities arise from weak seed patterns that provide insufficient entropy. The fix is to use multiple, diverse seed components including a string discriminator and entity identifiers.
Recommended Fix
Before (Vulnerable)
let pda = create_program_address(&[&[0]], program_id)?; // Single constant
After (Fixed)
let (pda, bump) = find_program_address(
&[b"vault", user.key.as_ref(), mint.key.as_ref()],
program_id,
);
Alternative Mitigations
1. Always use find_program_address for canonical bumps
// find_program_address returns the canonical (highest valid) bump
let (pda, canonical_bump) = Pubkey::find_program_address(&seeds, program_id);
// Store and reuse the canonical bump
account_data.bump = canonical_bump;
2. Multi-component seeds
// Combine multiple high-entropy sources
let (pda, _) = find_program_address(
&[b"escrow", authority.as_ref(), counterparty.as_ref(), &nonce.to_le_bytes()],
program_id,
);
3. Anchor seeds constraint
#[account(seeds = [b"vault", authority.key().as_ref()], bump)]
pub vault: Account<'info, Vault>,
Common Mistakes
Mistake 1: Single-byte seeds
// WRONG: minimal entropy
let pda = create_program_address(&[&[1]], program_id)?;
Mistake 2: Using create_program_address without find_program_address
// WRONG: non-canonical bump
let pda = create_program_address(&[b"vault", user, &[254]], program_id)?;
// CORRECT: derive canonical bump first
let (_, bump) = find_program_address(&[b"vault", user], program_id);
let pda = create_program_address(&[b"vault", user, &[bump]], program_id)?;