tycho_simulation/evm/protocol/balancer_v3/
decoder.rs1use std::{collections::HashMap, str::FromStr};
7
8use alloy::primitives::Address as AlloyAddress;
9use tycho_client::feed::synchronizer::ComponentWithState;
10use tycho_common::{models::token::Token, Bytes};
11
12use crate::{
13 evm::{
14 engine_db::{create_engine, SHARED_TYCHO_DB},
15 protocol::{
16 balancer_v3::{state::BalancerV3State, vm},
17 vm::utils::load_stateless_contracts,
18 },
19 },
20 protocol::{
21 errors::InvalidSnapshotError,
22 models::{DecoderContext, TryFromWithBlock},
23 },
24};
25
26impl TryFromWithBlock<ComponentWithState, tycho_client::feed::BlockHeader> for BalancerV3State {
27 type Error = InvalidSnapshotError;
28
29 async fn try_from_with_header(
31 value: ComponentWithState,
32 block: tycho_client::feed::BlockHeader,
33 _account_balances: &HashMap<Bytes, HashMap<Bytes, Bytes>>,
34 _all_tokens: &HashMap<Bytes, Token>,
35 decoder_context: &DecoderContext,
36 ) -> Result<Self, Self::Error> {
37 let pool_address = Bytes::from_str(value.component.id.as_str()).map_err(|e| {
38 InvalidSnapshotError::ValueError(format!(
39 "expected balancer_v3 component id to be the pool address: {e}"
40 ))
41 })?;
42
43 let pool = AlloyAddress::from_slice(pool_address.as_ref());
44 let pool_type = vm::resolve_pool_type(&value.component.static_attributes, &pool)
47 .map_err(|e| InvalidSnapshotError::ValueError(e.to_string()))?;
48
49 let engine = create_engine(
50 SHARED_TYCHO_DB.clone(),
51 decoder_context
52 .vm_traces
53 .unwrap_or_default(),
54 )
55 .expect("Infallible");
56
57 load_stateless_contracts(&engine, &value.state.attributes)
61 .await
62 .map_err(|e| InvalidSnapshotError::ValueError(e.to_string()))?;
63
64 let tokens = value.component.tokens.clone();
67 let state = vm::read_pool_state(
68 &engine,
69 &pool,
70 pool_type,
71 &tokens,
72 &value.component.static_attributes,
73 block.timestamp,
74 )
75 .map_err(|e| InvalidSnapshotError::ValueError(e.to_string()))?;
76 let min_token_balances = match pool_type {
79 vm::BalancerPoolType::Weighted => vm::read_weighted_min_token_balances(&engine, &pool),
80 vm::BalancerPoolType::Stable |
81 vm::BalancerPoolType::Reclamm |
82 vm::BalancerPoolType::QuantAmm => Vec::new(),
83 };
84
85 Ok(BalancerV3State::new(pool_address, tokens, min_token_balances, block.timestamp, state))
86 }
87}