@@ -13,7 +13,22 @@ use super::validate_owner;
13
13
pub fn process_set_authority ( accounts : & [ AccountInfo ] , instruction_data : & [ u8 ] ) -> ProgramResult {
14
14
// Validates the instruction data.
15
15
16
- let args = SetAuthority :: try_from_bytes ( instruction_data) ?;
16
+ // SAFETY: The expected size of the instruction data is either 2 or 34 bytes:
17
+ // - authority_type (1 byte)
18
+ // - option + new_authority (1 byte + 32 bytes)
19
+ let ( authority_type, new_authority) = unsafe {
20
+ match instruction_data. len ( ) {
21
+ 2 if * instruction_data. get_unchecked ( 1 ) == 0 => (
22
+ AuthorityType :: try_from ( * instruction_data. get_unchecked ( 0 ) ) ?,
23
+ None ,
24
+ ) ,
25
+ 34 if * instruction_data. get_unchecked ( 1 ) == 1 => (
26
+ AuthorityType :: try_from ( * instruction_data. get_unchecked ( 0 ) ) ?,
27
+ Some ( & * ( instruction_data. as_ptr ( ) . add ( 2 ) as * const Pubkey ) ) ,
28
+ ) ,
29
+ _ => return Err ( ProgramError :: InvalidInstructionData ) ,
30
+ }
31
+ } ;
17
32
18
33
// Validates the accounts.
19
34
@@ -30,11 +45,11 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
30
45
return Err ( TokenError :: AccountFrozen . into ( ) ) ;
31
46
}
32
47
33
- match args . authority_type ( ) ? {
48
+ match authority_type {
34
49
AuthorityType :: AccountOwner => {
35
50
validate_owner ( & account. owner , authority_info, remaining) ?;
36
51
37
- if let Some ( authority) = args . new_authority ( ) {
52
+ if let Some ( authority) = new_authority {
38
53
account. owner = * authority;
39
54
} else {
40
55
return Err ( TokenError :: InvalidInstruction . into ( ) ) ;
@@ -51,7 +66,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
51
66
let authority = account. close_authority ( ) . unwrap_or ( & account. owner ) ;
52
67
validate_owner ( authority, authority_info, remaining) ?;
53
68
54
- if let Some ( authority) = args . new_authority ( ) {
69
+ if let Some ( authority) = new_authority {
55
70
account. set_close_authority ( authority) ;
56
71
} else {
57
72
account. clear_close_authority ( ) ;
@@ -66,15 +81,15 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
66
81
// `load_mut` validates that the mint is initialized.
67
82
let mint = unsafe { load_mut :: < Mint > ( account_info. borrow_mut_data_unchecked ( ) ) ? } ;
68
83
69
- match args . authority_type ( ) ? {
84
+ match authority_type {
70
85
AuthorityType :: MintTokens => {
71
86
// Once a mint's supply is fixed, it cannot be undone by setting a new
72
87
// mint_authority.
73
88
let mint_authority = mint. mint_authority ( ) . ok_or ( TokenError :: FixedSupply ) ?;
74
89
75
90
validate_owner ( mint_authority, authority_info, remaining) ?;
76
91
77
- if let Some ( authority) = args . new_authority ( ) {
92
+ if let Some ( authority) = new_authority {
78
93
mint. set_mint_authority ( authority) ;
79
94
} else {
80
95
mint. clear_mint_authority ( ) ;
@@ -89,7 +104,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
89
104
90
105
validate_owner ( freeze_authority, authority_info, remaining) ?;
91
106
92
- if let Some ( authority) = args . new_authority ( ) {
107
+ if let Some ( authority) = new_authority {
93
108
mint. set_freeze_authority ( authority) ;
94
109
} else {
95
110
mint. clear_freeze_authority ( ) ;
@@ -105,40 +120,3 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
105
120
106
121
Ok ( ( ) )
107
122
}
108
-
109
- #[ repr( C ) ]
110
- struct SetAuthority {
111
- authority_type : u8 ,
112
-
113
- new_authority : ( u8 , Pubkey ) ,
114
- }
115
-
116
- impl SetAuthority {
117
- #[ inline]
118
- pub fn try_from_bytes ( bytes : & [ u8 ] ) -> Result < & SetAuthority , ProgramError > {
119
- // The minimum expected size of the instruction data is either 2 or 34 bytes:
120
- // - authority_type (1 byte)
121
- // - option + new_authority (1 byte + 32 bytes)
122
- unsafe {
123
- match bytes. len ( ) {
124
- 2 if * bytes. get_unchecked ( 1 ) == 0 => Ok ( & * ( bytes. as_ptr ( ) as * const SetAuthority ) ) ,
125
- 34 => Ok ( & * ( bytes. as_ptr ( ) as * const SetAuthority ) ) ,
126
- _ => Err ( ProgramError :: InvalidInstructionData ) ,
127
- }
128
- }
129
- }
130
-
131
- #[ inline]
132
- pub fn authority_type ( & self ) -> Result < AuthorityType , ProgramError > {
133
- self . authority_type . try_into ( )
134
- }
135
-
136
- #[ inline]
137
- pub fn new_authority ( & self ) -> Option < & Pubkey > {
138
- if self . new_authority . 0 == 0 {
139
- Option :: None
140
- } else {
141
- Option :: Some ( & self . new_authority . 1 )
142
- }
143
- }
144
- }
0 commit comments