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}