Skip to main content

spl_stake_pool/
error.rs

1//! Error types
2
3use {
4    num_derive::FromPrimitive,
5    solana_program_error::{ProgramError, ToStr},
6    thiserror::Error,
7};
8
9/// Errors that may be returned by the Stake Pool program.
10#[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)]
11pub enum StakePoolError {
12    // 0.
13    /// The account cannot be initialized because it is already being used.
14    #[error("AlreadyInUse")]
15    AlreadyInUse,
16    /// The program address provided doesn't match the value generated by the
17    /// program.
18    #[error("InvalidProgramAddress")]
19    InvalidProgramAddress,
20    /// The stake pool state is invalid.
21    #[error("InvalidState")]
22    InvalidState,
23    /// The calculation failed.
24    #[error("CalculationFailure")]
25    CalculationFailure,
26    /// Stake pool fee greater than 1.
27    #[error("FeeTooHigh")]
28    FeeTooHigh,
29
30    // 5.
31    /// Token account is associated with the wrong mint.
32    #[error("WrongAccountMint")]
33    WrongAccountMint,
34    /// Wrong pool manager account.
35    #[error("WrongManager")]
36    WrongManager,
37    /// Required signature is missing.
38    #[error("SignatureMissing")]
39    SignatureMissing,
40    /// Invalid validator stake list account.
41    #[error("InvalidValidatorStakeList")]
42    InvalidValidatorStakeList,
43    /// Invalid manager fee account.
44    #[error("InvalidFeeAccount")]
45    InvalidFeeAccount,
46
47    // 10.
48    /// Specified pool mint account is wrong.
49    #[error("WrongPoolMint")]
50    WrongPoolMint,
51    /// Stake account is not in the state expected by the program.
52    #[error("WrongStakeStake")]
53    WrongStakeStake,
54    /// User stake is not active
55    #[error("UserStakeNotActive")]
56    UserStakeNotActive,
57    /// Stake account voting for this validator already exists in the pool.
58    #[error("ValidatorAlreadyAdded")]
59    ValidatorAlreadyAdded,
60    /// Stake account for this validator not found in the pool.
61    #[error("ValidatorNotFound")]
62    ValidatorNotFound,
63
64    // 15.
65    /// Stake account address not properly derived from the validator address.
66    #[error("InvalidStakeAccountAddress")]
67    InvalidStakeAccountAddress,
68    /// Identify validator stake accounts with old balances and update them.
69    #[error("StakeListOutOfDate")]
70    StakeListOutOfDate,
71    /// First update old validator stake account balances and then pool stake
72    /// balance.
73    #[error("StakeListAndPoolOutOfDate")]
74    StakeListAndPoolOutOfDate,
75    /// Validator stake account is not found in the list storage.
76    #[error("UnknownValidatorStakeAccount")]
77    UnknownValidatorStakeAccount,
78    /// Wrong minting authority set for mint pool account
79    #[error("WrongMintingAuthority")]
80    WrongMintingAuthority,
81
82    // 20.
83    /// The size of the given validator stake list does match the expected
84    /// amount
85    #[error("UnexpectedValidatorListAccountSize")]
86    UnexpectedValidatorListAccountSize,
87    /// Wrong pool staker account.
88    #[error("WrongStaker")]
89    WrongStaker,
90    /// Pool token supply is not zero on initialization
91    #[error("NonZeroPoolTokenSupply")]
92    NonZeroPoolTokenSupply,
93    /// The lamports in the validator stake account is not equal to the minimum
94    #[error("StakeLamportsNotEqualToMinimum")]
95    StakeLamportsNotEqualToMinimum,
96    /// The provided deposit stake account is not delegated to the preferred
97    /// deposit vote account
98    #[error("IncorrectDepositVoteAddress")]
99    IncorrectDepositVoteAddress,
100
101    // 25.
102    /// The provided withdraw stake account is not the preferred deposit vote
103    /// account
104    #[error("IncorrectWithdrawVoteAddress")]
105    IncorrectWithdrawVoteAddress,
106    /// The mint has an invalid freeze authority
107    #[error("InvalidMintFreezeAuthority")]
108    InvalidMintFreezeAuthority,
109    /// Proposed fee increase exceeds stipulated ratio
110    #[error("FeeIncreaseTooHigh")]
111    FeeIncreaseTooHigh,
112    /// Not enough pool tokens provided to withdraw stake with one lamport
113    #[error("WithdrawalTooSmall")]
114    WithdrawalTooSmall,
115    /// Not enough lamports provided for deposit to result in one pool token
116    #[error("DepositTooSmall")]
117    DepositTooSmall,
118
119    // 30.
120    /// Provided stake deposit authority does not match the program's
121    #[error("InvalidStakeDepositAuthority")]
122    InvalidStakeDepositAuthority,
123    /// Provided sol deposit authority does not match the program's
124    #[error("InvalidSolDepositAuthority")]
125    InvalidSolDepositAuthority,
126    /// Provided preferred validator is invalid
127    #[error("InvalidPreferredValidator")]
128    InvalidPreferredValidator,
129    /// Provided validator stake account already has a transient stake account
130    /// in use
131    #[error("TransientAccountInUse")]
132    TransientAccountInUse,
133    /// Provided sol withdraw authority does not match the program's
134    #[error("InvalidSolWithdrawAuthority")]
135    InvalidSolWithdrawAuthority,
136
137    // 35.
138    /// Too much SOL withdrawn from the stake pool's reserve account
139    #[error("SolWithdrawalTooLarge")]
140    SolWithdrawalTooLarge,
141    /// Provided metadata account does not match metadata account derived for
142    /// pool mint
143    #[error("InvalidMetadataAccount")]
144    InvalidMetadataAccount,
145    /// The mint has an unsupported extension
146    #[error("UnsupportedMintExtension")]
147    UnsupportedMintExtension,
148    /// The fee account has an unsupported extension
149    #[error("UnsupportedFeeAccountExtension")]
150    UnsupportedFeeAccountExtension,
151    /// Instruction exceeds desired slippage limit
152    #[error("Instruction exceeds desired slippage limit")]
153    ExceededSlippage,
154
155    // 40.
156    /// Provided mint does not have 9 decimals to match SOL
157    #[error("IncorrectMintDecimals")]
158    IncorrectMintDecimals,
159    /// Pool reserve does not have enough lamports to fund rent-exempt reserve
160    /// in split destination. Deposit more SOL in reserve, or pre-fund split
161    /// destination with the rent-exempt reserve for a stake account.
162    #[error("ReserveDepleted")]
163    ReserveDepleted,
164    /// Missing required sysvar account
165    #[error("Missing required sysvar account")]
166    MissingRequiredSysvar,
167    /// Epoch reward distribution is currently in progress, stakes are still being updated
168    #[error("Epoch reward distribution is currently in progress, stakes are still being updated")]
169    EpochRewardDistributionInProgress,
170    /// The stake pool has too many validators in the pool
171    #[error("The stake pool has too many validators in the pool")]
172    TooManyValidatorsInPool,
173}
174impl From<StakePoolError> for ProgramError {
175    fn from(e: StakePoolError) -> Self {
176        ProgramError::Custom(e as u32)
177    }
178}
179impl TryFrom<u32> for StakePoolError {
180    type Error = ProgramError;
181    fn try_from(code: u32) -> Result<Self, Self::Error> {
182        num_traits::FromPrimitive::from_u32(code).ok_or(ProgramError::InvalidArgument)
183    }
184}
185impl ToStr for StakePoolError {
186    fn to_str(&self) -> &'static str {
187        match self {
188            // 0.
189            Self::AlreadyInUse => "Error: The account cannot be initialized because it is already being used.",
190            Self::InvalidProgramAddress => "Error: The program address provided doesn't match the value generated by the program.",
191            Self::InvalidState => "Error: The stake pool state is invalid.",
192            Self::CalculationFailure => "Error: The calculation failed.",
193            Self::FeeTooHigh => "Error: Stake pool fee greater than 1.",
194
195            // 5.
196            Self::WrongAccountMint => "Error: Token account is associated with the wrong mint.",
197            Self::WrongManager => "Error: Wrong pool manager account.",
198            Self::SignatureMissing => "Error: Required signature is missing.",
199            Self::InvalidValidatorStakeList => "Error: Invalid validator stake list account.",
200            Self::InvalidFeeAccount => "Error: Invalid manager fee account.",
201
202            // 10.
203            Self::WrongPoolMint => "Error: Specified pool mint account is wrong.",
204            Self::WrongStakeStake => "Error: Stake account is not in the state expected by the program.",
205            Self::UserStakeNotActive => "Error: User stake is not active",
206            Self::ValidatorAlreadyAdded => "Error: Stake account voting for this validator already exists in the pool.",
207            Self::ValidatorNotFound => "Error: Stake account for this validator not found in the pool.",
208
209            // 15.
210            Self::InvalidStakeAccountAddress => "Error: Stake account address not properly derived from the validator address.",
211            Self::StakeListOutOfDate => "Error: Identify validator stake accounts with old balances and update them.",
212            Self::StakeListAndPoolOutOfDate => "Error: First update old validator stake account balances and then pool stake balance.",
213            Self::UnknownValidatorStakeAccount => "Error: Validator stake account is not found in the list storage.",
214            Self::WrongMintingAuthority => "Error: Wrong minting authority set for mint pool account",
215
216            // 20.
217            Self::UnexpectedValidatorListAccountSize => "Error: The size of the given validator stake list does match the expected amount",
218            Self::WrongStaker => "Error: Wrong pool staker account.",
219            Self::NonZeroPoolTokenSupply => "Error: Pool token supply is not zero on initialization",
220            Self::StakeLamportsNotEqualToMinimum => "Error: The lamports in the validator stake account is not equal to the minimum",
221            Self::IncorrectDepositVoteAddress => "Error: The provided deposit stake account is not delegated to the preferred deposit vote account",
222
223            // 25.
224            Self::IncorrectWithdrawVoteAddress => "Error: The provided withdraw stake account is not the preferred deposit vote account",
225            Self::InvalidMintFreezeAuthority => "Error: The mint has an invalid freeze authority",
226            Self::FeeIncreaseTooHigh => "Error: Proposed fee increase exceeds stipulated ratio",
227            Self::WithdrawalTooSmall => "Error: Not enough pool tokens provided to withdraw stake with one lamport",
228            Self::DepositTooSmall => "Error: Not enough lamports provided for deposit to result in one pool token",
229
230            // 30.
231            Self::InvalidStakeDepositAuthority => "Error: Provided stake deposit authority does not match the program's",
232            Self::InvalidSolDepositAuthority => "Error: Provided sol deposit authority does not match the program's",
233            Self::InvalidPreferredValidator => "Error: Provided preferred validator is invalid",
234            Self::TransientAccountInUse => "Error: Provided validator stake account already has a transient stake account in use",
235            Self::InvalidSolWithdrawAuthority => "Error: Provided sol withdraw authority does not match the program's",
236
237            // 35.
238            Self::SolWithdrawalTooLarge => "Error: Too much SOL withdrawn from the stake pool's reserve account",
239            Self::InvalidMetadataAccount => "Error: Provided metadata account does not match metadata account derived for pool mint",
240            Self::UnsupportedMintExtension => "Error: The mint has an unsupported extension",
241            Self::UnsupportedFeeAccountExtension => "Error: The fee account has an unsupported extension",
242            Self::ExceededSlippage => "Error: Instruction exceeds desired slippage limit",
243
244            // 40.
245            Self::IncorrectMintDecimals => "Error: Provided mint does not have 9 decimals to match SOL",
246            Self::ReserveDepleted => "Error: Pool reserve does not have enough lamports to fund rent-exempt reserve in split destination. Deposit more SOL in reserve, or pre-fund split destination with the rent-exempt reserve for a stake account.",
247            Self::MissingRequiredSysvar => "Error: Missing required sysvar account",
248            Self::EpochRewardDistributionInProgress => "Error: Epoch reward distribution is currently in progress, stakes are still being updated",
249            Self::TooManyValidatorsInPool => "Error: The stake pool has too many validators in the pool",
250        }
251    }
252}