Skip to main content

klend_interface/state/
lending_market.rs

1use bytemuck::{Pod, Zeroable};
2use solana_pubkey::Pubkey;
3use spl_discriminator::SplDiscriminate;
4
5use super::pod::PodU128;
6
7// ---------------------------------------------------------------------------
8// LendingMarket
9// ---------------------------------------------------------------------------
10
11/// Lending market account state.
12#[derive(Debug, Clone, Copy, Pod, Zeroable, SplDiscriminate)]
13#[discriminator_hash_input("account:LendingMarket")]
14#[repr(C)]
15pub struct LendingMarket {
16    pub version: u64,
17    pub bump_seed: u64,
18    pub lending_market_owner: Pubkey,
19    pub lending_market_owner_cached: Pubkey,
20    pub quote_currency: [u8; 32],
21    pub referral_fee_bps: u16,
22    pub emergency_mode: u8,
23    pub autodeleverage_enabled: u8,
24    pub borrow_disabled: u8,
25    pub price_refresh_trigger_to_max_age_pct: u8,
26    pub liquidation_max_debt_close_factor_pct: u8,
27    pub insolvency_risk_unhealthy_ltv_pct: u8,
28    pub min_full_liquidation_value_threshold: u64,
29    pub max_liquidatable_debt_market_value_at_once: u64,
30    pub reserved0: [u8; 8],
31    pub global_allowed_borrow_value: u64,
32    pub emergency_council: Pubkey,
33    pub reserved1: [u8; 8],
34    pub elevation_groups: [ElevationGroup; 32],
35    pub elevation_group_padding: [u64; 90],
36    pub min_net_value_in_obligation_sf: PodU128,
37    pub min_value_skip_liquidation_ltv_checks: u64,
38    pub name: [u8; 32],
39    pub min_value_skip_liquidation_bf_checks: u64,
40    pub individual_autodeleverage_margin_call_period_secs: u64,
41    pub min_initial_deposit_amount: u64,
42    pub obligation_order_execution_enabled: u8,
43    pub immutable: u8,
44    pub obligation_order_creation_enabled: u8,
45    pub price_triggered_liquidation_disabled: u8,
46    pub mature_reserve_debt_liquidation_enabled: u8,
47    pub obligation_borrow_debt_term_liquidation_enabled: u8,
48    pub borrow_order_creation_enabled: u8,
49    pub borrow_order_execution_enabled: u8,
50    pub proposer_authority: Pubkey,
51    pub min_borrow_order_fill_value: u64,
52    pub withdraw_ticket_issuance_enabled: u8,
53    pub withdraw_ticket_redemption_enabled: u8,
54    pub obligation_borrow_rollover_configuration_enabled: u8,
55    pub obligation_borrow_migration_to_fixed_execution_enabled: u8,
56    pub withdraw_ticket_cancellation_enabled: u8,
57    pub padding2: [u8; 1],
58    /// Cap (in basis points; `FULL_BPS = 10_000` = 100%) on reserve rewards distribution APR
59    pub reserve_rewards_max_apr_bps: u16,
60    pub min_withdraw_queued_liquidity_value: u64,
61    pub fixed_term_rollover_window_duration_seconds: u64,
62    pub open_term_rollover_window_duration_seconds: u64,
63    pub min_partial_rollover_value: u64,
64    pub term_based_full_liquidation_duration_secs: u64,
65    pub permissioning_authority: Pubkey,
66    pub permissioned_ops: u64,
67    pub padding1: [u64; 153],
68}
69
70const _: () = assert!(core::mem::size_of::<LendingMarket>() == 4656);
71
72impl LendingMarket {
73    /// Whether the market is in emergency mode.
74    pub fn is_emergency_mode(&self) -> bool {
75        self.emergency_mode != 0
76    }
77
78    /// Whether borrowing is globally disabled.
79    pub fn is_borrow_disabled(&self) -> bool {
80        self.borrow_disabled != 0
81    }
82
83    /// Whether autodeleverage is enabled.
84    pub fn is_autodeleverage_enabled(&self) -> bool {
85        self.autodeleverage_enabled != 0
86    }
87
88    /// Max percentage of debt that can be closed in a single liquidation.
89    pub fn liquidation_max_debt_close_factor_pct(&self) -> u8 {
90        self.liquidation_max_debt_close_factor_pct
91    }
92
93    /// Minimum value threshold for full liquidation.
94    pub fn min_full_liquidation_value_threshold(&self) -> u64 {
95        self.min_full_liquidation_value_threshold
96    }
97
98    /// Maximum liquidatable debt market value at once.
99    pub fn max_liquidatable_debt_market_value_at_once(&self) -> u64 {
100        self.max_liquidatable_debt_market_value_at_once
101    }
102
103    /// Referral fee in basis points.
104    pub fn referral_fee_bps(&self) -> u16 {
105        self.referral_fee_bps
106    }
107
108    /// Get an elevation group by index (0-31). Returns `None` if out of bounds.
109    pub fn elevation_group(&self, index: usize) -> Option<&ElevationGroup> {
110        self.elevation_groups.get(index)
111    }
112
113    /// Whether the market is immutable (no more config changes).
114    pub fn is_immutable(&self) -> bool {
115        self.immutable != 0
116    }
117
118    /// Whether withdraw ticket cancellation is enabled.
119    pub fn is_withdraw_ticket_cancellation_enabled(&self) -> bool {
120        self.withdraw_ticket_cancellation_enabled != 0
121    }
122
123    /// Whether migration-to-fixed rollover execution is enabled.
124    pub fn is_obligation_borrow_migration_to_fixed_execution_enabled(&self) -> bool {
125        self.obligation_borrow_migration_to_fixed_execution_enabled != 0
126    }
127}
128
129// ---------------------------------------------------------------------------
130// ElevationGroup
131// ---------------------------------------------------------------------------
132
133#[derive(Debug, Clone, Copy, Zeroable, Pod)]
134#[repr(C)]
135pub struct ElevationGroup {
136    pub max_liquidation_bonus_bps: u16,
137    pub id: u8,
138    pub ltv_pct: u8,
139    pub liquidation_threshold_pct: u8,
140    pub allow_new_loans: u8,
141    pub max_reserves_as_collateral: u8,
142    pub padding_0: u8,
143    pub debt_reserve: Pubkey,
144    pub padding_1: [u64; 4],
145}