Skip to main content

balancer_maths_rust/common/
errors.rs

1//! Custom error types for the Balancer maths library
2
3use alloy_primitives::U256;
4use std::fmt;
5
6/// Errors that can occur during pool operations
7#[derive(Debug, Clone, PartialEq)]
8pub enum PoolError {
9    /// Invalid amount provided (zero or negative)
10    InvalidAmount,
11
12    /// Insufficient liquidity for the operation
13    InsufficientLiquidity,
14
15    /// Mathematical overflow occurred
16    MathOverflow,
17
18    /// Invalid pool type specified
19    InvalidPoolType,
20
21    /// Invalid token index
22    InvalidTokenIndex,
23
24    /// Invalid swap parameters
25    InvalidSwapParameters,
26
27    /// Invalid liquidity parameters
28    InvalidLiquidityParameters,
29
30    /// Pool not found
31    PoolNotFound,
32
33    /// Hook error
34    HookError(String),
35
36    /// Custom error message
37    Custom(String),
38
39    /// Zero invariant error
40    ZeroInvariant,
41
42    /// Maximum input ratio exceeded
43    MaxInRatioExceeded,
44
45    /// Maximum output ratio exceeded
46    MaxOutRatioExceeded,
47
48    /// Invalid input parameters
49    InvalidInput(String),
50
51    // Python SystemError equivalents
52    /// Input token not found on pool
53    InputTokenNotFound,
54
55    /// Output token not found on pool
56    OutputTokenNotFound,
57
58    /// Trade amount too small
59    TradeAmountTooSmall,
60
61    /// Before swap hook failed
62    BeforeSwapHookFailed,
63
64    /// After swap hook failed
65    AfterSwapHookFailed,
66
67    /// Before add liquidity hook failed
68    BeforeAddLiquidityHookFailed,
69
70    /// After add liquidity hook failed
71    AfterAddLiquidityHookFailed,
72
73    /// Before remove liquidity hook failed
74    BeforeRemoveLiquidityHookFailed,
75
76    /// After remove liquidity hook failed
77    AfterRemoveLiquidityHookFailed,
78
79    /// Unsupported pool type
80    UnsupportedPoolType(String),
81
82    /// Unsupported hook type
83    UnsupportedHookType(String),
84
85    /// No state for hook
86    NoStateForHook(String),
87
88    /// Stable invariant didn't converge
89    StableInvariantDidntConverge,
90
91    /// Stable math received a zero token balance (invariant undefined unless all balances are zero)
92    StableZeroBalance,
93
94    TokenAmountOutIsGreaterThanBalance,
95
96    /// Quoting at a timestamp before the pool's last update (e.g. backfill / reorg)
97    TimestampBeforeLastUpdate,
98
99    /// reCLAMM computed a negative amount out (invariant inconsistency)
100    ReClammNegativeAmountOut,
101
102    /// ERC4626 buffer wrap amount below the minimum safe threshold
103    BufferWrapAmountTooSmall,
104
105    /// ERC4626 deposit exceeds the vault's maxDeposit limit
106    Erc4626ExceededMaxDeposit {
107        requested: U256,
108        max: U256,
109    },
110
111    /// ERC4626 mint exceeds the vault's maxMint limit
112    Erc4626ExceededMaxMint {
113        requested: U256,
114        max: U256,
115    },
116}
117
118impl fmt::Display for PoolError {
119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120        match self {
121            PoolError::InvalidAmount => write!(f, "Invalid amount provided"),
122            PoolError::InsufficientLiquidity => write!(f, "Insufficient liquidity"),
123            PoolError::MathOverflow => write!(f, "Mathematical overflow occurred"),
124            PoolError::InvalidPoolType => write!(f, "Invalid pool type"),
125            PoolError::InvalidTokenIndex => write!(f, "Invalid token index"),
126            PoolError::InvalidSwapParameters => write!(f, "Invalid swap parameters"),
127            PoolError::InvalidLiquidityParameters => write!(f, "Invalid liquidity parameters"),
128            PoolError::PoolNotFound => write!(f, "Pool not found"),
129            PoolError::HookError(msg) => write!(f, "Hook error: {}", msg),
130            PoolError::Custom(msg) => write!(f, "Custom error: {}", msg),
131            PoolError::ZeroInvariant => write!(f, "Zero invariant"),
132            PoolError::MaxInRatioExceeded => write!(f, "Maximum input ratio exceeded"),
133            PoolError::MaxOutRatioExceeded => write!(f, "Maximum output ratio exceeded"),
134            PoolError::InvalidInput(msg) => write!(f, "Invalid input: {}", msg),
135
136            // Python SystemError equivalents
137            PoolError::InputTokenNotFound => write!(f, "Input token not found on pool"),
138            PoolError::OutputTokenNotFound => write!(f, "Output token not found on pool"),
139            PoolError::TradeAmountTooSmall => write!(f, "TradeAmountTooSmall"),
140            PoolError::BeforeSwapHookFailed => write!(f, "BeforeSwapHookFailed"),
141            PoolError::AfterSwapHookFailed => write!(f, "AfterSwapHookFailed"),
142            PoolError::BeforeAddLiquidityHookFailed => write!(f, "BeforeAddLiquidityHookFailed"),
143            PoolError::AfterAddLiquidityHookFailed => write!(f, "AfterAddLiquidityHookFailed"),
144            PoolError::BeforeRemoveLiquidityHookFailed => {
145                write!(f, "BeforeRemoveLiquidityHookFailed")
146            }
147            PoolError::AfterRemoveLiquidityHookFailed => {
148                write!(f, "AfterRemoveLiquidityHookFailed")
149            }
150            PoolError::UnsupportedPoolType(pool_type) => {
151                write!(f, "Unsupported Pool Type: {}", pool_type)
152            }
153            PoolError::UnsupportedHookType(hook_type) => {
154                write!(f, "Unsupported Hook Type: {}", hook_type)
155            }
156            PoolError::NoStateForHook(hook_name) => write!(f, "No state for Hook: {}", hook_name),
157            PoolError::StableInvariantDidntConverge => {
158                write!(f, "Stable invariant didn't converge")
159            }
160            PoolError::StableZeroBalance => {
161                write!(f, "Stable math undefined for zero token balance")
162            }
163            PoolError::TokenAmountOutIsGreaterThanBalance => {
164                write!(f, "Token amount out is greater than balance")
165            }
166            PoolError::TimestampBeforeLastUpdate => {
167                write!(f, "Timestamp is before the pool's last update")
168            }
169            PoolError::ReClammNegativeAmountOut => {
170                write!(f, "reClammMath: NegativeAmountOut")
171            }
172            PoolError::BufferWrapAmountTooSmall => write!(f, "wrapAmountTooSmall"),
173            PoolError::Erc4626ExceededMaxDeposit { requested, max } => {
174                write!(f, "ERC4626ExceededMaxDeposit {} {}", requested, max)
175            }
176            PoolError::Erc4626ExceededMaxMint { requested, max } => {
177                write!(f, "ERC4626ExceededMaxMint {} {}", requested, max)
178            }
179        }
180    }
181}
182
183impl std::error::Error for PoolError {}