1#![deny(unused_must_use)]
20#![deny(clippy::all)]
21#![allow(clippy::bool_assert_comparison)]
22#![allow(non_camel_case_types)]
23#![allow(clippy::too_many_arguments)]
24
25pub mod atrix;
26pub mod lending;
27pub mod orca;
28pub mod quarry;
29pub mod raydium;
30pub mod unknown;
31
32use crate::{
33 atrix::Atrix, lending::Lending, orca::Orca, quarry::Quarry, raydium::Raydium, unknown::Unknown,
34};
35use anchor_lang::prelude::*;
36use tulip_arrform::{arrform, ArrForm};
37
38#[derive(Clone, Copy, PartialEq, Eq, AnchorSerialize, AnchorDeserialize, Debug)]
39pub enum Farm {
42 Raydium {
45 name: Raydium,
47 },
48 Lending {
51 name: Lending,
53 },
54 Orca {
57 name: Orca,
59 },
60 Quarry {
63 name: Quarry,
65 },
66 Atrix {
69 name: Atrix,
71 },
72 Unknown { name: Unknown },
75}
76
77impl Farm {
78 pub fn name(&self) -> String {
79 self.to_string()
80 }
81 pub fn market_name(&self) -> Option<String> {
89 if let Farm::Raydium { name: _name } = self {
90 let name = self.name();
91 let lp_name_parts: Vec<_> = name.split('-').collect();
92 if lp_name_parts.len() < 2 {
93 return None;
94 }
95 return Some(farm_identifier_stripper(&name, &lp_name_parts));
96 }
97 if let Farm::Orca { name: _name } = self {
98 let name = self.name();
99 let lp_name_parts: Vec<_> = name.split('-').collect();
100 if lp_name_parts.len() < 2 {
101 return None;
102 }
103 return Some(farm_identifier_stripper(&name, &lp_name_parts));
104 }
105 if let Farm::Lending { name } = self {
106 return Some(name.name());
107 }
108 if let Farm::Quarry { name } = self {
109 return Some(name.name());
110 }
111 if let Farm::Atrix { name } = self {
112 return Some(name.name());
113 }
114 None
115 }
116 pub fn serialize(&self) -> std::result::Result<Vec<u8>, std::io::Error> {
117 let wire_type: [u64; 2] = (*self).into();
118 let mut data_bytes = Vec::with_capacity(16);
119 data_bytes.extend_from_slice(&AnchorSerialize::try_to_vec(&wire_type[0])?);
120 data_bytes.extend_from_slice(&AnchorSerialize::try_to_vec(&wire_type[1])?);
121 Ok(data_bytes)
122 }
123}
124
125impl ToString for Farm {
126 fn to_string(&self) -> String {
127 match self {
128 Farm::Raydium { name } => arrform!(128, "RAYDIUM-{}", name.name()).as_str().to_owned(),
129 Farm::Lending { name } => arrform!(128, "LENDING-{}", name.name()).as_str().to_owned(),
130 Farm::Orca { name } => arrform!(128, "ORCA-{}", name.name()).as_str().to_owned(),
131 Farm::Quarry { name } => arrform!(128, "QUARRY-{}", name.name()).as_str().to_owned(),
132 Farm::Atrix { name } => arrform!(128, "ATRIX-{}", name.name()).as_str().to_owned(),
133 _ => String::from("UNKNOWN"),
134 }
135 }
136}
137
138impl From<&String> for Farm {
139 fn from(val: &String) -> Self {
140 farm_from_str(val)
141 }
142}
143
144impl From<&str> for Farm {
145 fn from(val: &str) -> Self {
146 farm_from_str(val)
147 }
148}
149
150impl Default for Farm {
151 fn default() -> Self {
152 Self::Unknown {
153 name: Unknown::Unknown,
154 }
155 }
156}
157
158impl From<Raydium> for Farm {
159 fn from(val: Raydium) -> Self {
160 Farm::Raydium { name: val }
161 }
162}
163
164impl From<Lending> for Farm {
165 fn from(val: Lending) -> Self {
166 Farm::Lending { name: val }
167 }
168}
169
170impl From<Orca> for Farm {
171 fn from(val: Orca) -> Self {
172 Farm::Orca { name: val }
173 }
174}
175
176impl From<Quarry> for Farm {
177 fn from(val: Quarry) -> Self {
178 Farm::Quarry { name: val }
179 }
180}
181
182impl From<[u64; 2]> for Farm {
183 fn from(val: [u64; 2]) -> Self {
184 match val[0] {
185 0 => Farm::Raydium {
186 name: val[1].into(),
187 },
188 1 => Farm::Lending {
189 name: val[1].into(),
190 },
191 2 => Farm::Orca {
192 name: val[1].into(),
193 },
194 3 => Farm::Quarry {
195 name: val[1].into(),
196 },
197 4 => Farm::Atrix {
198 name: val[1].into(),
199 },
200 _ => Farm::Unknown {
201 name: Unknown::Unknown,
202 },
203 }
204 }
205}
206
207impl From<Farm> for [u64; 2] {
208 fn from(value: Farm) -> Self {
209 match value {
210 Farm::Raydium { name } => [0_u64, name.into()],
211 Farm::Lending { name } => [1_u64, name.into()],
212 Farm::Orca { name } => [2_u64, name.into()],
213 Farm::Quarry { name } => [3_u64, name.into()],
214 Farm::Atrix { name } => [4_u64, name.into()],
215 _ => [u64::MAX, u64::MAX],
216 }
217 }
218}
219
220pub fn farm_identifier_stripper(farm_type: &str, parts: &[&str]) -> String {
222 let mut farm_name = String::with_capacity(farm_type.len() - parts[0].len());
223 for (idx, part) in parts.iter().enumerate() {
224 if idx == 0 {
225 continue;
226 }
227 farm_name.push_str(part);
228 if idx < parts.len() - 1 {
229 farm_name.push('-');
230 }
231 }
232 farm_name
233}
234
235fn farm_from_str(val: &str) -> Farm {
236 let parts: Vec<_> = val.split('-').collect();
237 if parts.len() <= 1 {
238 return Farm::Unknown {
239 name: Unknown::Unknown,
240 };
241 }
242 match parts[0] {
243 "RAYDIUM" => {
244 let farm_name = farm_identifier_stripper(val, &parts);
245 Farm::Raydium {
246 name: Raydium::from(farm_name.as_str()),
247 }
248 }
249 "LENDING" => {
250 let farm_name = farm_identifier_stripper(val, &parts);
251 Farm::Lending {
252 name: Lending::from(farm_name.as_str()),
253 }
254 }
255 "ORCA" => {
256 let farm_name = farm_identifier_stripper(val, &parts);
257 Farm::Orca {
258 name: Orca::from(farm_name.as_str()),
259 }
260 }
261 "QUARRY" => {
262 let farm_name = farm_identifier_stripper(val, &parts);
263 Farm::Quarry {
264 name: Quarry::from(farm_name.as_str()),
265 }
266 }
267 "ATRIX" => {
268 let farm_name = farm_identifier_stripper(val, &parts);
269 Farm::Atrix {
270 name: Atrix::from(farm_name.as_str()),
271 }
272 }
273 _ => Farm::Unknown {
274 name: Unknown::Unknown,
275 },
276 }
277}
278#[cfg(test)]
279mod test {
280 use super::*;
281 #[test]
282 fn size_of() {
283 println!("size {}", std::mem::size_of::<Farm>());
284 }
285 #[test]
286 fn test_farm_raydium() {
287 let farm = Farm::from(Raydium::from(0_u64));
288 assert!(farm.eq(&Farm::Raydium {
289 name: Raydium::ALEPHUSDC
290 }));
291 assert!(farm.name().eq(&"RAYDIUM-ALEPH-USDC".to_string()));
292 assert!(Farm::from(Raydium::from("ALEPH-USDC")).eq(&Farm::Raydium {
293 name: Raydium::ALEPHUSDC
294 }));
295 let farm2 = Farm::from([0_u64, 0_u64]);
296 assert!(farm.eq(&farm2));
297
298 let farm = Farm::from(Raydium::from(1_u64));
299 assert!(farm.eq(&Farm::Raydium {
300 name: Raydium::BOPRAY
301 }));
302 assert!(farm.name().eq(&"RAYDIUM-BOP-RAY".to_string()));
303 assert!(Farm::from(Raydium::from("BOP-RAY")).eq(&Farm::Raydium {
304 name: Raydium::BOPRAY
305 }));
306 let farm2 = Farm::from([0_u64, 1_u64]);
307 assert!(farm.eq(&farm2));
308
309 let farm = Farm::from(Raydium::from(2_u64));
310 assert!(farm.eq(&Farm::Raydium {
311 name: Raydium::COPEUSDC
312 }));
313 assert!(farm.name().eq(&"RAYDIUM-COPE-USDC".to_string()));
314 assert!(Farm::from(Raydium::from("COPE-USDC")).eq(&Farm::Raydium {
315 name: Raydium::COPEUSDC
316 }));
317 let farm2 = Farm::from([0_u64, 2_u64]);
318 assert!(farm.eq(&farm2));
319
320 let farm = Farm::from(Raydium::from(3_u64));
321 assert!(farm.eq(&Farm::Raydium {
322 name: Raydium::LIKEUSDC
323 }));
324 assert!(farm.name().eq(&"RAYDIUM-LIKE-USDC".to_string()));
325 assert!(Farm::from(Raydium::from("LIKE-USDC")).eq(&Farm::Raydium {
326 name: Raydium::LIKEUSDC
327 }));
328 let farm2 = Farm::from([0_u64, 3_u64]);
329 assert!(farm.eq(&farm2));
330
331 let farm = Farm::from(Raydium::from(4_u64));
332 assert!(farm.eq(&Farm::Raydium {
333 name: Raydium::PSYUSDC
334 }));
335 assert!(farm.name().eq(&"RAYDIUM-PSY-USDC".to_string()));
336 assert!(Farm::from(Raydium::from("PSY-USDC")).eq(&Farm::Raydium {
337 name: Raydium::PSYUSDC
338 }));
339 let farm2 = Farm::from([0_u64, 4_u64]);
340 assert!(farm.eq(&farm2));
341
342 let farm = Farm::from(Raydium::from(5_u64));
343 assert!(farm.eq(&Farm::Raydium {
344 name: Raydium::MERUSDC
345 }));
346 assert!(farm.name().eq(&"RAYDIUM-MER-USDC".to_string()));
347 assert!(Farm::from(Raydium::from("MER-USDC")).eq(&Farm::Raydium {
348 name: Raydium::MERUSDC
349 }));
350 let farm2 = Farm::from([0_u64, 5_u64]);
351 assert!(farm.eq(&farm2));
352
353 let farm = Farm::from(Raydium::from(6_u64));
354 assert!(farm.eq(&Farm::Raydium {
355 name: Raydium::stSOLUSDC
356 }));
357 assert!(farm.name().eq(&"RAYDIUM-stSOL-USDC".to_string()));
358 assert!(Farm::from(Raydium::from("stSOL-USDC")).eq(&Farm::Raydium {
359 name: Raydium::stSOLUSDC
360 }));
361 let farm2 = Farm::from([0_u64, 6_u64]);
362 assert!(farm.eq(&farm2));
363
364 let farm = Farm::from(Raydium::from(7_u64));
365 assert!(farm.eq(&Farm::Raydium { name: Raydium::RAY }));
366 assert!(farm.name().eq(&"RAYDIUM-RAY".to_string()));
367 assert!(Farm::from(Raydium::from("RAY")).eq(&Farm::Raydium { name: Raydium::RAY }));
368 let farm2 = Farm::from([0_u64, 7_u64]);
369 assert!(farm.eq(&farm2));
370
371 let farm = Farm::from(Raydium::from(8_u64));
372 assert!(farm.eq(&Farm::Raydium {
373 name: Raydium::RAYUSDT
374 }));
375 assert!(farm.name().eq(&"RAYDIUM-RAY-USDT".to_string()));
376 assert!(Farm::from(Raydium::from("RAY-USDT")).eq(&Farm::Raydium {
377 name: Raydium::RAYUSDT
378 }));
379 let farm2 = Farm::from([0_u64, 8_u64]);
380 assert!(farm.eq(&farm2));
381
382 let farm = Farm::from(Raydium::from(9_u64));
383 assert!(farm.eq(&Farm::Raydium {
384 name: Raydium::RAYUSDC
385 }));
386 assert!(farm.name().eq(&"RAYDIUM-RAY-USDC".to_string()));
387 assert!(Farm::from(Raydium::from("RAY-USDC")).eq(&Farm::Raydium {
388 name: Raydium::RAYUSDC
389 }));
390 let farm2 = Farm::from([0_u64, 9_u64]);
391 assert!(farm.eq(&farm2));
392
393 let farm = Farm::from(Raydium::from(10_u64));
394 assert!(farm.eq(&Farm::Raydium {
395 name: Raydium::RAYSRM
396 }));
397 assert!(farm.name().eq(&"RAYDIUM-RAY-SRM".to_string()));
398 assert!(Farm::from(Raydium::from("RAY-SRM")).eq(&Farm::Raydium {
399 name: Raydium::RAYSRM
400 }));
401 let farm2 = Farm::from([0_u64, 10_u64]);
402 assert!(farm.eq(&farm2));
403
404 let farm = Farm::from(Raydium::from(11_u64));
405 assert!(farm.eq(&Farm::Raydium {
406 name: Raydium::RAYSOL
407 }));
408 assert!(farm.name().eq(&"RAYDIUM-RAY-SOL".to_string()));
409 assert!(Farm::from(Raydium::from("RAY-SOL")).eq(&Farm::Raydium {
410 name: Raydium::RAYSOL
411 }));
412 let farm2 = Farm::from([0_u64, 11_u64]);
413 assert!(farm.eq(&farm2));
414
415 let farm = Farm::from(Raydium::from(12_u64));
416 assert!(farm.eq(&Farm::Raydium {
417 name: Raydium::RAYETH
418 }));
419 assert!(farm.name().eq(&"RAYDIUM-RAY-ETH".to_string()));
420 assert!(Farm::from(Raydium::from("RAY-ETH")).eq(&Farm::Raydium {
421 name: Raydium::RAYETH
422 }));
423 let farm2 = Farm::from([0_u64, 12_u64]);
424 assert!(farm.eq(&farm2));
425
426 let farm = Farm::from(Raydium::from(13_u64));
427 assert!(farm.eq(&Farm::Raydium {
428 name: Raydium::ROPEUSDC
429 }));
430 assert!(farm.name().eq(&"RAYDIUM-ROPE-USDC".to_string()));
431 assert!(Farm::from(Raydium::from("ROPE-USDC")).eq(&Farm::Raydium {
432 name: Raydium::ROPEUSDC
433 }));
434 let farm2 = Farm::from([0_u64, 13_u64]);
435 assert!(farm.eq(&farm2));
436
437 let farm = Farm::from(Raydium::from(14_u64));
438 assert!(farm.eq(&Farm::Raydium {
439 name: Raydium::SAMORAY
440 }));
441 assert!(farm.name().eq(&"RAYDIUM-SAMO-RAY".to_string()));
442 assert!(Farm::from(Raydium::from("SAMO-RAY")).eq(&Farm::Raydium {
443 name: Raydium::SAMORAY
444 }));
445 let farm2 = Farm::from([0_u64, 14_u64]);
446 assert!(farm.eq(&farm2));
447
448 let farm = Farm::from(Raydium::from(15_u64));
449 assert!(farm.eq(&Farm::Raydium {
450 name: Raydium::SNYUSDC
451 }));
452 assert!(farm.name().eq(&"RAYDIUM-SNY-USDC".to_string()));
453 assert!(Farm::from(Raydium::from("SNY-USDC")).eq(&Farm::Raydium {
454 name: Raydium::SNYUSDC
455 }));
456 let farm2 = Farm::from([0_u64, 15_u64]);
457 assert!(farm.eq(&farm2));
458
459 let farm = Farm::from(Raydium::from(16_u64));
460 assert!(farm.eq(&Farm::Raydium {
461 name: Raydium::stSOLUSDT
462 }));
463 assert!(farm.name().eq(&"RAYDIUM-stSOL-USDT".to_string()));
464 assert!(Farm::from(Raydium::from("stSOL-USDT")).eq(&Farm::Raydium {
465 name: Raydium::stSOLUSDT
466 }));
467 let farm2 = Farm::from([0_u64, 16_u64]);
468 assert!(farm.eq(&farm2));
469
470 let farm = Farm::from(Raydium::from(17_u64));
471 assert!(farm.eq(&Farm::Raydium {
472 name: Raydium::TULIPUSDC
473 }));
474 assert!(farm.name().eq(&"RAYDIUM-TULIP-USDC".to_string()));
475 assert!(Farm::from(Raydium::from("TULIP-USDC")).eq(&Farm::Raydium {
476 name: Raydium::TULIPUSDC
477 }));
478 let farm2 = Farm::from([0_u64, 17_u64]);
479 assert!(farm.eq(&farm2));
480
481 let farm = Farm::from(Raydium::from(18_u64));
482 assert!(farm.eq(&Farm::Raydium {
483 name: Raydium::POLISRAY
484 }));
485 assert!(farm.name().eq(&"RAYDIUM-POLIS-RAY".to_string()));
486 assert!(Farm::from(Raydium::from("POLIS-RAY")).eq(&Farm::Raydium {
487 name: Raydium::POLISRAY
488 }));
489 let farm2 = Farm::from([0_u64, 18_u64]);
490 assert!(farm.eq(&farm2));
491
492 let farm = Farm::from(Raydium::from(19_u64));
493 assert!(farm.eq(&Farm::Raydium {
494 name: Raydium::ATLASRAY
495 }));
496 assert!(farm.name().eq(&"RAYDIUM-ATLAS-RAY".to_string()));
497 assert!(Farm::from(Raydium::from("ATLAS-RAY")).eq(&Farm::Raydium {
498 name: Raydium::ATLASRAY
499 }));
500 let farm2 = Farm::from([0_u64, 19_u64]);
501 assert!(farm.eq(&farm2));
502
503 let farm = Farm::from(Raydium::from(u64::MAX));
504 assert!(farm.eq(&Farm::Raydium {
505 name: Raydium::UNKNOWN
506 }));
507 assert!(farm.name().eq(&"RAYDIUM-UNKNOWN".to_string()));
508 assert!(Farm::from(Raydium::from("abababab")).eq(&Farm::Raydium {
509 name: Raydium::UNKNOWN
510 }));
511 let farm2 = Farm::from([0_u64, 128_u64]);
512 assert!(farm.eq(&farm2));
513
514 let farm = Farm::from(Raydium::from(u64::MAX - 1));
515 assert!(farm.eq(&Farm::Raydium {
516 name: Raydium::UNKNOWN
517 }));
518 assert!(farm.name().eq(&"RAYDIUM-UNKNOWN".to_string()));
519 assert!(Farm::from(Raydium::from("bcbcbcb")).eq(&Farm::Raydium {
520 name: Raydium::UNKNOWN
521 }));
522 let farm2 = Farm::from([0_u64, 255_u64]);
523 assert!(farm.eq(&farm2));
524 }
525 #[test]
526 fn test_farm_from() {
527 assert!(
528 Farm::from([0_u64, 0_u64])
529 == Farm::Raydium {
530 name: Raydium::ALEPHUSDC
531 }
532 );
533 assert!(Farm::from([0_u64, 0_u64]).name() == *"RAYDIUM-ALEPH-USDC");
534
535 assert!(
536 Farm::from([0_u64, 1_u64])
537 == Farm::Raydium {
538 name: Raydium::BOPRAY
539 }
540 );
541 assert!(Farm::from([0_u64, 1_u64]).name() == *"RAYDIUM-BOP-RAY");
542
543 assert!(
544 Farm::from([0_u64, 17_u64])
545 == Farm::Raydium {
546 name: Raydium::TULIPUSDC
547 }
548 );
549 assert!(Farm::from([0_u64, 17_u64]).name() == *"RAYDIUM-TULIP-USDC");
550
551 assert!(Farm::from([1_u64, 0_u64]).name() == *"LENDING-TULIP");
552 assert!(Farm::from([1_u64, 1_u64]).name() == *"LENDING-SOLEND");
553
554 assert!(
555 Farm::from([100_u64, 0_u64])
556 == Farm::Unknown {
557 name: Unknown::Unknown
558 }
559 );
560 assert!(Farm::from([100_u64, 0_u64]).name() == *"UNKNOWN");
561 }
562 #[test]
563 fn test_farm_lending() {
564 let farm = Farm::from(Lending::from(0_u64));
565 assert!(farm.eq(&Farm::Lending {
566 name: Lending::TULIP,
567 }));
568 assert!(farm.name().eq(&"LENDING-TULIP".to_string()));
569
570 let farm = Farm::from(Lending::from(1_u64));
571 assert!(farm.eq(&Farm::Lending {
572 name: Lending::SOLEND,
573 }));
574 assert!(farm.name().eq(&"LENDING-SOLEND".to_string()));
575
576 let farm = Farm::from(Lending::from(2_u64));
577 assert!(farm.eq(&Farm::Lending {
578 name: Lending::MANGO,
579 }));
580 assert!(farm.name().eq(&"LENDING-MANGO".to_string()));
581
582 let farm = Farm::from(Lending::from(3_u64));
583 assert!(farm.eq(&Farm::Lending {
584 name: Lending::PORT,
585 }));
586 assert!(farm.name().eq(&"LENDING-PORT".to_string()));
587
588 let farm = Farm::from(Lending::from(4_u64));
589 assert!(farm.eq(&Farm::Lending {
590 name: Lending::LARIX,
591 }));
592 assert!(farm.name().eq(&"LENDING-LARIX".to_string()));
593
594 let farm = Farm::from(Lending::from(5_u64));
595 assert!(farm.eq(&Farm::Lending {
596 name: Lending::PARROT,
597 }));
598 assert!(farm.name().eq(&"LENDING-PARROT".to_string()));
599 }
600 #[test]
601 fn test_farm_orca() {
602 let farm = Farm::from(Orca::from(0_u64));
603 assert!(farm.eq(&Farm::Orca {
604 name: Orca::ATLASUSDC
605 }));
606 assert!(farm.name().eq(&"ORCA-ATLAS-USDC".to_string()));
607 assert!(Farm::from(Orca::from("ATLAS-USDC")).eq(&Farm::Orca {
608 name: Orca::ATLASUSDC
609 }));
610 let farm2 = Farm::from([2_u64, 0_u64]);
611 assert!(farm.eq(&farm2));
612
613 let farm = Farm::from(Orca::from(1_u64));
614 assert!(farm.eq(&Farm::Orca {
615 name: Orca::POLISUSDC
616 }));
617 assert!(farm.name().eq(&"ORCA-POLIS-USDC".to_string()));
618 assert!(Farm::from(Orca::from("POLIS-USDC")).eq(&Farm::Orca {
619 name: Orca::POLISUSDC
620 }));
621 let farm2 = Farm::from([2_u64, 1_u64]);
622 assert!(farm.eq(&farm2));
623
624 let farm = Farm::from(Orca::from(6969420_u64));
625 assert!(farm.eq(&Farm::Orca {
626 name: Orca::UNKNOWN
627 }));
628 assert!(farm.name().eq(&"ORCA-UNKNOWN".to_string()));
629 assert!(Farm::from(Orca::from("UNKNOWN")).eq(&Farm::Orca {
630 name: Orca::UNKNOWN
631 }));
632 let farm2 = Farm::from([2_u64, 6969420_u64]);
633 assert!(farm.eq(&farm2));
634 }
635 #[test]
636 fn test_lending_market_name() {
637 let farm = Farm::Lending {
638 name: Lending::USDC,
639 };
640 println!("{}", farm.market_name().unwrap())
641 }
642 #[test]
643 fn test_farm_quarry() {
644 let farm = Farm::from(Quarry::from(0_u64));
645 assert!(farm.eq(&Farm::Quarry {
646 name: Quarry::VANILLA
647 }));
648 assert_eq!(farm.name(), "QUARRY-VANILLA".to_string());
649 assert_eq!(
650 Farm::from(Quarry::from("VANILLA")),
651 Farm::Quarry {
652 name: Quarry::VANILLA
653 }
654 );
655 let farm2: Farm = [3_u64, 0_u64].into();
656 assert_eq!(farm, farm2);
657 let farm3: [u64; 2] = farm2.into();
658 let farm4: [u64; 2] = farm.into();
659 assert_eq!(farm3, farm4);
660 }
661}