11use anchor_compressed_token:: ErrorCode ;
22use anchor_lang:: prelude:: ProgramError ;
3+ use arrayvec:: ArrayVec ;
34use light_account_checks:: packed_accounts:: ProgramPackedAccounts ;
45use light_compressed_account:: instruction_data:: data:: ZOutputCompressedAccountWithPackedContextMut ;
56use light_ctoken_types:: {
@@ -9,16 +10,23 @@ use light_ctoken_types::{
910} ;
1011use light_program_profiler:: profile;
1112use pinocchio:: account_info:: AccountInfo ;
13+ use spl_pod:: solana_msg:: msg;
1214
13- use crate :: mint_action:: {
14- accounts:: MintActionAccounts ,
15- check_authority,
16- mint_to:: process_mint_to_compressed_action,
17- mint_to_ctoken:: process_mint_to_ctoken_action,
18- queue_indices:: QueueIndices ,
19- update_metadata:: {
20- process_remove_metadata_key_action, process_update_metadata_authority_action,
21- process_update_metadata_field_action,
15+ use crate :: {
16+ mint_action:: {
17+ accounts:: MintActionAccounts ,
18+ check_authority,
19+ mint_to:: process_mint_to_compressed_action,
20+ mint_to_ctoken:: process_mint_to_ctoken_action,
21+ queue_indices:: QueueIndices ,
22+ update_metadata:: {
23+ process_remove_metadata_key_action, process_update_metadata_authority_action,
24+ process_update_metadata_field_action,
25+ } ,
26+ } ,
27+ shared:: {
28+ convert_program_error,
29+ transfer_lamports:: { multi_transfer_lamports, Transfer } ,
2230 } ,
2331} ;
2432
@@ -35,6 +43,9 @@ pub fn process_actions<'a>(
3543 packed_accounts : & ProgramPackedAccounts < ' _ , AccountInfo > ,
3644 compressed_mint : & mut CompressedMint ,
3745) -> Result < ( ) , ProgramError > {
46+ // Array to accumulate transfer amounts by account index (max 40 packed accounts)
47+ let mut transfer_map = [ 0u64 ; 40 ] ;
48+
3849 // Start metadata authority with same value as mint authority
3950 for action in parsed_instruction_data. actions . iter ( ) {
4051 match action {
@@ -80,13 +91,27 @@ pub fn process_actions<'a>(
8091 // compressed_mint.metadata.spl_mint_initialized = true;
8192 }
8293 ZAction :: MintToCToken ( mint_to_ctoken_action) => {
83- process_mint_to_ctoken_action (
94+ let transfer = process_mint_to_ctoken_action (
8495 mint_to_ctoken_action,
8596 compressed_mint,
8697 validated_accounts,
8798 packed_accounts,
8899 parsed_instruction_data. mint . metadata . mint ,
89100 ) ?;
101+
102+ // Accumulate transfer amount if present (deduplication happens here)
103+ if let Some ( ( account_index, amount) ) = transfer {
104+ if account_index as usize > 40 {
105+ msg ! (
106+ "Too many compression transfers: {}, max 40 allowed" ,
107+ account_index
108+ ) ;
109+ return Err ( ErrorCode :: TooManyCompressionTransfers . into ( ) ) ;
110+ }
111+ transfer_map[ account_index as usize ] = transfer_map[ account_index as usize ]
112+ . checked_add ( amount)
113+ . ok_or ( ProgramError :: ArithmeticOverflow ) ?;
114+ }
90115 }
91116 ZAction :: UpdateMetadataField ( update_metadata_action) => {
92117 process_update_metadata_field_action (
@@ -112,5 +137,37 @@ pub fn process_actions<'a>(
112137 }
113138 }
114139
140+ // Build transfers array from deduplicated map
141+ let transfers: ArrayVec < Transfer , 40 > = transfer_map
142+ . iter ( )
143+ . enumerate ( )
144+ . filter_map ( |( index, & amount) | {
145+ if amount != 0 {
146+ Some ( ( index as u8 , amount) )
147+ } else {
148+ None
149+ }
150+ } )
151+ . map ( |( index, amount) | {
152+ Ok ( Transfer {
153+ account : packed_accounts. get_u8 ( index, "transfer account" ) ?,
154+ amount,
155+ } )
156+ } )
157+ . collect :: < Result < ArrayVec < Transfer , 40 > , ProgramError > > ( ) ?;
158+
159+ // Execute transfers if any exist
160+ if !transfers. is_empty ( ) {
161+ let fee_payer = validated_accounts
162+ . executing
163+ . as_ref ( )
164+ . and_then ( |exec| Some ( exec. system . fee_payer ) )
165+ . ok_or_else ( || {
166+ msg ! ( "Fee payer required for compressible token account top-ups" ) ;
167+ ProgramError :: NotEnoughAccountKeys
168+ } ) ?;
169+ multi_transfer_lamports ( fee_payer, & transfers) . map_err ( convert_program_error) ?;
170+ }
171+
115172 Ok ( ( ) )
116173}
0 commit comments