tycho_simulation/evm/protocol/fluid/
decoder.rs

1use std::{collections::HashMap, str::FromStr};
2
3use tycho_client::feed::{synchronizer::ComponentWithState, BlockHeader};
4use tycho_common::{models::token::Token, Bytes};
5
6use crate::{
7    evm::{
8        engine_db::{create_engine, SHARED_TYCHO_DB},
9        protocol::fluid::{v1::FluidV1, vm},
10    },
11    protocol::{
12        errors::InvalidSnapshotError,
13        models::{DecoderContext, TryFromWithBlock},
14    },
15};
16
17impl TryFromWithBlock<ComponentWithState, BlockHeader> for FluidV1 {
18    type Error = InvalidSnapshotError;
19
20    async fn try_from_with_header(
21        value: ComponentWithState,
22        _block: BlockHeader,
23        _account_balances: &HashMap<Bytes, HashMap<Bytes, Bytes>>,
24        all_tokens: &HashMap<Bytes, Token>,
25        decoder_context: &DecoderContext,
26    ) -> Result<Self, Self::Error> {
27        let pool_address = Bytes::from_str(value.component.id.as_str()).map_err(|e| {
28            InvalidSnapshotError::ValueError(format!(
29                "Expected component id to be pool contract address: {e}"
30            ))
31        })?;
32        let token0_address = value
33            .component
34            .tokens
35            .first()
36            .ok_or_else(|| {
37                InvalidSnapshotError::ValueError("Missing token0 in component".to_string())
38            })?;
39        let token0 = all_tokens
40            .get(token0_address)
41            .ok_or_else(|| {
42                InvalidSnapshotError::ValueError(format!(
43                    "Missing token0 in state: {token0_address}"
44                ))
45            })?;
46        let token1_address = value
47            .component
48            .tokens
49            .get(1)
50            .ok_or_else(|| {
51                InvalidSnapshotError::ValueError("Missing token1 in component".to_string())
52            })?;
53        let token1 = all_tokens
54            .get(token1_address)
55            .ok_or_else(|| {
56                InvalidSnapshotError::ValueError(format!(
57                    "Missing token1 in state: {token1_address}"
58                ))
59            })?;
60        let resolver_address = value
61            .component
62            .static_attributes
63            .get("reserves_resolver_address")
64            .ok_or_else(|| {
65                InvalidSnapshotError::ValueError(
66                    "Missing reserves resolver address in component".to_string(),
67                )
68            })?;
69        let engine = create_engine(
70            SHARED_TYCHO_DB.clone(),
71            decoder_context
72                .vm_traces
73                .unwrap_or_default(),
74        )
75        .expect("Infallible");
76        let state =
77            vm::decode_from_vm(&pool_address, token0, token1, resolver_address.as_ref(), engine)?;
78
79        Ok(state)
80    }
81}