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 =
85 market.get_config_by_key(MarketConfigKey::MinTokensForFirstDeposit);
86
87 if *min_tokens_for_first_deposit == 0 {
89 return Ok(());
90 }
91
92 require_keys_eq!(
93 *receiver,
94 Self::first_deposit_receiver(),
95 CoreError::InvalidReceiverForFirstDeposit
96 );
97
98 require_gte!(
99 min_amount as u128,
100 *min_tokens_for_first_deposit,
101 CoreError::NotEnoughMarketTokenAmountForFirstDeposit
102 );
103
104 Ok(())
105 }
106}
107
108impl Seed for Deposit {
109 const SEED: &'static [u8] = b"deposit";
111}
112
113impl Action for Deposit {
114 const MIN_EXECUTION_LAMPORTS: u64 = 200_000;
115
116 fn header(&self) -> &ActionHeader {
117 &self.header
118 }
119}
120
121#[zero_copy]
123#[cfg_attr(feature = "debug", derive(derive_more::Debug))]
124#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
125pub struct DepositTokenAccounts {
126 pub initial_long_token: TokenAndAccount,
128 pub initial_short_token: TokenAndAccount,
130 pub(crate) market_token: TokenAndAccount,
132 #[cfg_attr(feature = "debug", debug(skip))]
133 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
134 reserved: [u8; 128],
135}
136
137impl DepositTokenAccounts {
138 pub fn market_token(&self) -> Pubkey {
140 self.market_token.token().expect("must exist")
141 }
142
143 pub fn market_token_account(&self) -> Pubkey {
145 self.market_token.account().expect("must exist")
146 }
147}
148
149#[zero_copy]
151#[cfg_attr(feature = "debug", derive(derive_more::Debug))]
152#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
153pub struct DepositActionParams {
154 pub(crate) initial_long_token_amount: u64,
156 pub(crate) initial_short_token_amount: u64,
158 pub(crate) min_market_token_amount: u64,
160 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
161 #[cfg_attr(feature = "debug", debug(skip))]
162 reserved: [u8; 64],
163}
164
165impl Default for DepositActionParams {
166 fn default() -> Self {
167 Self {
168 initial_long_token_amount: 0,
169 initial_short_token_amount: 0,
170 min_market_token_amount: 0,
171 reserved: [0; 64],
172 }
173 }
174}
175
176impl DepositActionParams {
177 pub(crate) fn validate_market_token_amount(&self, minted: u64) -> Result<()> {
178 require_gte!(
179 minted,
180 self.min_market_token_amount,
181 CoreError::InsufficientOutputAmount
182 );
183 Ok(())
184 }
185}