af_iperps/
lib.rs

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