@paraswap/dex-lib 2.50.6-sdai → 2.50.7-sdai

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/build/config.js +4 -2
  2. package/build/config.js.map +1 -1
  3. package/build/dex/algebra/config.js +0 -16
  4. package/build/dex/algebra/config.js.map +1 -1
  5. package/build/dex/curve-v1-factory/config.js +128 -11
  6. package/build/dex/curve-v1-factory/config.js.map +1 -1
  7. package/build/dex/curve-v1-factory/curve-v1-factory.d.ts +1 -0
  8. package/build/dex/curve-v1-factory/curve-v1-factory.js +29 -17
  9. package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
  10. package/build/dex/curve-v1-factory/curve-v1-pool-manager.js +1 -0
  11. package/build/dex/curve-v1-factory/curve-v1-pool-manager.js.map +1 -1
  12. package/build/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.js +1 -0
  13. package/build/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.js.map +1 -1
  14. package/build/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.js +4 -1
  15. package/build/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.js.map +1 -1
  16. package/build/dex/curve-v1-factory/price-handlers/functions/_rates.js +1 -0
  17. package/build/dex/curve-v1-factory/price-handlers/functions/_rates.js.map +1 -1
  18. package/build/dex/curve-v1-factory/price-handlers/functions/_xp.js +1 -0
  19. package/build/dex/curve-v1-factory/price-handlers/functions/_xp.js.map +1 -1
  20. package/build/dex/curve-v1-factory/price-handlers/functions/_xp_mem.js +1 -0
  21. package/build/dex/curve-v1-factory/price-handlers/functions/_xp_mem.js.map +1 -1
  22. package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js +1 -0
  23. package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js.map +1 -1
  24. package/build/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.js +1 -0
  25. package/build/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.js.map +1 -1
  26. package/build/dex/curve-v1-factory/price-handlers/functions/constants.js +10 -0
  27. package/build/dex/curve-v1-factory/price-handlers/functions/constants.js.map +1 -1
  28. package/build/dex/curve-v1-factory/price-handlers/functions/get_D.js +40 -0
  29. package/build/dex/curve-v1-factory/price-handlers/functions/get_D.js.map +1 -1
  30. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_mem.js +1 -0
  31. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_mem.js.map +1 -1
  32. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.js +1 -0
  33. package/build/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.js.map +1 -1
  34. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy.js +24 -0
  35. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy.js.map +1 -1
  36. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.js +1 -0
  37. package/build/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.js.map +1 -1
  38. package/build/dex/curve-v1-factory/price-handlers/functions/get_y.js +53 -0
  39. package/build/dex/curve-v1-factory/price-handlers/functions/get_y.js.map +1 -1
  40. package/build/dex/curve-v1-factory/price-handlers/functions/get_y_D.js +1 -0
  41. package/build/dex/curve-v1-factory/price-handlers/functions/get_y_D.js.map +1 -1
  42. package/build/dex/curve-v1-factory/price-handlers/functions/utils.d.ts +1 -0
  43. package/build/dex/curve-v1-factory/price-handlers/functions/utils.js +5 -1
  44. package/build/dex/curve-v1-factory/price-handlers/functions/utils.js.map +1 -1
  45. package/build/dex/curve-v1-factory/price-handlers/types.d.ts +2 -2
  46. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.d.ts +3 -2
  47. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js +38 -6
  48. package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js.map +1 -1
  49. package/build/dex/curve-v1-factory/state-polling-pools/pool-polling-base.js.map +1 -1
  50. package/build/dex/curve-v1-factory/types.d.ts +11 -2
  51. package/build/dex/curve-v1-factory/types.js +3 -0
  52. package/build/dex/curve-v1-factory/types.js.map +1 -1
  53. package/build/dex/dexalot/config.js +7 -0
  54. package/build/dex/dexalot/config.js.map +1 -1
  55. package/build/dex/hashflow/constants.d.ts +27 -0
  56. package/build/dex/hashflow/constants.js +29 -1
  57. package/build/dex/hashflow/constants.js.map +1 -1
  58. package/build/dex/hashflow/hashflow.d.ts +3 -2
  59. package/build/dex/hashflow/hashflow.js +69 -12
  60. package/build/dex/hashflow/hashflow.js.map +1 -1
  61. package/build/dex/hashflow/types.d.ts +11 -0
  62. package/build/dex/hashflow/types.js +9 -0
  63. package/build/dex/hashflow/types.js.map +1 -1
  64. package/build/dex/idex.d.ts +1 -1
  65. package/build/dex/index.d.ts +2 -2
  66. package/build/dex/pancakeswap-v3/config.js +30 -0
  67. package/build/dex/pancakeswap-v3/config.js.map +1 -1
  68. package/build/dex/pancakeswap-v3/pancakeswap-v3.js +5 -1
  69. package/build/dex/pancakeswap-v3/pancakeswap-v3.js.map +1 -1
  70. package/build/dex/woo-fi-v2/config.js +4 -4
  71. package/package.json +1 -1
  72. package/src/config.ts +4 -2
  73. package/src/dex/algebra/config.ts +0 -18
  74. package/src/dex/curve-v1-factory/config.ts +128 -11
  75. package/src/dex/curve-v1-factory/curve-v1-factory-e2e.test.ts +123 -1
  76. package/src/dex/curve-v1-factory/curve-v1-factory-integration.test.ts +392 -0
  77. package/src/dex/curve-v1-factory/curve-v1-factory.ts +61 -39
  78. package/src/dex/curve-v1-factory/curve-v1-pool-manager.ts +1 -0
  79. package/src/dex/curve-v1-factory/price-handlers/functions/_calc_withdraw_one_coin.ts +2 -0
  80. package/src/dex/curve-v1-factory/price-handlers/functions/_dynamic_fee.ts +6 -2
  81. package/src/dex/curve-v1-factory/price-handlers/functions/_rates.ts +2 -0
  82. package/src/dex/curve-v1-factory/price-handlers/functions/_xp.ts +2 -0
  83. package/src/dex/curve-v1-factory/price-handlers/functions/_xp_mem.ts +2 -0
  84. package/src/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.ts +2 -0
  85. package/src/dex/curve-v1-factory/price-handlers/functions/calc_withdraw_one_coin.ts +2 -0
  86. package/src/dex/curve-v1-factory/price-handlers/functions/constants.ts +11 -0
  87. package/src/dex/curve-v1-factory/price-handlers/functions/get_D.ts +59 -1
  88. package/src/dex/curve-v1-factory/price-handlers/functions/get_D_mem.ts +2 -0
  89. package/src/dex/curve-v1-factory/price-handlers/functions/get_D_precisions.ts +2 -0
  90. package/src/dex/curve-v1-factory/price-handlers/functions/get_dy.ts +51 -0
  91. package/src/dex/curve-v1-factory/price-handlers/functions/get_dy_underlying.ts +2 -0
  92. package/src/dex/curve-v1-factory/price-handlers/functions/get_y.ts +68 -1
  93. package/src/dex/curve-v1-factory/price-handlers/functions/get_y_D.ts +2 -0
  94. package/src/dex/curve-v1-factory/price-handlers/functions/utils.ts +4 -0
  95. package/src/dex/curve-v1-factory/price-handlers/types.ts +8 -1
  96. package/src/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.ts +71 -18
  97. package/src/dex/curve-v1-factory/state-polling-pools/pool-polling-base.ts +1 -0
  98. package/src/dex/curve-v1-factory/types.ts +12 -1
  99. package/src/dex/dexalot/config.ts +7 -0
  100. package/src/dex/dexalot/dexalot-e2e.test.ts +23 -1
  101. package/src/dex/dexalot/dexalot-integration.test.ts +121 -0
  102. package/src/dex/hashflow/constants.ts +32 -0
  103. package/src/dex/hashflow/hashflow.ts +121 -19
  104. package/src/dex/hashflow/types.ts +20 -2
  105. package/src/dex/idex.ts +1 -1
  106. package/src/dex/index.ts +2 -2
  107. package/src/dex/pancakeswap-v3/config.ts +32 -0
  108. package/src/dex/pancakeswap-v3/pancakeswap-v3-e2e.test.ts +21 -0
  109. package/src/dex/pancakeswap-v3/pancakeswap-v3.ts +7 -1
  110. package/src/dex/woo-fi-v2/config.ts +4 -4
  111. package/tests/constants-e2e.ts +38 -3
  112. package/tests/utils-e2e.ts +1 -0
  113. package/src/abi/uniswap-v3/AlienBaseV3Router.abi.json +0 -52
