@paraswap/dex-lib 2.33.4-balancer-v2-multihop.2 → 2.35.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/composed-event-subscriber.js +8 -2
- package/build/composed-event-subscriber.js.map +1 -1
- 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/index.js +2 -0
- package/build/dex/index.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/abi/api3-proxy.json +46 -0
- package/src/abi/api3-server-v1.json +463 -0
- package/src/abi/quick-perps/fast-price-events.json +70 -0
- package/src/abi/quick-perps/fast-price-feed.json +741 -0
- package/src/abi/quick-perps/reader.json +313 -0
- package/src/abi/quick-perps/vault-price-feed.json +323 -0
- package/src/abi/quick-perps/vault.json +1953 -0
- package/src/composed-event-subscriber.ts +16 -11
- 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/index.ts +2 -0
- package/src/dex/quick-perps/config.ts +31 -0
- package/src/dex/quick-perps/fast-price-feed.ts +279 -0
- package/src/dex/quick-perps/pool.ts +372 -0
- package/src/dex/quick-perps/quick-perps-e2e.test.ts +65 -0
- package/src/dex/quick-perps/quick-perps-events.test.ts +101 -0
- package/src/dex/quick-perps/quick-perps-integration.test.ts +153 -0
- package/src/dex/quick-perps/quick-perps.ts +292 -0
- package/src/dex/quick-perps/types.ts +97 -0
- package/src/dex/quick-perps/usdq.ts +83 -0
- package/src/dex/quick-perps/vault-price-feed.ts +322 -0
- package/src/dex/quick-perps/vault-utils.ts +53 -0
- package/src/dex/quick-perps/vault.ts +290 -0
- 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/api3-feed.ts +140 -0
- package/src/lib/decoders.ts +13 -0
- package/src/stateful-event-subscriber.ts +8 -0
- package/tests/constants-e2e.ts +29 -0
- package/tests/tenderly-simulation.ts +46 -2
- package/tests/utils-e2e.ts +18 -10
- 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/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/src/dex/balancer-v2/balancer-v2-optimizer.test.ts +0 -226
|
@@ -110,17 +110,22 @@ export abstract class ComposedEventSubscriber<
|
|
|
110
110
|
.call({}, blockNumber)
|
|
111
111
|
).returnData;
|
|
112
112
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
try {
|
|
114
|
+
const stateParts = await Promise.all(
|
|
115
|
+
this.parts.map((p, i) =>
|
|
116
|
+
p.generateState(
|
|
117
|
+
returnData.slice(...this.multiCallSlices[i]),
|
|
118
|
+
blockNumber,
|
|
119
|
+
),
|
|
118
120
|
),
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
)
|
|
121
|
+
);
|
|
122
|
+
return this.parts.reduce(
|
|
123
|
+
(acc, p, i) => p.lens.set(stateParts[i])(acc),
|
|
124
|
+
this.blankState,
|
|
125
|
+
);
|
|
126
|
+
} catch (e) {
|
|
127
|
+
this.logger.error(`Error generating state: ${e}`);
|
|
128
|
+
throw e;
|
|
129
|
+
}
|
|
125
130
|
}
|
|
126
131
|
}
|
package/src/config.ts
CHANGED
|
@@ -317,6 +317,36 @@ const baseConfigs: { [network: number]: BaseConfig } = {
|
|
|
317
317
|
rpcPollingBlocksBackToTriggerUpdate: 3,
|
|
318
318
|
forceRpcFallbackDexs: [],
|
|
319
319
|
},
|
|
320
|
+
|
|
321
|
+
[Network.ZKEVM]: {
|
|
322
|
+
network: Network.ZKEVM,
|
|
323
|
+
networkName: 'Polygon zkEVM',
|
|
324
|
+
isTestnet: false,
|
|
325
|
+
nativeTokenName: 'Ether',
|
|
326
|
+
nativeTokenSymbol: 'ETH',
|
|
327
|
+
wrappedNativeTokenAddress: '0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9',
|
|
328
|
+
hasEIP1559: true,
|
|
329
|
+
augustusAddress: '0xB83B554730d29cE4Cb55BB42206c3E2c03E4A40A',
|
|
330
|
+
augustusRFQAddress: '0x7Ee1F7fa4C0b2eDB0Fdd5944c14A07167700486E',
|
|
331
|
+
tokenTransferProxyAddress: '0xc8a21fcd5a100c3ecc037c97e2f9c53a8d3a02a1',
|
|
332
|
+
multicallV2Address: '0x6cA478C852DfA8941FC819fDf248606eA04780B6',
|
|
333
|
+
privateHttpProvider: process.env.HTTP_PROVIDER_1101,
|
|
334
|
+
adapterAddresses: {
|
|
335
|
+
PolygonZkEvmAdapter01: '0xd63B7691dD98fa89A2ea5e1604700489c585aa7B',
|
|
336
|
+
PolygonZkEvmBuyAdapter: '0xe2137168CdA486a2555E16c597905854C84F9127',
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
rpcPollingMaxAllowedStateDelayInBlocks: 0,
|
|
340
|
+
rpcPollingBlocksBackToTriggerUpdate: 0,
|
|
341
|
+
hashFlowAuthToken: process.env.API_KEY_HASHFLOW_AUTH_TOKEN || '',
|
|
342
|
+
hashFlowDisabledMMs:
|
|
343
|
+
process.env[`HASHFLOW_DISABLED_MMS_10`]?.split(',') || [],
|
|
344
|
+
uniswapV3EventLoggingSampleRate: 0,
|
|
345
|
+
rfqConfigs: {},
|
|
346
|
+
forceRpcFallbackDexs: [],
|
|
347
|
+
// FIXME: Not set properly
|
|
348
|
+
uniswapV2ExchangeRouterAddress: '',
|
|
349
|
+
},
|
|
320
350
|
};
|
|
321
351
|
|
|
322
352
|
// Should not be used, except by internal test code
|
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
} from '../../../tests/utils';
|
|
15
15
|
import { Tokens } from '../../../tests/constants-e2e';
|
|
16
16
|
import { Address } from '@paraswap/core';
|
|
17
|
+
import { AlgebraEventPoolV1_1 } from './algebra-pool-v1_1';
|
|
18
|
+
import { DecodedStateMultiCallResultWithRelativeBitmapsV1_1 } from './types';
|
|
17
19
|
|
|
18
20
|
function getReaderCalldata(
|
|
19
21
|
exchangeAddress: string,
|
|
@@ -432,5 +434,125 @@ describe('Algebra', function () {
|
|
|
432
434
|
);
|
|
433
435
|
}
|
|
434
436
|
});
|
|
437
|
+
|
|
438
|
+
it('both generate state result match', async function () {
|
|
439
|
+
const pool = (await algebra.getPool(
|
|
440
|
+
tokens[srcTokenSymbol].address,
|
|
441
|
+
tokens[destTokenSymbol].address,
|
|
442
|
+
blockNumber,
|
|
443
|
+
)) as AlgebraEventPoolV1_1;
|
|
444
|
+
|
|
445
|
+
const [balance0, balance1, stateMulticallFull] =
|
|
446
|
+
await pool.fetchPoolStateSingleStep(blockNumber);
|
|
447
|
+
|
|
448
|
+
const stateMulticall = {
|
|
449
|
+
pool: stateMulticallFull.pool.toLowerCase(),
|
|
450
|
+
globalState: {
|
|
451
|
+
price: stateMulticallFull.globalState.price,
|
|
452
|
+
tick: stateMulticallFull.globalState.tick,
|
|
453
|
+
fee: stateMulticallFull.globalState.fee,
|
|
454
|
+
communityFeeToken0: stateMulticallFull.globalState.communityFeeToken0,
|
|
455
|
+
communityFeeToken1: stateMulticallFull.globalState.communityFeeToken1,
|
|
456
|
+
},
|
|
457
|
+
liquidity: stateMulticallFull.liquidity,
|
|
458
|
+
tickSpacing: stateMulticallFull.tickSpacing,
|
|
459
|
+
maxLiquidityPerTick: stateMulticallFull.maxLiquidityPerTick,
|
|
460
|
+
tickBitmap: stateMulticallFull.tickBitmap.map(t => ({
|
|
461
|
+
index: t.index,
|
|
462
|
+
value: t.value,
|
|
463
|
+
})),
|
|
464
|
+
ticks: stateMulticallFull.ticks.map(t => ({
|
|
465
|
+
index: t.index,
|
|
466
|
+
value: {
|
|
467
|
+
liquidityNet: t.value.liquidityNet,
|
|
468
|
+
liquidityGross: t.value.liquidityGross,
|
|
469
|
+
secondsOutside: t.value.secondsOutside,
|
|
470
|
+
secondsPerLiquidityOutsideX128:
|
|
471
|
+
t.value.secondsPerLiquidityOutsideX128,
|
|
472
|
+
tickCumulativeOutside: t.value.tickCumulativeOutside,
|
|
473
|
+
initialized: t.value.initialized,
|
|
474
|
+
},
|
|
475
|
+
})),
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
const stateMulticallWithBalance = [balance0, balance1, stateMulticall];
|
|
479
|
+
const stateManually = await pool.fetchStateManually(blockNumber);
|
|
480
|
+
// @ts-ignore
|
|
481
|
+
delete stateManually[2]['blockTimestamp'];
|
|
482
|
+
stateManually[2].pool = stateManually[2].pool.toLowerCase();
|
|
483
|
+
|
|
484
|
+
expect(stateMulticallWithBalance).toStrictEqual(stateManually);
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
describe('ZKEVM', () => {
|
|
489
|
+
const network = Network.ZKEVM;
|
|
490
|
+
const dexHelper = new DummyDexHelper(network);
|
|
491
|
+
|
|
492
|
+
beforeAll(async () => {
|
|
493
|
+
blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
|
|
494
|
+
algebra = new Algebra(network, dexKey, dexHelper);
|
|
495
|
+
if (algebra.initializePricing) {
|
|
496
|
+
await algebra.initializePricing(blockNumber);
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
it('WETH/DAI generate state is working for problematic pool', async function () {
|
|
501
|
+
const pool = (await algebra.getPool(
|
|
502
|
+
'0x4F9A0e7FD2Bf6067db6994CF12E4495Df938E6e9',
|
|
503
|
+
'0xc5015b9d9161dca7e18e32f6f25c4ad850731fd4',
|
|
504
|
+
blockNumber,
|
|
505
|
+
)) as AlgebraEventPoolV1_1;
|
|
506
|
+
|
|
507
|
+
const stateManually = await pool.fetchStateManually(blockNumber);
|
|
508
|
+
// We can not compare with usual way, because this pool can not be requested normally
|
|
509
|
+
expect(Array.isArray(stateManually)).toBeTruthy();
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
it('WETH/MATIC generate state is working for problematic pool', async function () {
|
|
513
|
+
const pool = (await algebra.getPool(
|
|
514
|
+
'0x4f9a0e7fd2bf6067db6994cf12e4495df938e6e9',
|
|
515
|
+
'0xa2036f0538221a77a3937f1379699f44945018d0',
|
|
516
|
+
blockNumber,
|
|
517
|
+
)) as AlgebraEventPoolV1_1;
|
|
518
|
+
|
|
519
|
+
const stateManually = await pool.fetchStateManually(blockNumber);
|
|
520
|
+
// We can not compare with usual way, because this pool can not be requested normally
|
|
521
|
+
expect(Array.isArray(stateManually)).toBeTruthy();
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
it('stMATIC/WETH generate state is working for problematic pool', async function () {
|
|
525
|
+
const pool = (await algebra.getPool(
|
|
526
|
+
'0x83b874c1e09d316059d929da402dcb1a98e92082',
|
|
527
|
+
'0x4f9a0e7fd2bf6067db6994cf12e4495df938e6e9',
|
|
528
|
+
blockNumber,
|
|
529
|
+
)) as AlgebraEventPoolV1_1;
|
|
530
|
+
|
|
531
|
+
const stateManually = await pool.fetchStateManually(blockNumber);
|
|
532
|
+
// We can not compare with usual way, because this pool can not be requested normally
|
|
533
|
+
expect(Array.isArray(stateManually)).toBeTruthy();
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
it('WETH/USDC generate state is working for problematic pool', async function () {
|
|
537
|
+
const pool = (await algebra.getPool(
|
|
538
|
+
'0x4f9a0e7fd2bf6067db6994cf12e4495df938e6e9',
|
|
539
|
+
'0xa8ce8aee21bc2a48a5ef670afcc9274c7bbbc035',
|
|
540
|
+
blockNumber,
|
|
541
|
+
)) as AlgebraEventPoolV1_1;
|
|
542
|
+
|
|
543
|
+
const stateManually = await pool.fetchStateManually(blockNumber);
|
|
544
|
+
// We can not compare with usual way, because this pool can not be requested normally
|
|
545
|
+
expect(Array.isArray(stateManually)).toBeTruthy();
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
it('recognize pool does not exist error', async function () {
|
|
549
|
+
const pool = (await algebra.getPool(
|
|
550
|
+
'0x8aaebb46e1742f4623e6e1621f909f01846ca5e2',
|
|
551
|
+
'0xf9ed88937b2d82707d0eabd8c3d9aa4870b714d3',
|
|
552
|
+
blockNumber,
|
|
553
|
+
)) as AlgebraEventPoolV1_1;
|
|
554
|
+
|
|
555
|
+
expect(pool).toBeNull();
|
|
556
|
+
});
|
|
435
557
|
});
|
|
436
558
|
});
|
|
@@ -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;
|