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}