jito_priority_fee_distribution/
state.rs1use std::mem::size_of;
4
5use anchor_lang::prelude::*;
6
7use crate::ErrorCode::{AccountValidationFailure, ArithmeticError};
8
9#[account]
10#[derive(Default)]
11pub struct Config {
12 pub authority: Pubkey,
14
15 pub expired_funds_account: Pubkey,
18
19 pub num_epochs_valid: u64,
21
22 pub max_validator_commission_bps: u16,
24
25 pub go_live_epoch: u64,
27
28 pub bump: u8,
30}
31
32#[account]
34#[derive(Default)]
35pub struct PriorityFeeDistributionAccount {
36 pub validator_vote_account: Pubkey,
39
40 pub merkle_root_upload_authority: Pubkey,
42
43 pub merkle_root: Option<MerkleRoot>,
45
46 pub epoch_created_at: u64,
48
49 pub validator_commission_bps: u16,
51
52 pub expires_at: u64,
54
55 pub total_lamports_transferred: u64,
57
58 pub bump: u8,
60}
61
62#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
63pub struct MerkleRoot {
64 pub root: [u8; 32],
66
67 pub max_total_claim: u64,
69
70 pub max_num_nodes: u64,
72
73 pub total_funds_claimed: u64,
75
76 pub num_nodes_claimed: u64,
78}
79
80const HEADER_SIZE: usize = 8;
81
82impl Config {
83 pub const SEED: &'static [u8] = b"CONFIG_ACCOUNT";
84 pub const SIZE: usize = HEADER_SIZE + size_of::<Self>();
85
86 pub fn validate(&self) -> Result<()> {
87 const MAX_NUM_EPOCHS_VALID: u64 = 10;
88 const MAX_VALIDATOR_COMMISSION_BPS: u16 = 10000;
89
90 if self.num_epochs_valid == 0 || self.num_epochs_valid > MAX_NUM_EPOCHS_VALID {
91 return Err(AccountValidationFailure.into());
92 }
93
94 if self.max_validator_commission_bps > MAX_VALIDATOR_COMMISSION_BPS {
95 return Err(AccountValidationFailure.into());
96 }
97
98 let default_pubkey = Pubkey::default();
99 if self.expired_funds_account == default_pubkey || self.authority == default_pubkey {
100 return Err(AccountValidationFailure.into());
101 }
102
103 Ok(())
104 }
105}
106
107impl PriorityFeeDistributionAccount {
108 pub const SEED: &'static [u8] = b"PF_DISTRIBUTION_ACCOUNT";
109
110 pub const SIZE: usize = HEADER_SIZE + size_of::<Self>();
111
112 pub fn validate(&self) -> Result<()> {
113 let default_pubkey = Pubkey::default();
114 if self.validator_vote_account == default_pubkey
115 || self.merkle_root_upload_authority == default_pubkey
116 {
117 return Err(AccountValidationFailure.into());
118 }
119
120 Ok(())
121 }
122
123 pub fn claim_expired(from: AccountInfo, to: AccountInfo) -> Result<u64> {
124 let rent = Rent::get()?;
125 let min_rent_lamports = rent.minimum_balance(from.data_len());
126
127 let amount = from
128 .lamports()
129 .checked_sub(min_rent_lamports)
130 .ok_or(ArithmeticError)?;
131 Self::transfer_lamports(from, to, amount)?;
132
133 Ok(amount)
134 }
135
136 pub fn claim(from: AccountInfo, to: AccountInfo, amount: u64) -> Result<()> {
137 Self::transfer_lamports(from, to, amount)
138 }
139
140 pub fn increment_total_lamports_transferred(&mut self, amount: u64) -> Result<()> {
141 let old_balance = self.total_lamports_transferred;
142 let new_balance = old_balance.checked_add(amount).ok_or(ArithmeticError)?;
143
144 self.total_lamports_transferred = new_balance;
145
146 Ok(())
147 }
148
149 fn transfer_lamports(from: AccountInfo, to: AccountInfo, amount: u64) -> Result<()> {
150 **from.try_borrow_mut_lamports()? =
152 from.lamports().checked_sub(amount).ok_or(ArithmeticError)?;
153 **to.try_borrow_mut_lamports()? =
155 to.lamports().checked_add(amount).ok_or(ArithmeticError)?;
156
157 Ok(())
158 }
159}
160
161#[account]
165#[derive(Default)]
166pub struct ClaimStatus {
167 pub claim_status_payer: Pubkey,
169
170 pub expires_at: u64,
173}
174
175impl ClaimStatus {
176 pub const SEED: &'static [u8] = b"CLAIM_STATUS";
177
178 pub const SIZE: usize = HEADER_SIZE + size_of::<Self>();
179}
180
181#[account]
183#[derive(Default)]
184pub struct MerkleRootUploadConfig {
185 pub override_authority: Pubkey,
187
188 pub original_upload_authority: Pubkey,
191
192 pub bump: u8,
194}
195
196impl MerkleRootUploadConfig {
197 pub const SEED: &'static [u8] = b"ROOT_UPLOAD_CONFIG";
198
199 pub const SIZE: usize = HEADER_SIZE + size_of::<Self>();
200}