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]] [[package]]
name = "ethereum-balancer-v2" name = "ethereum-balancer-v2"
version = "0.2.5" version = "0.3.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes",
"ethabi 18.0.0", "ethabi 18.0.0",
"getrandom", "getrandom",
"hex", "hex",
"hex-literal 0.4.1",
"itertools 0.12.1", "itertools 0.12.1",
"num-bigint", "num-bigint",
"prost 0.11.9",
"prost-types 0.12.6",
"substreams", "substreams",
"substreams-ethereum", "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]] [[package]]
@@ -1701,6 +1697,22 @@ dependencies = [
"substreams-ethereum", "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]] [[package]]
name = "tycho-substreams" name = "tycho-substreams"
version = "0.2.1" version = "0.2.1"

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "ethereum-balancer-v2" name = "ethereum-balancer-v2"
version = "0.2.5" version = "0.3.0"
edition = "2021" edition = "2021"
[lib] [lib]
@@ -10,16 +10,12 @@ crate-type = ["cdylib"]
[dependencies] [dependencies]
substreams = "0.5.22" substreams = "0.5.22"
substreams-ethereum = "0.9.9" substreams-ethereum = "0.9.9"
prost = "0.11"
prost-types = "0.12.3"
hex-literal = "0.4.1"
ethabi = "18.0.0" ethabi = "18.0.0"
hex = "0.4.3" hex = "0.4.3"
bytes = "1.5.0"
anyhow = "1.0.75" anyhow = "1.0.75"
num-bigint = "0.4.4" num-bigint = "0.4.4"
itertools = "0.12.0" 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] [build-dependencies]
anyhow = "1" anyhow = "1"

View File

