use std::mem::size_of;
use anchor_lang::prelude::*;
use crate::ErrorCode::{AccountValidationFailure, ArithmeticError};
#[account]
#[derive(Default)]
pub struct Config {
pub authority: Pubkey,
pub expired_funds_account: Pubkey,
pub num_epochs_valid: u64,
pub max_validator_commission_bps: u16,
pub go_live_epoch: u64,
pub bump: u8,
}
#[account]
#[derive(Default)]
pub struct PriorityFeeDistributionAccount {
pub validator_vote_account: Pubkey,
pub merkle_root_upload_authority: Pubkey,
pub merkle_root: Option<MerkleRoot>,
pub epoch_created_at: u64,
pub validator_commission_bps: u16,
pub expires_at: u64,
pub total_lamports_transferred: u64,
pub bump: u8,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
pub struct MerkleRoot {
pub root: [u8; 32],
pub max_total_claim: u64,
pub max_num_nodes: u64,
pub total_funds_claimed: u64,
pub num_nodes_claimed: u64,
}
const HEADER_SIZE: usize = 8;
impl Config {
pub const SEED: &'static [u8] = b"CONFIG_ACCOUNT";
pub const SIZE: usize = HEADER_SIZE + size_of::<Self>();
pub fn validate(&self) -> Result<()> {
const MAX_NUM_EPOCHS_VALID: u64 = 10;
const MAX_VALIDATOR_COMMISSION_BPS: u16 = 10000;
if self.num_epochs_valid == 0 || self.num_epochs_valid > MAX_NUM_EPOCHS_VALID {
return Err(AccountValidationFailure.into());
}
if self.max_validator_commission_bps > MAX_VALIDATOR_COMMISSION_BPS {
return Err(AccountValidationFailure.into());
}
let default_pubkey = Pubkey::default();
if self.expired_funds_account == default_pubkey || self.authority == default_pubkey {
return Err(AccountValidationFailure.into());
}
Ok(())
}
}
impl PriorityFeeDistributionAccount {
pub const SEED: &'static [u8] = b"PF_DISTRIBUTION_ACCOUNT";
pub const SIZE: usize = HEADER_SIZE + size_of::<Self>();
pub fn validate(&self) -> Result<()> {
let default_pubkey = Pubkey::default();
if self.validator_vote_account == default_pubkey
|| self.merkle_root_upload_authority == default_pubkey
{
return Err(AccountValidationFailure.into());
}
Ok(())
}
pub fn claim_expired(from: AccountInfo, to: AccountInfo) -> Result<u64> {
let rent = Rent::get()?;
let min_rent_lamports = rent.minimum_balance(from.data_len());
let amount = from
.lamports()
.checked_sub(min_rent_lamports)
.ok_or(ArithmeticError)?;
Self::transfer_lamports(from, to, amount)?;
Ok(amount)
}
pub fn claim(from: AccountInfo, to: AccountInfo, amount: u64) -> Result<()> {
Self::transfer_lamports(from, to, amount)
}
pub fn increment_total_lamports_transferred(&mut self, amount: u64) -> Result<()> {
let old_balance = self.total_lamports_transferred;
let new_balance = old_balance.checked_add(amount).ok_or(ArithmeticError)?;
self.total_lamports_transferred = new_balance;
Ok(())
}
fn transfer_lamports(from: AccountInfo, to: AccountInfo, amount: u64) -> Result<()> {
**from.try_borrow_mut_lamports()? =
from.lamports().checked_sub(amount).ok_or(ArithmeticError)?;
**to.try_borrow_mut_lamports()? =
to.lamports().checked_add(amount).ok_or(ArithmeticError)?;
Ok(())
}
}
#[account]
#[derive(Default)]
pub struct ClaimStatus {
pub claim_status_payer: Pubkey,
pub expires_at: u64,
}
impl ClaimStatus {
pub const SEED: &'static [u8] = b"CLAIM_STATUS";
pub const SIZE: usize = HEADER_SIZE + size_of::<Self>();
}
#[account]
#[derive(Default)]
pub struct MerkleRootUploadConfig {
pub override_authority: Pubkey,
pub original_upload_authority: Pubkey,
pub bump: u8,
}
impl MerkleRootUploadConfig {
pub const SEED: &'static [u8] = b"ROOT_UPLOAD_CONFIG";
pub const SIZE: usize = HEADER_SIZE + size_of::<Self>();
}