@@ -3,7 +3,7 @@ use pinocchio::{
33} ;
44use token_interface:: {
55 error:: TokenError ,
6- state:: { account:: Account , load_mut } ,
6+ state:: { account:: Account , load } ,
77} ;
88
99use super :: validate_owner;
@@ -24,26 +24,30 @@ pub fn process_close_account(accounts: &[AccountInfo]) -> ProgramResult {
2424 // raw pointer.
2525 if source_account_info == destination_account_info {
2626 return Err ( ProgramError :: InvalidAccountData ) ;
27- }
28-
29- let source_account =
30- unsafe { load_mut :: < Account > ( source_account_info. borrow_mut_data_unchecked ( ) ) ? } ;
31-
32- if !source_account. is_native ( ) && source_account. amount ( ) != 0 {
33- return Err ( TokenError :: NonNativeHasBalance . into ( ) ) ;
34- }
35-
36- let authority = source_account
37- . close_authority ( )
38- . unwrap_or ( & source_account. owner ) ;
39-
40- if !source_account. is_owned_by_system_program_or_incinerator ( ) {
41- validate_owner ( authority, authority_info, remaining) ?;
42- } else if destination_account_info. key ( ) != & INCINERATOR_ID {
43- return Err ( ProgramError :: InvalidAccountData ) ;
27+ } else {
28+ // SAFETY: scoped immutable borrow to `source_account_info` account data and
29+ // `load` validates that the account is initialized.
30+ let source_account =
31+ unsafe { load :: < Account > ( source_account_info. borrow_data_unchecked ( ) ) ? } ;
32+
33+ if !source_account. is_native ( ) && source_account. amount ( ) != 0 {
34+ return Err ( TokenError :: NonNativeHasBalance . into ( ) ) ;
35+ }
36+
37+ let authority = source_account
38+ . close_authority ( )
39+ . unwrap_or ( & source_account. owner ) ;
40+
41+ if !source_account. is_owned_by_system_program_or_incinerator ( ) {
42+ validate_owner ( authority, authority_info, remaining) ?;
43+ } else if destination_account_info. key ( ) != & INCINERATOR_ID {
44+ return Err ( ProgramError :: InvalidAccountData ) ;
45+ }
4446 }
4547
4648 let destination_starting_lamports = destination_account_info. lamports ( ) ;
49+ // SAFETY: single mutable borrow to `destination_account_info` lamports and
50+ // there are no "active" borrows of `source_account_info` account data.
4751 unsafe {
4852 // Moves the lamports to the destination account.
4953 * destination_account_info. borrow_mut_lamports_unchecked ( ) = destination_starting_lamports
0 commit comments