Skip to main content
Sigvex

Hardcoded Sysvar Address Remediation

How to fix hardcoded sysvar addresses by using proper derivation functions.

Remediating Hardcoded Sysvar Addresses

Overview

Related Detector: Hardcoded Sysvar Address

Hardcoded sysvar addresses reduce code readability and increase copy-paste risk. The fix is to replace byte array constants with the corresponding sysvar::id() function calls, or use the account-validation framework’s typed sysvar accounts.

Before (Vulnerable)

use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};

const RENT_SYSVAR: [u8; 32] = [
    6, 167, 213, 23, 25, 47, 10, 175, 198, 242, 101, 227, 251, 119, 204, 122,
    218, 130, 197, 41, 208, 190, 59, 19, 110, 45, 0, 85, 32, 0, 0, 0,
];

pub fn check_rent(accounts: &[AccountInfo]) -> ProgramResult {
    if *accounts[0].key != Pubkey::from(RENT_SYSVAR) {
        return Err(ProgramError::InvalidAccountData);
    }
    Ok(())
}

After (Fixed)

use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, sysvar};

pub fn check_rent(accounts: &[AccountInfo]) -> ProgramResult {
    if *accounts[0].key != sysvar::rent::id() {
        return Err(ProgramError::InvalidAccountData);
    }
    Ok(())
}

Alternative Mitigations

  1. Anchor typed sysvar: Use Sysvar<'info, Rent> in your account struct. This eliminates manual key checking entirely.
#[derive(Accounts)]
pub struct CheckRent<'info> {
    pub rent: Sysvar<'info, Rent>,
}
  1. Sysvar::get(): For sysvars that support it, use Rent::get() to read directly from the runtime without any account input.
let rent = Rent::get()?;
  1. Centralized constants module: If derivation functions are not available, centralize sysvar addresses in a single module with clear naming instead of scattering byte arrays.

Common Mistakes

  • Replacing only some instances: Search the entire codebase for hardcoded sysvar bytes and replace all occurrences, not just the one flagged.
  • Using the wrong sysvar ID: When replacing, ensure you use the correct sysvar:: module. Mixing up sysvar::rent::id() with sysvar::clock::id() introduces a real bug.
  • Keeping the constant declaration: After switching to sysvar::id(), remove the unused byte array constant to avoid confusion.

References