@@ -11,10 +11,10 @@ use anchor_spl::{
1111 } ,
1212 token_interface:: { transfer_checked, Mint , TokenAccount , TransferChecked } ,
1313} ;
14+ use spl_discriminator:: SplDiscriminate ;
1415use spl_tlv_account_resolution:: {
1516 account:: ExtraAccountMeta , seeds:: Seed , state:: ExtraAccountMetaList ,
1617} ;
17- use spl_discriminator:: SplDiscriminate ;
1818use spl_transfer_hook_interface:: instruction:: {
1919 ExecuteInstruction , InitializeExtraAccountMetaListInstruction ,
2020} ;
@@ -25,12 +25,6 @@ use std::{cell::RefMut, str::FromStr};
2525
2626declare_id ! ( "FjcHckEgXcBhFmSGai3FRpDLiT6hbpV893n8iTxVd81g" ) ;
2727
28- /// Convert anchor-lang's Pubkey (solana-pubkey 3.x) to the spl crate's Pubkey (solana-pubkey 2.x).
29- /// Both are #[repr(transparent)] over [u8; 32], so byte-level conversion is safe.
30- fn transmute_pubkey ( key : & Pubkey ) -> spl_tlv_account_resolution:: solana_pubkey:: Pubkey {
31- spl_tlv_account_resolution:: solana_pubkey:: Pubkey :: from ( key. to_bytes ( ) )
32- }
33-
3428#[ error_code]
3529pub enum TransferError {
3630 #[ msg( "Amount Too big" ) ]
@@ -50,12 +44,11 @@ pub mod transfer_hook {
5044 let extra_account_metas = InitializeExtraAccountMetaList :: extra_account_metas ( ) ?;
5145
5246 // initialize ExtraAccountMetaList account with extra accounts
53- // .map_err() needed because spl-tlv-account-resolution uses solana-program-error 2.x
54- // while anchor-lang 1.0 uses 3.x — structurally identical but different semver types
5547 ExtraAccountMetaList :: init :: < ExecuteInstruction > (
5648 & mut ctx. accounts . extra_account_meta_list . try_borrow_mut_data ( ) ?,
5749 & extra_account_metas,
58- ) . map_err ( |_| ProgramError :: InvalidAccountData ) ?;
50+ )
51+ . map_err ( |_| ProgramError :: InvalidAccountData ) ?;
5952
6053 Ok ( ( ) )
6154 }
@@ -67,7 +60,6 @@ pub mod transfer_hook {
6760
6861 if amount > 50 {
6962 msg ! ( "The amount is too big {0}" , amount) ;
70- //return err!(TransferError::AmountTooBig);
7163 }
7264
7365 ctx. accounts . counter_account . counter += 1 ;
@@ -77,7 +69,6 @@ pub mod transfer_hook {
7769 ctx. accounts. counter_account. counter
7870 ) ;
7971
80- // All accounts are non writable so you can not burn any of them for example here
8172 msg ! (
8273 "Is writable mint {0}" ,
8374 ctx. accounts. mint. to_account_info( ) . is_writable
@@ -116,11 +107,10 @@ pub mod transfer_hook {
116107fn check_is_transferring ( ctx : & Context < TransferHook > ) -> Result < ( ) > {
117108 let source_token_info = ctx. accounts . source_token . to_account_info ( ) ;
118109 let mut account_data_ref: RefMut < & mut [ u8 ] > = source_token_info. try_borrow_mut_data ( ) ?;
119- // .map_err() needed because spl-token-2022 uses solana-program-error 2.x
120- // while anchor-lang 1.0 uses 3.x — structurally identical but different semver types
121110 let mut account = PodStateWithExtensionsMut :: < PodAccount > :: unpack ( * account_data_ref)
122111 . map_err ( |_| ProgramError :: InvalidAccountData ) ?;
123- let account_extension = account. get_extension_mut :: < TransferHookAccount > ( )
112+ let account_extension = account
113+ . get_extension_mut :: < TransferHookAccount > ( )
124114 . map_err ( |_| ProgramError :: InvalidAccountData ) ?;
125115
126116 if !bool:: from ( account_extension. transferring ) {
@@ -162,15 +152,9 @@ impl<'info> InitializeExtraAccountMetaList<'info> {
162152 // index 0-3 are the accounts required for token transfer (source, mint, destination, owner)
163153 // index 4 is address of ExtraAccountMetaList account
164154
165- // .map_err() needed because spl-tlv-account-resolution uses solana-program-error 2.x
166- // while anchor-lang 1.0 uses 3.x — structurally identical but different semver types.
167- // Pubkey types also differ (solana-pubkey 2.x vs 3.x), so we convert via bytes using
168- // transmute_pubkey() — both are #[repr(transparent)] over [u8; 32].
169- let wsol_mint = transmute_pubkey (
170- & Pubkey :: from_str ( "So11111111111111111111111111111111111111112" ) . unwrap ( )
171- ) ;
172- let token_program_id = transmute_pubkey ( & Token :: id ( ) ) ;
173- let ata_program_id = transmute_pubkey ( & AssociatedToken :: id ( ) ) ;
155+ let wsol_mint = Pubkey :: from_str ( "So11111111111111111111111111111111111111112" ) . unwrap ( ) ;
156+ let token_program_id = Token :: id ( ) ;
157+ let ata_program_id = AssociatedToken :: id ( ) ;
174158
175159 Ok ( vec ! [
176160 // index 5, wrapped SOL mint
@@ -189,7 +173,8 @@ impl<'info> InitializeExtraAccountMetaList<'info> {
189173 } ] ,
190174 false , // is_signer
191175 true , // is_writable
192- ) . map_err( |_| ProgramError :: InvalidArgument ) ?,
176+ )
177+ . map_err( |_| ProgramError :: InvalidArgument ) ?,
193178 // index 9, delegate wrapped SOL token account
194179 ExtraAccountMeta :: new_external_pda_with_seeds(
195180 7 , // associated token program index
@@ -200,7 +185,8 @@ impl<'info> InitializeExtraAccountMetaList<'info> {
200185 ] ,
201186 false , // is_signer
202187 true , // is_writable
203- ) . map_err( |_| ProgramError :: InvalidArgument ) ?,
188+ )
189+ . map_err( |_| ProgramError :: InvalidArgument ) ?,
204190 // index 10, sender wrapped SOL token account
205191 ExtraAccountMeta :: new_external_pda_with_seeds(
206192 7 , // associated token program index
@@ -211,14 +197,16 @@ impl<'info> InitializeExtraAccountMetaList<'info> {
211197 ] ,
212198 false , // is_signer
213199 true , // is_writable
214- ) . map_err( |_| ProgramError :: InvalidArgument ) ?,
200+ )
201+ . map_err( |_| ProgramError :: InvalidArgument ) ?,
215202 ExtraAccountMeta :: new_with_seeds(
216203 & [ Seed :: Literal {
217204 bytes: b"counter" . to_vec( ) ,
218205 } ] ,
219206 false , // is_signer
220207 true , // is_writable
221- ) . map_err( |_| ProgramError :: InvalidArgument ) ?,
208+ )
209+ . map_err( |_| ProgramError :: InvalidArgument ) ?,
222210 ] )
223211 }
224212
@@ -232,19 +220,24 @@ impl<'info> InitializeExtraAccountMetaList<'info> {
232220// The first 4 accounts are the accounts required for token transfer (source, mint, destination, owner)
233221// Remaining accounts are the extra accounts required from the ExtraAccountMetaList account
234222// These accounts are provided via CPI to this program from the token2022 program
223+ //
224+ // Box<InterfaceAccount> used for source_token, destination_token, wsol_mint,
225+ // delegate_wsol_token_account, and sender_wsol_token_account to avoid exceeding
226+ // the 4096-byte BPF stack frame limit in try_accounts deserialization.
227+ // This struct has 12 accounts — without Box, the generated code uses ~4160 bytes of stack.
235228#[ derive( Accounts ) ]
236229pub struct TransferHook < ' info > {
237230 #[ account( token:: mint = mint, token:: authority = owner) ]
238- pub source_token : InterfaceAccount < ' info , TokenAccount > ,
239- pub mint : InterfaceAccount < ' info , Mint > ,
231+ pub source_token : Box < InterfaceAccount < ' info , TokenAccount > > ,
232+ pub mint : Box < InterfaceAccount < ' info , Mint > > ,
240233 #[ account( token:: mint = mint) ]
241- pub destination_token : InterfaceAccount < ' info , TokenAccount > ,
234+ pub destination_token : Box < InterfaceAccount < ' info , TokenAccount > > ,
242235 /// CHECK: source token account owner, can be SystemAccount or PDA owned by another program
243236 pub owner : UncheckedAccount < ' info > ,
244237 /// CHECK: ExtraAccountMetaList Account,
245238 #[ account( seeds = [ b"extra-account-metas" , mint. key( ) . as_ref( ) ] , bump) ]
246239 pub extra_account_meta_list : UncheckedAccount < ' info > ,
247- pub wsol_mint : InterfaceAccount < ' info , Mint > ,
240+ pub wsol_mint : Box < InterfaceAccount < ' info , Mint > > ,
248241 pub token_program : Program < ' info , Token > ,
249242 pub associated_token_program : Program < ' info , AssociatedToken > ,
250243 #[ account(
@@ -258,13 +251,13 @@ pub struct TransferHook<'info> {
258251 token:: mint = wsol_mint,
259252 token:: authority = delegate,
260253 ) ]
261- pub delegate_wsol_token_account : InterfaceAccount < ' info , TokenAccount > ,
254+ pub delegate_wsol_token_account : Box < InterfaceAccount < ' info , TokenAccount > > ,
262255 #[ account(
263256 mut ,
264257 token:: mint = wsol_mint,
265258 token:: authority = owner,
266259 ) ]
267- pub sender_wsol_token_account : InterfaceAccount < ' info , TokenAccount > ,
260+ pub sender_wsol_token_account : Box < InterfaceAccount < ' info , TokenAccount > > ,
268261 #[ account( seeds = [ b"counter" ] , bump) ]
269262 pub counter_account : Account < ' info , CounterAccount > ,
270263}
0 commit comments