1#![doc = include_str!("../README.md")]
2
3mod types;
4mod util;
5use anchor_lang::prelude::*;
6use solana_program::pubkey;
7
8pub mod dex;
9pub mod events;
10pub use crate::types::*;
11pub use crate::util::*;
12
13#[cfg(feature = "devnet")]
14declare_id!("Zo1ThtSHMh9tZGECwBDL81WJRL6s3QTHf733Tyko7KQ");
15
16#[cfg(not(feature = "devnet"))]
17declare_id!("Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk");
18
19pub static ZO_DEX_PID: Pubkey = match cfg!(feature = "devnet") {
20 true => pubkey!("ZDxUi178LkcuwdxcEqsSo2E7KATH99LAAXN5LcSVMBC"),
21 false => pubkey!("ZDx8a8jBqGmJyxi1whFxxCo5vG6Q9t4hTzW2GSixMKK"),
22};
23
24pub static SERUM_DEX_PID: Pubkey = match cfg!(feature = "devnet") {
25 true => pubkey!("DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY"),
26 false => pubkey!("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"),
27};
28
29pub static ZO_STATE_ID: Pubkey = match cfg!(feature = "devnet") {
30 true => pubkey!("KwcWW7WvgSXLJcyjKZJBHLbfriErggzYHpjS9qjVD5F"),
31 false => pubkey!("71yykwxq1zQqy99PgRsgZJXi2HHK2UDx9G4va7pH6qRv"),
32};
33
34pub static ZO_HEIMDALL_ID: Pubkey = match cfg!(feature = "devnet") {
35 true => pubkey!("Aoi3SGj4zLiMQSHrJ4yEDFwMQnGjVQCeKSYD6ygi6WLr"),
36 false => pubkey!("Cyvjas5Hg6nb6RNsuCi8sK3kcjbWzTgdJcHxmSYS8mkY"),
37};
38
39#[program]
40mod zo_abi {
41 #![allow(dead_code)]
42 #![allow(unused_variables)]
43 #![allow(clippy::too_many_arguments)]
44
45 use super::*;
46
47 pub(crate) fn create_margin(
50 cx: Context<CreateMargin>,
51 margin_nonce: u8,
52 ) -> Result<()> {
53 Ok(())
54 }
55
56 pub(crate) fn deposit(
57 cx: Context<Deposit>,
58 repay_only: bool,
59 amount: u64,
60 ) -> Result<()> {
61 Ok(())
62 }
63
64 pub(crate) fn withdraw(
65 cx: Context<Withdraw>,
66 allow_borrow: bool,
67 amount: u64,
68 ) -> Result<()> {
69 Ok(())
70 }
71
72 pub(crate) fn create_perp_open_orders(
76 cx: Context<CreatePerpOpenOrders>,
77 ) -> Result<()> {
78 Ok(())
79 }
80
81 pub(crate) fn place_perp_order(
83 cx: Context<PlacePerpOrder>,
84 is_long: bool,
85 limit_price: u64,
86 max_base_quantity: u64,
87 max_quote_quantity: u64,
88 order_type: OrderType,
89 limit: u16,
90 client_id: u64,
91 ) -> Result<()> {
92 Ok(())
93 }
94
95 pub(crate) fn place_perp_order_with_max_ts(
98 cx: Context<PlacePerpOrder>,
99 is_long: bool,
100 limit_price: u64,
101 max_base_quantity: u64,
102 max_quote_quantity: u64,
103 order_type: OrderType,
104 limit: u16,
105 client_id: u64,
106 max_ts: i64,
107 ) -> Result<()> {
108 Ok(())
109 }
110
111 pub(crate) fn place_perp_order_lite(
114 cx: Context<PlacePerpOrder>,
115 is_long: bool,
116 limit_price: u64,
117 max_base_quantity: u64,
118 max_quote_quantity: u64,
119 order_type: OrderType,
120 limit: u16,
121 client_id: u64,
122 ) -> Result<()> {
123 Ok(())
124 }
125
126 pub(crate) fn cancel_perp_order(
128 cx: Context<CancelPerpOrder>,
129 order_id: Option<u128>,
130 is_long: Option<bool>,
131 client_id: Option<u64>,
132 ) -> Result<()> {
133 Ok(())
134 }
135
136 pub(crate) fn cancel_all_perp_orders(
138 cx: Context<CancelAllPerpOrders>,
139 limit: u16,
140 ) -> Result<()> {
141 Ok(())
142 }
143
144 pub(crate) fn settle_funds(cx: Context<SettleFunds>) -> Result<()> {
146 Ok(())
147 }
148
149 pub(crate) fn swap(
156 cx: Context<Swap>,
157 buy: bool,
158 allow_borrow: bool, amount: u64, min_rate: u64, ) -> Result<()> {
162 Ok(())
163 }
164
165 pub(crate) fn update_perp_funding(
168 cx: Context<UpdatePerpFunding>,
169 ) -> Result<()> {
170 Ok(())
171 }
172
173 pub(crate) fn cache_oracle(
174 cx: Context<CacheOracle>,
175 symbols: Vec<String>,
176 mock_prices: Option<Vec<Option<u64>>>,
177 ) -> Result<()> {
178 Ok(())
179 }
180
181 pub(crate) fn cache_interest_rates(
182 cx: Context<CacheInterestRates>,
183 start: u8,
184 end: u8,
185 ) -> Result<()> {
186 Ok(())
187 }
188
189 pub(crate) fn consume_events(
190 cx: Context<ConsumeEvents>,
191 limit: u16,
192 ) -> Result<()> {
193 Ok(())
194 }
195
196 pub(crate) fn crank_pnl(cx: Context<CrankPnl>) -> Result<()> {
197 Ok(())
198 }
199
200 pub(crate) fn force_cancel_all_perp_orders(
204 cx: Context<ForceCancelAllPerpOrders>,
205 limit: u16,
206 ) -> Result<()> {
207 Ok(())
208 }
209
210 pub(crate) fn liquidate_perp_position(
212 cx: Context<LiquidatePerpPosition>,
213 asset_transfer_lots: u64,
214 ) -> Result<()> {
215 Ok(())
216 }
217
218 pub(crate) fn liquidate_spot_position(
220 cx: Context<LiquidateSpotPosition>,
221 asset_transfer_amount: i64,
222 ) -> Result<()> {
223 Ok(())
224 }
225
226 pub(crate) fn settle_bankruptcy(
228 cx: Context<SettleBankruptcy>,
229 ) -> Result<()> {
230 Ok(())
231 }
232
233 pub fn create_special_orders_account(
236 cx: Context<CreateSpecialOrdersAccount>,
237 ) -> Result<()> {
238 Ok(())
239 }
240
241 pub(crate) fn place_special_order(
242 cx: Context<PlaceSpecialOrder>,
243 is_long: bool,
244 special_order_type: SpecialOrderType,
245 trigger_price: u64,
246 limit_price: u64,
247 size: u64,
248 ) -> Result<()> {
249 Ok(())
250 }
251
252 pub(crate) fn cancel_special_order(
253 cx: Context<CancelSpecialOrder>,
254 id: u16,
255 ) -> Result<()> {
256 Ok(())
257 }
258
259 pub(crate) fn execute_special_order(
260 cx: Context<ExecuteSpecialOrder>,
261 id: u16,
262 ) -> Result<()> {
263 Ok(())
264 }
265}
266
267#[derive(Accounts)]
268struct SettleFunds<'info> {
269 pub authority: Signer<'info>,
270 pub state: AccountLoader<'info, State>,
271 #[account(mut)]
272 pub state_signer: UncheckedAccount<'info>,
273 #[account(mut)]
274 pub cache: AccountLoader<'info, Cache>,
275 #[account(mut)]
276 pub margin: AccountLoader<'info, Margin>,
277 #[account(mut)]
278 pub control: AccountLoader<'info, Control>,
279 #[account(mut)]
280 pub open_orders: UncheckedAccount<'info>,
281 #[account(mut)]
282 pub dex_market: UncheckedAccount<'info>,
283 pub dex_program: UncheckedAccount<'info>,
284}
285
286#[derive(Accounts)]
287struct CancelPerpOrder<'info> {
288 pub state: AccountLoader<'info, State>,
289 #[account(mut)]
290 pub cache: AccountLoader<'info, Cache>,
291 pub authority: Signer<'info>,
292 #[account(mut)]
293 pub margin: AccountLoader<'info, Margin>,
294 #[account(mut)]
295 pub control: AccountLoader<'info, Control>,
296 #[account(mut)]
297 pub open_orders: UncheckedAccount<'info>,
298 #[account(mut)]
299 pub dex_market: UncheckedAccount<'info>,
300 #[account(mut)]
301 pub market_bids: UncheckedAccount<'info>,
302 #[account(mut)]
303 pub market_asks: UncheckedAccount<'info>,
304 #[account(mut)]
305 pub event_q: UncheckedAccount<'info>,
306 pub dex_program: UncheckedAccount<'info>,
307}
308
309#[derive(Accounts)]
310struct CancelAllPerpOrders<'info> {
311 pub authority: Signer<'info>,
312 pub state: AccountLoader<'info, State>,
313 #[account(mut)]
314 pub cache: AccountLoader<'info, Cache>,
315 #[account(mut)]
316 pub state_signer: UncheckedAccount<'info>,
317 #[account(mut)]
318 pub margin: AccountLoader<'info, Margin>,
319 #[account(mut)]
320 pub control: AccountLoader<'info, Control>,
321 #[account(mut)]
322 pub open_orders: UncheckedAccount<'info>,
323 #[account(mut)]
324 pub dex_market: UncheckedAccount<'info>,
325 #[account(mut)]
326 pub req_q: UncheckedAccount<'info>,
327 #[account(mut)]
328 pub event_q: UncheckedAccount<'info>,
329 #[account(mut)]
330 pub market_bids: UncheckedAccount<'info>,
331 #[account(mut)]
332 pub market_asks: UncheckedAccount<'info>,
333 pub dex_program: UncheckedAccount<'info>,
334}
335
336#[derive(Accounts)]
337struct CreatePerpOpenOrders<'info> {
338 pub state: AccountLoader<'info, State>,
339 #[account(mut)]
340 pub state_signer: UncheckedAccount<'info>,
341 pub authority: Signer<'info>,
342 #[account(mut)]
344 pub payer: Signer<'info>,
345 #[account(mut)]
346 pub margin: AccountLoader<'info, Margin>,
347 #[account(mut)]
348 pub control: AccountLoader<'info, Control>,
349 #[account(mut)]
350 pub open_orders: UncheckedAccount<'info>,
351 #[account(mut)]
352 pub dex_market: UncheckedAccount<'info>,
353 pub dex_program: UncheckedAccount<'info>,
354 pub rent: Sysvar<'info, Rent>,
355 pub system_program: Program<'info, System>,
356}
357
358#[derive(Accounts)]
359struct CreateMargin<'info> {
360 pub state: AccountInfo<'info>,
361 pub authority: Signer<'info>,
362 #[account(mut)]
364 pub payer: Signer<'info>,
365 #[account(mut)]
368 pub margin: AccountInfo<'info>,
369 #[account(zero)]
372 pub control: AccountInfo<'info>,
373 pub rent: AccountInfo<'info>,
374 pub system_program: AccountInfo<'info>,
375}
376
377#[derive(Accounts)]
378struct Deposit<'info> {
379 pub state: AccountInfo<'info>,
380 pub state_signer: AccountInfo<'info>,
382 #[account(mut)]
383 pub cache: AccountInfo<'info>,
384 pub authority: Signer<'info>,
385 #[account(mut)]
386 pub margin: AccountInfo<'info>,
387 #[account(mut)]
388 pub token_account: AccountInfo<'info>,
389 #[account(mut)]
391 pub vault: AccountInfo<'info>,
392 pub token_program: AccountInfo<'info>,
393}
394
395#[derive(Accounts)]
396struct Withdraw<'info> {
397 #[account(mut)]
398 pub state: AccountInfo<'info>,
399 #[account(mut)]
401 pub state_signer: AccountInfo<'info>,
402 #[account(mut)]
403 pub cache: AccountInfo<'info>,
404 pub authority: Signer<'info>,
405 #[account(mut)]
406 pub margin: AccountInfo<'info>,
407 #[account(mut)]
408 pub control: AccountInfo<'info>,
409 #[account(mut)]
410 pub token_account: AccountInfo<'info>,
411 #[account(mut)]
413 pub vault: AccountInfo<'info>,
414 pub token_program: AccountInfo<'info>,
415 #[account(mut)]
418 pub heimdall: AccountInfo<'info>,
419}
420
421#[derive(Accounts)]
422struct UpdatePerpFunding<'info> {
423 pub state: AccountInfo<'info>,
424 #[account(mut)]
425 pub state_signer: AccountInfo<'info>,
426 #[account(mut)]
427 pub cache: AccountInfo<'info>,
428 #[account(mut)]
429 pub dex_market: AccountInfo<'info>,
430 #[account(mut)]
431 pub market_bids: AccountInfo<'info>,
432 #[account(mut)]
433 pub market_asks: AccountInfo<'info>,
434 #[account(address = ZO_DEX_PID)]
435 pub dex_program: AccountInfo<'info>,
436}
437
438#[derive(Accounts)]
441struct CacheOracle<'info> {
442 pub signer: Signer<'info>,
443 pub state: AccountInfo<'info>,
444 #[account(mut)]
445 pub cache: AccountInfo<'info>,
446 #[account(address = ZO_DEX_PID)]
447 pub dex_program: AccountInfo<'info>,
448}
449
450#[derive(Accounts)]
451struct CacheInterestRates<'info> {
452 pub signer: Signer<'info>,
453 pub state: AccountInfo<'info>,
454 #[account(mut)]
455 pub cache: AccountInfo<'info>,
456}
457
458#[derive(Accounts)]
459struct ConsumeEvents<'info> {
460 #[account(mut)]
461 pub state: AccountInfo<'info>,
462 #[account(mut)]
463 pub state_signer: AccountInfo<'info>,
464 pub dex_program: AccountInfo<'info>,
465 #[account(mut)]
466 pub market: AccountInfo<'info>,
467 #[account(mut)]
468 pub event_queue: AccountInfo<'info>,
469 }
471
472#[derive(Accounts)]
473struct CrankPnl<'info> {
474 pub state: AccountInfo<'info>,
475 #[account(mut)]
476 pub state_signer: AccountInfo<'info>,
477 #[account(mut)]
478 pub cache: AccountInfo<'info>,
479 pub dex_program: AccountInfo<'info>,
480 #[account(mut)]
481 pub market: AccountInfo<'info>,
482 }
484
485#[derive(Accounts)]
486struct ForceCancelAllPerpOrders<'info> {
487 pub pruner: Signer<'info>,
488 pub state: AccountInfo<'info>,
489 #[account(mut)]
490 pub cache: AccountInfo<'info>,
491 #[account(mut)]
492 pub state_signer: AccountInfo<'info>,
493 #[account(mut)]
494 pub liqee_margin: AccountInfo<'info>,
495 #[account(mut)]
496 pub liqee_control: AccountInfo<'info>,
497 #[account(mut)]
498 pub liqee_oo: AccountInfo<'info>,
499 #[account(mut)]
500 pub dex_market: AccountInfo<'info>,
501 #[account(mut)]
502 pub req_q: AccountInfo<'info>,
503 #[account(mut)]
504 pub event_q: AccountInfo<'info>,
505 #[account(mut)]
506 pub market_bids: AccountInfo<'info>,
507 #[account(mut)]
508 pub market_asks: AccountInfo<'info>,
509 #[account(address = ZO_DEX_PID)]
510 pub dex_program: AccountInfo<'info>,
511}
512
513#[derive(Accounts)]
514struct LiquidatePerpPosition<'info> {
515 pub state: AccountInfo<'info>,
516 #[account(mut)]
517 pub cache: AccountInfo<'info>,
518 #[account(mut)]
519 pub state_signer: AccountInfo<'info>,
520 pub liqor: Signer<'info>,
521 #[account(mut)]
522 pub liqor_margin: AccountInfo<'info>,
523 #[account(mut)]
524 pub liqor_control: AccountInfo<'info>,
525 #[account(mut)]
526 pub liqor_oo: AccountInfo<'info>,
527 pub liqee: AccountInfo<'info>,
528 #[account(mut)]
529 pub liqee_margin: AccountInfo<'info>,
530 #[account(mut)]
531 pub liqee_control: AccountInfo<'info>,
532 #[account(mut)]
533 pub liqee_oo: AccountInfo<'info>,
534 #[account(mut)]
535 pub dex_market: AccountInfo<'info>,
536 #[account(mut)]
537 pub req_q: AccountInfo<'info>,
538 #[account(mut)]
539 pub event_q: AccountInfo<'info>,
540 #[account(mut)]
541 pub market_bids: AccountInfo<'info>,
542 #[account(mut)]
543 pub market_asks: AccountInfo<'info>,
544 #[account(address = ZO_DEX_PID)]
545 pub dex_program: AccountInfo<'info>,
546}
547
548#[derive(Accounts)]
549struct LiquidateSpotPosition<'info> {
550 pub state: AccountInfo<'info>,
551 #[account(mut)]
552 pub cache: AccountInfo<'info>,
553 pub liqor: Signer<'info>,
554 #[account(mut)]
555 pub liqor_margin: AccountInfo<'info>,
556 #[account(mut)]
557 pub liqor_control: AccountInfo<'info>,
558 #[account(mut)]
559 pub liqee_margin: AccountInfo<'info>,
560 #[account(mut)]
561 pub liqee_control: AccountInfo<'info>,
562 pub asset_mint: AccountInfo<'info>,
563 pub quote_mint: AccountInfo<'info>,
564}
565
566#[derive(Accounts)]
567struct PlacePerpOrder<'info> {
568 pub state: AccountInfo<'info>,
569 #[account(mut)]
570 pub state_signer: AccountInfo<'info>,
571 #[account(mut)]
572 pub cache: AccountInfo<'info>,
573 pub authority: Signer<'info>,
574 #[account(mut)]
575 pub margin: AccountInfo<'info>,
576 #[account(mut)]
577 pub control: AccountInfo<'info>,
578 #[account(mut)]
579 pub open_orders: AccountInfo<'info>,
580 #[account(mut)]
581 pub dex_market: AccountInfo<'info>,
582 #[account(mut)]
583 pub req_q: AccountInfo<'info>,
584 #[account(mut)]
585 pub event_q: AccountInfo<'info>,
586 #[account(mut)]
587 pub market_bids: AccountInfo<'info>,
588 #[account(mut)]
589 pub market_asks: AccountInfo<'info>,
590 #[account(address = ZO_DEX_PID)]
591 pub dex_program: AccountInfo<'info>,
592 pub rent: AccountInfo<'info>,
593}
594
595#[derive(Accounts)]
596struct SettleBankruptcy<'info> {
597 #[account(mut)]
598 pub state: AccountInfo<'info>,
599 #[account(mut)]
600 pub state_signer: AccountInfo<'info>,
601 #[account(mut)]
602 pub cache: AccountInfo<'info>,
603 pub liqor: Signer<'info>,
604 #[account(mut)]
605 pub liqor_margin: AccountInfo<'info>,
606 #[account(mut)]
607 pub liqor_control: AccountInfo<'info>,
608 #[account(mut)]
609 pub liqee_margin: AccountInfo<'info>,
610 #[account(mut)]
611 pub liqee_control: AccountInfo<'info>,
612 pub asset_mint: AccountInfo<'info>,
613}
614
615#[derive(Accounts)]
616struct Swap<'info> {
617 pub authority: Signer<'info>,
618 #[account(mut)]
619 pub state: AccountInfo<'info>,
620 pub state_signer: AccountInfo<'info>,
621 #[account(mut)]
622 pub cache: AccountInfo<'info>,
623 #[account(mut)]
624 pub margin: AccountInfo<'info>,
625 #[account(mut)]
626 pub control: AccountInfo<'info>,
627 pub quote_mint: AccountInfo<'info>,
630 #[account(mut)]
631 pub quote_vault: AccountInfo<'info>,
632 pub asset_mint: AccountInfo<'info>,
633 #[account(mut)]
634 pub asset_vault: AccountInfo<'info>,
635 #[account(mut)]
636 pub swap_fee_vault: AccountInfo<'info>,
637 #[account(mut)]
638 pub serum_open_orders: AccountInfo<'info>,
639 #[account(mut)]
640 pub serum_market: AccountInfo<'info>,
641 #[account(mut)]
642 pub serum_request_queue: AccountInfo<'info>,
643 #[account(mut)]
644 pub serum_event_queue: AccountInfo<'info>,
645 #[account(mut)]
646 pub serum_bids: AccountInfo<'info>,
647 #[account(mut)]
648 pub serum_asks: AccountInfo<'info>,
649 #[account(mut)]
650 pub serum_coin_vault: AccountInfo<'info>,
651 #[account(mut)]
652 pub serum_pc_vault: AccountInfo<'info>,
653 pub serum_vault_signer: AccountInfo<'info>,
654 #[account(address = SERUM_DEX_PID)]
655 pub srm_spot_program: AccountInfo<'info>,
656 pub token_program: AccountInfo<'info>,
657 pub rent: AccountInfo<'info>,
658}
659
660#[derive(Accounts)]
661pub struct CreateSpecialOrdersAccount<'info> {
662 pub state: AccountLoader<'info, State>,
663 pub authority: Signer<'info>,
664 #[account(mut)]
665 pub payer: Signer<'info>,
666 #[account(mut)]
668 pub special_orders: AccountLoader<'info, SpecialOrders>,
669 pub rent: Sysvar<'info, Rent>,
670 pub system_program: Program<'info, System>,
671}
672
673#[derive(Accounts)]
674pub struct PlaceSpecialOrder<'info> {
675 pub state: AccountLoader<'info, State>,
676 pub authority: Signer<'info>,
677 #[account(mut)]
679 pub special_orders: AccountLoader<'info, SpecialOrders>,
680 pub dex_market: AccountInfo<'info>,
681 pub system_program: Program<'info, System>,
682}
683
684#[derive(Accounts)]
685pub struct CancelSpecialOrder<'info> {
686 pub state: AccountLoader<'info, State>,
687 pub authority: Signer<'info>,
688 #[account(mut)]
690 pub special_orders: AccountLoader<'info, SpecialOrders>,
691 pub dex_market: AccountInfo<'info>,
692}
693
694#[derive(Accounts)]
695pub struct ExecuteSpecialOrder<'info> {
696 pub state: AccountLoader<'info, State>,
697 #[account(mut)]
698 pub state_signer: UncheckedAccount<'info>,
699 #[account(mut)]
700 pub cache: AccountLoader<'info, Cache>,
701 #[account(mut)]
702 pub payer: Signer<'info>,
703 pub authority: AccountInfo<'info>,
704 #[account(mut)]
705 pub margin: AccountLoader<'info, Margin>,
706 #[account(mut)]
707 pub control: AccountLoader<'info, Control>,
708 #[account(mut)]
710 pub special_orders: AccountLoader<'info, SpecialOrders>,
711 #[account(mut)]
712 pub open_orders: UncheckedAccount<'info>,
713 #[account(mut)]
714 pub dex_market: UncheckedAccount<'info>,
715 #[account(mut)]
716 pub req_q: UncheckedAccount<'info>,
717 #[account(mut)]
718 pub event_q: UncheckedAccount<'info>,
719 #[account(mut)]
720 pub market_bids: UncheckedAccount<'info>,
721 #[account(mut)]
722 pub market_asks: UncheckedAccount<'info>,
723 #[account(address = ZO_DEX_PID)]
724 pub dex_program: UncheckedAccount<'info>,
725 pub rent: Sysvar<'info, Rent>,
726}