@paraswap/dex-lib 2.47.4-hashflow-mm → 2.47.4

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 (145) hide show
  1. package/build/abi/balancer-v2/gyro-e.abi.json +1595 -0
  2. package/build/dex/balancer-v2/balancer-v2.d.ts +6 -3
  3. package/build/dex/balancer-v2/balancer-v2.js +55 -35
  4. package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
  5. package/build/dex/balancer-v2/pools/gyro/Gyro3Pool.d.ts +32 -0
  6. package/build/dex/balancer-v2/pools/gyro/Gyro3Pool.js +149 -0
  7. package/build/dex/balancer-v2/pools/gyro/Gyro3Pool.js.map +1 -0
  8. package/build/dex/balancer-v2/pools/gyro/GyroEPool.d.ts +37 -0
  9. package/build/dex/balancer-v2/pools/gyro/GyroEPool.js +222 -0
  10. package/build/dex/balancer-v2/pools/gyro/GyroEPool.js.map +1 -0
  11. package/build/dex/balancer-v2/pools/gyro/gyro-helpers.d.ts +2 -0
  12. package/build/dex/balancer-v2/pools/gyro/gyro-helpers.js +19 -0
  13. package/build/dex/balancer-v2/pools/gyro/gyro-helpers.js.map +1 -0
  14. package/build/dex/balancer-v2/queryOnChain.d.ts +1 -0
  15. package/build/dex/balancer-v2/queryOnChain.js +40 -0
  16. package/build/dex/balancer-v2/queryOnChain.js.map +1 -0
  17. package/build/dex/balancer-v2/types.d.ts +24 -1
  18. package/build/dex/balancer-v2/types.js +2 -0
  19. package/build/dex/balancer-v2/types.js.map +1 -1
  20. package/build/dex/balancer-v2/utils.d.ts +8 -0
  21. package/build/dex/balancer-v2/utils.js +17 -1
  22. package/build/dex/balancer-v2/utils.js.map +1 -1
  23. package/build/dex/hashflow/constants.js +1 -1
  24. package/build/dex/hashflow/constants.js.map +1 -1
  25. package/build/dex/hashflow/hashflow.js +0 -1
  26. package/build/dex/hashflow/hashflow.js.map +1 -1
  27. package/package.json +2 -1
  28. package/src/abi/balancer-v2/gyro-e.abi.json +1595 -0
  29. package/src/dex/balancer-v2/balancer-v2-e2e.test.ts +94 -0
  30. package/src/dex/balancer-v2/balancer-v2-gyro3.test.ts +268 -0
  31. package/src/dex/balancer-v2/balancer-v2-gyroE.test.ts +401 -0
  32. package/src/dex/balancer-v2/balancer-v2-integration.test.ts +253 -112
  33. package/src/dex/balancer-v2/balancer-v2.ts +105 -69
  34. package/src/dex/balancer-v2/pools/gyro/Gyro3Pool.ts +255 -0
  35. package/src/dex/balancer-v2/pools/gyro/GyroEPool.ts +403 -0
  36. package/src/dex/balancer-v2/pools/gyro/gyro-helpers.ts +15 -0
  37. package/src/dex/balancer-v2/queryOnChain.ts +48 -0
  38. package/src/dex/balancer-v2/types.ts +26 -0
  39. package/src/dex/balancer-v2/utils.ts +16 -0
  40. package/src/dex/hashflow/constants.ts +1 -1
  41. package/src/dex/hashflow/hashflow.ts +1 -4
  42. package/src/dex/synthetix/synthetix-state.ts +2 -2
  43. package/tests/constants-e2e.ts +26 -0
  44. package/build/abi/Redstone.json +0 -739
  45. package/build/abi/angle/stagToken.json +0 -963
  46. package/build/abi/angle-transmuter/Pyth.json +0 -1534
  47. package/build/abi/angle-transmuter/Transmuter.json +0 -1719
  48. package/build/abi/smardex/smardex-factory.json +0 -185
  49. package/build/abi/smardex/smardex-pool.json +0 -578
  50. package/build/abi/smardex/smardex-router.json +0 -648
  51. package/build/abi/trader-joe-v2_1/FactoryABI.json +0 -1208
  52. package/build/abi/trader-joe-v2_1/PairABI.json +0 -1493
  53. package/build/abi/trader-joe-v2_1/RouterABI.json +0 -1489
  54. package/build/abi/trader-joe-v2_1/StateMulticall.json +0 -193
  55. package/build/abi/wombat/pool.json +0 -1289
  56. package/build/dex/angle-staked-stable/angle-staked-stable-pool.d.ts +0 -53
  57. package/build/dex/angle-staked-stable/angle-staked-stable-pool.js +0 -175
  58. package/build/dex/angle-staked-stable/angle-staked-stable-pool.js.map +0 -1
  59. package/build/dex/angle-staked-stable/angle-staked-stable.d.ts +0 -42
  60. package/build/dex/angle-staked-stable/angle-staked-stable.js +0 -232
  61. package/build/dex/angle-staked-stable/angle-staked-stable.js.map +0 -1
  62. package/build/dex/angle-staked-stable/config.d.ts +0 -4
  63. package/build/dex/angle-staked-stable/config.js +0 -26
  64. package/build/dex/angle-staked-stable/config.js.map +0 -1
  65. package/build/dex/angle-staked-stable/types.d.ts +0 -15
  66. package/build/dex/angle-staked-stable/types.js +0 -3
  67. package/build/dex/angle-staked-stable/types.js.map +0 -1
  68. package/build/dex/angle-transmuter/angle-transmuter-pool.d.ts +0 -43
  69. package/build/dex/angle-transmuter/angle-transmuter-pool.js +0 -309
  70. package/build/dex/angle-transmuter/angle-transmuter-pool.js.map +0 -1
  71. package/build/dex/angle-transmuter/angle-transmuter.d.ts +0 -46
  72. package/build/dex/angle-transmuter/angle-transmuter.js +0 -233
  73. package/build/dex/angle-transmuter/angle-transmuter.js.map +0 -1
  74. package/build/dex/angle-transmuter/backedOracle.d.ts +0 -19
  75. package/build/dex/angle-transmuter/backedOracle.js +0 -56
  76. package/build/dex/angle-transmuter/backedOracle.js.map +0 -1
  77. package/build/dex/angle-transmuter/config.d.ts +0 -4
  78. package/build/dex/angle-transmuter/config.js +0 -20
  79. package/build/dex/angle-transmuter/config.js.map +0 -1
  80. package/build/dex/angle-transmuter/constants.d.ts +0 -4
  81. package/build/dex/angle-transmuter/constants.js +0 -8
  82. package/build/dex/angle-transmuter/constants.js.map +0 -1
  83. package/build/dex/angle-transmuter/pyth.d.ts +0 -19
  84. package/build/dex/angle-transmuter/pyth.js +0 -71
  85. package/build/dex/angle-transmuter/pyth.js.map +0 -1
  86. package/build/dex/angle-transmuter/redstone.d.ts +0 -20
  87. package/build/dex/angle-transmuter/redstone.js +0 -73
  88. package/build/dex/angle-transmuter/redstone.js.map +0 -1
  89. package/build/dex/angle-transmuter/transmuter.d.ts +0 -50
  90. package/build/dex/angle-transmuter/transmuter.js +0 -314
  91. package/build/dex/angle-transmuter/transmuter.js.map +0 -1
  92. package/build/dex/angle-transmuter/types.d.ts +0 -144
  93. package/build/dex/angle-transmuter/types.js +0 -31
  94. package/build/dex/angle-transmuter/types.js.map +0 -1
  95. package/build/dex/angle-transmuter/utils.d.ts +0 -9
  96. package/build/dex/angle-transmuter/utils.js +0 -264
  97. package/build/dex/angle-transmuter/utils.js.map +0 -1
  98. package/build/dex/smardex/subgraph-queries.d.ts +0 -1
  99. package/build/dex/smardex/subgraph-queries.js +0 -17
  100. package/build/dex/smardex/subgraph-queries.js.map +0 -1
  101. package/build/dex/smardex/usd-reserves.d.ts +0 -23
  102. package/build/dex/smardex/usd-reserves.js +0 -86
  103. package/build/dex/smardex/usd-reserves.js.map +0 -1
  104. package/build/dex/trader-joe-v2-1-2/config.d.ts +0 -4
  105. package/build/dex/trader-joe-v2-1-2/config.js +0 -47
  106. package/build/dex/trader-joe-v2-1-2/config.js.map +0 -1
  107. package/build/dex/trader-joe-v2-1-2/constants.d.ts +0 -20
  108. package/build/dex/trader-joe-v2-1-2/constants.js +0 -22
  109. package/build/dex/trader-joe-v2-1-2/constants.js.map +0 -1
  110. package/build/dex/trader-joe-v2-1-2/math/index.d.ts +0 -37
  111. package/build/dex/trader-joe-v2-1-2/math/index.js +0 -291
  112. package/build/dex/trader-joe-v2-1-2/math/index.js.map +0 -1
  113. package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2-pool.d.ts +0 -60
  114. package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2-pool.js +0 -248
  115. package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2-pool.js.map +0 -1
  116. package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2.d.ts +0 -53
  117. package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2.js +0 -307
  118. package/build/dex/trader-joe-v2-1-2/trader-joe-v2-1-2.js.map +0 -1
  119. package/build/dex/trader-joe-v2-1-2/types.d.ts +0 -82
  120. package/build/dex/trader-joe-v2-1-2/types.js +0 -9
  121. package/build/dex/trader-joe-v2-1-2/types.js.map +0 -1
  122. package/build/dex/trader-joe-v2_1/config.d.ts +0 -4
  123. package/build/dex/trader-joe-v2_1/config.js +0 -47
  124. package/build/dex/trader-joe-v2_1/config.js.map +0 -1
  125. package/build/dex/trader-joe-v2_1/constants.d.ts +0 -20
  126. package/build/dex/trader-joe-v2_1/constants.js +0 -22
  127. package/build/dex/trader-joe-v2_1/constants.js.map +0 -1
  128. package/build/dex/trader-joe-v2_1/math/index.d.ts +0 -37
  129. package/build/dex/trader-joe-v2_1/math/index.js +0 -291
  130. package/build/dex/trader-joe-v2_1/math/index.js.map +0 -1
  131. package/build/dex/trader-joe-v2_1/trader-joe-v2.1.d.ts +0 -0
  132. package/build/dex/trader-joe-v2_1/trader-joe-v2.1.js +0 -384
  133. package/build/dex/trader-joe-v2_1/trader-joe-v2.1.js.map +0 -1
  134. package/build/dex/trader-joe-v2_1/trader-joe-v2_1-pool.d.ts +0 -60
  135. package/build/dex/trader-joe-v2_1/trader-joe-v2_1-pool.js +0 -247
  136. package/build/dex/trader-joe-v2_1/trader-joe-v2_1-pool.js.map +0 -1
  137. package/build/dex/trader-joe-v2_1/trader-joe-v2_1.d.ts +0 -53
  138. package/build/dex/trader-joe-v2_1/trader-joe-v2_1.js +0 -307
  139. package/build/dex/trader-joe-v2_1/trader-joe-v2_1.js.map +0 -1
  140. package/build/dex/trader-joe-v2_1/types.d.ts +0 -82
  141. package/build/dex/trader-joe-v2_1/types.js +0 -9
  142. package/build/dex/trader-joe-v2_1/types.js.map +0 -1
  143. package/build/dex/wombat/wombat-pool-poller.d.ts +0 -22
  144. package/build/dex/wombat/wombat-pool-poller.js +0 -164
  145. package/build/dex/wombat/wombat-pool-poller.js.map +0 -1
