use alloy::{dyn_abi::SolType, primitives::Address, sol};
use hypersync_client::simple_types::Log;
use nautilus_model::defi::SharedDex;
use crate::{
events::burn::BurnEvent,
hypersync::helpers::{
extract_address_from_topic, extract_block_number, extract_log_index,
extract_transaction_hash, extract_transaction_index, validate_event_signature_hash,
},
};
const BURN_EVENT_SIGNATURE_HASH: &str =
"0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c";
sol! {
struct BurnEventData {
uint128 amount;
uint256 amount0;
uint256 amount1;
}
}
pub fn parse_burn_event(dex: SharedDex, log: Log) -> anyhow::Result<BurnEvent> {
validate_event_signature_hash("Burn", BURN_EVENT_SIGNATURE_HASH, &log)?;
let owner = extract_address_from_topic(&log, 1, "owner")?;
let tick_lower = match log.topics.get(2).and_then(|t| t.as_ref()) {
Some(topic) => {
let tick_lower_bytes: [u8; 32] = topic.as_ref().try_into()?;
i32::from_be_bytes(tick_lower_bytes[28..32].try_into()?)
}
None => anyhow::bail!("Missing tickLower in topic2 when parsing burn event"),
};
let tick_upper = match log.topics.get(3).and_then(|t| t.as_ref()) {
Some(topic) => {
let tick_upper_bytes: [u8; 32] = topic.as_ref().try_into()?;
i32::from_be_bytes(tick_upper_bytes[28..32].try_into()?)
}
None => anyhow::bail!("Missing tickUpper in topic3 when parsing burn event"),
};
if let Some(data) = &log.data {
let data_bytes = data.as_ref();
if data_bytes.len() < 3 * 32 {
anyhow::bail!("Burn event data is too short");
}
let decoded = match <BurnEventData as SolType>::abi_decode(data_bytes) {
Ok(decoded) => decoded,
Err(e) => anyhow::bail!("Failed to decode burn event data: {e}"),
};
let pool_address = Address::from_slice(
log.address
.clone()
.expect("Contract address should be set in logs")
.as_ref(),
);
Ok(BurnEvent::new(
dex,
pool_address,
extract_block_number(&log)?,
extract_transaction_hash(&log)?,
extract_transaction_index(&log)?,
extract_log_index(&log)?,
owner,
tick_lower,
tick_upper,
decoded.amount,
decoded.amount0,
decoded.amount1,
))
} else {
Err(anyhow::anyhow!("Missing data in burn event log"))
}
}