templar_common/market/
external.rs

1use std::collections::HashMap;
2
3use near_sdk::{near, AccountId, Promise, PromiseOrValue};
4
5use crate::{
6    accumulator::Accumulator,
7    asset::{BorrowAsset, BorrowAssetAmount, CollateralAssetAmount},
8    borrow::{BorrowPosition, BorrowStatus},
9    number::Decimal,
10    oracle::pyth::OracleResponse,
11    snapshot::Snapshot,
12    supply::SupplyPosition,
13    withdrawal_queue::{
14        WithdrawalQueueExecutionResult, WithdrawalQueueStatus, WithdrawalRequestStatus,
15    },
16};
17
18use super::{BorrowAssetMetrics, MarketConfiguration};
19
20#[derive(Debug, Clone, Copy, Default)]
21#[near(serializers = [json, borsh])]
22pub enum HarvestYieldMode {
23    #[default]
24    Default,
25    Compounding,
26    SnapshotLimit(u32),
27}
28
29#[near_sdk::ext_contract(ext_market)]
30pub trait MarketExternalInterface {
31    // ========================
32    // MARKET GENERAL FUNCTIONS
33    // ========================
34
35    /// Retrieve the market configuration.
36    fn get_configuration(&self) -> MarketConfiguration;
37
38    /// Retrieve the current snapshot (in progress; not yet finalized).
39    fn get_current_snapshot(&self) -> Snapshot;
40
41    /// Retrieve the count of finalized snapshots.
42    fn get_finalized_snapshots_len(&self) -> u32;
43
44    /// Retrieve a list of finalized snapshots.
45    fn list_finalized_snapshots(&self, offset: Option<u32>, count: Option<u32>) -> Vec<&Snapshot>;
46
47    /// Retrieve current contract metrics about borrow asset deposit,
48    /// availability, usage, etc.
49    fn get_borrow_asset_metrics(&self) -> BorrowAssetMetrics;
50
51    // ==================
52    // BORROW FUNCTIONS
53    // ==================
54
55    // *_on_transfer where msg = Collateralize
56    // *_on_transfer where msg = Repay
57
58    /// Retrieve a map of borrow positions.
59    fn list_borrow_positions(
60        &self,
61        offset: Option<u32>,
62        count: Option<u32>,
63    ) -> HashMap<AccountId, BorrowPosition>;
64
65    /// Retrieve a specific borrow position, with estimated fees.
66    ///
67    /// This function may report fees slightly inaccurately. This is because
68    /// the function has to estimate what fees will be applied between the last
69    /// finalized market snapshot and the (present) time when the function was
70    /// called.
71    fn get_borrow_position(&self, account_id: AccountId) -> Option<BorrowPosition>;
72
73    /// Retrieves the status of a borrow position (healthy or in liquidation)
74    /// given some asset prices.
75    ///
76    /// This is just a read-only function, so it does not validate the price
77    /// data. It is intended to be called by liquidators so they can easily see
78    /// whether a position is eligible for liquidation.
79    fn get_borrow_status(
80        &self,
81        account_id: AccountId,
82        oracle_response: OracleResponse,
83    ) -> Option<BorrowStatus>;
84
85    /// Transfers `amount` of borrow asset tokens to the caller, provided
86    /// their borrow position will still be sufficiently collateralized.
87    fn borrow(&mut self, amount: BorrowAssetAmount) -> Promise;
88
89    /// Transfers `amount` of collateral asset tokens to the caller, provided
90    /// their borrow position will still be sufficiently collateralized.
91    fn withdraw_collateral(&mut self, amount: CollateralAssetAmount) -> Promise;
92
93    /// Applies interest to the predecessor's borrow record.
94    /// Not likely to be used in real life, since there it does not affect the
95    /// final interest calculation, and rounds fractional interest UP.
96    fn apply_interest(&mut self, account_id: Option<AccountId>, snapshot_limit: Option<u32>);
97
98    // ================
99    // SUPPLY FUNCTIONS
100    // ================
101
102    // *_on_transfer where msg = Supply
103
104    /// Retrieves a set of supply positions.
105    fn list_supply_positions(
106        &self,
107        offset: Option<u32>,
108        count: Option<u32>,
109    ) -> HashMap<AccountId, SupplyPosition>;
110
111    /// Retrieves a supply position record, with estimated yield.
112    fn get_supply_position(&self, account_id: AccountId) -> Option<SupplyPosition>;
113
114    /// Enters a supply position into the withdrawal queue, requesting to
115    /// withdraw `amount` borrow asset tokens.
116    ///
117    /// If the account is already in the queue, it will be moved to the back
118    /// of the queue with the updated amount.
119    fn create_supply_withdrawal_request(&mut self, amount: BorrowAssetAmount);
120
121    /// Removes a supply position from the withdrawal queue.
122    fn cancel_supply_withdrawal_request(&mut self);
123
124    /// Attempts to fulfill the first withdrawal request in the queue.
125    fn execute_next_supply_withdrawal_request(
126        &mut self,
127        batch_limit: Option<u32>,
128    ) -> PromiseOrValue<WithdrawalQueueExecutionResult>;
129
130    /// Retrieves the status of a withdrawal request in the queue.
131    fn get_supply_withdrawal_request_status(
132        &self,
133        account_id: AccountId,
134    ) -> Option<WithdrawalRequestStatus>;
135
136    /// Retrieves the status of the withdrawal queue.
137    fn get_supply_withdrawal_queue_status(&self) -> WithdrawalQueueStatus;
138
139    /// Claim any distributed yield to the supply record.
140    /// If mode is set to [`HarvestYieldMode::Compounding`], the all of the
141    /// yield (including any harvested in previous, non-compounding
142    /// `harvest_yield` calls) will be deposited to the supply record, so it
143    /// can be withdrawn and will contribute to future yield calculations.
144    fn harvest_yield(
145        &mut self,
146        account_id: Option<AccountId>,
147        mode: Option<HarvestYieldMode>,
148    ) -> BorrowAssetAmount;
149
150    /// This value is an *expected average over time*.
151    /// Supply positions actually earn all of their yield the instant it is
152    /// distributed.
153    fn get_last_yield_rate(&self) -> Decimal;
154
155    // =====================
156    // LIQUIDATION FUNCTIONS
157    // =====================
158
159    // *_on_transfer where msg = Liquidate { account_id }
160
161    // =================
162    // YIELD FUNCTIONS
163    // =================
164
165    /// Retrieves the amount of yield earned by an account statically
166    /// configured to earn yield (e.g. [`MarketConfiguration::yield_weights`]
167    /// or [`MarketConfiguration::protocol_account_id`]).
168    fn get_static_yield(&self, account_id: AccountId) -> Option<Accumulator<BorrowAsset>>;
169
170    /// Accumulates yield for an account that earns static yield.
171    fn accumulate_static_yield(
172        &mut self,
173        account_id: Option<AccountId>,
174        snapshot_limit: Option<u32>,
175    );
176
177    /// Attempts to withdraw the amount of yield earned by an account
178    /// statically configured to earn yield (e.g.
179    /// [`MarketConfiguration::yield_weights`] or
180    /// [`MarketConfiguration::protocol_account_id`]).
181    ///
182    /// Calls to this function should be preceded by calls to
183    /// [`MarketExternalInterface::accumulate_static_yield`].
184    fn withdraw_static_yield(&mut self, amount: Option<BorrowAssetAmount>) -> Promise;
185}