gmsol_store/states/
withdrawal.rs1use anchor_lang::prelude::*;
2
3use crate::{events::WithdrawalRemoved, CoreError};
4
5use super::{
6 common::{
7 action::{Action, ActionHeader, Closable},
8 swap::SwapActionParams,
9 token::TokenAndAccount,
10 },
11 Seed,
12};
13
14#[account(zero_copy)]
16#[cfg_attr(feature = "debug", derive(derive_more::Debug))]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub struct Withdrawal {
19 pub(crate) header: ActionHeader,
21 pub(crate) tokens: WithdrawalTokenAccounts,
23 pub(crate) params: WithdrawalActionParams,
25 pub(crate) swap: SwapActionParams,
27 #[cfg_attr(feature = "debug", debug(skip))]
28 padding_1: [u8; 4],
29 #[cfg_attr(feature = "debug", debug(skip))]
30 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
31 reserved: [u8; 128],
32}
33
34impl Withdrawal {
35 pub fn tokens(&self) -> &WithdrawalTokenAccounts {
37 &self.tokens
38 }
39
40 pub fn swap(&self) -> &SwapActionParams {
42 &self.swap
43 }
44}
45
46impl Seed for Withdrawal {
47 const SEED: &'static [u8] = b"withdrawal";
49}
50
51impl gmsol_utils::InitSpace for Withdrawal {
52 const INIT_SPACE: usize = std::mem::size_of::<Self>();
53}
54
55impl Action for Withdrawal {
56 const MIN_EXECUTION_LAMPORTS: u64 = 200_000;
57
58 fn header(&self) -> &ActionHeader {
59 &self.header
60 }
61}
62
63impl Closable for Withdrawal {
64 type ClosedEvent = WithdrawalRemoved;
65
66 fn to_closed_event(&self, address: &Pubkey, reason: &str) -> Result<Self::ClosedEvent> {
67 WithdrawalRemoved::new(
68 self.header.id,
69 self.header.store,
70 *address,
71 self.tokens.market_token(),
72 self.header.owner,
73 self.header.action_state()?,
74 reason,
75 )
76 }
77}
78
79#[zero_copy]
81#[cfg_attr(feature = "debug", derive(derive_more::Debug))]
82#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
83pub struct WithdrawalTokenAccounts {
84 pub(crate) final_long_token: TokenAndAccount,
86 pub(crate) final_short_token: TokenAndAccount,
88 pub(crate) market_token: TokenAndAccount,
90 #[cfg_attr(feature = "debug", debug(skip))]
91 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
92 reserved: [u8; 128],
93}
94
95impl WithdrawalTokenAccounts {
96 pub fn market_token(&self) -> Pubkey {
98 self.market_token.token().expect("must exist")
99 }
100
101 pub fn market_token_account(&self) -> Pubkey {
103 self.market_token.account().expect("must exist")
104 }
105
106 pub fn final_long_token(&self) -> Pubkey {
108 self.final_long_token.token().expect("must exist")
109 }
110
111 pub fn final_long_token_account(&self) -> Pubkey {
113 self.final_long_token.account().expect("must exist")
114 }
115
116 pub fn final_short_token(&self) -> Pubkey {
118 self.final_short_token.token().expect("must exist")
119 }
120
121 pub fn final_short_token_account(&self) -> Pubkey {
123 self.final_short_token.account().expect("must exist")
124 }
125}
126
127#[zero_copy]
129#[cfg_attr(feature = "debug", derive(derive_more::Debug))]
130#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
131pub struct WithdrawalActionParams {
132 pub market_token_amount: u64,
134 pub min_long_token_amount: u64,
136 pub min_short_token_amount: u64,
138 #[cfg_attr(feature = "debug", debug(skip))]
139 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
140 reserved: [u8; 64],
141}
142
143impl Default for WithdrawalActionParams {
144 fn default() -> Self {
145 Self {
146 reserved: [0; 64],
147 market_token_amount: 0,
148 min_long_token_amount: 0,
149 min_short_token_amount: 0,
150 }
151 }
152}
153
154impl WithdrawalActionParams {
155 pub(crate) fn validate_output_amounts(
156 &self,
157 long_amount: u64,
158 short_amount: u64,
159 ) -> Result<()> {
160 require_gte!(
161 long_amount,
162 self.min_long_token_amount,
163 CoreError::InsufficientOutputAmount
164 );
165 require_gte!(
166 short_amount,
167 self.min_short_token_amount,
168 CoreError::InsufficientOutputAmount
169 );
170 Ok(())
171 }
172}