@@ -2,7 +2,12 @@ import _ from 'lodash';
2
2
  import { CONVERGENCE_ERROR_PREFIX } from '../../constants';
3
3
  import { ImplementationNames } from '../../types';
4
4
  import { get_D, IPoolContext } from '../types';
5
- import { getCachedValueOrCallFunc, requireConstant } from './utils';
5
+ import {
6
+ getCachedValueOrCallFunc,
7
+ pow_mod256,
8
+ requireConstant,
9
+ requireValue,
10
+ } from './utils';
6
11
 
7
12
  /*
8
13
  * This function get_D may be optimized further. We are doing many redundant
@@ -52,6 +57,57 @@ const customPlain3CoinThree: get_D = (
52
57
  return D;
53
58
  };
54
59
 
60
+ const stableNg: get_D = (
61
+ self: IPoolContext,
62
+ xp: bigint[],
63
+ amp: bigint,
64
+ N_COINS?: number,
65
+ ): bigint => {
66
+ const A_PRECISION = requireConstant(self, 'A_PRECISION', 'stableNg');
67
+ const BI_N_COINS = BigInt(N_COINS!);
68
+
69
+ let S = 0n;
70
+ let Dprev = 0n;
71
+
72
+ for (const _x of xp) {
73
+ S += _x;
74
+ }
75
+ if (S === 0n) {
76
+ return 0n;
77
+ }
78
+
79
+ let D = S;
80
+ const Ann = amp * BI_N_COINS;
81
+ for (const _i of _.range(255)) {
82
+ let D_P = D;
83
+ for (const _x of xp) {
84
+ D_P = (D_P * D) / _x;
85
+ }
86
+
87
+ D_P /= pow_mod256(BI_N_COINS, BI_N_COINS);
88
+ Dprev = D;
89
+ D =
90
+ (((Ann * S) / A_PRECISION + D_P * BI_N_COINS) * D) /
91
+ (((Ann - A_PRECISION) * D) / A_PRECISION + (BI_N_COINS + 1n) * D_P);
92
+ // Equality with the precision of 1
93
+ if (D > Dprev) {
94
+ if (D - Dprev <= 1n) {
95
+ return D;
96
+ }
97
+ } else {
98
+ if (Dprev - D <= 1n) {
99
+ return D;
100
+ }
101
+ }
102
+ }
103
+
104
+ // convergence typically occurs in 4 rounds or less, this should be unreachable!
105
+ // if it does happen the pool is borked and LPs can withdraw via `remove_liquidity`
106
+ throw new Error(
107
+ `${CONVERGENCE_ERROR_PREFIX}_${self.IMPLEMENTATION_NAME}: function stableNg didn't converge`,
108
+ );
109
+ };
110
+
55
111
  const customPlain2CoinFrax: get_D = (
56
112
  self: IPoolContext,
57
113
  xp: bigint[],
@@ -323,6 +379,8 @@ const implementations: Record<ImplementationNames, get_D> = {
323
379
  makeFuncCacheable(factoryPlain2Basic),
324
380
  [ImplementationNames.FACTORY_PLAIN_2_CRV_EMA]:
325
381
  makeFuncCacheable(factoryPlain2Basic),
382
+
383
+ [ImplementationNames.FACTORY_STABLE_NG]: stableNg,
326
384
  };
327
385
 
328
386
  export default implementations;
@@ -141,6 +141,8 @@ export const implementations: Record<ImplementationNames, get_D_mem> = {
141
141
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA]: factoryPlain2Basic,
142
142
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA2]: factoryPlain2EthEma2,
143
143
  [ImplementationNames.FACTORY_PLAIN_2_CRV_EMA]: factoryPlain2Basic,
144
+
145
+ [ImplementationNames.FACTORY_STABLE_NG]: notImplemented,
144
146
  };
145
147
 
146
148
  export default implementations;
@@ -113,6 +113,8 @@ const implementations: Record<ImplementationNames, get_D_precisions> = {
113
113
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA]: notExist,
114
114
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA2]: notExist,
115
115
  [ImplementationNames.FACTORY_PLAIN_2_CRV_EMA]: notExist,
116
+
117
+ [ImplementationNames.FACTORY_STABLE_NG]: notExist,
116
118
  };
117
119
 
118
120
  export default implementations;
@@ -2,6 +2,7 @@ import _ from 'lodash';
2
2
  import { ImplementationNames, PoolState } from '../../types';
3
3
  import { get_dy, IPoolContext } from '../types';
4
4
  import { requireConstant, requireValue } from './utils';
5
+ import get_y from './get_y';
5
6
 
6
7
  const _genericFactoryPlain2Basic = (
7
8
  self: IPoolContext,
@@ -162,6 +163,54 @@ const customPlain3CoinBtc: get_dy = (
162
163
  return dy - _fee;
163
164
  };
164
165
 
166
+ const stableNg: get_dy = (
167
+ self: IPoolContext,
168
+ state: PoolState,
169
+ i: number,
170
+ j: number,
171
+ dx: bigint,
172
+ ) => {
173
+ const rates = requireValue(self, state, 'storedRates', 'stableNg');
174
+ const N_COINS = requireValue(self, state, 'n_coins', 'stableNg');
175
+ const A = requireValue(self, state, 'A', 'stableNg');
176
+ const stateFee = requireValue(self, state, 'fee', 'stableNg');
177
+ const offpeg_fee_multiplier = requireValue(
178
+ self,
179
+ state,
180
+ 'offpeg_fee_multiplier',
181
+ 'stableNg',
182
+ );
183
+
184
+ const { FEE_DENOMINATOR, PRECISION } = self.constants;
185
+ const xp: bigint[] = [];
186
+ const { balances } = state;
187
+
188
+ for (const idx of _.range(N_COINS)) {
189
+ xp.push((rates[idx] * balances[idx]) / PRECISION);
190
+ }
191
+
192
+ const amp = A;
193
+ const D = self.get_D(self, xp, amp, N_COINS);
194
+
195
+ const x = xp[i] + (dx * rates[i]) / PRECISION;
196
+ const y = self.get_y(self, state, i, j, x, xp, amp, D);
197
+ const dy = xp[j] - y - 1n;
198
+
199
+ const base_fee = stateFee;
200
+ const fee_multiplier = offpeg_fee_multiplier;
201
+ const dynamic_fee = self._dynamic_fee(
202
+ self,
203
+ (xp[i] + x) / 2n,
204
+ (xp[j] + y) / 2n,
205
+ base_fee,
206
+ fee_multiplier,
207
+ );
208
+
209
+ const fee = (dynamic_fee * dy) / FEE_DENOMINATOR;
210
+
211
+ return ((dy - fee) * PRECISION) / rates[j];
212
+ };
213
+
165
214
  const customAvalanche3CoinLending: get_dy = (
166
215
  self: IPoolContext,
167
216
  state: PoolState,
@@ -267,6 +316,8 @@ const implementations: Record<ImplementationNames, get_dy> = {
267
316
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA]: factoryPlain2Basic,
268
317
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA2]: factoryPlain2EthEma2,
269
318
  [ImplementationNames.FACTORY_PLAIN_2_CRV_EMA]: factoryPlain2Basic,
319
+
320
+ [ImplementationNames.FACTORY_STABLE_NG]: stableNg,
270
321
  };
271
322
 
272
323
  export default implementations;
@@ -286,6 +286,8 @@ const implementations: Record<ImplementationNames, get_dy_underlying> = {
286
286
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA]: notExist,
287
287
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA2]: notExist,
288
288
  [ImplementationNames.FACTORY_PLAIN_2_CRV_EMA]: notExist,
289
+
290
+ [ImplementationNames.FACTORY_STABLE_NG]: notExist,
289
291
  };
290
292
 
291
293
  export default implementations;
@@ -2,9 +2,74 @@ import _ from 'lodash';
2
2
  import { ImplementationNames, PoolState } from '../../types';
3
3
  import { _require } from '../../../../utils';
4
4
  import { get_y, IPoolContext } from '../types';
5
- import { requireConstant } from './utils';
5
+ import { requireConstant, requireValue } from './utils';
6
6
  import { CONVERGENCE_ERROR_PREFIX } from '../../constants';
7
7
 
8
+ const stableNg = (
9
+ self: IPoolContext,
10
+ state: PoolState,
11
+ i: number,
12
+ j: number,
13
+ x: bigint,
14
+ xp: bigint[],
15
+ _amp?: bigint,
16
+ _D?: bigint,
17
+ ): bigint => {
18
+ const A_PRECISION = requireConstant(self, 'A_PRECISION', 'stableNg');
19
+ const N_COINS = requireValue(self, state, 'n_coins', 'stableNg');
20
+ // x in the input is converted to the same price/precision
21
+
22
+ _require(i !== j, 'same coin', { i, j }, 'i !== j');
23
+ _require(j >= 0, 'j below zero', { i, j }, 'j >= 0');
24
+ _require(j < N_COINS, 'j above N_COINS', { i, j, N_COINS }, 'j < N_COINS');
25
+
26
+ // should be unreachable, but good for safety
27
+ _require(i >= 0, 'i below zero', { i, j }, 'i >= 0');
28
+ _require(i < N_COINS, 'i above N_COINS', { i, j, N_COINS }, 'i < N_COINS');
29
+
30
+ const BI_N_COINS = BigInt(N_COINS);
31
+
32
+ const amp = _amp!;
33
+ const D = _D!;
34
+ let c = D;
35
+ let S_ = 0n;
36
+ const Ann = amp * BI_N_COINS;
37
+
38
+ let _x = 0n;
39
+ for (const _i of _.range(N_COINS)) {
40
+ if (_i === i) {
41
+ _x = x;
42
+ } else if (_i !== j) {
43
+ _x = xp[_i];
44
+ } else {
45
+ continue;
46
+ }
47
+ S_ += _x;
48
+ c = (c * D) / (_x * BI_N_COINS);
49
+ }
50
+ c = (c * D * A_PRECISION) / (Ann * BI_N_COINS);
51
+ const b = S_ + (D * A_PRECISION) / Ann; // - D
52
+ let y_prev = 0n;
53
+ let y = D;
54
+
55
+ for (const _i of _.range(255)) {
56
+ y_prev = y;
57
+ y = (y * y + c) / (2n * y + b - D);
58
+ //
59
+ // Equality with the precision of 1
60
+ if (y > y_prev) {
61
+ if (y - y_prev <= 1) {
62
+ break;
63
+ }
64
+ } else {
65
+ if (y_prev - y <= 1) {
66
+ break;
67
+ }
68
+ }
69
+ }
70
+ return y;
71
+ };
72
+
8
73
  const customPlain3CoinThree = (
9
74
  self: IPoolContext,
10
75
  state: PoolState,
@@ -190,6 +255,8 @@ const implementations: Record<ImplementationNames, get_y> = {
190
255
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA]: customPlain2CoinFrax,
191
256
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA2]: customPlain2CoinFrax,
192
257
  [ImplementationNames.FACTORY_PLAIN_2_CRV_EMA]: customPlain2CoinFrax,
258
+
259
+ [ImplementationNames.FACTORY_STABLE_NG]: stableNg,
193
260
  };
194
261
 
195
262
  export default implementations;
@@ -176,6 +176,8 @@ const implementations: Record<ImplementationNames, get_y_D> = {
176
176
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA]: customPlain2CoinFrax,
177
177
  [ImplementationNames.FACTORY_PLAIN_2_ETH_EMA2]: customPlain2CoinFrax,
178
178
  [ImplementationNames.FACTORY_PLAIN_2_CRV_EMA]: customPlain2CoinFrax,
179
+
180
+ [ImplementationNames.FACTORY_STABLE_NG]: customPlain2CoinFrax,
179
181
  };
180
182
 
181
183
  export default implementations;
@@ -70,3 +70,7 @@ export const getCachedValueOrCallFunc = <T>(
70
70
  curveV1FactoryNodeCache.set(key, calculated);
71
71
  return calculated;
72
72
  };
73
+
74
+ export function pow_mod256(a: bigint, b: bigint): bigint {
75
+ return a ** b % 2n ** 256n;
76
+ }
@@ -52,7 +52,12 @@ export type get_D_precisions = (
52
52
  amp: bigint,
53
53
  ) => bigint;
54
54
 
55
- export type get_D = (self: IPoolContext, xp: bigint[], amp: bigint) => bigint;
55
+ export type get_D = (
56
+ self: IPoolContext,
57
+ xp: bigint[],
58
+ amp: bigint,
59
+ N_COINS?: number,
60
+ ) => bigint;
56
61
 
57
62
  export type get_dy_underlying = (
58
63
  self: IPoolContext,
@@ -85,6 +90,8 @@ export type get_y = (
85
90
  j: number,
86
91
  x: bigint,
87
92
  xp_: bigint[],
93
+ _amp?: bigint,
94
+ _D?: bigint,
88
95
  ) => bigint;
89
96
 
90
97
  /*
@@ -2,6 +2,7 @@ import { Interface, JsonFragment } from '@ethersproject/abi';
2
2
  import { Logger } from 'log4js';
3
3
  import { MultiCallParams, MultiResult } from '../../../lib/multi-wrapper';
4
4
  import {
5
+ DexParams,
5
6
  FactoryImplementationNames,
6
7
  PoolConstants,
7
8
  PoolContextConstants,
@@ -9,19 +10,20 @@ import {
9
10
  } from '../types';
10
11
  import { PoolPollingBase, MulticallReturnedTypes } from './pool-polling-base';
11
12
  import FactoryCurveV1ABI from '../../../abi/curve-v1-factory/FactoryCurveV1.json';
12
- import { generalDecoder, uint256ToBigInt } from '../../../lib/decoders';
13
+ import {
14
+ generalDecoder,
15
+ uint256DecodeToNumber,
16
+ uint256ToBigInt,
17
+ } from '../../../lib/decoders';
13
18
  import { BytesLike } from 'ethers/lib/utils';
14
19
  import { Address } from '@paraswap/core';
15
20
  import { BigNumber } from 'ethers';
16
- import { _require } from '../../../utils';
17
- import { AbiItem } from 'web3-utils';
21
+ import { DexConfigMap } from '../../../types';
18
22
 
19
23
  const DEFAULT_2_ZERO_ARRAY = [0n, 0n];
20
24
  const DEFAULT_4_ZERO_ARRAY = [0n, 0n, 0n, 0n];
21
25
 
22
- type AdditionalContractFunctions = 'stored_rates';
23
-
24
- const getStoredRatesABI = (n: number) => ({
26
+ const getStoredRatesABI = (n: string) => ({
25
27
  name: 'stored_rates',
26
28
  stateMutability: 'view',
27
29
  type: 'function',
@@ -38,7 +40,7 @@ export class FactoryStateHandler extends PoolPollingBase {
38
40
  readonly implementationName: FactoryImplementationNames,
39
41
  implementationAddress: Address,
40
42
  readonly address: Address,
41
- stateUpdatePeriodMs: number,
43
+ readonly config: DexParams,
42
44
  readonly factoryAddress: Address,
43
45
  readonly poolIdentifier: string,
44
46
  readonly poolConstants: PoolConstants,
@@ -52,7 +54,7 @@ export class FactoryStateHandler extends PoolPollingBase {
52
54
  FactoryCurveV1ABI as JsonFragment[],
53
55
  ),
54
56
  private additionalFuncsIface: Interface = new Interface([
55
- getStoredRatesABI(poolContextConstants.N_COINS),
57
+ getStoredRatesABI(poolContextConstants?.N_COINS?.toString() || ''),
56
58
  ]),
57
59
  ) {
58
60
  super(
@@ -62,7 +64,7 @@ export class FactoryStateHandler extends PoolPollingBase {
62
64
  cacheStateKey,
63
65
  implementationName,
64
66
  implementationAddress,
65
- stateUpdatePeriodMs,
67
+ config.stateUpdatePeriodMs,
66
68
  poolIdentifier,
67
69
  poolConstants,
68
70
  address,
@@ -81,6 +83,11 @@ export class FactoryStateHandler extends PoolPollingBase {
81
83
  }
82
84
 
83
85
  getStateMultiCalldata(): MultiCallParams<MulticallReturnedTypes>[] {
86
+ const factoryConfig = this.config.factories?.find(
87
+ ({ address }) =>
88
+ address.toLowerCase() === this.factoryAddress.toLowerCase(),
89
+ );
90
+
84
91
  const calls = [
85
92
  {
86
93
  target: this.factoryAddress,
@@ -106,8 +113,11 @@ export class FactoryStateHandler extends PoolPollingBase {
106
113
  this.address,
107
114
  ]),
108
115
  decodeFunction: (result: MultiResult<BytesLike> | BytesLike) =>
109
- generalDecoder(result, ['uint256[4]'], DEFAULT_4_ZERO_ARRAY, parsed =>
110
- parsed[0].map((p: BigNumber) => p.toBigInt()),
116
+ generalDecoder(
117
+ result,
118
+ [`uint256[${factoryConfig?.isStableNg ? '' : '4'}]`],
119
+ DEFAULT_4_ZERO_ARRAY,
120
+ parsed => parsed[0].map((p: BigNumber) => p.toBigInt()),
111
121
  ),
112
122
  },
113
123
  ];
@@ -122,13 +132,51 @@ export class FactoryStateHandler extends PoolPollingBase {
122
132
  decodeFunction: (result: MultiResult<BytesLike> | BytesLike) =>
123
133
  generalDecoder(
124
134
  result,
125
- [`uint256[${this.poolContextConstants.N_COINS}]`],
135
+ [
136
+ `uint256[${
137
+ factoryConfig?.isStableNg
138
+ ? ''
139
+ : this.poolContextConstants.N_COINS
140
+ }]`,
141
+ ],
126
142
  new Array(this.poolContextConstants.N_COINS).fill(0n),
127
143
  parsed => parsed[0].map((p: BigNumber) => p.toBigInt()),
128
144
  ),
129
145
  });
130
146
  }
131
147
 
148
+ if (factoryConfig?.isStableNg) {
149
+ calls.push({
150
+ target: this.address,
151
+ callData: this.abiCoder.encodeFunctionCall(
152
+ {
153
+ stateMutability: 'view',
154
+ type: 'function',
155
+ name: 'offpeg_fee_multiplier',
156
+ inputs: [],
157
+ outputs: [{ name: '', type: 'uint256' }],
158
+ },
159
+ [],
160
+ ),
161
+ decodeFunction: uint256ToBigInt,
162
+ });
163
+
164
+ calls.push({
165
+ target: this.address,
166
+ callData: this.abiCoder.encodeFunctionCall(
167
+ {
168
+ stateMutability: 'view',
169
+ type: 'function',
170
+ name: 'N_COINS',
171
+ inputs: [],
172
+ outputs: [{ name: '', type: 'uint256' }],
173
+ },
174
+ [],
175
+ ),
176
+ decodeFunction: uint256DecodeToNumber,
177
+ });
178
+ }
179
+
132
180
  return calls;
133
181
  }
134
182
 
@@ -137,12 +185,15 @@ export class FactoryStateHandler extends PoolPollingBase {
137
185
  blockNumber: number,
138
186
  updatedAtMs: number,
139
187
  ): PoolState {
140
- const [A, fees, balances, storedRates] = multiOutputs as [
141
- bigint,
142
- bigint[],
143
- bigint[],
144
- bigint[] | undefined,
145
- ];
188
+ const [A, fees, balances, storedRates, offpeg_fee_multiplier, n_coins] =
189
+ multiOutputs as [
190
+ bigint,
191
+ bigint[],
192
+ bigint[],
193
+ bigint[] | undefined,
194
+ bigint | undefined,
195
+ number | undefined,
196
+ ];
146
197
 
147
198
  let basePoolState: PoolState | undefined;
148
199
  if (this.isMetaPool) {
@@ -164,9 +215,11 @@ export class FactoryStateHandler extends PoolPollingBase {
164
215
  fee: fees[0], // Array has [fee, adminFee], but we want only fee
165
216
  balances: balances,
166
217
  constants: this.poolConstants,
218
+ n_coins,
167
219
  basePoolState,
168
220
  updatedAtMs,
169
221
  blockNumber,
222
+ offpeg_fee_multiplier,
170
223
  storedRates,
171
224
  };
172
225
  }
@@ -53,6 +53,7 @@ export abstract class PoolPollingBase {
53
53
  this.fullName = `${dexKey}-${network}-${this.CLASS_NAME}-${this.implementationName}-${this.address}`;
54
54
  this.isMetaPool = baseStatePoolPolling !== undefined;
55
55
  this.coinsToIndices = this._reduceToIndexMapping(poolConstants.COINS);
56
+
56
57
  this.underlyingCoinsToIndices = baseStatePoolPolling
57
58
  ? this._reduceToIndexMapping([
58
59
  poolConstants.COINS[0],
@@ -58,6 +58,7 @@ export type PoolState = {
58
58
  offpeg_fee_multiplier?: bigint; // from pool
59
59
  basePoolState?: PoolState;
60
60
  storedRates?: bigint[]; // from pool, but only for oracle ones
61
+ n_coins?: number;
61
62
  };
62
63
 
63
64
  export type PoolStateWithUpdateInfo<T> = {
@@ -115,6 +116,10 @@ export enum FactoryImplementationNames {
115
116
  FACTORY_PLAIN_4_BASIC = 'factory_plain_4_basic',
116
117
  FACTORY_PLAIN_4_ETH = 'factory_plain_4_eth',
117
118
  FACTORY_PLAIN_4_OPTIMIZED = 'factory_plain_4_optimized',
119
+
120
+ FACTORY_STABLE_NG = 'factory_stable_ng',
121
+ // FACTORY_STABLE_6_NG = 'factory_stable_6_ng',
122
+ // FACTORY_STABLE_8_NG = 'factory_stable_8_ng',
118
123
  }
119
124
 
120
125
  export enum CustomImplementationNames {
@@ -175,8 +180,14 @@ export type CustomPoolConfig = {
175
180
  useForPricing: boolean;
176
181
  };
177
182
 
183
+ type DexParamFactory = {
184
+ address: string;
185
+ maxPlainCoins?: number;
186
+ isStableNg?: boolean;
187
+ };
188
+
178
189
  export type DexParams = {
179
- factoryAddresses: string[] | null;
190
+ factories: DexParamFactory[] | null;
180
191
  stateUpdatePeriodMs: number;
181
192
  factoryPoolImplementations: Record<Address, FactoryPoolImplementations>;
182
193
  customPools: Record<string, CustomPoolConfig>;
@@ -7,6 +7,9 @@ export const DexalotConfig: DexConfigMap<DexParams> = {
7
7
  [Network.AVALANCHE]: {
8
8
  mainnetRFQAddress: '0xEed3c159F3A96aB8d41c8B9cA49EE1e5071A7cdD',
9
9
  },
10
+ [Network.ARBITRUM]: {
11
+ mainnetRFQAddress: '0x010224949cCa211Fb5dDfEDD28Dc8Bf9D2990368',
12
+ },
10
13
  },
11
14
  };
12
15
 
@@ -15,4 +18,8 @@ export const Adapters: Record<number, AdapterMappings> = {
15
18
  [SwapSide.SELL]: [{ name: 'AvalancheAdapter02', index: 6 }],
16
19
  [SwapSide.BUY]: [{ name: 'AvalancheBuyAdapter', index: 8 }],
17
20
  },
21
+ [Network.ARBITRUM]: {
22
+ [SwapSide.SELL]: [{ name: 'ArbitrumAdapter03', index: 2 }],
23
+ [SwapSide.BUY]: [{ name: 'ArbitrumBuyAdapter', index: 11 }],
24
+ },
18
25
  };
@@ -196,7 +196,7 @@ describe('Dexalot E2E', () => {
196
196
  const tokenASymbol: string = 'BTCb';
197
197
  const tokenBSymbol: string = 'USDC';
198
198
 
199
- const tokenAAmount: string = '100';
199
+ const tokenAAmount: string = '10000';
200
200
  const tokenBAmount: string = '9000000000';
201
201
  const nativeTokenAmount = '1000000000000000000';
202
202
 
@@ -211,4 +211,26 @@ describe('Dexalot E2E', () => {
211
211
  true,
212
212
  );
213
213
  });
214
+
215
+ describe('Arbitrum', () => {
216
+ const network = Network.ARBITRUM;
217
+
218
+ const tokenASymbol: string = 'USDT';
219
+ const tokenBSymbol: string = 'USDC';
220
+
221
+ const tokenAAmount: string = '1000000';
222
+ const tokenBAmount: string = '1000000';
223
+ const nativeTokenAmount = '1000000000000000000';
224
+
225
+ testForNetwork(
226
+ network,
227
+ dexKey,
228
+ tokenASymbol,
229
+ tokenBSymbol,
230
+ tokenAAmount,
231
+ tokenBAmount,
232
+ nativeTokenAmount,
233
+ true,
234
+ );
235
+ });
214
236
  });