diff --git a/Cargo.lock b/Cargo.lock index 49d5c8b1a..092e20598 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2123,7 +2123,7 @@ checksum = "7c76b6234c13c9ea73946d1379d33186151148e0da231506b964b44f3d023505" dependencies = [ "arbitrary", "lazy_static", - "memmap2 0.9.4", + "memmap2 0.9.5", "rustc_version", ] @@ -2517,19 +2517,18 @@ dependencies = [ [[package]] name = "lz4" -version = "1.26.0" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958b4caa893816eea05507c20cfe47574a43d9a697138a7872990bba8a0ece68" +checksum = "a231296ca742e418c43660cb68e082486ff2538e8db432bc818580f3965025ed" dependencies = [ - "libc", "lz4-sys", ] [[package]] name = "lz4-sys" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868" +checksum = "fcb44a01837a858d47e5a630d2ccf304c8efcc4b83b8f9f75b7a9ee4fcc6e57d" dependencies = [ "cc", "libc", @@ -2552,9 +2551,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] @@ -2891,9 +2890,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "33ea5043e58958ee56f3e15a90aee535795cd7dfd319846288d93c5b57d85cbe" [[package]] name = "opaque-debug" @@ -6068,9 +6067,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" diff --git a/crates/client/src/source_code_generators/fuzz_instructions_generator.rs b/crates/client/src/source_code_generators/fuzz_instructions_generator.rs index 758a48305..afd221ff3 100644 --- a/crates/client/src/source_code_generators/fuzz_instructions_generator.rs +++ b/crates/client/src/source_code_generators/fuzz_instructions_generator.rs @@ -1,99 +1,173 @@ -use std::collections::HashMap; - -use syn::{parse_quote, parse_str}; - +use anchor_lang_idl_spec::{Idl, IdlInstructionAccountItem, IdlType}; use convert_case::{Case, Casing}; -use quote::{format_ident, ToTokens}; - -use anchor_lang_idl_spec::{Idl, IdlInstruction, IdlInstructionAccountItem, IdlType}; +use quote::{format_ident, quote, ToTokens}; +use std::collections::{HashMap, HashSet}; +use syn::{parse_quote, parse_str}; +// Main function to generate source code from IDLs pub fn generate_source_code(idls: &[Idl]) -> String { - let code = idls - .iter() - .map(|idl| { - let program_name = idl.metadata.name.to_case(Case::Snake); - let fuzz_instructions_module_name = format_ident!("{}_fuzz_instructions", program_name); + // Collections to store generated items + let mut all_instructions: Vec = Vec::new(); + let mut all_instruction_inputs: Vec = Vec::new(); + let mut all_instructions_ixops_impls: Vec = Vec::new(); + let mut all_fuzz_accounts: Vec = Vec::new(); + let mut all_snapshot_types: Vec = Vec::new(); + + // Mappings for instructions and accounts + let mut instructions_mappings: HashMap = HashMap::new(); + let mut accounts_mappings: HashMap = HashMap::new(); + + // Extract unique instructions and accounts across all IDLs + get_unique_accounts_n_instructions(idls, &mut instructions_mappings, &mut accounts_mappings); + + // Iterate over each IDL to generate various parts of the code + for idl in idls { + all_instructions.extend(get_instruction_variants(idl, &instructions_mappings)); + all_instruction_inputs.extend(get_instruction_inputs(idl, &instructions_mappings)); + all_instructions_ixops_impls.extend(get_instruction_ixops(idl, &instructions_mappings)); + all_snapshot_types.extend(get_snapshot_types(idl, &instructions_mappings)); + all_fuzz_accounts.extend(get_fuzz_accounts(idl, &accounts_mappings)); + } - let instructions = idl.instructions.iter().map(|instruction| { - let instruction_name = instruction.name.to_case(Case::UpperCamel); - let instruction_struct_name: syn::Ident = parse_str(&instruction_name).unwrap(); + // Define the Rust module with all generated code + let module_definition = quote! { + use trident_client::fuzzing::*; - // Generate enum variant for the instruction - let enum_variant: syn::Variant = parse_quote! { - #instruction_struct_name(#instruction_struct_name) - }; + #(#all_snapshot_types)* - enum_variant - }); + #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] + pub enum FuzzInstruction { + #(#all_instructions),* + } - let instruction_inputs = get_instruction_inputs(&idl.instructions); - let instructions_ixops_impls = get_instruction_ixops(&idl.instructions, program_name); - let fuzz_accounts = get_fuzz_accounts(&idl.instructions); - let snapshot_types = get_snapshot_types(&idl.instructions); + #(#all_instruction_inputs)* - let module_definition: syn::ItemMod = parse_quote! { - pub mod #fuzz_instructions_module_name { - use trident_client::fuzzing::*; + #(#all_instructions_ixops_impls)* - #(#snapshot_types)* + /// Use AccountsStorage where T can be one of: + /// Keypair, PdaStore, TokenStore, MintStore, ProgramStore + #[derive(Default)] + pub struct FuzzAccounts { + #(#all_fuzz_accounts),* + } + }; - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - #(#instructions),* - } + // Convert the module definition to a string and return it + module_definition.into_token_stream().to_string() +} - #(#instruction_inputs)* +// Function to get unique accounts and instructions across all IDLs +fn get_unique_accounts_n_instructions( + idls: &[Idl], + instructions_mappings: &mut HashMap, + accounts_mappings: &mut HashMap, +) { + for idl in idls { + let mut seen_accounts: HashSet = HashSet::new(); - #(#instructions_ixops_impls)* + for instruction in idl.instructions.iter() { + let instruction_name = instruction.name.to_case(Case::UpperCamel); + *instructions_mappings.entry(instruction_name).or_insert(0) += 1; - // FIX this is just a workaround to propagate a comment to the source code easily - /// Use AccountsStorage where T can be one of: - /// Keypair, PdaStore, TokenStore, MintStore, ProgramStore - #[derive(Default)] - pub struct FuzzAccounts { - #(#fuzz_accounts),* + for account in instruction.accounts.iter() { + let account_name = match account { + IdlInstructionAccountItem::Composite(_) => { + panic!("Composite Accounts are not supported yet!") } - + IdlInstructionAccountItem::Single(single_account) => { + let account_name = single_account.name.clone(); + account_name.to_case(Case::Snake) + } + }; + // Only add the account if it hasn't been seen in this IDL yet + if !seen_accounts.contains(&account_name) { + *accounts_mappings + .entry(account_name.to_string()) + .or_insert(0) += 1; + seen_accounts.insert(account_name); } + } + } + } +} + +// Generate instruction variants for the enum +fn get_instruction_variants( + idl: &Idl, + instruction_mappings: &HashMap, +) -> Vec { + let program_name = idl.metadata.name.to_case(Case::UpperCamel); + + idl.instructions + .iter() + .fold(Vec::new(), |mut variants, instruction| { + let mut instruction_name = instruction.name.to_case(Case::UpperCamel); + let count = instruction_mappings.get(&instruction_name).unwrap_or(&1); + + // Append the program name if the instruction name is not unique + if *count > 1 { + instruction_name.push_str(&program_name); + } + + let instruction_struct_name: syn::Ident = parse_str(&instruction_name).unwrap(); + let variant: syn::Variant = parse_quote! { + #instruction_struct_name(#instruction_struct_name) }; - module_definition.into_token_stream().to_string() + variants.push(variant); + variants }) - .collect::(); - - code } -fn get_snapshot_types(instructions: &[IdlInstruction]) -> Vec { - instructions +// Generate snapshot types for each instruction +fn get_snapshot_types(idl: &Idl, instruction_mappings: &HashMap) -> Vec { + let program_name = idl.metadata.name.to_case(Case::UpperCamel); + + idl.instructions .iter() .fold(Vec::new(), |mut snapshot_types, instruction| { - let instruction_name = instruction.name.to_case(Case::UpperCamel); + let mut instruction_name = instruction.name.to_case(Case::UpperCamel); + let count = instruction_mappings.get(&instruction_name).unwrap_or(&1); + + // Append the program name if the instruction name is not unique + if *count > 1 { + instruction_name.push_str(&program_name); + } let ix_snapshot: syn::Ident = format_ident!("{}Snapshot", &instruction_name); let ix_alias: syn::Ident = format_ident!("{}Alias", &instruction_name); let snapshot_type: syn::ItemType = parse_quote!(type #ix_snapshot<'info> = #ix_alias<'info>;); - snapshot_types.push(snapshot_type); snapshot_types }) } -fn get_instruction_inputs(instructions: &[IdlInstruction]) -> Vec { - instructions +// Generate input structures for each instruction +fn get_instruction_inputs( + idl: &Idl, + instruction_mappings: &HashMap, +) -> Vec { + let program_name = idl.metadata.name.to_case(Case::UpperCamel); + + idl.instructions .iter() .fold(Vec::new(), |mut instructions_data, instruction| { - let instruction_name = instruction.name.to_case(Case::UpperCamel); + let mut instruction_name = instruction.name.to_case(Case::UpperCamel); + let count = instruction_mappings.get(&instruction_name).unwrap_or(&1); - let instruction_name_ident: syn::Ident = format_ident!("{}", &instruction_name); + // Append the program name if the instruction name is not unique + if *count > 1 { + instruction_name.push_str(&program_name); + } + let instruction_name_ident: syn::Ident = format_ident!("{}", &instruction_name); let instruction_data_name: syn::Ident = format_ident!("{}Data", &instruction_name); - let instruction_accounts_name: syn::Ident = format_ident!("{}Accounts", &instruction_name); + // Generate accounts and parameters let accounts = instruction .accounts .iter() @@ -114,21 +188,19 @@ fn get_instruction_inputs(instructions: &[IdlInstruction]) -> Vec>(); + // Define the input structures let instructions_inputs: syn::ItemStruct = parse_quote! { #[derive(Arbitrary, Debug)] pub struct #instruction_name_ident { pub accounts: #instruction_accounts_name, pub data: #instruction_data_name } - }; let instructions_input_accounts: syn::ItemStruct = parse_quote! { @@ -136,7 +208,6 @@ fn get_instruction_inputs(instructions: &[IdlInstruction]) -> Vec Vec Vec, ) -> Vec { - let module_name: syn::Ident = parse_str(&program_name).unwrap(); + let module_name: syn::Ident = parse_str(&idl.metadata.name).unwrap(); + let program_name = idl.metadata.name.to_case(Case::UpperCamel); - instructions + idl.instructions .iter() .fold(Vec::new(), |mut instructions_ixops_impl, instruction| { - let instruction_name = instruction.name.to_case(Case::UpperCamel); - + let mut instruction_name = instruction.name.to_case(Case::UpperCamel); let instruction_ident_name: syn::Ident = format_ident!("{}", &instruction_name); + let count = instruction_mappings.get(&instruction_name).unwrap_or(&1); + + // Append the program name if the instruction name is not unique + if *count > 1 { + instruction_name.push_str(&program_name); + } + let instruction_ident_name_modified: syn::Ident = + format_ident!("{}", &instruction_name); let ix_snapshot: syn::Ident = format_ident!("{}Snapshot", &instruction_name); + // Map arguments to their types let parameters = instruction .args .iter() .map(|arg| { let arg_name = format_ident!("{}", arg.name); - let parameter: syn::FieldValue = match arg.ty { IdlType::Pubkey => parse_quote!(#arg_name: todo!()), IdlType::String => { @@ -198,19 +277,21 @@ fn get_instruction_ixops( parse_quote!(#arg_name: #arg_value) } }; - parameter }) .collect::>(); + // Define the implementation of the IxOps trait let ix_impl: syn::ItemImpl = parse_quote! { - impl<'info> IxOps<'info> for #instruction_ident_name { + impl<'info> IxOps<'info> for #instruction_ident_name_modified { type IxData = #module_name::instruction::#instruction_ident_name; type IxAccounts = FuzzAccounts; type IxSnapshot = #ix_snapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { #module_name::ID } + fn get_data( &self, _client: &mut impl FuzzClient, @@ -233,7 +314,6 @@ fn get_instruction_ixops( Ok((signers, acc_meta)) } } - }; instructions_ixops_impl.push(ix_impl); @@ -241,8 +321,12 @@ fn get_instruction_ixops( }) } -fn get_fuzz_accounts(instructions: &[IdlInstruction]) -> Vec { - let fuzz_accounts = instructions.iter().fold( +// Generate accounts for fuzzing +fn get_fuzz_accounts(idl: &Idl, accounts_mappings: &HashMap) -> Vec { + let program_name = idl.metadata.name.to_case(Case::Snake); + + // Create a HashMap to collect all fuzz accounts + let fuzz_accounts = idl.instructions.iter().fold( HashMap::new(), |mut fuzz_accounts: HashMap, instruction| { instruction @@ -254,7 +338,15 @@ fn get_fuzz_accounts(instructions: &[IdlInstruction]) -> Vec { panic!("Composite Accounts are not supported yet!") } IdlInstructionAccountItem::Single(single) => { - let name: syn::Ident = format_ident!("{}", &single.name); + let mut account_name = single.name.to_case(Case::Snake); + let count = accounts_mappings.get(&account_name).unwrap_or(&1); + + // Append the program name if the account name is not unique + if *count > 1 { + account_name.push_str(&format!("_{}", &program_name)); + } + + let name: syn::Ident = format_ident!("{}", &account_name); let account = match single.pda { Some(_) => parse_quote! { #name: AccountsStorage }, None => parse_quote! { #name: AccountsStorage }, @@ -267,15 +359,14 @@ fn get_fuzz_accounts(instructions: &[IdlInstruction]) -> Vec { fuzz_accounts }, ); - let mut sorted_accounts: Vec<_> = fuzz_accounts.into_iter().collect(); + // Sort and return the fuzz accounts + let mut sorted_accounts: Vec<_> = fuzz_accounts.into_iter().collect(); sorted_accounts.sort_by(|(k1, _), (k2, _)| k1.cmp(k2)); - - // Extract the FnArg values into a Vec sorted_accounts.into_iter().map(|(_, v)| v).collect() } -/// Converts an `IdlType` to a corresponding Rust `syn::Type`. +// Converts an `IdlType` to a corresponding Rust `syn::Type`. fn idl_type_to_syn_type(idl_type: &IdlType) -> syn::Type { match idl_type { IdlType::Bool => parse_quote!(bool), @@ -306,7 +397,6 @@ fn idl_type_to_syn_type(idl_type: &IdlType) -> syn::Type { } IdlType::Array(inner, len) => { let inner_type = get_inner_type(inner, 0); - let len = match len { anchor_lang_idl_spec::IdlArrayLen::Generic(_generic) => { panic!("Generic within Array len not supported") @@ -315,8 +405,7 @@ fn idl_type_to_syn_type(idl_type: &IdlType) -> syn::Type { }; parse_quote!([#inner_type;#len]) } - // TODO try to automatically generate the struct so we can simply - // derive arbitrary + // Handle defined types IdlType::Defined { name, generics: _ } => { let name_ident: syn::Ident = format_ident!("{}", &name); parse_quote!(#name_ident) @@ -328,6 +417,7 @@ fn idl_type_to_syn_type(idl_type: &IdlType) -> syn::Type { } } +// Helper function to get the inner type from an `IdlType` fn get_inner_type(idl_type: &IdlType, nestings: u8) -> syn::Type { if nestings >= 5 { panic!("No more than 5 nestings allowed"); @@ -361,7 +451,6 @@ fn get_inner_type(idl_type: &IdlType, nestings: u8) -> syn::Type { } IdlType::Array(inner, len) => { let inner_type = get_inner_type(inner, nestings + 1); - let len = match len { anchor_lang_idl_spec::IdlArrayLen::Generic(_generic) => { panic!("Generic within Array len not supported") diff --git a/crates/client/src/source_code_generators/test_fuzz_generator.rs b/crates/client/src/source_code_generators/test_fuzz_generator.rs index f67604e52..96a1795f0 100644 --- a/crates/client/src/source_code_generators/test_fuzz_generator.rs +++ b/crates/client/src/source_code_generators/test_fuzz_generator.rs @@ -6,35 +6,17 @@ use syn::parse_quote; pub fn generate_source_code(idl_instructions: &[Idl]) -> String { let program_imports = get_program_imports(idl_instructions); let program_names = get_program_names(idl_instructions); - let fuzz_instructions = get_fuzz_instructions(idl_instructions); let (fuzzing_programs, programs_array) = get_fuzzing_programs(idl_instructions); - let main_fuzz_instruction: syn::ItemType = match fuzz_instructions.len() { - 1 => { - let program_name = idl_instructions[0].metadata.name.to_case(Case::Snake); - let alias = format_ident!("fuzz_instruction_{}", program_name); - - parse_quote!( - pub type FuzzInstruction = #alias; - ) - } - _ => parse_quote!( - pub type FuzzInstruction = todo!(); - ), - }; - let test_fuzz_definition: syn::File = parse_quote! { use trident_client::fuzzing::*; mod fuzz_instructions; + use fuzz_instructions::FuzzInstruction; #(#program_imports)* #(#program_names)* - #(#fuzz_instructions)* - - #main_fuzz_instruction - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData {} @@ -66,16 +48,6 @@ pub fn generate_source_code(idl_instructions: &[Idl]) -> String { test_fuzz_definition.into_token_stream().to_string() } -fn get_fuzz_instructions(idl_instructions: &[Idl]) -> Vec { - idl_instructions.iter().map(|idl| { - let program_name = idl.metadata.name.to_case(Case::Snake); - let fuzz_instructions_program_ident = format_ident!("{}_fuzz_instructions", program_name); - let alias = format_ident!("fuzz_instruction_{}", program_name); - - parse_quote!(use fuzz_instructions::#fuzz_instructions_program_ident::FuzzInstruction as #alias;) - }).collect() -} - fn get_program_names(idl_instructions: &[Idl]) -> Vec { idl_instructions .iter() diff --git a/crates/client/tests/anchor_idl/dummy_2.json b/crates/client/tests/anchor_idl/dummy_2.json new file mode 100644 index 000000000..78c4f65aa --- /dev/null +++ b/crates/client/tests/anchor_idl/dummy_2.json @@ -0,0 +1,175 @@ +{ + "address": "BssCdiqmJQnEXLrudod2FpsLqgkTwPnzmgojnmBCHbk5", + "metadata": { + "name": "dummy_2", + "version": "0.1.0", + "spec": "0.1.0", + "description": "Created with Anchor" + }, + "instructions": [ + { + "name": "initialize_ix", + "discriminator": [ + 150, + 84, + 235, + 128, + 82, + 59, + 240, + 136 + ], + "accounts": [ + { + "name": "signer", + "signer": true + } + ], + "args": [ + { + "name": "_var1", + "type": "bool" + }, + { + "name": "_var2", + "type": "u8" + }, + { + "name": "_var3", + "type": "i8" + }, + { + "name": "_var4", + "type": "u16" + }, + { + "name": "_var5", + "type": "i16" + }, + { + "name": "_var6", + "type": "u32" + }, + { + "name": "_var7", + "type": "i32" + }, + { + "name": "_var8", + "type": "u64" + }, + { + "name": "_var9", + "type": "i32" + }, + { + "name": "_var10", + "type": "f64" + }, + { + "name": "_var11", + "type": "u128" + }, + { + "name": "_var12", + "type": "i128" + }, + { + "name": "_ver13", + "type": "bytes" + }, + { + "name": "_var14", + "type": "string" + }, + { + "name": "_var15", + "type": "pubkey" + }, + { + "name": "_var16", + "type": { + "option": "i16" + } + }, + { + "name": "_var17", + "type": { + "vec": "u32" + } + }, + { + "name": "_var18", + "type": { + "array": [ + "i128", + 5 + ] + } + }, + { + "name": "_var19", + "type": { + "defined": { + "name": "InputParameter" + } + } + }, + { + "name": "_var20", + "type": { + "vec": { + "vec": { + "vec": { + "vec": "bytes" + } + } + } + } + }, + { + "name": "_var21", + "type": { + "vec": { + "vec": { + "vec": { + "vec": { + "option": "u8" + } + } + } + } + } + }, + { + "name": "_var22", + "type": { + "vec": { + "vec": { + "vec": { + "vec": { + "option": "bytes" + } + } + } + } + } + } + ] + } + ], + "types": [ + { + "name": "InputParameter", + "type": { + "kind": "struct", + "fields": [ + { + "name": "field1", + "type": "u8" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/crates/client/tests/anchor_idl/example.json b/crates/client/tests/anchor_idl/dummy_example.json similarity index 99% rename from crates/client/tests/anchor_idl/example.json rename to crates/client/tests/anchor_idl/dummy_example.json index d695238e7..16bfc9647 100644 --- a/crates/client/tests/anchor_idl/example.json +++ b/crates/client/tests/anchor_idl/dummy_example.json @@ -278,4 +278,4 @@ } } ] -} +} \ No newline at end of file diff --git a/crates/client/tests/expected_source_codes/expected_fuzz_instructions.rs b/crates/client/tests/expected_source_codes/expected_fuzz_instructions.rs index f4f1b4926..91b147a89 100644 --- a/crates/client/tests/expected_source_codes/expected_fuzz_instructions.rs +++ b/crates/client/tests/expected_source_codes/expected_fuzz_instructions.rs @@ -1,118 +1,201 @@ -pub mod dummy_example_fuzz_instructions { - use trident_client::fuzzing::*; - type InitializeIxSnapshot<'info> = InitializeIxAlias<'info>; - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - InitializeIx(InitializeIx), +use trident_client::fuzzing::*; +type InitializeIxDummy2Snapshot<'info> = InitializeIxDummy2Alias<'info>; +type InitializeIxDummyExampleSnapshot<'info> = InitializeIxDummyExampleAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + InitializeIxDummy2(InitializeIxDummy2), + InitializeIxDummyExample(InitializeIxDummyExample), +} +#[derive(Arbitrary, Debug)] +pub struct InitializeIxDummy2 { + pub accounts: InitializeIxDummy2Accounts, + pub data: InitializeIxDummy2Data, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeIxDummy2Accounts { + pub signer: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeIxDummy2Data { + pub _var1: bool, + pub _var2: u8, + pub _var3: i8, + pub _var4: u16, + pub _var5: i16, + pub _var6: u32, + pub _var7: i32, + pub _var8: u64, + pub _var9: i32, + pub _var10: f64, + pub _var11: u128, + pub _var12: i128, + pub _ver13: Vec, + pub _var14: String, + pub _var15: AccountId, + pub _var16: Option, + pub _var17: Vec, + pub _var18: [i128; 5usize], + pub _var19: InputParameter, + pub _var20: Vec>>>>, + pub _var21: Vec>>>>, + pub _var22: Vec>>>>>, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeIxDummyExample { + pub accounts: InitializeIxDummyExampleAccounts, + pub data: InitializeIxDummyExampleData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeIxDummyExampleAccounts { + pub account: AccountId, + pub account_info: AccountId, + pub account_loader: AccountId, + pub boxed: AccountId, + pub interace: AccountId, + pub interface_account: AccountId, + pub option: AccountId, + pub program: AccountId, + pub signer: AccountId, + pub system_account: AccountId, + pub sysvar: AccountId, + pub unchecked_account: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeIxDummyExampleData { + pub _var1: bool, + pub _var2: u8, + pub _var3: i8, + pub _var4: u16, + pub _var5: i16, + pub _var6: u32, + pub _var7: i32, + pub _var8: u64, + pub _var9: i32, + pub _var10: f64, + pub _var11: u128, + pub _var12: i128, + pub _ver13: Vec, + pub _var14: String, + pub _var15: AccountId, + pub _var16: Option, + pub _var17: Vec, + pub _var18: [i128; 5usize], + pub _var19: InputParameter, + pub _var20: Vec>>>>, + pub _var21: Vec>>>>, + pub _var22: Vec>>>>>, +} +impl<'info> IxOps<'info> for InitializeIxDummy2 { + type IxData = dummy_2::instruction::InitializeIx; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeIxDummy2Snapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + dummy_2::ID } - #[derive(Arbitrary, Debug)] - pub struct InitializeIx { - pub accounts: InitializeIxAccounts, - pub data: InitializeIxData, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = dummy_2::instruction::InitializeIx { + _var1: self.data._var1, + _var2: self.data._var2, + _var3: self.data._var3, + _var4: self.data._var4, + _var5: self.data._var5, + _var6: self.data._var6, + _var7: self.data._var7, + _var8: self.data._var8, + _var9: self.data._var9, + _var10: self.data._var10, + _var11: self.data._var11, + _var12: self.data._var12, + _ver13: self.data._ver13.clone(), + _var14: self.data._var14.clone(), + _var15: todo!(), + _var16: self.data._var16, + _var17: self.data._var17.clone(), + _var18: self.data._var18, + _var19: todo!(), + _var20: self.data._var20.clone(), + _var21: self.data._var21.clone(), + _var22: self.data._var22.clone(), + }; + Ok(data) } - #[derive(Arbitrary, Debug)] - pub struct InitializeIxAccounts { - pub account: AccountId, - pub account_info: AccountId, - pub account_loader: AccountId, - pub boxed: AccountId, - pub interace: AccountId, - pub interface_account: AccountId, - pub option: AccountId, - pub program: AccountId, - pub signer: AccountId, - pub system_account: AccountId, - pub sysvar: AccountId, - pub unchecked_account: AccountId, + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let signers = vec![todo!()]; + let acc_meta = todo!(); + Ok((signers, acc_meta)) } - #[derive(Arbitrary, Debug)] - pub struct InitializeIxData { - pub _var1: bool, - pub _var2: u8, - pub _var3: i8, - pub _var4: u16, - pub _var5: i16, - pub _var6: u32, - pub _var7: i32, - pub _var8: u64, - pub _var9: i32, - pub _var10: f64, - pub _var11: u128, - pub _var12: i128, - pub _ver13: Vec, - pub _var14: String, - pub _var15: AccountId, - pub _var16: Option, - pub _var17: Vec, - pub _var18: [i128; 5usize], - pub _var19: InputParameter, - pub _var20: Vec>>>>, - pub _var21: Vec>>>>, - pub _var22: Vec>>>>>, +} +impl<'info> IxOps<'info> for InitializeIxDummyExample { + type IxData = dummy_example::instruction::InitializeIx; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeIxDummyExampleSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + dummy_example::ID } - impl<'info> IxOps<'info> for InitializeIx { - type IxData = dummy_example::instruction::InitializeIx; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitializeIxSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - dummy_example::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = dummy_example::instruction::InitializeIx { - _var1: self.data._var1, - _var2: self.data._var2, - _var3: self.data._var3, - _var4: self.data._var4, - _var5: self.data._var5, - _var6: self.data._var6, - _var7: self.data._var7, - _var8: self.data._var8, - _var9: self.data._var9, - _var10: self.data._var10, - _var11: self.data._var11, - _var12: self.data._var12, - _ver13: self.data._ver13.clone(), - _var14: self.data._var14.clone(), - _var15: todo!(), - _var16: self.data._var16, - _var17: self.data._var17.clone(), - _var18: self.data._var18, - _var19: todo!(), - _var20: self.data._var20.clone(), - _var21: self.data._var21.clone(), - _var22: self.data._var22.clone(), - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let signers = vec![todo!()]; - let acc_meta = todo!(); - Ok((signers, acc_meta)) - } + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = dummy_example::instruction::InitializeIx { + _var1: self.data._var1, + _var2: self.data._var2, + _var3: self.data._var3, + _var4: self.data._var4, + _var5: self.data._var5, + _var6: self.data._var6, + _var7: self.data._var7, + _var8: self.data._var8, + _var9: self.data._var9, + _var10: self.data._var10, + _var11: self.data._var11, + _var12: self.data._var12, + _ver13: self.data._ver13.clone(), + _var14: self.data._var14.clone(), + _var15: todo!(), + _var16: self.data._var16, + _var17: self.data._var17.clone(), + _var18: self.data._var18, + _var19: todo!(), + _var20: self.data._var20.clone(), + _var21: self.data._var21.clone(), + _var22: self.data._var22.clone(), + }; + Ok(data) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - account: AccountsStorage, - account_info: AccountsStorage, - account_loader: AccountsStorage, - boxed: AccountsStorage, - interace: AccountsStorage, - interface_account: AccountsStorage, - option: AccountsStorage, - program: AccountsStorage, - signer: AccountsStorage, - system_account: AccountsStorage, - sysvar: AccountsStorage, - unchecked_account: AccountsStorage, + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let signers = vec![todo!()]; + let acc_meta = todo!(); + Ok((signers, acc_meta)) } } +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + signer_dummy_2: AccountsStorage, + account: AccountsStorage, + account_info: AccountsStorage, + account_loader: AccountsStorage, + boxed: AccountsStorage, + interace: AccountsStorage, + interface_account: AccountsStorage, + option: AccountsStorage, + program: AccountsStorage, + signer_dummy_example: AccountsStorage, + system_account: AccountsStorage, + sysvar: AccountsStorage, + unchecked_account: AccountsStorage, +} diff --git a/crates/client/tests/expected_source_codes/expected_test_fuzz.rs b/crates/client/tests/expected_source_codes/expected_test_fuzz.rs index bf69ebc93..4dce8fb05 100644 --- a/crates/client/tests/expected_source_codes/expected_test_fuzz.rs +++ b/crates/client/tests/expected_source_codes/expected_test_fuzz.rs @@ -2,14 +2,15 @@ use trident_client::fuzzing::*; mod fuzz_instructions; +use dummy_2::entry as entry_dummy_2; +use dummy_2::ID as PROGRAM_ID_DUMMY_2; use dummy_example::entry as entry_dummy_example; use dummy_example::ID as PROGRAM_ID_DUMMY_EXAMPLE; +use fuzz_instructions::FuzzInstruction; -const PROGRAM_NAME_DUMMY_EXAMPLE: &str = "dummy_example"; - -use fuzz_instructions::dummy_example_fuzz_instructions::FuzzInstruction as fuzz_instruction_dummy_example; +const PROGRAM_NAME_DUMMY_2: &str = "dummy_2"; -pub type FuzzInstruction = fuzz_instruction_dummy_example; +const PROGRAM_NAME_DUMMY_EXAMPLE: &str = "dummy_example"; struct MyFuzzData; @@ -17,13 +18,23 @@ impl FuzzDataBuilder for MyFuzzData {} fn fuzz_iteration + std::fmt::Display, U>(fuzz_data: FuzzData) { + let fuzzing_program_dummy_2 = FuzzingProgram::new( + PROGRAM_NAME_DUMMY_2, + &PROGRAM_ID_DUMMY_2, + processor!(convert_entry!(entry_dummy_2)), + ); + let fuzzing_program_dummy_example = FuzzingProgram::new( PROGRAM_NAME_DUMMY_EXAMPLE, &PROGRAM_ID_DUMMY_EXAMPLE, processor!(convert_entry!(entry_dummy_example)), ); - let mut client = ProgramTestClientBlocking::new(&[fuzzing_program_dummy_example], &[]).unwrap(); + let mut client = ProgramTestClientBlocking::new( + &[fuzzing_program_dummy_2, fuzzing_program_dummy_example], + &[], + ) + .unwrap(); let _ = fuzz_data.run_with_runtime(&mut client); } diff --git a/crates/client/tests/test_fuzz.rs b/crates/client/tests/test_fuzz.rs index 4b4cdb0d8..9740526a1 100644 --- a/crates/client/tests/test_fuzz.rs +++ b/crates/client/tests/test_fuzz.rs @@ -16,10 +16,13 @@ async fn test_fuzz_instructions() { "/tests/expected_source_codes/expected_fuzz_instructions.rs" )); - let idl = read_idl()?; + let idl_2 = read_idl("dummy_2.json")?; + let idl_dummy = read_idl("dummy_example.json")?; let fuzz_instructions_code = - trident_client::___private::fuzz_instructions_generator::generate_source_code(&vec![idl]); + trident_client::___private::fuzz_instructions_generator::generate_source_code(&vec![ + idl_2, idl_dummy, + ]); let fuzz_instructions_code = trident_client::___private::Commander::format_program_code(&fuzz_instructions_code).await?; @@ -35,10 +38,12 @@ async fn test_fuzz_test() { "/tests/expected_source_codes/expected_test_fuzz.rs" )); - let idl = read_idl()?; + let idl_2 = read_idl("dummy_2.json")?; + let idl_dummy = read_idl("dummy_example.json")?; - let test_fuzz = - trident_client::___private::test_fuzz_generator::generate_source_code(&vec![idl]); + let test_fuzz = trident_client::___private::test_fuzz_generator::generate_source_code(&vec![ + idl_2, idl_dummy, + ]); let test_fuzz = trident_client::___private::Commander::format_program_code_nightly(&test_fuzz).await?; @@ -47,12 +52,12 @@ async fn test_fuzz_test() { } #[throws] -fn read_idl() -> Idl { +fn read_idl(_idl_name: &str) -> Idl { let current_dir = std::env::current_dir()?; let anchor_idl_path: PathBuf = [ current_dir.as_ref(), - Path::new("tests/anchor_idl/example.json"), + Path::new(&format!("tests/anchor_idl/{}", _idl_name)), ] .iter() .collect(); diff --git a/examples/fuzz-tests/arbitrary-custom-types-4/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/arbitrary-custom-types-4/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index 2bdc01249..62bf91ca5 100644 --- a/examples/fuzz-tests/arbitrary-custom-types-4/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/arbitrary-custom-types-4/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,169 +1,167 @@ -pub mod arbitrary_custom_types_4_fuzz_instructions { - use solana_sdk::native_token::LAMPORTS_PER_SOL; - use trident_client::fuzzing::*; +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; - use arbitrary_custom_types_4::trident_fuzz_initialize_snapshot::InitializeAlias; - use arbitrary_custom_types_4::trident_fuzz_update_snapshot::UpdateAlias; - - type InitializeSnapshot<'info> = InitializeAlias<'info>; - type UpdateSnapshot<'info> = UpdateAlias<'info>; - - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - Initialize(Initialize), - Update(Update), - } - #[derive(Arbitrary, Debug)] - pub struct Initialize { - pub accounts: InitializeAccounts, - pub data: InitializeData, - } - #[derive(Arbitrary, Debug)] - pub struct InitializeAccounts { - pub counter: AccountId, - pub user: AccountId, - pub system_program: AccountId, - } - #[derive(Arbitrary, Debug)] - pub struct InitializeData {} - #[derive(Arbitrary, Debug)] - pub struct Update { - pub accounts: UpdateAccounts, - pub data: UpdateData, - } - #[derive(Arbitrary, Debug)] - pub struct UpdateAccounts { - pub counter: AccountId, - pub authority: AccountId, +use arbitrary_custom_types_4::trident_fuzz_initialize_snapshot::InitializeAlias; +use arbitrary_custom_types_4::trident_fuzz_update_snapshot::UpdateAlias; +type InitializeSnapshot<'info> = InitializeAlias<'info>; +type UpdateSnapshot<'info> = UpdateAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + Initialize(Initialize), + Update(Update), +} +#[derive(Arbitrary, Debug)] +pub struct Initialize { + pub accounts: InitializeAccounts, + pub _data: InitializeData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeAccounts { + pub counter: AccountId, + pub user: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeData {} +#[derive(Arbitrary, Debug)] +pub struct Update { + pub accounts: UpdateAccounts, + pub data: UpdateData, +} +#[derive(Arbitrary, Debug)] +pub struct UpdateAccounts { + pub counter: AccountId, + pub authority: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct UpdateData { + pub input: InputUpdatePrameters, + pub variant: InputUpdateVariant, +} +impl<'info> IxOps<'info> for Initialize { + type IxData = arbitrary_custom_types_4::instruction::Initialize; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + arbitrary_custom_types_4::ID } - #[derive(Arbitrary, Debug)] - pub struct UpdateData { - pub input: InputUpdatePrameters, - pub variant: InputUpdateVariant, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = arbitrary_custom_types_4::instruction::Initialize {}; + Ok(data) } - impl<'info> IxOps<'info> for Initialize { - type IxData = arbitrary_custom_types_4::instruction::Initialize; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitializeSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - arbitrary_custom_types_4::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = arbitrary_custom_types_4::instruction::Initialize {}; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let user = fuzz_accounts.user.get_or_create_account( - self.accounts.user, - client, - 5 * LAMPORTS_PER_SOL, - ); - let counter = fuzz_accounts.counter.get_or_create_account( - self.accounts.counter, - client, - 5 * LAMPORTS_PER_SOL, - ); + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let user = fuzz_accounts.user.get_or_create_account( + self.accounts.user, + client, + 5 * LAMPORTS_PER_SOL, + ); + let counter = fuzz_accounts.counter.get_or_create_account( + self.accounts.counter, + client, + 5 * LAMPORTS_PER_SOL, + ); - let acc_meta = arbitrary_custom_types_4::accounts::Initialize { - counter: counter.pubkey(), - user: user.pubkey(), - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((vec![user, counter], acc_meta)) + let acc_meta = arbitrary_custom_types_4::accounts::Initialize { + counter: counter.pubkey(), + user: user.pubkey(), + system_program: solana_sdk::system_program::ID, } + .to_account_metas(None); + Ok((vec![user, counter], acc_meta)) } - impl<'info> IxOps<'info> for Update { - type IxData = arbitrary_custom_types_4::instruction::Update; - type IxAccounts = FuzzAccounts; - type IxSnapshot = UpdateSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - arbitrary_custom_types_4::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let input = self.data.input.into(); - let variant = self.data.variant.into(); +} +impl<'info> IxOps<'info> for Update { + type IxData = arbitrary_custom_types_4::instruction::Update; + type IxAccounts = FuzzAccounts; + type IxSnapshot = UpdateSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + arbitrary_custom_types_4::ID + } + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let input = self.data.input.into(); + let variant = self.data.variant.into(); - let data = arbitrary_custom_types_4::instruction::Update { input, variant }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let user = fuzz_accounts.user.get_or_create_account( - self.accounts.authority, - client, - 15 * LAMPORTS_PER_SOL, - ); - let counter = fuzz_accounts.counter.get_or_create_account( - self.accounts.counter, - client, - 5 * LAMPORTS_PER_SOL, - ); + let data = arbitrary_custom_types_4::instruction::Update { input, variant }; + Ok(data) + } + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let user = fuzz_accounts.user.get_or_create_account( + self.accounts.authority, + client, + 15 * LAMPORTS_PER_SOL, + ); + let counter = fuzz_accounts.counter.get_or_create_account( + self.accounts.counter, + client, + 5 * LAMPORTS_PER_SOL, + ); - let acc_meta = arbitrary_custom_types_4::accounts::Update { - counter: counter.pubkey(), - authority: user.pubkey(), - } - .to_account_metas(None); - Ok((vec![user], acc_meta)) + let acc_meta = arbitrary_custom_types_4::accounts::Update { + counter: counter.pubkey(), + authority: user.pubkey(), } + .to_account_metas(None); + Ok((vec![user], acc_meta)) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - user: AccountsStorage, - counter: AccountsStorage, - } +} +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + user: AccountsStorage, + counter: AccountsStorage, + // _authority: AccountsStorage, + // _system_program: AccountsStorage, +} - // ------------------------------------------------------------------- - // ------------------------------------------------------------------- - // ------------------------------------------------------------------- - // Use arbitrary section - #[derive(Arbitrary, Debug, Clone, Copy)] - pub struct InputUpdatePrameters { - pub input1: u8, - pub input2: u8, - } +// ------------------------------------------------------------------- +// ------------------------------------------------------------------- +// ------------------------------------------------------------------- +// Use arbitrary section +#[derive(Arbitrary, Debug, Clone, Copy)] +pub struct InputUpdatePrameters { + pub input1: u8, + pub input2: u8, +} - #[derive(Arbitrary, Debug, Clone, Copy)] - pub enum InputUpdateVariant { - UpdateVariant1, - UpdateVariant2, - } +#[derive(Arbitrary, Debug, Clone, Copy)] +pub enum InputUpdateVariant { + UpdateVariant1, + UpdateVariant2, +} - impl std::convert::From for arbitrary_custom_types_4::InputUpdatePrameters { - fn from(val: InputUpdatePrameters) -> Self { - arbitrary_custom_types_4::InputUpdatePrameters { - input1: val.input1, - input2: val.input2, - } +impl std::convert::From for arbitrary_custom_types_4::InputUpdatePrameters { + fn from(val: InputUpdatePrameters) -> Self { + arbitrary_custom_types_4::InputUpdatePrameters { + input1: val.input1, + input2: val.input2, } } - impl std::convert::From for arbitrary_custom_types_4::InputUpdateVariant { - fn from(val: InputUpdateVariant) -> Self { - match val { - InputUpdateVariant::UpdateVariant1 => { - arbitrary_custom_types_4::InputUpdateVariant::UpdateVariant1 - } - InputUpdateVariant::UpdateVariant2 => { - arbitrary_custom_types_4::InputUpdateVariant::UpdateVariant2 - } +} +impl std::convert::From for arbitrary_custom_types_4::InputUpdateVariant { + fn from(val: InputUpdateVariant) -> Self { + match val { + InputUpdateVariant::UpdateVariant1 => { + arbitrary_custom_types_4::InputUpdateVariant::UpdateVariant1 + } + InputUpdateVariant::UpdateVariant2 => { + arbitrary_custom_types_4::InputUpdateVariant::UpdateVariant2 } } } diff --git a/examples/fuzz-tests/arbitrary-custom-types-4/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/arbitrary-custom-types-4/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index a020ee579..a429af20d 100644 --- a/examples/fuzz-tests/arbitrary-custom-types-4/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/arbitrary-custom-types-4/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -1,18 +1,15 @@ -use fuzz_instructions::arbitrary_custom_types_4_fuzz_instructions::Initialize; -use fuzz_instructions::arbitrary_custom_types_4_fuzz_instructions::Update; +use fuzz_instructions::Initialize; +use fuzz_instructions::Update; use trident_client::fuzzing::*; mod fuzz_instructions; use arbitrary_custom_types_4::entry as entry_arbitrary_custom_types_4; use arbitrary_custom_types_4::ID as PROGRAM_ID_ARBITRARY_CUSTOM_TYPES_4; +use fuzz_instructions::FuzzInstruction; const PROGRAM_NAME_ARBITRARY_CUSTOM_TYPES_4: &str = "arbitrary_custom_types_4"; -use fuzz_instructions::arbitrary_custom_types_4_fuzz_instructions::FuzzInstruction as fuzz_instruction_arbitrary_custom_types_4; - -pub type FuzzInstruction = fuzz_instruction_arbitrary_custom_types_4; - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData { diff --git a/examples/fuzz-tests/arbitrary-limit-inputs-5/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/arbitrary-limit-inputs-5/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index 066dc1f20..9c6c2ecbf 100644 --- a/examples/fuzz-tests/arbitrary-limit-inputs-5/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/arbitrary-limit-inputs-5/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,357 +1,356 @@ -pub mod arbitrary_limit_inputs_5_fuzz_instructions { - use solana_sdk::native_token::LAMPORTS_PER_SOL; - use trident_client::fuzzing::*; +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; - use arbitrary_limit_inputs_5::trident_fuzz_init_vesting_context_snapshot::InitVestingContextAlias; - use arbitrary_limit_inputs_5::trident_fuzz_withdraw_unlocked_snapshot::WithdrawUnlockedAlias; +use arbitrary_limit_inputs_5::trident_fuzz_init_vesting_context_snapshot::InitVestingContextAlias; +use arbitrary_limit_inputs_5::trident_fuzz_withdraw_unlocked_snapshot::WithdrawUnlockedAlias; - type InitVestingSnapshot<'info> = InitVestingContextAlias<'info>; - type WithdrawUnlockedSnapshot<'info> = WithdrawUnlockedAlias<'info>; +type InitVestingSnapshot<'info> = InitVestingContextAlias<'info>; +type WithdrawUnlockedSnapshot<'info> = WithdrawUnlockedAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + InitVesting(InitVesting), + WithdrawUnlocked(WithdrawUnlocked), +} +#[derive(Arbitrary, Debug)] +pub struct InitVesting { + pub accounts: InitVestingAccounts, + pub data: InitVestingData, +} +#[derive(Arbitrary, Debug)] +pub struct InitVestingAccounts { + pub sender: AccountId, + pub sender_token_account: AccountId, + pub escrow: AccountId, + pub escrow_token_account: AccountId, + pub _mint: AccountId, + pub _token_program: AccountId, + pub _system_program: AccountId, +} +#[derive(Debug)] +pub struct InitVestingData { + pub recipient: AccountId, + // This is also possible to limit the input data however you neet do specify + // `#[derive(Arbitrary,Debug)]` above + // #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1..=1_000_000))] + pub amount: u64, + // #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(0..=1_000_000))] + pub start_at: u64, + // #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1_001_001..=1_050_000))] + pub end_at: u64, + // #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1..=1000))] + pub interval: u64, +} - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - InitVesting(InitVesting), - WithdrawUnlocked(WithdrawUnlocked), - } - #[derive(Arbitrary, Debug)] - pub struct InitVesting { - pub accounts: InitVestingAccounts, - pub data: InitVestingData, - } - #[derive(Arbitrary, Debug)] - pub struct InitVestingAccounts { - pub sender: AccountId, - pub sender_token_account: AccountId, - pub escrow: AccountId, - pub escrow_token_account: AccountId, - pub mint: AccountId, - pub token_program: AccountId, - pub system_program: AccountId, - } - #[derive(Debug)] - pub struct InitVestingData { - pub recipient: AccountId, - // This is also possible to limit the input data however you neet do specify - // `#[derive(Arbitrary,Debug)]` above - // #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1..=1_000_000))] - pub amount: u64, - // #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(0..=1_000_000))] - pub start_at: u64, - // #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1_001_001..=1_050_000))] - pub end_at: u64, - // #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1..=1000))] - pub interval: u64, - } - // ------------------------------------------------------------------- - // ------------------------------------------------------------------- - // Implement Arbitrary - impl<'a> Arbitrary<'a> for InitVestingData { - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - // obtain AccountId - let recipient = AccountId::arbitrary(u)?; +// ------------------------------------------------------------------- +// ------------------------------------------------------------------- +// Implement Arbitrary +impl<'a> Arbitrary<'a> for InitVestingData { + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + // obtain AccountId + let recipient = AccountId::arbitrary(u)?; - // limit the generated amount to the 1_000_000 - let amount = u.int_in_range(1..=1_000_000)?; + // limit the generated amount to the 1_000_000 + let amount = u.int_in_range(1..=1_000_000)?; - // now we want to obtain - // - start_at - // - end_at - // - interval - // however we want to limit the data such that: - // - start_at < end_at - // - end_at - start_at > interval - // - interval has lower limit of 500 and upper limit of 1000. + // now we want to obtain + // - start_at + // - end_at + // - interval + // however we want to limit the data such that: + // - start_at < end_at + // - end_at - start_at > interval + // - interval has lower limit of 500 and upper limit of 1000. - let start_at: u64 = u.int_in_range(1_000_000..=5_000_000)?; - let end_at: u64 = u.int_in_range(1_000_000..=5_000_000)?; - let interval: u64 = u.int_in_range(500..=1000)?; + let start_at: u64 = u.int_in_range(1_000_000..=5_000_000)?; + let end_at: u64 = u.int_in_range(1_000_000..=5_000_000)?; + let interval: u64 = u.int_in_range(500..=1000)?; - // ensure that start_at < end_at - if start_at >= end_at { - return Err(arbitrary::Error::IncorrectFormat); - } + // ensure that start_at < end_at + if start_at >= end_at { + return Err(arbitrary::Error::IncorrectFormat); + } - // ensure that end_at - start_at > interval - match end_at.checked_sub(start_at) { - Some(diff) => { - if diff <= interval { - return Err(arbitrary::Error::IncorrectFormat); - } + // ensure that end_at - start_at > interval + match end_at.checked_sub(start_at) { + Some(diff) => { + if diff <= interval { + return Err(arbitrary::Error::IncorrectFormat); } - None => return Err(arbitrary::Error::IncorrectFormat), } - - Ok(InitVestingData { - recipient, - amount, - start_at, - end_at, - interval, - }) + None => return Err(arbitrary::Error::IncorrectFormat), } - // ------------------------------------------------------------------- - // ------------------------------------------------------------------- + + Ok(InitVestingData { + recipient, + amount, + start_at, + end_at, + interval, + }) } - #[derive(Arbitrary, Debug)] - pub struct WithdrawUnlocked { - pub accounts: WithdrawUnlockedAccounts, - pub data: WithdrawUnlockedData, + // ------------------------------------------------------------------- + // ------------------------------------------------------------------- +} + +#[derive(Arbitrary, Debug)] +pub struct WithdrawUnlocked { + pub accounts: WithdrawUnlockedAccounts, + pub _data: WithdrawUnlockedData, +} +#[derive(Arbitrary, Debug)] +pub struct WithdrawUnlockedAccounts { + pub recipient: AccountId, + pub recipient_token_account: AccountId, + pub escrow: AccountId, + pub escrow_token_account: AccountId, + pub escrow_pda_authority: AccountId, + pub _mint: AccountId, + pub _token_program: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct WithdrawUnlockedData {} +impl<'info> IxOps<'info> for InitVesting { + type IxData = arbitrary_limit_inputs_5::instruction::InitVesting; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitVestingSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + arbitrary_limit_inputs_5::ID } - #[derive(Arbitrary, Debug)] - pub struct WithdrawUnlockedAccounts { - pub recipient: AccountId, - pub recipient_token_account: AccountId, - pub escrow: AccountId, - pub escrow_token_account: AccountId, - pub escrow_pda_authority: AccountId, - pub mint: AccountId, - pub token_program: AccountId, - pub system_program: AccountId, + fn get_data( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let recipient = fuzz_accounts.recipient.get_or_create_account( + self.data.recipient, + client, + 10 * LAMPORTS_PER_SOL, + ); + let data = arbitrary_limit_inputs_5::instruction::InitVesting { + recipient: recipient.pubkey(), + amount: self.data.amount, + start_at: self.data.start_at, + end_at: self.data.end_at, + interval: self.data.interval, + }; + Ok(data) } - #[derive(Arbitrary, Debug)] - pub struct WithdrawUnlockedData {} - impl<'info> IxOps<'info> for InitVesting { - type IxData = arbitrary_limit_inputs_5::instruction::InitVesting; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitVestingSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - arbitrary_limit_inputs_5::ID - } - fn get_data( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let recipient = fuzz_accounts.recipient.get_or_create_account( - self.data.recipient, - client, - 10 * LAMPORTS_PER_SOL, - ); - let data = arbitrary_limit_inputs_5::instruction::InitVesting { - recipient: recipient.pubkey(), - amount: self.data.amount, - start_at: self.data.start_at, - end_at: self.data.end_at, - interval: self.data.interval, - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let sender = fuzz_accounts.sender.get_or_create_account( - self.accounts.sender, - client, - 5 * LAMPORTS_PER_SOL, - ); - // INFO use constant Account ID, so we will not generate multiple mints, - // and also we can easily link to Withdraw - let mint = fuzz_accounts - .mint - .get_or_create_account(0, client, 6, &sender.pubkey(), None) - .unwrap(); - - let sender_token_account = fuzz_accounts - .sender_token_account - .get_or_create_account( - self.accounts.sender_token_account, - client, - mint, - sender.pubkey(), - u64::MAX, - None, - None, - 0, - None, - ) - .unwrap(); + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let sender = fuzz_accounts.sender.get_or_create_account( + self.accounts.sender, + client, + 5 * LAMPORTS_PER_SOL, + ); + // INFO use constant Account ID, so we will not generate multiple mints, + // and also we can easily link to Withdraw + let mint = fuzz_accounts + .mint + .get_or_create_account(0, client, 6, &sender.pubkey(), None) + .unwrap(); - let recipient = fuzz_accounts.recipient.get_or_create_account( - self.data.recipient, + let sender_token_account = fuzz_accounts + .sender_token_account + .get_or_create_account( + self.accounts.sender_token_account, client, - 10 * LAMPORTS_PER_SOL, - ); - let escrow = fuzz_accounts - .escrow - .get_or_create_account( - self.accounts.escrow, - &[recipient.pubkey().as_ref(), b"ESCROW_SEED"], - &arbitrary_limit_inputs_5::ID, - ) - .unwrap(); + mint, + sender.pubkey(), + u64::MAX, + None, + None, + 0, + None, + ) + .unwrap(); - let escrow_token_account = fuzz_accounts - .escrow_token_account - .get_or_create_account( - self.accounts.escrow_token_account, - client, - mint, - sender.pubkey(), - 0, - None, - None, - 0, - None, - ) - .unwrap(); + let recipient = fuzz_accounts.recipient.get_or_create_account( + self.data.recipient, + client, + 10 * LAMPORTS_PER_SOL, + ); + let escrow = fuzz_accounts + .escrow + .get_or_create_account( + self.accounts.escrow, + &[recipient.pubkey().as_ref(), b"ESCROW_SEED"], + &arbitrary_limit_inputs_5::ID, + ) + .unwrap(); - let acc_meta = arbitrary_limit_inputs_5::accounts::InitVestingContext { - sender: sender.pubkey(), - sender_token_account, - escrow: escrow.pubkey(), - escrow_token_account, + let escrow_token_account = fuzz_accounts + .escrow_token_account + .get_or_create_account( + self.accounts.escrow_token_account, + client, mint, - token_program: anchor_spl::token::ID, - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); + sender.pubkey(), + 0, + None, + None, + 0, + None, + ) + .unwrap(); - Ok((vec![sender], acc_meta)) + let acc_meta = arbitrary_limit_inputs_5::accounts::InitVestingContext { + sender: sender.pubkey(), + sender_token_account, + escrow: escrow.pubkey(), + escrow_token_account, + mint, + token_program: anchor_spl::token::ID, + system_program: solana_sdk::system_program::ID, } - } - impl<'info> IxOps<'info> for WithdrawUnlocked { - type IxData = arbitrary_limit_inputs_5::instruction::WithdrawUnlocked; - type IxAccounts = FuzzAccounts; - type IxSnapshot = WithdrawUnlockedSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - arbitrary_limit_inputs_5::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = arbitrary_limit_inputs_5::instruction::WithdrawUnlocked {}; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let recipient = fuzz_accounts.recipient.get_or_create_account( - self.accounts.recipient, - client, - 5 * LAMPORTS_PER_SOL, - ); + .to_account_metas(None); - // INFO use constant Account ID, so we will not generate multiple mints, - // and also we can easily link to Initialize - let mint = fuzz_accounts - .mint - .get_or_create_account(0, client, 6, &recipient.pubkey(), None) - .unwrap(); + Ok((vec![sender], acc_meta)) + } +} +impl<'info> IxOps<'info> for WithdrawUnlocked { + type IxData = arbitrary_limit_inputs_5::instruction::WithdrawUnlocked; + type IxAccounts = FuzzAccounts; + type IxSnapshot = WithdrawUnlockedSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + arbitrary_limit_inputs_5::ID + } + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = arbitrary_limit_inputs_5::instruction::WithdrawUnlocked {}; + Ok(data) + } + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let recipient = fuzz_accounts.recipient.get_or_create_account( + self.accounts.recipient, + client, + 5 * LAMPORTS_PER_SOL, + ); - let recipient_token_account = fuzz_accounts - .recipient_token_account - .get_or_create_account( - self.accounts.recipient_token_account, - client, - mint, - recipient.pubkey(), - 0, - None, - None, - 0, - None, - ) - .unwrap(); + // INFO use constant Account ID, so we will not generate multiple mints, + // and also we can easily link to Initialize + let mint = fuzz_accounts + .mint + .get_or_create_account(0, client, 6, &recipient.pubkey(), None) + .unwrap(); - let escrow = fuzz_accounts - .escrow - .get_or_create_account( - self.accounts.escrow, - &[recipient.pubkey().as_ref(), b"ESCROW_SEED"], - &arbitrary_limit_inputs_5::ID, - ) - .unwrap(); + let recipient_token_account = fuzz_accounts + .recipient_token_account + .get_or_create_account( + self.accounts.recipient_token_account, + client, + mint, + recipient.pubkey(), + 0, + None, + None, + 0, + None, + ) + .unwrap(); - let escrow_pda_authority = fuzz_accounts - .escrow_pda_authority - .get_or_create_account( - self.accounts.escrow_pda_authority, - &[b"ESCROW_PDA_AUTHORITY"], - &arbitrary_limit_inputs_5::ID, - ) - .unwrap(); + let escrow = fuzz_accounts + .escrow + .get_or_create_account( + self.accounts.escrow, + &[recipient.pubkey().as_ref(), b"ESCROW_SEED"], + &arbitrary_limit_inputs_5::ID, + ) + .unwrap(); - let escrow_token_account = fuzz_accounts - .escrow_token_account - .get_or_create_account( - self.accounts.escrow_token_account, - client, - mint, - escrow_pda_authority.pubkey(), - u64::MAX, - None, - None, - 0, - None, - ) - .unwrap(); + let escrow_pda_authority = fuzz_accounts + .escrow_pda_authority + .get_or_create_account( + self.accounts.escrow_pda_authority, + &[b"ESCROW_PDA_AUTHORITY"], + &arbitrary_limit_inputs_5::ID, + ) + .unwrap(); - let acc_meta = arbitrary_limit_inputs_5::accounts::WithdrawUnlocked { - recipient: recipient.pubkey(), - recipient_token_account, - escrow: escrow.pubkey(), - escrow_token_account, - escrow_pda_authority: escrow_pda_authority.pubkey(), + let escrow_token_account = fuzz_accounts + .escrow_token_account + .get_or_create_account( + self.accounts.escrow_token_account, + client, mint, - token_program: anchor_spl::token::ID, - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((vec![recipient], acc_meta)) + escrow_pda_authority.pubkey(), + u64::MAX, + None, + None, + 0, + None, + ) + .unwrap(); + + let acc_meta = arbitrary_limit_inputs_5::accounts::WithdrawUnlocked { + recipient: recipient.pubkey(), + recipient_token_account, + escrow: escrow.pubkey(), + escrow_token_account, + escrow_pda_authority: escrow_pda_authority.pubkey(), + mint, + token_program: anchor_spl::token::ID, + system_program: solana_sdk::system_program::ID, } - fn check( - &self, - pre_ix: Self::IxSnapshot, - post_ix: Self::IxSnapshot, - _ix_data: Self::IxData, - ) -> Result<(), FuzzingError> { - if let Some(escrow) = pre_ix.escrow { - let recipient = pre_ix.recipient; - let recipient_token_account_pre = pre_ix.recipient_token_account; - let recipient_token_account_post = post_ix.recipient_token_account; - if escrow.recipient == *recipient.key { - if recipient_token_account_pre.amount == recipient_token_account_post.amount { - // Recipient was not able to withdraw - return Err(FuzzingError::BalanceMismatch); - } else if recipient_token_account_pre.amount + escrow.amount - != recipient_token_account_post.amount + .to_account_metas(None); + Ok((vec![recipient], acc_meta)) + } + fn check( + &self, + pre_ix: Self::IxSnapshot, + post_ix: Self::IxSnapshot, + _ix_data: Self::IxData, + ) -> Result<(), FuzzingError> { + if let Some(escrow) = pre_ix.escrow { + let recipient = pre_ix.recipient; + let recipient_token_account_pre = pre_ix.recipient_token_account; + let recipient_token_account_post = post_ix.recipient_token_account; + if escrow.recipient == *recipient.key { + if recipient_token_account_pre.amount == recipient_token_account_post.amount { + // Recipient was not able to withdraw + return Err(FuzzingError::BalanceMismatch); + } else if recipient_token_account_pre.amount + escrow.amount + != recipient_token_account_post.amount + { + if recipient_token_account_pre.amount + escrow.amount + > recipient_token_account_post.amount { - if recipient_token_account_pre.amount + escrow.amount - > recipient_token_account_post.amount - { - // Recipient withdraw less - return Err(FuzzingError::Custom(15)); - } else { - // Recipient withdraw more - return Err(FuzzingError::Custom(2)); - } + // Recipient withdraw less + return Err(FuzzingError::Custom(15)); + } else { + // Recipient withdraw more + return Err(FuzzingError::Custom(2)); } } } - Ok(()) } + Ok(()) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - // No need to fuzz Token Program - // token_program: AccountsStorage, - sender_token_account: AccountsStorage, - escrow_token_account: AccountsStorage, - escrow_pda_authority: AccountsStorage, - sender: AccountsStorage, - // No need to fuzz System Program - // _system_program: AccountsStorage, - recipient_token_account: AccountsStorage, - recipient: AccountsStorage, - mint: AccountsStorage, - escrow: AccountsStorage, - } +} +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + // No need to fuzz Token Program + // token_program: AccountsStorage, + sender_token_account: AccountsStorage, + escrow_token_account: AccountsStorage, + escrow_pda_authority: AccountsStorage, + sender: AccountsStorage, + // No need to fuzz System Program + // _system_program: AccountsStorage, + recipient_token_account: AccountsStorage, + recipient: AccountsStorage, + mint: AccountsStorage, + escrow: AccountsStorage, } diff --git a/examples/fuzz-tests/arbitrary-limit-inputs-5/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/arbitrary-limit-inputs-5/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index 2951707da..b8f9fa055 100644 --- a/examples/fuzz-tests/arbitrary-limit-inputs-5/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/arbitrary-limit-inputs-5/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -1,18 +1,15 @@ -use fuzz_instructions::arbitrary_limit_inputs_5_fuzz_instructions::InitVesting; -use fuzz_instructions::arbitrary_limit_inputs_5_fuzz_instructions::WithdrawUnlocked; +use fuzz_instructions::InitVesting; +use fuzz_instructions::WithdrawUnlocked; use trident_client::fuzzing::*; mod fuzz_instructions; use arbitrary_limit_inputs_5::entry as entry_arbitrary_limit_inputs_5; use arbitrary_limit_inputs_5::ID as PROGRAM_ID_ARBITRARY_LIMIT_INPUTS_5; +use fuzz_instructions::FuzzInstruction; const PROGRAM_NAME_ARBITRARY_LIMIT_INPUTS_5: &str = "arbitrary_limit_inputs_5"; -use fuzz_instructions::arbitrary_limit_inputs_5_fuzz_instructions::FuzzInstruction as fuzz_instruction_arbitrary_limit_inputs_5; - -pub type FuzzInstruction = fuzz_instruction_arbitrary_limit_inputs_5; - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData { diff --git a/examples/fuzz-tests/cpi-metaplex-7/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/cpi-metaplex-7/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index a2bb3718d..cae273ca7 100644 --- a/examples/fuzz-tests/cpi-metaplex-7/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/cpi-metaplex-7/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,96 +1,94 @@ -pub mod cpi_metaplex_7_fuzz_instructions { - use solana_sdk::native_token::LAMPORTS_PER_SOL; - use trident_client::fuzzing::*; +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; - use cpi_metaplex_7::trident_fuzz_initialize_snapshot::InitializeAlias; +use cpi_metaplex_7::trident_fuzz_initialize_snapshot::InitializeAlias; - type InitializeSnapshot<'info> = InitializeAlias<'info>; - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - Initialize(Initialize), - } - #[derive(Arbitrary, Debug)] - pub struct Initialize { - pub accounts: InitializeAccounts, - pub data: InitializeData, - } - #[derive(Arbitrary, Debug)] - pub struct InitializeAccounts { - pub signer: AccountId, - pub mint: AccountId, - pub metadata_account: AccountId, - pub mpl_token_metadata: AccountId, - pub system_program: AccountId, - pub token_program: AccountId, +type InitializeSnapshot<'info> = InitializeAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + Initialize(Initialize), +} +#[derive(Arbitrary, Debug)] +pub struct Initialize { + pub accounts: InitializeAccounts, + pub data: InitializeData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeAccounts { + pub signer: AccountId, + pub mint: AccountId, + pub _metadata_account: AccountId, + pub _mpl_token_metadata: AccountId, + pub _system_program: AccountId, + pub _token_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeData { + pub input: u8, + pub name: String, + pub symbol: String, + pub uri: String, +} +impl<'info> IxOps<'info> for Initialize { + type IxData = cpi_metaplex_7::instruction::Initialize; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + cpi_metaplex_7::ID } - #[derive(Arbitrary, Debug)] - pub struct InitializeData { - pub input: u8, - pub name: String, - pub symbol: String, - pub uri: String, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = cpi_metaplex_7::instruction::Initialize { + input: self.data.input, + name: self.data.name.clone(), + symbol: self.data.symbol.clone(), + uri: self.data.uri.clone(), + }; + Ok(data) } - impl<'info> IxOps<'info> for Initialize { - type IxData = cpi_metaplex_7::instruction::Initialize; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitializeSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - cpi_metaplex_7::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = cpi_metaplex_7::instruction::Initialize { - input: self.data.input, - name: self.data.name.clone(), - symbol: self.data.symbol.clone(), - uri: self.data.uri.clone(), - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let signer = fuzz_accounts.signer.get_or_create_account( - self.accounts.signer, - client, - 10 * LAMPORTS_PER_SOL, - ); + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let signer = fuzz_accounts.signer.get_or_create_account( + self.accounts.signer, + client, + 10 * LAMPORTS_PER_SOL, + ); - let mint = fuzz_accounts.mint.get_or_create_account( - self.accounts.mint, - client, - 10 * LAMPORTS_PER_SOL, - ); + let mint = fuzz_accounts.mint.get_or_create_account( + self.accounts.mint, + client, + 10 * LAMPORTS_PER_SOL, + ); - let metadata_account = mpl_token_metadata::accounts::Metadata::find_pda(&mint.pubkey()); + let metadata_account = mpl_token_metadata::accounts::Metadata::find_pda(&mint.pubkey()); - let signers = vec![signer.clone(), mint.clone()]; - let acc_meta = cpi_metaplex_7::accounts::Initialize { - signer: signer.pubkey(), - mint: mint.pubkey(), - metadata_account: metadata_account.0, - mpl_token_metadata: mpl_token_metadata::ID, - system_program: solana_sdk::system_program::ID, - token_program: anchor_spl::token::ID, - } - .to_account_metas(None); - Ok((signers, acc_meta)) + let signers = vec![signer.clone(), mint.clone()]; + let acc_meta = cpi_metaplex_7::accounts::Initialize { + signer: signer.pubkey(), + mint: mint.pubkey(), + metadata_account: metadata_account.0, + mpl_token_metadata: mpl_token_metadata::ID, + system_program: solana_sdk::system_program::ID, + token_program: anchor_spl::token::ID, } + .to_account_metas(None); + Ok((signers, acc_meta)) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - _metadata_account: AccountsStorage, - mint: AccountsStorage, - _mpl_token_metadata: AccountsStorage, - signer: AccountsStorage, - _system_program: AccountsStorage, - _token_program: AccountsStorage, - } +} +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + _metadata_account: AccountsStorage, + mint: AccountsStorage, + _mpl_token_metadata: AccountsStorage, + signer: AccountsStorage, + _system_program: AccountsStorage, + _token_program: AccountsStorage, } diff --git a/examples/fuzz-tests/cpi-metaplex-7/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/cpi-metaplex-7/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index 665813cca..8f06e7c93 100644 --- a/examples/fuzz-tests/cpi-metaplex-7/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/cpi-metaplex-7/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -1,17 +1,14 @@ -use fuzz_instructions::cpi_metaplex_7_fuzz_instructions::Initialize; +use fuzz_instructions::Initialize; use trident_client::fuzzing::*; mod fuzz_instructions; use cpi_metaplex_7::entry as entry_cpi_metaplex_7; use cpi_metaplex_7::ID as PROGRAM_ID_CPI_METAPLEX_7; +use fuzz_instructions::FuzzInstruction; const PROGRAM_NAME_CPI_METAPLEX_7: &str = "cpi_metaplex_7"; -use fuzz_instructions::cpi_metaplex_7_fuzz_instructions::FuzzInstruction as fuzz_instruction_cpi_metaplex_7; - -pub type FuzzInstruction = fuzz_instruction_cpi_metaplex_7; - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData { diff --git a/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index c0b032280..9f6fad618 100644 --- a/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,95 +1,93 @@ -pub mod hello_world_fuzz_instructions { - use solana_sdk::native_token::LAMPORTS_PER_SOL; - use trident_client::fuzzing::*; +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; - use hello_world::trident_fuzz_initialize_context_snapshot::InitializeContextAlias; +use hello_world::trident_fuzz_initialize_context_snapshot::InitializeContextAlias; - type InitializeFnSnapshot<'info> = InitializeContextAlias<'info>; - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - InitializeFn(InitializeFn), - } - #[derive(Arbitrary, Debug)] - pub struct InitializeFn { - pub accounts: InitializeFnAccounts, - pub data: InitializeFnData, - } - #[derive(Arbitrary, Debug)] - pub struct InitializeFnAccounts { - pub author: AccountId, - pub hello_world_account: AccountId, - pub system_program: AccountId, +type InitializeFnSnapshot<'info> = InitializeContextAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + InitializeFn(InitializeFn), +} +#[derive(Arbitrary, Debug)] +pub struct InitializeFn { + pub accounts: InitializeFnAccounts, + pub data: InitializeFnData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeFnAccounts { + pub author: AccountId, + pub hello_world_account: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeFnData { + pub input: u8, +} +impl<'info> IxOps<'info> for InitializeFn { + type IxData = hello_world::instruction::InitializeFn; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeFnSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + hello_world::ID } - #[derive(Arbitrary, Debug)] - pub struct InitializeFnData { - pub input: u8, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = hello_world::instruction::InitializeFn { + input: self.data.input, + }; + Ok(data) } - impl<'info> IxOps<'info> for InitializeFn { - type IxData = hello_world::instruction::InitializeFn; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitializeFnSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - hello_world::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = hello_world::instruction::InitializeFn { - input: self.data.input, - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let author = fuzz_accounts.author.get_or_create_account( - self.accounts.author, - client, - 5 * LAMPORTS_PER_SOL, - ); + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let author = fuzz_accounts.author.get_or_create_account( + self.accounts.author, + client, + 5 * LAMPORTS_PER_SOL, + ); - let hello_world_account = fuzz_accounts - .hello_world_account - .get_or_create_account( - self.accounts.hello_world_account, - &[b"hello_world_seed"], - &hello_world::ID, - ) - .unwrap(); - let signers = vec![author.clone()]; - let acc_meta = hello_world::accounts::InitializeContext { - author: author.pubkey(), - hello_world_account: hello_world_account.pubkey(), - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((signers, acc_meta)) + let hello_world_account = fuzz_accounts + .hello_world_account + .get_or_create_account( + self.accounts.hello_world_account, + &[b"hello_world_seed"], + &hello_world::ID, + ) + .unwrap(); + let signers = vec![author.clone()]; + let acc_meta = hello_world::accounts::InitializeContext { + author: author.pubkey(), + hello_world_account: hello_world_account.pubkey(), + system_program: solana_sdk::system_program::ID, } - fn check( - &self, - _pre_ix: Self::IxSnapshot, - post_ix: Self::IxSnapshot, - _ix_data: Self::IxData, - ) -> Result<(), FuzzingError> { - if let Some(hello_world_account) = post_ix.hello_world_account { - if hello_world_account.input == 253 { - return Err(FuzzingError::Custom(1)); - } + .to_account_metas(None); + Ok((signers, acc_meta)) + } + fn check( + &self, + _pre_ix: Self::IxSnapshot, + post_ix: Self::IxSnapshot, + _ix_data: Self::IxData, + ) -> Result<(), FuzzingError> { + if let Some(hello_world_account) = post_ix.hello_world_account { + if hello_world_account.input == 253 { + return Err(FuzzingError::Custom(1)); } - Ok(()) } + Ok(()) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - author: AccountsStorage, - hello_world_account: AccountsStorage, - // No need to fuzz system_program - // system_program: AccountsStorage, - } +} +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + author: AccountsStorage, + hello_world_account: AccountsStorage, + // No need to fuzz system_program + // system_program: AccountsStorage, } diff --git a/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index c6c452cfa..49763f26c 100644 --- a/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/hello_world/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -2,15 +2,12 @@ use trident_client::fuzzing::*; mod fuzz_instructions; +use fuzz_instructions::FuzzInstruction; use hello_world::entry as entry_hello_world; use hello_world::ID as PROGRAM_ID_HELLO_WORLD; const PROGRAM_NAME_HELLO_WORLD: &str = "hello_world"; -use fuzz_instructions::hello_world_fuzz_instructions::FuzzInstruction as fuzz_instruction_hello_world; - -pub type FuzzInstruction = fuzz_instruction_hello_world; - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData {} diff --git a/examples/fuzz-tests/incorrect-integer-arithmetic-3/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/incorrect-integer-arithmetic-3/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index 0c9983f72..13d976f55 100644 --- a/examples/fuzz-tests/incorrect-integer-arithmetic-3/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/incorrect-integer-arithmetic-3/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,308 +1,305 @@ -pub mod incorrect_integer_arithmetic_3_fuzz_instructions { - use solana_sdk::native_token::LAMPORTS_PER_SOL; - use trident_client::fuzzing::*; +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; - use incorrect_integer_arithmetic_3::trident_fuzz_init_vesting_snapshot::InitVestingAlias; - use incorrect_integer_arithmetic_3::trident_fuzz_withdraw_unlocked_snapshot::WithdrawUnlockedAlias; +use incorrect_integer_arithmetic_3::trident_fuzz_init_vesting_snapshot::InitVestingAlias; +use incorrect_integer_arithmetic_3::trident_fuzz_withdraw_unlocked_snapshot::WithdrawUnlockedAlias; - type InitVestingSnapshot<'info> = InitVestingAlias<'info>; - type WithdrawUnlockedSnapshot<'info> = WithdrawUnlockedAlias<'info>; - - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - InitVesting(InitVesting), - WithdrawUnlocked(WithdrawUnlocked), - } - #[derive(Arbitrary, Debug)] - pub struct InitVesting { - pub accounts: InitVestingAccounts, - pub data: InitVestingData, - } - #[derive(Arbitrary, Debug)] - pub struct InitVestingAccounts { - pub sender: AccountId, - pub sender_token_account: AccountId, - pub escrow: AccountId, - pub escrow_token_account: AccountId, - pub mint: AccountId, - pub token_program: AccountId, - pub system_program: AccountId, - } - #[derive(Arbitrary, Debug)] - pub struct InitVestingData { - pub recipient: AccountId, - #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1..=1_000_000))] - pub amount: u64, - // we want start_at smaller than end_at - // and for testing purposes we can run tests with times from the past - #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(0..=1_000_000))] - pub start_at: u64, - #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1_001_001..=1_050_000))] - pub end_at: u64, - #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1..=1000))] - pub interval: u64, - } - #[derive(Arbitrary, Debug)] - pub struct WithdrawUnlocked { - pub accounts: WithdrawUnlockedAccounts, - pub data: WithdrawUnlockedData, +type InitVestingSnapshot<'info> = InitVestingAlias<'info>; +type WithdrawUnlockedSnapshot<'info> = WithdrawUnlockedAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + InitVesting(InitVesting), + WithdrawUnlocked(WithdrawUnlocked), +} +#[derive(Arbitrary, Debug)] +pub struct InitVesting { + pub accounts: InitVestingAccounts, + pub data: InitVestingData, +} +#[derive(Arbitrary, Debug)] +pub struct InitVestingAccounts { + pub sender: AccountId, + pub sender_token_account: AccountId, + pub escrow: AccountId, + pub escrow_token_account: AccountId, + pub _mint: AccountId, + pub _token_program: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitVestingData { + pub recipient: AccountId, + #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1..=1_000_000))] + pub amount: u64, + // we want start_at smaller than end_at + // and for testing purposes we can run tests with times from the past + #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(0..=1_000_000))] + pub start_at: u64, + #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1_001_001..=1_050_000))] + pub end_at: u64, + #[arbitrary(with = |u: &mut arbitrary::Unstructured| u.int_in_range(1..=1000))] + pub interval: u64, +} +#[derive(Arbitrary, Debug)] +pub struct WithdrawUnlocked { + pub accounts: WithdrawUnlockedAccounts, + pub _data: WithdrawUnlockedData, +} +#[derive(Arbitrary, Debug)] +pub struct WithdrawUnlockedAccounts { + pub recipient: AccountId, + pub recipient_token_account: AccountId, + pub escrow: AccountId, + pub escrow_token_account: AccountId, + pub escrow_pda_authority: AccountId, + pub _mint: AccountId, + pub _token_program: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct WithdrawUnlockedData {} +impl<'info> IxOps<'info> for InitVesting { + type IxData = incorrect_integer_arithmetic_3::instruction::InitVesting; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitVestingSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + incorrect_integer_arithmetic_3::ID } - #[derive(Arbitrary, Debug)] - pub struct WithdrawUnlockedAccounts { - pub recipient: AccountId, - pub recipient_token_account: AccountId, - pub escrow: AccountId, - pub escrow_token_account: AccountId, - pub escrow_pda_authority: AccountId, - pub mint: AccountId, - pub token_program: AccountId, - pub system_program: AccountId, + fn get_data( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let recipient = fuzz_accounts.recipient.get_or_create_account( + self.data.recipient, + client, + 10 * LAMPORTS_PER_SOL, + ); + + let data = incorrect_integer_arithmetic_3::instruction::InitVesting { + recipient: recipient.pubkey(), + amount: self.data.amount, + start_at: self.data.start_at, + end_at: self.data.end_at, + interval: self.data.interval, + }; + Ok(data) } - #[derive(Arbitrary, Debug)] - pub struct WithdrawUnlockedData {} - impl<'info> IxOps<'info> for InitVesting { - type IxData = incorrect_integer_arithmetic_3::instruction::InitVesting; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitVestingSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - incorrect_integer_arithmetic_3::ID - } - fn get_data( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let recipient = fuzz_accounts.recipient.get_or_create_account( - self.data.recipient, - client, - 10 * LAMPORTS_PER_SOL, - ); + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let sender = fuzz_accounts.sender.get_or_create_account( + self.accounts.sender, + client, + 5 * LAMPORTS_PER_SOL, + ); + // INFO use constant Account ID, so we will not generate multiple mints, + // and also we can easily link to Withdraw + let mint = fuzz_accounts + .mint + .get_or_create_account(0, client, 6, &sender.pubkey(), None) + .unwrap(); - let data = incorrect_integer_arithmetic_3::instruction::InitVesting { - recipient: recipient.pubkey(), - amount: self.data.amount, - start_at: self.data.start_at, - end_at: self.data.end_at, - interval: self.data.interval, - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let sender = fuzz_accounts.sender.get_or_create_account( - self.accounts.sender, + let sender_token_account = fuzz_accounts + .sender_token_account + .get_or_create_account( + self.accounts.sender_token_account, client, - 5 * LAMPORTS_PER_SOL, - ); - // INFO use constant Account ID, so we will not generate multiple mints, - // and also we can easily link to Withdraw - let mint = fuzz_accounts - .mint - .get_or_create_account(0, client, 6, &sender.pubkey(), None) - .unwrap(); + mint, + sender.pubkey(), + u64::MAX, + None, + None, + 0, + None, + ) + .unwrap(); - let sender_token_account = fuzz_accounts - .sender_token_account - .get_or_create_account( - self.accounts.sender_token_account, - client, - mint, - sender.pubkey(), - u64::MAX, - None, - None, - 0, - None, - ) - .unwrap(); + let recipient = fuzz_accounts.recipient.get_or_create_account( + self.data.recipient, + client, + 10 * LAMPORTS_PER_SOL, + ); + let escrow = fuzz_accounts + .escrow + .get_or_create_account( + self.accounts.escrow, + &[recipient.pubkey().as_ref(), b"ESCROW_SEED"], + &incorrect_integer_arithmetic_3::ID, + ) + .unwrap(); - let recipient = fuzz_accounts.recipient.get_or_create_account( - self.data.recipient, + let escrow_token_account = fuzz_accounts + .escrow_token_account + .get_or_create_account( + self.accounts.escrow_token_account, client, - 10 * LAMPORTS_PER_SOL, - ); - let escrow = fuzz_accounts - .escrow - .get_or_create_account( - self.accounts.escrow, - &[recipient.pubkey().as_ref(), b"ESCROW_SEED"], - &incorrect_integer_arithmetic_3::ID, - ) - .unwrap(); - - let escrow_token_account = fuzz_accounts - .escrow_token_account - .get_or_create_account( - self.accounts.escrow_token_account, - client, - mint, - sender.pubkey(), - 0, - None, - None, - 0, - None, - ) - .unwrap(); - - let acc_meta = incorrect_integer_arithmetic_3::accounts::InitVesting { - sender: sender.pubkey(), - sender_token_account, - escrow: escrow.pubkey(), - escrow_token_account, mint, - token_program: anchor_spl::token::ID, - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); + sender.pubkey(), + 0, + None, + None, + 0, + None, + ) + .unwrap(); - Ok((vec![sender], acc_meta)) - } - } - impl<'info> IxOps<'info> for WithdrawUnlocked { - type IxData = incorrect_integer_arithmetic_3::instruction::WithdrawUnlocked; - type IxAccounts = FuzzAccounts; - type IxSnapshot = WithdrawUnlockedSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - incorrect_integer_arithmetic_3::ID + let acc_meta = incorrect_integer_arithmetic_3::accounts::InitVesting { + sender: sender.pubkey(), + sender_token_account, + escrow: escrow.pubkey(), + escrow_token_account, + mint, + token_program: anchor_spl::token::ID, + system_program: solana_sdk::system_program::ID, } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = incorrect_integer_arithmetic_3::instruction::WithdrawUnlocked {}; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let recipient = fuzz_accounts.recipient.get_or_create_account( - self.accounts.recipient, - client, - 5 * LAMPORTS_PER_SOL, - ); + .to_account_metas(None); - // INFO use constant Account ID, so we will not generate multiple mints, - // and also we can easily link to Initialize - let mint = fuzz_accounts - .mint - .get_or_create_account(0, client, 6, &recipient.pubkey(), None) - .unwrap(); + Ok((vec![sender], acc_meta)) + } +} +impl<'info> IxOps<'info> for WithdrawUnlocked { + type IxData = incorrect_integer_arithmetic_3::instruction::WithdrawUnlocked; + type IxAccounts = FuzzAccounts; + type IxSnapshot = WithdrawUnlockedSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + incorrect_integer_arithmetic_3::ID + } + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = incorrect_integer_arithmetic_3::instruction::WithdrawUnlocked {}; + Ok(data) + } + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let recipient = fuzz_accounts.recipient.get_or_create_account( + self.accounts.recipient, + client, + 5 * LAMPORTS_PER_SOL, + ); - let recipient_token_account = fuzz_accounts - .recipient_token_account - .get_or_create_account( - self.accounts.recipient_token_account, - client, - mint, - recipient.pubkey(), - 0, - None, - None, - 0, - None, - ) - .unwrap(); + // INFO use constant Account ID, so we will not generate multiple mints, + // and also we can easily link to Initialize + let mint = fuzz_accounts + .mint + .get_or_create_account(0, client, 6, &recipient.pubkey(), None) + .unwrap(); - let escrow = fuzz_accounts - .escrow - .get_or_create_account( - self.accounts.escrow, - &[recipient.pubkey().as_ref(), b"ESCROW_SEED"], - &incorrect_integer_arithmetic_3::ID, - ) - .unwrap(); + let recipient_token_account = fuzz_accounts + .recipient_token_account + .get_or_create_account( + self.accounts.recipient_token_account, + client, + mint, + recipient.pubkey(), + 0, + None, + None, + 0, + None, + ) + .unwrap(); - let escrow_pda_authority = fuzz_accounts - .escrow_pda_authority - .get_or_create_account( - self.accounts.escrow_pda_authority, - &[b"ESCROW_PDA_AUTHORITY"], - &incorrect_integer_arithmetic_3::ID, - ) - .unwrap(); + let escrow = fuzz_accounts + .escrow + .get_or_create_account( + self.accounts.escrow, + &[recipient.pubkey().as_ref(), b"ESCROW_SEED"], + &incorrect_integer_arithmetic_3::ID, + ) + .unwrap(); - let escrow_token_account = fuzz_accounts - .escrow_token_account - .get_or_create_account( - self.accounts.escrow_token_account, - client, - mint, - escrow_pda_authority.pubkey(), - u64::MAX, - None, - None, - 0, - None, - ) - .unwrap(); + let escrow_pda_authority = fuzz_accounts + .escrow_pda_authority + .get_or_create_account( + self.accounts.escrow_pda_authority, + &[b"ESCROW_PDA_AUTHORITY"], + &incorrect_integer_arithmetic_3::ID, + ) + .unwrap(); - let acc_meta = incorrect_integer_arithmetic_3::accounts::WithdrawUnlocked { - recipient: recipient.pubkey(), - recipient_token_account, - escrow: escrow.pubkey(), - escrow_token_account, - escrow_pda_authority: escrow_pda_authority.pubkey(), + let escrow_token_account = fuzz_accounts + .escrow_token_account + .get_or_create_account( + self.accounts.escrow_token_account, + client, mint, - token_program: anchor_spl::token::ID, - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((vec![recipient], acc_meta)) + escrow_pda_authority.pubkey(), + u64::MAX, + None, + None, + 0, + None, + ) + .unwrap(); + + let acc_meta = incorrect_integer_arithmetic_3::accounts::WithdrawUnlocked { + recipient: recipient.pubkey(), + recipient_token_account, + escrow: escrow.pubkey(), + escrow_token_account, + escrow_pda_authority: escrow_pda_authority.pubkey(), + mint, + token_program: anchor_spl::token::ID, + system_program: solana_sdk::system_program::ID, } - fn check( - &self, - pre_ix: Self::IxSnapshot, - post_ix: Self::IxSnapshot, - _ix_data: Self::IxData, - ) -> Result<(), FuzzingError> { - if let Some(escrow) = pre_ix.escrow { - let recipient = pre_ix.recipient; - let recipient_token_account_pre = pre_ix.recipient_token_account; - let recipient_token_account_post = post_ix.recipient_token_account; - if escrow.recipient == recipient.key() { - if recipient_token_account_pre.amount == recipient_token_account_post.amount { - // Recipient was not able to withdraw - return Err(FuzzingError::BalanceMismatch); - } else if recipient_token_account_pre.amount + escrow.amount - != recipient_token_account_post.amount + .to_account_metas(None); + Ok((vec![recipient], acc_meta)) + } + fn check( + &self, + pre_ix: Self::IxSnapshot, + post_ix: Self::IxSnapshot, + _ix_data: Self::IxData, + ) -> Result<(), FuzzingError> { + if let Some(escrow) = pre_ix.escrow { + let recipient = pre_ix.recipient; + let recipient_token_account_pre = pre_ix.recipient_token_account; + let recipient_token_account_post = post_ix.recipient_token_account; + if escrow.recipient == recipient.key() { + if recipient_token_account_pre.amount == recipient_token_account_post.amount { + // Recipient was not able to withdraw + return Err(FuzzingError::BalanceMismatch); + } else if recipient_token_account_pre.amount + escrow.amount + != recipient_token_account_post.amount + { + if recipient_token_account_pre.amount + escrow.amount + > recipient_token_account_post.amount { - if recipient_token_account_pre.amount + escrow.amount - > recipient_token_account_post.amount - { - // Recipient withdraw less - return Err(FuzzingError::Custom(15)); - } else { - // Recipient withdraw more - return Err(FuzzingError::Custom(2)); - } + // Recipient withdraw less + return Err(FuzzingError::Custom(15)); + } else { + // Recipient withdraw more + return Err(FuzzingError::Custom(2)); } } } - Ok(()) } + Ok(()) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - // No need to fuzz Token Program - // token_program: AccountsStorage, - sender_token_account: AccountsStorage, - escrow_token_account: AccountsStorage, - escrow_pda_authority: AccountsStorage, - sender: AccountsStorage, - // No need to fuzz System Program - // _system_program: AccountsStorage, - recipient_token_account: AccountsStorage, - recipient: AccountsStorage, - mint: AccountsStorage, - escrow: AccountsStorage, - } +} +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + // No need to fuzz Token Program + // token_program: AccountsStorage, + sender_token_account: AccountsStorage, + escrow_token_account: AccountsStorage, + escrow_pda_authority: AccountsStorage, + sender: AccountsStorage, + // No need to fuzz System Program + // _system_program: AccountsStorage, + recipient_token_account: AccountsStorage, + recipient: AccountsStorage, + mint: AccountsStorage, + escrow: AccountsStorage, } diff --git a/examples/fuzz-tests/incorrect-integer-arithmetic-3/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/incorrect-integer-arithmetic-3/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index 7845cd9d8..78fcc12ef 100644 --- a/examples/fuzz-tests/incorrect-integer-arithmetic-3/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/incorrect-integer-arithmetic-3/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -1,17 +1,14 @@ -use fuzz_instructions::incorrect_integer_arithmetic_3_fuzz_instructions::InitVesting; +use fuzz_instructions::InitVesting; use trident_client::fuzzing::*; mod fuzz_instructions; +use fuzz_instructions::FuzzInstruction; use incorrect_integer_arithmetic_3::entry as entry_incorrect_integer_arithmetic_3; use incorrect_integer_arithmetic_3::ID as PROGRAM_ID_INCORRECT_INTEGER_ARITHMETIC_3; const PROGRAM_NAME_INCORRECT_INTEGER_ARITHMETIC_3: &str = "incorrect_integer_arithmetic_3"; -use fuzz_instructions::incorrect_integer_arithmetic_3_fuzz_instructions::FuzzInstruction as fuzz_instruction_incorrect_integer_arithmetic_3; - -pub type FuzzInstruction = fuzz_instruction_incorrect_integer_arithmetic_3; - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData { diff --git a/examples/fuzz-tests/incorrect-ix-sequence-1/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/incorrect-ix-sequence-1/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index 2191a6ec2..56ca21150 100644 --- a/examples/fuzz-tests/incorrect-ix-sequence-1/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/incorrect-ix-sequence-1/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,322 +1,319 @@ -pub mod incorrect_ix_sequence_1_fuzz_instructions { - use incorrect_ix_sequence_1::{PROJECT_SEED, STATE_SEED}; - use solana_sdk::native_token::LAMPORTS_PER_SOL; - use trident_client::fuzzing::*; +use incorrect_ix_sequence_1::{PROJECT_SEED, STATE_SEED}; +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; - use incorrect_ix_sequence_1::trident_fuzz_end_registration_snapshot::EndRegistrationAlias; - use incorrect_ix_sequence_1::trident_fuzz_initialize_snapshot::InitializeAlias; - use incorrect_ix_sequence_1::trident_fuzz_invest_snapshot::InvestAlias; - use incorrect_ix_sequence_1::trident_fuzz_register_snapshot::RegisterAlias; +use incorrect_ix_sequence_1::trident_fuzz_end_registration_snapshot::EndRegistrationAlias; +use incorrect_ix_sequence_1::trident_fuzz_initialize_snapshot::InitializeAlias; +use incorrect_ix_sequence_1::trident_fuzz_invest_snapshot::InvestAlias; +use incorrect_ix_sequence_1::trident_fuzz_register_snapshot::RegisterAlias; - type EndRegistrationsSnapshot<'info> = EndRegistrationAlias<'info>; - type InitializeSnapshot<'info> = InitializeAlias<'info>; - type InvestSnapshot<'info> = InvestAlias<'info>; - type RegisterSnapshot<'info> = RegisterAlias<'info>; - - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - EndRegistrations(EndRegistrations), - Initialize(Initialize), - Invest(Invest), - Register(Register), - } - #[derive(Arbitrary, Debug)] - pub struct EndRegistrations { - pub accounts: EndRegistrationsAccounts, - pub data: EndRegistrationsData, - } - #[derive(Arbitrary, Debug)] - pub struct EndRegistrationsAccounts { - pub author: AccountId, - pub state: AccountId, - } - #[derive(Arbitrary, Debug)] - pub struct EndRegistrationsData {} - #[derive(Arbitrary, Debug)] - pub struct Initialize { - pub accounts: InitializeAccounts, - pub data: InitializeData, +type EndRegistrationsSnapshot<'info> = EndRegistrationAlias<'info>; +type InitializeSnapshot<'info> = InitializeAlias<'info>; +type InvestSnapshot<'info> = InvestAlias<'info>; +type RegisterSnapshot<'info> = RegisterAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + EndRegistrations(EndRegistrations), + Initialize(Initialize), + Invest(Invest), + Register(Register), +} +#[derive(Arbitrary, Debug)] +pub struct EndRegistrations { + pub accounts: EndRegistrationsAccounts, + pub _data: EndRegistrationsData, +} +#[derive(Arbitrary, Debug)] +pub struct EndRegistrationsAccounts { + pub author: AccountId, + pub state: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct EndRegistrationsData {} +#[derive(Arbitrary, Debug)] +pub struct Initialize { + pub accounts: InitializeAccounts, + pub _data: InitializeData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeAccounts { + pub author: AccountId, + pub state: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeData {} +#[derive(Arbitrary, Debug)] +pub struct Invest { + pub accounts: InvestAccounts, + pub data: InvestData, +} +#[derive(Arbitrary, Debug)] +pub struct InvestAccounts { + pub investor: AccountId, + pub project: AccountId, + pub state: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InvestData { + pub amount: u64, +} +#[derive(Arbitrary, Debug)] +pub struct Register { + pub accounts: RegisterAccounts, + pub _data: RegisterData, +} +#[derive(Arbitrary, Debug)] +pub struct RegisterAccounts { + pub project_author: AccountId, + pub project: AccountId, + pub state: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct RegisterData {} +impl<'info> IxOps<'info> for EndRegistrations { + type IxData = incorrect_ix_sequence_1::instruction::EndRegistrations; + type IxAccounts = FuzzAccounts; + type IxSnapshot = EndRegistrationsSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + incorrect_ix_sequence_1::ID } - #[derive(Arbitrary, Debug)] - pub struct InitializeAccounts { - pub author: AccountId, - pub state: AccountId, - pub system_program: AccountId, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = incorrect_ix_sequence_1::instruction::EndRegistrations {}; + Ok(data) } - #[derive(Arbitrary, Debug)] - pub struct InitializeData {} - #[derive(Arbitrary, Debug)] - pub struct Invest { - pub accounts: InvestAccounts, - pub data: InvestData, + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let author = fuzz_accounts.author.get_or_create_account( + self.accounts.author, + client, + 5 * LAMPORTS_PER_SOL, + ); + let signers = vec![author.clone()]; + let state = fuzz_accounts + .state + .get_or_create_account( + self.accounts.state, + &[author.pubkey().as_ref(), STATE_SEED.as_ref()], + &incorrect_ix_sequence_1::ID, + ) + .ok_or(FuzzingError::Custom(4))? + .pubkey(); + let acc_meta = incorrect_ix_sequence_1::accounts::EndRegistration { + author: author.pubkey(), + state, + } + .to_account_metas(None); + Ok((signers, acc_meta)) } - #[derive(Arbitrary, Debug)] - pub struct InvestAccounts { - pub investor: AccountId, - pub project: AccountId, - pub state: AccountId, - pub system_program: AccountId, +} +impl<'info> IxOps<'info> for Initialize { + type IxData = incorrect_ix_sequence_1::instruction::Initialize; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + incorrect_ix_sequence_1::ID } - #[derive(Arbitrary, Debug)] - pub struct InvestData { - pub amount: u64, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = incorrect_ix_sequence_1::instruction::Initialize {}; + Ok(data) } - #[derive(Arbitrary, Debug)] - pub struct Register { - pub accounts: RegisterAccounts, - pub data: RegisterData, + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let author = fuzz_accounts.author.get_or_create_account( + self.accounts.author, + client, + 5 * LAMPORTS_PER_SOL, + ); + let signers = vec![author.clone()]; + let state = fuzz_accounts + .state + .get_or_create_account( + self.accounts.state, + &[author.pubkey().as_ref(), STATE_SEED.as_ref()], + &incorrect_ix_sequence_1::ID, + ) + .ok_or(FuzzingError::Custom(1))? + .pubkey(); + + let acc_meta = incorrect_ix_sequence_1::accounts::Initialize { + author: author.pubkey(), + state, + system_program: solana_sdk::system_program::ID, + } + .to_account_metas(None); + Ok((signers, acc_meta)) } - #[derive(Arbitrary, Debug)] - pub struct RegisterAccounts { - pub project_author: AccountId, - pub project: AccountId, - pub state: AccountId, - pub system_program: AccountId, +} +impl<'info> IxOps<'info> for Invest { + type IxData = incorrect_ix_sequence_1::instruction::Invest; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InvestSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + incorrect_ix_sequence_1::ID } - #[derive(Arbitrary, Debug)] - pub struct RegisterData {} - impl<'info> IxOps<'info> for EndRegistrations { - type IxData = incorrect_ix_sequence_1::instruction::EndRegistrations; - type IxAccounts = FuzzAccounts; - type IxSnapshot = EndRegistrationsSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - incorrect_ix_sequence_1::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = incorrect_ix_sequence_1::instruction::EndRegistrations {}; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let author = fuzz_accounts.author.get_or_create_account( - self.accounts.author, - client, - 5 * LAMPORTS_PER_SOL, - ); - let signers = vec![author.clone()]; - let state = fuzz_accounts - .state - .get_or_create_account( - self.accounts.state, - &[author.pubkey().as_ref(), STATE_SEED.as_ref()], - &incorrect_ix_sequence_1::ID, - ) - .ok_or(FuzzingError::Custom(4))? - .pubkey(); - let acc_meta = incorrect_ix_sequence_1::accounts::EndRegistration { - author: author.pubkey(), - state, - } - .to_account_metas(None); - Ok((signers, acc_meta)) - } + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = incorrect_ix_sequence_1::instruction::Invest { + amount: self.data.amount, + }; + Ok(data) } - impl<'info> IxOps<'info> for Initialize { - type IxData = incorrect_ix_sequence_1::instruction::Initialize; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitializeSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - incorrect_ix_sequence_1::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = incorrect_ix_sequence_1::instruction::Initialize {}; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let author = fuzz_accounts.author.get_or_create_account( - self.accounts.author, - client, - 5 * LAMPORTS_PER_SOL, - ); - let signers = vec![author.clone()]; - let state = fuzz_accounts - .state - .get_or_create_account( - self.accounts.state, - &[author.pubkey().as_ref(), STATE_SEED.as_ref()], - &incorrect_ix_sequence_1::ID, - ) - .ok_or(FuzzingError::Custom(1))? - .pubkey(); + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let investor = fuzz_accounts.investor.get_or_create_account( + self.accounts.investor, + client, + 5 * LAMPORTS_PER_SOL, + ); + let signers = vec![investor.clone()]; - let acc_meta = incorrect_ix_sequence_1::accounts::Initialize { - author: author.pubkey(), - state, - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((signers, acc_meta)) - } - } - impl<'info> IxOps<'info> for Invest { - type IxData = incorrect_ix_sequence_1::instruction::Invest; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InvestSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - incorrect_ix_sequence_1::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = incorrect_ix_sequence_1::instruction::Invest { - amount: self.data.amount, - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let investor = fuzz_accounts.investor.get_or_create_account( - self.accounts.investor, - client, - 5 * LAMPORTS_PER_SOL, - ); - let signers = vec![investor.clone()]; + let project_author = fuzz_accounts.project_author.get_or_create_account( + self.accounts.project, + client, + 5 * LAMPORTS_PER_SOL, + ); + let state = fuzz_accounts + .state + .get_or_create_account( + self.accounts.state, + &[project_author.pubkey().as_ref(), STATE_SEED.as_ref()], + &incorrect_ix_sequence_1::ID, + ) + .ok_or(FuzzingError::Custom(5))? + .pubkey(); - let project_author = fuzz_accounts.project_author.get_or_create_account( + let project = fuzz_accounts + .project + .get_or_create_account( self.accounts.project, - client, - 5 * LAMPORTS_PER_SOL, - ); - let state = fuzz_accounts - .state - .get_or_create_account( - self.accounts.state, - &[project_author.pubkey().as_ref(), STATE_SEED.as_ref()], - &incorrect_ix_sequence_1::ID, - ) - .ok_or(FuzzingError::Custom(5))? - .pubkey(); - - let project = fuzz_accounts - .project - .get_or_create_account( - self.accounts.project, - &[ - project_author.pubkey().as_ref(), - state.as_ref(), - PROJECT_SEED.as_ref(), - ], - &incorrect_ix_sequence_1::ID, - ) - .ok_or(FuzzingError::Custom(6))? - .pubkey(); - let acc_meta = incorrect_ix_sequence_1::accounts::Invest { - investor: investor.pubkey(), - project, - state, - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((signers, acc_meta)) + &[ + project_author.pubkey().as_ref(), + state.as_ref(), + PROJECT_SEED.as_ref(), + ], + &incorrect_ix_sequence_1::ID, + ) + .ok_or(FuzzingError::Custom(6))? + .pubkey(); + let acc_meta = incorrect_ix_sequence_1::accounts::Invest { + investor: investor.pubkey(), + project, + state, + system_program: solana_sdk::system_program::ID, } + .to_account_metas(None); + Ok((signers, acc_meta)) } - impl<'info> IxOps<'info> for Register { - type IxData = incorrect_ix_sequence_1::instruction::Register; - type IxAccounts = FuzzAccounts; - type IxSnapshot = RegisterSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - incorrect_ix_sequence_1::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = incorrect_ix_sequence_1::instruction::Register {}; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let project_author = fuzz_accounts.project_author.get_or_create_account( - self.accounts.project_author, - client, - 5 * LAMPORTS_PER_SOL, - ); - let signers = vec![project_author.clone()]; - let state = fuzz_accounts - .state - .get_or_create_account( - self.accounts.state, - &[project_author.pubkey().as_ref(), STATE_SEED.as_ref()], - &incorrect_ix_sequence_1::ID, - ) - .ok_or(FuzzingError::Custom(2))? - .pubkey(); +} +impl<'info> IxOps<'info> for Register { + type IxData = incorrect_ix_sequence_1::instruction::Register; + type IxAccounts = FuzzAccounts; + type IxSnapshot = RegisterSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + incorrect_ix_sequence_1::ID + } + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = incorrect_ix_sequence_1::instruction::Register {}; + Ok(data) + } + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let project_author = fuzz_accounts.project_author.get_or_create_account( + self.accounts.project_author, + client, + 5 * LAMPORTS_PER_SOL, + ); + let signers = vec![project_author.clone()]; + let state = fuzz_accounts + .state + .get_or_create_account( + self.accounts.state, + &[project_author.pubkey().as_ref(), STATE_SEED.as_ref()], + &incorrect_ix_sequence_1::ID, + ) + .ok_or(FuzzingError::Custom(2))? + .pubkey(); - let project = fuzz_accounts - .project - .get_or_create_account( - self.accounts.project, - &[ - project_author.pubkey().as_ref(), - state.as_ref(), - PROJECT_SEED.as_ref(), - ], - &incorrect_ix_sequence_1::ID, - ) - .ok_or(FuzzingError::Custom(3))? - .pubkey(); + let project = fuzz_accounts + .project + .get_or_create_account( + self.accounts.project, + &[ + project_author.pubkey().as_ref(), + state.as_ref(), + PROJECT_SEED.as_ref(), + ], + &incorrect_ix_sequence_1::ID, + ) + .ok_or(FuzzingError::Custom(3))? + .pubkey(); - let acc_meta = incorrect_ix_sequence_1::accounts::Register { - project_author: project_author.pubkey(), - project, - state, - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((signers, acc_meta)) + let acc_meta = incorrect_ix_sequence_1::accounts::Register { + project_author: project_author.pubkey(), + project, + state, + system_program: solana_sdk::system_program::ID, } - fn check( - &self, - pre_ix: Self::IxSnapshot, - post_ix: Self::IxSnapshot, - _ix_data: Self::IxData, - ) -> Result<(), FuzzingError> { - // This fuzz check will reveal that registrations can be performed - // even though registration windows is not open. - let state = pre_ix.state; - if let Some(_project) = post_ix.project { - let registrations_round = state.registrations_round; - if !registrations_round { - return Err(FuzzingError::Custom(1)); - } + .to_account_metas(None); + Ok((signers, acc_meta)) + } + fn check( + &self, + pre_ix: Self::IxSnapshot, + post_ix: Self::IxSnapshot, + _ix_data: Self::IxData, + ) -> Result<(), FuzzingError> { + // This fuzz check will reveal that registrations can be performed + // even though registration windows is not open. + let state = pre_ix.state; + if let Some(_project) = post_ix.project { + let registrations_round = state.registrations_round; + if !registrations_round { + return Err(FuzzingError::Custom(1)); } - Ok(()) } + Ok(()) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - project_author: AccountsStorage, - author: AccountsStorage, - project: AccountsStorage, - // There is no need to fuzz the 'system_program' account. - // system_program: AccountsStorage, - investor: AccountsStorage, - state: AccountsStorage, - } +} +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + project_author: AccountsStorage, + author: AccountsStorage, + project: AccountsStorage, + // There is no need to fuzz the 'system_program' account. + // system_program: AccountsStorage, + investor: AccountsStorage, + state: AccountsStorage, } diff --git a/examples/fuzz-tests/incorrect-ix-sequence-1/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/incorrect-ix-sequence-1/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index ae7f54e9f..2fc9e6636 100644 --- a/examples/fuzz-tests/incorrect-ix-sequence-1/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/incorrect-ix-sequence-1/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -1,17 +1,14 @@ -use fuzz_instructions::incorrect_ix_sequence_1_fuzz_instructions::Initialize; +use fuzz_instructions::Initialize; use trident_client::fuzzing::*; mod fuzz_instructions; +use fuzz_instructions::FuzzInstruction; use incorrect_ix_sequence_1::entry as entry_incorrect_ix_sequence_1; use incorrect_ix_sequence_1::ID as PROGRAM_ID_INCORRECT_IX_SEQUENCE_1; const PROGRAM_NAME_INCORRECT_IX_SEQUENCE_1: &str = "incorrect_ix_sequence_1"; -use fuzz_instructions::incorrect_ix_sequence_1_fuzz_instructions::FuzzInstruction as fuzz_instruction_incorrect_ix_sequence_1; - -pub type FuzzInstruction = fuzz_instruction_incorrect_ix_sequence_1; - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData { diff --git a/examples/fuzz-tests/simple-cpi-6/Cargo.lock b/examples/fuzz-tests/simple-cpi-6/Cargo.lock index 99c4a2833..67ba96fa1 100644 --- a/examples/fuzz-tests/simple-cpi-6/Cargo.lock +++ b/examples/fuzz-tests/simple-cpi-6/Cargo.lock @@ -928,6 +928,8 @@ name = "callee" version = "0.1.0" dependencies = [ "anchor-lang", + "trident-derive-accounts-snapshots", + "trident-fuzz", ] [[package]] diff --git a/examples/fuzz-tests/simple-cpi-6/programs/callee/Cargo.toml b/examples/fuzz-tests/simple-cpi-6/programs/callee/Cargo.toml index 73a678805..28bd0fcda 100644 --- a/examples/fuzz-tests/simple-cpi-6/programs/callee/Cargo.toml +++ b/examples/fuzz-tests/simple-cpi-6/programs/callee/Cargo.toml @@ -15,6 +15,9 @@ no-entrypoint = [] no-idl = [] no-log-ix-name = [] idl-build = ["anchor-lang/idl-build"] +trident-fuzzing = ["dep:trident-fuzz"] [dependencies] +trident-derive-accounts-snapshots = { path = "../../../../../crates/fuzz/derive/accounts_snapshots" } +trident-fuzz = { path = "../../../../../crates/fuzz", optional = true } anchor-lang = "0.30.1" diff --git a/examples/fuzz-tests/simple-cpi-6/programs/callee/src/lib.rs b/examples/fuzz-tests/simple-cpi-6/programs/callee/src/lib.rs index c7576f3d1..3774bfa78 100644 --- a/examples/fuzz-tests/simple-cpi-6/programs/callee/src/lib.rs +++ b/examples/fuzz-tests/simple-cpi-6/programs/callee/src/lib.rs @@ -1,5 +1,7 @@ use anchor_lang::prelude::*; +use trident_derive_accounts_snapshots::AccountsSnapshots; + declare_id!("HJR1TK8bgrUWzysdpS1pBGBYKF7zi1tU9cS4qj8BW8ZL"); #[program] @@ -16,7 +18,7 @@ pub mod callee { } } -#[derive(Accounts)] +#[derive(Accounts, AccountsSnapshots)] pub struct InitializeCallee<'info> { pub signer: Signer<'info>, } diff --git a/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/Cargo.toml b/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/Cargo.toml index e93ae379d..2ea35037a 100644 --- a/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/Cargo.toml +++ b/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/Cargo.toml @@ -18,6 +18,7 @@ path = "../../../../../crates/client" [dependencies.callee] path = "../../programs/callee" +features = ["trident-fuzzing"] [dependencies.caller] path = "../../programs/caller" diff --git a/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index 0a1da48e7..1da549488 100644 --- a/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,68 +1,109 @@ -pub mod caller_fuzz_instructions { - use trident_client::fuzzing::*; +use trident_client::fuzzing::*; - use caller::trident_fuzz_initialize_caller_snapshot::InitializeCallerAlias; +use callee::trident_fuzz_initialize_callee_snapshot::InitializeCalleeAlias; +use caller::trident_fuzz_initialize_caller_snapshot::InitializeCallerAlias; - type InitializeCallerSnapshot<'info> = InitializeCallerAlias<'info>; - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - InitializeCaller(InitializeCaller), +type InitializeCalleeSnapshot<'info> = InitializeCalleeAlias<'info>; +type InitializeCallerSnapshot<'info> = InitializeCallerAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + InitializeCallee(InitializeCallee), + InitializeCaller(InitializeCaller), +} +#[derive(Arbitrary, Debug)] +pub struct InitializeCallee { + pub accounts: InitializeCalleeAccounts, + pub data: InitializeCalleeData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeCalleeAccounts { + pub signer: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeCalleeData { + pub input: u8, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeCaller { + pub accounts: InitializeCallerAccounts, + pub data: InitializeCallerData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeCallerAccounts { + pub signer: AccountId, + pub program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeCallerData { + pub input: u8, +} +impl<'info> IxOps<'info> for InitializeCallee { + type IxData = callee::instruction::InitializeCallee; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeCalleeSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + callee::ID } - #[derive(Arbitrary, Debug)] - pub struct InitializeCaller { - pub accounts: InitializeCallerAccounts, - pub data: InitializeCallerData, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = callee::instruction::InitializeCallee { + input: self.data.input, + }; + Ok(data) } - #[derive(Arbitrary, Debug)] - pub struct InitializeCallerAccounts { - pub signer: AccountId, - pub program: AccountId, + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let signers = vec![todo!()]; + let acc_meta = todo!(); + Ok((signers, acc_meta)) } - #[derive(Arbitrary, Debug)] - pub struct InitializeCallerData { - pub input: u8, +} +impl<'info> IxOps<'info> for InitializeCaller { + type IxData = caller::instruction::InitializeCaller; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeCallerSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + caller::ID } - impl<'info> IxOps<'info> for InitializeCaller { - type IxData = caller::instruction::InitializeCaller; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitializeCallerSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - caller::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = caller::instruction::InitializeCaller { - input: self.data.input, - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let signer = fuzz_accounts.signer.get_or_create_account( - self.accounts.signer, - client, - 5 * solana_sdk::native_token::LAMPORTS_PER_SOL, - ); - let signers = vec![signer.clone()]; - let acc_meta = caller::accounts::InitializeCaller { - signer: signer.pubkey(), - program: callee::ID, - } - .to_account_metas(None); - Ok((signers, acc_meta)) - } + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = caller::instruction::InitializeCaller { + input: self.data.input, + }; + Ok(data) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - _program: AccountsStorage, - signer: AccountsStorage, + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let signer = fuzz_accounts.signer_caller.get_or_create_account( + self.accounts.signer, + client, + 5 * solana_sdk::native_token::LAMPORTS_PER_SOL, + ); + let signers = vec![signer.clone()]; + let acc_meta = caller::accounts::InitializeCaller { + signer: signer.pubkey(), + program: callee::ID, + } + .to_account_metas(None); + Ok((signers, acc_meta)) } } +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + _program: AccountsStorage, + signer_caller: AccountsStorage, +} diff --git a/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index 27fd7f7ba..0bc8147aa 100644 --- a/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/simple-cpi-6/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -1,3 +1,4 @@ +use fuzz_instructions::InitializeCaller; use trident_client::fuzzing::*; mod fuzz_instructions; @@ -6,18 +7,26 @@ use callee::entry as entry_callee; use callee::ID as PROGRAM_ID_CALLEE; use caller::entry as entry_caller; use caller::ID as PROGRAM_ID_CALLER; +use fuzz_instructions::FuzzInstruction; const PROGRAM_NAME_CALLEE: &str = "callee"; const PROGRAM_NAME_CALLER: &str = "caller"; -use fuzz_instructions::caller_fuzz_instructions::FuzzInstruction as fuzz_instruction_caller; - -pub type FuzzInstruction = fuzz_instruction_caller; - struct MyFuzzData; -impl FuzzDataBuilder for MyFuzzData {} +impl FuzzDataBuilder for MyFuzzData { + fn pre_ixs(u: &mut arbitrary::Unstructured) -> arbitrary::Result> { + let init_caller = FuzzInstruction::InitializeCaller(InitializeCaller::arbitrary(u)?); + Ok(vec![init_caller]) + } + fn ixs(_u: &mut arbitrary::Unstructured) -> arbitrary::Result> { + Ok(vec![]) + } + fn post_ixs(_u: &mut arbitrary::Unstructured) -> arbitrary::Result> { + Ok(vec![]) + } +} fn fuzz_iteration + std::fmt::Display, U>(fuzz_data: FuzzData) { let fuzzing_program_callee = FuzzingProgram::new( diff --git a/examples/fuzz-tests/unauthorized-access-2/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/unauthorized-access-2/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index f47561509..786b6042b 100644 --- a/examples/fuzz-tests/unauthorized-access-2/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/unauthorized-access-2/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,186 +1,184 @@ -pub mod unauthorized_access_2_fuzz_instructions { - use solana_sdk::native_token::LAMPORTS_PER_SOL; - use trident_client::fuzzing::*; - use unauthorized_access_2::ESCROW_SEED; +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; - use unauthorized_access_2::trident_fuzz_initialize_snapshot::InitializeAlias; - use unauthorized_access_2::trident_fuzz_withdraw_snapshot::WithdrawAlias; +use unauthorized_access_2::trident_fuzz_initialize_snapshot::InitializeAlias; +use unauthorized_access_2::trident_fuzz_withdraw_snapshot::WithdrawAlias; +use unauthorized_access_2::ESCROW_SEED; - type InitializeSnapshot<'info> = InitializeAlias<'info>; - type WithdrawSnapshot<'info> = WithdrawAlias<'info>; - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - Initialize(Initialize), - Withdraw(Withdraw), - } - #[derive(Arbitrary, Debug)] - pub struct Initialize { - pub accounts: InitializeAccounts, - pub data: InitializeData, +type InitializeSnapshot<'info> = InitializeAlias<'info>; +type WithdrawSnapshot<'info> = WithdrawAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + Initialize(Initialize), + Withdraw(Withdraw), +} +#[derive(Arbitrary, Debug)] +pub struct Initialize { + pub accounts: InitializeAccounts, + pub data: InitializeData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeAccounts { + pub author: AccountId, + pub escrow: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeData { + pub receiver: AccountId, + pub amount: u64, +} +#[derive(Arbitrary, Debug)] +pub struct Withdraw { + pub accounts: WithdrawAccounts, + pub _data: WithdrawData, +} +#[derive(Arbitrary, Debug)] +pub struct WithdrawAccounts { + pub receiver: AccountId, + pub escrow: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct WithdrawData {} +impl<'info> IxOps<'info> for Initialize { + type IxData = unauthorized_access_2::instruction::Initialize; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + unauthorized_access_2::ID } - #[derive(Arbitrary, Debug)] - pub struct InitializeAccounts { - pub author: AccountId, - pub escrow: AccountId, - pub system_program: AccountId, + fn get_data( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let receiver = fuzz_accounts.receiver.get_or_create_account( + self.data.receiver, + client, + 10 * LAMPORTS_PER_SOL, + ); + let data = unauthorized_access_2::instruction::Initialize { + receiver: receiver.pubkey(), + amount: self.data.amount, + }; + Ok(data) } - #[derive(Arbitrary, Debug)] - pub struct InitializeData { - pub receiver: AccountId, - pub amount: u64, + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let author = fuzz_accounts.author.get_or_create_account( + self.accounts.author, + client, + 10 * LAMPORTS_PER_SOL, + ); + + let receiver = fuzz_accounts.receiver.get_or_create_account( + self.data.receiver, + client, + 10 * LAMPORTS_PER_SOL, + ); + + let escrow = fuzz_accounts + .escrow + .get_or_create_account( + self.accounts.escrow, + &[ + author.pubkey().as_ref(), + receiver.pubkey().as_ref(), + ESCROW_SEED.as_ref(), + ], + &unauthorized_access_2::ID, + ) + .unwrap(); + let acc_meta = unauthorized_access_2::accounts::Initialize { + author: author.pubkey(), + escrow: escrow.pubkey(), + system_program: solana_sdk::system_program::ID, + } + .to_account_metas(None); + Ok((vec![author], acc_meta)) } - #[derive(Arbitrary, Debug)] - pub struct Withdraw { - pub accounts: WithdrawAccounts, - pub data: WithdrawData, +} +impl<'info> IxOps<'info> for Withdraw { + type IxData = unauthorized_access_2::instruction::Withdraw; + type IxAccounts = FuzzAccounts; + type IxSnapshot = WithdrawSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + unauthorized_access_2::ID } - #[derive(Arbitrary, Debug)] - pub struct WithdrawAccounts { - pub receiver: AccountId, - pub escrow: AccountId, - pub system_program: AccountId, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = unauthorized_access_2::instruction::Withdraw {}; + Ok(data) } - #[derive(Arbitrary, Debug)] - pub struct WithdrawData {} - impl<'info> IxOps<'info> for Initialize { - type IxData = unauthorized_access_2::instruction::Initialize; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitializeSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - unauthorized_access_2::ID - } - fn get_data( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let receiver = fuzz_accounts.receiver.get_or_create_account( - self.data.receiver, - client, - 10 * LAMPORTS_PER_SOL, - ); - let data = unauthorized_access_2::instruction::Initialize { - receiver: receiver.pubkey(), - amount: self.data.amount, - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let author = fuzz_accounts.author.get_or_create_account( - self.accounts.author, - client, - 10 * LAMPORTS_PER_SOL, - ); + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let receiver = fuzz_accounts.receiver.get_or_create_account( + self.accounts.receiver, + client, + 10 * LAMPORTS_PER_SOL, + ); - let receiver = fuzz_accounts.receiver.get_or_create_account( - self.data.receiver, - client, - 10 * LAMPORTS_PER_SOL, - ); + let escrow = fuzz_accounts + .escrow + .get_or_create_account( + self.accounts.escrow, + &[ + receiver.pubkey().as_ref(), + receiver.pubkey().as_ref(), + ESCROW_SEED.as_ref(), + ], + &unauthorized_access_2::ID, + ) + .unwrap(); - let escrow = fuzz_accounts - .escrow - .get_or_create_account( - self.accounts.escrow, - &[ - author.pubkey().as_ref(), - receiver.pubkey().as_ref(), - ESCROW_SEED.as_ref(), - ], - &unauthorized_access_2::ID, - ) - .unwrap(); - let acc_meta = unauthorized_access_2::accounts::Initialize { - author: author.pubkey(), - escrow: escrow.pubkey(), - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((vec![author], acc_meta)) + let acc_meta = unauthorized_access_2::accounts::Withdraw { + receiver: receiver.pubkey(), + escrow: escrow.pubkey(), + system_program: solana_sdk::system_program::ID, } + .to_account_metas(None); + Ok((vec![receiver], acc_meta)) } - impl<'info> IxOps<'info> for Withdraw { - type IxData = unauthorized_access_2::instruction::Withdraw; - type IxAccounts = FuzzAccounts; - type IxSnapshot = WithdrawSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - unauthorized_access_2::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = unauthorized_access_2::instruction::Withdraw {}; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let receiver = fuzz_accounts.receiver.get_or_create_account( - self.accounts.receiver, - client, - 10 * LAMPORTS_PER_SOL, - ); - - let escrow = fuzz_accounts - .escrow - .get_or_create_account( - self.accounts.escrow, - &[ - receiver.pubkey().as_ref(), - receiver.pubkey().as_ref(), - ESCROW_SEED.as_ref(), - ], - &unauthorized_access_2::ID, - ) - .unwrap(); + fn check( + &self, + pre_ix: Self::IxSnapshot, + post_ix: Self::IxSnapshot, + _ix_data: Self::IxData, + ) -> Result<(), FuzzingError> { + if let Some(escrow_pre) = pre_ix.escrow { + let receiver = pre_ix.receiver; + let receiver_lamports_before = receiver.lamports(); + let receiver_lamports_after = post_ix.receiver.lamports(); - let acc_meta = unauthorized_access_2::accounts::Withdraw { - receiver: receiver.pubkey(), - escrow: escrow.pubkey(), - system_program: solana_sdk::system_program::ID, + // If the Receiver (i.e. Signer in the Context) and stored Receiver inside Escrow Account, + // do not match, however the receiver`s balance increased, we found an Error + if receiver.key() != escrow_pre.receiver + && receiver_lamports_before < receiver_lamports_after + { + return Err(FuzzingError::BalanceMismatch); } - .to_account_metas(None); - Ok((vec![receiver], acc_meta)) } - fn check( - &self, - pre_ix: Self::IxSnapshot, - post_ix: Self::IxSnapshot, - _ix_data: Self::IxData, - ) -> Result<(), FuzzingError> { - if let Some(escrow_pre) = pre_ix.escrow { - let receiver = pre_ix.receiver; - let receiver_lamports_before = receiver.lamports(); - let receiver_lamports_after = post_ix.receiver.lamports(); - // If the Receiver (i.e. Signer in the Context) and stored Receiver inside Escrow Account, - // do not match, however the receiver`s balance increased, we found an Error - if receiver.key() != escrow_pre.receiver - && receiver_lamports_before < receiver_lamports_after - { - return Err(FuzzingError::BalanceMismatch); - } - } - - Ok(()) - } - } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - receiver: AccountsStorage, - // No need to fuzz system_program - // system_program: AccountsStorage, - author: AccountsStorage, - escrow: AccountsStorage, + Ok(()) } } +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + receiver: AccountsStorage, + // No need to fuzz system_program + // system_program: AccountsStorage, + author: AccountsStorage, + escrow: AccountsStorage, +} diff --git a/examples/fuzz-tests/unauthorized-access-2/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/unauthorized-access-2/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index cf5992955..9e5c7af33 100644 --- a/examples/fuzz-tests/unauthorized-access-2/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/unauthorized-access-2/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -1,17 +1,14 @@ -use fuzz_instructions::unauthorized_access_2_fuzz_instructions::Initialize; +use fuzz_instructions::Initialize; use trident_client::fuzzing::*; mod fuzz_instructions; +use fuzz_instructions::FuzzInstruction; use unauthorized_access_2::entry as entry_unauthorized_access_2; use unauthorized_access_2::ID as PROGRAM_ID_UNAUTHORIZED_ACCESS_2; const PROGRAM_NAME_UNAUTHORIZED_ACCESS_2: &str = "unauthorized_access_2"; -use fuzz_instructions::unauthorized_access_2_fuzz_instructions::FuzzInstruction as fuzz_instruction_unauthorized_access_2; - -pub type FuzzInstruction = fuzz_instruction_unauthorized_access_2; - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData { diff --git a/examples/fuzz-tests/unchecked-arithmetic-0/Anchor.toml b/examples/fuzz-tests/unchecked-arithmetic-0/Anchor.toml index 5ab6c5d50..ab430270d 100644 --- a/examples/fuzz-tests/unchecked-arithmetic-0/Anchor.toml +++ b/examples/fuzz-tests/unchecked-arithmetic-0/Anchor.toml @@ -1,4 +1,5 @@ [toolchain] +anchor_version = "0.30.1" [features] seeds = false diff --git a/examples/fuzz-tests/unchecked-arithmetic-0/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs b/examples/fuzz-tests/unchecked-arithmetic-0/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs index db2fd40ba..b0a5c667a 100644 --- a/examples/fuzz-tests/unchecked-arithmetic-0/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs +++ b/examples/fuzz-tests/unchecked-arithmetic-0/trident-tests/fuzz_tests/fuzz_0/fuzz_instructions.rs @@ -1,140 +1,138 @@ -pub mod unchecked_arithmetic_0_fuzz_instructions { - use solana_sdk::native_token::LAMPORTS_PER_SOL; - use trident_client::fuzzing::*; +use solana_sdk::native_token::LAMPORTS_PER_SOL; +use trident_client::fuzzing::*; - use unchecked_arithmetic_0::trident_fuzz_initialize_snapshot::InitializeAlias; - use unchecked_arithmetic_0::trident_fuzz_update_snapshot::UpdateAlias; +use unchecked_arithmetic_0::trident_fuzz_initialize_snapshot::InitializeAlias; +use unchecked_arithmetic_0::trident_fuzz_update_snapshot::UpdateAlias; - type InitializeSnapshot<'info> = InitializeAlias<'info>; - type UpdateSnapshot<'info> = UpdateAlias<'info>; - #[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] - pub enum FuzzInstruction { - Initialize(Initialize), - Update(Update), - } - #[derive(Arbitrary, Debug)] - pub struct Initialize { - pub accounts: InitializeAccounts, - pub data: InitializeData, - } - #[derive(Arbitrary, Debug)] - pub struct InitializeAccounts { - pub counter: AccountId, - pub user: AccountId, - pub system_program: AccountId, - } - #[derive(Arbitrary, Debug)] - pub struct InitializeData {} - #[derive(Arbitrary, Debug)] - pub struct Update { - pub accounts: UpdateAccounts, - pub data: UpdateData, - } - #[derive(Arbitrary, Debug)] - pub struct UpdateAccounts { - pub counter: AccountId, - pub authority: AccountId, +type InitializeSnapshot<'info> = InitializeAlias<'info>; +type UpdateSnapshot<'info> = UpdateAlias<'info>; +#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)] +pub enum FuzzInstruction { + Initialize(Initialize), + Update(Update), +} +#[derive(Arbitrary, Debug)] +pub struct Initialize { + pub accounts: InitializeAccounts, + pub _data: InitializeData, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeAccounts { + pub counter: AccountId, + pub user: AccountId, + pub _system_program: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct InitializeData {} +#[derive(Arbitrary, Debug)] +pub struct Update { + pub accounts: UpdateAccounts, + pub data: UpdateData, +} +#[derive(Arbitrary, Debug)] +pub struct UpdateAccounts { + pub counter: AccountId, + pub authority: AccountId, +} +#[derive(Arbitrary, Debug)] +pub struct UpdateData { + pub input1: u8, + pub input2: u8, +} +impl<'info> IxOps<'info> for Initialize { + type IxData = unchecked_arithmetic_0::instruction::Initialize; + type IxAccounts = FuzzAccounts; + type IxSnapshot = InitializeSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + unchecked_arithmetic_0::ID } - #[derive(Arbitrary, Debug)] - pub struct UpdateData { - pub input1: u8, - pub input2: u8, + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = unchecked_arithmetic_0::instruction::Initialize {}; + Ok(data) } - impl<'info> IxOps<'info> for Initialize { - type IxData = unchecked_arithmetic_0::instruction::Initialize; - type IxAccounts = FuzzAccounts; - type IxSnapshot = InitializeSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - unchecked_arithmetic_0::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = unchecked_arithmetic_0::instruction::Initialize {}; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let user = fuzz_accounts.user.get_or_create_account( - self.accounts.user, - client, - 5 * LAMPORTS_PER_SOL, - ); - let counter = fuzz_accounts.counter.get_or_create_account( - self.accounts.counter, - client, - 5 * LAMPORTS_PER_SOL, - ); + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let user = fuzz_accounts.user.get_or_create_account( + self.accounts.user, + client, + 5 * LAMPORTS_PER_SOL, + ); + let counter = fuzz_accounts.counter.get_or_create_account( + self.accounts.counter, + client, + 5 * LAMPORTS_PER_SOL, + ); - let acc_meta = unchecked_arithmetic_0::accounts::Initialize { - counter: counter.pubkey(), - user: user.pubkey(), - system_program: solana_sdk::system_program::ID, - } - .to_account_metas(None); - Ok((vec![user, counter], acc_meta)) + let acc_meta = unchecked_arithmetic_0::accounts::Initialize { + counter: counter.pubkey(), + user: user.pubkey(), + system_program: solana_sdk::system_program::ID, } + .to_account_metas(None); + Ok((vec![user, counter], acc_meta)) } - impl<'info> IxOps<'info> for Update { - type IxData = unchecked_arithmetic_0::instruction::Update; - type IxAccounts = FuzzAccounts; - type IxSnapshot = UpdateSnapshot<'info>; - fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { - unchecked_arithmetic_0::ID - } - fn get_data( - &self, - _client: &mut impl FuzzClient, - _fuzz_accounts: &mut FuzzAccounts, - ) -> Result { - let data = unchecked_arithmetic_0::instruction::Update { - input1: self.data.input1, - input2: self.data.input2, - }; - Ok(data) - } - fn get_accounts( - &self, - client: &mut impl FuzzClient, - fuzz_accounts: &mut FuzzAccounts, - ) -> Result<(Vec, Vec), FuzzingError> { - let user = fuzz_accounts.user.get_or_create_account( - self.accounts.authority, - client, - 15 * LAMPORTS_PER_SOL, - ); - let counter = fuzz_accounts.counter.get_or_create_account( - self.accounts.counter, - client, - 5 * LAMPORTS_PER_SOL, - ); +} +impl<'info> IxOps<'info> for Update { + type IxData = unchecked_arithmetic_0::instruction::Update; + type IxAccounts = FuzzAccounts; + type IxSnapshot = UpdateSnapshot<'info>; + fn get_program_id(&self) -> solana_sdk::pubkey::Pubkey { + unchecked_arithmetic_0::ID + } + fn get_data( + &self, + _client: &mut impl FuzzClient, + _fuzz_accounts: &mut FuzzAccounts, + ) -> Result { + let data = unchecked_arithmetic_0::instruction::Update { + input1: self.data.input1, + input2: self.data.input2, + }; + Ok(data) + } + fn get_accounts( + &self, + client: &mut impl FuzzClient, + fuzz_accounts: &mut FuzzAccounts, + ) -> Result<(Vec, Vec), FuzzingError> { + let user = fuzz_accounts.user.get_or_create_account( + self.accounts.authority, + client, + 15 * LAMPORTS_PER_SOL, + ); + let counter = fuzz_accounts.counter.get_or_create_account( + self.accounts.counter, + client, + 5 * LAMPORTS_PER_SOL, + ); - let acc_meta = unchecked_arithmetic_0::accounts::Update { - counter: counter.pubkey(), - authority: user.pubkey(), - } - .to_account_metas(None); - Ok((vec![user], acc_meta)) + let acc_meta = unchecked_arithmetic_0::accounts::Update { + counter: counter.pubkey(), + authority: user.pubkey(), } + .to_account_metas(None); + Ok((vec![user], acc_meta)) } - #[doc = r" Use AccountsStorage where T can be one of:"] - #[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] - #[derive(Default)] - pub struct FuzzAccounts { - // The 'authority' and 'system_program' were automatically - // generated in the FuzzAccounts struct, as they are both - // used in the program. However, the 'authority' is in fact - // the user account, just named differently. Therefore, we will use only - // the generated user accounts for both 'user' and 'authority account' fields - // in this fuzz test. Additionally, there is no need to fuzz the 'system_program' account. - user: AccountsStorage, - counter: AccountsStorage, - // authority: AccountsStorage, - // system_program: AccountsStorage, - } +} +#[doc = r" Use AccountsStorage where T can be one of:"] +#[doc = r" Keypair, PdaStore, TokenStore, MintStore, ProgramStore"] +#[derive(Default)] +pub struct FuzzAccounts { + // The 'authority' and 'system_program' were automatically + // generated in the FuzzAccounts struct, as they are both + // used in the program. However, the 'authority' is in fact + // the user account, just named differently. Therefore, we will use only + // the generated user accounts for both 'user' and 'authority account' fields + // in this fuzz test. Additionally, there is no need to fuzz the 'system_program' account. + user: AccountsStorage, + counter: AccountsStorage, + // authority: AccountsStorage, + // system_program: AccountsStorage, } diff --git a/examples/fuzz-tests/unchecked-arithmetic-0/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs b/examples/fuzz-tests/unchecked-arithmetic-0/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs index 3e3e8ad20..eabe55094 100644 --- a/examples/fuzz-tests/unchecked-arithmetic-0/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs +++ b/examples/fuzz-tests/unchecked-arithmetic-0/trident-tests/fuzz_tests/fuzz_0/test_fuzz.rs @@ -1,18 +1,15 @@ -use fuzz_instructions::unchecked_arithmetic_0_fuzz_instructions::Initialize; -use fuzz_instructions::unchecked_arithmetic_0_fuzz_instructions::Update; +use fuzz_instructions::Initialize; +use fuzz_instructions::Update; use trident_client::fuzzing::*; mod fuzz_instructions; +use fuzz_instructions::FuzzInstruction; use unchecked_arithmetic_0::entry as entry_unchecked_arithmetic_0; use unchecked_arithmetic_0::ID as PROGRAM_ID_UNCHECKED_ARITHMETIC_0; const PROGRAM_NAME_UNCHECKED_ARITHMETIC_0: &str = "unchecked_arithmetic_0"; -use fuzz_instructions::unchecked_arithmetic_0_fuzz_instructions::FuzzInstruction as fuzz_instruction_unchecked_arithmetic_0; - -pub type FuzzInstruction = fuzz_instruction_unchecked_arithmetic_0; - struct MyFuzzData; impl FuzzDataBuilder for MyFuzzData {