@paraswap/dex-lib 2.33.4-balancer-v2-multihop.2 → 2.34.0
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.
- package/build/abi/algebra/AlgebraPool.abi.json +727 -0
- package/build/config.js +27 -0
- package/build/config.js.map +1 -1
- package/build/dex/algebra/algebra-pool-v1_1.d.ts +16 -2
- package/build/dex/algebra/algebra-pool-v1_1.js +166 -4
- package/build/dex/algebra/algebra-pool-v1_1.js.map +1 -1
- package/build/dex/algebra/algebra-pool.d.ts +46 -0
- package/build/dex/algebra/algebra-pool.js +336 -0
- package/build/dex/algebra/algebra-pool.js.map +1 -0
- package/build/dex/algebra/algebra.js +9 -7
- package/build/dex/algebra/algebra.js.map +1 -1
- package/build/dex/algebra/config.js +1 -0
- package/build/dex/algebra/config.js.map +1 -1
- package/build/dex/algebra/types.d.ts +3 -2
- package/build/dex/algebra/utils.d.ts +3 -1
- package/build/dex/algebra/utils.js +59 -1
- package/build/dex/algebra/utils.js.map +1 -1
- package/build/dex/balancer-v2/optimizer.d.ts +0 -1
- package/build/dex/balancer-v2/optimizer.js +21 -29
- package/build/dex/balancer-v2/optimizer.js.map +1 -1
- package/build/dex/solidly/forks-override/velodromeV2.js +4 -1
- package/build/dex/solidly/forks-override/velodromeV2.js.map +1 -1
- package/build/dex/uniswap-v2/nomiswap-v2.js.map +1 -1
- package/build/dex/uniswap-v3/uniswap-v3.js +7 -1
- package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
- package/build/lib/decoders.d.ts +3 -0
- package/build/lib/decoders.js +9 -1
- package/build/lib/decoders.js.map +1 -1
- package/build/stateful-event-subscriber.d.ts +1 -0
- package/build/stateful-event-subscriber.js +6 -0
- package/build/stateful-event-subscriber.js.map +1 -1
- package/package.json +1 -1
- package/src/abi/algebra/AlgebraFactory-v1_1.abi.json +250 -0
- package/src/config.ts +30 -0
- package/src/dex/algebra/algebra-integration.test.ts +122 -0
- package/src/dex/algebra/algebra-pool-v1_1.ts +259 -8
- package/src/dex/algebra/algebra.ts +9 -6
- package/src/dex/algebra/config.ts +1 -0
- package/src/dex/algebra/types.ts +3 -2
- package/src/dex/algebra/utils.ts +83 -2
- package/src/dex/balancer-v2/optimizer.ts +23 -38
- package/src/dex/solidly/forks-override/velodromeV2.ts +4 -2
- package/src/dex/uniswap-v2/nomiswap-v2.ts +2 -1
- package/src/dex/uniswap-v2/uniswap-v2-e2e-bsc.test.ts +6 -8
- package/src/dex/uniswap-v3/uniswap-v3-e2e.test.ts +52 -47
- package/src/dex/uniswap-v3/uniswap-v3-integration.test.ts +1 -9
- package/src/dex/uniswap-v3/uniswap-v3.ts +7 -1
- package/src/lib/decoders.ts +13 -0
- package/src/stateful-event-subscriber.ts +8 -0
- package/build/abi/api3-proxy.json +0 -46
- package/build/abi/api3-server-v1.json +0 -463
- package/build/abi/quick-perps/fast-price-events.json +0 -70
- package/build/abi/quick-perps/fast-price-feed.json +0 -741
- package/build/abi/quick-perps/reader.json +0 -313
- package/build/abi/quick-perps/vault-price-feed.json +0 -323
- package/build/abi/quick-perps/vault.json +0 -1953
- package/build/abi/quickPerps/fast-price-events.json +0 -70
- package/build/abi/quickPerps/fast-price-feed.json +0 -748
- package/build/abi/quickPerps/reader.json +0 -313
- package/build/abi/quickPerps/vault-price-feed.json +0 -477
- package/build/abi/quickPerps/vault.json +0 -1953
- package/build/abi/uniswap-v3/pancakeswap-v3/PancakeswapV3QuoterV2.abi.json +0 -285
- package/build/abi/uniswap-v3/pancakeswap-v3/PancakeswapV3Router.abi.json +0 -583
- package/build/abi/woo-fi/WooFeeManager.abi.json +0 -318
- package/build/abi/woo-fi/WooPP.abi.json +0 -548
- package/build/abi/woo-fi/Wooracle.abi.json +0 -260
- package/build/dex/aave-v3/tokens/arbitrum.json +0 -50
- package/build/dex/aave-v3/tokens/avalanche.json +0 -74
- package/build/dex/aave-v3/tokens/fantom.json +0 -62
- package/build/dex/aave-v3/tokens/optimism.json +0 -50
- package/build/dex/aave-v3/tokens/polygon.json +0 -116
- package/build/dex/balancer-v2/LinearMath.d.ts +0 -19
- package/build/dex/balancer-v2/LinearMath.js +0 -179
- package/build/dex/balancer-v2/LinearMath.js.map +0 -1
- package/build/dex/balancer-v2/LinearPool.d.ts +0 -47
- package/build/dex/balancer-v2/LinearPool.js +0 -324
- package/build/dex/balancer-v2/LinearPool.js.map +0 -1
- package/build/dex/balancer-v2/PhantomStablePool.d.ts +0 -47
- package/build/dex/balancer-v2/PhantomStablePool.js +0 -294
- package/build/dex/balancer-v2/PhantomStablePool.js.map +0 -1
- package/build/dex/balancer-v2/StableMath.d.ts +0 -9
- package/build/dex/balancer-v2/StableMath.js +0 -272
- package/build/dex/balancer-v2/StableMath.js.map +0 -1
- package/build/dex/balancer-v2/balancer-v2-pool.d.ts +0 -75
- package/build/dex/balancer-v2/balancer-v2-pool.js +0 -417
- package/build/dex/balancer-v2/balancer-v2-pool.js.map +0 -1
- package/build/dex/quick-perps/config.d.ts +0 -11
- package/build/dex/quick-perps/config.js +0 -27
- package/build/dex/quick-perps/config.js.map +0 -1
- package/build/dex/quick-perps/fast-price-feed.d.ts +0 -26
- package/build/dex/quick-perps/fast-price-feed.js +0 -176
- package/build/dex/quick-perps/fast-price-feed.js.map +0 -1
- package/build/dex/quick-perps/pool.d.ts +0 -21
- package/build/dex/quick-perps/pool.js +0 -210
- package/build/dex/quick-perps/pool.js.map +0 -1
- package/build/dex/quick-perps/quick-perps.d.ts +0 -52
- package/build/dex/quick-perps/quick-perps.js +0 -205
- package/build/dex/quick-perps/quick-perps.js.map +0 -1
- package/build/dex/quick-perps/types.d.ts +0 -98
- package/build/dex/quick-perps/types.js +0 -3
- package/build/dex/quick-perps/types.js.map +0 -1
- package/build/dex/quick-perps/usdq.d.ts +0 -15
- package/build/dex/quick-perps/usdq.js +0 -61
- package/build/dex/quick-perps/usdq.js.map +0 -1
- package/build/dex/quick-perps/vault-price-feed.d.ts +0 -43
- package/build/dex/quick-perps/vault-price-feed.js +0 -194
- package/build/dex/quick-perps/vault-price-feed.js.map +0 -1
- package/build/dex/quick-perps/vault-utils.d.ts +0 -8
- package/build/dex/quick-perps/vault-utils.js +0 -41
- package/build/dex/quick-perps/vault-utils.js.map +0 -1
- package/build/dex/quick-perps/vault.d.ts +0 -46
- package/build/dex/quick-perps/vault.js +0 -166
- package/build/dex/quick-perps/vault.js.map +0 -1
- package/build/dex/quickswap-v3.d.ts +0 -21
- package/build/dex/quickswap-v3.js +0 -40
- package/build/dex/quickswap-v3.js.map +0 -1
- package/build/dex/test-dex/config.d.ts +0 -4
- package/build/dex/test-dex/config.js +0 -15
- package/build/dex/test-dex/config.js.map +0 -1
- package/build/dex/test-dex/test-dex-pool.d.ts +0 -39
- package/build/dex/test-dex/test-dex-pool.js +0 -63
- package/build/dex/test-dex/test-dex-pool.js.map +0 -1
- package/build/dex/test-dex/test-dex.d.ts +0 -37
- package/build/dex/test-dex/test-dex.js +0 -126
- package/build/dex/test-dex/test-dex.js.map +0 -1
- package/build/dex/test-dex/types.d.ts +0 -6
- package/build/dex/test-dex/types.js +0 -3
- package/build/dex/test-dex/types.js.map +0 -1
- package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.d.ts +0 -12
- package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.js +0 -23
- package/build/dex/uniswap-v3/forks/pancakeswap-v3/pancakeswap-v3.js.map +0 -1
- package/build/dex/woo-fi/config.d.ts +0 -4
- package/build/dex/woo-fi/config.js +0 -141
- package/build/dex/woo-fi/config.js.map +0 -1
- package/build/dex/woo-fi/constants.d.ts +0 -5
- package/build/dex/woo-fi/constants.js +0 -20
- package/build/dex/woo-fi/constants.js.map +0 -1
- package/build/dex/woo-fi/types.d.ts +0 -48
- package/build/dex/woo-fi/types.js +0 -3
- package/build/dex/woo-fi/types.js.map +0 -1
- package/build/dex/woo-fi/woo-fi-decimal-math.d.ts +0 -14
- package/build/dex/woo-fi/woo-fi-decimal-math.js +0 -42
- package/build/dex/woo-fi/woo-fi-decimal-math.js.map +0 -1
- package/build/dex/woo-fi/woo-fi-math.d.ts +0 -31
- package/build/dex/woo-fi/woo-fi-math.js +0 -300
- package/build/dex/woo-fi/woo-fi-math.js.map +0 -1
- package/build/dex/woo-fi/woo-fi.d.ts +0 -65
- package/build/dex/woo-fi/woo-fi.js +0 -480
- package/build/dex/woo-fi/woo-fi.js.map +0 -1
- package/build/dex/woo-fi-v2/woo-fi-math.d.ts +0 -16
- package/build/dex/woo-fi-v2/woo-fi-math.js +0 -137
- package/build/dex/woo-fi-v2/woo-fi-math.js.map +0 -1
- package/build/lib/api3-feed.d.ts +0 -26
- package/build/lib/api3-feed.js +0 -82
- package/build/lib/api3-feed.js.map +0 -1
- package/src/dex/balancer-v2/balancer-v2-optimizer.test.ts +0 -226
|
@@ -9,31 +9,47 @@ import {
|
|
|
9
9
|
} from '../../stateful-event-subscriber';
|
|
10
10
|
import { IDexHelper } from '../../dex-helper/idex-helper';
|
|
11
11
|
import {
|
|
12
|
+
DecodedGlobalStateV1_1,
|
|
12
13
|
PoolStateV1_1,
|
|
13
14
|
TickBitMapMappingsWithBigNumber,
|
|
14
15
|
TickInfoMappingsWithBigNumber,
|
|
16
|
+
TickInfoWithBigNumber,
|
|
15
17
|
} from './types';
|
|
16
|
-
import { ethers } from 'ethers';
|
|
18
|
+
import { BigNumber, ethers } from 'ethers';
|
|
17
19
|
import { Contract } from 'web3-eth-contract';
|
|
18
20
|
import AlgebraABI from '../../abi/algebra/AlgebraPool-v1_1.abi.json';
|
|
21
|
+
import FactoryABI from '../../abi/algebra/AlgebraFactory-v1_1.abi.json';
|
|
19
22
|
import { DecodedStateMultiCallResultWithRelativeBitmapsV1_1 } from './types';
|
|
20
23
|
import {
|
|
21
24
|
OUT_OF_RANGE_ERROR_POSTFIX,
|
|
22
25
|
TICK_BITMAP_BUFFER,
|
|
23
26
|
TICK_BITMAP_TO_USE,
|
|
24
27
|
} from '../uniswap-v3/constants';
|
|
25
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
addressDecode,
|
|
30
|
+
uint256ToBigInt,
|
|
31
|
+
uint128ToBigNumber,
|
|
32
|
+
int24ToNumber,
|
|
33
|
+
} from '../../lib/decoders';
|
|
26
34
|
import { MultiCallParams } from '../../lib/multi-wrapper';
|
|
27
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
decodeGlobalStateV1_1,
|
|
37
|
+
decodeStateMultiCallResultWithRelativeBitmapsV1_1,
|
|
38
|
+
decodeTicksV1_1,
|
|
39
|
+
} from './utils';
|
|
28
40
|
import { AlgebraMath } from './lib/AlgebraMath';
|
|
29
41
|
import {
|
|
30
42
|
_reduceTickBitmap,
|
|
31
43
|
_reduceTicks,
|
|
32
44
|
} from '../uniswap-v3/contract-math/utils';
|
|
33
45
|
import { Constants } from './lib/Constants';
|
|
34
|
-
import { Network } from '../../constants';
|
|
46
|
+
import { Network, NULL_ADDRESS } from '../../constants';
|
|
35
47
|
import { TickTable } from './lib/TickTable';
|
|
36
48
|
|
|
49
|
+
const BN_ZERO = BigNumber.from(0);
|
|
50
|
+
const MAX_BATCH_SIZE = 100;
|
|
51
|
+
const MAX_NUMBER_OF_BATCH_REQUEST_HALVING = 3;
|
|
52
|
+
|
|
37
53
|
export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1> {
|
|
38
54
|
handlers: {
|
|
39
55
|
[event: string]: (
|
|
@@ -53,6 +69,13 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
|
|
|
53
69
|
readonly token1: Address;
|
|
54
70
|
|
|
55
71
|
public readonly poolIface = new Interface(AlgebraABI);
|
|
72
|
+
public readonly factoryIface = new Interface(FactoryABI);
|
|
73
|
+
|
|
74
|
+
private readonly cachedStateMultiCalls: MultiCallParams<
|
|
75
|
+
string | bigint | BigNumber | number | DecodedGlobalStateV1_1
|
|
76
|
+
>[];
|
|
77
|
+
|
|
78
|
+
private optimalTickRequestBatchSize?: number;
|
|
56
79
|
|
|
57
80
|
public initFailed = false;
|
|
58
81
|
public initRetryAttemptCount = 0;
|
|
@@ -69,6 +92,7 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
|
|
|
69
92
|
mapKey: string = '',
|
|
70
93
|
readonly poolInitCodeHash: string,
|
|
71
94
|
readonly poolDeployer: string,
|
|
95
|
+
private readonly forceManualStateGeneration: boolean = false,
|
|
72
96
|
) {
|
|
73
97
|
super(parentName, `${token0}_${token1}`, dexHelper, logger, true, mapKey);
|
|
74
98
|
this.token0 = token0.toLowerCase();
|
|
@@ -84,6 +108,8 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
|
|
|
84
108
|
this.handlers['Flash'] = this.handleFlashEvent.bind(this);
|
|
85
109
|
this.handlers['Collect'] = this.handleCollectEvent.bind(this);
|
|
86
110
|
this.handlers['CommunityFee'] = this.handleCommunityFee.bind(this);
|
|
111
|
+
|
|
112
|
+
this.cachedStateMultiCalls = this._getStateMulticall();
|
|
87
113
|
}
|
|
88
114
|
|
|
89
115
|
get poolAddress() {
|
|
@@ -174,7 +200,7 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
|
|
|
174
200
|
return TICK_BITMAP_TO_USE + TICK_BITMAP_BUFFER;
|
|
175
201
|
}
|
|
176
202
|
|
|
177
|
-
|
|
203
|
+
async fetchPoolStateSingleStep(
|
|
178
204
|
blockNumber: number,
|
|
179
205
|
): Promise<
|
|
180
206
|
[bigint, bigint, DecodedStateMultiCallResultWithRelativeBitmapsV1_1]
|
|
@@ -336,7 +362,7 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
|
|
|
336
362
|
[bigint, bigint, DecodedStateMultiCallResultWithRelativeBitmapsV1_1]
|
|
337
363
|
> {
|
|
338
364
|
try {
|
|
339
|
-
return await this.
|
|
365
|
+
return await this.fetchPoolStateSingleStep(blockNumber);
|
|
340
366
|
} catch (e) {
|
|
341
367
|
if (e instanceof Error && e.message.includes('Pool does not exist'))
|
|
342
368
|
throw e;
|
|
@@ -347,9 +373,234 @@ export class AlgebraEventPoolV1_1 extends StatefulEventSubscriber<PoolStateV1_1>
|
|
|
347
373
|
}
|
|
348
374
|
}
|
|
349
375
|
|
|
376
|
+
private _getStateMulticall(): MultiCallParams<
|
|
377
|
+
string | bigint | BigNumber | number | DecodedGlobalStateV1_1
|
|
378
|
+
>[] {
|
|
379
|
+
return [
|
|
380
|
+
{
|
|
381
|
+
target: this.factoryAddress,
|
|
382
|
+
callData: this.factoryIface.encodeFunctionData('poolByPair', [
|
|
383
|
+
this.token0,
|
|
384
|
+
this.token1,
|
|
385
|
+
]),
|
|
386
|
+
decodeFunction: addressDecode,
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
target: this.token0,
|
|
390
|
+
callData: this.erc20Interface.encodeFunctionData('balanceOf', [
|
|
391
|
+
this.poolAddress,
|
|
392
|
+
]),
|
|
393
|
+
decodeFunction: uint256ToBigInt,
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
target: this.token1,
|
|
397
|
+
callData: this.erc20Interface.encodeFunctionData('balanceOf', [
|
|
398
|
+
this.poolAddress,
|
|
399
|
+
]),
|
|
400
|
+
decodeFunction: uint256ToBigInt,
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
target: this.poolAddress,
|
|
404
|
+
callData: this.poolIface.encodeFunctionData('liquidity', []),
|
|
405
|
+
decodeFunction: uint128ToBigNumber,
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
target: this.poolAddress,
|
|
409
|
+
callData: this.poolIface.encodeFunctionData('tickSpacing', []),
|
|
410
|
+
decodeFunction: int24ToNumber,
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
target: this.poolAddress,
|
|
414
|
+
callData: this.poolIface.encodeFunctionData('maxLiquidityPerTick', []),
|
|
415
|
+
decodeFunction: uint128ToBigNumber,
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
target: this.poolAddress,
|
|
419
|
+
callData: this.poolIface.encodeFunctionData('globalState', []),
|
|
420
|
+
decodeFunction: decodeGlobalStateV1_1,
|
|
421
|
+
},
|
|
422
|
+
];
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
async fetchStateManually(
|
|
426
|
+
blockNumber: number,
|
|
427
|
+
): Promise<
|
|
428
|
+
[bigint, bigint, DecodedStateMultiCallResultWithRelativeBitmapsV1_1]
|
|
429
|
+
> {
|
|
430
|
+
// Unfortunately I can not unite this call with the next one. For some reason even if pool does not exist
|
|
431
|
+
// call succeeds and makes decoding function to throw. Otherwise, I should rewrite decoders in different which
|
|
432
|
+
// require some time
|
|
433
|
+
const [poolAddress] = (await this.dexHelper.multiWrapper.aggregate<
|
|
434
|
+
string | bigint | BigNumber | number | DecodedGlobalStateV1_1
|
|
435
|
+
>(this.cachedStateMultiCalls.slice(0, 1), blockNumber, MAX_BATCH_SIZE)) as [
|
|
436
|
+
string,
|
|
437
|
+
];
|
|
438
|
+
|
|
439
|
+
if (poolAddress === NULL_ADDRESS) {
|
|
440
|
+
throw new Error('Pool does not exist');
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const [
|
|
444
|
+
balance0,
|
|
445
|
+
balance1,
|
|
446
|
+
liquidity,
|
|
447
|
+
tickSpacing,
|
|
448
|
+
maxLiquidityPerTick,
|
|
449
|
+
globalState,
|
|
450
|
+
] = (await this.dexHelper.multiWrapper.aggregate<
|
|
451
|
+
string | bigint | BigNumber | number | DecodedGlobalStateV1_1
|
|
452
|
+
>(this.cachedStateMultiCalls.slice(1), blockNumber, MAX_BATCH_SIZE)) as [
|
|
453
|
+
bigint,
|
|
454
|
+
bigint,
|
|
455
|
+
BigNumber,
|
|
456
|
+
number,
|
|
457
|
+
BigNumber,
|
|
458
|
+
DecodedGlobalStateV1_1,
|
|
459
|
+
];
|
|
460
|
+
|
|
461
|
+
assert(
|
|
462
|
+
poolAddress.toLowerCase() === this.poolAddress.toLowerCase(),
|
|
463
|
+
`Pool address mismatch: ${poolAddress.toLowerCase()} != ${this.poolAddress.toLowerCase()}`,
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
const currentBitMapIndex = TickTable.position(
|
|
467
|
+
BigInt(BigInt(globalState.tick) / BigInt(tickSpacing)),
|
|
468
|
+
)[0];
|
|
469
|
+
|
|
470
|
+
const leftBitMapIndex = currentBitMapIndex - this.getBitmapRangeToRequest();
|
|
471
|
+
const rightBitMapIndex =
|
|
472
|
+
currentBitMapIndex + this.getBitmapRangeToRequest();
|
|
473
|
+
|
|
474
|
+
const allTickBitMaps = await this.dexHelper.multiWrapper.aggregate(
|
|
475
|
+
_.range(Number(leftBitMapIndex), Number(rightBitMapIndex + 1n)).map(
|
|
476
|
+
index => {
|
|
477
|
+
return {
|
|
478
|
+
target: poolAddress,
|
|
479
|
+
callData: this.poolIface.encodeFunctionData('tickTable', [
|
|
480
|
+
int16(BigInt(index)),
|
|
481
|
+
]),
|
|
482
|
+
decodeFunction: uint256ToBigInt,
|
|
483
|
+
};
|
|
484
|
+
},
|
|
485
|
+
),
|
|
486
|
+
blockNumber,
|
|
487
|
+
MAX_BATCH_SIZE,
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
const tickBitmap: TickBitMapMappingsWithBigNumber[] = [];
|
|
491
|
+
|
|
492
|
+
let globalIndex = 0;
|
|
493
|
+
for (let i = leftBitMapIndex; i <= rightBitMapIndex; i++) {
|
|
494
|
+
const index = Number(int16(i));
|
|
495
|
+
const bitmap = allTickBitMaps[globalIndex];
|
|
496
|
+
globalIndex++;
|
|
497
|
+
if (bitmap == 0n) continue;
|
|
498
|
+
tickBitmap.push({ index: Number(index), value: BigNumber.from(bitmap) });
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const tickIndexes: bigint[] = [];
|
|
502
|
+
|
|
503
|
+
const tickRequests = tickBitmap
|
|
504
|
+
.map(tb => {
|
|
505
|
+
const allBits: MultiCallParams<TickInfoWithBigNumber>[] = [];
|
|
506
|
+
if (tb.value === BN_ZERO) return allBits;
|
|
507
|
+
|
|
508
|
+
_.range(0, 256).forEach(j => {
|
|
509
|
+
if ((tb.value.toBigInt() & (1n << BigInt(j))) > 0n) {
|
|
510
|
+
const populatedTick =
|
|
511
|
+
(BigInt.asIntN(16, BigInt(tb.index) << 8n) + BigInt(j)) *
|
|
512
|
+
BigInt(tickSpacing);
|
|
513
|
+
|
|
514
|
+
tickIndexes.push(populatedTick);
|
|
515
|
+
allBits.push({
|
|
516
|
+
target: poolAddress,
|
|
517
|
+
callData: this.poolIface.encodeFunctionData('ticks', [
|
|
518
|
+
populatedTick,
|
|
519
|
+
]),
|
|
520
|
+
decodeFunction: decodeTicksV1_1,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
return allBits;
|
|
525
|
+
})
|
|
526
|
+
.flat();
|
|
527
|
+
|
|
528
|
+
let ticksValues: TickInfoWithBigNumber[] = [];
|
|
529
|
+
if (this.optimalTickRequestBatchSize) {
|
|
530
|
+
ticksValues = await this.dexHelper.multiWrapper.aggregate(
|
|
531
|
+
tickRequests,
|
|
532
|
+
blockNumber,
|
|
533
|
+
this.optimalTickRequestBatchSize,
|
|
534
|
+
);
|
|
535
|
+
// If we don't know what is optimal number of requests for this pool, we want to try it experimentally and save it
|
|
536
|
+
// Maybe later to consider distant caching
|
|
537
|
+
} else {
|
|
538
|
+
for (const i of _.range(0, MAX_NUMBER_OF_BATCH_REQUEST_HALVING)) {
|
|
539
|
+
const currentBatchSize = MAX_BATCH_SIZE / (+i + 1);
|
|
540
|
+
try {
|
|
541
|
+
// Some of the pools fails with 100 batch size, for them we want to try additionally with reduced batch size
|
|
542
|
+
ticksValues = await this.dexHelper.multiWrapper.aggregate(
|
|
543
|
+
tickRequests,
|
|
544
|
+
blockNumber,
|
|
545
|
+
currentBatchSize,
|
|
546
|
+
);
|
|
547
|
+
this.optimalTickRequestBatchSize = currentBatchSize;
|
|
548
|
+
break;
|
|
549
|
+
} catch (e) {
|
|
550
|
+
if (+i + 1 === MAX_NUMBER_OF_BATCH_REQUEST_HALVING) {
|
|
551
|
+
this.logger.warn(
|
|
552
|
+
`Failed to fetch ticks for pool ${poolAddress} (${this.token0}_${this.token1}) with batch size ${currentBatchSize}`,
|
|
553
|
+
e,
|
|
554
|
+
);
|
|
555
|
+
throw e;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
assert(
|
|
562
|
+
tickIndexes.length === ticksValues.length,
|
|
563
|
+
`Tick indexes mismatch: ${tickIndexes.length} != ${ticksValues.length}`,
|
|
564
|
+
);
|
|
565
|
+
|
|
566
|
+
const ticks: TickInfoMappingsWithBigNumber[] = new Array(
|
|
567
|
+
tickIndexes.length,
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
tickIndexes.forEach((tickIndex, index) => {
|
|
571
|
+
ticks[index] = {
|
|
572
|
+
index: Number(tickIndex),
|
|
573
|
+
value: ticksValues[index],
|
|
574
|
+
};
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
return [
|
|
578
|
+
balance0,
|
|
579
|
+
balance1,
|
|
580
|
+
{
|
|
581
|
+
pool: poolAddress,
|
|
582
|
+
blockTimestamp: BigNumber.from(Date.now()),
|
|
583
|
+
globalState,
|
|
584
|
+
liquidity,
|
|
585
|
+
tickSpacing,
|
|
586
|
+
maxLiquidityPerTick,
|
|
587
|
+
tickBitmap,
|
|
588
|
+
ticks,
|
|
589
|
+
},
|
|
590
|
+
];
|
|
591
|
+
}
|
|
592
|
+
|
|
350
593
|
async generateState(blockNumber: number): Promise<Readonly<PoolStateV1_1>> {
|
|
351
|
-
|
|
352
|
-
|
|
594
|
+
let balance0 = 0n;
|
|
595
|
+
let balance1 = 0n;
|
|
596
|
+
let _state: DecodedStateMultiCallResultWithRelativeBitmapsV1_1;
|
|
597
|
+
if (this.forceManualStateGeneration) {
|
|
598
|
+
[balance0, balance1, _state] = await this.fetchStateManually(blockNumber);
|
|
599
|
+
} else {
|
|
600
|
+
[balance0, balance1, _state] = await this._fetchInitStateMultiStrategies(
|
|
601
|
+
blockNumber,
|
|
602
|
+
);
|
|
603
|
+
}
|
|
353
604
|
|
|
354
605
|
const tickBitmap = {};
|
|
355
606
|
const ticks = {};
|
|
@@ -160,14 +160,15 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
|
|
|
160
160
|
if (this.network !== Network.ZKEVM) return pool;
|
|
161
161
|
|
|
162
162
|
if (
|
|
163
|
-
pool.
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
pool.getStaleState() === null ||
|
|
164
|
+
(pool.getState(blockNumber) === null &&
|
|
165
|
+
blockNumber - pool.getStateBlockNumber() >
|
|
166
|
+
MAX_STALE_STATE_BLOCK_AGE[this.network])
|
|
166
167
|
) {
|
|
167
168
|
/* reload state, on zkEVM this would most likely timeout during request life
|
|
168
169
|
* but would allow to rely on staleState for couple of min for next requests
|
|
169
170
|
*/
|
|
170
|
-
await pool.initialize(blockNumber);
|
|
171
|
+
await pool.initialize(blockNumber, { forceRegenerate: true });
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
return pool;
|
|
@@ -226,6 +227,7 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
|
|
|
226
227
|
this.cacheStateKey,
|
|
227
228
|
this.config.initHash,
|
|
228
229
|
this.config.deployer,
|
|
230
|
+
this.config.forceManualStateGenerate,
|
|
229
231
|
);
|
|
230
232
|
|
|
231
233
|
try {
|
|
@@ -255,10 +257,10 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
|
|
|
255
257
|
e,
|
|
256
258
|
);
|
|
257
259
|
} else {
|
|
258
|
-
// on
|
|
260
|
+
// on unknown error mark as failed and increase retryCount for retry init strategy
|
|
259
261
|
// note: state would be null by default which allows to fallback
|
|
260
262
|
this.logger.warn(
|
|
261
|
-
`${this.dexKey}: Can not generate pool state for srcAddress=${srcAddress}, destAddress=${destAddress}pool fallback to rpc and retry every ${this.config.initRetryFrequency} times, initRetryAttemptCount=${pool.initRetryAttemptCount}`,
|
|
263
|
+
`${this.dexKey}: Can not generate pool state for srcAddress=${srcAddress}, destAddress=${destAddress} pool fallback to rpc and retry every ${this.config.initRetryFrequency} times, initRetryAttemptCount=${pool.initRetryAttemptCount}`,
|
|
262
264
|
e,
|
|
263
265
|
);
|
|
264
266
|
pool.initFailed = true;
|
|
@@ -790,6 +792,7 @@ export class Algebra extends SimpleExchange implements IDex<AlgebraData> {
|
|
|
790
792
|
subgraphURL: this.config.subgraphURL,
|
|
791
793
|
version: this.config.version,
|
|
792
794
|
forceRPC: this.config.forceRPC,
|
|
795
|
+
forceManualStateGenerate: this.config.forceManualStateGenerate,
|
|
793
796
|
};
|
|
794
797
|
return newConfig;
|
|
795
798
|
}
|
|
@@ -33,6 +33,7 @@ export const AlgebraConfig: DexConfigMap<DexParams> = {
|
|
|
33
33
|
uniswapMulticall: '0x61530d6E1c7A47BBB3e48e8b8EdF7569DcFeE121',
|
|
34
34
|
deployer: '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270',
|
|
35
35
|
version: 'v1.1',
|
|
36
|
+
forceManualStateGenerate: true,
|
|
36
37
|
},
|
|
37
38
|
},
|
|
38
39
|
ZyberSwapV3: {
|
package/src/dex/algebra/types.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { BigNumber } from 'ethers';
|
|
|
2
2
|
import { Address, NumberAsString } from '../../types';
|
|
3
3
|
import { TickInfo } from '../uniswap-v3/types';
|
|
4
4
|
|
|
5
|
-
type GlobalStateV1_1 = {
|
|
5
|
+
export type GlobalStateV1_1 = {
|
|
6
6
|
price: bigint; // The square root of the current price in Q64.96 format
|
|
7
7
|
tick: bigint; // The current tick
|
|
8
8
|
fee: bigint; // The current fee in hundredths of a bip, i.e. 1e-6
|
|
@@ -72,6 +72,7 @@ export type DexParams = {
|
|
|
72
72
|
initHash: string;
|
|
73
73
|
version: 'v1.1' | 'v1.9';
|
|
74
74
|
forceRPC?: boolean;
|
|
75
|
+
forceManualStateGenerate?: boolean;
|
|
75
76
|
};
|
|
76
77
|
|
|
77
78
|
export type IAlgebraPoolState = PoolStateV1_1 | PoolState_v1_9;
|
|
@@ -95,7 +96,7 @@ export type TickInfoMappingsWithBigNumber = {
|
|
|
95
96
|
value: TickInfoWithBigNumber;
|
|
96
97
|
};
|
|
97
98
|
|
|
98
|
-
type DecodedGlobalStateV1_1 = {
|
|
99
|
+
export type DecodedGlobalStateV1_1 = {
|
|
99
100
|
price: BigNumber;
|
|
100
101
|
tick: number;
|
|
101
102
|
fee: number;
|
package/src/dex/algebra/utils.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { BytesLike, ethers } from 'ethers';
|
|
1
|
+
import { BigNumber, BytesLike, ethers } from 'ethers';
|
|
2
2
|
import { assert } from 'ts-essentials';
|
|
3
3
|
import { extractSuccessAndValue } from '../../lib/decoders';
|
|
4
4
|
import { MultiResult } from '../../lib/multi-wrapper';
|
|
5
5
|
import {
|
|
6
|
-
|
|
6
|
+
DecodedGlobalStateV1_1,
|
|
7
7
|
DecodedStateMultiCallResultWithRelativeBitmapsV1_1,
|
|
8
8
|
DecodedStateMultiCallResultWithRelativeBitmapsV1_9,
|
|
9
|
+
TickInfoWithBigNumber,
|
|
9
10
|
} from './types';
|
|
10
11
|
|
|
11
12
|
export function decodeStateMultiCallResultWithRelativeBitmapsV1_1(
|
|
@@ -134,3 +135,83 @@ export function decodeStateMultiCallResultWithRelativeBitmapsV1_9(
|
|
|
134
135
|
// But I typed only the ones that are used later
|
|
135
136
|
return decoded as DecodedStateMultiCallResultWithRelativeBitmapsV1_9;
|
|
136
137
|
}
|
|
138
|
+
|
|
139
|
+
export function decodeGlobalStateV1_1(
|
|
140
|
+
result: MultiResult<BytesLike> | BytesLike,
|
|
141
|
+
): DecodedGlobalStateV1_1 {
|
|
142
|
+
const [isSuccess, toDecode] = extractSuccessAndValue(result);
|
|
143
|
+
|
|
144
|
+
assert(
|
|
145
|
+
isSuccess && toDecode !== '0x',
|
|
146
|
+
`decodeGlobalStateV1_1 failed to get decodable result: ${result}`,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const results: DecodedGlobalStateV1_1 = {
|
|
150
|
+
price: BigNumber.from(0),
|
|
151
|
+
tick: 0,
|
|
152
|
+
fee: 0,
|
|
153
|
+
communityFeeToken0: 0,
|
|
154
|
+
communityFeeToken1: 0,
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
[
|
|
158
|
+
results.price,
|
|
159
|
+
results.tick,
|
|
160
|
+
results.fee,
|
|
161
|
+
,
|
|
162
|
+
results.communityFeeToken0,
|
|
163
|
+
results.communityFeeToken1,
|
|
164
|
+
] = ethers.utils.defaultAbiCoder.decode(
|
|
165
|
+
[`uint160`, `int24`, `uint16`, `uint16`, `uint8`, `uint8`, `bool`],
|
|
166
|
+
toDecode,
|
|
167
|
+
);
|
|
168
|
+
// This conversion is not precise, because when we decode, we have more values
|
|
169
|
+
// But used later
|
|
170
|
+
return results;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function decodeTicksV1_1(
|
|
174
|
+
result: MultiResult<BytesLike> | BytesLike,
|
|
175
|
+
): TickInfoWithBigNumber {
|
|
176
|
+
const [isSuccess, toDecode] = extractSuccessAndValue(result);
|
|
177
|
+
|
|
178
|
+
assert(
|
|
179
|
+
isSuccess && toDecode !== '0x',
|
|
180
|
+
`decodeGlobalStateV1_1 failed to get decodable result: ${result}`,
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const results: TickInfoWithBigNumber = {
|
|
184
|
+
liquidityNet: BigNumber.from(0),
|
|
185
|
+
liquidityGross: BigNumber.from(0),
|
|
186
|
+
secondsOutside: 0,
|
|
187
|
+
secondsPerLiquidityOutsideX128: BigNumber.from(0),
|
|
188
|
+
tickCumulativeOutside: BigNumber.from(0),
|
|
189
|
+
initialized: false,
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
[
|
|
193
|
+
results.liquidityGross,
|
|
194
|
+
results.liquidityNet,
|
|
195
|
+
,
|
|
196
|
+
,
|
|
197
|
+
results.tickCumulativeOutside,
|
|
198
|
+
results.secondsPerLiquidityOutsideX128,
|
|
199
|
+
results.secondsOutside,
|
|
200
|
+
results.initialized,
|
|
201
|
+
] = ethers.utils.defaultAbiCoder.decode(
|
|
202
|
+
[
|
|
203
|
+
`uint128`,
|
|
204
|
+
`int128`,
|
|
205
|
+
`uint256`,
|
|
206
|
+
`uint256`,
|
|
207
|
+
`int256`,
|
|
208
|
+
`uint160`,
|
|
209
|
+
`uint32`,
|
|
210
|
+
`bool`,
|
|
211
|
+
],
|
|
212
|
+
toDecode,
|
|
213
|
+
);
|
|
214
|
+
// This conversion is not precise, because when we decode, we have more values
|
|
215
|
+
// But used later
|
|
216
|
+
return results;
|
|
217
|
+
}
|
|
@@ -3,20 +3,22 @@ import { BalancerSwapV2 } from './types';
|
|
|
3
3
|
import { SwapSide } from '../../constants';
|
|
4
4
|
import { BalancerConfig } from './config';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const MAX_UINT256 =
|
|
7
|
+
'115792089237316195423570985008687907853269984665640564039457584007913129639935';
|
|
8
|
+
|
|
9
|
+
const AllBalancerV2Forks = Object.keys(BalancerConfig);
|
|
7
10
|
|
|
8
11
|
export function balancerV2Merge(or: UnoptimizedRate): UnoptimizedRate {
|
|
9
12
|
const fixSwap = (
|
|
10
13
|
rawSwap: OptimalSwapExchange<any>[],
|
|
11
|
-
accumulatedBalancers: { [key: string]: OptimalSwapExchange<any> },
|
|
12
14
|
side: SwapSide,
|
|
13
15
|
): OptimalSwapExchange<any>[] => {
|
|
14
|
-
let optimizedSwap = new Array<OptimalSwapExchange<any>>();
|
|
15
16
|
const newBalancers: { [key: string]: OptimalSwapExchange<any> } = {};
|
|
17
|
+
let optimizedSwap = new Array<OptimalSwapExchange<any>>();
|
|
16
18
|
rawSwap.forEach((s: OptimalSwapExchange<any>) => {
|
|
17
19
|
const exchangeKey = s.exchange.toLowerCase();
|
|
18
20
|
if (AllBalancerV2Forks.some(d => d.toLowerCase() === exchangeKey)) {
|
|
19
|
-
if (!(exchangeKey in
|
|
21
|
+
if (!(exchangeKey in newBalancers)) {
|
|
20
22
|
newBalancers[exchangeKey] = {
|
|
21
23
|
exchange: s.exchange,
|
|
22
24
|
srcAmount: '0',
|
|
@@ -28,33 +30,27 @@ export function balancerV2Merge(or: UnoptimizedRate): UnoptimizedRate {
|
|
|
28
30
|
gasUSD: '0',
|
|
29
31
|
},
|
|
30
32
|
};
|
|
31
|
-
accumulatedBalancers[exchangeKey] = newBalancers[exchangeKey];
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
BigInt(
|
|
35
|
-
BigInt(s.srcAmount)
|
|
34
|
+
newBalancers[exchangeKey].srcAmount = (
|
|
35
|
+
BigInt(newBalancers[exchangeKey].srcAmount) + BigInt(s.srcAmount)
|
|
36
36
|
).toString();
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
BigInt(
|
|
40
|
-
BigInt(s.destAmount)
|
|
38
|
+
newBalancers[exchangeKey].destAmount = (
|
|
39
|
+
BigInt(newBalancers[exchangeKey].destAmount) + BigInt(s.destAmount)
|
|
41
40
|
).toString();
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
parseFloat(accumulatedBalancers[exchangeKey].data.gasUSD) +
|
|
42
|
+
newBalancers[exchangeKey].percent += s.percent;
|
|
43
|
+
newBalancers[exchangeKey].data.exchangeProxy = s.data.exchangeProxy;
|
|
44
|
+
newBalancers[exchangeKey].data.gasUSD = (
|
|
45
|
+
parseFloat(newBalancers[exchangeKey].data.gasUSD) +
|
|
48
46
|
parseFloat(s.data.gasUSD)
|
|
49
47
|
).toFixed(6);
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
newBalancers[exchangeKey].data.swaps.push({
|
|
52
50
|
poolId: s.data.poolId,
|
|
53
51
|
amount: side === SwapSide.SELL ? s.srcAmount : s.destAmount,
|
|
54
52
|
});
|
|
55
|
-
|
|
56
|
-
s.poolAddresses![0],
|
|
57
|
-
);
|
|
53
|
+
newBalancers[exchangeKey].poolAddresses!.push(s.poolAddresses![0]);
|
|
58
54
|
} else {
|
|
59
55
|
optimizedSwap.push(s);
|
|
60
56
|
}
|
|
@@ -63,23 +59,12 @@ export function balancerV2Merge(or: UnoptimizedRate): UnoptimizedRate {
|
|
|
63
59
|
return optimizedSwap;
|
|
64
60
|
};
|
|
65
61
|
|
|
66
|
-
or.bestRoute = or.bestRoute.map(r => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
.map(s => ({
|
|
74
|
-
...s,
|
|
75
|
-
swapExchanges: fixSwap(
|
|
76
|
-
s.swapExchanges,
|
|
77
|
-
accumulatedBalancers,
|
|
78
|
-
or.side,
|
|
79
|
-
),
|
|
80
|
-
}))
|
|
81
|
-
.filter(s => s.swapExchanges.length > 0),
|
|
82
|
-
};
|
|
83
|
-
});
|
|
62
|
+
or.bestRoute = or.bestRoute.map(r => ({
|
|
63
|
+
...r,
|
|
64
|
+
swaps: r.swaps.map(s => ({
|
|
65
|
+
...s,
|
|
66
|
+
swapExchanges: fixSwap(s.swapExchanges, or.side),
|
|
67
|
+
})),
|
|
68
|
+
}));
|
|
84
69
|
return or;
|
|
85
70
|
}
|
|
@@ -24,7 +24,6 @@ const VelodromeV2FactoryABI = [
|
|
|
24
24
|
const velodromeV2FactoryIface = new Interface(VelodromeV2FactoryABI);
|
|
25
25
|
|
|
26
26
|
export class VelodromeV2 extends Solidly {
|
|
27
|
-
|
|
28
27
|
public static dexKeysWithNetwork: { key: string; networks: Network[] }[] =
|
|
29
28
|
getDexKeysWithNetwork(_.pick(SolidlyConfig, ['VelodromeV2']));
|
|
30
29
|
|
|
@@ -44,7 +43,10 @@ export class VelodromeV2 extends Solidly {
|
|
|
44
43
|
protected getFeesMultiCallData(pair: SolidlyPair) {
|
|
45
44
|
const callEntry = {
|
|
46
45
|
target: this.factoryAddress,
|
|
47
|
-
callData: velodromeV2FactoryIface.encodeFunctionData('getFee', [
|
|
46
|
+
callData: velodromeV2FactoryIface.encodeFunctionData('getFee', [
|
|
47
|
+
pair.exchange,
|
|
48
|
+
pair.stable,
|
|
49
|
+
]),
|
|
48
50
|
};
|
|
49
51
|
const callDecoder = (values: any[]) =>
|
|
50
52
|
parseInt(
|
|
@@ -15,7 +15,8 @@ export const NomiswapV2Config: DexConfigMap<DexParams> = {
|
|
|
15
15
|
'0x83eb759f5ea0525124f03d4ac741bb4af0bb1c703d5f694bd42a8bd72e495a01',
|
|
16
16
|
poolGasCost: 120 * 1000,
|
|
17
17
|
feeCode: 0, // this is ignored as Nomiswap uses dynamic fees,
|
|
18
|
-
subgraphURL:
|
|
18
|
+
subgraphURL:
|
|
19
|
+
'https://api.thegraph.com/subgraphs/name/nominex/nomiswap-exchange-subgraph',
|
|
19
20
|
},
|
|
20
21
|
},
|
|
21
22
|
};
|
|
@@ -2,7 +2,11 @@ import dotenv from 'dotenv';
|
|
|
2
2
|
dotenv.config();
|
|
3
3
|
|
|
4
4
|
import { testE2E } from '../../../tests/utils-e2e';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
Tokens,
|
|
7
|
+
Holders,
|
|
8
|
+
NativeTokenSymbols,
|
|
9
|
+
} from '../../../tests/constants-e2e';
|
|
6
10
|
import { Network, ContractMethod, SwapSide } from '../../constants';
|
|
7
11
|
import { StaticJsonRpcProvider } from '@ethersproject/providers';
|
|
8
12
|
import { generateConfig } from '../../config';
|
|
@@ -34,13 +38,7 @@ function testForNetwork(
|
|
|
34
38
|
ContractMethod.megaSwap,
|
|
35
39
|
],
|
|
36
40
|
],
|
|
37
|
-
[
|
|
38
|
-
SwapSide.BUY,
|
|
39
|
-
[
|
|
40
|
-
ContractMethod.simpleBuy,
|
|
41
|
-
ContractMethod.buy,
|
|
42
|
-
],
|
|
43
|
-
],
|
|
41
|
+
[SwapSide.BUY, [ContractMethod.simpleBuy, ContractMethod.buy]],
|
|
44
42
|
]);
|
|
45
43
|
|
|
46
44
|
describe(`${network}`, () => {
|