diff --git a/governance/chat/program/tests/program_test/mod.rs b/governance/chat/program/tests/program_test/mod.rs index 1d656df79d2..a8abd4b9fa6 100644 --- a/governance/chat/program/tests/program_test/mod.rs +++ b/governance/chat/program/tests/program_test/mod.rs @@ -103,13 +103,14 @@ impl GovernanceChatProgramTest { let token_source = Keypair::new(); let transfer_authority = Keypair::new(); + let amount = 100; self.bench .create_token_account_with_transfer_authority( &token_source, &governing_token_mint_keypair.pubkey(), &governing_token_mint_authority, - 100, + amount, &token_owner, &transfer_authority.pubkey(), ) @@ -122,6 +123,7 @@ impl GovernanceChatProgramTest { &token_owner.pubkey(), &token_owner.pubkey(), &self.bench.payer.pubkey(), + amount, &governing_token_mint_keypair.pubkey(), ); @@ -244,6 +246,7 @@ impl GovernanceChatProgramTest { &token_owner.pubkey(), &token_owner.pubkey(), &self.bench.payer.pubkey(), + deposit_amount, &proposal_cookie.governing_token_mint, ); diff --git a/governance/program/src/instruction.rs b/governance/program/src/instruction.rs index d6bd22febec..69461b2f981 100644 --- a/governance/program/src/instruction.rs +++ b/governance/program/src/instruction.rs @@ -82,7 +82,11 @@ pub enum GovernanceInstruction { /// 7. `[]` System /// 8. `[]` SPL Token /// 9. `[]` Sysvar Rent - DepositGoverningTokens {}, + DepositGoverningTokens { + /// The amount to deposit into the realm + #[allow(dead_code)] + amount: u64, + }, /// Withdraws governing tokens (Community or Council) from Governance Realm and downgrades your voter weight within the Realm /// Note: It's only possible to withdraw tokens if the Voter doesn't have any outstanding active votes @@ -509,6 +513,7 @@ pub fn create_realm( } /// Creates DepositGoverningTokens instruction +#[allow(clippy::too_many_arguments)] pub fn deposit_governing_tokens( program_id: &Pubkey, // Accounts @@ -518,6 +523,7 @@ pub fn deposit_governing_tokens( governing_token_transfer_authority: &Pubkey, payer: &Pubkey, // Args + amount: u64, governing_token_mint: &Pubkey, ) -> Instruction { let token_owner_record_address = get_token_owner_record_address( @@ -543,7 +549,7 @@ pub fn deposit_governing_tokens( AccountMeta::new_readonly(sysvar::rent::id(), false), ]; - let instruction = GovernanceInstruction::DepositGoverningTokens {}; + let instruction = GovernanceInstruction::DepositGoverningTokens { amount }; Instruction { program_id: *program_id, diff --git a/governance/program/src/processor/mod.rs b/governance/program/src/processor/mod.rs index 67406e89092..438ff045411 100644 --- a/governance/program/src/processor/mod.rs +++ b/governance/program/src/processor/mod.rs @@ -26,7 +26,6 @@ mod process_sign_off_proposal; mod process_withdraw_governing_tokens; use crate::instruction::GovernanceInstruction; -use borsh::BorshDeserialize; use process_add_signatory::*; use process_cancel_proposal::*; @@ -54,8 +53,8 @@ use process_sign_off_proposal::*; use process_withdraw_governing_tokens::*; use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError, - pubkey::Pubkey, + account_info::AccountInfo, borsh::try_from_slice_unchecked, entrypoint::ProgramResult, msg, + program_error::ProgramError, pubkey::Pubkey, }; /// Processes an instruction @@ -64,8 +63,9 @@ pub fn process_instruction( accounts: &[AccountInfo], input: &[u8], ) -> ProgramResult { - let instruction = GovernanceInstruction::try_from_slice(input) - .map_err(|_| ProgramError::InvalidInstructionData)?; + // Use try_from_slice_unchecked to support forward compatibility of newer UI with older program + let instruction: GovernanceInstruction = + try_from_slice_unchecked(input).map_err(|_| ProgramError::InvalidInstructionData)?; if let GovernanceInstruction::InsertInstruction { index, @@ -88,8 +88,8 @@ pub fn process_instruction( process_create_realm(program_id, accounts, name, config_args) } - GovernanceInstruction::DepositGoverningTokens {} => { - process_deposit_governing_tokens(program_id, accounts) + GovernanceInstruction::DepositGoverningTokens { amount } => { + process_deposit_governing_tokens(program_id, accounts, amount) } GovernanceInstruction::WithdrawGoverningTokens {} => { diff --git a/governance/program/src/processor/process_deposit_governing_tokens.rs b/governance/program/src/processor/process_deposit_governing_tokens.rs index 08d434f25fd..c5588bd9f69 100644 --- a/governance/program/src/processor/process_deposit_governing_tokens.rs +++ b/governance/program/src/processor/process_deposit_governing_tokens.rs @@ -21,9 +21,7 @@ use crate::{ }, tools::{ account::create_and_serialize_account_signed, - spl_token::{ - get_spl_token_amount, get_spl_token_mint, get_spl_token_owner, transfer_spl_tokens, - }, + spl_token::{get_spl_token_mint, get_spl_token_owner, transfer_spl_tokens}, }, }; @@ -31,6 +29,7 @@ use crate::{ pub fn process_deposit_governing_tokens( program_id: &Pubkey, accounts: &[AccountInfo], + amount: u64, ) -> ProgramResult { let account_info_iter = &mut accounts.iter(); @@ -59,8 +58,6 @@ pub fn process_deposit_governing_tokens( governing_token_holding_info.key, )?; - let amount = get_spl_token_amount(governing_token_source_info)?; - transfer_spl_tokens( governing_token_source_info, governing_token_holding_info, diff --git a/governance/program/src/tools/spl_token.rs b/governance/program/src/tools/spl_token.rs index 86eacc9e051..c202937dccf 100644 --- a/governance/program/src/tools/spl_token.rs +++ b/governance/program/src/tools/spl_token.rs @@ -220,17 +220,6 @@ pub fn assert_is_valid_spl_token_mint(mint_info: &AccountInfo) -> Result<(), Pro Ok(()) } -/// Computationally cheap method to get amount from a token account -/// It reads amount without deserializing full account data -pub fn get_spl_token_amount(token_account_info: &AccountInfo) -> Result { - assert_is_valid_spl_token_account(token_account_info)?; - - // TokeAccount layout: mint(32), owner(32), amount(8), ... - let data = token_account_info.try_borrow_data()?; - let amount = array_ref![data, 64, 8]; - Ok(u64::from_le_bytes(*amount)) -} - /// Computationally cheap method to get mint from a token account /// It reads mint without deserializing full account data pub fn get_spl_token_mint(token_account_info: &AccountInfo) -> Result { diff --git a/governance/program/tests/process_deposit_governing_tokens.rs b/governance/program/tests/process_deposit_governing_tokens.rs index 678136bda62..ea7ec37c9ce 100644 --- a/governance/program/tests/process_deposit_governing_tokens.rs +++ b/governance/program/tests/process_deposit_governing_tokens.rs @@ -196,13 +196,15 @@ async fn test_deposit_initial_community_tokens_with_owner_must_sign_error() { let transfer_authority = Keypair::new(); let token_source = Keypair::new(); + let amount = 10; + governance_test .bench .create_token_account_with_transfer_authority( &token_source, &realm_cookie.account.community_mint, &realm_cookie.community_mint_authority, - 10, + amount, &token_owner, &transfer_authority.pubkey(), ) @@ -215,6 +217,7 @@ async fn test_deposit_initial_community_tokens_with_owner_must_sign_error() { &token_owner.pubkey(), &transfer_authority.pubkey(), &governance_test.bench.context.payer.pubkey(), + amount, &realm_cookie.account.community_mint, ); @@ -244,13 +247,15 @@ async fn test_deposit_initial_community_tokens_with_invalid_owner_error() { let invalid_owner = Keypair::new(); + let amount = 10; + governance_test .bench .create_token_account_with_transfer_authority( &token_source, &realm_cookie.account.community_mint, &realm_cookie.community_mint_authority, - 10, + amount, &token_owner, &transfer_authority.pubkey(), ) @@ -263,6 +268,7 @@ async fn test_deposit_initial_community_tokens_with_invalid_owner_error() { &invalid_owner.pubkey(), &transfer_authority.pubkey(), &governance_test.bench.context.payer.pubkey(), + amount, &realm_cookie.account.community_mint, ); @@ -290,13 +296,15 @@ async fn test_deposit_community_tokens_with_malicious_holding_account_error() { .await .unwrap(); + let amount = 50; + governance_test .bench .mint_tokens( &realm_cookie.account.community_mint, &realm_cookie.community_mint_authority, &token_owner_record_cookie.token_source, - 50, + amount, ) .await; @@ -307,6 +315,7 @@ async fn test_deposit_community_tokens_with_malicious_holding_account_error() { &token_owner_record_cookie.token_owner.pubkey(), &token_owner_record_cookie.token_owner.pubkey(), &governance_test.bench.context.payer.pubkey(), + amount, &realm_cookie.account.community_mint, ); diff --git a/governance/program/tests/program_test/mod.rs b/governance/program/tests/program_test/mod.rs index fb666b3df94..5c62a795009 100644 --- a/governance/program/tests/program_test/mod.rs +++ b/governance/program/tests/program_test/mod.rs @@ -523,6 +523,7 @@ impl GovernanceProgramTest { &token_owner.pubkey(), &token_owner.pubkey(), &self.bench.payer.pubkey(), + amount, governing_mint, ); @@ -615,6 +616,7 @@ impl GovernanceProgramTest { &token_owner_record_cookie.token_owner.pubkey(), &token_owner_record_cookie.token_owner.pubkey(), &self.bench.payer.pubkey(), + amount, governing_token_mint, );