vortex_common/
msg.rs

1use std::collections::HashSet;
2
3use crate::{
4    error::ContractError,
5    types::{
6        i32_to_direction, i32_to_order_type, MarginRatios, Order, OrderType, PositionDirection,
7        PositionEffect,
8    },
9    utils::SignedDecimal,
10};
11use cosmwasm_std::{Addr, Coin, Decimal};
12use cw20::Cw20ReceiveMsg;
13use schemars::JsonSchema;
14use serde::{Deserialize, Serialize};
15
16#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
17pub struct MigrateMsg {}
18
19#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
20pub struct InstantiateMsg {
21    pub whitelist: Vec<String>,
22    pub denoms: Vec<String>,
23    pub supported_collateral_denoms: Vec<String>,
24    pub supported_multicollateral_denoms: Vec<String>,
25    pub full_denom_mapping: Vec<(String, String, Decimal)>,
26    pub oracle_denom_mapping: Vec<(String, String, Decimal)>,
27    pub use_whitelist: bool,
28    pub multicollateral_whitelist: Vec<Addr>,
29    pub multicollateral_whitelist_enable: bool,
30    pub admin: String,
31    pub limit_order_fee: SignedDecimal,
32    pub market_order_fee: SignedDecimal,
33    pub liquidation_order_fee: SignedDecimal,
34    pub max_leverage: SignedDecimal,
35    pub funding_payment_lookback: u64,
36    pub native_token: String,
37    pub default_base: String,
38    pub spot_market_contract: Addr,
39    pub funding_payment_pairs: Vec<(String, String)>,
40    pub default_margin_ratios: MarginRatios,
41}
42
43#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
44#[serde(rename_all = "snake_case")]
45pub enum ExecuteMsg {
46    Receive(Cw20ReceiveMsg),
47    Deposit {},
48    Withdraw {
49        coins: Vec<Coin>,
50    },
51    WithdrawInsuranceFund {
52        coin: Coin,
53    },
54    SwapMulticollateralToBase {
55        orders: Vec<OrderPlacement>,
56    },
57    UseWhitelist(bool),
58    AddToCW20DenomMapping {
59        address: String,
60        denom: String,
61    },
62    AddToFullDenomMapping {
63        full_denom: String,
64        internal_denom: String,
65        conversion_rate: Decimal,
66    },
67    AddToOracleDenomMapping {
68        oracle_denom: String,
69        internal_denom: String,
70        conversion_rate: Decimal,
71    },
72    AddToWhitelist {
73        converter: String,
74    },
75    AddToSupportedMultiCollateralDenoms {
76        denom: String,
77    },
78    AddToFundingPaymentPairs {
79        price_denom: String,
80        asset_denom: String,
81    },
82    RemoveFromWhitelist {
83        converter: String,
84    },
85    AddDenom {
86        denom: String,
87    },
88    RemoveDenom {
89        denom: String,
90    },
91    UpdateMarginRatio {
92        margin_ratio: MarginRatios,
93    },
94    UpdateMaxLeverage {
95        max_leverage: SignedDecimal,
96    },
97    UpdateMarketOrderFee {
98        market_order_fee: SignedDecimal,
99    },
100    UpdateLimitOrderFee {
101        limit_order_fee: SignedDecimal,
102    },
103    UpdateLiquidationOrderFee {
104        liquidation_order_fee: SignedDecimal,
105    },
106    UpdateAdmin {
107        admin: String,
108    },
109    UpdateFundingPaymentLookback {
110        funding_payment_lookback: u64,
111    },
112    UpdateNativeToken {
113        native_token: String,
114    },
115    UpdateBase {
116        default_base: String,
117    },
118    UpdateSpotMarketContract {
119        contract_addr: String,
120    },
121    UpdateMultiCollateralWhitelist {
122        whitelist: Vec<Addr>,
123        whitelist_enable: bool,
124    },
125    Liquidate {
126        account: Addr,
127        multicollateral_liquidation: bool,
128    },
129    CreateDenom {
130        denom_name: String,
131    },
132    MintDenom {
133        denom_name: String,
134        denom_amount: u128,
135    },
136}
137
138#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
139pub struct DecimalCoin {
140    pub denom: String,
141    pub amount: Decimal,
142}
143
144#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
145#[serde(rename_all = "snake_case")]
146pub enum SudoMsg {
147    Settlement {
148        epoch: i64,
149        entries: Vec<SettlementEntry>,
150    },
151
152    NewBlock {
153        epoch: i64,
154    },
155
156    BulkOrderPlacements {
157        orders: Vec<OrderPlacement>,
158        deposits: Vec<DepositInfo>,
159    },
160
161    BulkOrderCancellations {
162        ids: Vec<u64>,
163    },
164
165    Liquidation {
166        requests: Vec<LiquidationRequest>,
167    },
168
169    FinalizeBlock {
170        contract_order_results: Vec<ContractOrderResult>,
171    },
172}
173
174#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
175#[serde(rename_all = "snake_case")]
176pub enum QueryMsg {
177    GetBalance {
178        account: String,
179        symbol: String,
180    },
181
182    GetBalances {
183        account: String,
184    },
185
186    GetCumulativeFundingPaymentRate {
187        price_denom: String,
188        asset_denom: String,
189    },
190
191    GetPosition {
192        account: String,
193        price_denom: String,
194        asset_denom: String,
195    },
196
197    GetOrder {
198        account: String,
199        price_denom: String,
200        asset_denom: String,
201    },
202
203    GetPortfolioSpecs {
204        account: String,
205    },
206
207    GetInsuranceFundBalance {
208        denom: String,
209    },
210
211    GetOrderEstimate {
212        order: Order,
213    },
214
215    GetConfig {},
216}
217
218#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
219pub struct GetBalanceResponse {
220    pub amount: SignedDecimal,
221}
222
223#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
224pub struct GetBalancesResponse {
225    pub symbols: Vec<String>,
226    pub amounts: Vec<SignedDecimal>,
227}
228
229#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
230pub struct GetPositionResponse {
231    pub long_position: SignedDecimal,
232    pub long_position_margin_debt: SignedDecimal,
233    pub long_position_last_funding_payment_epoch: i64,
234    pub long_position_pnl: SignedDecimal,
235    pub short_position: SignedDecimal,
236    pub short_position_margin_debt: SignedDecimal,
237    pub short_position_last_funding_payment_epoch: i64,
238    pub short_position_pnl: SignedDecimal,
239}
240
241#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
242pub struct GetPortfolioSpecsResponse {
243    pub equity: SignedDecimal,
244    pub total_position_value: SignedDecimal,
245    pub buying_power: SignedDecimal,
246    pub unrealized_pnl: SignedDecimal,
247    pub leverage: SignedDecimal,
248    pub balance: SignedDecimal,
249}
250
251#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
252pub struct GetInsuranceFundBalanceResponse {
253    pub balance: SignedDecimal,
254}
255
256#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
257pub struct GetOrderResponse {
258    pub orders: Vec<Order>,
259}
260
261#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
262pub struct GetCumulativeFundingRateResponse {
263    pub price_diff: SignedDecimal,
264}
265
266#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
267pub struct GetOrderEstimateResponse {
268    pub order_fee_estimate: SignedDecimal,
269    pub deposits_required: Coin,
270}
271
272#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
273pub struct GetConfigResponse {
274    pub admin: String,
275    pub whitelist: HashSet<Addr>,
276    pub use_whitelist: bool,
277    pub limit_order_fee: SignedDecimal,
278    pub market_order_fee: SignedDecimal,
279    pub liquidation_order_fee: SignedDecimal,
280    pub default_margin_ratios: MarginRatios,
281    pub max_leverage: SignedDecimal,
282    pub spot_market_contract: String,
283}
284
285#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
286pub struct BulkOrderPlacementsResponse {
287    pub unsuccessful_orders: Vec<UnsuccessfulOrder>,
288}
289
290#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
291pub struct UnsuccessfulOrder {
292    pub id: u64,
293    pub reason: String,
294}
295
296#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema)]
297pub struct LiquidationResponse {
298    pub successful_accounts: Vec<String>,
299    pub liquidation_orders: Vec<OrderPlacement>,
300}
301
302#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
303pub struct SettlementEntry {
304    pub account: String,
305    pub price_denom: String,
306    pub asset_denom: String,
307    pub quantity: Decimal,
308    pub execution_cost_or_proceed: Decimal,
309    pub expected_cost_or_proceed: Decimal,
310    pub position_direction: PositionDirection,
311    pub order_type: OrderType,
312    pub order_id: u64,
313}
314
315#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
316pub struct OrderPlacement {
317    pub id: u64,
318    pub status: i32,
319    pub account: String,
320    pub contract_address: String,
321    pub price_denom: String,
322    pub asset_denom: String,
323    pub price: Decimal,
324    pub quantity: Decimal,
325    pub order_type: i32,
326    pub position_direction: i32,
327    pub data: String,
328    pub status_description: String,
329}
330
331#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
332pub struct OrderData {
333    pub leverage: Decimal,
334    pub position_effect: PositionEffect,
335}
336
337impl OrderPlacement {
338    pub fn to_order(&self) -> Result<Order, ContractError> {
339        let order_data: OrderData = match serde_json_wasm::from_str(&self.data) {
340            Ok(data) => data,
341            Err(_) => return Result::Err(ContractError::InvalidOrderData {}),
342        };
343        let order = Order {
344            id: self.id,
345            account: self.account.to_owned(),
346            price_denom: self.price_denom.to_owned(),
347            asset_denom: self.asset_denom.to_owned(),
348            price: SignedDecimal::new(self.price),
349            quantity: SignedDecimal::new(self.quantity),
350            remaining_quantity: SignedDecimal::new(self.quantity),
351            direction: i32_to_direction(self.position_direction),
352            order_type: i32_to_order_type(self.order_type),
353            effect: order_data.position_effect,
354            leverage: SignedDecimal::new(order_data.leverage),
355        };
356        Result::Ok(order)
357    }
358}
359
360#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
361pub struct DepositInfo {
362    pub account: String,
363    pub denom: String,
364    pub amount: Decimal,
365}
366
367#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
368pub struct LiquidationRequest {
369    pub requestor: String,
370    pub account: String,
371}
372
373#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
374pub struct ContractOrderResult {
375    pub contract_address: String,
376    pub order_placement_results: Vec<OrderPlacementResult>,
377    pub order_execution_results: Vec<OrderExecutionResult>,
378}
379
380#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
381pub struct OrderPlacementResult {
382    pub order_id: u64,
383    pub status_code: i32,
384}
385
386#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
387pub struct OrderExecutionResult {
388    pub order_id: u64,
389    pub execution_price: Decimal,
390    pub executed_quantity: Decimal,
391    pub total_notional: Decimal,
392    pub position_direction: String,
393}