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