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