@@ -4,11 +4,9 @@ use std::convert::From;
44use anchor_lang:: prelude:: * ;
55use anchor_lang:: solana_program:: instruction:: Instruction ;
66use anchor_lang:: solana_program:: program:: invoke_signed;
7- use anchor_lang:: Discriminator ;
87use solana_address_lookup_table_program:: state:: AddressLookupTable ;
98
109use crate :: errors:: * ;
11- use crate :: id;
1210use crate :: state:: * ;
1311
1412/// Sanitized and validated combination of a `MsTransactionMessage` and `AccountInfo`s it references.
@@ -171,21 +169,23 @@ impl<'a, 'info> ExecutableTransactionMessage<'a, 'info> {
171169 } )
172170 }
173171
172+ /// Executes all instructions in the message via CPI calls.
173+ /// # Arguments
174+ /// * `vault_seeds` - Seeds for the vault PDA.
175+ /// * `ephemeral_signer_seeds` - Seeds for the ephemeral signer PDAs.
176+ /// * `protected_accounts` - Accounts that must not be passed as writable to the CPI calls to prevent potential reentrancy attacks.
174177 pub fn execute_message (
175178 & self ,
176179 vault_seeds : & [ Vec < u8 > ] ,
177180 ephemeral_signer_seeds : & [ Vec < Vec < u8 > > ] ,
181+ protected_accounts : & [ Pubkey ] ,
178182 ) -> Result < ( ) > {
179183 for ( ix, account_infos) in self . to_instructions_and_accounts ( ) . iter ( ) {
180- // Make sure we don't allow reentrancy of transaction_execute.
181- if ix. program_id == id ( ) {
182- require ! (
183- ix. data[ ..8 ] != crate :: instruction:: VaultTransactionExecute :: DISCRIMINATOR ,
184- MultisigError :: ExecuteReentrancy
185- ) ;
184+ // Make sure we don't pass protected accounts as writable to CPI calls.
185+ for account_meta in ix. accounts . iter ( ) . filter ( |m| m. is_writable ) {
186186 require ! (
187- ix . data [ .. 8 ] != crate :: instruction :: BatchExecuteTransaction :: DISCRIMINATOR ,
188- MultisigError :: ExecuteReentrancy
187+ !protected_accounts . contains ( & account_meta . pubkey ) ,
188+ MultisigError :: ProtectedAccount
189189 ) ;
190190 }
191191
0 commit comments