@@ -7,7 +7,7 @@ use crate::{
77 constants:: DISCRIMINATOR_SIZE ,
88 error:: CustomError ,
99 event:: ExecutedRelayerRefundRoot ,
10- state:: { ExecuteRelayerRefundLeafParams , RootBundle , State , TransferLiability } ,
10+ state:: { ExecuteRelayerRefundLeafParams , RefundAccount , RootBundle , State , TransferLiability } ,
1111 utils:: { is_claimed, set_claimed, verify_merkle_proof} ,
1212} ;
1313
@@ -104,9 +104,12 @@ impl RelayerRefundLeaf {
104104 }
105105}
106106
107- pub fn execute_relayer_refund_leaf < ' info > (
108- ctx : Context < ' _ , ' _ , ' _ , ' info , ExecuteRelayerRefundLeaf < ' info > > ,
109- ) -> Result < ( ) > {
107+ pub fn execute_relayer_refund_leaf < ' c , ' info > (
108+ ctx : Context < ' _ , ' _ , ' c , ' info , ExecuteRelayerRefundLeaf < ' info > > ,
109+ ) -> Result < ( ) >
110+ where
111+ ' c : ' info ,
112+ {
110113 // Get pre-loaded instruction parameters.
111114 let instruction_params = & ctx. accounts . instruction_params ;
112115 let root_bundle_id = instruction_params. root_bundle_id ;
@@ -148,30 +151,48 @@ pub fn execute_relayer_refund_leaf<'info>(
148151 let seeds = & [ b"state" , state_seed_bytes. as_ref ( ) , & [ ctx. bumps . state ] ] ;
149152 let signer_seeds = & [ & seeds[ ..] ] ;
150153
154+ // Will include in the emitted event at the end if there are any claim accounts.
155+ let mut deferred_refunds = false ;
156+
151157 for ( i, amount) in relayer_refund_leaf. refund_amounts . iter ( ) . enumerate ( ) {
152- let refund_account = relayer_refund_leaf. refund_accounts [ i] ;
153158 let amount = * amount as u64 ;
154159
155- // TODO: we might be able to just use the refund_account and improve this block but it's not clear yet if that's possible.
156- let refund_account_info = ctx
157- . remaining_accounts
158- . iter ( )
159- . find ( |account| account. key == & refund_account)
160- . cloned ( )
161- . ok_or ( CustomError :: AccountNotFound ) ?;
162-
163- let transfer_accounts = TransferChecked {
164- from : ctx. accounts . vault . to_account_info ( ) ,
165- mint : ctx. accounts . mint . to_account_info ( ) ,
166- to : refund_account_info. to_account_info ( ) ,
167- authority : ctx. accounts . state . to_account_info ( ) ,
168- } ;
169- let cpi_context = CpiContext :: new_with_signer (
170- ctx. accounts . token_program . to_account_info ( ) ,
171- transfer_accounts,
172- signer_seeds,
173- ) ;
174- transfer_checked ( cpi_context, amount, ctx. accounts . mint . decimals ) ?;
160+ // Refund account holds either a regular token account or a claim account. This checks all required constraints.
161+ let refund_account = RefundAccount :: try_from_remaining_account (
162+ ctx. remaining_accounts ,
163+ i,
164+ & relayer_refund_leaf. refund_accounts [ i] ,
165+ & ctx. accounts . mint . key ( ) ,
166+ & ctx. accounts . token_program . key ( ) ,
167+ ) ?;
168+
169+ match refund_account {
170+ // Valid token account was passed, transfer the refund atomically.
171+ RefundAccount :: TokenAccount ( token_account) => {
172+ let transfer_accounts = TransferChecked {
173+ from : ctx. accounts . vault . to_account_info ( ) ,
174+ mint : ctx. accounts . mint . to_account_info ( ) ,
175+ to : token_account. to_account_info ( ) ,
176+ authority : ctx. accounts . state . to_account_info ( ) ,
177+ } ;
178+ let cpi_context = CpiContext :: new_with_signer (
179+ ctx. accounts . token_program . to_account_info ( ) ,
180+ transfer_accounts,
181+ signer_seeds,
182+ ) ;
183+ transfer_checked ( cpi_context, amount, ctx. accounts . mint . decimals ) ?;
184+ }
185+ // Valid claim account was passed, increment the claim account amount.
186+ RefundAccount :: ClaimAccount ( mut claim_account) => {
187+ claim_account. amount += amount;
188+
189+ // Indicate in the event at the end that some refunds have been deferred.
190+ deferred_refunds = true ;
191+
192+ // Persist the updated claim account (Anchor handles this only for static accounts).
193+ claim_account. exit ( ctx. program_id ) ?;
194+ }
195+ }
175196 }
176197
177198 if relayer_refund_leaf. amount_to_return > 0 {
@@ -187,6 +208,7 @@ pub fn execute_relayer_refund_leaf<'info>(
187208 leaf_id: relayer_refund_leaf. leaf_id,
188209 l2_token_address: ctx. accounts. mint. key( ) ,
189210 refund_addresses: relayer_refund_leaf. refund_accounts,
211+ deferred_refunds,
190212 caller: ctx. accounts. signer. key( ) ,
191213 } ) ;
192214
0 commit comments