spl_token_2022/
error.rs

1//! Error types
2
3#[cfg(not(target_os = "solana"))]
4use spl_token_confidential_transfer_proof_generation::errors::TokenProofGenerationError;
5use {
6    num_derive::FromPrimitive,
7    solana_decode_error::DecodeError,
8    solana_msg::msg,
9    solana_program_error::{PrintProgramError, ProgramError},
10    spl_token_confidential_transfer_proof_extraction::errors::TokenProofExtractionError,
11    thiserror::Error,
12};
13
14/// Errors that may be returned by the Token program.
15#[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)]
16pub enum TokenError {
17    // 0
18    /// Lamport balance below rent-exempt threshold.
19    #[error("Lamport balance below rent-exempt threshold")]
20    NotRentExempt,
21    /// Insufficient funds for the operation requested.
22    #[error("Insufficient funds")]
23    InsufficientFunds,
24    /// Invalid Mint.
25    #[error("Invalid Mint")]
26    InvalidMint,
27    /// Account not associated with this Mint.
28    #[error("Account not associated with this Mint")]
29    MintMismatch,
30    /// Owner does not match.
31    #[error("Owner does not match")]
32    OwnerMismatch,
33
34    // 5
35    /// This token's supply is fixed and new tokens cannot be minted.
36    #[error("Fixed supply")]
37    FixedSupply,
38    /// The account cannot be initialized because it is already being used.
39    #[error("Already in use")]
40    AlreadyInUse,
41    /// Invalid number of provided signers.
42    #[error("Invalid number of provided signers")]
43    InvalidNumberOfProvidedSigners,
44    /// Invalid number of required signers.
45    #[error("Invalid number of required signers")]
46    InvalidNumberOfRequiredSigners,
47    /// State is uninitialized.
48    #[error("State is uninitialized")]
49    UninitializedState,
50
51    // 10
52    /// Instruction does not support native tokens
53    #[error("Instruction does not support native tokens")]
54    NativeNotSupported,
55    /// Non-native account can only be closed if its balance is zero
56    #[error("Non-native account can only be closed if its balance is zero")]
57    NonNativeHasBalance,
58    /// Invalid instruction
59    #[error("Invalid instruction")]
60    InvalidInstruction,
61    /// State is invalid for requested operation.
62    #[error("State is invalid for requested operation")]
63    InvalidState,
64    /// Operation overflowed
65    #[error("Operation overflowed")]
66    Overflow,
67
68    // 15
69    /// Account does not support specified authority type.
70    #[error("Account does not support specified authority type")]
71    AuthorityTypeNotSupported,
72    /// This token mint cannot freeze accounts.
73    #[error("This token mint cannot freeze accounts")]
74    MintCannotFreeze,
75    /// Account is frozen; all account operations will fail
76    #[error("Account is frozen")]
77    AccountFrozen,
78    /// Mint decimals mismatch between the client and mint
79    #[error("The provided decimals value different from the Mint decimals")]
80    MintDecimalsMismatch,
81    /// Instruction does not support non-native tokens
82    #[error("Instruction does not support non-native tokens")]
83    NonNativeNotSupported,
84
85    // 20
86    /// Extension type does not match already existing extensions
87    #[error("Extension type does not match already existing extensions")]
88    ExtensionTypeMismatch,
89    /// Extension does not match the base type provided
90    #[error("Extension does not match the base type provided")]
91    ExtensionBaseMismatch,
92    /// Extension already initialized on this account
93    #[error("Extension already initialized on this account")]
94    ExtensionAlreadyInitialized,
95    /// An account can only be closed if its confidential balance is zero
96    #[error("An account can only be closed if its confidential balance is zero")]
97    ConfidentialTransferAccountHasBalance,
98    /// Account not approved for confidential transfers
99    #[error("Account not approved for confidential transfers")]
100    ConfidentialTransferAccountNotApproved,
101
102    // 25
103    /// Account not accepting deposits or transfers
104    #[error("Account not accepting deposits or transfers")]
105    ConfidentialTransferDepositsAndTransfersDisabled,
106    /// ElGamal public key mismatch
107    #[error("ElGamal public key mismatch")]
108    ConfidentialTransferElGamalPubkeyMismatch,
109    /// Balance mismatch
110    #[error("Balance mismatch")]
111    ConfidentialTransferBalanceMismatch,
112    /// Mint has non-zero supply. Burn all tokens before closing the mint.
113    #[error("Mint has non-zero supply. Burn all tokens before closing the mint")]
114    MintHasSupply,
115    /// No authority exists to perform the desired operation
116    #[error("No authority exists to perform the desired operation")]
117    NoAuthorityExists,
118
119    // 30
120    /// Transfer fee exceeds maximum of 10,000 basis points
121    #[error("Transfer fee exceeds maximum of 10,000 basis points")]
122    TransferFeeExceedsMaximum,
123    /// Mint required for this account to transfer tokens, use
124    /// `transfer_checked` or `transfer_checked_with_fee`
125    #[error("Mint required for this account to transfer tokens, use `transfer_checked` or `transfer_checked_with_fee`")]
126    MintRequiredForTransfer,
127    /// Calculated fee does not match expected fee
128    #[error("Calculated fee does not match expected fee")]
129    FeeMismatch,
130    /// Fee parameters associated with confidential transfer zero-knowledge
131    /// proofs do not match fee parameters in mint
132    #[error(
133        "Fee parameters associated with zero-knowledge proofs do not match fee parameters in mint"
134    )]
135    FeeParametersMismatch,
136    /// The owner authority cannot be changed
137    #[error("The owner authority cannot be changed")]
138    ImmutableOwner,
139
140    // 35
141    /// An account can only be closed if its withheld fee balance is zero,
142    /// harvest fees to the mint and try again
143    #[error("An account can only be closed if its withheld fee balance is zero, harvest fees to the mint and try again")]
144    AccountHasWithheldTransferFees,
145    /// No memo in previous instruction; required for recipient to receive a
146    /// transfer
147    #[error("No memo in previous instruction; required for recipient to receive a transfer")]
148    NoMemo,
149    /// Transfer is disabled for this mint
150    #[error("Transfer is disabled for this mint")]
151    NonTransferable,
152    /// Non-transferable tokens can't be minted to an account without immutable
153    /// ownership
154    #[error("Non-transferable tokens can't be minted to an account without immutable ownership")]
155    NonTransferableNeedsImmutableOwnership,
156    /// The total number of `Deposit` and `Transfer` instructions to an account
157    /// cannot exceed the associated
158    /// `maximum_pending_balance_credit_counter`
159    #[error(
160        "The total number of `Deposit` and `Transfer` instructions to an account cannot exceed
161            the associated `maximum_pending_balance_credit_counter`"
162    )]
163    MaximumPendingBalanceCreditCounterExceeded,
164
165    // 40
166    /// The deposit amount for the confidential extension exceeds the maximum
167    /// limit
168    #[error("Deposit amount exceeds maximum limit")]
169    MaximumDepositAmountExceeded,
170    /// CPI Guard cannot be enabled or disabled in CPI
171    #[error("CPI Guard cannot be enabled or disabled in CPI")]
172    CpiGuardSettingsLocked,
173    /// CPI Guard is enabled, and a program attempted to transfer user funds
174    /// without using a delegate
175    #[error("CPI Guard is enabled, and a program attempted to transfer user funds via CPI without using a delegate")]
176    CpiGuardTransferBlocked,
177    /// CPI Guard is enabled, and a program attempted to burn user funds without
178    /// using a delegate
179    #[error(
180        "CPI Guard is enabled, and a program attempted to burn user funds via CPI without using a delegate"
181    )]
182    CpiGuardBurnBlocked,
183    /// CPI Guard is enabled, and a program attempted to close an account
184    /// without returning lamports to owner
185    #[error("CPI Guard is enabled, and a program attempted to close an account via CPI without returning lamports to owner")]
186    CpiGuardCloseAccountBlocked,
187
188    // 45
189    /// CPI Guard is enabled, and a program attempted to approve a delegate
190    #[error("CPI Guard is enabled, and a program attempted to approve a delegate via CPI")]
191    CpiGuardApproveBlocked,
192    /// CPI Guard is enabled, and a program attempted to add or replace an
193    /// authority
194    #[error(
195        "CPI Guard is enabled, and a program attempted to add or replace an authority via CPI"
196    )]
197    CpiGuardSetAuthorityBlocked,
198    /// Account ownership cannot be changed while CPI Guard is enabled
199    #[error("Account ownership cannot be changed while CPI Guard is enabled")]
200    CpiGuardOwnerChangeBlocked,
201    /// Extension not found in account data
202    #[error("Extension not found in account data")]
203    ExtensionNotFound,
204    /// Account does not accept non-confidential transfers
205    #[error("Non-confidential transfers disabled")]
206    NonConfidentialTransfersDisabled,
207
208    // 50
209    /// An account can only be closed if the confidential withheld fee is zero
210    #[error("An account can only be closed if the confidential withheld fee is zero")]
211    ConfidentialTransferFeeAccountHasWithheldFee,
212    /// A mint or an account is initialized to an invalid combination of
213    /// extensions
214    #[error("A mint or an account is initialized to an invalid combination of extensions")]
215    InvalidExtensionCombination,
216    /// Extension allocation with overwrite must use the same length
217    #[error("Extension allocation with overwrite must use the same length")]
218    InvalidLengthForAlloc,
219    /// Failed to decrypt a confidential transfer account
220    #[error("Failed to decrypt a confidential transfer account")]
221    AccountDecryption,
222    /// Failed to generate a zero-knowledge proof needed for a token instruction
223    #[error("Failed to generate proof")]
224    ProofGeneration,
225
226    // 55
227    /// An invalid proof instruction offset was provided
228    #[error("An invalid proof instruction offset was provided")]
229    InvalidProofInstructionOffset,
230    /// Harvest of withheld tokens to mint is disabled
231    #[error("Harvest of withheld tokens to mint is disabled")]
232    HarvestToMintDisabled,
233    /// Split proof context state accounts not supported for instruction
234    #[error("Split proof context state accounts not supported for instruction")]
235    SplitProofContextStateAccountsNotSupported,
236    /// Not enough proof context state accounts provided
237    #[error("Not enough proof context state accounts provided")]
238    NotEnoughProofContextStateAccounts,
239    /// Ciphertext is malformed
240    #[error("Ciphertext is malformed")]
241    MalformedCiphertext,
242
243    // 60
244    /// Ciphertext arithmetic failed
245    #[error("Ciphertext arithmetic failed")]
246    CiphertextArithmeticFailed,
247    /// Pedersen commitments did not match
248    #[error("Pedersen commitment mismatch")]
249    PedersenCommitmentMismatch,
250    /// Range proof length did not match
251    #[error("Range proof length mismatch")]
252    RangeProofLengthMismatch,
253    /// Illegal transfer amount bit length
254    #[error("Illegal transfer amount bit length")]
255    IllegalBitLength,
256    /// Fee calculation failed
257    #[error("Fee calculation failed")]
258    FeeCalculation,
259
260    //65
261    /// Withdraw / Deposit not allowed for confidential-mint-burn
262    #[error("Withdraw / Deposit not allowed for confidential-mint-burn")]
263    IllegalMintBurnConversion,
264    /// Invalid scale for scaled ui amount
265    #[error("Invalid scale for scaled ui amount")]
266    InvalidScale,
267    /// Transferring, minting, and burning is paused on this mint
268    #[error("Transferring, minting, and burning is paused on this mint")]
269    MintPaused,
270    /// Pending supply is not zero
271    #[error("Key rotation attempted while pending balance is not zero")]
272    PendingBalanceNonZero,
273}
274impl From<TokenError> for ProgramError {
275    fn from(e: TokenError) -> Self {
276        ProgramError::Custom(e as u32)
277    }
278}
279impl<T> DecodeError<T> for TokenError {
280    fn type_of() -> &'static str {
281        "TokenError"
282    }
283}
284
285impl PrintProgramError for TokenError {
286    fn print<E>(&self)
287    where
288        E: 'static + std::error::Error + DecodeError<E> + num_traits::FromPrimitive,
289    {
290        match self {
291            TokenError::NotRentExempt => msg!("Error: Lamport balance below rent-exempt threshold"),
292            TokenError::InsufficientFunds => msg!("Error: insufficient funds"),
293            TokenError::InvalidMint => msg!("Error: Invalid Mint"),
294            TokenError::MintMismatch => msg!("Error: Account not associated with this Mint"),
295            TokenError::OwnerMismatch => msg!("Error: owner does not match"),
296            TokenError::FixedSupply => msg!("Error: the total supply of this token is fixed"),
297            TokenError::AlreadyInUse => msg!("Error: account or token already in use"),
298            TokenError::InvalidNumberOfProvidedSigners => {
299                msg!("Error: Invalid number of provided signers")
300            }
301            TokenError::InvalidNumberOfRequiredSigners => {
302                msg!("Error: Invalid number of required signers")
303            }
304            TokenError::UninitializedState => msg!("Error: State is uninitialized"),
305            TokenError::NativeNotSupported => {
306                msg!("Error: Instruction does not support native tokens")
307            }
308            TokenError::NonNativeHasBalance => {
309                msg!("Error: Non-native account can only be closed if its balance is zero")
310            }
311            TokenError::InvalidInstruction => msg!("Error: Invalid instruction"),
312            TokenError::InvalidState => msg!("Error: Invalid account state for operation"),
313            TokenError::Overflow => msg!("Error: Operation overflowed"),
314            TokenError::AuthorityTypeNotSupported => {
315                msg!("Error: Account does not support specified authority type")
316            }
317            TokenError::MintCannotFreeze => msg!("Error: This token mint cannot freeze accounts"),
318            TokenError::AccountFrozen => msg!("Error: Account is frozen"),
319            TokenError::MintDecimalsMismatch => {
320                msg!("Error: decimals different from the Mint decimals")
321            }
322            TokenError::NonNativeNotSupported => {
323                msg!("Error: Instruction does not support non-native tokens")
324            }
325            TokenError::ExtensionTypeMismatch => {
326                msg!("Error: New extension type does not match already existing extensions")
327            }
328            TokenError::ExtensionBaseMismatch => {
329                msg!("Error: Extension does not match the base type provided")
330            }
331            TokenError::ExtensionAlreadyInitialized => {
332                msg!("Error: Extension already initialized on this account")
333            }
334            TokenError::ConfidentialTransferAccountHasBalance => {
335                msg!("Error: An account can only be closed if its confidential balance is zero")
336            }
337            TokenError::ConfidentialTransferAccountNotApproved => {
338                msg!("Error: Account not approved for confidential transfers")
339            }
340            TokenError::ConfidentialTransferDepositsAndTransfersDisabled => {
341                msg!("Error: Account not accepting deposits or transfers")
342            }
343            TokenError::ConfidentialTransferElGamalPubkeyMismatch => {
344                msg!("Error: ElGamal public key mismatch")
345            }
346            TokenError::ConfidentialTransferBalanceMismatch => {
347                msg!("Error: Balance mismatch")
348            }
349            TokenError::MintHasSupply => {
350                msg!("Error: Mint has non-zero supply. Burn all tokens before closing the mint")
351            }
352            TokenError::NoAuthorityExists => {
353                msg!("Error: No authority exists to perform the desired operation");
354            }
355            TokenError::TransferFeeExceedsMaximum => {
356                msg!("Error: Transfer fee exceeds maximum of 10,000 basis points");
357            }
358            TokenError::MintRequiredForTransfer => {
359                msg!("Mint required for this account to transfer tokens, use `transfer_checked` or `transfer_checked_with_fee`");
360            }
361            TokenError::FeeMismatch => {
362                msg!("Calculated fee does not match expected fee");
363            }
364            TokenError::FeeParametersMismatch => {
365                msg!("Fee parameters associated with zero-knowledge proofs do not match fee parameters in mint")
366            }
367            TokenError::ImmutableOwner => {
368                msg!("The owner authority cannot be changed");
369            }
370            TokenError::AccountHasWithheldTransferFees => {
371                msg!("Error: An account can only be closed if its withheld fee balance is zero, harvest fees to the mint and try again");
372            }
373            TokenError::NoMemo => {
374                msg!("Error: No memo in previous instruction; required for recipient to receive a transfer");
375            }
376            TokenError::NonTransferable => {
377                msg!("Transfer is disabled for this mint");
378            }
379            TokenError::NonTransferableNeedsImmutableOwnership => {
380                msg!("Non-transferable tokens can't be minted to an account without immutable ownership");
381            }
382            TokenError::MaximumPendingBalanceCreditCounterExceeded => {
383                msg!("The total number of `Deposit` and `Transfer` instructions to an account cannot exceed the associated `maximum_pending_balance_credit_counter`");
384            }
385            TokenError::MaximumDepositAmountExceeded => {
386                msg!("Deposit amount exceeds maximum limit")
387            }
388            TokenError::CpiGuardSettingsLocked => {
389                msg!("CPI Guard status cannot be changed in CPI")
390            }
391            TokenError::CpiGuardTransferBlocked => {
392                msg!("CPI Guard is enabled, and a program attempted to transfer user funds without using a delegate")
393            }
394            TokenError::CpiGuardBurnBlocked => {
395                msg!("CPI Guard is enabled, and a program attempted to burn user funds without using a delegate")
396            }
397            TokenError::CpiGuardCloseAccountBlocked => {
398                msg!("CPI Guard is enabled, and a program attempted to close an account without returning lamports to owner")
399            }
400            TokenError::CpiGuardApproveBlocked => {
401                msg!("CPI Guard is enabled, and a program attempted to approve a delegate")
402            }
403            TokenError::CpiGuardSetAuthorityBlocked => {
404                msg!("CPI Guard is enabled, and a program attempted to add or change an authority")
405            }
406            TokenError::CpiGuardOwnerChangeBlocked => {
407                msg!("Account ownership cannot be changed while CPI Guard is enabled")
408            }
409            TokenError::ExtensionNotFound => {
410                msg!("Extension not found in account data")
411            }
412            TokenError::NonConfidentialTransfersDisabled => {
413                msg!("Non-confidential transfers disabled")
414            }
415            TokenError::ConfidentialTransferFeeAccountHasWithheldFee => {
416                msg!("Account has non-zero confidential withheld fee")
417            }
418            TokenError::InvalidExtensionCombination => {
419                msg!("Mint or account is initialized to an invalid combination of extensions")
420            }
421            TokenError::InvalidLengthForAlloc => {
422                msg!("Extension allocation with overwrite must use the same length")
423            }
424            TokenError::AccountDecryption => {
425                msg!("Failed to decrypt a confidential transfer account")
426            }
427            TokenError::ProofGeneration => {
428                msg!("Failed to generate proof")
429            }
430            TokenError::InvalidProofInstructionOffset => {
431                msg!("An invalid proof instruction offset was provided")
432            }
433            TokenError::HarvestToMintDisabled => {
434                msg!("Harvest of withheld tokens to mint is disabled")
435            }
436            TokenError::SplitProofContextStateAccountsNotSupported => {
437                msg!("Split proof context state accounts not supported for instruction")
438            }
439            TokenError::NotEnoughProofContextStateAccounts => {
440                msg!("Not enough proof context state accounts provided")
441            }
442            TokenError::MalformedCiphertext => {
443                msg!("Ciphertext is malformed")
444            }
445            TokenError::CiphertextArithmeticFailed => {
446                msg!("Ciphertext arithmetic failed")
447            }
448            TokenError::PedersenCommitmentMismatch => {
449                msg!("Pedersen commitments did not match")
450            }
451            TokenError::RangeProofLengthMismatch => {
452                msg!("Range proof lengths did not match")
453            }
454            TokenError::IllegalBitLength => {
455                msg!("Illegal transfer amount bit length")
456            }
457            TokenError::FeeCalculation => {
458                msg!("Transfer fee calculation failed")
459            }
460            TokenError::IllegalMintBurnConversion => {
461                msg!("Conversions from normal to confidential token balance and vice versa are illegal if the confidential-mint-burn extension is enabled")
462            }
463            TokenError::InvalidScale => {
464                msg!("Invalid scale for scaled ui amount")
465            }
466            TokenError::MintPaused => {
467                msg!("Transferring, minting, and burning is paused on this mint")
468            }
469            TokenError::PendingBalanceNonZero => {
470                msg!("Key rotation attempted while pending balance is not zero")
471            }
472        }
473    }
474}
475
476#[cfg(not(target_os = "solana"))]
477impl From<TokenProofGenerationError> for TokenError {
478    fn from(e: TokenProofGenerationError) -> Self {
479        match e {
480            TokenProofGenerationError::ProofGeneration(_) => TokenError::ProofGeneration,
481            TokenProofGenerationError::NotEnoughFunds => TokenError::InsufficientFunds,
482            TokenProofGenerationError::IllegalAmountBitLength => TokenError::IllegalBitLength,
483            TokenProofGenerationError::FeeCalculation => TokenError::FeeCalculation,
484            TokenProofGenerationError::CiphertextExtraction => TokenError::MalformedCiphertext,
485        }
486    }
487}
488
489impl From<TokenProofExtractionError> for TokenError {
490    fn from(e: TokenProofExtractionError) -> Self {
491        match e {
492            TokenProofExtractionError::ElGamalPubkeyMismatch => {
493                TokenError::ConfidentialTransferElGamalPubkeyMismatch
494            }
495            TokenProofExtractionError::PedersenCommitmentMismatch => {
496                TokenError::PedersenCommitmentMismatch
497            }
498            TokenProofExtractionError::RangeProofLengthMismatch => {
499                TokenError::RangeProofLengthMismatch
500            }
501            TokenProofExtractionError::FeeParametersMismatch => TokenError::FeeParametersMismatch,
502            TokenProofExtractionError::CurveArithmetic => TokenError::CiphertextArithmeticFailed,
503            TokenProofExtractionError::CiphertextExtraction => TokenError::MalformedCiphertext,
504        }
505    }
506}
OSZAR »