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}