tycho_common/
traits.rs

1use core::fmt::Debug;
2use std::{collections::HashMap, sync::Arc};
3
4use async_trait::async_trait;
5
6use crate::{
7    models::{
8        blockchain::{Block, BlockTag},
9        contract::AccountDelta,
10        token::{CurrencyToken, TokenQuality, TransferCost, TransferTax},
11        Address, Balance,
12    },
13    Bytes,
14};
15
16#[async_trait]
17pub trait AccountExtractor {
18    type Error;
19
20    async fn get_accounts(
21        &self,
22        block: Block,
23        account_addresses: Vec<Address>,
24    ) -> Result<HashMap<Bytes, AccountDelta>, Self::Error>; //TODO: do not return `AccountUpdate` but `Account`
25}
26
27/// Trait for analyzing a token, including its quality, transfer cost, and transfer tax.
28#[async_trait]
29pub trait TokenAnalyzer: Send + Sync {
30    type Error;
31
32    /// Analyzes the quality of a token given its address and a block tag.
33    ///
34    /// # Parameters
35    /// * `token` - The address of the token to analyze.
36    /// * `block` - The block tag at which the analysis should be performed.
37    ///
38    /// # Returns
39    /// A result containing:
40    /// * `TokenQuality` - The quality assessment of the token (either `Good` or `Bad`).
41    /// * `Option<TransferCost>` - The average cost per transfer, if available.
42    /// * `Option<TransferTax>` - The transfer tax, if applicable.
43    ///
44    /// On failure, returns `Self::Error`.
45    async fn analyze(
46        &self,
47        token: Bytes,
48        block: BlockTag,
49    ) -> Result<(TokenQuality, Option<TransferCost>, Option<TransferTax>), Self::Error>;
50}
51
52/// Trait for finding an address that owns a specific token. This is useful for detecting
53/// bad tokens by identifying addresses with enough balance to simulate transactions.
54#[async_trait]
55pub trait TokenOwnerFinding: Send + Sync + Debug {
56    /// Finds an address that holds at least `min_balance` of the specified token.
57    ///
58    /// # Parameters
59    /// * `token` - The address of the token to search for.
60    /// * `min_balance` - The minimum balance required for the address to be considered.
61    ///
62    /// # Returns
63    /// A result containing:
64    /// * `Option<(Address, Balance)>` - The address and its actual balance if an owner is found.
65    /// If no address meets the criteria, returns `None`.
66    /// On failure, returns a string representing an error message.
67    async fn find_owner(
68        &self,
69        token: Address,
70        min_balance: Balance,
71    ) -> Result<Option<(Address, Balance)>, String>; // TODO: introduce custom error type
72}
73
74/// Trait for retrieving additional information about tokens, such as the number of decimals
75/// and the token symbol, to help construct `CurrencyToken` objects.
76#[async_trait]
77pub trait TokenPreProcessor: Send + Sync {
78    /// Given a list of token addresses, this function retrieves additional metadata for each token.
79    ///
80    /// # Parameters
81    /// * `addresses` - A vector of token addresses to process.
82    /// * `token_finder` - A reference to a `TokenOwnerFinding` implementation to help find token
83    ///   owners.
84    /// * `block` - The block tag at which the information should be retrieved.
85    ///
86    /// # Returns
87    /// A vector of `CurrencyToken` objects, each containing the processed information for the
88    /// token.
89    async fn get_tokens(
90        &self,
91        addresses: Vec<Bytes>,
92        token_finder: Arc<dyn TokenOwnerFinding>,
93        block: BlockTag,
94    ) -> Vec<CurrencyToken>;
95}