From 99c8a32d23feb40868922a242ff74b1406738662 Mon Sep 17 00:00:00 2001 From: TAMARA LIPOWSKI Date: Fri, 19 Sep 2025 02:06:26 -0400 Subject: [PATCH] feat: Add test for PancakeswapV2 - There are some ugly hardcodings here that I hope to improve. --- protocol-testing/src/test_runner.rs | 63 +++++++++++++++---- protocol-testing/src/tycho_runner.rs | 2 + ...integration_test_pancakeswap_v2.tycho.yaml | 19 ++++++ 3 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 substreams/ethereum-uniswap-v2/integration_test_pancakeswap_v2.tycho.yaml diff --git a/protocol-testing/src/test_runner.rs b/protocol-testing/src/test_runner.rs index c3e556b..6963e84 100644 --- a/protocol-testing/src/test_runner.rs +++ b/protocol-testing/src/test_runner.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, env, path::PathBuf, str::FromStr}; +use std::{collections::HashMap, env, path::PathBuf, str::FromStr, sync::LazyLock}; use alloy::primitives::U256; use figment::{ @@ -23,8 +23,9 @@ use tycho_simulation::{ decoder::TychoStreamDecoder, engine_db::tycho_db::PreCachedDB, protocol::{ - u256_num::bytes_to_u256, uniswap_v2::state::UniswapV2State, - uniswap_v3::state::UniswapV3State, vm::state::EVMPoolState, + pancakeswap_v2::state::PancakeswapV2State, u256_num::bytes_to_u256, + uniswap_v2::state::UniswapV2State, uniswap_v3::state::UniswapV3State, + vm::state::EVMPoolState, }, }, protocol::models::DecoderContext, @@ -44,12 +45,20 @@ use crate::{ utils::build_spkg, }; +static CLONE_TO_BASE_PROTOCOL: LazyLock> = LazyLock::new(|| { + HashMap::from([ + ("ethereum-sushiswap-v2", "ethereum-uniswap-v2"), + ("ethereum-pancakeswap-v2", "ethereum-uniswap-v2"), + ]) +}); + pub struct TestRunner { db_url: String, vm_traces: bool, substreams_path: PathBuf, adapter_contract_builder: AdapterContractBuilder, match_test: Option, + config_file_path: PathBuf, } impl TestRunner { @@ -60,13 +69,39 @@ impl TestRunner { db_url: String, vm_traces: bool, ) -> Self { + let base_protocol = CLONE_TO_BASE_PROTOCOL + .get(protocol.as_str()) + .unwrap_or(&protocol.as_str()) + .to_string(); let substreams_path = root_path .join("substreams") - .join(protocol); + .join(&base_protocol); let evm_path = root_path.join("evm"); let adapter_contract_builder = AdapterContractBuilder::new(evm_path.to_string_lossy().to_string()); - Self { db_url, vm_traces, substreams_path, adapter_contract_builder, match_test } + + // Calculate config file path based on protocol. If the protocol is a clone of another + // protocol, we assume this protocol name will be appended to the integration test filename. + let config_file_name = if protocol != base_protocol { + format!( + "integration_test_{}.tycho.yaml", + protocol + .replace("ethereum-", "") + .replace('-', "_") + ) + } else { + "integration_test.tycho.yaml".to_string() + }; + let config_file_path = substreams_path.join(&config_file_name); + + Self { + db_url, + vm_traces, + substreams_path, + adapter_contract_builder, + match_test, + config_file_path, + } } pub fn run_tests(&self) -> miette::Result<()> { @@ -75,20 +110,16 @@ impl TestRunner { .unwrap_or(80); info!("{}\n", "-".repeat(terminal_width)); - let config_yaml_path = self - .substreams_path - .join("integration_test.tycho.yaml"); - // Skip if test files don't exist - if !config_yaml_path.exists() { + if !self.config_file_path.exists() { warn!( - "integration_test.tycho.yaml file not found at {}", - self.substreams_path.display() + "Config file not found at {}.", + self.config_file_path.display() ); return Ok(()); } - let config = match Self::parse_config(&config_yaml_path) { + let config = match Self::parse_config(&self.config_file_path) { Ok(cfg) => cfg, Err(e) => { warn!("Failed to parse config: {:?}", e); @@ -390,6 +421,12 @@ fn validate_state( decoder .register_decoder_with_context::(protocol_system, decoder_context); } + "pancakeswap_v2" => { + decoder.register_decoder_with_context::( + protocol_system, + decoder_context, + ); + } "uniswap_v3" | "pancakeswap_v3" => { decoder .register_decoder_with_context::(protocol_system, decoder_context); diff --git a/protocol-testing/src/tycho_runner.rs b/protocol-testing/src/tycho_runner.rs index 9cccd3e..ef46473 100644 --- a/protocol-testing/src/tycho_runner.rs +++ b/protocol-testing/src/tycho_runner.rs @@ -42,6 +42,8 @@ impl TychoRunner { // Determine the correct module name based on protocol system let module_name = match protocol_system { "uniswap_v2" => "map_pool_events", + "pancakeswap_v2" => "map_pool_events", + "sushiswap_v2" => "map_pool_events", _ => "map_protocol_changes", }; diff --git a/substreams/ethereum-uniswap-v2/integration_test_pancakeswap_v2.tycho.yaml b/substreams/ethereum-uniswap-v2/integration_test_pancakeswap_v2.tycho.yaml new file mode 100644 index 0000000..1631e27 --- /dev/null +++ b/substreams/ethereum-uniswap-v2/integration_test_pancakeswap_v2.tycho.yaml @@ -0,0 +1,19 @@ +substreams_yaml_path: ./ethereum-pancakeswap-v2.yaml +protocol_system: "pancakeswap_v2" +protocol_type_names: + - "pancakeswap_v2_pool" +skip_balance_check: true +initialized_accounts: +tests: + - name: test_trump_weth_pool + start_block: 20303260 + stop_block: 20303261 + expected_components: + - id: "0x2f7D5e1cA605fEFFCEdfEB9FD861d8da25a95a1d" + tokens: + - "0x7349a598D40F4533bECd9C95470D81Cc89ba7777" # TRUMP + - "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" # WETH + static_attributes: + fee: "0x1e" + creation_tx: "0x5cb93db6aa4e666f2086cdab31c87a55f244b13cc961b076fe6f171966d947d3" + skip_simulation: false