@@ -20,6 +20,20 @@ const N_COINS: u8 = 2;
20
20
const N_COINS_SQUARED : u8 = 4 ;
21
21
const ITERATIONS : u8 = 32 ;
22
22
23
+ /// Calculates A for deriving D
24
+ ///
25
+ /// Per discussion with the designer and writer of stable curves, this A is not
26
+ /// the same as the A from the whitepaper, it's actually `A * n**(n-1)`, so when
27
+ /// you set A, you actually set `A * n**(n-1)`. This is because `D**n / prod(x)`
28
+ /// loses precision with a huge A value.
29
+ ///
30
+ /// There is little information to document this choice, but the original contracts
31
+ /// use this same convention, see a comment in the code at:
32
+ /// https://github.com/curvefi/curve-contract/blob/b0bbf77f8f93c9c5f4e415bce9cd71f0cdee960e/contracts/pool-templates/base/SwapTemplateBase.vy#L136
33
+ fn compute_a ( amp : u64 ) -> Option < u64 > {
34
+ amp. checked_mul ( N_COINS as u64 )
35
+ }
36
+
23
37
/// Returns self to the power of b
24
38
fn checked_u8_power ( a : & U256 , b : u8 ) -> Option < U256 > {
25
39
let mut result = * a;
@@ -141,7 +155,7 @@ impl CurveCalculator for StableCurve {
141
155
swap_destination_amount : u128 ,
142
156
_trade_direction : TradeDirection ,
143
157
) -> Option < SwapWithoutFeesResult > {
144
- let leverage = self . amp . checked_mul ( N_COINS as u64 ) ?;
158
+ let leverage = compute_a ( self . amp ) ?;
145
159
146
160
let new_source_amount = swap_source_amount. checked_add ( source_amount) ?;
147
161
let new_destination_amount = compute_new_destination_amount (
@@ -215,7 +229,7 @@ impl CurveCalculator for StableCurve {
215
229
if source_amount == 0 {
216
230
return Some ( 0 ) ;
217
231
}
218
- let leverage = self . amp . checked_mul ( N_COINS as u64 ) ?;
232
+ let leverage = compute_a ( self . amp ) ?;
219
233
let d0 = PreciseNumber :: new ( compute_d (
220
234
leverage,
221
235
swap_token_a_amount,
@@ -248,7 +262,7 @@ impl CurveCalculator for StableCurve {
248
262
if source_amount == 0 {
249
263
return Some ( 0 ) ;
250
264
}
251
- let leverage = self . amp . checked_mul ( N_COINS as u64 ) ?;
265
+ let leverage = compute_a ( self . amp ) ?;
252
266
let d0 = PreciseNumber :: new ( compute_d (
253
267
leverage,
254
268
swap_token_a_amount,
@@ -277,7 +291,7 @@ impl CurveCalculator for StableCurve {
277
291
) -> Option < PreciseNumber > {
278
292
#[ cfg( not( any( test, feature = "fuzz" ) ) ) ]
279
293
{
280
- let leverage = self . amp . checked_mul ( N_COINS as u64 ) ?;
294
+ let leverage = compute_a ( self . amp ) ?;
281
295
PreciseNumber :: new ( compute_d (
282
296
leverage,
283
297
swap_token_a_amount,
0 commit comments