diff --git a/addin-vesting/program/src/instruction.rs b/addin-vesting/program/src/instruction.rs index 8dc7bd5..0608ed1 100644 --- a/addin-vesting/program/src/instruction.rs +++ b/addin-vesting/program/src/instruction.rs @@ -25,7 +25,7 @@ pub enum VestingInstruction { /// * Single owner /// 0. `[]` The system program account /// 1. `[]` The spl-token program account - /// 2. `[writable]` The vesting account. PDA seeds: [seeds] + /// 2. `[writable]` The vesting account. PDA seeds: [vesting spl-token account] /// 3. `[writable]` The vesting spl-token account /// 4. `[signer]` The source spl-token account owner /// 5. `[writable]` The source spl-token account @@ -39,8 +39,6 @@ pub enum VestingInstruction { /// 11. `[writable]` The MaxVoterWeightRecord. PDA seeds: ['max_voter_weight', realm, token_mint] /// Deposit { - #[allow(dead_code)] - seeds: [u8; 32], #[allow(dead_code)] schedules: Vec, }, @@ -51,7 +49,7 @@ pub enum VestingInstruction { /// /// * Single owner /// 0. `[]` The spl-token program account - /// 1. `[writable]` The vesting account. PDA seeds: [seeds] + /// 1. `[writable]` The vesting account. PDA seeds: [vesting spl-token account] /// 2. `[writable]` The vesting spl-token account /// 3. `[writable]` The destination spl-token account /// 4. `[signer]` The Vesting Owner account @@ -63,11 +61,7 @@ pub enum VestingInstruction { /// 8. `[writable]` The VoterWeightRecord. PDA seeds: ['voter_weight', realm, token_mint, vesting_owner] /// 9. `[writable]` The MaxVoterWeightRecord. PDA seeds: ['max_voter_weight', realm, token_mint] /// - Withdraw { - #[allow(dead_code)] - seeds: [u8; 32], - }, - + Withdraw, /// Change the destination account of a given simple vesting contract (SVC) @@ -76,7 +70,7 @@ pub enum VestingInstruction { /// Accounts expected by this instruction: /// /// * Single owner - /// 0. `[writable]` The Vesting account. PDA seeds: [seeds] + /// 0. `[writable]` The Vesting account. PDA seeds: [vesting spl-token account] /// 1. `[signer]` The Current Vesting Owner account /// 2. `[]` The New Vesting Owner account /// @@ -86,10 +80,8 @@ pub enum VestingInstruction { /// 5. `[]` Governing Owner Record. PDA seeds (governance program): ['governance', realm, token_mint, current_vesting_owner] /// 6. `[writable]` The from VoterWeight Record. PDA seeds: ['voter_weight', realm, token_mint, current_vesting_owner] /// 7. `[writable]` The to VoterWeight Record. PDA seeds: ['voter_weight', realm, token_mint, new_vesting_owner] - ChangeOwner { - #[allow(dead_code)] - seeds: [u8; 32], - }, + ChangeOwner, + /// Create VoterWeightRecord for account /// @@ -105,12 +97,13 @@ pub enum VestingInstruction { /// 6. `[writable]` The VoterWeightRecord. PDA seeds: ['voter_weight', realm, token_mint, token_owner] CreateVoterWeightRecord, + /// Set Vote Percentage for calcalate voter_weight from total_amount of deposited tokens /// /// Accounts expected by this instruction: /// /// * Single owner - /// 0. `[]` The Vesting account. PDA seeds: [seeds] + /// 0. `[]` The Vesting account. PDA seeds: [vesting spl-token account] /// 1. `[]` The Vesting Owner account /// 2. `[signer]` The Vesting Authority account /// 3. `[]` The Governance program account @@ -118,9 +111,6 @@ pub enum VestingInstruction { /// 5. `[]` Governing Owner Record. PDA seeds (governance program): ['governance', realm, token_mint, vesting_owner] /// 6. `[writable]` The VoterWeight Record. PDA seeds: ['voter_weight', realm, token_mint, vesting_owner] SetVotePercentage { - #[allow(dead_code)] - seeds: [u8; 32], - #[allow(dead_code)] vote_percentage: u16, }, @@ -131,7 +121,6 @@ pub enum VestingInstruction { pub fn deposit( program_id: &Pubkey, token_program_id: &Pubkey, - seeds: [u8; 32], vesting_token_account: &Pubkey, source_token_owner: &Pubkey, source_token_account: &Pubkey, @@ -139,7 +128,7 @@ pub fn deposit( payer: &Pubkey, schedules: Vec, ) -> Result { - let vesting_account = Pubkey::create_program_address(&[&seeds], program_id)?; + let (vesting_account, _) = Pubkey::find_program_address(&[vesting_token_account.as_ref()], program_id); let accounts = vec![ AccountMeta::new_readonly(system_program::id(), false), AccountMeta::new_readonly(*token_program_id, false), @@ -151,7 +140,7 @@ pub fn deposit( AccountMeta::new_readonly(*payer, true), ]; - let instruction = VestingInstruction::Deposit { seeds, schedules }; + let instruction = VestingInstruction::Deposit { schedules }; Ok(Instruction { program_id: *program_id, @@ -166,7 +155,6 @@ pub fn deposit( pub fn deposit_with_realm( program_id: &Pubkey, token_program_id: &Pubkey, - seeds: [u8; 32], vesting_token_account: &Pubkey, source_token_owner: &Pubkey, source_token_account: &Pubkey, @@ -177,7 +165,7 @@ pub fn deposit_with_realm( realm: &Pubkey, mint: &Pubkey, ) -> Result { - let vesting_account = Pubkey::create_program_address(&[&seeds], program_id)?; + let (vesting_account, _) = Pubkey::find_program_address(&[vesting_token_account.as_ref()], program_id); let voting_weight_record_account = get_voter_weight_record_address(program_id, realm, mint, vesting_owner); let max_voting_weight_record_account = get_max_voter_weight_record_address(program_id, realm, mint); let accounts = vec![ @@ -196,7 +184,7 @@ pub fn deposit_with_realm( AccountMeta::new(max_voting_weight_record_account, false), ]; - let instruction = VestingInstruction::Deposit { seeds, schedules }; + let instruction = VestingInstruction::Deposit { schedules }; Ok(Instruction { program_id: *program_id, @@ -209,12 +197,11 @@ pub fn deposit_with_realm( pub fn withdraw( program_id: &Pubkey, token_program_id: &Pubkey, - seeds: [u8; 32], vesting_token_account: &Pubkey, destination_token_account: &Pubkey, vesting_owner: &Pubkey, ) -> Result { - let vesting_account = Pubkey::create_program_address(&[&seeds], program_id)?; + let (vesting_account, _) = Pubkey::find_program_address(&[vesting_token_account.as_ref()], program_id); let accounts = vec![ AccountMeta::new_readonly(*token_program_id, false), AccountMeta::new(vesting_account, false), @@ -223,7 +210,7 @@ pub fn withdraw( AccountMeta::new_readonly(*vesting_owner, true), ]; - let instruction = VestingInstruction::Withdraw { seeds }; + let instruction = VestingInstruction::Withdraw; Ok(Instruction { program_id: *program_id, @@ -237,7 +224,6 @@ pub fn withdraw( pub fn withdraw_with_realm( program_id: &Pubkey, token_program_id: &Pubkey, - seeds: [u8; 32], vesting_token_account: &Pubkey, destination_token_account: &Pubkey, vesting_owner: &Pubkey, @@ -245,7 +231,7 @@ pub fn withdraw_with_realm( realm: &Pubkey, mint: &Pubkey, ) -> Result { - let vesting_account = Pubkey::create_program_address(&[&seeds], program_id)?; + let (vesting_account, _) = Pubkey::find_program_address(&[vesting_token_account.as_ref()], program_id); let owner_record_account = get_token_owner_record_address(governance_id, realm, mint, vesting_owner); let voting_weight_record_account = get_voter_weight_record_address(program_id, realm, mint, vesting_owner); let max_voting_weight_record_account = get_max_voter_weight_record_address(program_id, realm, mint); @@ -263,7 +249,7 @@ pub fn withdraw_with_realm( AccountMeta::new(max_voting_weight_record_account, false), ]; - let instruction = VestingInstruction::Withdraw { seeds }; + let instruction = VestingInstruction::Withdraw; Ok(Instruction { program_id: *program_id, @@ -275,18 +261,18 @@ pub fn withdraw_with_realm( /// Creates a `ChangeOwner` instruction pub fn change_owner( program_id: &Pubkey, - seeds: [u8; 32], + vesting_token_account: &Pubkey, vesting_owner: &Pubkey, new_vesting_owner: &Pubkey, ) -> Result { - let vesting_account = Pubkey::create_program_address(&[&seeds], program_id)?; + let (vesting_account, _) = Pubkey::find_program_address(&[vesting_token_account.as_ref()], program_id); let accounts = vec![ AccountMeta::new(vesting_account, false), AccountMeta::new_readonly(*vesting_owner, true), AccountMeta::new_readonly(*new_vesting_owner, false), ]; - let instruction = VestingInstruction::ChangeOwner { seeds }; + let instruction = VestingInstruction::ChangeOwner; Ok(Instruction { program_id: *program_id, @@ -298,14 +284,14 @@ pub fn change_owner( /// Creates a `ChangeOwner` instruction with realm pub fn change_owner_with_realm( program_id: &Pubkey, - seeds: [u8; 32], + vesting_token_account: &Pubkey, vesting_owner: &Pubkey, new_vesting_owner: &Pubkey, governance_id: &Pubkey, realm: &Pubkey, mint: &Pubkey, ) -> Result { - let vesting_account = Pubkey::create_program_address(&[&seeds], program_id)?; + let (vesting_account, _) = Pubkey::find_program_address(&[vesting_token_account.as_ref()], program_id); let current_owner_record_account = get_token_owner_record_address(governance_id, realm, mint, vesting_owner); let current_voter_weight_record_account = get_voter_weight_record_address(program_id, realm, mint, vesting_owner); let new_voter_weight_record_account = get_voter_weight_record_address(program_id, realm, mint, new_vesting_owner); @@ -321,7 +307,7 @@ pub fn change_owner_with_realm( AccountMeta::new(new_voter_weight_record_account, false), ]; - let instruction = VestingInstruction::ChangeOwner { seeds }; + let instruction = VestingInstruction::ChangeOwner; Ok(Instruction { program_id: *program_id, @@ -365,7 +351,7 @@ pub fn create_voter_weight_record( #[allow(clippy::too_many_arguments)] pub fn set_vote_percentage_with_realm( program_id: &Pubkey, - seeds: [u8; 32], + vesting_token_account: &Pubkey, vesting_owner: &Pubkey, vesting_authority: &Pubkey, governance_id: &Pubkey, @@ -373,7 +359,7 @@ pub fn set_vote_percentage_with_realm( mint: &Pubkey, vote_percentage: u16, ) -> Result { - let vesting_account = Pubkey::create_program_address(&[&seeds], program_id)?; + let (vesting_account, _) = Pubkey::find_program_address(&[vesting_token_account.as_ref()], program_id); let token_owner_record_account = get_token_owner_record_address(governance_id, realm, mint, vesting_owner); let voter_weight_record_account = get_voter_weight_record_address(program_id, realm, mint, vesting_owner); let accounts = vec![ @@ -386,7 +372,7 @@ pub fn set_vote_percentage_with_realm( AccountMeta::new(voter_weight_record_account, false), ]; - let instruction = VestingInstruction::SetVotePercentage { seeds, vote_percentage }; + let instruction = VestingInstruction::SetVotePercentage { vote_percentage }; Ok(Instruction { program_id: *program_id, @@ -404,7 +390,6 @@ mod test { #[test] fn test_instruction_packing() { let original_deposit = VestingInstruction::Deposit { - seeds: [50u8; 32], schedules: vec![VestingSchedule { amount: 42, release_time: 250, @@ -416,17 +401,23 @@ mod test { ); - let original_withdraw = VestingInstruction::Withdraw { seeds: [50u8; 32] }; + let original_withdraw = VestingInstruction::Withdraw; assert_eq!( original_withdraw, VestingInstruction::try_from_slice(&original_withdraw.try_to_vec().unwrap()).unwrap() ); - let original_change = VestingInstruction::ChangeOwner { seeds: [50u8; 32] }; + let original_change = VestingInstruction::ChangeOwner; assert_eq!( original_change, VestingInstruction::try_from_slice(&original_change.try_to_vec().unwrap()).unwrap() ); + + let original_set_vote_percentage = VestingInstruction::SetVotePercentage { vote_percentage: 2500 }; + assert_eq!( + original_set_vote_percentage, + VestingInstruction::try_from_slice(&original_set_vote_percentage.try_to_vec().unwrap()).unwrap() + ); } } diff --git a/addin-vesting/program/src/processor.rs b/addin-vesting/program/src/processor.rs index 501194f..0ffa0ac 100644 --- a/addin-vesting/program/src/processor.rs +++ b/addin-vesting/program/src/processor.rs @@ -46,7 +46,6 @@ impl Processor { pub fn process_deposit( program_id: &Pubkey, accounts: &[AccountInfo], - seeds: [u8; 32], schedules: Vec, ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); @@ -69,11 +68,6 @@ impl Processor { None }; - let vesting_account_key = Pubkey::create_program_address(&[&seeds], program_id)?; - if vesting_account_key != *vesting_account.key { - return Err(VestingError::InvalidVestingAccount.into()); - } - if !source_token_account_owner.is_signer { return Err(VestingError::MissingRequiredSigner.into()); } @@ -84,7 +78,7 @@ impl Processor { let vesting_token_account_data = Account::unpack(&vesting_token_account.data.borrow())?; - if vesting_token_account_data.owner != vesting_account_key || + if vesting_token_account_data.owner != *vesting_account.key || vesting_token_account_data.delegate.is_some() || vesting_token_account_data.close_authority.is_some() { return Err(VestingError::InvalidVestingTokenAccount.into()); @@ -99,6 +93,7 @@ impl Processor { account_type: VestingAccountType::VestingRecord, owner: *vesting_owner_account.key, mint: vesting_token_account_data.mint, + token: *vesting_token_account.key, realm: realm_info.map(|v| *v.1.key), schedule: schedules }; @@ -106,7 +101,7 @@ impl Processor { payer_account, vesting_account, &vesting_record, - &[&seeds[..31]], + &[vesting_token_account.key.as_ref()], program_id, system_program_account, &Rent::get()?, @@ -188,7 +183,6 @@ impl Processor { pub fn process_withdraw( program_id: &Pubkey, _accounts: &[AccountInfo], - seeds: [u8; 32], ) -> ProgramResult { let accounts_iter = &mut _accounts.iter(); @@ -208,7 +202,7 @@ impl Processor { None }; - let vesting_account_key = Pubkey::create_program_address(&[&seeds], program_id)?; + let (vesting_account_key,vesting_account_seed) = Pubkey::find_program_address(&[vesting_token_account.key.as_ref()], program_id); if vesting_account_key != *vesting_account.key { return Err(VestingError::InvalidVestingAccount.into()); } @@ -222,6 +216,10 @@ impl Processor { return Err(VestingError::InvalidOwnerForVestingAccount.into()); } + if vesting_record.token != *vesting_token_account.key { + return Err(VestingError::InvalidVestingTokenAccount.into()); + } + let vesting_token_account_data = Account::unpack(&vesting_token_account.data.borrow())?; if vesting_token_account_data.owner != vesting_account_key { return Err(VestingError::InvalidVestingTokenAccount.into()); @@ -257,7 +255,7 @@ impl Processor { destination_token_account.clone(), vesting_account.clone(), ], - &[&[&seeds]], + &[&[vesting_token_account.key.as_ref(), &[vesting_account_seed]]], )?; // Reset released amounts to 0. This makes the simple unlock safe with complex scheduling contracts @@ -315,7 +313,6 @@ impl Processor { pub fn process_change_owner( program_id: &Pubkey, accounts: &[AccountInfo], - seeds: [u8; 32], ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); @@ -334,11 +331,6 @@ impl Processor { msg!("Change owner {} -> {}", vesting_owner_account.key, new_vesting_owner_account.key); - let vesting_account_key = Pubkey::create_program_address(&[&seeds], program_id)?; - if vesting_account_key != *vesting_account.key { - return Err(VestingError::InvalidVestingAccount.into()); - } - let mut vesting_record = get_account_data::(program_id, vesting_account)?; if vesting_record.owner != *vesting_owner_account.key { @@ -438,7 +430,6 @@ impl Processor { pub fn process_set_vote_percentage( program_id: &Pubkey, accounts: &[AccountInfo], - seeds: [u8; 32], vote_percentage: u16, ) -> ProgramResult { let accounts_iter = &mut accounts.iter(); @@ -451,11 +442,6 @@ impl Processor { let owner_record_account = next_account_info(accounts_iter)?; let voter_weight_record_account = next_account_info(accounts_iter)?; - let vesting_account_key = Pubkey::create_program_address(&[&seeds], program_id)?; - if vesting_account_key != *vesting_account.key { - return Err(VestingError::InvalidVestingAccount.into()); - } - let vesting_record = get_account_data::(program_id, vesting_account)?; let expected_realm_account = vesting_record.realm.ok_or(VestingError::VestingIsNotUnderRealm)?; @@ -502,20 +488,20 @@ impl Processor { msg!("VESTING-INSTRUCTION: {:?}", instruction); match instruction { - VestingInstruction::Deposit {seeds, schedules} => { - Self::process_deposit(program_id, accounts, seeds, schedules) + VestingInstruction::Deposit {schedules} => { + Self::process_deposit(program_id, accounts, schedules) } - VestingInstruction::Withdraw {seeds} => { - Self::process_withdraw(program_id, accounts, seeds) + VestingInstruction::Withdraw => { + Self::process_withdraw(program_id, accounts) } - VestingInstruction::ChangeOwner {seeds} => { - Self::process_change_owner(program_id, accounts, seeds) + VestingInstruction::ChangeOwner => { + Self::process_change_owner(program_id, accounts) } VestingInstruction::CreateVoterWeightRecord => { Self::process_create_voter_weight_record(program_id, accounts) } - VestingInstruction::SetVotePercentage {seeds, vote_percentage} => { - Self::process_set_vote_percentage(program_id, accounts, seeds, vote_percentage) + VestingInstruction::SetVotePercentage {vote_percentage} => { + Self::process_set_vote_percentage(program_id, accounts, vote_percentage) } } } diff --git a/addin-vesting/program/src/state.rs b/addin-vesting/program/src/state.rs index 2446ec3..978e9ee 100644 --- a/addin-vesting/program/src/state.rs +++ b/addin-vesting/program/src/state.rs @@ -26,6 +26,7 @@ pub struct VestingRecord { pub account_type: VestingAccountType, pub owner: Pubkey, pub mint: Pubkey, + pub token: Pubkey, pub realm: Option, pub schedule: Vec, } @@ -52,6 +53,7 @@ mod tests { account_type: VestingAccountType::VestingRecord, owner: Pubkey::new_unique(), mint: Pubkey::new_unique(), + token: Pubkey::new_unique(), realm: Some(Pubkey::new_unique()), schedule: vec!( VestingSchedule {release_time: 30767976, amount: 969}, @@ -81,5 +83,4 @@ mod tests { let vesting_record_target = get_account_data::(&program_id, &account_info).unwrap(); assert_eq!(vesting_record_source, vesting_record_target); } - } diff --git a/addin-vesting/program/tests/functional.rs b/addin-vesting/program/tests/functional.rs index 8f97e51..4011d1b 100644 --- a/addin-vesting/program/tests/functional.rs +++ b/addin-vesting/program/tests/functional.rs @@ -61,10 +61,8 @@ async fn test_token_vesting() { let new_destination_account = Keypair::new(); let new_destination_token_account = Keypair::new(); - let mut seeds = [42u8; 32]; - let (vesting_account_key, bump) = Pubkey::find_program_address(&[&seeds[..31]], &program_id); - seeds[31] = bump; let vesting_token_account = Keypair::new(); + let (vesting_account_key,_) = Pubkey::find_program_address(&[&vesting_token_account.pubkey().as_ref()], &program_id); let mut program_test = ProgramTest::new( "spl_governance_addin_vesting", @@ -136,7 +134,6 @@ async fn test_token_vesting() { deposit( &program_id, &spl_token::id(), - seeds.clone(), &vesting_token_account.pubkey(), &source_account.pubkey(), &source_token_account.pubkey(), @@ -157,7 +154,7 @@ async fn test_token_vesting() { let change_owner_instructions = [ change_owner( &program_id, - seeds.clone(), + &vesting_token_account.pubkey(), &destination_account.pubkey(), &new_destination_account.pubkey(), ).unwrap(), @@ -174,7 +171,6 @@ async fn test_token_vesting() { withdraw( &program_id, &spl_token::id(), - seeds.clone(), &vesting_token_account.pubkey(), &destination_token_account.pubkey(), &new_destination_account.pubkey(), @@ -217,16 +213,9 @@ async fn test_token_vesting_with_realm() { let new_destination_token_account = Keypair::new(); let new_destination_delegate = Keypair::new(); - let mut seeds = [42u8; 32]; - let (vesting_account_key, bump) = Pubkey::find_program_address(&[&seeds[..31]], &program_id); - seeds[31] = bump; let vesting_token_account = Keypair::new(); + let (vesting_account_key,_) = Pubkey::find_program_address(&[&vesting_token_account.pubkey().as_ref()], &program_id); - let mut seeds2 = [40u8; 32]; - let (vesting_account_key2, bump2) = Pubkey::find_program_address(&[&seeds2[..31]], &program_id); - seeds2[31] = bump2; - let vesting_token_account2 = Keypair::new(); - let mut program_test = ProgramTest::new( "spl_governance_addin_vesting", program_id, @@ -271,9 +260,6 @@ async fn test_token_vesting_with_realm() { banks_client.process_transaction( create_token_account(&payer, &mint, recent_blockhash, &new_destination_token_account, &new_destination_account.pubkey()) ).await.unwrap(); - banks_client.process_transaction( - create_token_account(&payer, &mint, recent_blockhash, &vesting_token_account2, &vesting_account_key2) - ).await.unwrap(); // Create and process the vesting transactions @@ -343,7 +329,6 @@ async fn test_token_vesting_with_realm() { deposit_with_realm( &program_id, &spl_token::id(), - seeds.clone(), &vesting_token_account.pubkey(), &source_account.pubkey(), &source_token_account.pubkey(), @@ -384,7 +369,7 @@ async fn test_token_vesting_with_realm() { let change_owner_instructions = [ change_owner_with_realm( &program_id, - seeds.clone(), + &vesting_token_account.pubkey(), &destination_account.pubkey(), &new_destination_account.pubkey(), &governance_id, @@ -421,7 +406,7 @@ async fn test_token_vesting_with_realm() { let set_vote_percentage_instructions = [ set_vote_percentage_with_realm( &program_id, - seeds.clone(), + &vesting_token_account.pubkey(), &new_destination_account.pubkey(), &new_destination_delegate.pubkey(), &governance_id, @@ -453,7 +438,6 @@ async fn test_token_vesting_with_realm() { withdraw_with_realm( &program_id, &spl_token::id(), - seeds.clone(), &vesting_token_account.pubkey(), &destination_token_account.pubkey(), &new_destination_account.pubkey(),