gmsol_store/ops/
execution_fee.rs1use anchor_lang::prelude::*;
2use typed_builder::TypedBuilder;
3
4use crate::CoreError;
5
6#[derive(TypedBuilder)]
8pub(crate) struct TransferExecutionFeeOperation<'a, 'info> {
9 payment: AccountInfo<'info>,
10 payer: AccountInfo<'info>,
11 execution_lamports: u64,
12 system_program: AccountInfo<'info>,
13 #[builder(default)]
14 signer_seeds: Option<&'a [&'a [u8]]>,
15}
16
17impl TransferExecutionFeeOperation<'_, '_> {
18 pub(crate) fn execute(self) -> Result<()> {
19 use anchor_lang::system_program::{transfer, Transfer};
20
21 if self.execution_lamports != 0 {
22 let ctx = CpiContext::new(
23 self.system_program,
24 Transfer {
25 from: self.payer,
26 to: self.payment,
27 },
28 );
29 if let Some(seeds) = self.signer_seeds {
30 transfer(ctx.with_signer(&[seeds]), self.execution_lamports)?;
31 } else {
32 transfer(ctx, self.execution_lamports)?;
33 }
34 }
35
36 Ok(())
37 }
38}
39
40#[derive(TypedBuilder)]
42pub(crate) struct PayExecutionFeeOperation<'info> {
43 payer: AccountInfo<'info>,
44 receiver: AccountInfo<'info>,
45 execution_lamports: u64,
46}
47
48impl PayExecutionFeeOperation<'_> {
49 pub(crate) fn execute(self) -> Result<()> {
50 let rent = Rent::get()?;
51 let remaining_lamports = self
52 .payer
53 .lamports()
54 .saturating_sub(self.execution_lamports);
55 require_gte!(
56 remaining_lamports,
57 rent.minimum_balance(self.payer.data_len()),
58 CoreError::NotEnoughExecutionFee,
59 );
60
61 let amount = self.execution_lamports;
62 if amount != 0 {
63 msg!("paying execution fee: {}", amount);
64 self.payer.sub_lamports(amount)?;
65 self.receiver.add_lamports(amount)?;
66 }
67
68 Ok(())
69 }
70}