serum_dex/
error.rs

1use num_enum::{FromPrimitive, IntoPrimitive};
2use solana_program::program_error::ProgramError;
3use thiserror::Error;
4
5pub type DexResult<T = ()> = Result<T, DexError>;
6
7#[derive(Debug)]
8pub struct AssertionError {
9    pub line: u16,
10    pub file_id: SourceFileId,
11}
12
13impl From<AssertionError> for u32 {
14    fn from(err: AssertionError) -> u32 {
15        (err.line as u32) + ((err.file_id as u8 as u32) << 24)
16    }
17}
18
19impl From<AssertionError> for DexError {
20    fn from(err: AssertionError) -> DexError {
21        let err: u32 = err.into();
22        DexError::ProgramError(ProgramError::Custom(err.into()))
23    }
24}
25
26#[derive(Error, Debug, PartialEq, Eq)]
27pub enum DexError {
28    #[error(transparent)]
29    ProgramError(#[from] ProgramError),
30    #[error("{0:?}")]
31    ErrorCode(#[from] DexErrorCode),
32}
33
34#[derive(Debug, IntoPrimitive, FromPrimitive, Clone, Copy, PartialEq, Eq)]
35#[repr(u32)]
36pub enum DexErrorCode {
37    InvalidMarketFlags = 0,
38    InvalidAskFlags,
39    InvalidBidFlags,
40    InvalidQueueLength,
41    OwnerAccountNotProvided,
42
43    ConsumeEventsQueueFailure,
44    WrongCoinVault,
45    WrongPcVault,
46    WrongCoinMint,
47    WrongPcMint,
48
49    CoinVaultProgramId = 10,
50    PcVaultProgramId,
51    CoinMintProgramId,
52    PcMintProgramId,
53
54    WrongCoinMintSize,
55    WrongPcMintSize,
56    WrongCoinVaultSize,
57    WrongPcVaultSize,
58
59    UninitializedVault,
60    UninitializedMint,
61
62    CoinMintUninitialized = 20,
63    PcMintUninitialized,
64    WrongMint,
65    WrongVaultOwner,
66    VaultHasDelegate,
67
68    AlreadyInitialized,
69    WrongAccountDataAlignment,
70    WrongAccountDataPaddingLength,
71    WrongAccountHeadPadding,
72    WrongAccountTailPadding,
73
74    RequestQueueEmpty = 30,
75    EventQueueTooSmall,
76    SlabTooSmall,
77    BadVaultSignerNonce,
78    InsufficientFunds,
79
80    SplAccountProgramId,
81    SplAccountLen,
82    WrongFeeDiscountAccountOwner,
83    WrongFeeDiscountMint,
84
85    CoinPayerProgramId,
86    PcPayerProgramId = 40,
87    ClientIdNotFound,
88    TooManyOpenOrders,
89
90    FakeErrorSoWeDontChangeNumbers,
91    BorrowError,
92
93    WrongOrdersAccount,
94    WrongBidsAccount,
95    WrongAsksAccount,
96    WrongRequestQueueAccount,
97    WrongEventQueueAccount,
98
99    RequestQueueFull = 50,
100    EventQueueFull,
101    MarketIsDisabled,
102    WrongSigner,
103    TransferFailed,
104    ClientOrderIdIsZero,
105
106    WrongRentSysvarAccount,
107    RentNotProvided,
108    OrdersNotRentExempt,
109    OrderNotFound,
110    OrderNotYours,
111
112    WouldSelfTrade,
113    InvalidOpenOrdersAuthority,
114
115    Unknown = 1000,
116
117    // This contains the line number in the lower 16 bits,
118    // and the source file id in the upper 8 bits
119    #[num_enum(default)]
120    AssertionError,
121}
122
123#[repr(u8)]
124#[derive(Error, Debug)]
125pub enum SourceFileId {
126    #[error("src/state.rs")]
127    State = 1,
128    #[error("src/matching.rs")]
129    Matching = 2,
130    #[error("src/critbit.rs")]
131    Critbit = 3,
132}
133
134#[macro_export]
135macro_rules! declare_check_assert_macros {
136    ($source_file_id:expr) => {
137        macro_rules! assertion_error {
138            () => {{
139                let file_id: SourceFileId = $source_file_id;
140                $crate::error::AssertionError {
141                    line: line!() as u16,
142                    file_id,
143                }
144            }};
145        }
146
147        #[allow(unused_macros)]
148        macro_rules! check_assert {
149            ($val:expr) => {{
150                if $val {
151                    Ok(())
152                } else {
153                    Err(assertion_error!())
154                }
155            }};
156        }
157
158        #[allow(unused_macros)]
159        macro_rules! check_assert_eq {
160            ($a:expr, $b:expr) => {{
161                if $a == $b {
162                    Ok(())
163                } else {
164                    Err(assertion_error!())
165                }
166            }};
167        }
168
169        #[allow(unused_macros)]
170        macro_rules! check_unreachable {
171            () => {{
172                Err(assertion_error!())
173            }};
174        }
175    };
176}
177
178impl std::fmt::Display for DexErrorCode {
179    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
180        <Self as std::fmt::Debug>::fmt(self, fmt)
181    }
182}
183
184impl std::error::Error for DexErrorCode {}
185
186impl std::convert::From<DexError> for ProgramError {
187    fn from(e: DexError) -> ProgramError {
188        match e {
189            DexError::ProgramError(e) => e,
190            DexError::ErrorCode(c) => ProgramError::Custom(c.into()),
191        }
192    }
193}
194
195impl std::convert::From<std::cell::BorrowError> for DexError {
196    fn from(_: std::cell::BorrowError) -> Self {
197        DexError::ErrorCode(DexErrorCode::BorrowError)
198    }
199}