@paraswap/dex-lib 2.16.0 → 2.16.1-generate-state-latest.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/composed-event-subscriber.d.ts +2 -2
- package/build/composed-event-subscriber.js +9 -4
- package/build/composed-event-subscriber.js.map +1 -1
- package/build/dex/aave-v1/aave-v1.d.ts +1 -1
- package/build/dex/aave-v1/aave-v1.js +1 -1
- package/build/dex/aave-v1/aave-v1.js.map +1 -1
- package/build/dex/aave-v2/aave-v2.d.ts +1 -1
- package/build/dex/aave-v2/aave-v2.js +1 -1
- package/build/dex/aave-v2/aave-v2.js.map +1 -1
- package/build/dex/aave-v3/aave-v3.d.ts +1 -1
- package/build/dex/aave-v3/aave-v3.js +1 -1
- package/build/dex/aave-v3/aave-v3.js.map +1 -1
- package/build/dex/aave-v3/tokens/arbitrum.json +50 -0
- package/build/dex/aave-v3/tokens/avalanche.json +74 -0
- package/build/dex/aave-v3/tokens/fantom.json +62 -0
- package/build/dex/aave-v3/tokens/optimism.json +50 -0
- package/build/dex/aave-v3/tokens/polygon.json +116 -0
- package/build/dex/aave-v3/utils.d.ts +1 -1
- package/build/dex/aave-v3/utils.js.map +1 -1
- package/build/dex/balancer-v1/balancer-v1-pool.d.ts +2 -2
- package/build/dex/balancer-v1/balancer-v1-pool.js +5 -1
- package/build/dex/balancer-v1/balancer-v1-pool.js.map +1 -1
- package/build/dex/balancer-v1/balancer-v1.d.ts +1 -1
- package/build/dex/balancer-v1/balancer-v1.js +7 -4
- package/build/dex/balancer-v1/balancer-v1.js.map +1 -1
- package/build/dex/balancer-v1/utils.d.ts +3 -1
- package/build/dex/balancer-v1/utils.js +18 -5
- package/build/dex/balancer-v1/utils.js.map +1 -1
- package/build/dex/balancer-v2/balancer-v2.d.ts +10 -5
- package/build/dex/balancer-v2/balancer-v2.js +15 -10
- package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
- package/build/dex/camelot/camelot.d.ts +2 -2
- package/build/dex/camelot/camelot.js +15 -6
- package/build/dex/camelot/camelot.js.map +1 -1
- package/build/dex/curve-v1/curve-v1.d.ts +1 -1
- package/build/dex/curve-v1/curve-v1.js +5 -8
- package/build/dex/curve-v1/curve-v1.js.map +1 -1
- package/build/dex/curve-v1/pools/curve-metapool.d.ts +2 -2
- package/build/dex/curve-v1/pools/curve-metapool.js +12 -4
- package/build/dex/curve-v1/pools/curve-metapool.js.map +1 -1
- package/build/dex/curve-v1/pools/curve-pool.d.ts +3 -3
- package/build/dex/curve-v1/pools/curve-pool.js +13 -4
- package/build/dex/curve-v1/pools/curve-pool.js.map +1 -1
- package/build/dex/curve-v1/pools/getstate-multicall.d.ts +6 -1
- package/build/dex/curve-v1/pools/getstate-multicall.js +32 -25
- package/build/dex/curve-v1/pools/getstate-multicall.js.map +1 -1
- package/build/dex/curve-v1-factory/curve-v1-factory.d.ts +3 -3
- package/build/dex/curve-v1-factory/curve-v1-factory.js +4 -4
- package/build/dex/curve-v1-factory/curve-v1-factory.js.map +1 -1
- package/build/dex/curve-v1-factory/curve-v1-pool-manager.d.ts +1 -1
- package/build/dex/curve-v1-factory/curve-v1-pool-manager.js +1 -1
- package/build/dex/curve-v1-factory/curve-v1-pool-manager.js.map +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/custom-pool-polling.d.ts +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/custom-pool-polling.js.map +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.d.ts +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.js.map +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.d.ts +4 -4
- package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.js +5 -15
- package/build/dex/curve-v1-factory/state-polling-pools/polling-manager.js.map +1 -1
- package/build/dex/curve-v1-factory/state-polling-pools/pool-polling-base.d.ts +1 -1
- package/build/dex/curve-v1-factory/types.d.ts +1 -1
- package/build/dex/generic-rfq/generic-rfq.d.ts +1 -1
- package/build/dex/generic-rfq/generic-rfq.js +1 -1
- package/build/dex/generic-rfq/generic-rfq.js.map +1 -1
- package/build/dex/generic-rfq/utils.js +1 -1
- package/build/dex/generic-rfq/utils.js.map +1 -1
- package/build/dex/gmx/gmx.d.ts +1 -1
- package/build/dex/gmx/gmx.js +1 -1
- package/build/dex/gmx/gmx.js.map +1 -1
- package/build/dex/gmx/pool.js +5 -4
- package/build/dex/gmx/pool.js.map +1 -1
- package/build/dex/idex.d.ts +1 -1
- package/build/dex/jarvis-v6/jarvis-v6-events.d.ts +4 -3
- package/build/dex/jarvis-v6/jarvis-v6-events.js +8 -4
- package/build/dex/jarvis-v6/jarvis-v6-events.js.map +1 -1
- package/build/dex/jarvis-v6/jarvis-v6.d.ts +1 -1
- package/build/dex/jarvis-v6/jarvis-v6.js +12 -8
- package/build/dex/jarvis-v6/jarvis-v6.js.map +1 -1
- package/build/dex/jarvis-v6/utils.d.ts +2 -1
- package/build/dex/jarvis-v6/utils.js +15 -6
- package/build/dex/jarvis-v6/utils.js.map +1 -1
- package/build/dex/kyberdmm/kyberdmm.js +4 -1
- package/build/dex/kyberdmm/kyberdmm.js.map +1 -1
- package/build/dex/kyberdmm/pool.d.ts +2 -2
- package/build/dex/kyberdmm/pool.js +21 -20
- package/build/dex/kyberdmm/pool.js.map +1 -1
- package/build/dex/maker-psm/maker-psm.d.ts +3 -3
- package/build/dex/maker-psm/maker-psm.js +35 -27
- package/build/dex/maker-psm/maker-psm.js.map +1 -1
- package/build/dex/maverick-v1/maverick-v1-pool.d.ts +3 -5
- package/build/dex/maverick-v1/maverick-v1-pool.js +27 -38
- package/build/dex/maverick-v1/maverick-v1-pool.js.map +1 -1
- package/build/dex/maverick-v1/maverick-v1.d.ts +2 -2
- package/build/dex/maverick-v1/maverick-v1.js +8 -8
- package/build/dex/maverick-v1/maverick-v1.js.map +1 -1
- package/build/dex/nerve/nerve-pool.d.ts +2 -2
- package/build/dex/nerve/nerve-pool.js +28 -25
- package/build/dex/nerve/nerve-pool.js.map +1 -1
- package/build/dex/nerve/nerve.d.ts +2 -2
- package/build/dex/nerve/nerve.js +5 -5
- package/build/dex/nerve/nerve.js.map +1 -1
- package/build/dex/platypus/platypus.d.ts +3 -3
- package/build/dex/platypus/platypus.js +6 -5
- package/build/dex/platypus/platypus.js.map +1 -1
- package/build/dex/swaap-v1/config.d.ts +1 -1
- package/build/dex/swaap-v1/config.js +2 -2
- package/build/dex/swaap-v1/swaap-v1-pool.d.ts +3 -3
- package/build/dex/swaap-v1/swaap-v1-pool.js +15 -9
- package/build/dex/swaap-v1/swaap-v1-pool.js.map +1 -1
- package/build/dex/swaap-v1/swaap-v1.d.ts +2 -2
- package/build/dex/swaap-v1/swaap-v1.js +11 -8
- package/build/dex/swaap-v1/swaap-v1.js.map +1 -1
- package/build/dex/synthetix/synthetix-state.js +1 -1
- package/build/dex/synthetix/synthetix-state.js.map +1 -1
- package/build/dex/synthetix/synthetix.d.ts +1 -1
- package/build/dex/synthetix/synthetix.js +5 -4
- package/build/dex/synthetix/synthetix.js.map +1 -1
- package/build/dex/test-dex/config.d.ts +4 -0
- package/build/dex/test-dex/config.js +15 -0
- package/build/dex/test-dex/config.js.map +1 -0
- package/build/dex/test-dex/test-dex-pool.d.ts +39 -0
- package/build/dex/test-dex/test-dex-pool.js +63 -0
- package/build/dex/test-dex/test-dex-pool.js.map +1 -0
- package/build/dex/test-dex/test-dex.d.ts +37 -0
- package/build/dex/test-dex/test-dex.js +126 -0
- package/build/dex/test-dex/test-dex.js.map +1 -0
- package/build/dex/test-dex/types.d.ts +6 -0
- package/build/dex/test-dex/types.js +3 -0
- package/build/dex/test-dex/types.js.map +1 -0
- package/build/dex/uniswap-v2/uniswap-v2.d.ts +2 -2
- package/build/dex/uniswap-v2/uniswap-v2.js +15 -10
- package/build/dex/uniswap-v2/uniswap-v2.js.map +1 -1
- package/build/dex/uniswap-v3/uniswap-v3-pool.d.ts +3 -3
- package/build/dex/uniswap-v3/uniswap-v3-pool.js +33 -27
- package/build/dex/uniswap-v3/uniswap-v3-pool.js.map +1 -1
- package/build/dex/uniswap-v3/uniswap-v3.d.ts +2 -2
- package/build/dex/uniswap-v3/uniswap-v3.js +4 -3
- package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
- package/build/dex/woo-fi-v2/woo-fi-math.d.ts +16 -0
- package/build/dex/woo-fi-v2/woo-fi-math.js +137 -0
- package/build/dex/woo-fi-v2/woo-fi-math.js.map +1 -0
- package/build/dex/woo-fi-v2/woo-fi-v2.d.ts +1 -1
- package/build/dex/woo-fi-v2/woo-fi-v2.js +1 -1
- package/build/dex/woo-fi-v2/woo-fi-v2.js.map +1 -1
- package/build/implementations/local-paraswap-sdk.js +1 -2
- package/build/implementations/local-paraswap-sdk.js.map +1 -1
- package/build/lib/generics-events-subscribers/erc20-event-subscriber.d.ts +2 -2
- package/build/lib/generics-events-subscribers/erc20-event-subscriber.js +17 -12
- package/build/lib/generics-events-subscribers/erc20-event-subscriber.js.map +1 -1
- package/build/lib/multi-wrapper.d.ts +5 -1
- package/build/lib/multi-wrapper.js +21 -2
- package/build/lib/multi-wrapper.js.map +1 -1
- package/build/lib/tokens/balancer-fetcher.d.ts +5 -1
- package/build/lib/tokens/balancer-fetcher.js +7 -9
- package/build/lib/tokens/balancer-fetcher.js.map +1 -1
- package/build/pricing-helper.d.ts +1 -1
- package/build/pricing-helper.js +1 -1
- package/build/pricing-helper.js.map +1 -1
- package/build/stateful-event-subscriber.d.ts +7 -3
- package/build/stateful-event-subscriber.js +25 -22
- package/build/stateful-event-subscriber.js.map +1 -1
- package/build/utils.d.ts +2 -2
- package/build/utils.js +1 -1
- package/build/utils.js.map +1 -1
- package/dex-template/__DexName__.ts.template +3 -1
- package/package.json +1 -1
- package/src/composed-event-subscriber.ts +24 -13
- package/src/dex/aave-v1/aave-v1.ts +1 -1
- package/src/dex/aave-v2/aave-v2.ts +1 -1
- package/src/dex/aave-v3/aave-v3.ts +3 -1
- package/src/dex/aave-v3/utils.ts +3 -3
- package/src/dex/balancer-v1/balancer-v1-pool.ts +18 -9
- package/src/dex/balancer-v1/balancer-v1.ts +13 -8
- package/src/dex/balancer-v1/utils.ts +36 -7
- package/src/dex/balancer-v2/balancer-v2.ts +42 -25
- package/src/dex/camelot/camelot.ts +29 -10
- package/src/dex/curve-v1/curve-v1.ts +11 -11
- package/src/dex/curve-v1/pools/curve-metapool.ts +23 -7
- package/src/dex/curve-v1/pools/curve-pool.ts +29 -8
- package/src/dex/curve-v1/pools/getstate-multicall.ts +83 -56
- package/src/dex/curve-v1-factory/curve-v1-factory.ts +4 -4
- package/src/dex/curve-v1-factory/curve-v1-pool-manager.ts +1 -1
- package/src/dex/curve-v1-factory/state-polling-pools/custom-pool-polling.ts +1 -1
- package/src/dex/curve-v1-factory/state-polling-pools/factory-pool-polling.ts +1 -1
- package/src/dex/curve-v1-factory/state-polling-pools/polling-manager.ts +5 -16
- package/src/dex/curve-v1-factory/state-polling-pools/pool-polling-base.ts +1 -1
- package/src/dex/curve-v1-factory/types.ts +1 -1
- package/src/dex/generic-rfq/generic-rfq.ts +3 -1
- package/src/dex/generic-rfq/utils.ts +1 -1
- package/src/dex/gmx/gmx.ts +1 -1
- package/src/dex/gmx/pool.ts +9 -4
- package/src/dex/idex.ts +1 -1
- package/src/dex/jarvis-v6/jarvis-v6-events.ts +17 -6
- package/src/dex/jarvis-v6/jarvis-v6.ts +17 -15
- package/src/dex/jarvis-v6/utils.ts +21 -9
- package/src/dex/kyberdmm/kyberdmm.ts +4 -1
- package/src/dex/kyberdmm/pool.ts +32 -24
- package/src/dex/maker-psm/maker-psm.ts +69 -47
- package/src/dex/maverick-v1/maverick-v1-pool.ts +50 -38
- package/src/dex/maverick-v1/maverick-v1.ts +12 -8
- package/src/dex/nerve/nerve-pool.ts +42 -30
- package/src/dex/nerve/nerve.ts +9 -5
- package/src/dex/platypus/platypus.ts +11 -7
- package/src/dex/swaap-v1/config.ts +1 -1
- package/src/dex/swaap-v1/swaap-v1-pool.ts +23 -14
- package/src/dex/swaap-v1/swaap-v1.ts +21 -14
- package/src/dex/synthetix/synthetix-state.ts +3 -3
- package/src/dex/synthetix/synthetix.ts +5 -4
- package/src/dex/uniswap-v2/uniswap-v2.ts +27 -13
- package/src/dex/uniswap-v3/uniswap-v3-pool.ts +43 -39
- package/src/dex/uniswap-v3/uniswap-v3.ts +5 -4
- package/src/dex/woo-fi-v2/woo-fi-v2.ts +3 -1
- package/src/implementations/local-paraswap-sdk.ts +1 -2
- package/src/lib/generics-events-subscribers/erc20-event-subscriber.ts +29 -18
- package/src/lib/multi-wrapper.ts +41 -2
- package/src/lib/tokens/balancer-fetcher.ts +23 -19
- package/src/pricing-helper.ts +5 -2
- package/src/stateful-event-subscriber.ts +35 -28
- package/src/utils.ts +3 -4
- package/tests/utils.test.ts +44 -0
|
@@ -113,7 +113,7 @@ export class UniswapV3
|
|
|
113
113
|
// To receive revert reasons
|
|
114
114
|
this.dexHelper.web3Provider.eth.handleRevert = false;
|
|
115
115
|
|
|
116
|
-
//
|
|
116
|
+
// Normalize once all config addresses and use across all scenarios
|
|
117
117
|
this.config = this._toLowerForAllConfigAddresses();
|
|
118
118
|
|
|
119
119
|
this.notExistingPoolSetKey =
|
|
@@ -133,7 +133,7 @@ export class UniswapV3
|
|
|
133
133
|
return `${this.dexKey}_${tokenAddresses}_${fee}`;
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
async initializePricing(blockNumber: number) {
|
|
136
|
+
async initializePricing(blockNumber: number | 'latest' = 'latest') {
|
|
137
137
|
// This is only for testing, because cold pool fetching is goes out of
|
|
138
138
|
// FETCH_POOL_INDENTIFIER_TIMEOUT range
|
|
139
139
|
await Promise.all(
|
|
@@ -168,7 +168,7 @@ export class UniswapV3
|
|
|
168
168
|
srcAddress: Address,
|
|
169
169
|
destAddress: Address,
|
|
170
170
|
fee: bigint,
|
|
171
|
-
blockNumber: number,
|
|
171
|
+
blockNumber: number | 'latest',
|
|
172
172
|
): Promise<UniswapV3EventPool | null> {
|
|
173
173
|
let pool =
|
|
174
174
|
this.eventPools[this.getPoolIdentifier(srcAddress, destAddress, fee)];
|
|
@@ -350,7 +350,8 @@ export class UniswapV3
|
|
|
350
350
|
[],
|
|
351
351
|
);
|
|
352
352
|
|
|
353
|
-
const balances = await getBalances(this.dexHelper.multiWrapper, requests)
|
|
353
|
+
const balances = (await getBalances(this.dexHelper.multiWrapper, requests))
|
|
354
|
+
.balances;
|
|
354
355
|
|
|
355
356
|
pools = pools.filter((pool, index) => {
|
|
356
357
|
const balance = balances[index].amounts[DEFAULT_ID_ERC20_AS_STRING];
|
|
@@ -106,7 +106,9 @@ export class WooFiV2 extends SimpleExchange implements IDex<WooFiV2Data> {
|
|
|
106
106
|
return this._baseTokens;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
async initializePricing(
|
|
109
|
+
async initializePricing(
|
|
110
|
+
blockNumber: number | 'latest' = 'latest',
|
|
111
|
+
): Promise<void> {
|
|
110
112
|
await this.initializeTokensAndAddresses();
|
|
111
113
|
this._initializePollingPool();
|
|
112
114
|
}
|
|
@@ -76,8 +76,7 @@ export class LocalParaswapSDK implements IParaSwapSDK {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
async initializePricing() {
|
|
79
|
-
|
|
80
|
-
await this.pricingHelper.initialize(blockNumber, [this.dexKey]);
|
|
79
|
+
await this.pricingHelper.initialize('latest', [this.dexKey]);
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
async releaseResources() {
|
|
@@ -2,7 +2,10 @@ import _ from 'lodash';
|
|
|
2
2
|
import { LogDescription } from '@ethersproject/abi';
|
|
3
3
|
import { DeepReadonly } from 'ts-essentials';
|
|
4
4
|
import { IDexHelper } from '../../dex-helper';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
StatefulEventSubscriber,
|
|
7
|
+
StateWithBlock,
|
|
8
|
+
} from '../../stateful-event-subscriber';
|
|
6
9
|
import { Log, BlockHeader, Address } from '../../types';
|
|
7
10
|
import { erc20Iface } from '../utils-interfaces';
|
|
8
11
|
import {
|
|
@@ -108,10 +111,12 @@ export class ERC20EventSubscriber extends StatefulEventSubscriber<ERC20StateMap>
|
|
|
108
111
|
blockHeader: Readonly<BlockHeader>,
|
|
109
112
|
): Promise<DeepReadonly<ERC20StateMap> | null> {
|
|
110
113
|
const _state = _.cloneDeep(state);
|
|
111
|
-
|
|
114
|
+
const newState = await super.processBlockLogs(_state, logs, blockHeader);
|
|
112
115
|
if (!newState) {
|
|
113
116
|
this.logger.warn('received empty state generate new one');
|
|
114
|
-
|
|
117
|
+
const newStateWithBn = await this.generateState('latest');
|
|
118
|
+
this.setState(newStateWithBn.state, newStateWithBn.blockNumber);
|
|
119
|
+
return newStateWithBn.state;
|
|
115
120
|
}
|
|
116
121
|
|
|
117
122
|
return newState;
|
|
@@ -153,7 +158,7 @@ export class ERC20EventSubscriber extends StatefulEventSubscriber<ERC20StateMap>
|
|
|
153
158
|
blockNumber,
|
|
154
159
|
);
|
|
155
160
|
|
|
156
|
-
return balances[0];
|
|
161
|
+
return balances.balances[0];
|
|
157
162
|
}
|
|
158
163
|
|
|
159
164
|
async subscribeToWalletBalanceChange(
|
|
@@ -185,7 +190,9 @@ export class ERC20EventSubscriber extends StatefulEventSubscriber<ERC20StateMap>
|
|
|
185
190
|
this.setState(state, blockNumber);
|
|
186
191
|
}
|
|
187
192
|
|
|
188
|
-
async generateState(
|
|
193
|
+
async generateState(
|
|
194
|
+
blockNumber: number | 'latest',
|
|
195
|
+
): Promise<StateWithBlock<ERC20StateMap>> {
|
|
189
196
|
const request = Array.from(this.walletAddresses).reduce((acc, wallet) => {
|
|
190
197
|
acc.push({
|
|
191
198
|
owner: wallet,
|
|
@@ -202,22 +209,26 @@ export class ERC20EventSubscriber extends StatefulEventSubscriber<ERC20StateMap>
|
|
|
202
209
|
return acc;
|
|
203
210
|
}, [] as BalanceRequest[]);
|
|
204
211
|
|
|
205
|
-
const
|
|
212
|
+
const balancesAndBn = await getBalances(
|
|
206
213
|
this.dexHelper.multiWrapper,
|
|
207
214
|
request,
|
|
208
215
|
blockNumber,
|
|
209
216
|
);
|
|
210
|
-
return
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
return {
|
|
218
|
+
blockNumber: balancesAndBn.blockNumber,
|
|
219
|
+
|
|
220
|
+
state: balancesAndBn.balances.reduce((acc, balance) => {
|
|
221
|
+
acc[balance.owner] = {
|
|
222
|
+
balance: balance.amounts[DEFAULT_ID_ERC20_AS_STRING],
|
|
223
|
+
};
|
|
224
|
+
this.dexHelper.cache.hset(
|
|
225
|
+
this.mapKey,
|
|
226
|
+
balance.owner,
|
|
227
|
+
balance.amounts[DEFAULT_ID_ERC20_AS_STRING].toString(),
|
|
228
|
+
);
|
|
229
|
+
return acc;
|
|
230
|
+
}, {} as ERC20StateMap),
|
|
231
|
+
};
|
|
221
232
|
}
|
|
222
233
|
|
|
223
234
|
async getBalance(wallet: Address, blockNumber: number): Promise<bigint> {
|
|
@@ -249,7 +260,7 @@ export class ERC20EventSubscriber extends StatefulEventSubscriber<ERC20StateMap>
|
|
|
249
260
|
);
|
|
250
261
|
const balance = await this.getBalanceRPC(wallet, blockNumber);
|
|
251
262
|
|
|
252
|
-
// this is ok because
|
|
263
|
+
// this is not ok because blockNumber might differ from subscriber blockNumber
|
|
253
264
|
state[wallet] = {
|
|
254
265
|
balance: balance.amounts[DEFAULT_ID_ERC20_AS_STRING],
|
|
255
266
|
};
|
package/src/lib/multi-wrapper.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { BytesLike } from 'ethers';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import { Logger } from 'log4js';
|
|
4
4
|
import { Contract } from 'web3-eth-contract';
|
|
5
|
+
import { uint256DecodeToNumber } from './decoders';
|
|
5
6
|
|
|
6
7
|
export type MultiResult<T> = {
|
|
7
8
|
success: boolean;
|
|
@@ -54,10 +55,12 @@ export class MultiWrapper {
|
|
|
54
55
|
async tryAggregate<T>(
|
|
55
56
|
mandatory: boolean,
|
|
56
57
|
calls: MultiCallParams<T>[],
|
|
57
|
-
blockNumber
|
|
58
|
+
blockNumber: number | 'latest' = 'latest',
|
|
58
59
|
batchSize: number = this.defaultBatchSize,
|
|
59
60
|
reportFails: boolean = true,
|
|
60
61
|
): Promise<MultiResult<T>[]> {
|
|
62
|
+
const _blockNumber = blockNumber === undefined ? 'latest' : blockNumber;
|
|
63
|
+
|
|
61
64
|
const allCalls = new Array(Math.ceil(calls.length / batchSize));
|
|
62
65
|
for (let i = 0; i < calls.length; i += batchSize) {
|
|
63
66
|
const batch = calls.slice(i, i + batchSize);
|
|
@@ -68,7 +71,7 @@ export class MultiWrapper {
|
|
|
68
71
|
allCalls.map(batch =>
|
|
69
72
|
this.multi.methods
|
|
70
73
|
.tryAggregate(mandatory, batch)
|
|
71
|
-
.call(undefined,
|
|
74
|
+
.call(undefined, _blockNumber),
|
|
72
75
|
),
|
|
73
76
|
);
|
|
74
77
|
|
|
@@ -105,4 +108,40 @@ export class MultiWrapper {
|
|
|
105
108
|
|
|
106
109
|
return results;
|
|
107
110
|
}
|
|
111
|
+
|
|
112
|
+
// I removed here batching because it may give inconsistent blockNumber
|
|
113
|
+
// If we see that is a problem, we can add later
|
|
114
|
+
async blockTryAggregateWithoutBatching<T>(
|
|
115
|
+
mandatory: boolean,
|
|
116
|
+
calls: MultiCallParams<T>[],
|
|
117
|
+
requestedBlockNumber: number | 'latest' = 'latest',
|
|
118
|
+
reportFails: boolean = true,
|
|
119
|
+
) {
|
|
120
|
+
const blockNumberCall: MultiCallParams<number> = {
|
|
121
|
+
target: this.multi.options.address,
|
|
122
|
+
callData: this.multi.methods.getBlockNumber().encodeABI() as string,
|
|
123
|
+
decodeFunction: uint256DecodeToNumber,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const callsWithBlockNumber: [
|
|
127
|
+
...MultiCallParams<T>[],
|
|
128
|
+
MultiCallParams<number>,
|
|
129
|
+
] = [...calls, blockNumberCall];
|
|
130
|
+
|
|
131
|
+
const results = await this.tryAggregate(
|
|
132
|
+
mandatory,
|
|
133
|
+
callsWithBlockNumber as MultiCallParams<T | number>[],
|
|
134
|
+
requestedBlockNumber,
|
|
135
|
+
callsWithBlockNumber.length,
|
|
136
|
+
reportFails,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// We guaranteed previously that at least one call is contained
|
|
140
|
+
const blockNumber = results.pop()!.returnData as number;
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
blockNumber,
|
|
144
|
+
results: results as MultiResult<T>[],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
108
147
|
}
|
|
@@ -135,11 +135,6 @@ export const getAllowanceCallParams = (
|
|
|
135
135
|
}
|
|
136
136
|
default:
|
|
137
137
|
throw new Error(`missing case for assetType ${req.assetType}`);
|
|
138
|
-
return {
|
|
139
|
-
calls: [],
|
|
140
|
-
spenders: new Set(),
|
|
141
|
-
length: 0,
|
|
142
|
-
};
|
|
143
138
|
}
|
|
144
139
|
};
|
|
145
140
|
|
|
@@ -241,11 +236,16 @@ export const decodeBalanceAndAllowanceMultiResult = (
|
|
|
241
236
|
return userBalance;
|
|
242
237
|
};
|
|
243
238
|
|
|
239
|
+
type getBalancesResult = {
|
|
240
|
+
blockNumber: number;
|
|
241
|
+
balances: UserBalance[];
|
|
242
|
+
};
|
|
243
|
+
|
|
244
244
|
export const getBalances = async (
|
|
245
245
|
multiv2: MultiWrapper,
|
|
246
246
|
reqs: BalanceRequest[],
|
|
247
247
|
blockNumber: number | 'latest' = 'latest',
|
|
248
|
-
): Promise<
|
|
248
|
+
): Promise<getBalancesResult> => {
|
|
249
249
|
const calls: MultiCallParams<MultiCallParamsType>[] = []; // TODO: compute the size on advance
|
|
250
250
|
|
|
251
251
|
const decodingInfo: MultiCallResultDecodeInfo[] = [];
|
|
@@ -257,27 +257,31 @@ export const getBalances = async (
|
|
|
257
257
|
params.length += balancesCalls.length;
|
|
258
258
|
decodingInfo.push(params);
|
|
259
259
|
}
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
260
|
+
const resultsAndBn =
|
|
261
|
+
await multiv2.blockTryAggregateWithoutBatching<MultiCallParamsType>(
|
|
262
|
+
false,
|
|
263
|
+
calls,
|
|
264
|
+
blockNumber,
|
|
265
|
+
);
|
|
265
266
|
|
|
266
267
|
const chunks = [];
|
|
267
268
|
let j = 0;
|
|
268
|
-
for (let i = 0; i < results.length; ) {
|
|
269
|
+
for (let i = 0; i < resultsAndBn.results.length; ) {
|
|
269
270
|
const batchSize = decodingInfo[j].length;
|
|
270
|
-
const chunk = results.slice(i, i + batchSize);
|
|
271
|
+
const chunk = resultsAndBn.results.slice(i, i + batchSize);
|
|
271
272
|
chunks.push(chunk);
|
|
272
273
|
j++;
|
|
273
274
|
i += batchSize;
|
|
274
275
|
}
|
|
275
276
|
|
|
276
|
-
return
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
277
|
+
return {
|
|
278
|
+
blockNumber: resultsAndBn.blockNumber,
|
|
279
|
+
balances: chunks.map((chunk, index) =>
|
|
280
|
+
decodeBalanceAndAllowanceMultiResult(
|
|
281
|
+
reqs[index],
|
|
282
|
+
decodingInfo[index].spenders,
|
|
283
|
+
chunk,
|
|
284
|
+
),
|
|
281
285
|
),
|
|
282
|
-
|
|
286
|
+
};
|
|
283
287
|
};
|
package/src/pricing-helper.ts
CHANGED
|
@@ -36,7 +36,10 @@ export class PricingHelper {
|
|
|
36
36
|
);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
private async initializeDex(
|
|
39
|
+
private async initializeDex(
|
|
40
|
+
dexKey: string,
|
|
41
|
+
blockNumber: number | 'latest' = 'latest',
|
|
42
|
+
) {
|
|
40
43
|
try {
|
|
41
44
|
const dexInstance = this.dexAdapterService.getDexByKey(dexKey);
|
|
42
45
|
|
|
@@ -80,7 +83,7 @@ export class PricingHelper {
|
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
public async initialize(blockNumber: number, dexKeys: string[]) {
|
|
86
|
+
public async initialize(blockNumber: number | 'latest', dexKeys: string[]) {
|
|
84
87
|
return await Promise.all(
|
|
85
88
|
dexKeys.map(key => this.initializeDex(key, blockNumber)),
|
|
86
89
|
);
|
|
@@ -15,8 +15,13 @@ type StateCache<State> = {
|
|
|
15
15
|
state: DeepReadonly<State>;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
export type StateWithBlock<State> = {
|
|
19
|
+
state: DeepReadonly<State>;
|
|
20
|
+
blockNumber: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
18
23
|
export type InitializeStateOptions<State> = {
|
|
19
|
-
|
|
24
|
+
stateWithBn?: StateWithBlock<State>;
|
|
20
25
|
initCallback?: (state: DeepReadonly<State>) => void;
|
|
21
26
|
};
|
|
22
27
|
|
|
@@ -83,12 +88,13 @@ export abstract class StatefulEventSubscriber<State>
|
|
|
83
88
|
// will also publish a message to cache to tell one master version of dex-lib that this slave
|
|
84
89
|
// instance subscribed to a pool from dex this.parentName and name this.name.
|
|
85
90
|
async initialize(
|
|
86
|
-
blockNumber: number,
|
|
91
|
+
blockNumber: number | 'latest',
|
|
87
92
|
options?: InitializeStateOptions<State>,
|
|
88
93
|
) {
|
|
89
94
|
let masterBn: undefined | number = undefined;
|
|
90
|
-
if (options && options.
|
|
91
|
-
this.setState(options.state, blockNumber);
|
|
95
|
+
if (options && options.stateWithBn) {
|
|
96
|
+
this.setState(options.stateWithBn.state, options.stateWithBn.blockNumber);
|
|
97
|
+
masterBn = options.stateWithBn.blockNumber;
|
|
92
98
|
} else {
|
|
93
99
|
if (this.dexHelper.config.isSlave && this.masterPoolNeeded) {
|
|
94
100
|
let stateAsString = await this.dexHelper.cache.hget(
|
|
@@ -104,37 +110,39 @@ export abstract class StatefulEventSubscriber<State>
|
|
|
104
110
|
this.logger.warn(
|
|
105
111
|
`${this.parentName}: ${this.name}: found null state in cache generate new one`,
|
|
106
112
|
);
|
|
107
|
-
|
|
113
|
+
const stateAndBn = await this.generateState(blockNumber);
|
|
114
|
+
|
|
115
|
+
state.state = stateAndBn.state;
|
|
116
|
+
state.bn = stateAndBn.blockNumber;
|
|
117
|
+
masterBn = state.bn;
|
|
118
|
+
this.setState(state.state, state.bn);
|
|
108
119
|
} else {
|
|
109
|
-
this.logger.
|
|
120
|
+
this.logger.trace(
|
|
110
121
|
`${this.parentName}: ${this.name}: found state from cache`,
|
|
111
122
|
);
|
|
112
|
-
blockNumber = state.bn;
|
|
113
|
-
|
|
114
123
|
const _masterBn = await this.dexHelper.cache.rawget(
|
|
115
124
|
this.dexHelper.config.masterBlockNumberCacheKey,
|
|
116
125
|
);
|
|
117
126
|
if (_masterBn) {
|
|
118
127
|
masterBn = parseInt(_masterBn, 10);
|
|
119
|
-
this.logger.
|
|
120
|
-
`${this.dexHelper.config.data.network} found master blockNumber ${
|
|
128
|
+
this.logger.trace(
|
|
129
|
+
`${this.dexHelper.config.data.network} found master blockNumber ${masterBn}`,
|
|
121
130
|
);
|
|
131
|
+
this.setState(state.state, state.bn);
|
|
122
132
|
} else {
|
|
123
|
-
|
|
133
|
+
throw new Error(
|
|
124
134
|
`${this.dexHelper.config.data.network} did not found blockNumber in cache`,
|
|
125
135
|
);
|
|
126
136
|
}
|
|
127
137
|
}
|
|
128
|
-
// set state and the according blockNumber. state.bn can be smaller, greater or equal
|
|
129
|
-
// to blockNumber
|
|
130
|
-
this.setState(state.state, blockNumber);
|
|
131
138
|
} else {
|
|
132
139
|
// if no state found in cache generate new state using rpc
|
|
133
140
|
this.logger.info(
|
|
134
141
|
`${this.parentName}: ${this.name}: did not found state on cache generating new one`,
|
|
135
142
|
);
|
|
136
|
-
const
|
|
137
|
-
|
|
143
|
+
const stateAndBn = await this.generateState(blockNumber);
|
|
144
|
+
masterBn = stateAndBn.blockNumber;
|
|
145
|
+
this.setState(stateAndBn.state, stateAndBn.blockNumber);
|
|
138
146
|
|
|
139
147
|
// we should publish only if generateState succeeded
|
|
140
148
|
this.dexHelper.cache.publish('new_pools', this.cacheName);
|
|
@@ -144,8 +152,9 @@ export abstract class StatefulEventSubscriber<State>
|
|
|
144
152
|
this.logger.info(
|
|
145
153
|
`${this.parentName}: ${this.name}: cache generating state`,
|
|
146
154
|
);
|
|
147
|
-
const
|
|
148
|
-
|
|
155
|
+
const stateAndBn = await this.generateState(blockNumber);
|
|
156
|
+
masterBn = stateAndBn.blockNumber;
|
|
157
|
+
this.setState(stateAndBn.state, stateAndBn.blockNumber);
|
|
149
158
|
}
|
|
150
159
|
}
|
|
151
160
|
|
|
@@ -160,7 +169,7 @@ export abstract class StatefulEventSubscriber<State>
|
|
|
160
169
|
this.dexHelper.blockManager.subscribeToLogs(
|
|
161
170
|
this,
|
|
162
171
|
this.addressesSubscribed,
|
|
163
|
-
masterBn
|
|
172
|
+
masterBn,
|
|
164
173
|
);
|
|
165
174
|
this.isInitialized = true;
|
|
166
175
|
}
|
|
@@ -203,7 +212,7 @@ export abstract class StatefulEventSubscriber<State>
|
|
|
203
212
|
//generate one from scratch.
|
|
204
213
|
abstract generateState(
|
|
205
214
|
blockNumber?: number | 'latest',
|
|
206
|
-
): AsyncOrSync<
|
|
215
|
+
): AsyncOrSync<StateWithBlock<State>>;
|
|
207
216
|
|
|
208
217
|
restart(blockNumber: number): void {
|
|
209
218
|
for (const _bn of Object.keys(this.stateHistory)) {
|
|
@@ -251,8 +260,8 @@ export abstract class StatefulEventSubscriber<State>
|
|
|
251
260
|
++indexBlockEnd;
|
|
252
261
|
}
|
|
253
262
|
if (!this.state) {
|
|
254
|
-
const
|
|
255
|
-
this.setState(
|
|
263
|
+
const freshStateAndBn = await this.generateState('latest');
|
|
264
|
+
this.setState(freshStateAndBn.state, freshStateAndBn.blockNumber);
|
|
256
265
|
}
|
|
257
266
|
//Find the last state before the blockNumber of the logs
|
|
258
267
|
let stateBeforeLog: DeepReadonly<State> | undefined;
|
|
@@ -285,18 +294,16 @@ export abstract class StatefulEventSubscriber<State>
|
|
|
285
294
|
if (this.state !== null) {
|
|
286
295
|
return true;
|
|
287
296
|
}
|
|
288
|
-
const latestBlockNumber =
|
|
289
|
-
this.dexHelper.blockManager.getLatestBlockNumber();
|
|
290
297
|
this.logger.warn(
|
|
291
|
-
`${network}: ${this.parentName}: ${this.name}: master generate (latest
|
|
298
|
+
`${network}: ${this.parentName}: ${this.name}: master generate (latest) new state because state is null`,
|
|
292
299
|
);
|
|
293
300
|
try {
|
|
294
|
-
const
|
|
295
|
-
this.setState(state,
|
|
301
|
+
const stateAndBn = await this.generateState('latest');
|
|
302
|
+
this.setState(stateAndBn.state, stateAndBn.blockNumber);
|
|
296
303
|
return true;
|
|
297
304
|
} catch (e) {
|
|
298
305
|
this.logger.error(
|
|
299
|
-
`${network}: ${this.parentName} ${this.name}: (
|
|
306
|
+
`${network}: ${this.parentName} ${this.name}: (latest) failed fetch state:`,
|
|
300
307
|
e,
|
|
301
308
|
);
|
|
302
309
|
}
|
package/src/utils.ts
CHANGED
|
@@ -319,7 +319,7 @@ export class Utils {
|
|
|
319
319
|
): Promise<T> {
|
|
320
320
|
return Promise.race([
|
|
321
321
|
promise,
|
|
322
|
-
new Promise<T>((
|
|
322
|
+
new Promise<T>((_, reject) => {
|
|
323
323
|
setTimeout(() => reject(message), timeout);
|
|
324
324
|
}),
|
|
325
325
|
]);
|
|
@@ -353,8 +353,8 @@ export const isTruthy = <T>(x: T | undefined | null | '' | false | 0): x is T =>
|
|
|
353
353
|
!!x;
|
|
354
354
|
|
|
355
355
|
type MultiCallParams = {
|
|
356
|
-
target:
|
|
357
|
-
callData:
|
|
356
|
+
target: string;
|
|
357
|
+
callData: string;
|
|
358
358
|
};
|
|
359
359
|
|
|
360
360
|
type BlockAndTryAggregateResult = {
|
|
@@ -383,6 +383,5 @@ export const blockAndTryAggregate = async (
|
|
|
383
383
|
|
|
384
384
|
export const isContractAddress = async (web3: Web3, addr: string) => {
|
|
385
385
|
const contractCode = await web3.eth.getCode(addr);
|
|
386
|
-
|
|
387
386
|
return contractCode !== '0x';
|
|
388
387
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
dotenv.config();
|
|
3
|
+
|
|
4
|
+
import Web3 from 'web3';
|
|
5
|
+
import { AbiItem } from 'web3-utils';
|
|
6
|
+
import MultiAbi from '../src/abi/multi-v2.json';
|
|
7
|
+
import { generateConfig } from '../src/config';
|
|
8
|
+
import { Network } from '../src/constants';
|
|
9
|
+
import { getBalanceERC20 } from '../src/lib/tokens/utils';
|
|
10
|
+
import { blockAndTryAggregate } from '../src/utils';
|
|
11
|
+
|
|
12
|
+
describe('MultiCall with blockNumber', () => {
|
|
13
|
+
const config = generateConfig(Network.MAINNET);
|
|
14
|
+
|
|
15
|
+
const web3 = new Web3(config.privateHttpProvider);
|
|
16
|
+
const multiContract = new web3.eth.Contract(
|
|
17
|
+
MultiAbi as AbiItem[],
|
|
18
|
+
config.multicallV2Address,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
it('MultiCall with blockNumber', async () => {
|
|
22
|
+
const res = await blockAndTryAggregate(
|
|
23
|
+
true,
|
|
24
|
+
multiContract,
|
|
25
|
+
[
|
|
26
|
+
{
|
|
27
|
+
target: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
28
|
+
callData: getBalanceERC20(
|
|
29
|
+
'0x05182e579fdfcf69e4390c3411d8fea1fb6467cf',
|
|
30
|
+
),
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
target: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
34
|
+
callData: getBalanceERC20(
|
|
35
|
+
'0x05182e579fdfcf69e4390c3411d8fea1fb6467cf',
|
|
36
|
+
),
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
'latest',
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
console.log(res);
|
|
43
|
+
});
|
|
44
|
+
});
|