diff --git a/src/evm/protocol/uniswap_v4/state.rs b/src/evm/protocol/uniswap_v4/state.rs index e0c93930..819de538 100644 --- a/src/evm/protocol/uniswap_v4/state.rs +++ b/src/evm/protocol/uniswap_v4/state.rs @@ -377,16 +377,12 @@ impl ProtocolSim for UniswapV4State { #[cfg(test)] mod tests { - use std::{ - collections::{HashMap, HashSet}, - str::FromStr, - }; + use std::{collections::HashSet, fs, path::Path, str::FromStr}; use num_bigint::ToBigUint; use num_traits::FromPrimitive; use serde_json::Value; use tycho_client::feed::synchronizer::ComponentWithState; - use tycho_core::hex_bytes::Bytes; use super::*; use crate::protocol::models::TryFromWithBlock; @@ -450,8 +446,11 @@ mod tests { /// Compares a quote that we got from the UniswapV4 Quoter contract on Sepolia with a simulation /// using Tycho-simulation and a state extracted with Tycho-indexer async fn test_swap_sim() { - let data_str = include_str!("assets/sepolia_state_block_7239119.json"); - let data: Value = serde_json::from_str(data_str).expect("Failed to parse JSON"); + let project_root = env!("CARGO_MANIFEST_DIR"); + let asset_path = Path::new(project_root) + .join("tests/assets/decoder/uniswap_v4_snapshot_sepolia_block_7239119.json"); + let json_data = fs::read_to_string(asset_path).expect("Failed to read test asset"); + let data: Value = serde_json::from_str(&json_data).expect("Failed to parse JSON"); let state: ComponentWithState = serde_json::from_value(data) .expect("Expected json to match ComponentWithState structure"); diff --git a/src/evm/protocol/uniswap_v4/tycho_decoder.rs b/src/evm/protocol/uniswap_v4/tycho_decoder.rs index 000aea8b..5e9ff1af 100644 --- a/src/evm/protocol/uniswap_v4/tycho_decoder.rs +++ b/src/evm/protocol/uniswap_v4/tycho_decoder.rs @@ -43,10 +43,10 @@ impl TryFromWithBlock for UniswapV4State { let lp_fee = u32::from( snapshot - .state - .attributes - .get("fee") - .ok_or_else(|| InvalidSnapshotError::MissingAttribute("fee".to_string()))? + .component + .static_attributes + .get("key_lp_fee") + .ok_or_else(|| InvalidSnapshotError::MissingAttribute("key_lp_fee".to_string()))? .clone(), ); @@ -142,10 +142,10 @@ mod tests { .unwrap() .naive_utc(); - // Add a static attribute "tick_spacing" - let mut static_attributes: HashMap = HashMap::new(); - static_attributes - .insert("tick_spacing".to_string(), Bytes::from(60_i32.to_be_bytes().to_vec())); + let static_attributes: HashMap = HashMap::from([ + ("key_lp_fee".to_string(), Bytes::from(500_i32.to_be_bytes().to_vec())), + ("tick_spacing".to_string(), Bytes::from(60_i32.to_be_bytes().to_vec())), + ]); ProtocolComponent { id: "State1".to_string(), @@ -162,8 +162,7 @@ mod tests { } fn usv4_attributes() -> HashMap { - vec![ - ("fee".to_string(), Bytes::from(500_i32.to_be_bytes().to_vec())), + HashMap::from([ ("liquidity".to_string(), Bytes::from(100_u64.to_be_bytes().to_vec())), ("tick".to_string(), Bytes::from(300_i32.to_be_bytes().to_vec())), ( @@ -177,9 +176,7 @@ mod tests { ("protocol_fees/zero2one".to_string(), Bytes::from(0_u32.to_be_bytes().to_vec())), ("protocol_fees/one2zero".to_string(), Bytes::from(0_u32.to_be_bytes().to_vec())), ("ticks/60/net_liquidity".to_string(), Bytes::from(400_i128.to_be_bytes().to_vec())), - ] - .into_iter() - .collect::>() + ]) } fn header() -> Header { Header { @@ -223,11 +220,12 @@ mod tests { #[case::missing_sqrt_price("sqrt_price")] #[case::missing_tick("tick")] #[case::missing_tick_liquidity("tick_liquidities")] - #[case::missing_fee("fee")] + #[case::missing_fee("key_lp_fee")] #[case::missing_fee("protocol_fees/one2zero")] #[case::missing_fee("protocol_fees/zero2one")] async fn test_usv4_try_from_invalid(#[case] missing_attribute: String) { // remove missing attribute + let mut component = usv4_component(); let mut attributes = usv4_attributes(); attributes.remove(&missing_attribute); @@ -239,8 +237,10 @@ mod tests { attributes.remove("sqrt_price_x96"); } - if missing_attribute == "fee" { - attributes.remove("fee"); + if missing_attribute == "key_lp_fee" { + component + .static_attributes + .remove("key_lp_fee"); } let snapshot = ComponentWithState { @@ -249,7 +249,7 @@ mod tests { attributes, balances: HashMap::new(), }, - component: usv4_component(), + component, }; let result = UniswapV4State::try_from_with_block(snapshot, header(), &HashMap::new()).await; diff --git a/src/evm/protocol/uniswap_v4/assets/sepolia_state_block_7239119.json b/tests/assets/decoder/uniswap_v4_snapshot_sepolia_block_7239119.json similarity index 95% rename from src/evm/protocol/uniswap_v4/assets/sepolia_state_block_7239119.json rename to tests/assets/decoder/uniswap_v4_snapshot_sepolia_block_7239119.json index d8ebfd73..071da82b 100644 --- a/src/evm/protocol/uniswap_v4/assets/sepolia_state_block_7239119.json +++ b/tests/assets/decoder/uniswap_v4_snapshot_sepolia_block_7239119.json @@ -6,7 +6,6 @@ "balance_owner": "0x8c4bcbe6b9ef47855f97e675296fa3f6fafa5f1a", "sqrt_price_x96": "0x01000000000000000000000000", "protocol_fees/one2zero": "0x00", - "fee": "0x0bb8", "liquidity": "0x09184f0b3680", "ticks/887220/net-liquidity": "0xf6e7b0f4c980", "ticks/-887220/net-liquidity": "0x09184f0b3680", @@ -30,7 +29,8 @@ "static_attributes": { "hooks": "0x0000000000000000000000000000000000000000", "pool_id": "0x12e4510bc312b3e459340cbee3e281d81671083f56161c0c6673dee018cab4d0", - "tick_spacing": "0x3c" + "tick_spacing": "0x3c", + "key_lp_fee": "0x0bb8" }, "change": "Creation", "creation_tx": "0x3d458bfd841ee29b03958b19f737255286c9ce9b4026220c47f8a015b8ed6d1a",