safe_token_2022/
error.rs

1//! Error types
2
3use {
4    num_derive::FromPrimitive,
5    solana_program::{
6        decode_error::DecodeError,
7        msg,
8        program_error::{PrintProgramError, ProgramError},
9    },
10    thiserror::Error,
11};
12
13/// Errors that may be returned by the Token program.
14#[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)]
15pub enum TokenError {
16    // 0
17    /// Lamport balance below rent-exempt threshold.
18    #[error("Lamport balance below rent-exempt threshold")]
19    NotRentExempt,
20    /// Insufficient funds for the operation requested.
21    #[error("Insufficient funds")]
22    InsufficientFunds,
23    /// Invalid Mint.
24    #[error("Invalid Mint")]
25    InvalidMint,
26    /// Account not associated with this Mint.
27    #[error("Account not associated with this Mint")]
28    MintMismatch,
29    /// Owner does not match.
30    #[error("Owner does not match")]
31    OwnerMismatch,
32
33    // 5
34    /// This token's supply is fixed and new tokens cannot be minted.
35    #[error("Fixed supply")]
36    FixedSupply,
37    /// The account cannot be initialized because it is already being used.
38    #[error("Already in use")]
39    AlreadyInUse,
40    /// Invalid number of provided signers.
41    #[error("Invalid number of provided signers")]
42    InvalidNumberOfProvidedSigners,
43    /// Invalid number of required signers.
44    #[error("Invalid number of required signers")]
45    InvalidNumberOfRequiredSigners,
46    /// State is uninitialized.
47    #[error("State is uninitialized")]
48    UninitializedState,
49
50    // 10
51    /// Instruction does not support native tokens
52    #[error("Instruction does not support native tokens")]
53    NativeNotSupported,
54    /// Non-native account can only be closed if its balance is zero
55    #[error("Non-native account can only be closed if its balance is zero")]
56    NonNativeHasBalance,
57    /// Invalid instruction
58    #[error("Invalid instruction")]
59    InvalidInstruction,
60    /// State is invalid for requested operation.
61    #[error("State is invalid for requested operation")]
62    InvalidState,
63    /// Operation overflowed
64    #[error("Operation overflowed")]
65    Overflow,
66
67    // 15
68    /// Account does not support specified authority type.
69    #[error("Account does not support specified authority type")]
70    AuthorityTypeNotSupported,
71    /// This token mint cannot freeze accounts.
72    #[error("This token mint cannot freeze accounts")]
73    MintCannotFreeze,
74    /// Account is frozen; all account operations will fail
75    #[error("Account is frozen")]
76    AccountFrozen,
77    /// Mint decimals mismatch between the client and mint
78    #[error("The provided decimals value different from the Mint decimals")]
79    MintDecimalsMismatch,
80    /// Instruction does not support non-native tokens
81    #[error("Instruction does not support non-native tokens")]
82    NonNativeNotSupported,
83
84    // 20
85    /// Extension type does not match already existing extensions
86    #[error("Extension type does not match already existing extensions")]
87    ExtensionTypeMismatch,
88    /// Extension does not match the base type provided
89    #[error("Extension does not match the base type provided")]
90    ExtensionBaseMismatch,
91    /// Extension already initialized on this account
92    #[error("Extension already initialized on this account")]
93    ExtensionAlreadyInitialized,
94    /// An account can only be closed if its confidential balance is zero
95    #[error("An account can only be closed if its confidential balance is zero")]
96    ConfidentialTransferAccountHasBalance,
97    /// Account not approved for confidential transfers
98    #[error("Account not approved for confidential transfers")]
99    ConfidentialTransferAccountNotApproved,
100
101    // 25
102    /// Account not accepting deposits or transfers
103    #[error("Account not accepting deposits or transfers")]
104    ConfidentialTransferDepositsAndTransfersDisabled,
105    /// ElGamal public key mismatch
106    #[error("ElGamal public key mismatch")]
107    ConfidentialTransferElGamalPubkeyMismatch,
108    /// Balance mismatch
109    #[error("Balance mismatch")]
110    ConfidentialTransferBalanceMismatch,
111    /// Mint has non-zero supply. Burn all tokens before closing the mint.
112    #[error("Mint has non-zero supply. Burn all tokens before closing the mint")]
113    MintHasSupply,
114    /// No authority exists to perform the desired operation
115    #[error("No authority exists to perform the desired operation")]
116    NoAuthorityExists,
117
118    // 30
119    /// Transfer fee exceeds maximum of 10,000 basis points
120    #[error("Transfer fee exceeds maximum of 10,000 basis points")]
121    TransferFeeExceedsMaximum,
122    /// Mint required for this account to transfer tokens, use `transfer_checked` or `transfer_checked_with_fee`
123    #[error("Mint required for this account to transfer tokens, use `transfer_checked` or `transfer_checked_with_fee`")]
124    MintRequiredForTransfer,
125    /// Calculated fee does not match expected fee
126    #[error("Calculated fee does not match expected fee")]
127    FeeMismatch,
128    /// Fee parameters associated with confidential transfer zero-knowledge proofs do not match fee parameters in mint
129    #[error(
130        "Fee parameters associated with zero-knowledge proofs do not match fee parameters in mint"
131    )]
132    FeeParametersMismatch,
133    /// The owner authority cannot be changed
134    #[error("The owner authority cannot be changed")]
135    ImmutableOwner,
136
137    // 35
138    /// An account can only be closed if its withheld fee balance is zero, harvest fees to the
139    /// mint and try again
140    #[error("An account can only be closed if its withheld fee balance is zero, harvest fees to the mint and try again")]
141    AccountHasWithheldTransferFees,
142    /// No memo in previous instruction; required for recipient to receive a transfer
143    #[error("No memo in previous instruction; required for recipient to receive a transfer")]
144    NoMemo,
145    /// Transfer is disabled for this mint
146    #[error("Transfer is disabled for this mint")]
147    NonTransferable,
148    /// Non-transferable tokens can't be minted to an account without immutable ownership
149    #[error("Non-transferable tokens can't be minted to an account without immutable ownership")]
150    NonTransferableNeedsImmutableOwnership,
151    /// The total number of `Deposit` and `Transfer` instructions to an account cannot exceed the
152    /// associated `maximum_pending_balance_credit_counter`
153    #[error(
154        "The total number of `Deposit` and `Transfer` instructions to an account cannot exceed
155            the associated `maximum_pending_balance_credit_counter`"
156    )]
157    MaximumPendingBalanceCreditCounterExceeded,
158
159    // 40
160    /// The deposit amount for the confidential extension exceeds the maximum limit
161    #[error("Deposit amount exceeds maximum limit")]
162    MaximumDepositAmountExceeded,
163    /// CPI Guard cannot be enabled or disabled in CPI
164    #[error("CPI Guard cannot be enabled or disabled in CPI")]
165    CpiGuardSettingsLocked,
166    /// CPI Guard is enabled, and a program attempted to transfer user funds without using a delegate
167    #[error("CPI Guard is enabled, and a program attempted to transfer user funds via CPI without using a delegate")]
168    CpiGuardTransferBlocked,
169    /// CPI Guard is enabled, and a program attempted to burn user funds without using a delegate
170    #[error(
171        "CPI Guard is enabled, and a program attempted to burn user funds via CPI without using a delegate"
172    )]
173    CpiGuardBurnBlocked,
174    /// CPI Guard is enabled, and a program attempted to close an account without returning lamports to owner
175    #[error("CPI Guard is enabled, and a program attempted to close an account via CPI without returning lamports to owner")]
176    CpiGuardCloseAccountBlocked,
177
178    // 45
179    /// CPI Guard is enabled, and a program attempted to approve a delegate
180    #[error("CPI Guard is enabled, and a program attempted to approve a delegate via CPI")]
181    CpiGuardApproveBlocked,
182    /// CPI Guard is enabled, and a program attempted to add or replace an authority
183    #[error(
184        "CPI Guard is enabled, and a program attempted to add or replace an authority via CPI"
185    )]
186    CpiGuardSetAuthorityBlocked,
187    /// Account ownership cannot be changed while CPI Guard is enabled
188    #[error("Account ownership cannot be changed while CPI Guard is enabled")]
189    CpiGuardOwnerChangeBlocked,
190    /// Extension not found in account data
191    #[error("Extension not found in account data")]
192    ExtensionNotFound,
193    /// Account does not accept non-confidential transfers
194    #[error("Non-confidential transfers disabled")]
195    NonConfidentialTransfersDisabled,
196}
197impl From<TokenError> for ProgramError {
198    fn from(e: TokenError) -> Self {
199        ProgramError::Custom(e as u32)
200    }
201}
202impl<T> DecodeError<T> for TokenError {
203    fn type_of() -> &'static str {
204        "TokenError"
205    }
206}
207
208impl PrintProgramError for TokenError {
209    fn print<E>(&self)
210    where
211        E: 'static + std::error::Error + DecodeError<E> + num_traits::FromPrimitive,
212    {
213        match self {
214            TokenError::NotRentExempt => msg!("Error: Lamport balance below rent-exempt threshold"),
215            TokenError::InsufficientFunds => msg!("Error: insufficient funds"),
216            TokenError::InvalidMint => msg!("Error: Invalid Mint"),
217            TokenError::MintMismatch => msg!("Error: Account not associated with this Mint"),
218            TokenError::OwnerMismatch => msg!("Error: owner does not match"),
219            TokenError::FixedSupply => msg!("Error: the total supply of this token is fixed"),
220            TokenError::AlreadyInUse => msg!("Error: account or token already in use"),
221            TokenError::InvalidNumberOfProvidedSigners => {
222                msg!("Error: Invalid number of provided signers")
223            }
224            TokenError::InvalidNumberOfRequiredSigners => {
225                msg!("Error: Invalid number of required signers")
226            }
227            TokenError::UninitializedState => msg!("Error: State is uninitialized"),
228            TokenError::NativeNotSupported => {
229                msg!("Error: Instruction does not support native tokens")
230            }
231            TokenError::NonNativeHasBalance => {
232                msg!("Error: Non-native account can only be closed if its balance is zero")
233            }
234            TokenError::InvalidInstruction => msg!("Error: Invalid instruction"),
235            TokenError::InvalidState => msg!("Error: Invalid account state for operation"),
236            TokenError::Overflow => msg!("Error: Operation overflowed"),
237            TokenError::AuthorityTypeNotSupported => {
238                msg!("Error: Account does not support specified authority type")
239            }
240            TokenError::MintCannotFreeze => msg!("Error: This token mint cannot freeze accounts"),
241            TokenError::AccountFrozen => msg!("Error: Account is frozen"),
242            TokenError::MintDecimalsMismatch => {
243                msg!("Error: decimals different from the Mint decimals")
244            }
245            TokenError::NonNativeNotSupported => {
246                msg!("Error: Instruction does not support non-native tokens")
247            }
248            TokenError::ExtensionTypeMismatch => {
249                msg!("Error: New extension type does not match already existing extensions")
250            }
251            TokenError::ExtensionBaseMismatch => {
252                msg!("Error: Extension does not match the base type provided")
253            }
254            TokenError::ExtensionAlreadyInitialized => {
255                msg!("Error: Extension already initialized on this account")
256            }
257            TokenError::ConfidentialTransferAccountHasBalance => {
258                msg!("Error: An account can only be closed if its confidential balance is zero")
259            }
260            TokenError::ConfidentialTransferAccountNotApproved => {
261                msg!("Error: Account not approved for confidential transfers")
262            }
263            TokenError::ConfidentialTransferDepositsAndTransfersDisabled => {
264                msg!("Error: Account not accepting deposits or transfers")
265            }
266            TokenError::ConfidentialTransferElGamalPubkeyMismatch => {
267                msg!("Error: ElGamal public key mismatch")
268            }
269            TokenError::ConfidentialTransferBalanceMismatch => {
270                msg!("Error: Balance mismatch")
271            }
272            TokenError::MintHasSupply => {
273                msg!("Error: Mint has non-zero supply. Burn all tokens before closing the mint")
274            }
275            TokenError::NoAuthorityExists => {
276                msg!("Error: No authority exists to perform the desired operation");
277            }
278            TokenError::TransferFeeExceedsMaximum => {
279                msg!("Error: Transfer fee exceeds maximum of 10,000 basis points");
280            }
281            TokenError::MintRequiredForTransfer => {
282                msg!("Mint required for this account to transfer tokens, use `transfer_checked` or `transfer_checked_with_fee`");
283            }
284            TokenError::FeeMismatch => {
285                msg!("Calculated fee does not match expected fee");
286            }
287            TokenError::FeeParametersMismatch => {
288                msg!("Fee parameters associated with zero-knowledge proofs do not match fee parameters in mint")
289            }
290            TokenError::ImmutableOwner => {
291                msg!("The owner authority cannot be changed");
292            }
293            TokenError::AccountHasWithheldTransferFees => {
294                msg!("Error: An account can only be closed if its withheld fee balance is zero, harvest fees to the mint and try again");
295            }
296            TokenError::NoMemo => {
297                msg!("Error: No memo in previous instruction; required for recipient to receive a transfer");
298            }
299            TokenError::NonTransferable => {
300                msg!("Transfer is disabled for this mint");
301            }
302            TokenError::NonTransferableNeedsImmutableOwnership => {
303                msg!("Non-transferable tokens can't be minted to an account without immutable ownership");
304            }
305            TokenError::MaximumPendingBalanceCreditCounterExceeded => {
306                msg!("The total number of `Deposit` and `Transfer` instructions to an account cannot exceed the associated `maximum_pending_balance_credit_counter`");
307            }
308            TokenError::MaximumDepositAmountExceeded => {
309                msg!("Deposit amount exceeds maximum limit")
310            }
311            TokenError::CpiGuardSettingsLocked => {
312                msg!("CPI Guard status cannot be changed in CPI")
313            }
314            TokenError::CpiGuardTransferBlocked => {
315                msg!("CPI Guard is enabled, and a program attempted to transfer user funds without using a delegate")
316            }
317            TokenError::CpiGuardBurnBlocked => {
318                msg!("CPI Guard is enabled, and a program attempted to burn user funds without using a delegate")
319            }
320            TokenError::CpiGuardCloseAccountBlocked => {
321                msg!("CPI Guard is enabled, and a program attempted to close an account without returning lamports to owner")
322            }
323            TokenError::CpiGuardApproveBlocked => {
324                msg!("CPI Guard is enabled, and a program attempted to approve a delegate")
325            }
326            TokenError::CpiGuardSetAuthorityBlocked => {
327                msg!("CPI Guard is enabled, and a program attempted to add or change an authority")
328            }
329            TokenError::CpiGuardOwnerChangeBlocked => {
330                msg!("Account ownership cannot be changed while CPI Guard is enabled")
331            }
332            TokenError::ExtensionNotFound => {
333                msg!("Extension not found in account data")
334            }
335            TokenError::NonConfidentialTransfersDisabled => {
336                msg!("Non-confidential transfers disabled")
337            }
338        }
339    }
340}