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