2025-08-18 18:00:14 +08:00
|
|
|
/// Calculate transaction fee based on amount and fee basis points
|
|
|
|
|
///
|
|
|
|
|
/// # Parameters
|
|
|
|
|
/// * `amount` - Transaction amount
|
|
|
|
|
/// * `fee_basis_points` - Fee basis points, 1 basis point = 0.01%
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
/// * fee_basis_points = 1 -> 0.01% fee
|
|
|
|
|
/// * fee_basis_points = 10 -> 0.1% fee
|
|
|
|
|
/// * fee_basis_points = 25 -> 0.25% fee (common exchange rate)
|
|
|
|
|
/// * fee_basis_points = 100 -> 1% fee
|
2025-10-07 00:08:41 +08:00
|
|
|
#[inline(always)]
|
|
|
|
|
pub const fn compute_fee(amount: u128, fee_basis_points: u128) -> u128 {
|
2025-08-18 18:00:14 +08:00
|
|
|
ceil_div(amount * fee_basis_points, 10_000)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Ceiling division implementation
|
|
|
|
|
/// Ceiling division that ensures results are not lost due to integer division precision
|
|
|
|
|
///
|
|
|
|
|
/// # Parameters
|
|
|
|
|
/// * `a` - Dividend
|
|
|
|
|
/// * `b` - Divisor
|
|
|
|
|
///
|
|
|
|
|
/// # Returns
|
|
|
|
|
/// Returns the ceiling result of a/b
|
2025-10-07 00:08:41 +08:00
|
|
|
#[inline(always)]
|
|
|
|
|
pub const fn ceil_div(a: u128, b: u128) -> u128 {
|
2025-08-18 18:00:14 +08:00
|
|
|
(a + b - 1) / b
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 16:53:36 +08:00
|
|
|
/// Maximum slippage in basis points (99.99% = 9999 bps)
|
|
|
|
|
/// This prevents the wrap amount from doubling when slippage is 100%
|
|
|
|
|
pub const MAX_SLIPPAGE_BASIS_POINTS: u64 = 9999;
|
|
|
|
|
|
2025-08-18 18:00:14 +08:00
|
|
|
/// Calculate buy amount with slippage protection
|
|
|
|
|
/// Add slippage percentage to the amount to ensure successful purchase
|
|
|
|
|
///
|
|
|
|
|
/// # Parameters
|
|
|
|
|
/// * `amount` - Original transaction amount
|
|
|
|
|
/// * `basis_points` - Slippage basis points, 1 basis point = 0.01%
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
/// * basis_points = 1 -> 0.01% slippage
|
2025-10-07 00:08:41 +08:00
|
|
|
/// * basis_points = 10 -> 0.1% slippage
|
2025-08-18 18:00:14 +08:00
|
|
|
/// * basis_points = 100 -> 1% slippage
|
|
|
|
|
/// * basis_points = 500 -> 5% slippage
|
2026-04-06 16:53:36 +08:00
|
|
|
///
|
|
|
|
|
/// # Note
|
|
|
|
|
/// Basis points are clamped to MAX_SLIPPAGE_BASIS_POINTS (9999 = 99.99%)
|
|
|
|
|
/// to prevent the amount from doubling when basis_points = 10000.
|
2025-10-07 00:08:41 +08:00
|
|
|
#[inline(always)]
|
|
|
|
|
pub const fn calculate_with_slippage_buy(amount: u64, basis_points: u64) -> u64 {
|
2026-04-06 16:53:36 +08:00
|
|
|
let bps = if basis_points > MAX_SLIPPAGE_BASIS_POINTS {
|
|
|
|
|
MAX_SLIPPAGE_BASIS_POINTS
|
|
|
|
|
} else {
|
|
|
|
|
basis_points
|
|
|
|
|
};
|
|
|
|
|
amount + (amount * bps / 10000)
|
2025-08-18 18:00:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Calculate sell amount with slippage protection
|
|
|
|
|
/// Subtract slippage percentage from the amount to ensure successful sale
|
|
|
|
|
///
|
|
|
|
|
/// # Parameters
|
|
|
|
|
/// * `amount` - Original transaction amount
|
|
|
|
|
/// * `basis_points` - Slippage basis points, 1 basis point = 0.01%
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
/// * basis_points = 1 -> 0.01% slippage
|
2025-10-07 00:08:41 +08:00
|
|
|
/// * basis_points = 10 -> 0.1% slippage
|
2025-08-18 18:00:14 +08:00
|
|
|
/// * basis_points = 100 -> 1% slippage
|
|
|
|
|
/// * basis_points = 500 -> 5% slippage
|
2025-10-07 00:08:41 +08:00
|
|
|
#[inline(always)]
|
|
|
|
|
pub const fn calculate_with_slippage_sell(amount: u64, basis_points: u64) -> u64 {
|
2026-05-03 17:30:09 +08:00
|
|
|
if amount == 0 {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2025-08-18 18:00:14 +08:00
|
|
|
if amount <= basis_points / 10000 {
|
|
|
|
|
1
|
|
|
|
|
} else {
|
|
|
|
|
amount - (amount * basis_points / 10000)
|
|
|
|
|
}
|
|
|
|
|
}
|