tycho_simulation/evm/protocol/erc4626/
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 super::state::ERC4626State;
7use crate::{
8    evm::{
9        engine_db::{create_engine, SHARED_TYCHO_DB},
10        protocol::erc4626::vm,
11    },
12    protocol::{
13        errors::InvalidSnapshotError,
14        models::{DecoderContext, TryFromWithBlock},
15    },
16};
17
18impl TryFromWithBlock<ComponentWithState, BlockHeader> for ERC4626State {
19    type Error = InvalidSnapshotError;
20
21    async fn try_from_with_header(
22        snapshot: ComponentWithState,
23        _block: BlockHeader,
24        _account_balances: &HashMap<Bytes, HashMap<Bytes, Bytes>>,
25        all_tokens: &HashMap<Bytes, Token>,
26        decoder_context: &DecoderContext,
27    ) -> Result<Self, Self::Error> {
28        let pool_address = Bytes::from_str(snapshot.component.id.as_str()).map_err(|e| {
29            InvalidSnapshotError::ValueError(format!(
30                "Expected component id to be pool contract address: {e}"
31            ))
32        })?;
33        let asset_address = snapshot
34            .component
35            .tokens
36            .iter()
37            .find(|t| **t != pool_address)
38            .ok_or_else(|| {
39                InvalidSnapshotError::ValueError(format!(
40                    "Failed to determine asset address: no token different from pool address ({pool_address}) was found"
41                ))
42            })?;
43        let asset_token = all_tokens
44            .get(asset_address)
45            .ok_or_else(|| {
46                InvalidSnapshotError::ValueError(format!(
47                    "Missing asset_token in state: {asset_address}"
48                ))
49            })?;
50        let share_token = all_tokens
51            .get(&pool_address)
52            .ok_or_else(|| {
53                InvalidSnapshotError::ValueError(format!(
54                    "Missing share_token in state: {pool_address}"
55                ))
56            })?;
57        let engine = create_engine(
58            SHARED_TYCHO_DB.clone(),
59            decoder_context
60                .vm_traces
61                .unwrap_or_default(),
62        )
63        .expect("Failed to create engine");
64
65        let erc4626_state = vm::decode_from_vm(&pool_address, asset_token, share_token, engine)?;
66        Ok(erc4626_state)
67    }
68}