diff --git a/target_chains/solana/programs/pyth-solana-receiver/src/lib.rs b/target_chains/solana/programs/pyth-solana-receiver/src/lib.rs index bd4f0c7b..28fc8394 100644 --- a/target_chains/solana/programs/pyth-solana-receiver/src/lib.rs +++ b/target_chains/solana/programs/pyth-solana-receiver/src/lib.rs @@ -142,6 +142,11 @@ pub mod pyth_solana_receiver { ); let guardian_keys = &guardian_set.keys; + require_gte!( + vaa.signature_count(), + config.minimum_signatures, + ReceiverError::InsufficientGuardianSignatures + ); // Generate the same message hash (using keccak) that the Guardians used to generate their // signatures. This message hash will be hashed again to produce the digest for @@ -172,12 +177,6 @@ pub mod pyth_solana_receiver { let treasury = &ctx.accounts.treasury; let price_update_account = &mut ctx.accounts.price_update_account; - require_gte!( - vaa.signature_count(), - config.minimum_signatures, - ReceiverError::InsufficientGuardianSignatures - ); - let vaa_components = VaaComponents { verification_level: VerificationLevel::Partial { num_signatures: vaa.signature_count(), @@ -339,8 +338,7 @@ fn deserialize_guardian_set_checked( wormhole: &Pubkey, ) -> Result> { let mut guardian_set_data: &[u8] = &account_info.try_borrow_data()?; - let guardian_set = - AccountVariant::::try_deserialize_unchecked(&mut guardian_set_data)?; + let guardian_set = AccountVariant::::try_deserialize(&mut guardian_set_data)?; let expected_address = Pubkey::find_program_address( &[ @@ -381,19 +379,22 @@ fn post_price_update_from_vaa<'info>( vaa_payload: &[u8], price_update: &MerklePriceUpdate, ) -> Result<()> { + let amount_to_pay = if treasury.lamports() == 0 { + Rent::get()? + .minimum_balance(0) + .max(config.single_update_fee_in_lamports) + } else { + config.single_update_fee_in_lamports + }; // First person to use the treasury account has to pay rent if payer.lamports() < Rent::get()? - .minimum_balance(0) - .saturating_add(config.single_update_fee_in_lamports) + .minimum_balance(payer.data_len()) + .saturating_add(amount_to_pay) { return err!(ReceiverError::InsufficientFunds); }; - let transfer_instruction = system_instruction::transfer( - payer.key, - treasury.key, - config.single_update_fee_in_lamports, - ); + let transfer_instruction = system_instruction::transfer(payer.key, treasury.key, amount_to_pay); anchor_lang::solana_program::program::invoke( &transfer_instruction, &[payer.to_account_info(), treasury.to_account_info()], diff --git a/target_chains/solana/programs/pyth-solana-receiver/tests/common/mod.rs b/target_chains/solana/programs/pyth-solana-receiver/tests/common/mod.rs index 9b6cddf2..64e1822d 100644 --- a/target_chains/solana/programs/pyth-solana-receiver/tests/common/mod.rs +++ b/target_chains/solana/programs/pyth-solana-receiver/tests/common/mod.rs @@ -8,8 +8,6 @@ use { get_config_address, get_guardian_set_address, get_treasury_address, - DEFAULT_TREASURY_ID, - SECONDARY_TREASURY_ID, }, ID, }, @@ -201,22 +199,6 @@ pub async fn setup_pyth_receiver( .unwrap(); assert_eq!(config_account, initial_config); - program_simulator - .airdrop( - &get_treasury_address(DEFAULT_TREASURY_ID), - Rent::default().minimum_balance(0), - ) - .await - .unwrap(); - - program_simulator - .airdrop( - &get_treasury_address(SECONDARY_TREASURY_ID), - Rent::default().minimum_balance(0), - ) - .await - .unwrap(); - ProgramTestFixtures { program_simulator, encoded_vaa_addresses, @@ -234,8 +216,5 @@ pub async fn assert_treasury_balance( .await .unwrap(); - assert_eq!( - treasury_balance, - expected_balance + Rent::default().minimum_balance(0) - ); + assert_eq!(treasury_balance, expected_balance); } diff --git a/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_price_update_from_vaa.rs b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_price_update_from_vaa.rs index 40bea6bb..63d7376e 100644 --- a/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_price_update_from_vaa.rs +++ b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_price_update_from_vaa.rs @@ -43,6 +43,7 @@ use { pubkey::Pubkey, }, solana_sdk::{ + rent::Rent, signature::Keypair, signer::Signer, }, @@ -332,7 +333,12 @@ async fn test_post_price_update_from_vaa() { .await .unwrap(); - assert_treasury_balance(&mut program_simulator, 1, DEFAULT_TREASURY_ID).await; + assert_treasury_balance( + &mut program_simulator, + Rent::default().minimum_balance(0), + DEFAULT_TREASURY_ID, + ) + .await; let mut price_update_account = program_simulator .get_anchor_account_data::(price_update_keypair.pubkey()) @@ -382,7 +388,12 @@ async fn test_post_price_update_from_vaa() { into_transaction_error(ReceiverError::InsufficientFunds) ); - assert_treasury_balance(&mut program_simulator, 1, DEFAULT_TREASURY_ID).await; + assert_treasury_balance( + &mut program_simulator, + Rent::default().minimum_balance(0), + DEFAULT_TREASURY_ID, + ) + .await; price_update_account = program_simulator .get_anchor_account_data::(price_update_keypair.pubkey()) @@ -432,7 +443,7 @@ async fn test_post_price_update_from_vaa() { assert_treasury_balance( &mut program_simulator, - LAMPORTS_PER_SOL + 1, + Rent::default().minimum_balance(0) + LAMPORTS_PER_SOL, DEFAULT_TREASURY_ID, ) .await; diff --git a/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates.rs b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates.rs index 2a708190..1c868bec 100644 --- a/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates.rs +++ b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates.rs @@ -32,6 +32,7 @@ use { }, solana_program::pubkey::Pubkey, solana_sdk::{ + rent::Rent, signature::Keypair, signer::Signer, }, @@ -78,7 +79,12 @@ async fn test_post_update() { .await .unwrap(); - assert_treasury_balance(&mut program_simulator, 1, DEFAULT_TREASURY_ID).await; + assert_treasury_balance( + &mut program_simulator, + Rent::default().minimum_balance(0), + DEFAULT_TREASURY_ID, + ) + .await; let mut price_update_account = program_simulator .get_anchor_account_data::(price_update_keypair.pubkey()) @@ -110,7 +116,12 @@ async fn test_post_update() { .await .unwrap(); - assert_treasury_balance(&mut program_simulator, 2, DEFAULT_TREASURY_ID).await; + assert_treasury_balance( + &mut program_simulator, + Rent::default().minimum_balance(0) + 1, + DEFAULT_TREASURY_ID, + ) + .await; price_update_account = program_simulator .get_anchor_account_data::(price_update_keypair.pubkey()) diff --git a/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates_atomic.rs b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates_atomic.rs index 444903e4..009cce53 100644 --- a/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates_atomic.rs +++ b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates_atomic.rs @@ -33,6 +33,7 @@ use { }, serde_wormhole::RawMessage, solana_sdk::{ + rent::Rent, signature::Keypair, signer::Signer, }, @@ -84,7 +85,12 @@ async fn test_post_update_atomic() { .await .unwrap(); - assert_treasury_balance(&mut program_simulator, 1, DEFAULT_TREASURY_ID).await; + assert_treasury_balance( + &mut program_simulator, + Rent::default().minimum_balance(0), + DEFAULT_TREASURY_ID, + ) + .await; let mut price_update_account = program_simulator .get_anchor_account_data::(price_update_keypair.pubkey()) @@ -119,7 +125,12 @@ async fn test_post_update_atomic() { .await .unwrap(); - assert_treasury_balance(&mut program_simulator, 2, DEFAULT_TREASURY_ID).await; + assert_treasury_balance( + &mut program_simulator, + Rent::default().minimum_balance(0) + 1, + DEFAULT_TREASURY_ID, + ) + .await; assert_treasury_balance(&mut program_simulator, 0, SECONDARY_TREASURY_ID).await; price_update_account = program_simulator @@ -155,8 +166,18 @@ async fn test_post_update_atomic() { .await .unwrap(); - assert_treasury_balance(&mut program_simulator, 2, DEFAULT_TREASURY_ID).await; - assert_treasury_balance(&mut program_simulator, 1, SECONDARY_TREASURY_ID).await; + assert_treasury_balance( + &mut program_simulator, + Rent::default().minimum_balance(0) + 1, + DEFAULT_TREASURY_ID, + ) + .await; + assert_treasury_balance( + &mut program_simulator, + Rent::default().minimum_balance(0), + SECONDARY_TREASURY_ID, + ) + .await; price_update_account = program_simulator .get_anchor_account_data::(price_update_keypair.pubkey())