@paraswap/dex-lib 4.1.3 → 4.1.4-bal-v3-hooks.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/balancer-v3/directionalFeeHook.json +684 -0
- package/build/abi/balancer-v3/stableSurgeHook.json +976 -0
- package/build/dex/balancer-v3/balancer-test-helpers.d.ts +5 -0
- package/build/dex/balancer-v3/balancer-test-helpers.js +122 -0
- package/build/dex/balancer-v3/balancer-test-helpers.js.map +1 -0
- package/build/dex/balancer-v3/balancer-v3-pool.d.ts +4 -1
- package/build/dex/balancer-v3/balancer-v3-pool.js +20 -13
- package/build/dex/balancer-v3/balancer-v3-pool.js.map +1 -1
- package/build/dex/balancer-v3/balancer-v3.d.ts +4 -0
- package/build/dex/balancer-v3/balancer-v3.js +29 -3
- package/build/dex/balancer-v3/balancer-v3.js.map +1 -1
- package/build/dex/balancer-v3/config.js +39 -0
- package/build/dex/balancer-v3/config.js.map +1 -1
- package/build/dex/balancer-v3/getOnChainState.d.ts +1 -2
- package/build/dex/balancer-v3/getOnChainState.js +0 -2
- package/build/dex/balancer-v3/getOnChainState.js.map +1 -1
- package/build/dex/balancer-v3/getPoolsApi.d.ts +2 -1
- package/build/dex/balancer-v3/getPoolsApi.js +17 -10
- package/build/dex/balancer-v3/getPoolsApi.js.map +1 -1
- package/build/dex/balancer-v3/getTopPoolsApi.d.ts +5 -1
- package/build/dex/balancer-v3/getTopPoolsApi.js +6 -3
- package/build/dex/balancer-v3/getTopPoolsApi.js.map +1 -1
- package/build/dex/balancer-v3/hooks/balancer-hook-event-subscriber.d.ts +54 -0
- package/build/dex/balancer-v3/hooks/balancer-hook-event-subscriber.js +153 -0
- package/build/dex/balancer-v3/hooks/balancer-hook-event-subscriber.js.map +1 -0
- package/build/dex/balancer-v3/hooks/directionalFeeHook.d.ts +26 -0
- package/build/dex/balancer-v3/hooks/directionalFeeHook.js +41 -0
- package/build/dex/balancer-v3/hooks/directionalFeeHook.js.map +1 -0
- package/build/dex/balancer-v3/hooks/loadHooksConfig.d.ts +2 -0
- package/build/dex/balancer-v3/hooks/loadHooksConfig.js +11 -0
- package/build/dex/balancer-v3/hooks/loadHooksConfig.js.map +1 -0
- package/build/dex/balancer-v3/hooks/stableSurgeHook.d.ts +39 -0
- package/build/dex/balancer-v3/hooks/stableSurgeHook.js +99 -0
- package/build/dex/balancer-v3/hooks/stableSurgeHook.js.map +1 -0
- package/build/dex/balancer-v3/types.d.ts +4 -1
- package/package.json +2 -2
- package/scripts/run-dex-integration-v3.ts +4 -4
- package/src/abi/balancer-v3/directionalFeeHook.json +684 -0
- package/src/abi/balancer-v3/stableSurgeHook.json +976 -0
- package/src/dex/balancer-v3/balancer-hooks-events.test.ts +99 -0
- package/src/dex/balancer-v3/balancer-stableSurge.test.ts +110 -0
- package/src/dex/balancer-v3/balancer-test-helpers.ts +199 -0
- package/src/dex/balancer-v3/balancer-v3-e2e.test.ts +20 -0
- package/src/dex/balancer-v3/balancer-v3-integration.test.ts +2 -197
- package/src/dex/balancer-v3/balancer-v3-pool.ts +37 -13
- package/src/dex/balancer-v3/balancer-v3.ts +42 -1
- package/src/dex/balancer-v3/config.ts +39 -0
- package/src/dex/balancer-v3/getOnChainState.ts +1 -4
- package/src/dex/balancer-v3/getPoolsApi.ts +42 -23
- package/src/dex/balancer-v3/getTopPoolsApi.ts +13 -2
- package/src/dex/balancer-v3/hooks/balancer-hook-event-subscriber.ts +226 -0
- package/src/dex/balancer-v3/hooks/directionalFeeHook.ts +51 -0
- package/src/dex/balancer-v3/hooks/loadHooksConfig.ts +12 -0
- package/src/dex/balancer-v3/hooks/stableSurgeHook.ts +163 -0
- package/src/dex/balancer-v3/types.ts +4 -2
- package/tests/constants-e2e.ts +6 -1
|
@@ -29,6 +29,11 @@ import {
|
|
|
29
29
|
isStableMutableState,
|
|
30
30
|
} from './stablePool';
|
|
31
31
|
import { BI_POWS } from '../../bigint-constants';
|
|
32
|
+
import {
|
|
33
|
+
HookStateMap,
|
|
34
|
+
HooksConfigMap,
|
|
35
|
+
} from './hooks/balancer-hook-event-subscriber';
|
|
36
|
+
import { StableSurge, StableSurgeHookState } from './hooks/stableSurgeHook';
|
|
32
37
|
|
|
33
38
|
export const WAD = BI_POWS[18];
|
|
34
39
|
|
|
@@ -48,8 +53,8 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
48
53
|
interfaces: {
|
|
49
54
|
[name: string]: Interface;
|
|
50
55
|
};
|
|
51
|
-
|
|
52
56
|
vault: Vault;
|
|
57
|
+
hooksConfigMap: HooksConfigMap = {};
|
|
53
58
|
|
|
54
59
|
constructor(
|
|
55
60
|
readonly parentName: string,
|
|
@@ -96,6 +101,10 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
96
101
|
this.vault = new Vault();
|
|
97
102
|
}
|
|
98
103
|
|
|
104
|
+
setHooksConfigMap(hooksConfigMap: HooksConfigMap) {
|
|
105
|
+
this.hooksConfigMap = hooksConfigMap;
|
|
106
|
+
}
|
|
107
|
+
|
|
99
108
|
/**
|
|
100
109
|
* The function is called every time any of the subscribed
|
|
101
110
|
* addresses release log. The function accepts the current
|
|
@@ -134,7 +143,11 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
134
143
|
blockNumber: number,
|
|
135
144
|
): Promise<DeepReadonly<PoolStateMap>> {
|
|
136
145
|
const block = await this.dexHelper.provider.getBlock(blockNumber);
|
|
137
|
-
const apiPoolStateMap = await getPoolsApi(
|
|
146
|
+
const apiPoolStateMap = await getPoolsApi(
|
|
147
|
+
this.network,
|
|
148
|
+
this.hooksConfigMap,
|
|
149
|
+
block.timestamp,
|
|
150
|
+
);
|
|
138
151
|
const allOnChainPools = await getOnChainState(
|
|
139
152
|
this.network,
|
|
140
153
|
apiPoolStateMap,
|
|
@@ -160,7 +173,10 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
160
173
|
existingPoolState: DeepReadonly<PoolStateMap>,
|
|
161
174
|
): Promise<DeepReadonly<PoolStateMap> | null> {
|
|
162
175
|
// Get all latest pools from API
|
|
163
|
-
const apiPoolStateMap = await getPoolsApi(
|
|
176
|
+
const apiPoolStateMap = await getPoolsApi(
|
|
177
|
+
this.network,
|
|
178
|
+
this.hooksConfigMap,
|
|
179
|
+
);
|
|
164
180
|
|
|
165
181
|
// Filter out pools that already exist in existing state
|
|
166
182
|
const newApiPools = Object.entries(apiPoolStateMap).reduce(
|
|
@@ -186,19 +202,10 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
186
202
|
this.interfaces,
|
|
187
203
|
);
|
|
188
204
|
|
|
189
|
-
// Filter out pools with hooks and paused pools from new state
|
|
190
|
-
// TODO this won't be necessary once API has this filter option
|
|
191
|
-
const filteredNewPools = Object.entries(newOnChainPools)
|
|
192
|
-
.filter(([_, pool]) => !(pool.hasHook || pool.isPoolPaused))
|
|
193
|
-
.reduce((acc, [address, pool]) => {
|
|
194
|
-
acc[address] = pool;
|
|
195
|
-
return acc;
|
|
196
|
-
}, {} as PoolStateMap);
|
|
197
|
-
|
|
198
205
|
// Merge existing pools with new pools
|
|
199
206
|
return {
|
|
200
207
|
...existingPoolState,
|
|
201
|
-
...
|
|
208
|
+
...newOnChainPools,
|
|
202
209
|
};
|
|
203
210
|
}
|
|
204
211
|
|
|
@@ -398,6 +405,7 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
398
405
|
amountRaw: bigint,
|
|
399
406
|
swapKind: SwapKind,
|
|
400
407
|
timestamp: number,
|
|
408
|
+
hookStateMap: HookStateMap,
|
|
401
409
|
): bigint {
|
|
402
410
|
if (amountRaw === 0n) return 0n;
|
|
403
411
|
|
|
@@ -411,6 +419,12 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
411
419
|
let outputAmountRaw = 0n;
|
|
412
420
|
for (const i of indices) {
|
|
413
421
|
const step = steps[i];
|
|
422
|
+
|
|
423
|
+
// If the pool has a hook we fetch latest hook state for use in maths
|
|
424
|
+
let hookState = undefined;
|
|
425
|
+
if ('hookAddress' in step.poolState && step.poolState.hookAddress)
|
|
426
|
+
hookState = hookStateMap[step.poolState.hookAddress];
|
|
427
|
+
|
|
414
428
|
// If its a Stable Pool with an updating Amp factor calculate current Amp value
|
|
415
429
|
if (
|
|
416
430
|
step.poolState.poolType === 'STABLE' &&
|
|
@@ -425,7 +439,16 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
425
439
|
BigInt(timestamp),
|
|
426
440
|
);
|
|
427
441
|
}
|
|
442
|
+
// StableSurge hook uses Amp as part of maths
|
|
443
|
+
if (step.poolState.hookType === StableSurge.type && hookState)
|
|
444
|
+
hookState = {
|
|
445
|
+
...(hookState as StableSurgeHookState)[
|
|
446
|
+
step.poolState.poolAddress.toLowerCase()
|
|
447
|
+
],
|
|
448
|
+
amp: step.poolState.amp,
|
|
449
|
+
};
|
|
428
450
|
}
|
|
451
|
+
|
|
429
452
|
outputAmountRaw = this.vault.swap(
|
|
430
453
|
{
|
|
431
454
|
...step.swapInput,
|
|
@@ -433,6 +456,7 @@ export class BalancerV3EventPool extends StatefulEventSubscriber<PoolStateMap> {
|
|
|
433
456
|
swapKind,
|
|
434
457
|
},
|
|
435
458
|
step.poolState,
|
|
459
|
+
hookState,
|
|
436
460
|
);
|
|
437
461
|
// Next step uses output from previous step as input
|
|
438
462
|
amount = outputAmountRaw;
|
|
@@ -27,11 +27,13 @@ import balancerRouterAbi from '../../abi/balancer-v3/router.json';
|
|
|
27
27
|
import balancerBatchRouterAbi from '../../abi/balancer-v3/batch-router.json';
|
|
28
28
|
import { getGasCost } from './getGasCost';
|
|
29
29
|
import { Block } from '@ethersproject/abstract-provider';
|
|
30
|
+
import { BalancerEventHook } from './hooks/balancer-hook-event-subscriber';
|
|
30
31
|
|
|
31
32
|
const MAX_UINT256 =
|
|
32
33
|
'115792089237316195423570985008687907853269984665640564039457584007913129639935';
|
|
33
34
|
const POOL_UPDATE_TTL = 1 * 60; // 1min
|
|
34
35
|
const RATE_UPDATE_TTL = 1 * 60; // 1min
|
|
36
|
+
const HOOK_UPDATE_TTL = 5 * 60; // 5min
|
|
35
37
|
|
|
36
38
|
type DeepMutable<T> = {
|
|
37
39
|
-readonly [P in keyof T]: T[P] extends object ? DeepMutable<T[P]> : T[P];
|
|
@@ -39,6 +41,7 @@ type DeepMutable<T> = {
|
|
|
39
41
|
|
|
40
42
|
export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
41
43
|
protected eventPools: BalancerV3EventPool;
|
|
44
|
+
protected eventHooks: BalancerEventHook;
|
|
42
45
|
|
|
43
46
|
readonly hasConstantPriceLargeAmounts = false;
|
|
44
47
|
// Vault can handle native
|
|
@@ -54,6 +57,7 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
54
57
|
balancerBatchRouter: Interface;
|
|
55
58
|
updateNewPoolsTimer?: NodeJS.Timeout;
|
|
56
59
|
updateRatesTimer?: NodeJS.Timeout;
|
|
60
|
+
updateHooksTimer?: NodeJS.Timeout;
|
|
57
61
|
|
|
58
62
|
latestBlock?: Block;
|
|
59
63
|
|
|
@@ -64,6 +68,12 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
64
68
|
) {
|
|
65
69
|
super(dexHelper, dexKey);
|
|
66
70
|
this.logger = dexHelper.getLogger(dexKey);
|
|
71
|
+
this.eventHooks = new BalancerEventHook(
|
|
72
|
+
dexKey,
|
|
73
|
+
network,
|
|
74
|
+
dexHelper,
|
|
75
|
+
this.logger,
|
|
76
|
+
);
|
|
67
77
|
this.eventPools = new BalancerV3EventPool(
|
|
68
78
|
dexKey,
|
|
69
79
|
network,
|
|
@@ -79,6 +89,8 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
79
89
|
// for pricing requests. It is optional for a DEX to
|
|
80
90
|
// implement this function
|
|
81
91
|
async initializePricing(blockNumber: number) {
|
|
92
|
+
await this.eventHooks.initialize(blockNumber);
|
|
93
|
+
this.eventPools.setHooksConfigMap(this.eventHooks.hooksConfigMap);
|
|
82
94
|
await this.eventPools.initialize(blockNumber);
|
|
83
95
|
|
|
84
96
|
// This will periodically query API and add any new pools to pool state
|
|
@@ -102,6 +114,17 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
102
114
|
}
|
|
103
115
|
}, RATE_UPDATE_TTL * 1000);
|
|
104
116
|
}
|
|
117
|
+
|
|
118
|
+
// This will periodically update any hook state that can't be tracked by events
|
|
119
|
+
if (!this.updateHooksTimer) {
|
|
120
|
+
this.updateHooksTimer = setInterval(async () => {
|
|
121
|
+
try {
|
|
122
|
+
await this.updateHooksState();
|
|
123
|
+
} catch (e) {
|
|
124
|
+
this.logger.error(`${this.dexKey}: Failed to update hook state:`, e);
|
|
125
|
+
}
|
|
126
|
+
}, HOOK_UPDATE_TTL * 1000);
|
|
127
|
+
}
|
|
105
128
|
}
|
|
106
129
|
|
|
107
130
|
getAdapters(side: SwapSide): null {
|
|
@@ -261,6 +284,7 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
261
284
|
unitAmount,
|
|
262
285
|
swapKind,
|
|
263
286
|
block.timestamp,
|
|
287
|
+
this.eventHooks.getState(blockNumber) || {},
|
|
264
288
|
);
|
|
265
289
|
|
|
266
290
|
const poolExchangePrice: PoolPrices<BalancerV3Data> = {
|
|
@@ -283,6 +307,7 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
283
307
|
amounts[j],
|
|
284
308
|
swapKind,
|
|
285
309
|
block.timestamp,
|
|
310
|
+
this.eventHooks.getState(blockNumber) || {},
|
|
286
311
|
);
|
|
287
312
|
}
|
|
288
313
|
}
|
|
@@ -559,6 +584,10 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
559
584
|
await this.eventPools.updateStatePools();
|
|
560
585
|
}
|
|
561
586
|
|
|
587
|
+
async updateHooksState(): Promise<void> {
|
|
588
|
+
await this.eventHooks.updateHookState();
|
|
589
|
+
}
|
|
590
|
+
|
|
562
591
|
// Returns list of top pools based on liquidity. Max
|
|
563
592
|
// limit number pools should be returned.
|
|
564
593
|
async getTopPoolsForToken(
|
|
@@ -571,7 +600,12 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
571
600
|
})
|
|
572
601
|
.map(([address]) => address);
|
|
573
602
|
|
|
574
|
-
const topPools = await getTopPoolsApi(
|
|
603
|
+
const topPools = await getTopPoolsApi(
|
|
604
|
+
this.network,
|
|
605
|
+
poolsWithToken,
|
|
606
|
+
count,
|
|
607
|
+
this.eventHooks.hooksConfigMap,
|
|
608
|
+
);
|
|
575
609
|
|
|
576
610
|
return topPools.map(pool => {
|
|
577
611
|
const tokens = pool.poolTokens
|
|
@@ -610,5 +644,12 @@ export class BalancerV3 extends SimpleExchange implements IDex<BalancerV3Data> {
|
|
|
610
644
|
`${this.dexKey}: cleared updateRatesTimer before shutting down`,
|
|
611
645
|
);
|
|
612
646
|
}
|
|
647
|
+
if (this.updateHooksTimer) {
|
|
648
|
+
clearInterval(this.updateHooksTimer);
|
|
649
|
+
this.updateHooksTimer = undefined;
|
|
650
|
+
this.logger.info(
|
|
651
|
+
`${this.dexKey}: cleared updateHooksTimer before shutting down`,
|
|
652
|
+
);
|
|
653
|
+
}
|
|
613
654
|
}
|
|
614
655
|
}
|
|
@@ -25,30 +25,69 @@ export const BalancerV3Config: DexConfigMap<DexParams> = {
|
|
|
25
25
|
apiNetworkName: 'SEPOLIA',
|
|
26
26
|
balancerRouterAddress: '0x0BF61f706105EA44694f2e92986bD01C39930280',
|
|
27
27
|
balancerBatchRouterAddress: '0xC85b652685567C1B074e8c0D4389f83a2E458b1C',
|
|
28
|
+
hooks: [
|
|
29
|
+
{
|
|
30
|
+
type: 'DirectionalFee',
|
|
31
|
+
address: '0xd68372e85d8a14afa5fdb3d506bf765939aaf382',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'StableSurge',
|
|
35
|
+
factory: '0x9eB9867C1d4B6fd3a7D0dAd3101b5A153b1107Ec', // Pools with StableSurge hook will always be deployed from this factory
|
|
36
|
+
address: '0xc0cbcdd6b823a4f22aa6bbdde44c17e754266aef', // Address of the hook that will be used by pools
|
|
37
|
+
},
|
|
38
|
+
],
|
|
28
39
|
},
|
|
29
40
|
[Network.GNOSIS]: {
|
|
30
41
|
vaultAddress: '0xbA1333333333a1BA1108E8412f11850A5C319bA9',
|
|
31
42
|
apiNetworkName: 'GNOSIS',
|
|
32
43
|
balancerRouterAddress: '0x84813aA3e079A665C0B80F944427eE83cBA63617',
|
|
33
44
|
balancerBatchRouterAddress: '0xe2fa4e1d17725e72dcdAfe943Ecf45dF4B9E285b',
|
|
45
|
+
hooks: [
|
|
46
|
+
{
|
|
47
|
+
type: 'StableSurge',
|
|
48
|
+
factory: '0x268E2EE1413D768b6e2dc3F5a4ddc9Ae03d9AF42', // Pools with StableSurge hook will always be deployed from this factory
|
|
49
|
+
address: '0xe4f1878eC9710846E2B529C1b5037F8bA94583b1', // Address of the hook that will be used by pools
|
|
50
|
+
},
|
|
51
|
+
],
|
|
34
52
|
},
|
|
35
53
|
[Network.MAINNET]: {
|
|
36
54
|
vaultAddress: '0xbA1333333333a1BA1108E8412f11850A5C319bA9',
|
|
37
55
|
apiNetworkName: 'MAINNET',
|
|
38
56
|
balancerRouterAddress: '0x5C6fb490BDFD3246EB0bB062c168DeCAF4bD9FDd',
|
|
39
57
|
balancerBatchRouterAddress: '0x136f1EFcC3f8f88516B9E94110D56FDBfB1778d1',
|
|
58
|
+
hooks: [
|
|
59
|
+
{
|
|
60
|
+
type: 'StableSurge',
|
|
61
|
+
factory: '0xD53F5d8d926fb2a0f7Be614B16e649B8aC102D83', // Pools with StableSurge hook will always be deployed from this factory
|
|
62
|
+
address: '0xb18fA0cb5DE8cecB8899AAE6e38b1B7ed77885dA', // Address of the hook that will be used by pools
|
|
63
|
+
},
|
|
64
|
+
],
|
|
40
65
|
},
|
|
41
66
|
[Network.ARBITRUM]: {
|
|
42
67
|
vaultAddress: '0xbA1333333333a1BA1108E8412f11850A5C319bA9',
|
|
43
68
|
apiNetworkName: 'ARBITRUM',
|
|
44
69
|
balancerRouterAddress: '0x0f08eEf2C785AA5e7539684aF04755dEC1347b7c',
|
|
45
70
|
balancerBatchRouterAddress: '0xaD89051bEd8d96f045E8912aE1672c6C0bF8a85E',
|
|
71
|
+
hooks: [
|
|
72
|
+
{
|
|
73
|
+
type: 'StableSurge',
|
|
74
|
+
factory: '0x86e67E115f96DF37239E0479441303De0de7bc2b', // Pools with StableSurge hook will always be deployed from this factory
|
|
75
|
+
address: '0x0Fa0f9990D7969a7aE6f9961d663E4A201Ed6417', // Address of the hook that will be used by pools
|
|
76
|
+
},
|
|
77
|
+
],
|
|
46
78
|
},
|
|
47
79
|
[Network.BASE]: {
|
|
48
80
|
vaultAddress: '0xbA1333333333a1BA1108E8412f11850A5C319bA9',
|
|
49
81
|
apiNetworkName: 'BASE',
|
|
50
82
|
balancerRouterAddress: '0x76578ecf9a141296Ec657847fb45B0585bCDa3a6',
|
|
51
83
|
balancerBatchRouterAddress: '0x85a80afee867aDf27B50BdB7b76DA70f1E853062',
|
|
84
|
+
hooks: [
|
|
85
|
+
{
|
|
86
|
+
type: 'StableSurge',
|
|
87
|
+
factory: '0x4fb47126Fa83A8734991E41B942Ac29A3266C968', // Pools with StableSurge hook will always be deployed from this factory
|
|
88
|
+
address: '0xb2007B8B7E0260042517f635CFd8E6dD2Dd7f007', // Address of the hook that will be used by pools
|
|
89
|
+
},
|
|
90
|
+
],
|
|
52
91
|
},
|
|
53
92
|
},
|
|
54
93
|
};
|
|
@@ -10,7 +10,7 @@ import { Interface, Result } from '@ethersproject/abi';
|
|
|
10
10
|
import { IDexHelper } from '../../dex-helper';
|
|
11
11
|
import { WAD } from './balancer-v3-pool';
|
|
12
12
|
|
|
13
|
-
interface callData {
|
|
13
|
+
export interface callData {
|
|
14
14
|
target: string;
|
|
15
15
|
callData: string;
|
|
16
16
|
}
|
|
@@ -161,9 +161,6 @@ const poolOnChain: Record<
|
|
|
161
161
|
(r: string) => BigInt(r),
|
|
162
162
|
),
|
|
163
163
|
isPoolPaused: resultIsPoolPaused[0],
|
|
164
|
-
hasHook:
|
|
165
|
-
resultHooksConfig[0].hooksContract !==
|
|
166
|
-
'0x0000000000000000000000000000000000000000',
|
|
167
164
|
};
|
|
168
165
|
},
|
|
169
166
|
},
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from './config';
|
|
8
8
|
import { CommonImmutablePoolState, ImmutablePoolStateMap } from './types';
|
|
9
9
|
import { parseUnits } from 'ethers/lib/utils';
|
|
10
|
+
import { HooksConfigMap } from './hooks/balancer-hook-event-subscriber';
|
|
10
11
|
|
|
11
12
|
interface PoolToken {
|
|
12
13
|
address: string;
|
|
@@ -21,6 +22,9 @@ interface Pool {
|
|
|
21
22
|
id: string;
|
|
22
23
|
type: string;
|
|
23
24
|
poolTokens: PoolToken[];
|
|
25
|
+
hook: {
|
|
26
|
+
address: string;
|
|
27
|
+
} | null;
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
interface QueryResponse {
|
|
@@ -44,7 +48,6 @@ function createQuery(
|
|
|
44
48
|
const whereClause = {
|
|
45
49
|
chainIn: networkString,
|
|
46
50
|
protocolVersionIn: 3,
|
|
47
|
-
hasHook: false,
|
|
48
51
|
poolTypeIn: `[${poolTypesString}]`,
|
|
49
52
|
...(timestamp && { createTime: `{lt: ${timestamp}}` }),
|
|
50
53
|
...(disabledPoolIdsString && { idNotIn: `[${disabledPoolIdsString}]` }),
|
|
@@ -69,37 +72,53 @@ function createQuery(
|
|
|
69
72
|
address
|
|
70
73
|
}
|
|
71
74
|
}
|
|
75
|
+
hook {
|
|
76
|
+
address
|
|
77
|
+
}
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
`;
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
function toImmutablePoolStateMap(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
83
|
+
function toImmutablePoolStateMap(
|
|
84
|
+
pools: Pool[],
|
|
85
|
+
hooksConfigMap: HooksConfigMap,
|
|
86
|
+
): ImmutablePoolStateMap {
|
|
87
|
+
return (
|
|
88
|
+
pools
|
|
89
|
+
// First filter out pools with hooks that aren't in hooksMap
|
|
90
|
+
.filter(
|
|
91
|
+
pool =>
|
|
92
|
+
!pool.hook ||
|
|
93
|
+
(pool.hook && pool.hook.address.toLowerCase() in hooksConfigMap),
|
|
94
|
+
)
|
|
95
|
+
.reduce((map, pool) => {
|
|
96
|
+
const immutablePoolState: CommonImmutablePoolState = {
|
|
97
|
+
poolAddress: pool.id,
|
|
98
|
+
tokens: pool.poolTokens.map(t => t.address),
|
|
99
|
+
tokensUnderlying: pool.poolTokens.map(t =>
|
|
100
|
+
t.underlyingToken ? t.underlyingToken.address : null,
|
|
101
|
+
),
|
|
102
|
+
weights: pool.poolTokens.map(t =>
|
|
103
|
+
t.weight ? parseUnits(t.weight, 18).toBigInt() : 0n,
|
|
104
|
+
),
|
|
105
|
+
poolType: pool.type,
|
|
106
|
+
hookAddress: pool.hook ? pool.hook.address.toLowerCase() : undefined,
|
|
107
|
+
hookType: pool.hook
|
|
108
|
+
? hooksConfigMap[pool.hook.address.toLowerCase()].type
|
|
109
|
+
: undefined,
|
|
110
|
+
supportsUnbalancedLiquidity: true,
|
|
111
|
+
};
|
|
112
|
+
map[pool.id] = immutablePoolState;
|
|
113
|
+
return map;
|
|
114
|
+
}, {} as ImmutablePoolStateMap)
|
|
115
|
+
);
|
|
98
116
|
}
|
|
99
117
|
|
|
100
118
|
// Any data from API will be immutable. Mutable data such as balances, etc will be fetched via onchain/event state.
|
|
101
119
|
export async function getPoolsApi(
|
|
102
120
|
network: number,
|
|
121
|
+
hooksConfigMap: HooksConfigMap,
|
|
103
122
|
timestamp?: number,
|
|
104
123
|
): Promise<ImmutablePoolStateMap> {
|
|
105
124
|
try {
|
|
@@ -121,7 +140,7 @@ export async function getPoolsApi(
|
|
|
121
140
|
);
|
|
122
141
|
|
|
123
142
|
const pools = response.data.data.poolGetAggregatorPools;
|
|
124
|
-
return toImmutablePoolStateMap(pools);
|
|
143
|
+
return toImmutablePoolStateMap(pools, hooksConfigMap);
|
|
125
144
|
} catch (error) {
|
|
126
145
|
// console.error('Error executing GraphQL query:', error);
|
|
127
146
|
throw error;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import { apiUrl, BalancerV3Config, disabledPoolIds } from './config';
|
|
3
|
+
import { HooksConfigMap } from './hooks/balancer-hook-event-subscriber';
|
|
3
4
|
|
|
4
5
|
interface PoolToken {
|
|
5
6
|
address: string;
|
|
@@ -16,6 +17,9 @@ export interface Pool {
|
|
|
16
17
|
dynamicData: {
|
|
17
18
|
totalLiquidity: string;
|
|
18
19
|
};
|
|
20
|
+
hook: {
|
|
21
|
+
address: string;
|
|
22
|
+
} | null;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
interface QueryResponse {
|
|
@@ -39,7 +43,6 @@ function createQuery(
|
|
|
39
43
|
const whereClause = {
|
|
40
44
|
chainIn: networkString,
|
|
41
45
|
protocolVersionIn: 3,
|
|
42
|
-
hasHook: false,
|
|
43
46
|
idIn: `[${poolIdString}]`,
|
|
44
47
|
...(disabledPoolIdsString && { idNotIn: `[${disabledPoolIdsString}]` }),
|
|
45
48
|
};
|
|
@@ -68,6 +71,9 @@ function createQuery(
|
|
|
68
71
|
dynamicData {
|
|
69
72
|
totalLiquidity
|
|
70
73
|
}
|
|
74
|
+
hook {
|
|
75
|
+
address
|
|
76
|
+
}
|
|
71
77
|
}
|
|
72
78
|
}
|
|
73
79
|
`;
|
|
@@ -77,6 +83,7 @@ export async function getTopPoolsApi(
|
|
|
77
83
|
networkId: number,
|
|
78
84
|
poolsFilter: string[],
|
|
79
85
|
count: number,
|
|
86
|
+
hooksTypeMap: HooksConfigMap,
|
|
80
87
|
): Promise<Pool[]> {
|
|
81
88
|
try {
|
|
82
89
|
const query = createQuery(networkId, poolsFilter, count);
|
|
@@ -92,7 +99,11 @@ export async function getTopPoolsApi(
|
|
|
92
99
|
},
|
|
93
100
|
);
|
|
94
101
|
|
|
95
|
-
const pools = response.data.data.poolGetAggregatorPools
|
|
102
|
+
const pools = response.data.data.poolGetAggregatorPools.filter(
|
|
103
|
+
pool =>
|
|
104
|
+
!pool.hook ||
|
|
105
|
+
(pool.hook && pool.hook.address.toLowerCase() in hooksTypeMap),
|
|
106
|
+
);
|
|
96
107
|
return pools;
|
|
97
108
|
} catch (error) {
|
|
98
109
|
// console.error('Error executing GraphQL query:', error);
|