feat: Add test for PancakeswapV2

- There are some ugly hardcodings here that I hope to improve.
This commit is contained in:
TAMARA LIPOWSKI
2025-09-19 02:06:26 -04:00
committed by Tamara
parent 1c5cf42d00
commit 99c8a32d23
3 changed files with 71 additions and 13 deletions

View File

@@ -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 alloy::primitives::U256;
use figment::{ use figment::{
@@ -23,8 +23,9 @@ use tycho_simulation::{
decoder::TychoStreamDecoder, decoder::TychoStreamDecoder,
engine_db::tycho_db::PreCachedDB, engine_db::tycho_db::PreCachedDB,
protocol::{ protocol::{
u256_num::bytes_to_u256, uniswap_v2::state::UniswapV2State, pancakeswap_v2::state::PancakeswapV2State, u256_num::bytes_to_u256,
uniswap_v3::state::UniswapV3State, vm::state::EVMPoolState, uniswap_v2::state::UniswapV2State, uniswap_v3::state::UniswapV3State,
vm::state::EVMPoolState,
}, },
}, },
protocol::models::DecoderContext, protocol::models::DecoderContext,
@@ -44,12 +45,20 @@ use crate::{
utils::build_spkg, utils::build_spkg,
}; };
static CLONE_TO_BASE_PROTOCOL: LazyLock<HashMap<&str, &str>> = LazyLock::new(|| {
HashMap::from([
("ethereum-sushiswap-v2", "ethereum-uniswap-v2"),
("ethereum-pancakeswap-v2", "ethereum-uniswap-v2"),
])
});
pub struct TestRunner { pub struct TestRunner {
db_url: String, db_url: String,
vm_traces: bool, vm_traces: bool,
substreams_path: PathBuf, substreams_path: PathBuf,
adapter_contract_builder: AdapterContractBuilder, adapter_contract_builder: AdapterContractBuilder,
match_test: Option<String>, match_test: Option<String>,
config_file_path: PathBuf,
} }
impl TestRunner { impl TestRunner {
@@ -60,13 +69,39 @@ impl TestRunner {
db_url: String, db_url: String,
vm_traces: bool, vm_traces: bool,
) -> Self { ) -> Self {
let base_protocol = CLONE_TO_BASE_PROTOCOL
.get(protocol.as_str())
.unwrap_or(&protocol.as_str())
.to_string();
let substreams_path = root_path let substreams_path = root_path
.join("substreams") .join("substreams")
.join(protocol); .join(&base_protocol);
let evm_path = root_path.join("evm"); let evm_path = root_path.join("evm");
let adapter_contract_builder = let adapter_contract_builder =
AdapterContractBuilder::new(evm_path.to_string_lossy().to_string()); 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<()> { pub fn run_tests(&self) -> miette::Result<()> {
@@ -75,20 +110,16 @@ impl TestRunner {
.unwrap_or(80); .unwrap_or(80);
info!("{}\n", "-".repeat(terminal_width)); info!("{}\n", "-".repeat(terminal_width));
let config_yaml_path = self
.substreams_path
.join("integration_test.tycho.yaml");
// Skip if test files don't exist // Skip if test files don't exist
if !config_yaml_path.exists() { if !self.config_file_path.exists() {
warn!( warn!(
"integration_test.tycho.yaml file not found at {}", "Config file not found at {}.",
self.substreams_path.display() self.config_file_path.display()
); );
return Ok(()); return Ok(());
} }
let config = match Self::parse_config(&config_yaml_path) { let config = match Self::parse_config(&self.config_file_path) {
Ok(cfg) => cfg, Ok(cfg) => cfg,
Err(e) => { Err(e) => {
warn!("Failed to parse config: {:?}", e); warn!("Failed to parse config: {:?}", e);
@@ -390,6 +421,12 @@ fn validate_state(
decoder decoder
.register_decoder_with_context::<UniswapV2State>(protocol_system, decoder_context); .register_decoder_with_context::<UniswapV2State>(protocol_system, decoder_context);
} }
"pancakeswap_v2" => {
decoder.register_decoder_with_context::<PancakeswapV2State>(
protocol_system,
decoder_context,
);
}
"uniswap_v3" | "pancakeswap_v3" => { "uniswap_v3" | "pancakeswap_v3" => {
decoder decoder
.register_decoder_with_context::<UniswapV3State>(protocol_system, decoder_context); .register_decoder_with_context::<UniswapV3State>(protocol_system, decoder_context);

View File

@@ -42,6 +42,8 @@ impl TychoRunner {
// Determine the correct module name based on protocol system // Determine the correct module name based on protocol system
let module_name = match protocol_system { let module_name = match protocol_system {
"uniswap_v2" => "map_pool_events", "uniswap_v2" => "map_pool_events",
"pancakeswap_v2" => "map_pool_events",
"sushiswap_v2" => "map_pool_events",
_ => "map_protocol_changes", _ => "map_protocol_changes",
}; };

View File

@@ -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