274 lines
12 KiB
Rust
274 lines
12 KiB
Rust
//! Error types
|
|
|
|
use {
|
|
num_derive::FromPrimitive,
|
|
solana_program::{
|
|
decode_error::DecodeError,
|
|
msg,
|
|
program_error::{PrintProgramError, ProgramError},
|
|
},
|
|
thiserror::Error,
|
|
};
|
|
|
|
/// Errors that may be returned by the Token program.
|
|
#[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)]
|
|
pub enum TokenError {
|
|
// 0
|
|
/// Lamport balance below rent-exempt threshold.
|
|
#[error("Lamport balance below rent-exempt threshold")]
|
|
NotRentExempt,
|
|
/// Insufficient funds for the operation requested.
|
|
#[error("Insufficient funds")]
|
|
InsufficientFunds,
|
|
/// Invalid Mint.
|
|
#[error("Invalid Mint")]
|
|
InvalidMint,
|
|
/// Account not associated with this Mint.
|
|
#[error("Account not associated with this Mint")]
|
|
MintMismatch,
|
|
/// Owner does not match.
|
|
#[error("Owner does not match")]
|
|
OwnerMismatch,
|
|
|
|
// 5
|
|
/// This token's supply is fixed and new tokens cannot be minted.
|
|
#[error("Fixed supply")]
|
|
FixedSupply,
|
|
/// The account cannot be initialized because it is already being used.
|
|
#[error("Already in use")]
|
|
AlreadyInUse,
|
|
/// Invalid number of provided signers.
|
|
#[error("Invalid number of provided signers")]
|
|
InvalidNumberOfProvidedSigners,
|
|
/// Invalid number of required signers.
|
|
#[error("Invalid number of required signers")]
|
|
InvalidNumberOfRequiredSigners,
|
|
/// State is uninitialized.
|
|
#[error("State is unititialized")]
|
|
UninitializedState,
|
|
|
|
// 10
|
|
/// Instruction does not support native tokens
|
|
#[error("Instruction does not support native tokens")]
|
|
NativeNotSupported,
|
|
/// Non-native account can only be closed if its balance is zero
|
|
#[error("Non-native account can only be closed if its balance is zero")]
|
|
NonNativeHasBalance,
|
|
/// Invalid instruction
|
|
#[error("Invalid instruction")]
|
|
InvalidInstruction,
|
|
/// State is invalid for requested operation.
|
|
#[error("State is invalid for requested operation")]
|
|
InvalidState,
|
|
/// Operation overflowed
|
|
#[error("Operation overflowed")]
|
|
Overflow,
|
|
|
|
// 15
|
|
/// Account does not support specified authority type.
|
|
#[error("Account does not support specified authority type")]
|
|
AuthorityTypeNotSupported,
|
|
/// This token mint cannot freeze accounts.
|
|
#[error("This token mint cannot freeze accounts")]
|
|
MintCannotFreeze,
|
|
/// Account is frozen; all account operations will fail
|
|
#[error("Account is frozen")]
|
|
AccountFrozen,
|
|
/// Mint decimals mismatch between the client and mint
|
|
#[error("The provided decimals value different from the Mint decimals")]
|
|
MintDecimalsMismatch,
|
|
/// Instruction does not support non-native tokens
|
|
#[error("Instruction does not support non-native tokens")]
|
|
NonNativeNotSupported,
|
|
|
|
// 20
|
|
/// Extension type does not match already existing extensions
|
|
#[error("Extension type does not match already existing extensions")]
|
|
ExtensionTypeMismatch,
|
|
/// Extension does not match the base type provided
|
|
#[error("Extension does not match the base type provided")]
|
|
ExtensionBaseMismatch,
|
|
/// Extension already initialized on this account
|
|
#[error("Extension already initialized on this account")]
|
|
ExtensionAlreadyInitialized,
|
|
/// An account can only be closed if its confidential balance is zero
|
|
#[error("An account can only be closed if its confidential balance is zero")]
|
|
ConfidentialTransferAccountHasBalance,
|
|
/// Account not approved for confidential transfers
|
|
#[error("Account not approved for confidential transfers")]
|
|
ConfidentialTransferAccountNotApproved,
|
|
|
|
// 25
|
|
/// Account not accepting deposits or transfers
|
|
#[error("Account not accepting deposits or transfers")]
|
|
ConfidentialTransferDepositsAndTransfersDisabled,
|
|
/// ElGamal public key mismatch
|
|
#[error("ElGamal public key mismatch")]
|
|
ConfidentialTransferElGamalPubkeyMismatch,
|
|
/// Balance mismatch
|
|
#[error("Balance mismatch")]
|
|
ConfidentialTransferBalanceMismatch,
|
|
/// Mint has non-zero supply. Burn all tokens before closing the mint.
|
|
#[error("Mint has non-zero supply. Burn all tokens before closing the mint")]
|
|
MintHasSupply,
|
|
/// No authority exists to perform the desired operation
|
|
#[error("No authority exists to perform the desired operation")]
|
|
NoAuthorityExists,
|
|
|
|
// 30
|
|
/// Transfer fee exceeds maximum of 10,000 basis points
|
|
#[error("Transfer fee exceeds maximum of 10,000 basis points")]
|
|
TransferFeeExceedsMaximum,
|
|
/// Mint required for this account to transfer tokens, use `transfer_checked` or `transfer_checked_with_fee`
|
|
#[error("Mint required for this account to transfer tokens, use `transfer_checked` or `transfer_checked_with_fee`")]
|
|
MintRequiredForTransfer,
|
|
/// Calculated fee does not match expected fee
|
|
#[error("Calculated fee does not match expected fee")]
|
|
FeeMismatch,
|
|
/// Fee parameters associated with confidential transfer zero-knowledge proofs do not match fee parameters in mint
|
|
#[error(
|
|
"Fee parameters associated with zero-knowledge proofs do not match fee parameters in mint"
|
|
)]
|
|
FeeParametersMismatch,
|
|
/// The owner authority cannot be changed
|
|
#[error("The owner authority cannot be changed")]
|
|
ImmutableOwner,
|
|
|
|
// 35
|
|
/// An account can only be closed if its withheld fee balance is zero, harvest fees to the
|
|
/// mint and try again
|
|
#[error("An account can only be closed if its withheld fee balance is zero, harvest fees to the mint and try again")]
|
|
AccountHasWithheldTransferFees,
|
|
|
|
/// No memo in previous instruction; required for recipient to receive a transfer
|
|
#[error("No memo in previous instruction; required for recipient to receive a transfer")]
|
|
NoMemo,
|
|
/// Transfer is disabled for this mint
|
|
#[error("Transfer is disabled for this mint")]
|
|
NonTransferable,
|
|
/// Non-transferable tokens can't be minted to an account without immutable ownership
|
|
#[error("Non-transferable tokens can't be minted to an account without immutable ownership")]
|
|
NonTransferableNeedsImmutableOwnership,
|
|
/// The total number of `Deposit` and `Transfer` instructions to an account cannot exceed the
|
|
/// associated `maximum_pending_balance_credit_counter`
|
|
#[error(
|
|
"The total number of `Deposit` and `Transfer` instructions to an account cannot exceed
|
|
the associated `maximum_pending_balance_credit_counter`"
|
|
)]
|
|
MaximumPendingBalanceCreditCounterExceeded,
|
|
}
|
|
impl From<TokenError> for ProgramError {
|
|
fn from(e: TokenError) -> Self {
|
|
ProgramError::Custom(e as u32)
|
|
}
|
|
}
|
|
impl<T> DecodeError<T> for TokenError {
|
|
fn type_of() -> &'static str {
|
|
"TokenError"
|
|
}
|
|
}
|
|
|
|
impl PrintProgramError for TokenError {
|
|
fn print<E>(&self)
|
|
where
|
|
E: 'static + std::error::Error + DecodeError<E> + num_traits::FromPrimitive,
|
|
{
|
|
match self {
|
|
TokenError::NotRentExempt => msg!("Error: Lamport balance below rent-exempt threshold"),
|
|
TokenError::InsufficientFunds => msg!("Error: insufficient funds"),
|
|
TokenError::InvalidMint => msg!("Error: Invalid Mint"),
|
|
TokenError::MintMismatch => msg!("Error: Account not associated with this Mint"),
|
|
TokenError::OwnerMismatch => msg!("Error: owner does not match"),
|
|
TokenError::FixedSupply => msg!("Error: the total supply of this token is fixed"),
|
|
TokenError::AlreadyInUse => msg!("Error: account or token already in use"),
|
|
TokenError::InvalidNumberOfProvidedSigners => {
|
|
msg!("Error: Invalid number of provided signers")
|
|
}
|
|
TokenError::InvalidNumberOfRequiredSigners => {
|
|
msg!("Error: Invalid number of required signers")
|
|
}
|
|
TokenError::UninitializedState => msg!("Error: State is uninitialized"),
|
|
TokenError::NativeNotSupported => {
|
|
msg!("Error: Instruction does not support native tokens")
|
|
}
|
|
TokenError::NonNativeHasBalance => {
|
|
msg!("Error: Non-native account can only be closed if its balance is zero")
|
|
}
|
|
TokenError::InvalidInstruction => msg!("Error: Invalid instruction"),
|
|
TokenError::InvalidState => msg!("Error: Invalid account state for operation"),
|
|
TokenError::Overflow => msg!("Error: Operation overflowed"),
|
|
TokenError::AuthorityTypeNotSupported => {
|
|
msg!("Error: Account does not support specified authority type")
|
|
}
|
|
TokenError::MintCannotFreeze => msg!("Error: This token mint cannot freeze accounts"),
|
|
TokenError::AccountFrozen => msg!("Error: Account is frozen"),
|
|
TokenError::MintDecimalsMismatch => {
|
|
msg!("Error: decimals different from the Mint decimals")
|
|
}
|
|
TokenError::NonNativeNotSupported => {
|
|
msg!("Error: Instruction does not support non-native tokens")
|
|
}
|
|
TokenError::ExtensionTypeMismatch => {
|
|
msg!("Error: New extension type does not match already existing extensions")
|
|
}
|
|
TokenError::ExtensionBaseMismatch => {
|
|
msg!("Error: Extension does not match the base type provided")
|
|
}
|
|
TokenError::ExtensionAlreadyInitialized => {
|
|
msg!("Error: Extension already initialized on this account")
|
|
}
|
|
TokenError::ConfidentialTransferAccountHasBalance => {
|
|
msg!("Error: An account can only be closed if its confidential balance is zero")
|
|
}
|
|
TokenError::ConfidentialTransferAccountNotApproved => {
|
|
msg!("Error: Account not approved for confidential transfers")
|
|
}
|
|
TokenError::ConfidentialTransferDepositsAndTransfersDisabled => {
|
|
msg!("Error: Account not accepting deposits or transfers")
|
|
}
|
|
TokenError::ConfidentialTransferElGamalPubkeyMismatch => {
|
|
msg!("Error: ElGamal public key mismatch")
|
|
}
|
|
TokenError::ConfidentialTransferBalanceMismatch => {
|
|
msg!("Error: Balance mismatch")
|
|
}
|
|
TokenError::MintHasSupply => {
|
|
msg!("Error: Mint has non-zero supply. Burn all tokens before closing the mint")
|
|
}
|
|
TokenError::NoAuthorityExists => {
|
|
msg!("Error: No authority exists to perform the desired operation");
|
|
}
|
|
TokenError::TransferFeeExceedsMaximum => {
|
|
msg!("Error: Transfer fee exceeds maximum of 10,000 basis points");
|
|
}
|
|
TokenError::MintRequiredForTransfer => {
|
|
msg!("Mint required for this account to transfer tokens, use `transfer_checked` or `transfer_checked_with_fee`");
|
|
}
|
|
TokenError::FeeMismatch => {
|
|
msg!("Calculated fee does not match expected fee");
|
|
}
|
|
TokenError::FeeParametersMismatch => {
|
|
msg!("Fee parameters associated with zero-knowledge proofs do not match fee parameters in mint")
|
|
}
|
|
TokenError::ImmutableOwner => {
|
|
msg!("The owner authority cannot be changed");
|
|
}
|
|
TokenError::AccountHasWithheldTransferFees => {
|
|
msg!("Error: An account can only be closed if its withheld fee balance is zero, harvest fees to the mint and try again");
|
|
}
|
|
TokenError::NoMemo => {
|
|
msg!("Error: No memo in previous instruction; required for recipient to receive a transfer");
|
|
}
|
|
TokenError::NonTransferable => {
|
|
msg!("Transfer is disabled for this mint");
|
|
}
|
|
TokenError::NonTransferableNeedsImmutableOwnership => {
|
|
msg!("Non-transferable tokens can't be minted to an account without immutable ownership");
|
|
}
|
|
TokenError::MaximumPendingBalanceCreditCounterExceeded => {
|
|
msg!("The total number of `Deposit` and `Transfer` instructions to an account cannot exceed the associated `maximum_pending_balance_credit_counter`");
|
|
}
|
|
}
|
|
}
|
|
}
|