feat: Balancer V2 DCI integration (#219)

* feat: Add DCI Entrypoints to BalancerV2 components

* fix: miscellaneous fixes before Balancer V2 resync

This commit fixes the entrypoints created by Balancer v2 packages, removes some disabled factories and remove support for BPT tokens (this is still to be investigated but so far we won't be able to support them)

* refactor: fix CI and bump version

* chore: update comments

---------

Co-authored-by: Thales <thales@datarevenue.com>
Co-authored-by: zizou <111426680+flopell@users.noreply.github.com>
Co-authored-by: Louise Poole <louise@datarevenue.com>
This commit is contained in:
Zizou
2025-06-16 11:35:59 +02:00
committed by GitHub
parent de5c9503bc
commit 7da01c745b
7 changed files with 324 additions and 278 deletions

24
substreams/Cargo.lock generated
View File

@@ -240,21 +240,17 @@ dependencies = [
[[package]]
name = "ethereum-balancer-v2"
version = "0.2.5"
version = "0.3.0"
dependencies = [
"anyhow",
"bytes",
"ethabi 18.0.0",
"getrandom",
"hex",
"hex-literal 0.4.1",
"itertools 0.12.1",
"num-bigint",
"prost 0.11.9",
"prost-types 0.12.6",
"substreams",
"substreams-ethereum",
"tycho-substreams 0.2.1 (git+https://github.com/propeller-heads/tycho-protocol-sdk.git?rev=52d5021)",
"tycho-substreams 0.2.1 (git+https://github.com/propeller-heads/tycho-protocol-sdk.git?rev=51995f9)",
]
[[package]]
@@ -1701,6 +1697,22 @@ dependencies = [
"substreams-ethereum",
]
[[package]]
name = "tycho-substreams"
version = "0.2.1"
source = "git+https://github.com/propeller-heads/tycho-protocol-sdk.git?rev=51995f9#51995f9731ecf549a5ae68c281906c90efe9909a"
dependencies = [
"ethabi 18.0.0",
"hex",
"itertools 0.12.1",
"num-bigint",
"prost 0.11.9",
"serde",
"serde_json",
"substreams",
"substreams-ethereum",
]
[[package]]
name = "tycho-substreams"
version = "0.2.1"

View File

@@ -1,6 +1,6 @@
[package]
name = "ethereum-balancer-v2"
version = "0.2.5"
version = "0.3.0"
edition = "2021"
[lib]
@@ -10,16 +10,12 @@ crate-type = ["cdylib"]
[dependencies]
substreams = "0.5.22"
substreams-ethereum = "0.9.9"
prost = "0.11"
prost-types = "0.12.3"
hex-literal = "0.4.1"
ethabi = "18.0.0"
hex = "0.4.3"
bytes = "1.5.0"
anyhow = "1.0.75"
num-bigint = "0.4.4"
itertools = "0.12.0"
tycho-substreams = { git = "https://github.com/propeller-heads/tycho-protocol-sdk.git", rev = "52d5021" }
tycho-substreams = { git = "https://github.com/propeller-heads/tycho-protocol-sdk.git", rev = "51995f9" }
[build-dependencies]
anyhow = "1"

View File

@@ -7,22 +7,6 @@ adapter_build_args: "0xBA12222222228d8Ba445958a75a0704d566BF2C8"
skip_balance_check: true
initialized_accounts:
- "0xba12222222228d8ba445958a75a0704d566bf2c8"
# Uncomment entries below to include composable stable pool dependencies
# wstETH dependencies
# - "0x72D07D7DcA67b8A406aD1Ec34ce969c90bFEE768"
# - "0xb8ffc3cd6e7cf5a098a1c92f48009765b24088dc"
# - "0xae7ab96520de3a18e5e111b5eaab095312d7fe84"
# - "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0"
# - "0x2b33cf282f867a7ff693a66e11b0fcc5552e4425"
# - "0x17144556fd3424edc8fc8a4c940b2d04936d17eb"
# sfrxETH dependencies
# - "0x302013E7936a39c358d07A3Df55dc94EC417E3a1"
# - "0xac3e018457b222d93114458476f3e3416abbe38f"
# rETH dependencies
# - "0x1a8F81c256aee9C640e14bB0453ce247ea0DFE6F"
# - "0x07fcabcbe4ff0d80c2b1eb42855c0131b6cba2f4"
# - "0x1d8f8f00cfa6758d7be78336684788fb0ee0fa46"
# - "0xae78736cd615f374d3085123a210448e74fc6393"
tests:
# WeightedPoolFactoryV4 - 0x897888115Ada5773E02aA29F775430BFB5F34c51
- name: test_weighted_pool_v4
@@ -64,7 +48,8 @@ tests:
expected_components:
- id: "0x42ed016f826165c2e5976fe5bc3df540c5ad0af700000000000000000000058b"
tokens:
- "0x42ed016f826165c2e5976fe5bc3df540c5ad0af7"
# BPT tokens not supported - their balance handling is currently bugged
# - "0x42ed016f826165c2e5976fe5bc3df540c5ad0af7"
- "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
- "0xac3E018457B222d93114458476f3E3416Abbe38F"
- "0xae78736Cd615f374D3085123A210448E74Fc6393"
@@ -74,19 +59,20 @@ tests:
fee: "0x5af3107a4000"
manual_updates: "0x01"
pool_type: "0x436f6d706f7361626c65537461626c65506f6f6c466163746f7279"
skip_simulation: true
skip_simulation: false
creation_tx: "0x53ff6bab0d8a76a998e29e59da8068ad906ae85507a1c2fbf2505e2cb52fd754"
# ERC4626LinearPoolFactory - 0x813EE7a840CE909E7Fea2117A44a90b8063bd4fd
- name: test_erc4626_linear_pool_creation
start_block: 17480142
stop_block: 17480242
stop_block: 17480152
expected_components:
- id: "0x3fcb7085b8f2f473f80bf6d879cae99ea4de934400000000000000000000056d"
tokens:
- "0x39Dd7790e75C6F663731f7E1FdC0f35007D3879b"
- "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
- "0x3fcb7085b8f2f473f80bf6d879cae99ea4de9344"
# BPT tokens not supported - their balance handling is currently bugged
# - "0x3fcb7085b8f2f473f80bf6d879cae99ea4de9344"
static_attributes:
wrapped_token: "0x39dd7790e75c6f663731f7e1fdc0f35007d3879b"
fee: "0x00b5e620f48000"
@@ -95,73 +81,10 @@ tests:
upper_target: "0x108b2a2c28029094000000"
bpt: "0x3fcb7085b8f2f473f80bf6d879cae99ea4de9344"
main_token: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
skip_simulation: true
skip_simulation: true # no liquidity added within more than 100k blocks
creation_tx: "0x5ff97870685370bab3876a4335d28c42e24659064fe78b486d6fb1b37b992877"
# EulerLinearPoolFactory - 0x5F43FBa61f63Fa6bFF101a0A0458cEA917f6B347
- name: test_euler_linear_pool_creation
start_block: 16588117
stop_block: 16588217
expected_components:
- id: "0xd4e7c1f3da1144c9e2cfd1b015eda7652b4a439900000000000000000000046a"
tokens:
- "0xD4e7C1F3DA1144c9E2CfD1b015eDA7652b4a4399"
- "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
- "0xEb91861f8A4e1C12333F42DCE8fB0Ecdc28dA716"
static_attributes:
wrapped_token: "0xeb91861f8a4e1c12333f42dce8fb0ecdc28da716"
fee: "0x00b5e620f48000"
manual_updates: "0x01"
pool_type: "0x45756c65724c696e656172506f6f6c466163746f7279"
upper_target: "0x108b2a2c28029094000000"
bpt: "0xd4e7c1f3da1144c9e2cfd1b015eda7652b4a4399"
main_token: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
skip_simulation: true
creation_tx: "0x4a9ea683052afefdae3d189862868c3a7dc8f431d1d9828b6bfd9451a8816426"
# SiloLinearPoolFactory - 0x4E11AEec21baF1660b1a46472963cB3DA7811C89
- name: test_silo_linear_pool_creation
start_block: 17173185
stop_block: 17173187
expected_components:
- id: "0x74cbfaf94a3577c539a9dcee9870a6349a33b34f000000000000000000000534"
tokens:
- "0x192E67544694a7bAA2DeA94f9B1Df58BB3395A12"
- "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
- "0x74cbfaf94a3577c539a9dcee9870a6349a33b34f"
static_attributes:
wrapped_token: "0x192e67544694a7baa2dea94f9b1df58bb3395a12"
fee: "0x00e8d4a51000"
manual_updates: "0x01"
pool_type: "0x53696c6f4c696e656172506f6f6c466163746f7279"
upper_target: "0x00"
bpt: "0x74cbfaf94a3577c539a9dcee9870a6349a33b34f"
main_token: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
skip_simulation: true
creation_tx: "0x215c9f4256ab450368132f4063611ae8cdd98e80bea7e44ecf0600ed1d757018"
# YearnLinearPoolFactory - 0x5F5222Ffa40F2AEd6380D022184D6ea67C776eE0a
- name: test_yearn_linear_pool_creation
start_block: 17052601
stop_block: 17052605
expected_components:
- id: "0xac5b4ef7ede2f2843a704e96dcaa637f4ba3dc3f00000000000000000000051d"
tokens:
- "0x806E02Dea8d4a0882caD9fA3Fa75B212328692dE"
- "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
- "0xac5b4ef7ede2f2843a704e96dcaa637f4ba3dc3f"
static_attributes:
wrapped_token: "0x806e02dea8d4a0882cad9fa3fa75b212328692de"
fee: "0x00e8d4a51000"
manual_updates: "0x01"
pool_type: "0x596561726e4c696e656172506f6f6c466163746f7279"
upper_target: "0x00"
bpt: "0xac5b4ef7ede2f2843a704e96dcaa637f4ba3dc3f"
main_token: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
skip_simulation: true
creation_tx: "0x497aa03ce84d236c183204ddfc6762c8e4158da1ebc5e7e18e7f6cceaa497a2a"
# WeigthedPoolFactoryV1 - 0x8E9aa87E45e92bad84D5F8DD1bff34Fb92637dE9
# WeightedPoolFactoryV1 - 0x8E9aa87E45e92bad84D5F8DD1bff34Fb92637dE9
- name: test_weighted_pool_v1
start_block: 13899835
stop_block: 13901090
@@ -178,7 +101,7 @@ tests:
skip_simulation: false
creation_tx: "0xc5c3b384644363aa15cf9a0c33dfebd22df351446bce92ee49ead7d5d896b4e9"
# WeigthedPoolFactoryV2 - 0xcC508a455F5b0073973107Db6a878DdBDab957bC
# WeightedPoolFactoryV2 - 0xcC508a455F5b0073973107Db6a878DdBDab957bC
- name: test_weighted_pool_v2
start_block: 15732922
stop_block: 15742922
@@ -194,23 +117,90 @@ tests:
normalized_weights: "0x5b22307830366630356235396433623230303030222c22307830366630356235396433623230303030225d"
rate_providers: "0x5b22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c22307831613866383163323536616565396336343065313462623034353363653234376561306466653666225d"
pool_type: "0x5765696768746564506f6f6c466163746f72795632"
skip_simulation: true # can't simulate because it has rate provider
skip_simulation: false
creation_tx: "0x9a949a52e4179d0c57dcffd6884d5787febfb92f8f4b7e114ef8cfbda0292a79"
# WeigthedPoolFactoryV3 - 0x5Dd94Da3644DDD055fcf6B3E1aa310Bb7801EB8b
# WeightedPoolFactoryV3 - 0x5Dd94Da3644DDD055fcf6B3E1aa310Bb7801EB8b
- name: test_weighted_pool_v3
start_block: 16975289
stop_block: 16975290
start_block: 16985129
stop_block: 16990284
expected_components:
- id: "0xd278166dabaf26707362f7cfdd204b277fd2a4600002000000000000000004f6"
- id: "0x42fbd9f666aacc0026ca1b88c94259519e03dd67000200000000000000000507"
tokens:
- "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
- "0xE60779CC1b2c1d0580611c526a8DF0E3f870EC48"
- "0x823E1B82cE1Dc147Bbdb25a203f046aFab1CE918"
- "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
static_attributes:
manual_updates: "0x01"
fee: "0x11c37937e08000"
fee: "0x0aa87bee538000"
normalized_weights: "0x5b22307830366630356235396433623230303030222c22307830366630356235396433623230303030225d"
rate_providers: "0x5b22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c22307830303030303030303030303030303030303030303030303030303030303030303030303030303030225d"
pool_type: "0x5765696768746564506f6f6c466163746f72795633"
skip_simulation: true # not enough liquidity added within more than 100k blocks
creation_tx: "0x3dda8ac9423f0018dffdda343c376cc1781ad12cb49827770351411d84036bf8"
skip_simulation: false
creation_tx: "0x628d8e5df9940f6c52844082b03160ef3fb7e06c17877a9a21c8188406e6a201"
# #########################################################################################################################
# TEST BELOW ARE NOT RELEVANT BECAUSE THE FACTORIES ARE DISABLED AND NO ONE OF THE POOLS HAVE RELEVANT LIQUIDITY
# #########################################################################################################################
# # EulerLinearPoolFactory - 0x5F43FBa61f63Fa6bFF101a0A0458cEA917f6B347
# - name: test_euler_linear_pool_creation
# start_block: 16588117
# stop_block: 16588217
# expected_components:
# - id: "0xd4e7c1f3da1144c9e2cfd1b015eda7652b4a439900000000000000000000046a"
# tokens:
# # - "0xD4e7C1F3DA1144c9E2CfD1b015eDA7652b4a4399"
# - "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
# - "0xEb91861f8A4e1C12333F42DCE8fB0Ecdc28dA716"
# static_attributes:
# wrapped_token: "0xeb91861f8a4e1c12333f42dce8fb0ecdc28da716"
# fee: "0x00b5e620f48000"
# manual_updates: "0x01"
# pool_type: "0x45756c65724c696e656172506f6f6c466163746f7279"
# upper_target: "0x108b2a2c28029094000000"
# bpt: "0xd4e7c1f3da1144c9e2cfd1b015eda7652b4a4399"
# main_token: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
# skip_simulation: false
# creation_tx: "0x4a9ea683052afefdae3d189862868c3a7dc8f431d1d9828b6bfd9451a8816426"
# # SiloLinearPoolFactory - 0x4E11AEec21baF1660b1a46472963cB3DA7811C89
# - name: test_silo_linear_pool_creation
# start_block: 17173185
# stop_block: 17173187
# expected_components:
# - id: "0x74cbfaf94a3577c539a9dcee9870a6349a33b34f000000000000000000000534"
# tokens:
# - "0x192E67544694a7bAA2DeA94f9B1Df58BB3395A12"
# - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
# - "0x74cbfaf94a3577c539a9dcee9870a6349a33b34f"
# static_attributes:
# wrapped_token: "0x192e67544694a7baa2dea94f9b1df58bb3395a12"
# fee: "0x00e8d4a51000"
# manual_updates: "0x01"
# pool_type: "0x53696c6f4c696e656172506f6f6c466163746f7279"
# upper_target: "0x00"
# bpt: "0x74cbfaf94a3577c539a9dcee9870a6349a33b34f"
# main_token: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
# skip_simulation: true
# creation_tx: "0x215c9f4256ab450368132f4063611ae8cdd98e80bea7e44ecf0600ed1d757018"
# # YearnLinearPoolFactory - 0x5F5222Ffa40F2AEd6380D022184D6ea67C776eE0
# - name: test_yearn_linear_pool_creation
# start_block: 17052601
# stop_block: 17052605
# expected_components:
# - id: "0xac5b4ef7ede2f2843a704e96dcaa637f4ba3dc3f00000000000000000000051d"
# tokens:
# - "0x806E02Dea8d4a0882caD9fA3Fa75B212328692dE"
# - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
# - "0xac5b4ef7ede2f2843a704e96dcaa637f4ba3dc3f"
# static_attributes:
# wrapped_token: "0x806e02dea8d4a0882cad9fa3fa75b212328692de"
# fee: "0x00e8d4a51000"
# manual_updates: "0x01"
# pool_type: "0x596561726e4c696e656172506f6f6c466163746f7279"
# upper_target: "0x00"
# bpt: "0xac5b4ef7ede2f2843a704e96dcaa637f4ba3dc3f"
# main_token: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
# skip_simulation: true
# creation_tx: "0x497aa03ce84d236c183204ddfc6762c8e4158da1ebc5e7e18e7f6cceaa497a2a"

View File

@@ -9,7 +9,9 @@ use substreams::{
};
use substreams_ethereum::{pb::eth, Event};
use tycho_substreams::{
balances::aggregate_balances_changes, contract::extract_contract_changes_builder, prelude::*,
attributes::json_deserialize_address_list, balances::aggregate_balances_changes,
block_storage::get_block_storage_changes, contract::extract_contract_changes_builder,
entrypoint::create_entrypoint, models::entry_point_params::TraceData, prelude::*,
};
pub const VAULT_ADDRESS: &[u8] = &hex!("BA12222222228d8Ba445958a75a0704d566BF2C8");
@@ -197,6 +199,29 @@ pub fn map_protocol_changes(
.components
.iter()
.for_each(|component| {
let rate_providers = component
.static_att
.iter()
.find(|att| att.name == "rate_providers")
.map(|att| json_deserialize_address_list(&att.value));
if let Some(rate_providers) = rate_providers {
for rate_provider in rate_providers {
let trace_data = TraceData::Rpc(RpcTraceData {
caller: None,
calldata: hex::decode("679aefce").unwrap(), // getRate()
});
let (entrypoint, entrypoint_params) = create_entrypoint(
rate_provider,
"getRate()".to_string(),
component.id.clone(),
trace_data,
);
builder.add_entrypoint(&entrypoint);
builder.add_entrypoint_params(&entrypoint_params);
}
}
builder.add_protocol_component(component);
let entity_change = EntityChanges {
component_id: component.id.clone(),
@@ -261,6 +286,8 @@ pub fn map_protocol_changes(
// Process all `transaction_changes` for final output in the `BlockChanges`,
// sorted by transaction index (the key).
let block_storage_changes = get_block_storage_changes(&block);
Ok(BlockChanges {
block: Some((&block).into()),
changes: transaction_changes
@@ -268,5 +295,6 @@ pub fn map_protocol_changes(
.sorted_unstable_by_key(|(index, _)| *index)
.filter_map(|(_, builder)| builder.build())
.collect::<Vec<_>>(),
storage_changes: block_storage_changes,
})
}

View File

@@ -22,17 +22,18 @@ fn get_pool_registered(
.clone()
}
fn get_token_registered(
tx: &TransactionTrace,
pool_id: &[u8],
) -> abi::vault::events::TokensRegistered {
tx.logs_with_calls()
.filter(|(log, _)| log.address == VAULT_ADDRESS)
.filter_map(|(log, _)| abi::vault::events::TokensRegistered::match_and_decode(log))
.find(|ev| ev.pool_id == pool_id)
.unwrap()
.clone()
}
// TODO: add this back if we need to track BPT
// fn get_token_registered(
// tx: &TransactionTrace,
// pool_id: &[u8],
// ) -> abi::vault::events::TokensRegistered {
// tx.logs_with_calls()
// .filter(|(log, _)| log.address == VAULT_ADDRESS)
// .filter_map(|(log, _)| abi::vault::events::TokensRegistered::match_and_decode(log))
// .find(|ev| ev.pool_id == pool_id)
// .unwrap()
// .clone()
// }
// This is the main function that handles the creation of `ProtocolComponent`s with `Attribute`s
// based on the specific factory address. There's 3 factory groups that are represented here:
@@ -179,12 +180,14 @@ pub fn address_map(
let pool_created =
abi::composable_stable_pool_factory::events::PoolCreated::match_and_decode(log)?;
let pool_registered = get_pool_registered(tx, &pool_created.pool);
let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
// let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
Some(
ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
.with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()])
.with_tokens(&tokens_registered.tokens)
// .with_tokens(&tokens_registered.tokens) // TODO: add this back if we need to
// track BPT
.with_tokens(&create_call.tokens)
.with_attributes(&[
("pool_type", "ComposableStablePoolFactory".as_bytes()),
("bpt", &pool_created.pool),
@@ -209,12 +212,17 @@ pub fn address_map(
let pool_created =
abi::erc_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
let pool_registered = get_pool_registered(tx, &pool_created.pool);
let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
// let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
Some(
ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
.with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()])
.with_tokens(&tokens_registered.tokens)
// .with_tokens(&tokens_registered.tokens) //TODO: does it make sense to include
// BPT token here?
.with_tokens(&[
create_call.main_token.clone(),
create_call.wrapped_token.clone(),
])
.with_attributes(&[
("pool_type", "ERC4626LinearPoolFactory".as_bytes()),
(
@@ -237,156 +245,6 @@ pub fn address_map(
.as_swap_type("balancer_v2_pool", ImplementationType::Vm),
)
}
hex!("5F43FBa61f63Fa6bFF101a0A0458cEA917f6B347") => {
let create_call =
abi::euler_linear_pool_factory::functions::Create::match_and_decode(call)?;
let pool_created =
abi::euler_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
let pool_registered = get_pool_registered(tx, &pool_created.pool);
let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
Some(
ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
.with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()])
.with_tokens(&tokens_registered.tokens)
.with_attributes(&[
("pool_type", "EulerLinearPoolFactory".as_bytes()),
(
"upper_target",
&create_call
.upper_target
.to_signed_bytes_be(),
),
("manual_updates", &[1u8]),
("bpt", &pool_created.pool),
("main_token", &create_call.main_token),
("wrapped_token", &create_call.wrapped_token),
(
"fee",
&create_call
.swap_fee_percentage
.to_signed_bytes_be(),
),
])
.as_swap_type("balancer_v2_pool", ImplementationType::Vm),
)
}
// ❌ Reading the deployed factory for Gearbox showcases that it's currently disabled
// hex!("39A79EB449Fc05C92c39aA6f0e9BfaC03BE8dE5B") => {
// let create_call =
// abi::gearbox_linear_pool_factory::functions::Create::match_and_decode(call)?;
// let pool_created =
// abi::gearbox_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
// Some(tycho::ProtocolComponent {
// id: hex::encode(&pool_created.pool),
// tokens: vec![create_call.main_token, create_call.wrapped_token],
// contracts: vec![pool_addr.into(), pool_created.pool],
// static_att: vec![
// tycho::Attribute {
// name: "pool_type".into(),
// value: "GearboxLinearPoolFactory".into(),
// change: tycho::ChangeType::Creation.into(),
// },
// tycho::Attribute {
// name: "upper_target".into(),
// value: create_call.upper_target.to_signed_bytes_be(),
// change: tycho::ChangeType::Creation.into(),
// },
// ],
// change: tycho::ChangeType::Creation.into(),
// })
// }
// ❌ The `ManagedPoolFactory` is a bit ✨ unique ✨, so we'll leave it commented out for
// now Take a look at it's `Create` call to see how the params are structured.
// hex!("BF904F9F340745B4f0c4702c7B6Ab1e808eA6b93") => {
// let create_call =
// abi::managed_pool_factory::functions::Create::match_and_decode(call)?;
// let pool_created =
// abi::managed_pool_factory::events::PoolCreated::match_and_decode(log)?;
// Some(tycho::ProtocolComponent {
// id: hex::encode(&pool_created.pool),
// tokens: create_call.tokens,
// contracts: vec![pool_addr.into(), pool_created.pool],
// static_att: vec![
// tycho::Attribute {
// name: "pool_type".into(),
// value: "ManagedPoolFactory".into(),
// change: tycho::ChangeType::Creation.into(),
// },
// ],
// change: tycho::ChangeType::Creation.into(),
// })
// }
hex!("4E11AEec21baF1660b1a46472963cB3DA7811C89") => {
let create_call =
abi::silo_linear_pool_factory::functions::Create::match_and_decode(call)?;
let pool_created =
abi::silo_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
let pool_registered = get_pool_registered(tx, &pool_created.pool);
let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
Some(
ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
.with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()])
.with_tokens(&tokens_registered.tokens)
.with_attributes(&[
("pool_type", "SiloLinearPoolFactory".as_bytes()),
(
"upper_target",
&create_call
.upper_target
.to_signed_bytes_be(),
),
("manual_updates", &[1u8]),
("bpt", &pool_created.pool),
("main_token", &create_call.main_token),
("wrapped_token", &create_call.wrapped_token),
(
"fee",
&create_call
.swap_fee_percentage
.to_signed_bytes_be(),
),
])
.as_swap_type("balancer_v2_pool", ImplementationType::Vm),
)
}
hex!("5F5222Ffa40F2AEd6380D022184D6ea67C776eE0") => {
let create_call =
abi::yearn_linear_pool_factory::functions::Create::match_and_decode(call)?;
let pool_created =
abi::yearn_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
let pool_registered = get_pool_registered(tx, &pool_created.pool);
let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
Some(
ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
.with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()])
.with_tokens(&tokens_registered.tokens)
.with_attributes(&[
("pool_type", "YearnLinearPoolFactory".as_bytes()),
(
"upper_target",
&create_call
.upper_target
.to_signed_bytes_be(),
),
("manual_updates", &[1u8]),
("bpt", &pool_created.pool),
("main_token", &create_call.main_token),
("wrapped_token", &create_call.wrapped_token),
(
"fee",
&create_call
.swap_fee_percentage
.to_signed_bytes_be(),
),
])
.as_swap_type("balancer_v2_pool", ImplementationType::Vm),
)
}
// The `WeightedPool2TokenFactory` is a deprecated contract, but we've included
// it to be able to track one of the highest TVL pools: 80BAL-20WETH.
hex!("A5bf2ddF098bb0Ef6d120C98217dD6B141c74EE0") => {
@@ -414,6 +272,168 @@ pub fn address_map(
.as_swap_type("balancer_v2_pool", ImplementationType::Vm),
)
}
// ❌ EulerLinearPoolFactory: factory is disabled and no existing pools have relevant
// liquidity hex!("5F43FBa61f63Fa6bFF101a0A0458cEA917f6B347") => {
// let create_call =
// abi::euler_linear_pool_factory::functions::Create::match_and_decode(call)?;
// let pool_created =
// abi::euler_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
// let pool_registered = get_pool_registered(tx, &pool_created.pool);
// let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
// Some(
// ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
// .with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()])
// // .with_tokens(&tokens_registered.tokens)
// .with_tokens(&[
// create_call.main_token.clone(),
// create_call.wrapped_token.clone(),
// ])
// .with_attributes(&[
// ("pool_type", "EulerLinearPoolFactory".as_bytes()),
// (
// "upper_target",
// &create_call
// .upper_target
// .to_signed_bytes_be(),
// ),
// ("manual_updates", &[1u8]),
// ("bpt", &pool_created.pool),
// ("main_token", &create_call.main_token),
// ("wrapped_token", &create_call.wrapped_token),
// (
// "fee",
// &create_call
// .swap_fee_percentage
// .to_signed_bytes_be(),
// ),
// ])
// .as_swap_type("balancer_v2_pool", ImplementationType::Vm),
// )
// }
// ❌ Reading the deployed factory for Gearbox showcases that it's currently disabled
// hex!("39A79EB449Fc05C92c39aA6f0e9BfaC03BE8dE5B") => {
// let create_call =
// abi::gearbox_linear_pool_factory::functions::Create::match_and_decode(call)?;
// let pool_created =
// abi::gearbox_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
// Some(tycho::ProtocolComponent {
// id: hex::encode(&pool_created.pool),
// tokens: vec![create_call.main_token, create_call.wrapped_token],
// contracts: vec![pool_addr.into(), pool_created.pool],
// static_att: vec![
// tycho::Attribute {
// name: "pool_type".into(),
// value: "GearboxLinearPoolFactory".into(),
// change: tycho::ChangeType::Creation.into(),
// },
// tycho::Attribute {
// name: "upper_target".into(),
// value: create_call.upper_target.to_signed_bytes_be(),
// change: tycho::ChangeType::Creation.into(),
// },
// ],
// change: tycho::ChangeType::Creation.into(),
// })
// }
// ❌ The `ManagedPoolFactory` is a bit ✨ unique ✨, so we'll leave it commented out for
// now. Take a look at it's `Create` call to see how the params are structured.
// hex!("BF904F9F340745B4f0c4702c7B6Ab1e808eA6b93") => {
// let create_call =
// abi::managed_pool_factory::functions::Create::match_and_decode(call)?;
// let pool_created =
// abi::managed_pool_factory::events::PoolCreated::match_and_decode(log)?;
// Some(tycho::ProtocolComponent {
// id: hex::encode(&pool_created.pool),
// tokens: create_call.tokens,
// contracts: vec![pool_addr.into(), pool_created.pool],
// static_att: vec![
// tycho::Attribute {
// name: "pool_type".into(),
// value: "ManagedPoolFactory".into(),
// change: tycho::ChangeType::Creation.into(),
// },
// ],
// change: tycho::ChangeType::Creation.into(),
// })
// }
// ❌ SiloLinearPoolFactory: factory is disabled and no existing pools have relevant
// liquidity hex!("4E11AEec21baF1660b1a46472963cB3DA7811C89") => {
// let create_call =
// abi::silo_linear_pool_factory::functions::Create::match_and_decode(call)?;
// let pool_created =
// abi::silo_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
// let pool_registered = get_pool_registered(tx, &pool_created.pool);
// let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
// Some(
// ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
// .with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()])
// .with_tokens(&tokens_registered.tokens)
// .with_attributes(&[
// ("pool_type", "SiloLinearPoolFactory".as_bytes()),
// (
// "upper_target",
// &create_call
// .upper_target
// .to_signed_bytes_be(),
// ),
// ("manual_updates", &[1u8]),
// ("bpt", &pool_created.pool),
// ("main_token", &create_call.main_token),
// ("wrapped_token", &create_call.wrapped_token),
// (
// "fee",
// &create_call
// .swap_fee_percentage
// .to_signed_bytes_be(),
// ),
// ])
// .as_swap_type("balancer_v2_pool", ImplementationType::Vm),
// )
// }
// ❌ YearnLinearPoolFactory: factory is disabled and no existing pools have relevant
// liquidity hex!("5F5222Ffa40F2AEd6380D022184D6ea67C776eE0") => {
// let create_call =
// abi::yearn_linear_pool_factory::functions::Create::match_and_decode(call)?;
// let pool_created =
// abi::yearn_linear_pool_factory::events::PoolCreated::match_and_decode(log)?;
// let pool_registered = get_pool_registered(tx, &pool_created.pool);
// let tokens_registered = get_token_registered(tx, &pool_registered.pool_id);
// Some(
// ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
// .with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()])
// .with_tokens(&tokens_registered.tokens)
// .with_attributes(&[
// ("pool_type", "YearnLinearPoolFactory".as_bytes()),
// (
// "upper_target",
// &create_call
// .upper_target
// .to_signed_bytes_be(),
// ),
// ("manual_updates", &[1u8]),
// ("bpt", &pool_created.pool),
// ("main_token", &create_call.main_token),
// ("wrapped_token", &create_call.wrapped_token),
// (
// "fee",
// &create_call
// .swap_fee_percentage
// .to_signed_bytes_be(),
// ),
// ])
// .as_swap_type("balancer_v2_pool", ImplementationType::Vm),
// )
// }
_ => None,
}
}

View File

@@ -1,7 +1,7 @@
specVersion: v0.1.0
package:
name: "ethereum_balancer_v2"
version: v0.2.5
version: v0.3.0
url: "https://github.com/propeller-heads/tycho-protocol-sdk/tree/main/substreams/ethereum-balancer-v2"
protobuf:

View File

@@ -335,10 +335,10 @@ class TestRunner:
for sell_token, buy_token in itertools.permutations(pool_state.tokens, 2):
for prctg in ["0.001", "0.01", "0.1"]:
# Try to sell 0.1% of the protocol balance
try:
sell_amount = (
Decimal(prctg) * pool_state.balances[sell_token.address]
)
try:
amount_out, gas_used, _ = pool_state.get_amount_out(
sell_token, sell_amount, buy_token
)