dex.rs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. use anchor_lang::solana_program::account_info::AccountInfo;
  2. use anchor_lang::solana_program::entrypoint::ProgramResult;
  3. use anchor_lang::solana_program::program_error::ProgramError;
  4. use anchor_lang::solana_program::pubkey::Pubkey;
  5. use anchor_lang::{context::CpiContext, Accounts, ToAccountInfos};
  6. use serum_dex::instruction::SelfTradeBehavior;
  7. use serum_dex::matching::{OrderType, Side};
  8. use std::io::Write;
  9. use std::num::NonZeroU64;
  10. pub use serum_dex;
  11. #[cfg(not(feature = "devnet"))]
  12. anchor_lang::solana_program::declare_id!("9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin");
  13. #[cfg(feature = "devnet")]
  14. anchor_lang::solana_program::declare_id!("DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY");
  15. #[allow(clippy::too_many_arguments)]
  16. pub fn new_order_v3<'info>(
  17. ctx: CpiContext<'_, '_, '_, 'info, NewOrderV3<'info>>,
  18. side: Side,
  19. limit_price: NonZeroU64,
  20. max_coin_qty: NonZeroU64,
  21. max_native_pc_qty_including_fees: NonZeroU64,
  22. self_trade_behavior: SelfTradeBehavior,
  23. order_type: OrderType,
  24. client_order_id: u64,
  25. limit: u16,
  26. ) -> ProgramResult {
  27. let referral = ctx.remaining_accounts.get(0);
  28. let ix = serum_dex::instruction::new_order(
  29. ctx.accounts.market.key,
  30. ctx.accounts.open_orders.key,
  31. ctx.accounts.request_queue.key,
  32. ctx.accounts.event_queue.key,
  33. ctx.accounts.market_bids.key,
  34. ctx.accounts.market_asks.key,
  35. ctx.accounts.order_payer_token_account.key,
  36. ctx.accounts.open_orders_authority.key,
  37. ctx.accounts.coin_vault.key,
  38. ctx.accounts.pc_vault.key,
  39. ctx.accounts.token_program.key,
  40. ctx.accounts.rent.key,
  41. referral.map(|r| r.key),
  42. &ID,
  43. side,
  44. limit_price,
  45. max_coin_qty,
  46. order_type,
  47. client_order_id,
  48. self_trade_behavior,
  49. limit,
  50. max_native_pc_qty_including_fees,
  51. )?;
  52. solana_program::program::invoke_signed(
  53. &ix,
  54. &ToAccountInfos::to_account_infos(&ctx),
  55. ctx.signer_seeds,
  56. )?;
  57. Ok(())
  58. }
  59. pub fn cancel_order_v2<'info>(
  60. ctx: CpiContext<'_, '_, '_, 'info, CancelOrderV2<'info>>,
  61. side: Side,
  62. order_id: u128,
  63. ) -> ProgramResult {
  64. let ix = serum_dex::instruction::cancel_order(
  65. &ID,
  66. ctx.accounts.market.key,
  67. ctx.accounts.market_bids.key,
  68. ctx.accounts.market_asks.key,
  69. ctx.accounts.open_orders.key,
  70. ctx.accounts.open_orders_authority.key,
  71. ctx.accounts.event_queue.key,
  72. side,
  73. order_id,
  74. )?;
  75. solana_program::program::invoke_signed(
  76. &ix,
  77. &ToAccountInfos::to_account_infos(&ctx),
  78. ctx.signer_seeds,
  79. )?;
  80. Ok(())
  81. }
  82. pub fn settle_funds<'info>(
  83. ctx: CpiContext<'_, '_, '_, 'info, SettleFunds<'info>>,
  84. ) -> ProgramResult {
  85. let referral = ctx.remaining_accounts.get(0);
  86. let ix = serum_dex::instruction::settle_funds(
  87. &ID,
  88. ctx.accounts.market.key,
  89. ctx.accounts.token_program.key,
  90. ctx.accounts.open_orders.key,
  91. ctx.accounts.open_orders_authority.key,
  92. ctx.accounts.coin_vault.key,
  93. ctx.accounts.coin_wallet.key,
  94. ctx.accounts.pc_vault.key,
  95. ctx.accounts.pc_wallet.key,
  96. referral.map(|r| r.key),
  97. ctx.accounts.vault_signer.key,
  98. )?;
  99. solana_program::program::invoke_signed(
  100. &ix,
  101. &ToAccountInfos::to_account_infos(&ctx),
  102. ctx.signer_seeds,
  103. )?;
  104. Ok(())
  105. }
  106. pub fn init_open_orders<'info>(
  107. ctx: CpiContext<'_, '_, '_, 'info, InitOpenOrders<'info>>,
  108. ) -> ProgramResult {
  109. let ix = serum_dex::instruction::init_open_orders(
  110. &ID,
  111. ctx.accounts.open_orders.key,
  112. ctx.accounts.authority.key,
  113. ctx.accounts.market.key,
  114. ctx.remaining_accounts.first().map(|acc| acc.key),
  115. )?;
  116. solana_program::program::invoke_signed(
  117. &ix,
  118. &ToAccountInfos::to_account_infos(&ctx),
  119. ctx.signer_seeds,
  120. )?;
  121. Ok(())
  122. }
  123. pub fn close_open_orders<'info>(
  124. ctx: CpiContext<'_, '_, '_, 'info, CloseOpenOrders<'info>>,
  125. ) -> ProgramResult {
  126. let ix = serum_dex::instruction::close_open_orders(
  127. &ID,
  128. ctx.accounts.open_orders.key,
  129. ctx.accounts.authority.key,
  130. ctx.accounts.destination.key,
  131. ctx.accounts.market.key,
  132. )?;
  133. solana_program::program::invoke_signed(
  134. &ix,
  135. &ToAccountInfos::to_account_infos(&ctx),
  136. ctx.signer_seeds,
  137. )?;
  138. Ok(())
  139. }
  140. pub fn sweep_fees<'info>(ctx: CpiContext<'_, '_, '_, 'info, SweepFees<'info>>) -> ProgramResult {
  141. let ix = serum_dex::instruction::sweep_fees(
  142. &ID,
  143. ctx.accounts.market.key,
  144. ctx.accounts.pc_vault.key,
  145. ctx.accounts.sweep_authority.key,
  146. ctx.accounts.sweep_receiver.key,
  147. ctx.accounts.vault_signer.key,
  148. ctx.accounts.token_program.key,
  149. )?;
  150. solana_program::program::invoke_signed(
  151. &ix,
  152. &ToAccountInfos::to_account_infos(&ctx),
  153. ctx.signer_seeds,
  154. )?;
  155. Ok(())
  156. }
  157. pub fn initialize_market<'info>(
  158. ctx: CpiContext<'_, '_, '_, 'info, InitializeMarket<'info>>,
  159. coin_lot_size: u64,
  160. pc_lot_size: u64,
  161. vault_signer_nonce: u64,
  162. pc_dust_threshold: u64,
  163. ) -> ProgramResult {
  164. let authority = ctx.remaining_accounts.get(0);
  165. let prune_authority = ctx.remaining_accounts.get(1);
  166. let ix = serum_dex::instruction::initialize_market(
  167. ctx.accounts.market.key,
  168. &ID,
  169. ctx.accounts.coin_mint.key,
  170. ctx.accounts.pc_mint.key,
  171. ctx.accounts.coin_vault.key,
  172. ctx.accounts.pc_vault.key,
  173. authority.map(|r| r.key),
  174. prune_authority.map(|r| r.key),
  175. ctx.accounts.bids.key,
  176. ctx.accounts.asks.key,
  177. ctx.accounts.req_q.key,
  178. ctx.accounts.event_q.key,
  179. coin_lot_size,
  180. pc_lot_size,
  181. vault_signer_nonce,
  182. pc_dust_threshold,
  183. )?;
  184. solana_program::program::invoke_signed(
  185. &ix,
  186. &ToAccountInfos::to_account_infos(&ctx),
  187. ctx.signer_seeds,
  188. )?;
  189. Ok(())
  190. }
  191. #[derive(Accounts)]
  192. pub struct NewOrderV3<'info> {
  193. pub market: AccountInfo<'info>,
  194. pub open_orders: AccountInfo<'info>,
  195. pub request_queue: AccountInfo<'info>,
  196. pub event_queue: AccountInfo<'info>,
  197. pub market_bids: AccountInfo<'info>,
  198. pub market_asks: AccountInfo<'info>,
  199. // Token account where funds are transferred from for the order. If
  200. // posting a bid market A/B, then this is the SPL token account for B.
  201. pub order_payer_token_account: AccountInfo<'info>,
  202. pub open_orders_authority: AccountInfo<'info>,
  203. // Also known as the "base" currency. For a given A/B market,
  204. // this is the vault for the A mint.
  205. pub coin_vault: AccountInfo<'info>,
  206. // Also known as the "quote" currency. For a given A/B market,
  207. // this is the vault for the B mint.
  208. pub pc_vault: AccountInfo<'info>,
  209. pub token_program: AccountInfo<'info>,
  210. pub rent: AccountInfo<'info>,
  211. }
  212. #[derive(Accounts)]
  213. pub struct CancelOrderV2<'info> {
  214. pub market: AccountInfo<'info>,
  215. pub market_bids: AccountInfo<'info>,
  216. pub market_asks: AccountInfo<'info>,
  217. pub open_orders: AccountInfo<'info>,
  218. pub open_orders_authority: AccountInfo<'info>,
  219. pub event_queue: AccountInfo<'info>,
  220. }
  221. #[derive(Accounts)]
  222. pub struct SettleFunds<'info> {
  223. pub market: AccountInfo<'info>,
  224. pub open_orders: AccountInfo<'info>,
  225. pub open_orders_authority: AccountInfo<'info>,
  226. pub coin_vault: AccountInfo<'info>,
  227. pub pc_vault: AccountInfo<'info>,
  228. pub coin_wallet: AccountInfo<'info>,
  229. pub pc_wallet: AccountInfo<'info>,
  230. pub vault_signer: AccountInfo<'info>,
  231. pub token_program: AccountInfo<'info>,
  232. }
  233. /// To use an (optional) market authority, add it as the first account of the
  234. /// CpiContext's `remaining_accounts` Vec.
  235. #[derive(Accounts)]
  236. pub struct InitOpenOrders<'info> {
  237. pub open_orders: AccountInfo<'info>,
  238. pub authority: AccountInfo<'info>,
  239. pub market: AccountInfo<'info>,
  240. pub rent: AccountInfo<'info>,
  241. }
  242. #[derive(Accounts)]
  243. pub struct CloseOpenOrders<'info> {
  244. pub open_orders: AccountInfo<'info>,
  245. pub authority: AccountInfo<'info>,
  246. pub destination: AccountInfo<'info>,
  247. pub market: AccountInfo<'info>,
  248. }
  249. #[derive(Accounts)]
  250. pub struct SweepFees<'info> {
  251. pub market: AccountInfo<'info>,
  252. pub pc_vault: AccountInfo<'info>,
  253. pub sweep_authority: AccountInfo<'info>,
  254. pub sweep_receiver: AccountInfo<'info>,
  255. pub vault_signer: AccountInfo<'info>,
  256. pub token_program: AccountInfo<'info>,
  257. }
  258. #[derive(Accounts)]
  259. pub struct InitializeMarket<'info> {
  260. pub market: AccountInfo<'info>,
  261. pub coin_mint: AccountInfo<'info>,
  262. pub pc_mint: AccountInfo<'info>,
  263. pub coin_vault: AccountInfo<'info>,
  264. pub pc_vault: AccountInfo<'info>,
  265. pub bids: AccountInfo<'info>,
  266. pub asks: AccountInfo<'info>,
  267. pub req_q: AccountInfo<'info>,
  268. pub event_q: AccountInfo<'info>,
  269. pub rent: AccountInfo<'info>,
  270. }
  271. #[derive(Clone)]
  272. pub struct Dex;
  273. impl anchor_lang::Id for Dex {
  274. fn id() -> Pubkey {
  275. ID
  276. }
  277. }