@@ -3,14 +3,16 @@ use pinocchio::{
3
3
} ;
4
4
use token_interface:: {
5
5
error:: TokenError ,
6
- state:: { account:: Account , load_mut } ,
6
+ state:: { account:: Account , load } ,
7
7
} ;
8
8
9
9
use super :: validate_owner;
10
10
11
- /// Incinerator address.
12
- const INCINERATOR_ID : Pubkey =
13
- pinocchio_pubkey:: pubkey!( "1nc1nerator11111111111111111111111111111111" ) ;
11
+ /// Incinerator (`1nc1nerator11111111111111111111111111111111`) address.
12
+ const INCINERATOR_ID : Pubkey = [
13
+ 0 , 51 , 144 , 114 , 141 , 52 , 17 , 96 , 121 , 189 , 201 , 17 , 191 , 255 , 0 , 219 , 212 , 77 , 46 , 205 , 204 ,
14
+ 247 , 156 , 166 , 225 , 0 , 56 , 225 , 0 , 0 , 0 , 0 ,
15
+ ] ;
14
16
15
17
#[ inline( always) ]
16
18
pub fn process_close_account ( accounts : & [ AccountInfo ] ) -> ProgramResult {
@@ -24,26 +26,30 @@ pub fn process_close_account(accounts: &[AccountInfo]) -> ProgramResult {
24
26
// raw pointer.
25
27
if source_account_info == destination_account_info {
26
28
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 ) ;
29
+ } else {
30
+ // SAFETY: scoped immutable borrow to `source_account_info` account data and
31
+ // `load` validates that the account is initialized.
32
+ let source_account =
33
+ unsafe { load :: < Account > ( source_account_info. borrow_data_unchecked ( ) ) ? } ;
34
+
35
+ if !source_account. is_native ( ) && source_account. amount ( ) != 0 {
36
+ return Err ( TokenError :: NonNativeHasBalance . into ( ) ) ;
37
+ }
38
+
39
+ let authority = source_account
40
+ . close_authority ( )
41
+ . unwrap_or ( & source_account. owner ) ;
42
+
43
+ if !source_account. is_owned_by_system_program_or_incinerator ( ) {
44
+ validate_owner ( authority, authority_info, remaining) ?;
45
+ } else if destination_account_info. key ( ) != & INCINERATOR_ID {
46
+ return Err ( ProgramError :: InvalidAccountData ) ;
47
+ }
44
48
}
45
49
46
50
let destination_starting_lamports = destination_account_info. lamports ( ) ;
51
+ // SAFETY: single mutable borrow to `destination_account_info` lamports and
52
+ // there are no "active" borrows of `source_account_info` account data.
47
53
unsafe {
48
54
// Moves the lamports to the destination account.
49
55
* destination_account_info. borrow_mut_lamports_unchecked ( ) = destination_starting_lamports
0 commit comments