1use std::fmt::{Debug};
2use strum_macros::{EnumIter, FromRepr};
3use thiserror::Error;
4
5#[repr(u16)]
6#[derive(Copy, Clone, Debug, Error, EnumIter, FromRepr, PartialEq)]
7pub enum ContractError {
8 #[error("No errors")]
9 NoError = 0x0000,
10 #[error("Incorrect account size")]
11 AccountSize = 0x0001,
12 #[error("The smart contract is not the owner of this account")]
13 AccountOwner = 0x0002,
14 #[error("The `isWritable` attribute does not match the expected one passed in the transaction")]
15 AccountWritableAttribute = 0x0003,
16 #[error("Account type is different from expected (determined by tag)")]
17 WrongAccountTag = 0x0004,
18 #[error("The account version is higher than expected by the smart contract")]
19 AccountVersionTooHigh = 0x0005,
20 #[error("The administrator must upgrade this account")]
21 AccountVersionTooLow = 0x0006,
22 #[error("The account is not part of the tree of accounts descended from the root account")]
23 RootAddress = 0x0007,
24 #[error("An attempt to resize the account was unsuccessful")]
25 IncreaseSize = 0x0008,
26 #[error("Incorrect instruction data length")]
27 InstructionDataLength = 0x0009,
28 #[error("For an account with this tag, no actions are provided for this transaction or the tag is invalid")]
29 UnknownAccountTag = 0x000A,
30 #[error("Error sending lamports from the signer's account to the target account")]
31 LamportTransfer = 0x000B,
32 #[error("Incorrect size, version, writable attribute, etc., only for legacy checks")]
33 AccountLegacyError = 0x000C,
34 #[error("Incorrect number of accounts passed to the transaction")]
35 AccountsQuantity = 0x000D,
36 #[error("A specific account is missing")]
37 AccountIsMissing = 0x000E,
38 #[error("There is a discrepancy between the order of the accounts passed to the Oracle instruction and the saved settings. Accounts must be transferred in the same order as the settings for them are specified.")]
39 MismatchOraclesOrder = 0x000F,
40 #[error("The derived PDA does not match the expected account. This may indicate an issue with the seed(s) used for its generation or incorrect account usage.")]
41 InvalidPDA = 0x0010,
42 #[error("The operation could not be completed due to insufficient funds in the involved account(s). This error is raised when an account lacks the necessary lamports to perform actions such as account creation, transaction fees, or lamport transfers.")]
43 InsufficientFunds = 0x0011,
44 #[error("Error while creating a new account")]
45 CreateAccount = 0x0012,
46 #[error("Such an Oracle does not exist (probably the number is greater than or equal to ORACLES_DATA_COUNT)")]
47 SuchOracleDoesNotExists = 0x0013,
48 #[error("Such an Instrument does not exist")]
49 SuchInstrumentDoesNotExists = 0x0014,
50 #[error("Used outdated instruction data format")]
51 InstructionDataVersion = 0x0015,
52 #[error("Operations halted nearing expiration (e.g., maintenance, lockout)")]
53 TradeCloseBeforeExpire = 0x0016,
54 #[error("Trade not possible; the option period has ended, next period yet to start (check option schedule)")]
55 OptionPeriodClosed = 0x0017,
56 #[error("Option order exceeds 0.5% of liquidity pool (reduce order size)")]
57 NotionalValueTooHigh = 0x0018,
58 #[error("Actual trade cost exceeds set maximum limit (adjust limit or price)")]
59 CostLimitExceeded = 0x0019,
60 #[error("Transaction exceeds daily trading limit; register as Power Trader to remove this restriction")]
61 DailyLimitExceeded = 0x001A,
62 #[error("New pool cannot start without initial funding; deposit funds to launch")]
63 PoolFundingRequired = 0x001B,
64 #[error("Cannot determine asset price via oracles; trading halted (oracle not configured or data refresh issue)")]
65 AssetPriceUnavailable = 0x001C,
66 #[error("Failed to read current time in smart contract; operation cannot proceed")]
67 TimeReadError = 0x001D,
68 #[error("Error during calculations (type conversion, division by zero, floating point overflow, etc.)")]
69 ComputationError = 0x001E,
70 #[error("Incorrect oracle number (number too large or negative); oracle does not exist")]
71 InvalidOracleNumber = 0x001F,
72 #[error("Transaction must be executed by platform administrator only, but current signer is not authorized")]
73 AdminOnlyTransaction = 0x0020,
74 #[error("Transaction requires the account to be a signer, but it is not")]
75 AccountNotSigner = 0x0021,
76 #[error("Operation on client account attempted by incorrect client (wrong account sequence, missing, or another client's account)")]
77 UnauthorizedClientOperation = 0x0022,
78 #[error("No record of the targeted pool in client's account")]
79 PoolRecordNotFound = 0x0023,
80 #[error("Significant price variance between oracles exceeds allowable range, preventing trade execution")]
81 PriceDiscrepancyError = 0x0024,
82 #[error("Required oracle for price calculation is not provided in the function call")]
83 MandatoryOracleMissing = 0x0025,
84 #[error("Invalid account ID")]
85 InvalidAccountId = 0x0026,
86 #[error("Invalid mint ID")]
87 InvalidMintId = 0x0027,
88 #[error("Operation with worker account cannot proceed due to incorrect state")]
89 WorkerInvalidState = 0x0028,
90 #[error("Task cannot start before the current date; adjust task start time")]
91 TaskStartBeforeCurrentDate = 0x0029,
92 #[error("Cannot assign new task as the maximum number of workers for the instrument has been reached")]
93 MaxWorkersExceeded = 0x002A,
94 #[error("Specified fee payer for account opening does not match any valid options")]
95 InvalidFeePayerOption = 0x002B,
96 #[error("Cannot finalize pool as it is not active")]
97 InactivePoolCannotFinalize = 0x002C,
98 #[error("Cannot finalize pool as the designated time for finalization has not yet been reached")]
99 PoolFinalizeTimeNotReached = 0x002D,
100 #[error("Provided PDA does not match expected for account creation")]
101 IncorrectExpectedPDA = 0x002E,
102 #[error("Failed to transfer lamports to newly created account for rent exemption")]
103 LamportsTransferFailed = 0x002F,
104 #[error("Created account size does not match the expected size")]
105 CreatedAccountSizeMismatch = 0x0030,
106 #[error("Attempting to execute a trade with zero volume is not allowed")]
107 ZeroVolumeTradeAttempt = 0x0031,
108 #[error("Trade operation attempted outside allowed activity hours or while pool is inactive")]
109 TradeOutsideActivePeriod = 0x0032,
110 #[error("Cannot participate in more than 128 pools simultaneously as LP")]
111 MaxPoolsParticipationReached= 0x0033,
112 #[error("Attempt to sell more pool tokens than owned")]
113 PoolTokenSaleExceedsHoldings= 0x0034,
114 #[error("Trade exceeds maximum allowed deposit in pool, cannot proceed")]
115 DepositExceedsPoolLimit = 0x0035,
116 #[error("Worker account in transaction does not match the one specified in instruction")]
117 WorkerAccountMismatch = 0x0036,
118 #[error("Specified pool index exceeds maximum limit or is not valid")]
119 PoolIndexOutOfRange = 0x0037,
120 #[error("Cannot proceed; settlement price not set or pool yet to be finalized")]
121 SettlementPriceUnavailable = 0x0038,
122 #[error("Attempt to claim payoff before pool expiration is not allowed")]
123 EarlyPayoffAttempt = 0x0039,
124 #[error("Invalid access to pool data for the client or worker account")]
125 InvalidPoolAccess = 0x003A,
126 #[error("Worker state is not valid for task assignment; must be in 'Assigned' state")]
127 WorkerInvalidStateForTask = 0x003B,
128 #[error("Worker's task duration cannot be zero; set a valid duration")]
129 WorkerDurationZero = 0x003C,
130 #[error("Worker's initial offering price cannot be below ID; ensure correct price setup")]
131 WorkerInitPxBelowID = 0x003D,
132 #[error("Worker's width factor cannot exceed ID; adjust width factor")]
133 WorkerWidthFactorExceedsID = 0x003E,
134 #[error("Worker's fee rate is out of acceptable bounds; ensure fee rate is within limits")]
135 WorkerFeeRateOutOfBounds = 0x003F,
136 #[error("Worker's fee ratio is out of acceptable bounds; adjust fee ratio to fit within limits")]
137 WorkerFeeRatioOutOfBounds = 0x0040,
138 #[error("Worker's inventories ratio is out of acceptable bounds; ensure inventories ratio is within limits")]
139 WorkerInvRatioOutOfBounds = 0x0041,
140 #[error("Transaction must be executed by KYC administrator only, but current signer is not authorized")]
141 KycAdminOnlyTransaction = 0x0042,
142 #[error("Token account owner does not match expected SPL Token program")]
143 TokenOwnerMismatch = 0x0043,
144 #[error("Token account's mint does not match the specified mint account")]
145 TokenMintMismatch = 0x0044,
146 #[error("Account is not initialized")]
147 AccountUninitialized = 0x0045,
148 #[error("Token account's public key does not match the expected")]
149 TokenPkMismatch = 0x0046,
150 #[error("Program token account does not match the specified program account")]
151 ProgramTokenAccMismatch = 0x0047,
152 #[error("Token transfer failed")]
153 TransferFailed = 0x0048,
154 #[error("Token transfer execution failed")]
155 TransferExecutionFailed = 0x0049,
156 #[error("Insufficient balance for withdrawal")]
157 InsufficientBalance = 0x004A,
158 #[error("Attempted to invoke a non-existent smart contract instruction; check the instruction number")]
159 InvalidInstruction = 0x004B,
160 #[error("Migration is not implemented for this account or version, please check SDK")]
161 MigrationNotImplemented = 0x004C,
162 #[error("Current version of the migrating account doesn't match, please check SDK")]
163 InvalidOldMigrationVersion = 0x004D,
164 #[error("New version of the migrating account doesn't match, please check SDK")]
165 InvalidNewMigrationVersion = 0x004E,
166 #[error("Migration is not successful, please check SDK")]
167 MigrationFailed = 0x004F,
168 #[error("Invalid strike id in the basket, must be less than BUCKETS_COUNT")]
169 InvalidBasketStrikeId = 0x0050,
170 #[error("Trading basket length is greater than Pool Log can save")]
171 BasketLengthIsTooBig = 0x0051,
172
173 #[error("Test abort")]
174 TestAbort = 0xFFFE,
175 #[error("Unknown error code, please update SDK version to get detailed message")]
177 UnknownError = 0xFFFF,
178
179}
180
181#[repr(u8)]
182#[derive(Copy, Clone, Debug, EnumIter, FromRepr, PartialEq)]
183pub enum AccountTag {
184 Root = 0x00,
186 Mints = 0x01,
187 Instruments = 0x02,
188 AllWorkers = 0x03,
189 PoolsTrace = 0x04,
190 TasksTrace = 0x05,
191 PoolsLog = 0x06,
192 Worker = 0x07,
193 Client = 0x08,
194 PayoffLog = 0x09,
195 MintLog = 0x0A,
196 TasksLog = 0x0B,
197 TradeLog = 0x0C,
198 Oracle = 0x0D,
199 Admin = 0x0E, SystemProgram = 0x0F, Target = 0x10, ExternalOracle = 0x11,
204 Wallet = 0x12, KycAdmin = 0x13, ClientToken = 0x14,
207 ProgramToken = 0x15,
208 Buffer = 0x16,
209 AccountDecodeError = 0xFF, }
212
213impl AccountTag {
214 pub fn from_u8(value: u8) -> Self {
215 let tag = Self::from_repr(value);
216 if let Some(tag) = tag {
217 tag
218 } else {
219 Self::AccountDecodeError
220 }
221 }
222}
223
224impl ContractError {
225 pub fn from_u16(value: u16) -> Self {
226 let error_code = Self::from_repr(value);
227 if let Some(error_code) = error_code {
228 error_code
229 } else {
230 Self::UnknownError
231 }
232 }
233}
234
235#[cfg(test)]
236mod tests {
237 use crate::dvl_error::DvlError;
238 use crate::errors::{AccountTag, ContractError};
239
240 #[test]
241 fn test_display_error() {
242 let error = DvlError::new_with_account(AccountTag::MintLog, ContractError::AccountSize);
243 assert_eq!(format!("{}", error), "Error: Incorrect account size, Account: MintLog");
244 }
245}