gmsol_store/states/
deposit.rs1use anchor_lang::prelude::*;
2use gmsol_utils::InitSpace;
3
4use crate::{events::DepositRemoved, states::MarketConfigKey, CoreError};
5
6use super::{
7 common::{
8 action::{Action, ActionHeader, Closable},
9 swap::SwapActionParams,
10 token::TokenAndAccount,
11 },
12 Market, Seed,
13};
14
15#[account(zero_copy)]
17#[cfg_attr(feature = "debug", derive(derive_more::Debug))]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct Deposit {
20 pub(crate) header: ActionHeader,
22 pub(crate) tokens: DepositTokenAccounts,
24 pub(crate) params: DepositActionParams,
26 pub(crate) swap: SwapActionParams,
28 #[cfg_attr(feature = "debug", debug(skip))]
29 padding_0: [u8; 4],
30 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
31 #[cfg_attr(feature = "debug", debug(skip))]
32 reserved: [u8; 128],
33}
34
35pub fn find_first_deposit_receiver_pda(store_program_id: &Pubkey) -> (Pubkey, u8) {
37 Pubkey::find_program_address(&[Deposit::FIRST_DEPOSIT_RECEIVER_SEED], store_program_id)
38}
39
40impl InitSpace for Deposit {
41 const INIT_SPACE: usize = std::mem::size_of::<Self>();
42}
43
44impl Closable for Deposit {
45 type ClosedEvent = DepositRemoved;
46
47 fn to_closed_event(&self, address: &Pubkey, reason: &str) -> Result<Self::ClosedEvent> {
48 DepositRemoved::new(
49 self.header.id,
50 self.header.store,
51 *address,
52 self.tokens.market_token(),
53 self.header.owner,
54 self.header.action_state()?,
55 reason,
56 )
57 }
58}
59
60impl Deposit {
61 pub const FIRST_DEPOSIT_RECEIVER_SEED: &'static [u8] = b"first_deposit_receiver";
63
64 pub fn first_deposit_receiver() -> Pubkey {
66 find_first_deposit_receiver_pda(&crate::ID).0
67 }
68
69 pub fn tokens(&self) -> &DepositTokenAccounts {
71 &self.tokens
72 }
73
74 pub fn swap(&self) -> &SwapActionParams {
76 &self.swap
77 }
78
79 pub(crate) fn validate_first_deposit(
80 receiver: &Pubkey,
81 min_amount: u64,
82 market: &Market,
83 ) -> Result<()> {
84 let min_tokens_for_first_deposit = market
85 .get_config_by_key(MarketConfigKey::MinTokensForFirstDeposit)
86 .ok_or_else(|| error!(CoreError::Unimplemented))?;
87
88 if *min_tokens_for_first_deposit == 0 {
90 return Ok(());
91 }
92
93 require_keys_eq!(
94 *receiver,
95 Self::first_deposit_receiver(),
96 CoreError::InvalidReceiverForFirstDeposit
97 );
98
99 require_gte!(
100 min_amount as u128,
101 *min_tokens_for_first_deposit,
102 CoreError::NotEnoughMarketTokenAmountForFirstDeposit
103 );
104
105 Ok(())
106 }
107}
108
109impl Seed for Deposit {
110 const SEED: &'static [u8] = b"deposit";
112}
113
114impl Action for Deposit {
115 const MIN_EXECUTION_LAMPORTS: u64 = 200_000;
116
117 fn header(&self) -> &ActionHeader {
118 &self.header
119 }
120}
121
122#[zero_copy]
124#[cfg_attr(feature = "debug", derive(derive_more::Debug))]
125#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
126pub struct DepositTokenAccounts {
127 pub initial_long_token: TokenAndAccount,
129 pub initial_short_token: TokenAndAccount,
131 pub(crate) market_token: TokenAndAccount,
133 #[cfg_attr(feature = "debug", debug(skip))]
134 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
135 reserved: [u8; 128],
136}
137
138impl DepositTokenAccounts {
139 pub fn market_token(&self) -> Pubkey {
141 self.market_token.token().expect("must exist")
142 }
143
144 pub fn market_token_account(&self) -> Pubkey {
146 self.market_token.account().expect("must exist")
147 }
148}
149
150#[zero_copy]
152#[cfg_attr(feature = "debug", derive(derive_more::Debug))]
153#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
154pub struct DepositActionParams {
155 pub(crate) initial_long_token_amount: u64,
157 pub(crate) initial_short_token_amount: u64,
159 pub(crate) min_market_token_amount: u64,
161 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
162 #[cfg_attr(feature = "debug", debug(skip))]
163 reserved: [u8; 64],
164}
165
166impl Default for DepositActionParams {
167 fn default() -> Self {
168 Self {
169 initial_long_token_amount: 0,
170 initial_short_token_amount: 0,
171 min_market_token_amount: 0,
172 reserved: [0; 64],
173 }
174 }
175}
176
177impl DepositActionParams {
178 pub(crate) fn validate_market_token_amount(&self, minted: u64) -> Result<()> {
179 require_gte!(
180 minted,
181 self.min_market_token_amount,
182 CoreError::InsufficientOutputAmount
183 );
184 Ok(())
185 }
186}