@@ -0,0 +1,403 @@
1
+ import { Interface } from '@ethersproject/abi';
2
+ import { BigNumber } from '@ethersproject/bignumber';
3
+
4
+ import { BasePool } from '../balancer-v2-pool';
5
+ import { NULL_ADDRESS, SwapSide } from '../../../../constants';
6
+ import {
7
+ decodeThrowError,
8
+ getTokenScalingFactor,
9
+ safeParseFixed,
10
+ } from '../../utils';
11
+ import { callData, SubgraphPoolBase, PoolState, TokenState } from '../../types';
12
+ import { MathSol } from '../../balancer-v2-math';
13
+ import {
14
+ GyroEMaths,
15
+ DerivedGyroEParams,
16
+ GyroEParams,
17
+ balancesFromTokenInOut,
18
+ Vector2,
19
+ } from '@balancer-labs/sor';
20
+ import GyroEAbi from '../../../../abi/balancer-v2/gyro-e.abi.json';
21
+ import * as util from 'util';
22
+
23
+ // Swap Limit factor
24
+ const SWAP_LIMIT_FACTOR = BigInt('999999000000000000');
25
+
26
+ // All values should be normalised to 18 decimals. e.g. 1USDC = 1e18 not 1e6
27
+ export type GyroEPoolPairData = {
28
+ balances: BigNumber[];
29
+ tokenRates: bigint[];
30
+ gyroParams: GyroEParams;
31
+ gyroDerivedParams: DerivedGyroEParams;
32
+ rateProviders: string[];
33
+ indexIn: number;
34
+ indexOut: number;
35
+ swapFee: bigint;
36
+ scalingFactors: bigint[];
37
+ tokenInIsToken0: boolean;
38
+ };
39
+
40
+ export class GyroEPool extends BasePool {
41
+ vaultAddress: string;
42
+ vaultInterface: Interface;
43
+ poolInterface = new Interface(GyroEAbi);
44
+
45
+ constructor(vaultAddress: string, vaultInterface: Interface) {
46
+ super();
47
+ this.vaultAddress = vaultAddress;
48
+ this.vaultInterface = vaultInterface;
49
+ }
50
+
51
+ parsePoolPairData(
52
+ pool: SubgraphPoolBase,
53
+ poolState: PoolState,
54
+ tokenIn: string,
55
+ tokenOut: string,
56
+ ): GyroEPoolPairData {
57
+ // All values should be normalised to 18 decimals. e.g. 1USDC = 1e18 not 1e6
58
+ let indexIn = 0,
59
+ indexOut = 0;
60
+ const scalingFactors: bigint[] = [];
61
+ const balances = pool.tokens.map((t, i) => {
62
+ if (t.address.toLowerCase() === tokenIn.toLowerCase()) indexIn = i;
63
+ else if (t.address.toLowerCase() === tokenOut.toLowerCase()) indexOut = i;
64
+ const scalingFactor = getTokenScalingFactor(t.decimals);
65
+ scalingFactors.push(scalingFactor);
66
+ return BigNumber.from(
67
+ this._upscale(
68
+ BigInt(poolState.tokens[t.address.toLowerCase()].balance),
69
+ scalingFactor,
70
+ ),
71
+ );
72
+ });
73
+
74
+ const tokenInIsToken0 = indexIn === 0;
75
+
76
+ const tokenRates = poolState.tokenRates
77
+ ? [poolState.tokenRates![0], poolState.tokenRates![1]]
78
+ : [];
79
+
80
+ const rateProviders = poolState.rateProviders ?? [];
81
+
82
+ const poolPairData: GyroEPoolPairData = {
83
+ gyroParams: poolState.gyroParams!,
84
+ gyroDerivedParams: poolState.gyroDerivedParams!,
85
+ tokenRates,
86
+ rateProviders,
87
+ balances,
88
+ indexIn,
89
+ indexOut,
90
+ scalingFactors,
91
+ swapFee: poolState.swapFee,
92
+ tokenInIsToken0,
93
+ };
94
+ return poolPairData;
95
+ }
96
+
97
+ getSwapMaxAmount(poolPairData: GyroEPoolPairData, side: SwapSide): bigint {
98
+ if (side === SwapSide.SELL) {
99
+ // Approximation - similar to traditional stable pools
100
+ return this._downscaleDown(
101
+ MathSol.mulDownFixed(
102
+ poolPairData.balances[poolPairData.indexOut].toBigInt(),
103
+ SWAP_LIMIT_FACTOR,
104
+ ),
105
+ poolPairData.scalingFactors[poolPairData.indexIn],
106
+ );
107
+ } else {
108
+ return this._downscaleDown(
109
+ MathSol.mulDownFixed(
110
+ poolPairData.balances[poolPairData.indexIn].toBigInt(),
111
+ SWAP_LIMIT_FACTOR,
112
+ ),
113
+ poolPairData.scalingFactors[poolPairData.indexOut],
114
+ );
115
+ }
116
+ }
117
+
118
+ /*
119
+ Helper function to construct onchain multicall data for Pool.
120
+ */
121
+ getOnChainCalls(pool: SubgraphPoolBase): callData[] {
122
+ const poolCallData: callData[] = [
123
+ {
124
+ target: this.vaultAddress,
125
+ callData: this.vaultInterface.encodeFunctionData('getPoolTokens', [
126
+ pool.id,
127
+ ]),
128
+ },
129
+ {
130
+ target: pool.address,
131
+ callData: this.poolInterface.encodeFunctionData('getSwapFeePercentage'),
132
+ },
133
+ {
134
+ target: pool.address,
135
+ callData: this.poolInterface.encodeFunctionData('getECLPParams'),
136
+ },
137
+ ];
138
+
139
+ // Only version 2 of GyroE uses token rates
140
+ const v2Calls =
141
+ pool.poolTypeVersion === 2
142
+ ? [
143
+ {
144
+ target: pool.address,
145
+ callData: this.poolInterface.encodeFunctionData('getTokenRates'),
146
+ },
147
+ {
148
+ target: pool.address,
149
+ callData: this.poolInterface.encodeFunctionData('rateProvider0'),
150
+ },
151
+ {
152
+ target: pool.address,
153
+ callData: this.poolInterface.encodeFunctionData('rateProvider1'),
154
+ },
155
+ ]
156
+ : [];
157
+
158
+ return [...poolCallData, ...v2Calls];
159
+ }
160
+
161
+ /*
162
+ Helper function to decode multicall data for Pool.
163
+ data must contain returnData
164
+ startIndex is where to start in returnData. Allows this decode function to be called along with other pool types.
165
+ */
166
+ decodeOnChainCalls(
167
+ pool: SubgraphPoolBase,
168
+ data: { success: boolean; returnData: any }[],
169
+ startIndex: number,
170
+ ): [{ [address: string]: PoolState }, number] {
171
+ const pools = {} as { [address: string]: PoolState };
172
+
173
+ const poolTokens = decodeThrowError(
174
+ this.vaultInterface,
175
+ 'getPoolTokens',
176
+ data[startIndex++],
177
+ pool.address,
178
+ );
179
+ const swapFee = decodeThrowError(
180
+ this.poolInterface,
181
+ 'getSwapFeePercentage',
182
+ data[startIndex++],
183
+ pool.address,
184
+ )[0];
185
+
186
+ const eclParams = decodeThrowError(
187
+ this.poolInterface,
188
+ 'getECLPParams',
189
+ data[startIndex++],
190
+ pool.address,
191
+ );
192
+
193
+ let tokenRates;
194
+ let rateProviders: string[] = [];
195
+ if (pool.poolTypeVersion === 2) {
196
+ tokenRates = decodeThrowError(
197
+ this.poolInterface,
198
+ 'getTokenRates',
199
+ data[startIndex++],
200
+ pool.address,
201
+ );
202
+ tokenRates = tokenRates.map(t => BigInt(t.toString()));
203
+
204
+ const rateProvider0 = decodeThrowError(
205
+ this.poolInterface,
206
+ 'rateProvider0',
207
+ data[startIndex++],
208
+ pool.address,
209
+ )[0];
210
+
211
+ const rateProvider1 = decodeThrowError(
212
+ this.poolInterface,
213
+ 'rateProvider1',
214
+ data[startIndex++],
215
+ pool.address,
216
+ )[0];
217
+ rateProviders = [rateProvider0, rateProvider1];
218
+ }
219
+
220
+ const poolState: PoolState = {
221
+ gyroParams: eclParams.params,
222
+ gyroDerivedParams: eclParams.d,
223
+ swapFee: BigInt(swapFee.toString()),
224
+ tokenRates,
225
+ rateProviders,
226
+ orderedTokens: poolTokens.tokens,
227
+ tokens: poolTokens.tokens.reduce(
228
+ (ptAcc: { [address: string]: TokenState }, pt: string, j: number) => {
229
+ const tokenState: TokenState = {
230
+ balance: BigInt(poolTokens.balances[j].toString()),
231
+ };
232
+ ptAcc[pt.toLowerCase()] = tokenState;
233
+ return ptAcc;
234
+ },
235
+ {},
236
+ ),
237
+ };
238
+ pools[pool.address] = poolState;
239
+ return [pools, startIndex];
240
+ }
241
+
242
+ onSell(amounts: bigint[], poolPairData: GyroEPoolPairData): bigint[] {
243
+ try {
244
+ const scalingFactorTokenIn = this._scalingFactor(
245
+ poolPairData.tokenInIsToken0,
246
+ poolPairData,
247
+ );
248
+ const scalingFactorTokenOut = this._scalingFactor(
249
+ !poolPairData.tokenInIsToken0,
250
+ poolPairData,
251
+ );
252
+ const normalizedBalances = this._normalizeBalances(
253
+ poolPairData.balances,
254
+ poolPairData.tokenRates,
255
+ );
256
+
257
+ const orderedNormalizedBalances = balancesFromTokenInOut(
258
+ normalizedBalances[poolPairData.indexIn],
259
+ normalizedBalances[poolPairData.indexOut],
260
+ poolPairData.tokenInIsToken0,
261
+ );
262
+
263
+ const [currentInvariant, invErr] = GyroEMaths.calculateInvariantWithError(
264
+ orderedNormalizedBalances,
265
+ poolPairData.gyroParams,
266
+ poolPairData.gyroDerivedParams,
267
+ );
268
+
269
+ const invariant: Vector2 = {
270
+ x: currentInvariant.add(invErr.mul(2)),
271
+ y: currentInvariant,
272
+ };
273
+
274
+ const tokenAmountsInScaled = amounts.map(a =>
275
+ this._upscale(a, scalingFactorTokenIn),
276
+ );
277
+
278
+ const tokenAmountsInWithFee = tokenAmountsInScaled.map(a =>
279
+ this._subtractSwapFeeAmount(a, poolPairData.swapFee),
280
+ );
281
+
282
+ const amountsOut: bigint[] = tokenAmountsInWithFee.map(amount => {
283
+ try {
284
+ const amountOut = GyroEMaths.calcOutGivenIn(
285
+ orderedNormalizedBalances,
286
+ BigNumber.from(amount),
287
+ poolPairData.tokenInIsToken0,
288
+ poolPairData.gyroParams,
289
+ poolPairData.gyroDerivedParams,
290
+ invariant,
291
+ ).toBigInt();
292
+
293
+ return this._downscaleDown(amountOut, scalingFactorTokenOut);
294
+ } catch (error) {
295
+ return BigInt(0);
296
+ }
297
+ });
298
+
299
+ return amountsOut;
300
+ } catch (error) {
301
+ return [];
302
+ }
303
+ }
304
+
305
+ onBuy(amounts: bigint[], poolPairData: GyroEPoolPairData): bigint[] {
306
+ try {
307
+ const scalingFactorTokenIn = this._scalingFactor(
308
+ poolPairData.tokenInIsToken0,
309
+ poolPairData,
310
+ );
311
+ const scalingFactorTokenOut = this._scalingFactor(
312
+ !poolPairData.tokenInIsToken0,
313
+ poolPairData,
314
+ );
315
+
316
+ const normalizedBalances = this._normalizeBalances(
317
+ poolPairData.balances,
318
+ poolPairData.tokenRates,
319
+ );
320
+
321
+ const orderedNormalizedBalances = balancesFromTokenInOut(
322
+ normalizedBalances[poolPairData.indexIn],
323
+ normalizedBalances[poolPairData.indexOut],
324
+ poolPairData.tokenInIsToken0,
325
+ );
326
+
327
+ const [currentInvariant, invErr] = GyroEMaths.calculateInvariantWithError(
328
+ orderedNormalizedBalances,
329
+ poolPairData.gyroParams,
330
+ poolPairData.gyroDerivedParams,
331
+ );
332
+
333
+ const invariant: Vector2 = {
334
+ x: currentInvariant.add(invErr.mul(2)),
335
+ y: currentInvariant,
336
+ };
337
+
338
+ const tokenAmountsOutScaled = amounts.map(a =>
339
+ this._upscale(a, scalingFactorTokenOut),
340
+ );
341
+
342
+ const amountsIn: bigint[] = tokenAmountsOutScaled.map(amount => {
343
+ try {
344
+ const amountIn = GyroEMaths.calcInGivenOut(
345
+ orderedNormalizedBalances,
346
+ BigNumber.from(amount),
347
+ poolPairData.tokenInIsToken0,
348
+ poolPairData.gyroParams,
349
+ poolPairData.gyroDerivedParams,
350
+ invariant,
351
+ ).toBigInt();
352
+ return amountIn;
353
+ } catch (error) {
354
+ return BigInt(0);
355
+ }
356
+ });
357
+
358
+ const downScaled = amountsIn.map(amount =>
359
+ this._downscaleUp(amount, scalingFactorTokenIn),
360
+ );
361
+
362
+ return downScaled.map(a => this._addFeeAmount(a, poolPairData.swapFee));
363
+ } catch (error) {
364
+ return [];
365
+ }
366
+ }
367
+
368
+ private _scalingFactor(
369
+ token0: boolean,
370
+ poolPairData: GyroEPoolPairData,
371
+ ): bigint {
372
+ const tokenIndex = token0 ? 0 : 1;
373
+ const scalingFactor = poolPairData.scalingFactors[tokenIndex];
374
+ if (
375
+ poolPairData.rateProviders.length === 0 ||
376
+ poolPairData.rateProviders[tokenIndex].toLowerCase() === NULL_ADDRESS
377
+ ) {
378
+ return scalingFactor;
379
+ } else {
380
+ return MathSol.mulDownFixed(
381
+ scalingFactor,
382
+ poolPairData.tokenRates[tokenIndex],
383
+ );
384
+ }
385
+ }
386
+
387
+ private _normalizeBalances(
388
+ balances: BigNumber[],
389
+ tokenRates: bigint[],
390
+ ): BigNumber[] {
391
+ // If pool is V1, e.g. has no tokenRates return balances
392
+ if (tokenRates.length === 0) return balances;
393
+ /*
394
+ Apply tokenRates
395
+ SOR upscales here first using scalingFactors but this is already being done in parse pair data so no need to repeat.
396
+ */
397
+ return balances.map((bal, i) => {
398
+ return BigNumber.from(
399
+ MathSol.mulDownFixed(bal.toBigInt(), tokenRates[i]),
400
+ );
401
+ });
402
+ }
403
+ }
@@ -0,0 +1,15 @@
1
+ export function _reduceFee(amountIn: bigint, swapFee: bigint): bigint {
2
+ const product = amountIn * swapFee;
3
+ const feeAmount = (product - 1n) / 1000000000000000000n + 1n;
4
+ return amountIn - feeAmount;
5
+ }
6
+
7
+ export function _addFee(amountIn: bigint, swapFee: bigint): bigint {
8
+ const fee = 1000000000000000000n - swapFee;
9
+ return divUp(amountIn, fee);
10
+ }
11
+
12
+ function divUp(a: bigint, b: bigint): bigint {
13
+ const aInflated = a * 1000000000000000000n;
14
+ return (aInflated - 1n) / b + 1n;
15
+ }
@@ -0,0 +1,48 @@
1
+ import dotenv from 'dotenv';
2
+ dotenv.config();
3
+ import { Contract } from '@ethersproject/contracts';
4
+ import { JsonRpcProvider } from '@ethersproject/providers';
5
+ import VaultABI from '../../abi/balancer-v2/vault.json';
6
+
7
+ // Compare retrieve an onchain query result for a single swap
8
+ export async function queryOnChain(
9
+ rpcUrl: string,
10
+ blockNumber: number,
11
+ poolId: string,
12
+ kind: 0 | 1,
13
+ assetIn: string,
14
+ assetOut: string,
15
+ amount: BigInt,
16
+ ): Promise<bigint[]> {
17
+ const provider = new JsonRpcProvider(rpcUrl);
18
+ const vaultAddress = '0xBA12222222228d8Ba445958a75a0704d566BF2C8';
19
+ const vaultContract = new Contract(vaultAddress, VaultABI, provider);
20
+
21
+ const funds = {
22
+ sender: '0x0000000000000000000000000000000000000000',
23
+ recipient: '0x0000000000000000000000000000000000000000',
24
+ fromInternalBalance: false,
25
+ toInternalBalance: false,
26
+ };
27
+ const swaps = [
28
+ {
29
+ poolId,
30
+ assetInIndex: 0,
31
+ assetOutIndex: 1,
32
+ amount,
33
+ userData: '0x',
34
+ },
35
+ ];
36
+ const assets = [assetIn, assetOut];
37
+ const deltas = await vaultContract.callStatic.queryBatchSwap(
38
+ kind,
39
+ swaps,
40
+ assets,
41
+ funds,
42
+ {
43
+ blockTag: blockNumber,
44
+ },
45
+ );
46
+ // console.log(deltas.toString());
47
+ return [deltas[0].toBigInt(), deltas[1].toBigInt()];
48
+ }
@@ -1,5 +1,6 @@
1
1
  import { NumberAsString } from '@paraswap/core';
