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