Skip to content

Commit

Permalink
token-swap: Add comment for stable curve A calculation (solana-labs#2556
Browse files Browse the repository at this point in the history
)
  • Loading branch information
joncinque authored Nov 3, 2021
1 parent 8aef395 commit fcbc0d3
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions token-swap/program/src/curve/stable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ const N_COINS: u8 = 2;
const N_COINS_SQUARED: u8 = 4;
const ITERATIONS: u8 = 32;

/// Calculates A for deriving D
///
/// Per discussion with the designer and writer of stable curves, this A is not
/// the same as the A from the whitepaper, it's actually `A * n**(n-1)`, so when
/// you set A, you actually set `A * n**(n-1)`. This is because `D**n / prod(x)`
/// loses precision with a huge A value.
///
/// There is little information to document this choice, but the original contracts
/// use this same convention, see a comment in the code at:
/// https://github.com/curvefi/curve-contract/blob/b0bbf77f8f93c9c5f4e415bce9cd71f0cdee960e/contracts/pool-templates/base/SwapTemplateBase.vy#L136
fn compute_a(amp: u64) -> Option<u64> {
amp.checked_mul(N_COINS as u64)
}

/// Returns self to the power of b
fn checked_u8_power(a: &U256, b: u8) -> Option<U256> {
let mut result = *a;
Expand Down Expand Up @@ -141,7 +155,7 @@ impl CurveCalculator for StableCurve {
swap_destination_amount: u128,
_trade_direction: TradeDirection,
) -> Option<SwapWithoutFeesResult> {
let leverage = self.amp.checked_mul(N_COINS as u64)?;
let leverage = compute_a(self.amp)?;

let new_source_amount = swap_source_amount.checked_add(source_amount)?;
let new_destination_amount = compute_new_destination_amount(
Expand Down Expand Up @@ -215,7 +229,7 @@ impl CurveCalculator for StableCurve {
if source_amount == 0 {
return Some(0);
}
let leverage = self.amp.checked_mul(N_COINS as u64)?;
let leverage = compute_a(self.amp)?;
let d0 = PreciseNumber::new(compute_d(
leverage,
swap_token_a_amount,
Expand Down Expand Up @@ -248,7 +262,7 @@ impl CurveCalculator for StableCurve {
if source_amount == 0 {
return Some(0);
}
let leverage = self.amp.checked_mul(N_COINS as u64)?;
let leverage = compute_a(self.amp)?;
let d0 = PreciseNumber::new(compute_d(
leverage,
swap_token_a_amount,
Expand Down Expand Up @@ -277,7 +291,7 @@ impl CurveCalculator for StableCurve {
) -> Option<PreciseNumber> {
#[cfg(not(any(test, feature = "fuzz")))]
{
let leverage = self.amp.checked_mul(N_COINS as u64)?;
let leverage = compute_a(self.amp)?;
PreciseNumber::new(compute_d(
leverage,
swap_token_a_amount,
Expand Down

0 comments on commit fcbc0d3

Please sign in to comment.