dloom_flow/dlmm/instructions/
create_community_pool.rs

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