@@ -13,7 +13,22 @@ use super::validate_owner;
1313pub fn process_set_authority ( accounts : & [ AccountInfo ] , instruction_data : & [ u8 ] ) -> ProgramResult {
1414 // Validates the instruction data.
1515
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+ } ;
1732
1833 // Validates the accounts.
1934
@@ -30,11 +45,11 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
3045 return Err ( TokenError :: AccountFrozen . into ( ) ) ;
3146 }
3247
33- match args . authority_type ( ) ? {
48+ match authority_type {
3449 AuthorityType :: AccountOwner => {
3550 validate_owner ( & account. owner , authority_info, remaining) ?;
3651
37- if let Some ( authority) = args . new_authority ( ) {
52+ if let Some ( authority) = new_authority {
3853 account. owner = * authority;
3954 } else {
4055 return Err ( TokenError :: InvalidInstruction . into ( ) ) ;
@@ -51,7 +66,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
5166 let authority = account. close_authority ( ) . unwrap_or ( & account. owner ) ;
5267 validate_owner ( authority, authority_info, remaining) ?;
5368
54- if let Some ( authority) = args . new_authority ( ) {
69+ if let Some ( authority) = new_authority {
5570 account. set_close_authority ( authority) ;
5671 } else {
5772 account. clear_close_authority ( ) ;
@@ -66,15 +81,15 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
6681 // `load_mut` validates that the mint is initialized.
6782 let mint = unsafe { load_mut :: < Mint > ( account_info. borrow_mut_data_unchecked ( ) ) ? } ;
6883
69- match args . authority_type ( ) ? {
84+ match authority_type {
7085 AuthorityType :: MintTokens => {
7186 // Once a mint's supply is fixed, it cannot be undone by setting a new
7287 // mint_authority.
7388 let mint_authority = mint. mint_authority ( ) . ok_or ( TokenError :: FixedSupply ) ?;
7489
7590 validate_owner ( mint_authority, authority_info, remaining) ?;
7691
77- if let Some ( authority) = args . new_authority ( ) {
92+ if let Some ( authority) = new_authority {
7893 mint. set_mint_authority ( authority) ;
7994 } else {
8095 mint. clear_mint_authority ( ) ;
@@ -89,7 +104,7 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
89104
90105 validate_owner ( freeze_authority, authority_info, remaining) ?;
91106
92- if let Some ( authority) = args . new_authority ( ) {
107+ if let Some ( authority) = new_authority {
93108 mint. set_freeze_authority ( authority) ;
94109 } else {
95110 mint. clear_freeze_authority ( ) ;
@@ -105,40 +120,3 @@ pub fn process_set_authority(accounts: &[AccountInfo], instruction_data: &[u8])
105120
106121 Ok ( ( ) )
107122}
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