use std::{collections::HashMap, fmt::Debug};
use alloy::primitives::{Address, U256};
use tycho_common::{
dto::ProtocolStateDelta,
models::token::Token,
simulation::{
errors::{SimulationError, TransitionError},
protocol_sim::Balances,
},
Bytes,
};
use crate::evm::protocol::uniswap_v4::{
hooks::models::{
AfterSwapDelta, AfterSwapParameters, AmountRanges, BeforeSwapOutput, BeforeSwapParameters,
SwapParams, WithGasEstimate,
},
state::UniswapV4State,
};
pub trait HookHandler: Debug + Send + Sync + 'static {
fn address(&self) -> Address;
fn before_swap(
&self,
params: BeforeSwapParameters,
overwrites: Option<HashMap<Address, HashMap<U256, U256>>>,
transient_storage: Option<HashMap<Address, HashMap<U256, U256>>>,
) -> Result<WithGasEstimate<BeforeSwapOutput>, SimulationError>;
fn after_swap(
&self,
params: AfterSwapParameters,
overwrites: Option<HashMap<Address, HashMap<U256, U256>>>,
transient_storage_params: Option<HashMap<Address, HashMap<U256, U256>>>,
) -> Result<WithGasEstimate<AfterSwapDelta>, SimulationError>;
fn fee(&self, context: &UniswapV4State, params: SwapParams) -> Result<f64, SimulationError>;
fn spot_price(&self, base: &Token, quote: &Token) -> Result<f64, SimulationError>;
fn get_amount_ranges(
&self,
token_in: Bytes,
token_out: Bytes,
) -> Result<AmountRanges, SimulationError>;
fn delta_transition(
&mut self,
delta: ProtocolStateDelta,
tokens: &HashMap<Bytes, Token>,
balances: &Balances,
) -> Result<(), TransitionError>;
fn clone_box(&self) -> Box<dyn HookHandler>;
fn as_any(&self) -> &dyn std::any::Any;
fn is_equal(&self, other: &dyn HookHandler) -> bool;
}
impl Clone for Box<dyn HookHandler> {
fn clone(&self) -> Self {
self.clone_box()
}
}