2
2
  import { Address } from '../../types';
3
+ import { DerivedGyroEParams, GyroEParams } from '@balancer-labs/sor';
3
4
 
4
5
  // These should match the Balancer Pool types available on Subgraph
5
6
  export enum BalancerPoolTypes {
@@ -20,6 +21,8 @@ export enum BalancerPoolTypes {
20
21
  SiloLinear = 'SiloLinear',
21
22
  TetuLinear = 'TetuLinear',
22
23
  YearnLinear = 'YearnLinear',
24
+ Gyro3 = 'Gyro3',
25
+ GyroE = 'GyroE',
23
26
  }
24
27
 
25
28
  export type TokenState = {
@@ -32,6 +35,10 @@ export type PoolState = {
32
35
  tokens: {
33
36
  [address: string]: TokenState;
34
37
  };
38
+ tokenRates?: bigint[];
39
+ rateProviders?: string[];
40
+ gyroParams?: GyroEParams;
41
+ gyroDerivedParams?: DerivedGyroEParams;
35
42
  swapFee: bigint;
36
43
  orderedTokens: string[];
37
44
  rate?: bigint;
@@ -71,12 +78,31 @@ export interface SubgraphPoolBase {
71
78
  id: string;
72
79
  address: string;
73
80
  poolType: BalancerPoolTypes;
81
+ poolTypeVersion: number;
74
82
  tokens: SubgraphToken[];
75
83
  tokensMap: { [tokenAddress: string]: SubgraphToken };
76
84
  mainIndex: number;
77
85
  wrappedIndex: number;
78
86
 
79
87
  mainTokens: SubgraphMainToken[];
88
+
89
+ // gyro3
90
+ root3Alpha: string;
91
+ // gyroE
92
+ alpha: string;
93
+ beta: string;
94
+ c: string;
95
+ s: string;
96
+ lambda: string;
97
+ tauAlphaX: string;
98
+ tauAlphaY: string;
99
+ tauBetaX: string;
100
+ tauBetaY: string;
101
+ u: string;
102
+ v: string;
103
+ w: string;
104
+ z: string;
105
+ dSq: string;
80
106
  }
81
107
 
82
108
  export type BalancerSwapV2 = {
@@ -1,5 +1,6 @@
1
1
  import { getAddress } from '@ethersproject/address';
2
2
  import { Interface, Result } from '@ethersproject/abi';
3
+ import { parseFixed, BigNumber } from '@ethersproject/bignumber';
3
4
  import { getBigIntPow } from '../../utils';
4
5
  import { BI_POWS } from '../../bigint-constants';
5
6
  import { SwapSide } from '../../constants';
@@ -19,6 +20,21 @@ interface BalancerPathHop {
19
20
  tokenOut: SubgraphToken;
20
21
  }
21
22
 
23
+ /**
24
+ * Parses a fixed-point decimal string into a BigNumber. If we do not have enough decimals to express the number, we truncate it.
25
+ * @param value
26
+ * @param decimals
27
+ * @returns BigNumber
28
+ */
29
+ export function safeParseFixed(value: string, decimals = 0): BigNumber {
30
+ const [integer, fraction] = value.split('.');
31
+ if (!fraction) {
32
+ return parseFixed(value, decimals);
33
+ }
34
+ const safeValue = integer + '.' + fraction.slice(0, decimals);
35
+ return parseFixed(safeValue, decimals);
36
+ }
37
+
22
38
  export const isSameAddress = (address1: string, address2: string): boolean =>
23
39
  getAddress(address1) === getAddress(address2);
24
40
 
@@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js';
2
2
 
3
3
  export const HASHFLOW_BLACKLIST_TTL_S = 60 * 60 * 24 * 7; // 7 days
4
4
 
5
- export const HASHFLOW_MM_RESTRICT_TTL_S = 60 * 5; // 5 minutes
5
+ export const HASHFLOW_MM_RESTRICT_TTL_S = 60 * 60;
6
6
 
7
7
  export const HASHFLOW_PRICES_CACHES_TTL_S = 3;
8
8
 
@@ -711,7 +711,7 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
711
711
  },
712
712
  { deadline: minDeadline },
713
713
  ];
714
- } catch (e: any) {
714
+ } catch (e) {
715
715
  if (
716
716
  e instanceof Error &&
717
717
  e.message.endsWith('User is restricted from using Hashflow')
@@ -726,9 +726,6 @@ export class Hashflow extends SimpleExchange implements IDex<HashflowData> {
726
726
  `${this.dexKey}-${this.network}: Market Maker ${mm} failed to build transaction on side ${side} with too strict slippage. Skipping restriction`,
727
727
  );
728
728
  } else {
729
- this.logger.error(
730
- `${this.dexKey}-${this.network} MM unknown preprocess transaction error: ${e}`,
731
- );
732
729
  await this.restrictMM(mm);
733
730
  }
734
731
  }
@@ -407,7 +407,7 @@ export class SynthetixState {
407
407
  Address,
408
408
  bigint,
409
409
  bigint,
410
- ...Address[]
410
+ ...Address[],
411
411
  ];
412
412
 
413
413
  const [
@@ -437,7 +437,7 @@ export class SynthetixState {
437
437
  Address,
438
438
  Address,
439
439
  bigint,
440
- ...string[]
440
+ ...string[],
441
441
  ];
442
442
 
443
443
  _require(
@@ -41,6 +41,14 @@ export const Tokens: {
41
41
  addBalance: balancesFn,
42
42
  addAllowance: allowedFn,
43
43
  },
44
+ R: {
45
+ address: '0x183015a9ba6ff60230fdeadc3f43b3d788b13e21',
46
+ decimals: 18,
47
+ },
48
+ sDAI: {
49
+ address: '0x83f20f44975d03b1b09e64809b757c47f942beea',
50
+ decimals: 18,
51
+ },
44
52
  CUSDC: {
45
53
  address: '0x39AA39c021dfbaE8faC545936693aC917d5E7563',
46
54
  decimals: 8,
@@ -335,6 +343,10 @@ export const Tokens: {
335
343
  address: '0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6',
336
344
  decimals: 19,
337
345
  },
346
+ GYD: {
347
+ address: '0xe07f9d810a48ab5c3c914ba3ca53af14e4491e8a',
348
+ decimals: 18,
349
+ },
338
350
  },
339
351
  [Network.ROPSTEN]: {
340
352
  DAI: {
@@ -465,10 +477,22 @@ export const Tokens: {
465
477
  address: '0xa3fa99a148fa48d14ed51d610c367c61876997f1',
466
478
  decimals: 18,
467
479
  },
480
+ BUSD: {
481
+ address: '0x9C9e5fD8bbc25984B178FdCE6117Defa39d2db39',
482
+ decimals: 18,
483
+ },
484
+ TUSD: {
485
+ address: '0x2e1ad108ff1d8c782fcbbb89aad783ac49586756',
486
+ decimals: 18,
487
+ },
468
488
  SDEX: {
469
489
  address: '0x6899fAcE15c14348E1759371049ab64A3a06bFA6',
470
490
  decimals: 18,
471
491
  },
492
+ MATICX: {
493
+ address: '0xfa68fb4628dff1028cfec22b4162fccd0d45efb6',
494
+ decimals: 18,
495
+ },
472
496
  },
473
497
  [Network.FANTOM]: {
474
498
  FTM: { address: ETHER_ADDRESS, decimals: 18 },
@@ -1031,6 +1055,8 @@ export const Holders: {
1031
1055
  WETH: '0x2fEb1512183545f48f6b9C5b4EbfCaF49CfCa6F3',
1032
1056
  USDT: '0x8A446971dbB112f3be15bc38C14D44B94D9E94b9',
1033
1057
  XAUT: '0xc4e161e8d8a4bc4ac762ab33a28bbac5474203d7',
1058
+ R: '0xBfe4c9D3235475C138a61f62e9e72FaD94A3303b',
1059
+ sDAI: '0x8846163Fedc6b881526A6B48321601b474D40923',
1034
1060
  CVX: '0x0aCA67Fa70B142A3b9bF2eD89A81B40ff85dACdC',
1035
1061
  MIM: '0xa046a8660e66d178ee07ec97c585eeb6aa18c26c',
1036
1062
  AnkETH: '0xF7260D4ADc48fEefd5a19a9Eb23f9747CeE15C92',