Skip to main content

balancer_maths_rust/hooks/
mod.rs

1//! Hook implementations for Balancer pools
2
3pub mod akron;
4pub mod directional_fee;
5pub mod exit_fee;
6pub mod stable_surge;
7pub mod types;
8
9pub use akron::{AkronHook, AkronHookState};
10pub use directional_fee::{DirectionalFeeHook, DirectionalFeeHookState};
11pub use exit_fee::{ExitFeeHook, ExitFeeHookState};
12pub use stable_surge::{StableSurgeHook, StableSurgeHookState};
13
14use crate::common::types::{AddLiquidityKind, RemoveLiquidityKind, SwapParams};
15use crate::hooks::types::{
16    AfterAddLiquidityResult, AfterRemoveLiquidityResult, AfterSwapParams, AfterSwapResult,
17    BeforeAddLiquidityResult, BeforeRemoveLiquidityResult, BeforeSwapResult, DynamicSwapFeeResult,
18    HookState,
19};
20use alloy_primitives::U256;
21
22/// Hook configuration flags
23#[derive(Debug, Clone, PartialEq, Default)]
24pub struct HookConfig {
25    /// Whether to call compute dynamic swap fee
26    pub should_call_compute_dynamic_swap_fee: bool,
27    /// Whether to call before swap
28    pub should_call_before_swap: bool,
29    /// Whether to call after swap
30    pub should_call_after_swap: bool,
31    /// Whether to call before add liquidity
32    pub should_call_before_add_liquidity: bool,
33    /// Whether to call after add liquidity
34    pub should_call_after_add_liquidity: bool,
35    /// Whether to call before remove liquidity
36    pub should_call_before_remove_liquidity: bool,
37    /// Whether to call after remove liquidity
38    pub should_call_after_remove_liquidity: bool,
39    /// Whether to enable hook adjusted amounts
40    pub enable_hook_adjusted_amounts: bool,
41}
42
43/// Trait for pool hooks (matches Python HookBase interface exactly)
44pub trait HookBase {
45    /// Get the hook type
46    fn hook_type(&self) -> &str;
47
48    /// Get the hook configuration
49    fn config(&self) -> &HookConfig;
50
51    /// Process before add liquidity (matches Python on_before_add_liquidity)
52    fn on_before_add_liquidity(
53        &self,
54        kind: AddLiquidityKind,
55        max_amounts_in_scaled_18: &[U256],
56        min_bpt_amount_out: &U256,
57        balances_scaled_18: &[U256],
58        hook_state: &HookState,
59    ) -> BeforeAddLiquidityResult;
60
61    /// Process after add liquidity (matches Python on_after_add_liquidity)
62    fn on_after_add_liquidity(
63        &self,
64        kind: AddLiquidityKind,
65        amounts_in_scaled_18: &[U256],
66        amounts_in_raw: &[U256],
67        bpt_amount_out: &U256,
68        balances_scaled_18: &[U256],
69        hook_state: &HookState,
70    ) -> AfterAddLiquidityResult;
71
72    /// Process before remove liquidity (matches Python on_before_remove_liquidity)
73    fn on_before_remove_liquidity(
74        &self,
75        kind: RemoveLiquidityKind,
76        max_bpt_amount_in: &U256,
77        min_amounts_out_scaled_18: &[U256],
78        balances_scaled_18: &[U256],
79        hook_state: &HookState,
80    ) -> BeforeRemoveLiquidityResult;
81
82    /// Process after remove liquidity (matches Python on_after_remove_liquidity)
83    fn on_after_remove_liquidity(
84        &self,
85        kind: RemoveLiquidityKind,
86        bpt_amount_in: &U256,
87        amounts_out_scaled_18: &[U256],
88        amounts_out_raw: &[U256],
89        balances_scaled_18: &[U256],
90        hook_state: &HookState,
91    ) -> AfterRemoveLiquidityResult;
92
93    /// Process before swap (matches Python on_before_swap)
94    fn on_before_swap(&self, swap_params: &SwapParams, hook_state: &HookState) -> BeforeSwapResult;
95
96    /// Process after swap (matches Python on_after_swap)
97    fn on_after_swap(
98        &self,
99        after_swap_params: &AfterSwapParams,
100        hook_state: &HookState,
101    ) -> AfterSwapResult;
102
103    /// Compute dynamic swap fee (matches Python on_compute_dynamic_swap_fee)
104    fn on_compute_dynamic_swap_fee(
105        &self,
106        swap_params: &SwapParams,
107        static_swap_fee_percentage: &U256,
108        hook_state: &HookState,
109    ) -> DynamicSwapFeeResult;
110}
111
112/// Default hook implementation (matches Python DefaultHook)
113pub struct DefaultHook {
114    config: HookConfig,
115}
116
117impl DefaultHook {
118    pub fn new() -> Self {
119        Self {
120            config: HookConfig::default(),
121        }
122    }
123}
124
125impl HookBase for DefaultHook {
126    fn hook_type(&self) -> &str {
127        "Default"
128    }
129
130    fn config(&self) -> &HookConfig {
131        &self.config
132    }
133
134    fn on_before_add_liquidity(
135        &self,
136        _kind: AddLiquidityKind,
137        _max_amounts_in_scaled_18: &[U256],
138        _min_bpt_amount_out: &U256,
139        balances_scaled_18: &[U256],
140        _hook_state: &HookState,
141    ) -> BeforeAddLiquidityResult {
142        BeforeAddLiquidityResult {
143            success: true,
144            hook_adjusted_balances_scaled_18: balances_scaled_18.to_vec(),
145        }
146    }
147
148    fn on_after_add_liquidity(
149        &self,
150        _kind: AddLiquidityKind,
151        _amounts_in_scaled_18: &[U256],
152        amounts_in_raw: &[U256],
153        _bpt_amount_out: &U256,
154        _balances_scaled_18: &[U256],
155        _hook_state: &HookState,
156    ) -> AfterAddLiquidityResult {
157        AfterAddLiquidityResult {
158            success: true,
159            hook_adjusted_amounts_in_raw: amounts_in_raw.to_vec(),
160        }
161    }
162
163    fn on_before_remove_liquidity(
164        &self,
165        _kind: RemoveLiquidityKind,
166        _max_bpt_amount_in: &U256,
167        _min_amounts_out_scaled_18: &[U256],
168        balances_scaled_18: &[U256],
169        _hook_state: &HookState,
170    ) -> BeforeRemoveLiquidityResult {
171        BeforeRemoveLiquidityResult {
172            success: true,
173            hook_adjusted_balances_scaled_18: balances_scaled_18.to_vec(),
174        }
175    }
176
177    fn on_after_remove_liquidity(
178        &self,
179        _kind: RemoveLiquidityKind,
180        _bpt_amount_in: &U256,
181        _amounts_out_scaled_18: &[U256],
182        amounts_out_raw: &[U256],
183        _balances_scaled_18: &[U256],
184        _hook_state: &HookState,
185    ) -> AfterRemoveLiquidityResult {
186        AfterRemoveLiquidityResult {
187            success: true,
188            hook_adjusted_amounts_out_raw: amounts_out_raw.to_vec(),
189        }
190    }
191
192    fn on_before_swap(
193        &self,
194        _swap_params: &SwapParams,
195        _hook_state: &HookState,
196    ) -> BeforeSwapResult {
197        BeforeSwapResult {
198            success: true,
199            hook_adjusted_balances_scaled_18: vec![],
200        }
201    }
202
203    fn on_after_swap(
204        &self,
205        _after_swap_params: &AfterSwapParams,
206        _hook_state: &HookState,
207    ) -> AfterSwapResult {
208        AfterSwapResult {
209            success: true,
210            hook_adjusted_amount_calculated_raw: U256::ZERO,
211        }
212    }
213
214    fn on_compute_dynamic_swap_fee(
215        &self,
216        _swap_params: &SwapParams,
217        static_swap_fee_percentage: &U256,
218        _hook_state: &HookState,
219    ) -> DynamicSwapFeeResult {
220        DynamicSwapFeeResult {
221            success: true,
222            dynamic_swap_fee: *static_swap_fee_percentage,
223        }
224    }
225}
226
227impl Default for DefaultHook {
228    fn default() -> Self {
229        DefaultHook::new()
230    }
231}