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