dloom_flow/dlmm/instructions/
create_pool.rs

1// FILE: programs/dloom_flow/src/dlmm/instructions/create_pool.rs
2
3use crate::{
4    constants::*,
5    errors::DloomError,
6    events::DlmmPoolCreated,
7    dlmm::{state::{DlmmPool, PoolType}},
8    state::{ProtocolConfig, DlmmParameters},
9};
10use anchor_lang::prelude::*;
11use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
12
13pub fn handle_create_dlmm_pool(
14    ctx: Context<CreateDlmmPool>,
15    bin_step: u16,
16    fee_rate: u16,
17    protocol_fee_share: u16,
18    referrer_fee_share: u16,
19    initial_bin_id: i32,
20) -> Result<()> {
21    let is_allowed = ctx
22        .accounts
23        .dlmm_parameters
24        .official_parameters
25        .iter()
26        .any(|p| p.bin_step == bin_step && p.fee_rate == fee_rate);
27    require!(is_allowed, DloomError::InvalidParameters);
28    require!(
29        protocol_fee_share as u128 <= BASIS_POINT_MAX,
30        DloomError::InvalidFeeRates
31    );
32    require!(
33        referrer_fee_share as u128 <= BASIS_POINT_MAX,
34        DloomError::InvalidFeeRates
35    );
36
37    let dlmm_pool = &mut ctx.accounts.dlmm_pool;
38    let clock = Clock::get()?;
39
40    // Set all fields for the new official pool
41    dlmm_pool.bump = ctx.bumps.dlmm_pool;
42    dlmm_pool.authority = ctx.accounts.authority.key();
43    dlmm_pool.pool_type = PoolType::Official;
44    dlmm_pool.token_a_mint = ctx.accounts.token_a_mint.key();
45    dlmm_pool.token_b_mint = ctx.accounts.token_b_mint.key();
46    dlmm_pool.token_a_vault = ctx.accounts.token_a_vault.key();
47    dlmm_pool.token_b_vault = ctx.accounts.token_b_vault.key();
48    dlmm_pool.protocol_fee_vault_a = ctx.accounts.protocol_fee_vault_a.key();
49    dlmm_pool.protocol_fee_vault_b = ctx.accounts.protocol_fee_vault_b.key();
50    dlmm_pool.active_bin_id = initial_bin_id;
51    dlmm_pool.bin_step = bin_step;
52    dlmm_pool.fee_rate = fee_rate;
53    dlmm_pool.protocol_fee_share = protocol_fee_share;
54    dlmm_pool.referrer_fee_share = referrer_fee_share;
55    dlmm_pool.reserves_a = 0;
56    dlmm_pool.reserves_b = 0;
57    dlmm_pool.volatility_accumulator = 0;
58    dlmm_pool.last_fee_update_timestamp = clock.unix_timestamp;
59
60    emit!(DlmmPoolCreated {
61        pool_address: dlmm_pool.key(),
62        token_a_mint: dlmm_pool.token_a_mint,
63        token_b_mint: dlmm_pool.token_b_mint,
64        bin_step,
65        fee_rate,
66    });
67
68    Ok(())
69}
70
71#[derive(Accounts)]
72#[instruction(bin_step: u16)]
73pub struct CreateDlmmPool<'info> {
74    #[account(mut)]
75    pub payer: Signer<'info>,
76    pub authority: Signer<'info>,
77
78    #[account(
79        seeds = [b"protocol_config"],
80        bump,
81        has_one = authority,
82    )]
83    pub protocol_config: Account<'info, ProtocolConfig>,
84
85    #[account(
86        seeds = [b"dlmm_parameters"],
87        bump
88    )]
89    pub dlmm_parameters: Account<'info, DlmmParameters>,
90
91    #[account(constraint = token_a_mint.key() < token_b_mint.key() @ DloomError::InvalidMintOrder)]
92    pub token_a_mint: InterfaceAccount<'info, Mint>,
93    pub token_b_mint: InterfaceAccount<'info, Mint>,
94
95    #[account(
96        init,
97        payer = payer,
98        space = 8 + 256,
99        seeds = [
100            b"dlmm_pool",
101            token_a_mint.key().as_ref(),
102            token_b_mint.key().as_ref(),
103            &bin_step.to_le_bytes()
104        ],
105        bump
106    )]
107    pub dlmm_pool: Box<Account<'info, DlmmPool>>,
108
109    #[account(
110        init,
111        payer = payer,
112        seeds = [b"vault", dlmm_pool.key().as_ref(), token_a_mint.key().as_ref()],
113        bump,
114        token::mint = token_a_mint,
115        token::authority = dlmm_pool,
116        token::token_program = token_a_program
117    )]
118    pub token_a_vault: InterfaceAccount<'info, TokenAccount>,
119    #[account(
120        init,
121        payer = payer,
122        seeds = [b"vault", dlmm_pool.key().as_ref(), token_b_mint.key().as_ref()],
123        bump,
124        token::mint = token_b_mint,
125        token::authority = dlmm_pool,
126        token::token_program = token_b_program
127    )]
128    pub token_b_vault: InterfaceAccount<'info, TokenAccount>,
129    #[account(
130        init,
131        payer = payer,
132        seeds = [b"protocol_fee_vault", dlmm_pool.key().as_ref(), token_a_mint.key().as_ref()],
133        bump,
134        token::mint = token_a_mint,
135        token::authority = authority,
136        token::token_program = token_a_program
137    )]
138    pub protocol_fee_vault_a: InterfaceAccount<'info, TokenAccount>,
139    #[account(
140        init,
141        payer = payer,
142        seeds = [b"protocol_fee_vault", dlmm_pool.key().as_ref(), token_b_mint.key().as_ref()],
143        bump,
144        token::mint = token_b_mint,
145        token::authority = authority,
146        token::token_program = token_b_program
147    )]
148    pub protocol_fee_vault_b: InterfaceAccount<'info, TokenAccount>,
149
150    pub system_program: Program<'info, System>,
151    pub token_a_program: Interface<'info, TokenInterface>,
152    pub token_b_program: Interface<'info, TokenInterface>,
153    pub rent: Sysvar<'info, Rent>,
154}