Skip to main content
Sigvex

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.

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)?;

References