use bytemuck::{Pod, Zeroable};
use solana_pubkey::Pubkey;
use spl_discriminator::SplDiscriminate;
use super::{
common::{BigFractionBytes, LastUpdate},
pod::PodU128,
};
#[derive(Debug, Clone, Copy, Pod, Zeroable, SplDiscriminate)]
#[discriminator_hash_input("account:Reserve")]
#[repr(C)]
pub struct Reserve {
pub version: u64,
pub last_update: LastUpdate,
pub lending_market: Pubkey,
pub farm_collateral: Pubkey,
pub farm_debt: Pubkey,
pub liquidity: ReserveLiquidity,
pub reserve_liquidity_padding: [u64; 150],
pub collateral: ReserveCollateral,
pub reserve_collateral_padding: [u64; 150],
pub config: ReserveConfig,
pub config_padding: [u64; 112],
pub borrowed_amount_outside_elevation_group: u64,
pub borrowed_amounts_against_this_reserve_in_elevation_groups: [u64; 32],
pub withdraw_queue: WithdrawQueue,
pub padding: [u64; 204],
}
const _: () = assert!(core::mem::size_of::<Reserve>() == 8616);
impl Reserve {
pub fn available_liquidity(&self) -> u64 {
self.liquidity.total_available_amount
}
pub fn borrowed_amount(&self) -> u128 {
u128::from(self.liquidity.borrowed_amount_sf)
}
pub fn market_price(&self) -> u128 {
u128::from(self.liquidity.market_price_sf)
}
pub fn mint_decimals(&self) -> u64 {
self.liquidity.mint_decimals
}
pub fn collateral_total_supply(&self) -> u64 {
self.collateral.mint_total_supply
}
pub fn accumulated_protocol_fees(&self) -> u128 {
u128::from(self.liquidity.accumulated_protocol_fees_sf)
}
pub fn accumulated_referrer_fees(&self) -> u128 {
u128::from(self.liquidity.accumulated_referrer_fees_sf)
}
pub fn status(&self) -> u8 {
self.config.status
}
pub fn is_emergency_mode(&self) -> bool {
self.config.emergency_mode != 0
}
pub fn loan_to_value_pct(&self) -> u8 {
self.config.loan_to_value_pct
}
pub fn liquidation_threshold_pct(&self) -> u8 {
self.config.liquidation_threshold_pct
}
pub fn borrow_factor_pct(&self) -> u64 {
self.config.borrow_factor_pct
}
pub fn deposit_limit(&self) -> u64 {
self.config.deposit_limit
}
pub fn borrow_limit(&self) -> u64 {
self.config.borrow_limit
}
pub fn next_withdraw_ticket_sequence_number(&self) -> u64 {
self.withdraw_queue.next_issued_ticket_sequence_number
}
}
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct ReserveLiquidity {
pub mint_pubkey: Pubkey,
pub supply_vault: Pubkey,
pub fee_vault: Pubkey,
pub total_available_amount: u64,
pub borrowed_amount_sf: PodU128,
pub market_price_sf: PodU128,
pub market_price_last_updated_ts: u64,
pub mint_decimals: u64,
pub deposit_limit_crossed_timestamp: u64,
pub borrow_limit_crossed_timestamp: u64,
pub cumulative_borrow_rate_bsf: BigFractionBytes,
pub accumulated_protocol_fees_sf: PodU128,
pub accumulated_referrer_fees_sf: PodU128,
pub pending_referrer_fees_sf: PodU128,
pub absolute_referral_rate_sf: PodU128,
pub token_program: Pubkey,
pub rewards_amount_available: u64,
pub padding2: [u64; 50],
pub padding3: [PodU128; 32],
}
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct ReserveCollateral {
pub mint_pubkey: Pubkey,
pub mint_total_supply: u64,
pub supply_vault: Pubkey,
pub padding1: [PodU128; 32],
pub padding2: [PodU128; 32],
}
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct ReserveConfig {
pub status: u8,
pub padding_deprecated_asset_tier: u8,
pub host_fixed_interest_rate_bps: u16,
pub min_deleveraging_bonus_bps: u16,
pub block_ctoken_usage: u8,
pub early_repay_remaining_interest_pct: u8,
pub emergency_mode: u8,
pub reserved_1: [u8; 4],
pub protocol_order_execution_fee_pct: u8,
pub protocol_take_rate_pct: u8,
pub protocol_liquidation_fee_pct: u8,
pub loan_to_value_pct: u8,
pub liquidation_threshold_pct: u8,
pub min_liquidation_bonus_bps: u16,
pub max_liquidation_bonus_bps: u16,
pub bad_debt_liquidation_bonus_bps: u16,
pub deleveraging_margin_call_period_secs: u64,
pub deleveraging_threshold_decrease_bps_per_day: u64,
pub fees: ReserveFees,
pub borrow_rate_curve: BorrowRateCurve,
pub borrow_factor_pct: u64,
pub deposit_limit: u64,
pub borrow_limit: u64,
pub token_info: TokenInfo,
pub deposit_withdrawal_cap: WithdrawalCaps,
pub debt_withdrawal_cap: WithdrawalCaps,
pub elevation_groups: [u8; 20],
pub disable_usage_as_coll_outside_emode: u8,
pub utilization_limit_block_borrowing_above_pct: u8,
pub autodeleverage_enabled: u8,
pub proposer_authority_locked: u8,
pub borrow_limit_outside_elevation_group: u64,
pub borrow_limit_against_this_collateral_in_elevation_group: [u64; 32],
pub deleveraging_bonus_increase_bps_per_day: u64,
pub debt_maturity_timestamp: u64,
pub debt_term_seconds: u64,
pub rewards_amount_per_slot: u64,
pub permissioned_ops: u64,
}
const _: () = assert!(core::mem::size_of::<ReserveConfig>() == 952);
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct ReserveFees {
pub origination_fee_sf: u64,
pub flash_loan_fee_sf: u64,
pub padding: [u8; 8],
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct BorrowRateCurve {
pub points: [CurvePoint; 11],
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct CurvePoint {
pub utilization_rate_bps: u32,
pub borrow_rate_bps: u32,
}
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct TokenInfo {
pub name: [u8; 32],
pub heuristic: PriceHeuristic,
pub max_twap_divergence_bps: u64,
pub max_age_price_seconds: u64,
pub max_age_twap_seconds: u64,
pub scope_configuration: ScopeConfiguration,
pub switchboard_configuration: SwitchboardConfiguration,
pub pyth_configuration: PythConfiguration,
pub block_price_usage: u8,
pub reserved: [u8; 7],
pub _padding: [u64; 19],
}
const _: () = assert!(core::mem::size_of::<TokenInfo>() == 384);
impl TokenInfo {
pub fn name_str(&self) -> Option<&str> {
let end = self
.name
.iter()
.position(|&b| b == 0)
.unwrap_or(self.name.len());
core::str::from_utf8(&self.name[..end]).ok()
}
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct PriceHeuristic {
pub lower: u64,
pub upper: u64,
pub exp: u64,
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct ScopeConfiguration {
pub price_feed: Pubkey,
pub price_chain: [u16; 4],
pub twap_chain: [u16; 4],
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct SwitchboardConfiguration {
pub price_aggregator: Pubkey,
pub twap_aggregator: Pubkey,
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct PythConfiguration {
pub price: Pubkey,
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct WithdrawalCaps {
pub config_capacity: i64,
pub current_total: i64,
pub last_interval_start_timestamp: u64,
pub config_interval_length_seconds: u64,
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)]
pub struct WithdrawQueue {
pub queued_collateral_amount: u64,
pub next_issued_ticket_sequence_number: u64,
pub next_withdrawable_ticket_sequence_number: u64,
}