af_iperps/lib.rs
1//! Move types for Aftermath's `Perpetuals` package
2
3use af_move_type::otw::Otw;
4use af_sui_pkg_sdk::sui_pkg_sdk;
5use af_sui_types::{Address, IdentStr, SUI_FRAMEWORK_ADDRESS};
6use af_utilities::types::ifixed::IFixed;
7use sui_framework_sdk::balance::Balance;
8use sui_framework_sdk::dynamic_object_field::Wrapper;
9use sui_framework_sdk::object::{ID, UID};
10use sui_framework_sdk::sui::SUI;
11use sui_framework_sdk::{Field, FieldTypeTag};
12
13pub mod errors;
14pub mod event_ext;
15pub mod event_instance;
16#[cfg(feature = "graphql")]
17pub mod graphql;
18pub mod math;
19pub mod order_helpers;
20pub mod order_id;
21#[cfg(feature = "stop-orders")]
22pub mod stop_order_helpers;
23
24pub use self::market::{MarketParams, MarketState};
25pub use self::orderbook::Order;
26pub use self::position::Position;
27
28// Convenient aliases since these types will never exist onchain with a type argument other than an
29// OTW.
30pub type AdminCapability = self::authority::Capability<self::authority::ADMIN>;
31pub type AssistantCapability = self::authority::Capability<self::authority::ASSISTANT>;
32pub type AdminAccountCap = self::account::AccountCap<self::account::ADMIN>;
33pub type AssistantAccountCap = self::account::AccountCap<self::account::ASSISTANT>;
34pub type Account = self::account::Account<Otw>;
35pub type AccountTypeTag = self::account::AccountTypeTag<Otw>;
36pub type StopOrderTicket = self::stop_orders::StopOrderTicket<Otw>;
37pub type StopOrderTicketTypetag = self::stop_orders::StopOrderTicketTypeTag<Otw>;
38pub type ClearingHouse = self::clearing_house::ClearingHouse<Otw>;
39pub type ClearingHouseTypeTag = self::clearing_house::ClearingHouseTypeTag<Otw>;
40pub type Vault = self::clearing_house::Vault<Otw>;
41pub type VaultTypeTag = self::clearing_house::VaultTypeTag<Otw>;
42pub type MarketInfo = self::registry::MarketInfo<Otw>;
43pub type CollateralInfo = self::registry::CollateralInfo<Otw>;
44
45/// Dynamic field storing a [`Vault`].
46pub type VaultDf = Field<keys::MarketVault, Vault>;
47/// Dynamic field storing a [`Position`].
48pub type PositionDf = Field<keys::Position, Position>;
49/// Dynamic field storing a leaf in a [`Map`] of [`Order`]s.
50///
51/// [`Map`]: self::ordered_map::Map
52pub type OrderLeafDf = Field<u64, ordered_map::Leaf<Order>>;
53/// Dynamic object field wrapper for the [`Orderbook`](orderbook::Orderbook) ID.
54pub type OrderbookDofWrapper = Field<Wrapper<keys::Orderbook>, ID>;
55/// Dynamic object field wrapper for the asks [`Map`](ordered_map::Map) ID.
56pub type AsksMapDofWrapper = Field<Wrapper<keys::AsksMap>, ID>;
57/// Dynamic object field wrapper for the bids [`Map`](ordered_map::Map) ID.
58pub type BidsMapDofWrapper = Field<Wrapper<keys::BidsMap>, ID>;
59/// Dynamic field storing a [`MarketInfo`].
60pub type MarketInfoDf = Field<keys::RegistryMarketInfo, MarketInfo>;
61/// Dynamic field storing a [`CollateralInfo`].
62pub type CollateralInfoDf = Field<keys::RegistryCollateralInfo<Otw>, CollateralInfo>;
63
64sui_pkg_sdk!(perpetuals {
65 module account {
66 /// Admin Role
67 struct ADMIN();
68
69 /// Assistant Role
70 struct ASSISTANT();
71
72 /// The AccountCap is used to check ownership of `Account` with the same `account_id`.
73 struct AccountCap<!phantom Role> has key, store {
74 id: UID,
75 // Account object id
76 account_obj_id: ID,
77 /// Numerical value associated to the account
78 account_id: u64,
79 }
80
81 /// The Account object saves the collateral available to be used in clearing houses.
82 struct Account<!phantom T> has key, store {
83 id: UID,
84 /// Numerical value associated to the account
85 account_id: u64,
86 /// Balance available to be allocated to markets.
87 collateral: Balance<T>,
88 /// Tracks the `ID`s of all `AccountCap<ASSISTANT>`s that have the authority
89 /// to interact with thie `Account`. Appended to in `new_assistant_account_cap`
90 /// and reduced in `revoke_assistant_account_cap`.
91 active_assistants: vector<ID>,
92 }
93
94 struct IntegratorConfig has store {
95 /// Max **additional** taker fee the user is willing
96 /// to pay for integrator-submitted orders.
97 max_taker_fee: IFixed
98 }
99 }
100
101 module authority {
102 /// Capability object required to perform admin functions.
103 ///
104 /// Minted once when the module is published and transfered to its creator.
105 struct Capability<!phantom Role> has key, store {
106 id: UID
107 }
108
109 /// Admin Role
110 struct ADMIN();
111
112 /// Assistant Role
113 struct ASSISTANT();
114 }
115
116 module clearing_house {
117 /// The central object that owns the market state.
118 ///
119 /// Dynamic fields:
120 /// - [`position::Position`]
121 /// - [`Vault`]
122 ///
123 /// Dynamic objects:
124 /// - [`orderbook::Orderbook`]
125 struct ClearingHouse<!phantom T> has key {
126 id: UID,
127 version: u64,
128 paused: bool,
129 market_params: market::MarketParams,
130 market_state: market::MarketState
131 }
132
133 /// Stores all deposits from traders for collateral T.
134 /// Stores the funds reserved for covering bad debt from untimely
135 /// liquidations.
136 ///
137 /// The Clearing House keeps track of who owns each share of the vault.
138 struct Vault<!phantom T> has store {
139 collateral_balance: Balance<T>,
140 insurance_fund_balance: Balance<T>,
141 }
142
143 /// Stores the proposed parameters for updating margin ratios
144 struct MarginRatioProposal has store {
145 /// Target timestamp at which to apply the proposed updates
146 maturity: u64,
147 /// Proposed IMR
148 margin_ratio_initial: IFixed,
149 /// Proposed MMR
150 margin_ratio_maintenance: IFixed,
151 }
152
153 /// Stores the proposed parameters for a position's custom fees
154 struct PositionFeesProposal has store {
155 /// Proposed IMR
156 maker_fee: IFixed,
157 /// Proposed MMR
158 taker_fee: IFixed,
159 }
160
161 /// Structure that stores the amount of fees collected by an integrator
162 struct IntegratorVault has store {
163 /// Amount of fees collected by this integrator, in collateral units
164 fees: IFixed,
165 }
166
167 struct IntegratorInfo has copy, drop {
168 integrator_address: address,
169 taker_fee: IFixed,
170 }
171
172 /// Stores the proposed parameters for a position's custom fees
173 struct SettlementPrices has store {
174 /// Base asset's settlement price
175 base_price: IFixed,
176 /// Collateral asset's settlement price
177 collateral_price: IFixed,
178 }
179 /// Used by clearing house to check margin when placing an order
180 struct SessionHotPotato<!phantom T> {
181 clearing_house: ClearingHouse<T>,
182 orderbook: orderbook::Orderbook,
183 account_id: u64,
184 timestamp_ms: u64,
185 collateral_price: IFixed,
186 index_price: IFixed,
187 gas_price: u64,
188 margin_before: IFixed,
189 min_margin_before: IFixed,
190 position_base_before: IFixed,
191 total_open_interest: IFixed,
192 total_fees: IFixed,
193 maker_events: vector<events::FilledMakerOrder>,
194 liqee_account_id: Option<u64>,
195 liquidator_fees: IFixed,
196 session_summary: SessionSummary
197 }
198
199 struct SessionSummary has drop {
200 base_filled_ask: IFixed,
201 base_filled_bid: IFixed,
202 quote_filled_ask: IFixed,
203 quote_filled_bid: IFixed,
204 base_posted_ask: IFixed,
205 base_posted_bid: IFixed,
206 posted_orders: u64,
207 base_liquidated: IFixed,
208 quote_liquidated: IFixed,
209 is_liqee_long: bool,
210 bad_debt: IFixed
211 }
212 }
213
214 module stop_orders {
215 /// Object that allows to place one order on behalf of the user, used to
216 /// offer stop limit or market orders. A stop order is an order that is placed
217 /// only if the index price respects certain conditions, like being above or
218 /// below a certain price.
219 ///
220 /// Only the `AccountCap` owner can mint this object and can decide who can be
221 /// the executor of the ticket. This allows users to run their
222 /// own stop orders bots eventually, but it's mainly used to allow 3rd parties
223 /// to offer such a service (the user is required to trust such 3rd party).
224 /// The object is shared and the 3rd party is set as `executors`. The ticket
225 /// can be destroyed in any moment only by the user or by the executor.
226 /// The user needs to trust the 3rd party for liveness of the service offered.
227 ///
228 /// The order details are encrypted offchain and the result is stored in the ticket.
229 /// The user needs to share such details with the 3rd party only to allow for execution.
230 ///
231 /// The ticket can be either a shared, owned or party object.
232 /// The permission to execute or cancel it is controlled exclusively through `executors`,
233 /// which can be modified only by the `AccountCap` owner associated with the ticket
234 /// using the function `edit_stop_order_ticket_executors`.
235 struct StopOrderTicket<!phantom T> has key, store {
236 id: UID,
237 /// Addresses allowed to execute the order on behalf of the user.
238 executors: vector<address>,
239 /// The executor collects the gas in case the order is placed or canceled for any reason.
240 /// The user gets back the gas in case he manually cancels the order.
241 gas: Balance<SUI>,
242 /// User account id
243 account_id: u64,
244 /// Value to indentify the stop order type. Available values can be found in the
245 /// constants module.
246 stop_order_type: u64,
247 /// Vector containing the blake2b hash obtained from offchain on the stop order parameters.
248 /// Depending on the stop order type value, a different set of parameters is expected to be used.
249 ///
250 /// Parameters encoded for a SLTP stop order (stop_order_type code 0):
251 /// - clearing_house_id: ID
252 /// - expire_timestamp: Option<u64>
253 /// - is_limit_order: `true` if limit order, `false` if market order
254 /// - stop_index_price: u256
255 /// - is_stop_loss: `true` if stop loss order, `false` if take profit order
256 /// - position_is_ask: `true` if position is short, `false` if position is long
257 /// - size: u64
258 /// - price: u64 (can be set at random value if `is_limit_order` is false)
259 /// - order_type: u64 (can be set at random value if `is_limit_order` is false)
260 /// - salt: vector<u8>
261 ///
262 /// Parameters encoded for a Standalone stop order (stop_order_type code 1):
263 /// - clearing_house_id: ID
264 /// - expire_timestamp: Option<u64>
265 /// - is_limit_order: `true` if limit order, `false` if market order
266 /// - stop_index_price: u256
267 /// - ge_stop_index_price: `true` means the order can be placed when
268 /// oracle index price is >= than chosen `stop_index_price`
269 /// - side: bool
270 /// - size: u64
271 /// - price: u64 (can be set at random value if `is_limit_order` is false)
272 /// - order_type: u64 (can be set at random value if `is_limit_order` is false)
273 /// - reduce_only: bool
274 /// - salt: vector<u8>
275 encrypted_details: vector<u8>
276 }
277 }
278
279 module events {
280 struct CreatedAccount<!phantom T> has copy, drop {
281 account_obj_id: ID,
282 user: address,
283 account_id: u64
284 }
285
286 struct DepositedCollateral<!phantom T> has copy, drop {
287 account_id: u64,
288 collateral: u64,
289 }
290
291 struct AllocatedCollateral has copy, drop {
292 ch_id: ID,
293 account_id: u64,
294 collateral: u64,
295 }
296
297 struct WithdrewCollateral<!phantom T> has copy, drop {
298 account_id: u64,
299 collateral: u64,
300 }
301
302 struct DeallocatedCollateral has copy, drop {
303 ch_id: ID,
304 account_id: u64,
305 collateral: u64,
306 }
307
308 struct CreatedOrderbook has copy, drop {
309 branch_min: u64,
310 branches_merge_max: u64,
311 branch_max: u64,
312 leaf_min: u64,
313 leaves_merge_max: u64,
314 leaf_max: u64
315 }
316
317 struct CreatedClearingHouse has copy, drop {
318 ch_id: ID,
319 collateral: String,
320 coin_decimals: u64,
321 margin_ratio_initial: IFixed,
322 margin_ratio_maintenance: IFixed,
323 base_oracle_id: ID,
324 collateral_oracle_id: ID,
325 funding_frequency_ms: u64,
326 funding_period_ms: u64,
327 premium_twap_frequency_ms: u64,
328 premium_twap_period_ms: u64,
329 spread_twap_frequency_ms: u64,
330 spread_twap_period_ms: u64,
331 maker_fee: IFixed,
332 taker_fee: IFixed,
333 liquidation_fee: IFixed,
334 force_cancel_fee: IFixed,
335 insurance_fund_fee: IFixed,
336 lot_size: u64,
337 tick_size: u64,
338 }
339
340 struct RegisteredMarketInfo<!phantom T> has copy, drop {
341 ch_id: ID,
342 base_pfs_id: ID,
343 base_pfs_source_id: ID,
344 collateral_pfs_id: ID,
345 collateral_pfs_source_id: ID,
346 scaling_factor: IFixed
347 }
348
349 struct RemovedRegisteredMarketInfo<!phantom T> has copy, drop {
350 ch_id: ID,
351 }
352
353 struct RegisteredCollateralInfo<!phantom T> has copy, drop {
354 ch_id: ID,
355 collateral_pfs_id: ID,
356 collateral_pfs_source_id: ID,
357 scaling_factor: IFixed
358 }
359
360 struct AddedIntegratorConfig<!phantom T> has copy, drop {
361 account_id: u64,
362 integrator_address: address,
363 max_taker_fee: IFixed
364 }
365
366 struct RemovedIntegratorConfig<!phantom T> has copy, drop {
367 account_id: u64,
368 integrator_address: address,
369 }
370
371 struct PaidIntegratorFees<!phantom T> has copy, drop {
372 account_id: u64,
373 integrator_address: address,
374 fees: IFixed
375 }
376
377 struct CreatedIntegratorVault has copy, drop {
378 ch_id: ID,
379 integrator_address: address,
380 }
381
382 struct WithdrewFromIntegratorVault has copy, drop {
383 ch_id: ID,
384 integrator_address: address,
385 fees: u64
386 }
387
388 struct UpdatedClearingHouseVersion has copy, drop {
389 ch_id: ID,
390 version: u64
391 }
392
393 struct PausedMarket has copy, drop {
394 ch_id: ID,
395 }
396
397 struct ResumedMarket has copy, drop {
398 ch_id: ID,
399 }
400
401 struct ClosedMarket has copy, drop {
402 ch_id: ID,
403 base_settlement_price: IFixed,
404 collateral_settlement_price: IFixed
405 }
406
407 struct ClosedPositionAtSettlementPrices has copy, drop {
408 ch_id: ID,
409 account_id: u64,
410 pnl: IFixed,
411 base_asset_amount: IFixed,
412 quote_asset_amount: IFixed,
413 deallocated_collateral: u64,
414 bad_debt: IFixed
415 }
416
417 struct UpdatedPremiumTwap has copy, drop {
418 ch_id: ID,
419 book_price: IFixed,
420 index_price: IFixed,
421 premium_twap: IFixed,
422 premium_twap_last_upd_ms: u64,
423 }
424
425 struct UpdatedSpreadTwap has copy, drop {
426 ch_id: ID,
427 book_price: IFixed,
428 index_price: IFixed,
429 spread_twap: IFixed,
430 spread_twap_last_upd_ms: u64,
431 }
432
433 struct UpdatedGasPriceTwap has copy, drop {
434 ch_id: ID,
435 gas_price: IFixed,
436 mean: IFixed,
437 variance: IFixed,
438 gas_price_last_upd_ms: u64
439 }
440
441 struct UpdatedGasPriceTwapParameters has copy, drop {
442 ch_id: ID,
443 gas_price_twap_period_ms: u64,
444 gas_price_taker_fee: IFixed,
445 z_score_threshold: IFixed
446 }
447
448 struct UpdatedMarketLotAndTick has copy, drop {
449 ch_id: ID,
450 lot_size: u64,
451 tick_size: u64
452 }
453
454 struct UpdatedFunding has copy, drop {
455 ch_id: ID,
456 cum_funding_rate_long: IFixed,
457 cum_funding_rate_short: IFixed,
458 funding_last_upd_ms: u64,
459 }
460
461 struct SettledFunding has copy, drop {
462 ch_id: ID,
463 account_id: u64,
464 collateral_change_usd: IFixed,
465 collateral_after: IFixed,
466 mkt_funding_rate_long: IFixed,
467 mkt_funding_rate_short: IFixed
468 }
469
470 struct FilledMakerOrders has copy, drop {
471 events: vector<FilledMakerOrder>
472 }
473
474 struct FilledMakerOrder has copy, drop {
475 ch_id: ID,
476 maker_account_id: u64,
477 taker_account_id: u64,
478 order_id: u128,
479 filled_size: u64,
480 remaining_size: u64,
481 canceled_size: u64,
482 pnl: IFixed,
483 fees: IFixed,
484 }
485
486 struct FilledTakerOrder has copy, drop {
487 ch_id: ID,
488 taker_account_id: u64,
489 taker_pnl: IFixed,
490 taker_fees: IFixed,
491 integrator_taker_fees: IFixed,
492 integrator_address: Option<address>,
493 base_asset_delta_ask: IFixed,
494 quote_asset_delta_ask: IFixed,
495 base_asset_delta_bid: IFixed,
496 quote_asset_delta_bid: IFixed,
497 }
498
499 struct PostedOrder has copy, drop {
500 ch_id: ID,
501 account_id: u64,
502 order_id: u128,
503 order_size: u64,
504 reduce_only: bool,
505 expiration_timestamp_ms: Option<u64>
506 }
507
508 struct CanceledOrder has copy, drop {
509 ch_id: ID,
510 account_id: u64,
511 size: u64,
512 order_id: u128,
513 }
514
515 struct LiquidatedPosition has copy, drop {
516 ch_id: ID,
517 liqee_account_id: u64,
518 liqor_account_id: u64,
519 is_liqee_long: bool,
520 base_liquidated: IFixed,
521 quote_liquidated: IFixed,
522 liqee_pnl: IFixed,
523 liquidation_fees: IFixed,
524 force_cancel_fees: IFixed,
525 insurance_fund_fees: IFixed,
526 bad_debt: IFixed
527 }
528
529 struct PerformedLiquidation has copy, drop {
530 ch_id: ID,
531 liqee_account_id: u64,
532 liqor_account_id: u64,
533 is_liqee_long: bool,
534 base_liquidated: IFixed,
535 quote_liquidated: IFixed,
536 liqor_pnl: IFixed,
537 liqor_fees: IFixed,
538 }
539
540 struct SocializedBadDebt has copy, drop {
541 ch_id: ID,
542 bad_debt_usd: IFixed,
543 socialized_fundings: IFixed,
544 added_to_long: bool,
545 cum_funding_rate_long: IFixed,
546 cum_funding_rate_short: IFixed,
547 }
548
549 struct PerformedADL has copy, drop {
550 ch_id: ID,
551 bad_debt_account_id: u64,
552 size_reduced: u64,
553 collateral_transferred: IFixed,
554 adl_price: u64,
555 counterparty_account_id: u64,
556 bad_debt_is_long: bool,
557 }
558
559 struct CreatedPosition has copy, drop {
560 ch_id: ID,
561 account_id: u64,
562 mkt_funding_rate_long: IFixed,
563 mkt_funding_rate_short: IFixed,
564 }
565
566 struct SetPositionInitialMarginRatio has copy, drop {
567 ch_id: ID,
568 account_id: u64,
569 initial_margin_ratio: IFixed,
570 }
571
572 struct CreatedStopOrderTicket<!phantom T> has copy, drop {
573 ticket_id: ID,
574 account_id: u64,
575 executors: vector<address>,
576 gas: u64,
577 stop_order_type: u64,
578 encrypted_details: vector<u8>
579 }
580
581 struct ExecutedStopOrderTicket<!phantom T> has copy, drop {
582 ticket_id: ID,
583 account_id: u64,
584 executor: address
585 }
586
587 struct DeletedStopOrderTicket<!phantom T> has copy, drop {
588 ticket_id: ID,
589 account_id: u64,
590 executor: address
591 }
592
593 struct EditedStopOrderTicketDetails<!phantom T> has copy, drop {
594 ticket_id: ID,
595 account_id: u64,
596 encrypted_details: vector<u8>
597 }
598
599 struct EditedStopOrderTicketExecutors<!phantom T> has copy, drop {
600 ticket_id: ID,
601 account_id: u64,
602 executors: vector<address>
603 }
604
605 struct CreatedMarginRatiosProposal has copy, drop {
606 ch_id: ID,
607 margin_ratio_initial: IFixed,
608 margin_ratio_maintenance: IFixed,
609 }
610
611 struct UpdatedMarginRatios has copy, drop {
612 ch_id: ID,
613 margin_ratio_initial: IFixed,
614 margin_ratio_maintenance: IFixed,
615 }
616
617 struct DeletedMarginRatiosProposal has copy, drop {
618 ch_id: ID,
619 margin_ratio_initial: IFixed,
620 margin_ratio_maintenance: IFixed,
621 }
622
623 struct CreatedPositionFeesProposal has copy, drop {
624 ch_id: ID,
625 account_id: u64,
626 maker_fee: IFixed,
627 taker_fee: IFixed,
628 }
629
630 struct DeletedPositionFeesProposal has copy, drop {
631 ch_id: ID,
632 account_id: u64,
633 maker_fee: IFixed,
634 taker_fee: IFixed,
635 }
636
637 struct AcceptedPositionFeesProposal has copy, drop {
638 ch_id: ID,
639 account_id: u64,
640 maker_fee: IFixed,
641 taker_fee: IFixed,
642 }
643
644 struct RejectedPositionFeesProposal has copy, drop {
645 ch_id: ID,
646 account_id: u64,
647 maker_fee: IFixed,
648 taker_fee: IFixed,
649 }
650
651 struct ResettedPositionFees has copy, drop {
652 ch_id: ID,
653 account_id: u64,
654 }
655
656 struct UpdatedFees has copy, drop {
657 ch_id: ID,
658 maker_fee: IFixed,
659 taker_fee: IFixed,
660 liquidation_fee: IFixed,
661 force_cancel_fee: IFixed,
662 insurance_fund_fee: IFixed,
663 }
664
665 struct UpdatedFundingParameters has copy, drop {
666 ch_id: ID,
667 funding_frequency_ms: u64,
668 funding_period_ms: u64,
669 premium_twap_frequency_ms: u64,
670 premium_twap_period_ms: u64,
671 }
672
673 struct UpdatedSpreadTwapParameters has copy, drop {
674 ch_id: ID,
675 spread_twap_frequency_ms: u64,
676 spread_twap_period_ms: u64
677 }
678
679 struct UpdatedMinOrderUsdValue has copy, drop {
680 ch_id: ID,
681 min_order_usd_value: IFixed,
682 }
683
684 struct UpdatedBasePfsID has copy, drop {
685 ch_id: ID,
686 pfs_id: ID,
687 }
688
689 struct UpdatedCollateralPfsID has copy, drop {
690 ch_id: ID,
691 pfs_id: ID,
692 }
693
694 struct UpdatedBasePfsSourceID has copy, drop {
695 ch_id: ID,
696 source_id: ID,
697 }
698
699 struct UpdatedCollateralPfsSourceID has copy, drop {
700 ch_id: ID,
701 source_id: ID,
702 }
703
704 struct UpdatedBasePfsTolerance has copy, drop {
705 ch_id: ID,
706 pfs_tolerance: u64,
707 }
708
709 struct UpdatedCollateralPfsTolerance has copy, drop {
710 ch_id: ID,
711 pfs_tolerance: u64,
712 }
713
714 struct UpdatedMaxSocializeLossesMrDecrease has copy, drop {
715 ch_id: ID,
716 max_socialize_losses_mr_decrease: IFixed,
717 }
718 struct UpdatedMaxBadDebt has copy, drop {
719 ch_id: ID,
720 max_bad_debt: IFixed,
721 }
722
723 struct UpdatedCollateralHaircut has copy, drop {
724 ch_id: ID,
725 collateral_haircut: IFixed,
726 }
727
728 struct UpdatedMaxOpenInterest has copy, drop {
729 ch_id: ID,
730 max_open_interest: IFixed,
731 }
732
733 struct UpdatedMaxOpenInterestPositionParams has copy, drop {
734 ch_id: ID,
735 max_open_interest_threshold: IFixed,
736 max_open_interest_position_percent: IFixed,
737 }
738
739 struct UpdatedMaxPendingOrders has copy, drop {
740 ch_id: ID,
741 max_pending_orders: u64
742 }
743
744 struct UpdatedStopOrderMistCost has copy, drop {
745 stop_order_mist_cost: u64
746 }
747
748 struct DonatedToInsuranceFund has copy, drop {
749 sender: address,
750 ch_id: ID,
751 new_balance: u64,
752 }
753
754 struct WithdrewFees has copy, drop {
755 sender: address,
756 ch_id: ID,
757 amount: u64,
758 vault_balance_after: u64,
759 }
760
761 struct WithdrewInsuranceFund has copy, drop {
762 sender: address,
763 ch_id: ID,
764 amount: u64,
765 insurance_fund_balance_after: u64,
766 }
767
768 struct UpdatedOpenInterestAndFeesAccrued has copy, drop {
769 ch_id: ID,
770 open_interest: IFixed,
771 fees_accrued: IFixed
772 }
773
774 struct CreatedAssistantAccountCap has copy, drop {
775 account_id: u64,
776 assistant_cap_id: ID,
777 }
778
779 struct RevokedAssistantAccountCap has copy, drop {
780 account_id: u64,
781 assistant_cap_id: ID,
782 }
783 }
784
785 module keys {
786 /// Key type for accessing a `MarketInfo` saved in registry.
787 struct RegistryMarketInfo has copy, drop, store {
788 ch_id: ID
789 }
790
791 /// Key type for accessing a `CollateralInfo` saved in registry.
792 struct RegistryCollateralInfo<!phantom T> has copy, drop, store {}
793
794 /// Key type for accessing a `Config` saved in registry.
795 struct RegistryConfig has copy, drop, store {}
796
797 /// Key type for accessing integrator configs for an account.
798 struct IntegratorConfig has copy, drop, store {
799 integrator_address: address,
800 }
801
802 /// Key type for accessing integrator's collected fees.
803 struct IntegratorVault has copy, drop, store {
804 integrator_address: address,
805 }
806
807 /// Key type for accessing in clearing house.
808 struct SettlementPrices has copy, drop, store {}
809
810 /// Key type for accessing market params in clearing house.
811 struct Orderbook has copy, drop, store {}
812
813 /// Key type for accessing vault in clearing house.
814 struct MarketVault has copy, drop, store {}
815
816 /// Key type for accessing trader position in clearing house.
817 struct Position has copy, drop, store {
818 account_id: u64,
819 }
820
821 /// Key type for accessing market margin parameters change proposal in clearing house.
822 struct MarginRatioProposal has copy, drop, store {}
823
824 /// Key type for accessing custom fees parameters change proposal for an account
825 struct PositionFeesProposal has copy, drop, store {
826 account_id: u64
827 }
828
829 /// Key type for accessing asks map in the orderbook
830 struct AsksMap has copy, drop, store {}
831
832 /// Key type for accessing asks map in the orderbook
833 struct BidsMap has copy, drop, store {}
834 }
835
836 module market {
837 /// Static attributes of a perpetuals market.
838 struct MarketParams has copy, drop, store {
839 /// Set of parameters governing market's core behaviors
840 core_params: CoreParams,
841 /// Set of parameters related to market's fees
842 fees_params: FeesParams,
843 /// Set of parameters governing fundings and twap updates
844 twap_params: TwapParams,
845 /// Set of parameters defining market's limits
846 limits_params: LimitsParams
847 }
848
849 struct CoreParams has copy, drop, store {
850 /// Identifier of the base asset's price feed storage.
851 base_pfs_id: ID,
852 /// Identifier of the collateral asset's price feed storage.
853 collateral_pfs_id: ID,
854 /// Identifier of the base asset's price feed storage source id (pyth, stork, etc...).
855 base_pfs_source_id: ID,
856 /// Identifier of the collateral asset's price feed storage source id (pyth, stork, etc...).
857 collateral_pfs_source_id: ID,
858 /// Timestamp tolerance for base oracle price
859 base_pfs_tolerance: u64,
860 /// Timestamp tolerance for collateral oracle price
861 collateral_pfs_tolerance: u64,
862 /// Number of base units exchanged per lot
863 lot_size: u64,
864 /// Number of quote units exchanged per tick
865 tick_size: u64,
866 /// Scaling factor to use to convert collateral units to ifixed values and viceversa
867 scaling_factor: IFixed,
868 /// Value haircut applied to collateral allocated in the position.
869 /// Example: 98%
870 collateral_haircut: IFixed,
871 /// Minimum margin ratio for opening a new position.
872 margin_ratio_initial: IFixed,
873 /// Margin ratio below which full liquidations can occur.
874 margin_ratio_maintenance: IFixed,
875 }
876
877 struct FeesParams has copy, drop, store {
878 /// Proportion of volume charged as fees from makers upon processing
879 /// fill events.
880 maker_fee: IFixed,
881 /// Proportion of volume charged as fees from takers after processing
882 /// fill events.
883 taker_fee: IFixed,
884 /// Proportion of volume charged as fees from liquidatees
885 liquidation_fee: IFixed,
886 /// Proportion of volume charged as fees from liquidatees after forced cancelling
887 /// of pending orders during liquidation.
888 force_cancel_fee: IFixed,
889 /// Proportion of volume charged as fees from liquidatees to deposit into insurance fund
890 insurance_fund_fee: IFixed,
891 /// Additional taker fee to apply in case the gas price set for the transaction violates
892 /// the z-score constraint
893 gas_price_taker_fee: IFixed,
894 }
895
896 struct TwapParams has copy, drop, store {
897 /// The time span between each funding rate update.
898 funding_frequency_ms: u64,
899 /// Period of time over which funding (the difference between book and
900 /// index prices) gets paid.
901 ///
902 /// Setting the funding period too long may cause the perpetual to start
903 /// trading at a very dislocated price to the index because there's less
904 /// of an incentive for basis arbitrageurs to push the prices back in
905 /// line since they would have to carry the basis risk for a longer
906 /// period of time.
907 ///
908 /// Setting the funding period too short may cause nobody to trade the
909 /// perpetual because there's too punitive of a price to pay in the case
910 /// the funding rate flips sign.
911 funding_period_ms: u64,
912 /// The time span between each funding TWAP (both index price and orderbook price) update.
913 premium_twap_frequency_ms: u64,
914 /// The reference time span used for weighting the TWAP (both index price and orderbook price)
915 /// updates for funding rates estimation
916 premium_twap_period_ms: u64,
917 /// The time span between each spread TWAP updates (used for liquidations).
918 spread_twap_frequency_ms: u64,
919 /// The reference time span used for weighting the TWAP updates for spread.
920 spread_twap_period_ms: u64,
921 /// The reference time span used for weighting the TWAP updates for gas price.
922 gas_price_twap_period_ms: u64,
923 }
924
925 struct LimitsParams has copy, drop, store {
926 /// Minimum USD value an order is required to be worth to be placed
927 min_order_usd_value: IFixed,
928 /// Maximum number of pending orders that a position can have.
929 max_pending_orders: u64,
930 /// Max open interest (in base tokens) available for this market
931 max_open_interest: IFixed,
932 /// The check on `max_open_interest_position_percent` is not performed if
933 /// the market's open interest is below this threshold.
934 max_open_interest_threshold: IFixed,
935 /// Max open interest percentage a position can have relative to total market's open interest
936 max_open_interest_position_percent: IFixed,
937 /// Max amount of bad debt that can be socialized in nominal value.
938 /// Positions that violate this check should be ADL'd.
939 max_bad_debt: IFixed,
940 /// Max amount of bad debt that can be socialized relative to total market's open interest.
941 /// Positions that violate this check should be ADL'd.
942 max_socialize_losses_mr_decrease: IFixed,
943 /// Z-Score threshold level used to determine if to apply `gas_price_taker_fee` to the
944 /// executed order
945 z_score_threshold: IFixed,
946 }
947 /// The state of a perpetuals market.
948 struct MarketState has store {
949 /// The latest cumulative funding premium in this market for longs. Must be updated
950 /// periodically.
951 cum_funding_rate_long: IFixed,
952 /// The latest cumulative funding premium in this market for shorts. Must be updated
953 /// periodically.
954 cum_funding_rate_short: IFixed,
955 /// The timestamp (millisec) of the latest cumulative funding premium update
956 /// (both longs and shorts).
957 funding_last_upd_ms: u64,
958 /// The last calculated funding premium TWAP (used for funding settlement).
959 premium_twap: IFixed,
960 /// The timestamp (millisec) of the last update of `premium_twap`.
961 premium_twap_last_upd_ms: u64,
962 /// The last calculated spread TWAP (used for liquidations).
963 /// Spread is (book - index).
964 spread_twap: IFixed,
965 /// The timestamp (millisec) of `spread_twap` last update.
966 spread_twap_last_upd_ms: u64,
967 /// Gas price TWAP mean.
968 /// It is used to calculate the penalty to add to taker fees based on the Z-score of the current gas price
969 /// relative to the smoothed mean and variance.
970 gas_price_mean: IFixed,
971 /// Gas price TWAP variance.
972 /// It is used to calculate the penalty to add to taker fees based on the Z-score of the current gas price
973 /// relative to the smoothed mean and variance.
974 gas_price_variance: IFixed,
975 /// The timestamp (millisec) of the last update of `gas_price_mean` and `gas_price_variance`.
976 gas_price_last_upd_ms: u64,
977 /// Open interest (in base tokens) as a fixed-point number. Counts the
978 /// total size of contracts as the sum of all long positions.
979 open_interest: IFixed,
980 /// Total amount of fees accrued by this market (in T's units)
981 /// Only admin can withdraw these fees.
982 fees_accrued: IFixed,
983 }
984 }
985
986 module orderbook {
987 /// An order on the orderbook
988 struct Order has copy, drop, store {
989 /// User's account id
990 account_id: u64,
991 /// Amount of lots to be filled
992 size: u64,
993 /// Optional reduce-only requirement for this order.
994 reduce_only: bool,
995 /// Optional expiration time for the order
996 expiration_timestamp_ms: Option<u64>
997 }
998
999 /// The orderbook doesn't know the types of tokens traded, it assumes a correct
1000 /// management by the clearing house
1001 struct Orderbook has key, store {
1002 id: UID,
1003 /// Number of limit orders placed on book, monotonically increases
1004 counter: u64,
1005 }
1006 }
1007
1008 module ordered_map {
1009 /// Ordered map with `u128` type as a key and `V` type as a value.
1010 struct Map<!phantom V: copy + drop + store> has key, store {
1011 /// Object UID for adding dynamic fields that are used as pointers to nodes.
1012 id: UID,
1013 /// Number of key-value pairs in the map.
1014 size: u64,
1015 /// Counter for creating another node as a dynamic field.
1016 counter: u64,
1017 /// Pointer to the root node, which is a branch or a leaf.
1018 root: u64,
1019 /// Pointer to first leaf.
1020 first: u64,
1021 /// Minimal number of kids in a non-root branch;
1022 /// must satisfy 2 <= branch_min <= branch_max / 2.
1023 branch_min: u64,
1024 /// Maximal number of kids in a branch, which is merge of two branches;
1025 /// must satisfy 2 * branch_min <= branches_merge_max <= branch_max.
1026 branches_merge_max: u64,
1027 /// Maximal number of kids in a branch.
1028 branch_max: u64,
1029 /// Minimal number of elements in a non-root leaf;
1030 /// must satisfy 2 <= leaf_min <= (leaf_max + 1) / 2.
1031 leaf_min: u64,
1032 /// Maximal number of elements in a leaf, which is merge of two leaves;
1033 /// must satisfy 2 * leaf_min - 1 <= leaves_merge_max <= leaf_max.
1034 leaves_merge_max: u64,
1035 /// Maximal number of elements in a leaf.
1036 leaf_max: u64,
1037 }
1038
1039 /// Branch node with kids and ordered separating keys.
1040 struct Branch has drop, store {
1041 /// Separating keys for kids sorted in ascending order.
1042 keys: vector<u128>,
1043 /// Kids of the node.
1044 kids: vector<u64>,
1045 }
1046
1047 /// Key-value pair.
1048 struct Pair<V: copy + drop + store> has copy, drop, store {
1049 key: u128,
1050 val: V,
1051 }
1052
1053 /// Leaf node with ordered key-value pairs.
1054 struct Leaf<V: copy + drop + store> has drop, store {
1055 /// Keys sorted in ascending order together with values.
1056 keys_vals: vector<Pair<V>>,
1057 /// Pointer to next leaf.
1058 next: u64,
1059 }
1060 }
1061
1062 module position {
1063 /// Stores information about an open position
1064 struct Position has store {
1065 /// Amount of allocated tokens (e.g., USD stables) backing this account's position.
1066 collateral: IFixed,
1067 /// The perpetual contract size, controlling the amount of exposure to
1068 /// the underlying asset. Positive implies long position and negative,
1069 /// short. Represented as a signed fixed-point number.
1070 base_asset_amount: IFixed,
1071 /// The entry value for this position, including leverage. Represented
1072 /// as a signed fixed-point number.
1073 quote_asset_notional_amount: IFixed,
1074 /// Last long cumulative funding rate used to update this position. The
1075 /// market's latest long cumulative funding rate minus this gives the funding
1076 /// rate this position must pay. This rate multiplied by this position's
1077 /// value (base asset amount * market price) gives the total funding
1078 /// owed, which is deducted from the trader account's margin. This debt
1079 /// is accounted for in margin ratio calculations, which may lead to
1080 /// liquidation. Represented as a signed fixed-point number.
1081 cum_funding_rate_long: IFixed,
1082 /// Last short cumulative funding rate used to update this position. The
1083 /// market's latest short cumulative funding rate minus this gives the funding
1084 /// rate this position must pay. This rate multiplied by this position's
1085 /// value (base asset amount * market price) gives the total funding
1086 /// owed, which is deducted from the trader account's margin. This debt
1087 /// is accounted for in margin ratio calculations, which may lead to
1088 /// liquidation. Represented as a signed fixed-point number.
1089 cum_funding_rate_short: IFixed,
1090 /// Base asset amount resting in ask orders in the orderbook.
1091 /// Represented as a signed fixed-point number.
1092 asks_quantity: IFixed,
1093 /// Base asset amount resting in bid orders in the orderbook.
1094 /// Represented as a signed fixed-point number.
1095 bids_quantity: IFixed,
1096 /// Number of pending orders in this position.
1097 pending_orders: u64,
1098 /// Custom maker fee for this position, set at default value of 100%
1099 maker_fee: IFixed,
1100 /// Custom taker fee for this position, set at default value of 100%
1101 taker_fee: IFixed,
1102 /// Initial Margin Ratio set by user for the position. Must always be less
1103 /// or equal than market's IMR. Used as a desired reference margin ratio when
1104 /// managing collateral in the position during all the actions. Can be changed
1105 /// by the user at any moment (between the allowed limits).
1106 initial_margin_ratio: IFixed
1107 }
1108 }
1109
1110 module registry {
1111 /// Registry object that maintains:
1112 /// - A mapping between a clearing house id and `MarketInfo`
1113 /// - A mapping between a collateral type `T` and `CollateralInfo`
1114 /// It also maintains the global counter for account creation.
1115 /// Minted and shared when the module is published.
1116 struct Registry has key {
1117 id: UID,
1118 next_account_id: u64
1119 }
1120
1121 /// Struct containing all the immutable info about a registered market
1122 struct MarketInfo<!phantom T> has store {
1123 base_pfs_id: ID,
1124 base_pfs_source_id: ID,
1125 collateral_pfs_id: ID,
1126 collateral_pfs_source_id: ID,
1127 scaling_factor: IFixed
1128 }
1129
1130 /// Struct containing all the immutable info about the collateral
1131 /// used in one or more markets
1132 struct CollateralInfo<!phantom T> has store {
1133 collateral_pfs_id: ID,
1134 collateral_pfs_source_id: ID,
1135 scaling_factor: IFixed
1136 }
1137
1138 /// Config that stores useful info for the protocol
1139 struct Config has store {
1140 stop_order_mist_cost: u64,
1141 }
1142 }
1143});
1144
1145impl<T: af_move_type::MoveType> clearing_house::ClearingHouse<T> {
1146 /// Convenience function to build the type of a [`PositionDf`].
1147 pub fn position_df_type(package: Address) -> FieldTypeTag<self::keys::Position, Position> {
1148 Field::type_(
1149 self::keys::Position::type_(package),
1150 Position::type_(package),
1151 )
1152 }
1153
1154 /// Convenience function to build the type of an [`OrderbookDofWrapper`].
1155 pub fn orderbook_dof_wrapper_type(
1156 package: Address,
1157 ) -> FieldTypeTag<Wrapper<keys::Orderbook>, ID> {
1158 Field::type_(
1159 Wrapper::type_(keys::Orderbook::type_(package)),
1160 ID::type_(SUI_FRAMEWORK_ADDRESS, IdentStr::cast("object").to_owned()),
1161 )
1162 }
1163}
1164
1165impl self::orderbook::Orderbook {
1166 /// Convenience function to build the type of an [`AsksMapDofWrapper`].
1167 pub fn asks_dof_wrapper_type(package: Address) -> FieldTypeTag<Wrapper<keys::AsksMap>, ID> {
1168 Field::type_(
1169 Wrapper::type_(keys::AsksMap::type_(package)),
1170 ID::type_(SUI_FRAMEWORK_ADDRESS, IdentStr::cast("object").to_owned()),
1171 )
1172 }
1173
1174 /// Convenience function to build the type of an [`BidsMapDofWrapper`].
1175 pub fn bids_dof_wrapper_type(package: Address) -> FieldTypeTag<Wrapper<keys::BidsMap>, ID> {
1176 Field::type_(
1177 Wrapper::type_(keys::BidsMap::type_(package)),
1178 ID::type_(SUI_FRAMEWORK_ADDRESS, IdentStr::cast("object").to_owned()),
1179 )
1180 }
1181}
1182
1183impl self::ordered_map::Map<Order> {
1184 /// Convenience function to build the type of an [`OrderLeafDf`].
1185 pub fn leaf_df_type(package: Address) -> FieldTypeTag<u64, self::ordered_map::Leaf<Order>> {
1186 Field::type_(
1187 af_move_type::U64TypeTag,
1188 self::ordered_map::Leaf::type_(package, Order::type_(package)),
1189 )
1190 }
1191}