1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use borsh::BorshDeserialize;
use solana_client::rpc_client::RpcClient;
use solana_sdk::pubkey::Pubkey;
use tabled::Tabled;

use crate::program::PROGRAM_ID;

#[derive(BorshDeserialize, Tabled, Copy, Clone)]
pub struct Clmmpool {
    /// clmm_config
    pub clmm_config: Pubkey,
    /// The pool token a mint address.
    pub token_a: Pubkey,
    /// The pool token b mint address.
    pub token_b: Pubkey,

    /// The vault for hold clmmpool's token a.
    pub token_a_vault: Pubkey,
    /// The vault for hold clmmpool's token b.
    pub token_b_vault: Pubkey,

    /// The tick spacing.
    pub tick_spacing: u16,

    pub tick_spacing_seed: u16,

    /// The numerator of fee rate, the denominator is 1_000_000.
    pub fee_rate: u16,
    /// The numerator of protocol fee rate, the denominator is 1_000_0.

    /// Protocol fee amount = fee_amount * protocol_fee_rate.
    pub protocol_fee_rate: u16,

    /// The liquidity of current tick index.
    pub liquidity: u128,

    /// The current sqrt price, Q64.64 and MAX/MIN is Q32.64.
    pub current_sqrt_price: u128,
    /// The current tick index.
    pub current_tick_index: i32,

    /// The fee growth a as Q64.64.
    pub fee_growth_global_a: u128,
    /// The fee growth b as Q64.64.
    pub fee_growth_global_b: u128,

    /// The amounts of token a owed to protocol.
    pub fee_protocol_token_a: u64,
    /// The amounts of token b owed to protocol.
    pub fee_protocol_token_b: u64,

    /// The bump
    pub bump: u8,

    pub reward_infos: Rewarders,
    pub reward_last_updated_time: u64, // 8
}

#[derive(Copy, Clone, BorshDeserialize, Default, Debug, PartialEq)]
pub struct Rewarder {
    pub mint_wrapper: Pubkey,
    pub minter: Pubkey,
    /// Reward token mint.
    pub mint: Pubkey,
    /// Authority account that has permission to initialize the reward and set emissions.
    pub authority: Pubkey,
    /// Q64.64 number that indicates how many tokens per second are earned per unit of liquidity.
    pub emissions_per_second: u128,
    /// Q64.64 number that tracks the total tokens earned per unit of liquidity since the reward
    /// emissions were turned on.
    pub growth_global: u128,
}

impl Rewarder {
    pub const LEN: usize = 32 + 32 + 32 + 32 + 16 + 16;
}

#[derive(Copy, Clone, BorshDeserialize, Default, Debug, PartialEq)]
pub struct Rewarders([Rewarder; 3]);

impl std::fmt::Display for Rewarders {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "reserved")
    }
}

impl Clmmpool {
    pub const REWARD_NUM: usize = 3;
    pub const LEN: usize =
        5 * 32 + 4 * 2 + 2 * 16 + 4 + 2 * 16 + 2 * 8 + 1 + Clmmpool::REWARD_NUM * Rewarder::LEN + 8;

    pub fn get_info(rpc_client: &RpcClient, pubkey: &Pubkey) -> Self {
        let data_slice = &rpc_client.get_account_data(pubkey).unwrap()[8..];
        Clmmpool::try_from_slice(data_slice).unwrap()
    }

    pub fn get_tick_map_address(pool: &Pubkey) -> Pubkey {
        let (expect_address, _) =
            Pubkey::find_program_address(&[b"tick_array_map", pool.as_ref()], &PROGRAM_ID);
        expect_address
    }

    pub fn get_ui_info(self, clmmpool: Pubkey) -> ClmmpoolUiList {
        ClmmpoolUiList {
            clmm_config: self.clmm_config,
            clmmpool: clmmpool,
            token_a: self.token_a,
            token_b: self.token_b,
            tick_spacing: self.tick_spacing,
            tick_spacing_seed: self.tick_spacing_seed,
            current_sqrt_price: self.current_sqrt_price,
            current_tick_index: self.current_tick_index,
            liquidity: self.liquidity
        }
    }
}

#[derive(Tabled)]
pub struct ClmmpoolUiList {
    /// clmm_config
    pub clmm_config: Pubkey,
    /// clmmpool
    pub clmmpool: Pubkey,
    /// The pool token a mint address.
    pub token_a: Pubkey,
    /// The pool token b mint address.
    pub token_b: Pubkey,
    /// The tick spacing.
    pub tick_spacing: u16,

    pub tick_spacing_seed: u16,
    /// The current sqrt price, Q64.64 and MAX/MIN is Q32.64.
    pub current_sqrt_price: u128,
    /// The current tick index.
    pub current_tick_index: i32,
    /// The liquidity of current tick index.
    pub liquidity: u128,
}