tycho_common/models/token.rs
1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use super::{Address, Balance};
6use crate::{models::Chain, traits::TokenOwnerFinding, Bytes};
7
8/// Cost related to a token transfer, for example amount of gas in evm chains.
9pub type TransferCost = u64;
10
11/// Tax related to a token transfer. Should be given in Basis Points (1/100th of a percent)
12pub type TransferTax = u64;
13
14#[derive(PartialEq, Debug, Clone, Deserialize, Serialize)]
15pub struct CurrencyToken {
16 pub address: Bytes,
17 pub symbol: String,
18 pub decimals: u32,
19 pub tax: TransferTax,
20 pub gas: Vec<Option<TransferCost>>,
21 pub chain: Chain,
22 /// Quality is between 0-100, where:
23 /// - 100: Normal token
24 /// - 75: Rebase token
25 /// - 50: Fee token
26 /// - 10: Token analysis failed at creation
27 /// - 9-5: Token analysis failed on cronjob (after creation).
28 /// - 0: Failed to extract decimals onchain
29 pub quality: u32,
30}
31
32impl CurrencyToken {
33 pub fn new(
34 address: &Bytes,
35 symbol: &str,
36 decimals: u32,
37 tax: u64,
38 gas: &[Option<u64>],
39 chain: Chain,
40 quality: u32,
41 ) -> Self {
42 Self {
43 address: address.clone(),
44 symbol: symbol.to_string(),
45 decimals,
46 tax,
47 gas: gas.to_owned(),
48 chain,
49 quality,
50 }
51 }
52}
53
54/// Represents the quality of a token.
55///
56/// * `Good`: Indicates that the token has successfully passed the analysis process.
57/// * `Bad`: Indicates that the token has failed the analysis process. In this case, a detailed
58/// reason for the failure is provided.
59///
60/// Note: Transfer taxes do not impact the token's quality.
61/// Even if a token has transfer taxes, as long as it successfully passes the analysis,
62/// it will still be marked as `Good`.
63#[derive(Debug, Clone, Eq, PartialEq)]
64pub enum TokenQuality {
65 Good,
66 Bad { reason: String },
67}
68
69impl TokenQuality {
70 pub fn is_good(&self) -> bool {
71 matches!(self, Self::Good { .. })
72 }
73
74 pub fn bad(reason: impl ToString) -> Self {
75 Self::Bad { reason: reason.to_string() }
76 }
77}
78
79/// A store for tracking token owners and their balances.
80///
81/// The `TokenOwnerStore` maintains a mapping between token addresses and their respective
82/// owner's address and balance. It can be used to quickly retrieve token owner information
83/// without needing to query external sources.
84///
85/// # Fields
86/// * `values` - A `HashMap` where:
87/// * The key is the token `Address`, representing the address of the token being tracked.
88/// * The value is a tuple containing:
89/// * The owner `Address` of the token.
90/// * The `Balance` of the owner for the token.
91#[derive(Debug)]
92pub struct TokenOwnerStore {
93 values: HashMap<Address, (Address, Balance)>,
94}
95
96impl TokenOwnerStore {
97 pub fn new(values: HashMap<Address, (Address, Balance)>) -> Self {
98 TokenOwnerStore { values }
99 }
100}
101
102#[async_trait::async_trait]
103impl TokenOwnerFinding for TokenOwnerStore {
104 async fn find_owner(
105 &self,
106 token: Address,
107 _min_balance: Balance,
108 ) -> Result<Option<(Address, Balance)>, String> {
109 Ok(self.values.get(&token).cloned())
110 }
111}