@@ -7,22 +7,6 @@ adapter_build_args: "0xBA12222222228d8Ba445958a75a0704d566BF2C8"
skip_balance_check: true skip_balance_check: true
initialized_accounts: initialized_accounts:
- "0xba12222222228d8ba445958a75a0704d566bf2c8" - "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: tests:
# WeightedPoolFactoryV4 - 0x897888115Ada5773E02aA29F775430BFB5F34c51 # WeightedPoolFactoryV4 - 0x897888115Ada5773E02aA29F775430BFB5F34c51
- name: test_weighted_pool_v4 - name: test_weighted_pool_v4
@@ -64,7 +48,8 @@ tests:
expected_components: expected_components:
- id: "0x42ed016f826165c2e5976fe5bc3df540c5ad0af700000000000000000000058b" - id: "0x42ed016f826165c2e5976fe5bc3df540c5ad0af700000000000000000000058b"
tokens: tokens:
- "0x42ed016f826165c2e5976fe5bc3df540c5ad0af7" # BPT tokens not supported - their balance handling is currently bugged
# - "0x42ed016f826165c2e5976fe5bc3df540c5ad0af7"
- "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0" - "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
- "0xac3E018457B222d93114458476f3E3416Abbe38F" - "0xac3E018457B222d93114458476f3E3416Abbe38F"
- "0xae78736Cd615f374D3085123A210448E74Fc6393" - "0xae78736Cd615f374D3085123A210448E74Fc6393"
@@ -74,19 +59,20 @@ tests:
fee: "0x5af3107a4000" fee: "0x5af3107a4000"
manual_updates: "0x01" manual_updates: "0x01"
pool_type: "0x436f6d706f7361626c65537461626c65506f6f6c466163746f7279" pool_type: "0x436f6d706f7361626c65537461626c65506f6f6c466163746f7279"
skip_simulation: true skip_simulation: false
creation_tx: "0x53ff6bab0d8a76a998e29e59da8068ad906ae85507a1c2fbf2505e2cb52fd754" creation_tx: "0x53ff6bab0d8a76a998e29e59da8068ad906ae85507a1c2fbf2505e2cb52fd754"
# ERC4626LinearPoolFactory - 0x813EE7a840CE909E7Fea2117A44a90b8063bd4fd # ERC4626LinearPoolFactory - 0x813EE7a840CE909E7Fea2117A44a90b8063bd4fd
- name: test_erc4626_linear_pool_creation - name: test_erc4626_linear_pool_creation
start_block: 17480142 start_block: 17480142
stop_block: 17480242 stop_block: 17480152
expected_components: expected_components:
- id: "0x3fcb7085b8f2f473f80bf6d879cae99ea4de934400000000000000000000056d" - id: "0x3fcb7085b8f2f473f80bf6d879cae99ea4de934400000000000000000000056d"
tokens: tokens:
- "0x39Dd7790e75C6F663731f7E1FdC0f35007D3879b" - "0x39Dd7790e75C6F663731f7E1FdC0f35007D3879b"
- "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
- "0x3fcb7085b8f2f473f80bf6d879cae99ea4de9344" # BPT tokens not supported - their balance handling is currently bugged
# - "0x3fcb7085b8f2f473f80bf6d879cae99ea4de9344"
static_attributes: static_attributes:
wrapped_token: "0x39dd7790e75c6f663731f7e1fdc0f35007d3879b" wrapped_token: "0x39dd7790e75c6f663731f7e1fdc0f35007d3879b"
fee: "0x00b5e620f48000" fee: "0x00b5e620f48000"
@@ -95,73 +81,10 @@ tests:
upper_target: "0x108b2a2c28029094000000" upper_target: "0x108b2a2c28029094000000"
bpt: "0x3fcb7085b8f2f473f80bf6d879cae99ea4de9344" bpt: "0x3fcb7085b8f2f473f80bf6d879cae99ea4de9344"
main_token: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" main_token: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
skip_simulation: true skip_simulation: true # no liquidity added within more than 100k blocks
creation_tx: "0x5ff97870685370bab3876a4335d28c42e24659064fe78b486d6fb1b37b992877" creation_tx: "0x5ff97870685370bab3876a4335d28c42e24659064fe78b486d6fb1b37b992877"
# EulerLinearPoolFactory - 0x5F43FBa61f63Fa6bFF101a0A0458cEA917f6B347 # WeightedPoolFactoryV1 - 0x8E9aa87E45e92bad84D5F8DD1bff34Fb92637dE9
- 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
- name: test_weighted_pool_v1 - name: test_weighted_pool_v1
start_block: 13899835 start_block: 13899835
stop_block: 13901090 stop_block: 13901090
@@ -178,7 +101,7 @@ tests:
skip_simulation: false skip_simulation: false
creation_tx: "0xc5c3b384644363aa15cf9a0c33dfebd22df351446bce92ee49ead7d5d896b4e9" creation_tx: "0xc5c3b384644363aa15cf9a0c33dfebd22df351446bce92ee49ead7d5d896b4e9"
# WeigthedPoolFactoryV2 - 0xcC508a455F5b0073973107Db6a878DdBDab957bC # WeightedPoolFactoryV2 - 0xcC508a455F5b0073973107Db6a878DdBDab957bC
- name: test_weighted_pool_v2 - name: test_weighted_pool_v2
start_block: 15732922 start_block: 15732922
stop_block: 15742922 stop_block: 15742922
@@ -194,23 +117,90 @@ tests:
normalized_weights: "0x5b22307830366630356235396433623230303030222c22307830366630356235396433623230303030225d" normalized_weights: "0x5b22307830366630356235396433623230303030222c22307830366630356235396433623230303030225d"
rate_providers: "0x5b22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c22307831613866383163323536616565396336343065313462623034353363653234376561306466653666225d" rate_providers: "0x5b22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c22307831613866383163323536616565396336343065313462623034353363653234376561306466653666225d"
pool_type: "0x5765696768746564506f6f6c466163746f72795632" pool_type: "0x5765696768746564506f6f6c466163746f72795632"
skip_simulation: true # can't simulate because it has rate provider skip_simulation: false
creation_tx: "0x9a949a52e4179d0c57dcffd6884d5787febfb92f8f4b7e114ef8cfbda0292a79" creation_tx: "0x9a949a52e4179d0c57dcffd6884d5787febfb92f8f4b7e114ef8cfbda0292a79"
# WeigthedPoolFactoryV3 - 0x5Dd94Da3644DDD055fcf6B3E1aa310Bb7801EB8b # WeightedPoolFactoryV3 - 0x5Dd94Da3644DDD055fcf6B3E1aa310Bb7801EB8b
- name: test_weighted_pool_v3 - name: test_weighted_pool_v3
start_block: 16975289 start_block: 16985129
stop_block: 16975290 stop_block: 16990284
expected_components: expected_components:
- id: "0xd278166dabaf26707362f7cfdd204b277fd2a4600002000000000000000004f6" - id: "0x42fbd9f666aacc0026ca1b88c94259519e03dd67000200000000000000000507"
tokens: tokens:
- "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - "0x823E1B82cE1Dc147Bbdb25a203f046aFab1CE918"
- "0xE60779CC1b2c1d0580611c526a8DF0E3f870EC48" - "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
static_attributes: static_attributes:
manual_updates: "0x01" manual_updates: "0x01"
fee: "0x11c37937e08000" fee: "0x0aa87bee538000"
normalized_weights: "0x5b22307830366630356235396433623230303030222c22307830366630356235396433623230303030225d" normalized_weights: "0x5b22307830366630356235396433623230303030222c22307830366630356235396433623230303030225d"
rate_providers: "0x5b22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c22307830303030303030303030303030303030303030303030303030303030303030303030303030303030225d" rate_providers: "0x5b22307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c22307830303030303030303030303030303030303030303030303030303030303030303030303030303030225d"
pool_type: "0x5765696768746564506f6f6c466163746f72795633" pool_type: "0x5765696768746564506f6f6c466163746f72795633"
skip_simulation: true # not enough liquidity added within more than 100k blocks skip_simulation: false
creation_tx: "0x3dda8ac9423f0018dffdda343c376cc1781ad12cb49827770351411d84036bf8" 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 substreams_ethereum::{pb::eth, Event};
use tycho_substreams::{ 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"); pub const VAULT_ADDRESS: &[u8] = &hex!("BA12222222228d8Ba445958a75a0704d566BF2C8");
@@ -197,6 +199,29 @@ pub fn map_protocol_changes(
.components .components
.iter() .iter()
.for_each(|component| { .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); builder.add_protocol_component(component);
let entity_change = EntityChanges { let entity_change = EntityChanges {
component_id: component.id.clone(), component_id: component.id.clone(),
@@ -261,6 +286,8 @@ pub fn map_protocol_changes(
// Process all `transaction_changes` for final output in the `BlockChanges`, // Process all `transaction_changes` for final output in the `BlockChanges`,
// sorted by transaction index (the key). // sorted by transaction index (the key).
let block_storage_changes = get_block_storage_changes(&block);
Ok(BlockChanges { Ok(BlockChanges {
block: Some((&block).into()), block: Some((&block).into()),
changes: transaction_changes changes: transaction_changes
@@ -268,5 +295,6 @@ pub fn map_protocol_changes(
.sorted_unstable_by_key(|(index, _)| *index) .sorted_unstable_by_key(|(index, _)| *index)
.filter_map(|(_, builder)| builder.build()) .filter_map(|(_, builder)| builder.build())
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
storage_changes: block_storage_changes,
}) })
} }

View File

@@ -22,17 +22,18 @@ fn get_pool_registered(
.clone() .clone()
} }
fn get_token_registered( // TODO: add this back if we need to track BPT
tx: &TransactionTrace, // fn get_token_registered(
pool_id: &[u8], // tx: &TransactionTrace,
) -> abi::vault::events::TokensRegistered { // pool_id: &[u8],
tx.logs_with_calls() // ) -> abi::vault::events::TokensRegistered {
.filter(|(log, _)| log.address == VAULT_ADDRESS) // tx.logs_with_calls()
.filter_map(|(log, _)| abi::vault::events::TokensRegistered::match_and_decode(log)) // .filter(|(log, _)| log.address == VAULT_ADDRESS)
.find(|ev| ev.pool_id == pool_id) // .filter_map(|(log, _)| abi::vault::events::TokensRegistered::match_and_decode(log))
.unwrap() // .find(|ev| ev.pool_id == pool_id)
.clone() // .unwrap()
} // .clone()
// }
// This is the main function that handles the creation of `ProtocolComponent`s with `Attribute`s // 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: // 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 = 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)?;
let pool_registered = get_pool_registered(tx, &pool_created.pool); 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( Some(
ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id))) ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
.with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()]) .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(&[ .with_attributes(&[
("pool_type", "ComposableStablePoolFactory".as_bytes()), ("pool_type", "ComposableStablePoolFactory".as_bytes()),
("bpt", &pool_created.pool), ("bpt", &pool_created.pool),
@@ -209,12 +212,17 @@ 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)?;
let pool_registered = get_pool_registered(tx, &pool_created.pool); 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( Some(
ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id))) ProtocolComponent::new(&format!("0x{}", hex::encode(pool_registered.pool_id)))
.with_contracts(&[pool_created.pool.clone(), VAULT_ADDRESS.to_vec()]) .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(&[ .with_attributes(&[
("pool_type", "ERC4626LinearPoolFactory".as_bytes()), ("pool_type", "ERC4626LinearPoolFactory".as_bytes()),
( (
@@ -237,156 +245,6 @@ pub fn address_map(
.as_swap_type("balancer_v2_pool", ImplementationType::Vm), .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 // The `WeightedPool2TokenFactory` is a deprecated contract, but we've included
// it to be able to track one of the highest TVL pools: 80BAL-20WETH. // it to be able to track one of the highest TVL pools: 80BAL-20WETH.
hex!("A5bf2ddF098bb0Ef6d120C98217dD6B141c74EE0") => { hex!("A5bf2ddF098bb0Ef6d120C98217dD6B141c74EE0") => {
@@ -414,6 +272,168 @@ pub fn address_map(
.as_swap_type("balancer_v2_pool", ImplementationType::Vm), .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, _ => None,
} }
} }

View File

@@ -1,7 +1,7 @@
specVersion: v0.1.0 specVersion: v0.1.0
package: package:
name: "ethereum_balancer_v2" 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" url: "https://github.com/propeller-heads/tycho-protocol-sdk/tree/main/substreams/ethereum-balancer-v2"
protobuf: protobuf:

View File

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