Skip to main content

af_iperps/
lib.rs

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