Add tycho pb type constructors.

This allows us to remove a lot of unnecessary boilerplate code.
This commit is contained in:
kayibal
2024-03-13 22:10:54 +00:00
parent 18e9dfcec4
commit 312d322585
4 changed files with 228 additions and 266 deletions

View File

@@ -7,6 +7,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use substreams_ethereum::pb::eth; use substreams_ethereum::pb::eth;
use substreams_ethereum::pb::eth::v2::StorageChange;
use crate::pb::tycho::evm::v1::{self as tycho}; use crate::pb::tycho::evm::v1::{self as tycho};
@@ -15,6 +16,12 @@ struct SlotValue {
start_value: Vec<u8>, start_value: Vec<u8>,
} }
impl From<&StorageChange> for SlotValue {
fn from(change: &StorageChange) -> Self {
Self { new_value: change.new_value.clone(), start_value: change.old_value.clone() }
}
}
impl SlotValue { impl SlotValue {
fn has_changed(&self) -> bool { fn has_changed(&self) -> bool {
self.start_value != self.new_value self.start_value != self.new_value
@@ -30,6 +37,22 @@ struct InterimContractChange {
change: tycho::ChangeType, change: tycho::ChangeType,
} }
impl InterimContractChange {
fn new(address: &[u8], creation: bool) -> Self {
Self {
address: address.to_vec(),
balance: vec![],
code: vec![],
slots: Default::default(),
change: if creation {
tycho::ChangeType::Creation.into()
} else {
tycho::ChangeType::Update.into()
},
}
}
}
impl From<InterimContractChange> for tycho::ContractChange { impl From<InterimContractChange> for tycho::ContractChange {
fn from(value: InterimContractChange) -> Self { fn from(value: InterimContractChange) -> Self {
tycho::ContractChange { tycho::ContractChange {
@@ -90,28 +113,20 @@ pub fn extract_contract_changes<F: Fn(&[u8]) -> bool>(
storage_changes storage_changes
.iter() .iter()
.filter(|changes| inclusion_predicate(&changes.address)) .filter(|changes| inclusion_predicate(&changes.address))
.for_each(|storage_change| { .for_each(|&storage_change| {
let contract_change = changed_contracts let contract_change = changed_contracts
.entry(storage_change.address.clone()) .entry(storage_change.address.clone())
.or_insert_with(|| InterimContractChange { .or_insert_with(|| {
address: storage_change.address.clone(), InterimContractChange::new(
balance: Vec::new(), &storage_change.address,
code: Vec::new(), created_accounts.contains_key(&storage_change.address),
slots: HashMap::new(), )
change: if created_accounts.contains_key(&storage_change.address) {
tycho::ChangeType::Creation
} else {
tycho::ChangeType::Update
},
}); });
let slot_value = contract_change let slot_value = contract_change
.slots .slots
.entry(storage_change.key.clone()) .entry(storage_change.key.clone())
.or_insert_with(|| SlotValue { .or_insert_with(|| storage_change.into());
new_value: storage_change.new_value.clone(),
start_value: storage_change.old_value.clone(),
});
slot_value slot_value
.new_value .new_value
@@ -124,16 +139,11 @@ pub fn extract_contract_changes<F: Fn(&[u8]) -> bool>(
.for_each(|balance_change| { .for_each(|balance_change| {
let contract_change = changed_contracts let contract_change = changed_contracts
.entry(balance_change.address.clone()) .entry(balance_change.address.clone())
.or_insert_with(|| InterimContractChange { .or_insert_with(|| {
address: balance_change.address.clone(), InterimContractChange::new(
balance: Vec::new(), &balance_change.address,
code: Vec::new(), created_accounts.contains_key(&balance_change.address),
slots: HashMap::new(), )
change: if created_accounts.contains_key(&balance_change.address) {
tycho::ChangeType::Creation
} else {
tycho::ChangeType::Update
},
}); });
if let Some(new_balance) = &balance_change.new_value { if let Some(new_balance) = &balance_change.new_value {
@@ -150,16 +160,11 @@ pub fn extract_contract_changes<F: Fn(&[u8]) -> bool>(
.for_each(|code_change| { .for_each(|code_change| {
let contract_change = changed_contracts let contract_change = changed_contracts
.entry(code_change.address.clone()) .entry(code_change.address.clone())
.or_insert_with(|| InterimContractChange { .or_insert_with(|| {
address: code_change.address.clone(), InterimContractChange::new(
balance: Vec::new(), &code_change.address,
code: Vec::new(), created_accounts.contains_key(&code_change.address),
slots: HashMap::new(), )
change: if created_accounts.contains_key(&code_change.address) {
tycho::ChangeType::Creation
} else {
tycho::ChangeType::Update
},
}); });
contract_change.code.clear(); contract_change.code.clear();
@@ -174,17 +179,7 @@ pub fn extract_contract_changes<F: Fn(&[u8]) -> bool>(
{ {
transaction_contract_changes transaction_contract_changes
.entry(block_tx.index.into()) .entry(block_tx.index.into())
.or_insert_with(|| tycho::TransactionContractChanges { .or_insert_with(|| tycho::TransactionContractChanges::new(&(block_tx.into())))
tx: Some(tycho::Transaction {
hash: block_tx.hash.clone(),
from: block_tx.from.clone(),
to: block_tx.to.clone(),
index: block_tx.index as u64,
}),
contract_changes: vec![],
component_changes: vec![],
balance_changes: vec![],
})
.contract_changes .contract_changes
.extend( .extend(
changed_contracts changed_contracts

View File

@@ -3,6 +3,7 @@ pub mod tycho {
pub mod evm { pub mod evm {
// @@protoc_insertion_point(attribute:tycho.evm.v1) // @@protoc_insertion_point(attribute:tycho.evm.v1)
pub mod v1 { pub mod v1 {
use substreams_ethereum::pb::eth::v2::{self as sf};
include!("tycho.evm.v1.rs"); include!("tycho.evm.v1.rs");
// @@protoc_insertion_point(tycho.evm.v1) // @@protoc_insertion_point(tycho.evm.v1)
@@ -16,6 +17,104 @@ pub mod tycho {
} }
} }
} }
impl From<&sf::TransactionTrace> for Transaction {
fn from(tx: &sf::TransactionTrace) -> Self {
Self {
hash: tx.hash.clone(),
from: tx.from.clone(),
to: tx.to.clone(),
index: tx.index.into(),
}
}
}
impl From<&sf::Block> for Block {
fn from(block: &sf::Block) -> Self {
Self {
number: block.number,
hash: block.hash.clone(),
parent_hash: block
.header
.as_ref()
.expect("Block header not present")
.parent_hash
.clone(),
ts: block.timestamp_seconds(),
}
}
}
impl ProtocolComponent {
pub fn new(id: &str, tx: &Transaction) -> Self {
Self {
id: id.to_string(),
tokens: vec![],
contracts: vec![],
static_att: vec![],
change: ChangeType::Creation.into(),
protocol_type: None,
tx: Some(tx.clone()),
}
}
pub fn at_contract(id: &[u8], tx: &Transaction) -> Self {
Self {
id: format!("0x{}", hex::encode(id)),
tokens: vec![],
contracts: vec![id.to_vec()],
static_att: vec![],
change: ChangeType::Creation.into(),
protocol_type: None,
tx: Some(tx.clone()),
}
}
pub fn with_tokens<B: AsRef<[u8]>>(mut self, tokens: &[B]) -> Self {
self.tokens = tokens
.iter()
.map(|e| e.as_ref().to_vec())
.collect::<Vec<Vec<u8>>>();
self
}
pub fn with_contracts<B: AsRef<[u8]>>(mut self, contracts: &[B]) -> Self {
self.contracts = contracts
.iter()
.map(|e| e.as_ref().to_vec())
.collect::<Vec<Vec<u8>>>();
self
}
pub fn with_attributes<K: AsRef<str>, V: AsRef<[u8]>>(
mut self,
attributes: &[(K, V)],
) -> Self {
self.static_att = attributes
.iter()
.map(|(k, v)| Attribute {
name: k.as_ref().to_string(),
value: v.as_ref().to_vec(),
change: ChangeType::Creation.into(),
})
.collect::<Vec<Attribute>>();
self
}
pub fn as_swap_type(
mut self,
name: &str,
implementation_type: ImplementationType,
) -> Self {
self.protocol_type = Some(ProtocolType {
name: name.to_string(),
financial_type: FinancialType::Swap.into(),
attribute_schema: vec![],
implementation_type: implementation_type.into(),
});
self
}
}
} }
} }
} }

View File

@@ -34,24 +34,14 @@ pub fn map_pools_created(block: eth::v2::Block) -> Result<BlockTransactionProtoc
call.call.address.as_slice(), call.call.address.as_slice(),
log, log,
call.call, call.call,
&tycho::Transaction { &(tx.into()),
hash: tx.hash.clone(),
from: tx.from.clone(),
to: tx.to.clone(),
index: tx.index.into(),
},
) )
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
if !components.is_empty() { if !components.is_empty() {
Some(TransactionProtocolComponents { Some(TransactionProtocolComponents {
tx: Some(tycho::Transaction { tx: Some(tx.into()),
hash: tx.hash.clone(),
from: tx.from.clone(),
to: tx.to.clone(),
index: Into::<u64>::into(tx.index),
}),
components, components,
}) })
} else { } else {
@@ -106,12 +96,7 @@ pub fn map_balance_deltas(
for (token, delta) in ev.tokens.iter().zip(ev.deltas.iter()) { for (token, delta) in ev.tokens.iter().zip(ev.deltas.iter()) {
deltas.push(BalanceDelta { deltas.push(BalanceDelta {
ord: vault_log.ordinal(), ord: vault_log.ordinal(),
tx: Some(tycho::Transaction { tx: Some(vault_log.receipt.transaction.into()),
hash: vault_log.receipt.transaction.hash.clone(),
from: vault_log.receipt.transaction.from.clone(),
to: vault_log.receipt.transaction.to.clone(),
index: vault_log.receipt.transaction.index.into(),
}),
token: token.to_vec(), token: token.to_vec(),
delta: delta.to_signed_bytes_be(), delta: delta.to_signed_bytes_be(),
component_id: component_id.clone(), component_id: component_id.clone(),
@@ -133,24 +118,14 @@ pub fn map_balance_deltas(
deltas.extend_from_slice(&[ deltas.extend_from_slice(&[
BalanceDelta { BalanceDelta {
ord: vault_log.ordinal(), ord: vault_log.ordinal(),
tx: Some(tycho::Transaction { tx: Some(vault_log.receipt.transaction.into()),
hash: vault_log.receipt.transaction.hash.clone(),
from: vault_log.receipt.transaction.from.clone(),
to: vault_log.receipt.transaction.to.clone(),
index: vault_log.receipt.transaction.index.into(),
}),
token: ev.token_in.to_vec(), token: ev.token_in.to_vec(),
delta: ev.amount_in.to_signed_bytes_be(), delta: ev.amount_in.to_signed_bytes_be(),
component_id: component_id.clone(), component_id: component_id.clone(),
}, },
BalanceDelta { BalanceDelta {
ord: vault_log.ordinal(), ord: vault_log.ordinal(),
tx: Some(tycho::Transaction { tx: Some(vault_log.receipt.transaction.into()),
hash: vault_log.receipt.transaction.hash.clone(),
from: vault_log.receipt.transaction.from.clone(),
to: vault_log.receipt.transaction.to.clone(),
index: vault_log.receipt.transaction.index.into(),
}),
token: ev.token_out.to_vec(), token: ev.token_out.to_vec(),
delta: ev.amount_out.neg().to_signed_bytes_be(), delta: ev.amount_out.neg().to_signed_bytes_be(),
component_id, component_id,
@@ -234,17 +209,7 @@ pub fn map_changes(
// Process all `transaction_contract_changes` for final output in the `BlockContractChanges`, // Process all `transaction_contract_changes` for final output in the `BlockContractChanges`,
// sorted by transaction index (the key). // sorted by transaction index (the key).
Ok(tycho::BlockContractChanges { Ok(tycho::BlockContractChanges {
block: Some(tycho::Block { block: Some((&block).into()),
number: block.number,
hash: block.hash.clone(),
parent_hash: block
.header
.as_ref()
.expect("Block header not present")
.parent_hash
.clone(),
ts: block.timestamp_seconds(),
}),
changes: transaction_contract_changes changes: transaction_contract_changes
.drain() .drain()
.sorted_unstable_by_key(|(index, _)| *index) .sorted_unstable_by_key(|(index, _)| *index)

View File

@@ -3,9 +3,7 @@ use substreams_ethereum::{Event, Function};
use crate::abi; use crate::abi;
use substreams::hex; use substreams::hex;
use tycho_substreams::pb::tycho::evm::v1::{ use tycho_substreams::pb::tycho::evm::v1::{ImplementationType, ProtocolComponent, Transaction};
self as tycho, FinancialType, ImplementationType, ProtocolType, Transaction,
};
use substreams::scalar::BigInt; use substreams::scalar::BigInt;
@@ -39,16 +37,16 @@ impl SerializableVecBigInt for Vec<BigInt> {
/// - Stable Pool Factories /// - Stable Pool Factories
/// (Balancer does have a bit more (esp. in the deprecated section) that could be implemented as /// (Balancer does have a bit more (esp. in the deprecated section) that could be implemented as
/// desired.) /// desired.)
/// We use the specific ABIs to decode both the log event and cooresponding call to gather /// We use the specific ABIs to decode both the log event and corresponding call to gather
/// `PoolCreated` event information alongside the `Create` calldata that provide us details to /// `PoolCreated` event information alongside the `Create` call data that provide us details to
/// fufill both the required details + any extra `Attributes` /// fulfill both the required details + any extra `Attributes`
/// Ref: https://docs.balancer.fi/reference/contracts/deployment-addresses/mainnet.html /// Ref: https://docs.balancer.fi/reference/contracts/deployment-addresses/mainnet.html
pub fn address_map( pub fn address_map(
pool_factory_address: &[u8], pool_factory_address: &[u8],
log: &Log, log: &Log,
call: &Call, call: &Call,
tx: &Transaction, tx: &Transaction,
) -> Option<tycho::ProtocolComponent> { ) -> Option<ProtocolComponent> {
match *pool_factory_address { match *pool_factory_address {
hex!("897888115Ada5773E02aA29F775430BFB5F34c51") => { hex!("897888115Ada5773E02aA29F775430BFB5F34c51") => {
let create_call = let create_call =
@@ -56,31 +54,18 @@ pub fn address_map(
let pool_created = let pool_created =
abi::weighted_pool_factory::events::PoolCreated::match_and_decode(log)?; abi::weighted_pool_factory::events::PoolCreated::match_and_decode(log)?;
Some(tycho::ProtocolComponent { Some(
id: hex::encode(&pool_created.pool), ProtocolComponent::at_contract(&pool_created.pool, &tx)
tokens: create_call.tokens, .with_tokens(&create_call.tokens)
contracts: vec![pool_created.pool], .with_attributes(&[
static_att: vec![ ("pool_type", "WeightedPoolFactory".as_bytes()),
tycho::Attribute { (
name: "pool_type".into(), "normalized_weights",
value: "WeightedPoolFactory".into(), &create_call.normalized_weights.serialize_bytes(),
change: tycho::ChangeType::Creation.into(), ),
}, ])
tycho::Attribute { .as_swap_type("balancer_pool", ImplementationType::Vm),
name: "normalized_weights".into(), )
value: create_call.normalized_weights.serialize_bytes(),
change: tycho::ChangeType::Creation.into(),
},
],
change: tycho::ChangeType::Creation.into(),
protocol_type: Some(ProtocolType {
name: "balancer_pool".to_string(),
financial_type: FinancialType::Swap.into(),
attribute_schema: vec![],
implementation_type: ImplementationType::Vm.into(),
}),
tx: Some(tx.clone()),
})
} }
hex!("DB8d758BCb971e482B2C45f7F8a7740283A1bd3A") => { hex!("DB8d758BCb971e482B2C45f7F8a7740283A1bd3A") => {
let create_call = let create_call =
@@ -88,24 +73,12 @@ pub fn address_map(
let pool_created = let pool_created =
abi::composable_stable_pool_factory::events::PoolCreated::match_and_decode(log)?; abi::composable_stable_pool_factory::events::PoolCreated::match_and_decode(log)?;
Some(tycho::ProtocolComponent { Some(
id: hex::encode(&pool_created.pool), ProtocolComponent::at_contract(&pool_created.pool, &tx)
tokens: create_call.tokens, .with_tokens(&create_call.tokens)
contracts: vec![pool_created.pool], .with_attributes(&[("pool_type", "ComposableStablePoolFactory".as_bytes())])
static_att: vec![tycho::Attribute { .as_swap_type("balancer_pool", ImplementationType::Vm),
name: "pool_type".into(), )
value: "ComposableStablePoolFactory".into(),
change: tycho::ChangeType::Creation.into(),
}],
change: tycho::ChangeType::Creation.into(),
protocol_type: Some(ProtocolType {
name: "balancer_pool".to_string(),
financial_type: FinancialType::Swap.into(),
attribute_schema: vec![],
implementation_type: ImplementationType::Vm.into(),
}),
tx: Some(tx.clone()),
})
} }
hex!("813EE7a840CE909E7Fea2117A44a90b8063bd4fd") => { hex!("813EE7a840CE909E7Fea2117A44a90b8063bd4fd") => {
let create_call = let create_call =
@@ -113,33 +86,18 @@ pub fn address_map(
let pool_created = let pool_created =
abi::erc_linear_pool_factory::events::PoolCreated::match_and_decode(log)?; abi::erc_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
Some(tycho::ProtocolComponent { Some(
id: hex::encode(&pool_created.pool), ProtocolComponent::at_contract(&pool_created.pool, &tx)
tokens: vec![create_call.main_token, create_call.wrapped_token], .with_tokens(&[create_call.main_token, create_call.wrapped_token])
contracts: vec![pool_created.pool], .with_attributes(&[
static_att: vec![ ("pool_type", "ERC4626LinearPoolFactory".as_bytes()),
tycho::Attribute { (
name: "pool_type".into(), "upper_target",
value: "ERC4626LinearPoolFactory".into(), &create_call.upper_target.to_signed_bytes_be(),
change: tycho::ChangeType::Creation.into(), ),
}, ])
tycho::Attribute { .as_swap_type("balancer_pool", ImplementationType::Vm),
name: "upper_target".into(), )
value: create_call.upper_target.to_signed_bytes_be(),
change: tycho::ChangeType::Creation.into(),
},
// Note, `lower_target` is generally hardcoded for all pools, not located in call data
// Note, rate provider might be provided as `create.protocol_id`, but as a BigInt. needs investigation
],
change: tycho::ChangeType::Creation.into(),
protocol_type: Some(ProtocolType {
name: "balancer_pool".to_string(),
financial_type: FinancialType::Swap.into(),
attribute_schema: vec![],
implementation_type: ImplementationType::Vm.into(),
}),
tx: Some(tx.clone()),
})
} }
hex!("5F43FBa61f63Fa6bFF101a0A0458cEA917f6B347") => { hex!("5F43FBa61f63Fa6bFF101a0A0458cEA917f6B347") => {
let create_call = let create_call =
@@ -147,31 +105,18 @@ pub fn address_map(
let pool_created = let pool_created =
abi::euler_linear_pool_factory::events::PoolCreated::match_and_decode(log)?; abi::euler_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
Some(tycho::ProtocolComponent { Some(
id: hex::encode(&pool_created.pool), ProtocolComponent::at_contract(&pool_created.pool, &tx)
tokens: vec![create_call.main_token, create_call.wrapped_token], .with_tokens(&[create_call.main_token, create_call.wrapped_token])
contracts: vec![pool_created.pool], .with_attributes(&[
static_att: vec![ ("pool_type", "EulerLinearPoolFactory".as_bytes()),
tycho::Attribute { (
name: "pool_type".into(), "upper_target",
value: "EulerLinearPoolFactory".into(), &create_call.upper_target.to_signed_bytes_be(),
change: tycho::ChangeType::Creation.into(), ),
}, ])
tycho::Attribute { .as_swap_type("balancer_pool", ImplementationType::Vm),
name: "upper_target".into(), )
value: create_call.upper_target.to_signed_bytes_be(),
change: tycho::ChangeType::Creation.into(),
},
],
change: tycho::ChangeType::Creation.into(),
protocol_type: Some(ProtocolType {
name: "balancer_pool".to_string(),
financial_type: FinancialType::Swap.into(),
attribute_schema: vec![],
implementation_type: ImplementationType::Vm.into(),
}),
tx: Some(tx.clone()),
})
} }
// ❌ Reading the deployed factory for Gearbox showcases that it's currently disabled // ❌ Reading the deployed factory for Gearbox showcases that it's currently disabled
// hex!("39A79EB449Fc05C92c39aA6f0e9BfaC03BE8dE5B") => { // hex!("39A79EB449Fc05C92c39aA6f0e9BfaC03BE8dE5B") => {
@@ -226,31 +171,18 @@ pub fn address_map(
let pool_created = let pool_created =
abi::silo_linear_pool_factory::events::PoolCreated::match_and_decode(log)?; abi::silo_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
Some(tycho::ProtocolComponent { Some(
id: hex::encode(&pool_created.pool), ProtocolComponent::at_contract(&pool_created.pool, &tx)
tokens: vec![create_call.main_token, create_call.wrapped_token], .with_tokens(&[create_call.main_token, create_call.wrapped_token])
contracts: vec![pool_created.pool], .with_attributes(&[
static_att: vec![ ("pool_type", "SiloLinearPoolFactory".as_bytes()),
tycho::Attribute { (
name: "pool_type".into(), "upper_target",
value: "SiloLinearPoolFactory".into(), &create_call.upper_target.to_signed_bytes_be(),
change: tycho::ChangeType::Creation.into(), ),
}, ])
tycho::Attribute { .as_swap_type("balancer_pool", ImplementationType::Vm),
name: "upper_target".into(), )
value: create_call.upper_target.to_signed_bytes_be(),
change: tycho::ChangeType::Creation.into(),
},
],
change: tycho::ChangeType::Creation.into(),
protocol_type: Some(ProtocolType {
name: "balancer_pool".to_string(),
financial_type: FinancialType::Swap.into(),
attribute_schema: vec![],
implementation_type: ImplementationType::Vm.into(),
}),
tx: Some(tx.clone()),
})
} }
hex!("5F5222Ffa40F2AEd6380D022184D6ea67C776eE0") => { hex!("5F5222Ffa40F2AEd6380D022184D6ea67C776eE0") => {
let create_call = let create_call =
@@ -258,65 +190,36 @@ pub fn address_map(
let pool_created = let pool_created =
abi::yearn_linear_pool_factory::events::PoolCreated::match_and_decode(log)?; abi::yearn_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
Some(tycho::ProtocolComponent { Some(
id: hex::encode(&pool_created.pool), ProtocolComponent::at_contract(&pool_created.pool, &tx)
tokens: vec![create_call.main_token, create_call.wrapped_token], .with_tokens(&[create_call.main_token, create_call.wrapped_token])
contracts: vec![pool_created.pool], .with_attributes(&[
static_att: vec![ ("pool_type", "YearnLinearPoolFactory".as_bytes()),
tycho::Attribute { (
name: "pool_type".into(), "upper_target",
value: "YearnLinearPoolFactory".into(), &create_call.upper_target.to_signed_bytes_be(),
change: tycho::ChangeType::Creation.into(), ),
}, ])
tycho::Attribute { .as_swap_type("balancer_pool", ImplementationType::Vm),
name: "upper_target".into(), )
value: create_call.upper_target.to_signed_bytes_be(),
change: tycho::ChangeType::Creation.into(),
},
],
change: tycho::ChangeType::Creation.into(),
protocol_type: Some(ProtocolType {
name: "balancer_pool".to_string(),
financial_type: FinancialType::Swap.into(),
attribute_schema: vec![],
implementation_type: ImplementationType::Vm.into(),
}),
tx: Some(tx.clone()),
})
} }
// The `WeightedPool2TokenFactory` is a deprecated contract but we've included it since one // The `WeightedPool2TokenFactory` is a deprecated contract, but we've included
// of the highest TVL pools, 80BAL-20WETH, is able to be tracked. // it to be able to track one of the highest TVL pools: 80BAL-20WETH.
hex!("A5bf2ddF098bb0Ef6d120C98217dD6B141c74EE0") => { hex!("A5bf2ddF098bb0Ef6d120C98217dD6B141c74EE0") => {
let create_call = let create_call =
abi::weighted_pool_tokens_factory::functions::Create::match_and_decode(call)?; abi::weighted_pool_tokens_factory::functions::Create::match_and_decode(call)?;
let pool_created = let pool_created =
abi::weighted_pool_tokens_factory::events::PoolCreated::match_and_decode(log)?; abi::weighted_pool_tokens_factory::events::PoolCreated::match_and_decode(log)?;
Some(tycho::ProtocolComponent { Some(
id: hex::encode(&pool_created.pool), ProtocolComponent::at_contract(&pool_created.pool, &tx)
tokens: create_call.tokens, .with_tokens(&create_call.tokens)
contracts: vec![pool_created.pool], .with_attributes(&[
static_att: vec![ ("pool_type", "WeightedPool2TokensFactory".as_bytes()),
tycho::Attribute { ("weights", &create_call.weights.serialize_bytes()),
name: "pool_type".into(), ])
value: "WeightedPool2TokensFactory".into(), .as_swap_type("balancer_pool", ImplementationType::Vm),
change: tycho::ChangeType::Creation.into(), )
},
tycho::Attribute {
name: "weights".into(),
value: create_call.weights.serialize_bytes(),
change: tycho::ChangeType::Creation.into(),
},
],
change: tycho::ChangeType::Creation.into(),
protocol_type: Some(ProtocolType {
name: "balancer_pool".to_string(),
financial_type: FinancialType::Swap.into(),
attribute_schema: vec![],
implementation_type: ImplementationType::Vm.into(),
}),
tx: Some(tx.clone()),
})
} }
_ => None, _ => None,
} }