continuation_router/action/
stable_swap.rs

1//! Step implementations for StableSwap.
2
3use std::ops::Deref;
4
5use crate::action::ProcessAction;
6use crate::*;
7
8macro_rules! build_swap_context {
9    ($component:expr, $ctx:expr $(,)?) => {{
10        stable_swap_anchor::SwapUserContext {
11            token_program: $ctx.token_program.to_account_info(),
12            user_authority: $ctx.owner.clone(),
13            swap: $component.swap.swap.clone(),
14            swap_authority: $component.swap.swap_authority.clone(),
15        }
16    }};
17}
18
19impl<'info> Deref for SSDepositA<'info> {
20    type Target = SSDeposit<'info>;
21    fn deref(&self) -> &Self::Target {
22        &self.inner
23    }
24}
25
26impl<'info> Deref for SSDepositB<'info> {
27    type Target = SSDeposit<'info>;
28    fn deref(&self) -> &Self::Target {
29        &self.inner
30    }
31}
32
33impl<'info> ProcessAction<'info> for SSDepositA<'info> {
34    /// Runs the deposit component instruction.
35    fn process(
36        ctx: &ActionContext<'_, '_, '_, 'info, Self>,
37        amount_in: u64,
38        minimum_amount_out: u64,
39    ) -> Result<()> {
40        let deposit = ctx.action;
41        let cpi_accounts = stable_swap_anchor::Deposit {
42            user: build_swap_context!(deposit, ctx),
43            input_a: (&deposit.input_a).into(),
44            input_b: (&deposit.input_b).into(),
45            output_lp: deposit.output_lp.to_account_info(),
46            pool_mint: deposit.pool_mint.clone(),
47        };
48        let cpi_ctx = CpiContext::new(ctx.swap_program.clone(), cpi_accounts);
49        stable_swap_anchor::deposit(cpi_ctx, amount_in, 0, minimum_amount_out)
50    }
51
52    fn input_account(&self) -> &Account<'info, TokenAccount> {
53        &self.input_a.user
54    }
55
56    fn output_account(&self) -> &Account<'info, TokenAccount> {
57        &self.output_lp
58    }
59}
60
61impl<'info> ProcessAction<'info> for SSDepositB<'info> {
62    /// Runs the deposit component instruction.
63    fn process(
64        ctx: &ActionContext<'_, '_, '_, 'info, Self>,
65        amount_in: u64,
66        minimum_amount_out: u64,
67    ) -> Result<()> {
68        let deposit = ctx.action;
69        let cpi_accounts = stable_swap_anchor::Deposit {
70            user: build_swap_context!(deposit, ctx),
71            input_a: (&deposit.input_a).into(),
72            input_b: (&deposit.input_b).into(),
73            output_lp: deposit.output_lp.to_account_info(),
74            pool_mint: deposit.pool_mint.clone(),
75        };
76        let cpi_ctx = CpiContext::new(ctx.swap_program.clone(), cpi_accounts);
77        stable_swap_anchor::deposit(cpi_ctx, 0, amount_in, minimum_amount_out)
78    }
79
80    fn input_account(&self) -> &Account<'info, TokenAccount> {
81        &self.input_b.user
82    }
83
84    fn output_account(&self) -> &Account<'info, TokenAccount> {
85        &self.output_lp
86    }
87}
88
89impl<'info> ProcessAction<'info> for SSWithdrawOne<'info> {
90    /// Runs the deposit component instruction.
91    fn process(
92        ctx: &ActionContext<'_, '_, '_, 'info, Self>,
93        amount_in: u64,
94        minimum_amount_out: u64,
95    ) -> Result<()> {
96        let action = ctx.action;
97        let cpi_accounts = stable_swap_anchor::WithdrawOne {
98            user: build_swap_context!(action, ctx),
99            pool_mint: action.pool_mint.clone(),
100            input_lp: action.input_lp.to_account_info(),
101            quote_reserves: action.quote_reserves.clone(),
102            output: (&action.output).into(),
103        };
104        let cpi_ctx = CpiContext::new(ctx.swap_program.clone(), cpi_accounts);
105        stable_swap_anchor::withdraw_one(cpi_ctx, amount_in, minimum_amount_out)
106    }
107
108    fn input_account(&self) -> &Account<'info, TokenAccount> {
109        &self.input_lp
110    }
111
112    fn output_account(&self) -> &Account<'info, TokenAccount> {
113        &self.output.user_token.user
114    }
115}
116
117impl<'info> ProcessAction<'info> for SSSwap<'info> {
118    /// Runs the deposit component instruction.
119    fn process(
120        ctx: &ActionContext<'_, '_, '_, 'info, Self>,
121        amount_in: u64,
122        minimum_amount_out: u64,
123    ) -> Result<()> {
124        let action = ctx.action;
125        let cpi_accounts = stable_swap_anchor::Swap {
126            user: build_swap_context!(action, ctx),
127            input: (&action.input).into(),
128            output: (&action.output).into(),
129        };
130        let cpi_ctx = CpiContext::new(ctx.swap_program.clone(), cpi_accounts);
131        stable_swap_anchor::swap(cpi_ctx, amount_in, minimum_amount_out)
132    }
133
134    fn input_account(&self) -> &Account<'info, TokenAccount> {
135        &self.input.user
136    }
137
138    fn output_account(&self) -> &Account<'info, TokenAccount> {
139        &self.output.user_token.user
140    }
141}
142
143impl<'info> From<&SwapToken<'info>> for stable_swap_anchor::SwapToken<'info> {
144    fn from(accounts: &SwapToken<'info>) -> stable_swap_anchor::SwapToken<'info> {
145        stable_swap_anchor::SwapToken {
146            user: accounts.user.to_account_info(),
147            reserve: accounts.reserve.clone(),
148        }
149    }
150}
151
152impl<'info> From<&SwapOutput<'info>> for stable_swap_anchor::SwapOutput<'info> {
153    fn from(accounts: &SwapOutput<'info>) -> stable_swap_anchor::SwapOutput<'info> {
154        stable_swap_anchor::SwapOutput {
155            user_token: (&accounts.user_token).into(),
156            fees: accounts.fees.clone(),
157        }
158    }
159}