dloom_flow/amm/instructions/
create_pool.rs1use crate::{amm::state::AmmPool, constants::*, errors::DloomError, events::AmmPoolCreated};
4use anchor_lang::prelude::*;
5use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
6
7pub fn handle_create_amm_pool(
9 ctx: Context<CreateAmmPool>,
10 fee_rate: u16,
11 protocol_fee_share: u16,
12 referrer_fee_share: u16,
13) -> Result<()> {
14 require!(
15 fee_rate as u128 <= BASIS_POINT_MAX,
16 DloomError::InvalidFeeRates
17 );
18 require!(
19 protocol_fee_share as u128 <= BASIS_POINT_MAX,
20 DloomError::InvalidFeeRates
21 );
22 require!(
23 referrer_fee_share as u128 <= BASIS_POINT_MAX,
24 DloomError::InvalidFeeRates
25 );
26
27 let total_fee_share = (protocol_fee_share as u128)
28 .checked_add(referrer_fee_share as u128)
29 .ok_or(DloomError::MathOverflow)?;
30 require!(
31 total_fee_share <= BASIS_POINT_MAX,
32 DloomError::FeeShareExceedsTotal
33 );
34
35 let amm_pool = &mut ctx.accounts.amm_pool;
36 amm_pool.bump = ctx.bumps.amm_pool;
37 amm_pool.authority = ctx.accounts.authority.key();
38 amm_pool.token_a_mint = ctx.accounts.token_a_mint.key();
39 amm_pool.token_b_mint = ctx.accounts.token_b_mint.key();
40 amm_pool.token_a_vault = ctx.accounts.token_a_vault.key();
41 amm_pool.token_b_vault = ctx.accounts.token_b_vault.key();
42 amm_pool.lp_mint = ctx.accounts.lp_mint.key();
43 amm_pool.fee_rate = fee_rate;
44 amm_pool.protocol_fee_share = protocol_fee_share;
45 amm_pool.referrer_fee_share = referrer_fee_share;
46 amm_pool.protocol_fee_vault_a = ctx.accounts.protocol_fee_vault_a.key();
47 amm_pool.protocol_fee_vault_b = ctx.accounts.protocol_fee_vault_b.key();
48 amm_pool.reserves_a = 0;
49 amm_pool.reserves_b = 0;
50 amm_pool.price_a_cumulative_last_fee_update = 0;
51
52 emit!(AmmPoolCreated {
53 pool_address: ctx.accounts.amm_pool.key(),
54 token_a_mint: ctx.accounts.token_a_mint.key(),
55 token_b_mint: ctx.accounts.token_b_mint.key(),
56 lp_mint: ctx.accounts.lp_mint.key(),
57 fee_rate,
58 });
59
60 Ok(())
61}
62
63#[derive(Accounts)]
64pub struct CreateAmmPool<'info> {
65 #[account(mut)]
66 pub payer: Signer<'info>,
67
68 pub authority: AccountInfo<'info>,
70
71 #[account(constraint = token_a_mint.key() < token_b_mint.key() @ DloomError::InvalidMintOrder)]
72 pub token_a_mint: InterfaceAccount<'info, Mint>,
73 pub token_b_mint: InterfaceAccount<'info, Mint>,
74
75 #[account(
76 init,
77 payer = payer,
78 space = 8 + 390,
79 seeds = [b"amm_pool", token_a_mint.key().as_ref(), token_b_mint.key().as_ref()],
80 bump
81 )]
82 pub amm_pool: Box<Account<'info, AmmPool>>,
83
84 #[account(
85 init,
86 payer = payer,
87 seeds = [b"lp_mint", amm_pool.key().as_ref()],
88 bump,
89 mint::decimals = 6,
90 mint::authority = amm_pool,
91 mint::token_program = token_program
92 )]
93 pub lp_mint: InterfaceAccount<'info, Mint>,
94
95 #[account(
96 init,
97 payer = payer,
98 seeds = [b"vault", amm_pool.key().as_ref(), token_a_mint.key().as_ref()],
99 bump,
100 token::mint = token_a_mint,
101 token::authority = amm_pool,
102 token::token_program = token_a_program
103 )]
104 pub token_a_vault: InterfaceAccount<'info, TokenAccount>,
105
106 #[account(
107 init,
108 payer = payer,
109 seeds = [b"vault", amm_pool.key().as_ref(), token_b_mint.key().as_ref()],
110 bump,
111 token::mint = token_b_mint,
112 token::authority = amm_pool,
113 token::token_program = token_b_program
114 )]
115 pub token_b_vault: InterfaceAccount<'info, TokenAccount>,
116
117 #[account(
118 init,
119 payer = payer,
120 seeds = [b"protocol_fee_vault", amm_pool.key().as_ref(), token_a_mint.key().as_ref()],
121 bump,
122 token::mint = token_a_mint,
123 token::authority = authority,
124 token::token_program = token_a_program
125 )]
126 pub protocol_fee_vault_a: InterfaceAccount<'info, TokenAccount>,
127
128 #[account(
129 init,
130 payer = payer,
131 seeds = [b"protocol_fee_vault", amm_pool.key().as_ref(), token_b_mint.key().as_ref()],
132 bump,
133 token::mint = token_b_mint,
134 token::authority = authority,
135 token::token_program = token_b_program
136 )]
137 pub protocol_fee_vault_b: InterfaceAccount<'info, TokenAccount>,
138
139 pub system_program: Program<'info, System>,
140 pub token_a_program: Interface<'info, TokenInterface>,
141 pub token_b_program: Interface<'info, TokenInterface>,
142 pub token_program: Interface<'info, TokenInterface>,
143
144 pub rent: Sysvar<'info, Rent>,
145}