Skip to main content

balancer_maths_rust/pools/buffer/
erc4626_buffer_wrap_or_unwrap.rs

1//! ERC4626 Buffer wrap or unwrap function
2
3use crate::common::errors::PoolError;
4use crate::common::types::SwapInput;
5use crate::pools::buffer::buffer_data::BufferState;
6use crate::pools::buffer::buffer_math::calculate_buffer_amounts;
7use crate::pools::buffer::enums::WrappingDirection;
8use alloy_primitives::{uint, U256};
9
10pub const _MINIMUM_WRAP_AMOUNT: U256 = uint!(1000_U256);
11
12/// ERC4626 Buffer wrap or unwrap function
13///
14/// # Arguments
15/// * `swap_input` - Swap input parameters
16/// * `pool_state` - Buffer pool state
17///
18/// # Returns
19/// Calculated amount for wrap/unwrap operation
20pub fn erc4626_buffer_wrap_or_unwrap(
21    swap_input: &SwapInput,
22    pool_state: &BufferState,
23) -> Result<U256, PoolError> {
24    if swap_input.amount_raw < _MINIMUM_WRAP_AMOUNT {
25        // If amount given is too small, rounding issues can be introduced that favors the user and can drain
26        // the buffer. _MINIMUM_WRAP_AMOUNT prevents it. Most tokens have protections against it already, this
27        // is just an extra layer of security.
28        return Err(PoolError::BufferWrapAmountTooSmall);
29    }
30
31    // Determine wrapping direction based on token addresses
32    let wrapping_direction =
33        if is_same_address(&swap_input.token_in, &pool_state.immutable.pool_address) {
34            WrappingDirection::Unwrap
35        } else {
36            WrappingDirection::Wrap
37        };
38
39    calculate_buffer_amounts(
40        wrapping_direction,
41        swap_input.swap_kind.clone(),
42        &swap_input.amount_raw,
43        &pool_state.mutable.rate,
44        pool_state.mutable.max_deposit.as_ref(),
45        pool_state.mutable.max_mint.as_ref(),
46    )
47}
48
49/// Check if two addresses are the same (case-insensitive)
50fn is_same_address(addr1: &str, addr2: &str) -> bool {
51    addr1.to_lowercase() == addr2.to_lowercase()
52}