2

When fuzz testing outside of bpf-land (i.e. the target os is not solana), cpis will fall back to crate-level program stubs, and we can invoke spl token instructions with the handy processor:

pub struct TestSyscallStubs {
    pub unix_timestamp: Option<i64>,
}

impl program_stubs::SyscallStubs for TestSyscallStubs {
    fn sol_invoke_signed(
        &self,
        instruction: &Instruction,
        account_infos: &[AccountInfo],
        signers_seeds: &[&[&[u8]]],
    ) -> ProgramResult {
        let mut new_account_infos = vec![];
        // Fill ix account metas as needed...

        if instruction.program_id == spl_token::ID {
            spl_token::processor::Processor::process(
                &instruction.program_id,
                &new_account_infos,
                &instruction.data,
            )
        } else if instruction.program_id == system_program::ID {
            // TODO
        }
  }
}

How can we do the same kind of thing for system program instructions like a SOL transfer?

1 Answer 1

2

There's no simple way unfortunately. The system program's instruction processor is written with native program hooks like the invoke context: https://github.com/anza-xyz/agave/blob/27f4b3d3b9b2cfad274c9cb45c33ea9a4009acb0/programs/system/src/system_processor.rs#L301

You might just need to stub the instruction processor for the few functions that you care about, ie:

if instruction.program_id == system_program::ID {
    let instruction = limited_deserialize(instruction.data)?;
    match instruction {
        SystemInstruction::CreateAccount => { ... }
        SystemInstruction::Transfer => { ... }
        _ => // error for ones that you don't care about
    }
}

Once there's a BPF version of the system program, this will be much easier, but it isn't done just yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.