@hyperlane-xyz/rebalancer 2.0.0 → 3.1.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/dist/bridges/LiFiBridge.d.ts +67 -0
- package/dist/bridges/LiFiBridge.d.ts.map +1 -0
- package/dist/bridges/LiFiBridge.js +386 -0
- package/dist/bridges/LiFiBridge.js.map +1 -0
- package/dist/config/RebalancerConfig.d.ts +8 -2
- package/dist/config/RebalancerConfig.d.ts.map +1 -1
- package/dist/config/RebalancerConfig.js +9 -4
- package/dist/config/RebalancerConfig.js.map +1 -1
- package/dist/config/RebalancerConfig.test.js +135 -1
- package/dist/config/RebalancerConfig.test.js.map +1 -1
- package/dist/config/types.d.ts +1023 -304
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +113 -10
- package/dist/config/types.js.map +1 -1
- package/dist/core/InventoryRebalancer.d.ts +190 -0
- package/dist/core/InventoryRebalancer.d.ts.map +1 -0
- package/dist/core/InventoryRebalancer.js +892 -0
- package/dist/core/InventoryRebalancer.js.map +1 -0
- package/dist/core/InventoryRebalancer.test.d.ts +2 -0
- package/dist/core/InventoryRebalancer.test.d.ts.map +1 -0
- package/dist/core/InventoryRebalancer.test.js +1382 -0
- package/dist/core/InventoryRebalancer.test.js.map +1 -0
- package/dist/core/Rebalancer.d.ts +11 -4
- package/dist/core/Rebalancer.d.ts.map +1 -1
- package/dist/core/Rebalancer.js +92 -9
- package/dist/core/Rebalancer.js.map +1 -1
- package/dist/core/Rebalancer.test.js +82 -49
- package/dist/core/Rebalancer.test.js.map +1 -1
- package/dist/core/RebalancerOrchestrator.d.ts +30 -9
- package/dist/core/RebalancerOrchestrator.d.ts.map +1 -1
- package/dist/core/RebalancerOrchestrator.js +79 -71
- package/dist/core/RebalancerOrchestrator.js.map +1 -1
- package/dist/core/RebalancerOrchestrator.test.d.ts +2 -0
- package/dist/core/RebalancerOrchestrator.test.d.ts.map +1 -0
- package/dist/core/RebalancerOrchestrator.test.js +719 -0
- package/dist/core/RebalancerOrchestrator.test.js.map +1 -0
- package/dist/core/RebalancerService.d.ts +7 -3
- package/dist/core/RebalancerService.d.ts.map +1 -1
- package/dist/core/RebalancerService.js +44 -24
- package/dist/core/RebalancerService.js.map +1 -1
- package/dist/core/RebalancerService.test.js +74 -110
- package/dist/core/RebalancerService.test.js.map +1 -1
- package/dist/e2e/collateral-deficit.e2e-test.js +1 -3
- package/dist/e2e/collateral-deficit.e2e-test.js.map +1 -1
- package/dist/e2e/composite.e2e-test.js.map +1 -1
- package/dist/e2e/harness/BridgeSetup.d.ts +6 -0
- package/dist/e2e/harness/BridgeSetup.d.ts.map +1 -1
- package/dist/e2e/harness/BridgeSetup.js +10 -1
- package/dist/e2e/harness/BridgeSetup.js.map +1 -1
- package/dist/e2e/harness/ForkIndexer.d.ts.map +1 -1
- package/dist/e2e/harness/ForkIndexer.js +1 -0
- package/dist/e2e/harness/ForkIndexer.js.map +1 -1
- package/dist/e2e/harness/TestHelpers.d.ts.map +1 -1
- package/dist/e2e/harness/TestHelpers.js +1 -4
- package/dist/e2e/harness/TestHelpers.js.map +1 -1
- package/dist/e2e/harness/TestRebalancer.d.ts +1 -1
- package/dist/e2e/harness/TestRebalancer.d.ts.map +1 -1
- package/dist/e2e/harness/TestRebalancer.js +9 -9
- package/dist/e2e/harness/TestRebalancer.js.map +1 -1
- package/dist/e2e/minAmount.e2e-test.js +0 -1
- package/dist/e2e/minAmount.e2e-test.js.map +1 -1
- package/dist/e2e/weighted.e2e-test.js +0 -1
- package/dist/e2e/weighted.e2e-test.js.map +1 -1
- package/dist/factories/RebalancerContextFactory.d.ts +48 -6
- package/dist/factories/RebalancerContextFactory.d.ts.map +1 -1
- package/dist/factories/RebalancerContextFactory.js +171 -17
- package/dist/factories/RebalancerContextFactory.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces/IExternalBridge.d.ts +101 -0
- package/dist/interfaces/IExternalBridge.d.ts.map +1 -0
- package/dist/interfaces/IExternalBridge.js +2 -0
- package/dist/interfaces/IExternalBridge.js.map +1 -0
- package/dist/interfaces/IMonitor.d.ts +1 -0
- package/dist/interfaces/IMonitor.d.ts.map +1 -1
- package/dist/interfaces/IRebalancer.d.ts +25 -25
- package/dist/interfaces/IRebalancer.d.ts.map +1 -1
- package/dist/interfaces/IStrategy.d.ts +36 -3
- package/dist/interfaces/IStrategy.d.ts.map +1 -1
- package/dist/interfaces/IStrategy.js +12 -1
- package/dist/interfaces/IStrategy.js.map +1 -1
- package/dist/metrics/PriceGetter.js +1 -1
- package/dist/metrics/PriceGetter.js.map +1 -1
- package/dist/metrics/scripts/metrics.d.ts +3 -3
- package/dist/monitor/Monitor.d.ts +12 -2
- package/dist/monitor/Monitor.d.ts.map +1 -1
- package/dist/monitor/Monitor.js +46 -1
- package/dist/monitor/Monitor.js.map +1 -1
- package/dist/service.js +40 -17
- package/dist/service.js.map +1 -1
- package/dist/strategy/BaseStrategy.d.ts +12 -6
- package/dist/strategy/BaseStrategy.d.ts.map +1 -1
- package/dist/strategy/BaseStrategy.js +56 -21
- package/dist/strategy/BaseStrategy.js.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.d.ts +1 -1
- package/dist/strategy/CollateralDeficitStrategy.d.ts.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.js +19 -11
- package/dist/strategy/CollateralDeficitStrategy.js.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.test.js +135 -2
- package/dist/strategy/CollateralDeficitStrategy.test.js.map +1 -1
- package/dist/strategy/CompositeStrategy.test.js +13 -0
- package/dist/strategy/CompositeStrategy.test.js.map +1 -1
- package/dist/strategy/MinAmountStrategy.test.js +4 -0
- package/dist/strategy/MinAmountStrategy.test.js.map +1 -1
- package/dist/strategy/StrategyFactory.d.ts +2 -1
- package/dist/strategy/StrategyFactory.d.ts.map +1 -1
- package/dist/strategy/StrategyFactory.js +24 -8
- package/dist/strategy/StrategyFactory.js.map +1 -1
- package/dist/strategy/WeightedStrategy.test.js +6 -0
- package/dist/strategy/WeightedStrategy.test.js.map +1 -1
- package/dist/test/helpers.d.ts +8 -7
- package/dist/test/helpers.d.ts.map +1 -1
- package/dist/test/helpers.js +23 -5
- package/dist/test/helpers.js.map +1 -1
- package/dist/test/lifiMocks.d.ts +51 -0
- package/dist/test/lifiMocks.d.ts.map +1 -0
- package/dist/test/lifiMocks.js +130 -0
- package/dist/test/lifiMocks.js.map +1 -0
- package/dist/tracking/ActionTracker.d.ts +34 -1
- package/dist/tracking/ActionTracker.d.ts.map +1 -1
- package/dist/tracking/ActionTracker.js +233 -26
- package/dist/tracking/ActionTracker.js.map +1 -1
- package/dist/tracking/ActionTracker.test.js +380 -19
- package/dist/tracking/ActionTracker.test.js.map +1 -1
- package/dist/tracking/IActionTracker.d.ts +48 -3
- package/dist/tracking/IActionTracker.d.ts.map +1 -1
- package/dist/tracking/InflightContextAdapter.d.ts.map +1 -1
- package/dist/tracking/InflightContextAdapter.js +24 -7
- package/dist/tracking/InflightContextAdapter.js.map +1 -1
- package/dist/tracking/InflightContextAdapter.test.js +7 -4
- package/dist/tracking/InflightContextAdapter.test.js.map +1 -1
- package/dist/tracking/types.d.ts +33 -2
- package/dist/tracking/types.d.ts.map +1 -1
- package/dist/utils/ExplorerClient.d.ts +3 -1
- package/dist/utils/ExplorerClient.d.ts.map +1 -1
- package/dist/utils/ExplorerClient.js +16 -8
- package/dist/utils/ExplorerClient.js.map +1 -1
- package/dist/utils/bridgeUtils.d.ts +27 -4
- package/dist/utils/bridgeUtils.d.ts.map +1 -1
- package/dist/utils/bridgeUtils.js +38 -0
- package/dist/utils/bridgeUtils.js.map +1 -1
- package/dist/utils/bridgeUtils.test.js +9 -0
- package/dist/utils/bridgeUtils.test.js.map +1 -1
- package/dist/utils/gasEstimation.d.ts +65 -0
- package/dist/utils/gasEstimation.d.ts.map +1 -0
- package/dist/utils/gasEstimation.js +176 -0
- package/dist/utils/gasEstimation.js.map +1 -0
- package/dist/utils/tokenUtils.d.ts +9 -1
- package/dist/utils/tokenUtils.d.ts.map +1 -1
- package/dist/utils/tokenUtils.js +11 -0
- package/dist/utils/tokenUtils.js.map +1 -1
- package/package.json +9 -7
- package/src/bridges/LiFiBridge.ts +538 -0
- package/src/config/RebalancerConfig.test.ts +162 -0
- package/src/config/RebalancerConfig.ts +21 -3
- package/src/config/types.ts +147 -10
- package/src/core/InventoryRebalancer.test.ts +1721 -0
- package/src/core/InventoryRebalancer.ts +1265 -0
- package/src/core/Rebalancer.test.ts +84 -30
- package/src/core/Rebalancer.ts +144 -23
- package/src/core/RebalancerOrchestrator.test.ts +869 -0
- package/src/core/RebalancerOrchestrator.ts +146 -95
- package/src/core/RebalancerService.test.ts +86 -124
- package/src/core/RebalancerService.ts +67 -33
- package/src/e2e/collateral-deficit.e2e-test.ts +2 -4
- package/src/e2e/composite.e2e-test.ts +5 -5
- package/src/e2e/harness/BridgeSetup.ts +28 -1
- package/src/e2e/harness/ForkIndexer.ts +1 -0
- package/src/e2e/harness/TestHelpers.ts +1 -4
- package/src/e2e/harness/TestRebalancer.ts +10 -7
- package/src/e2e/minAmount.e2e-test.ts +1 -2
- package/src/e2e/weighted.e2e-test.ts +1 -2
- package/src/factories/RebalancerContextFactory.ts +294 -24
- package/src/index.ts +22 -5
- package/src/interfaces/IExternalBridge.ts +115 -0
- package/src/interfaces/IMonitor.ts +1 -0
- package/src/interfaces/IRebalancer.ts +45 -29
- package/src/interfaces/IStrategy.ts +50 -3
- package/src/metrics/PriceGetter.ts +1 -1
- package/src/monitor/Monitor.ts +81 -2
- package/src/service.ts +59 -18
- package/src/strategy/BaseStrategy.ts +77 -24
- package/src/strategy/CollateralDeficitStrategy.test.ts +181 -4
- package/src/strategy/CollateralDeficitStrategy.ts +42 -15
- package/src/strategy/CompositeStrategy.test.ts +13 -0
- package/src/strategy/MinAmountStrategy.test.ts +4 -0
- package/src/strategy/StrategyFactory.ts +33 -6
- package/src/strategy/WeightedStrategy.test.ts +6 -0
- package/src/test/helpers.ts +39 -14
- package/src/test/lifiMocks.ts +174 -0
- package/src/tracking/ActionTracker.test.ts +443 -19
- package/src/tracking/ActionTracker.ts +339 -28
- package/src/tracking/IActionTracker.ts +59 -3
- package/src/tracking/InflightContextAdapter.test.ts +7 -4
- package/src/tracking/InflightContextAdapter.ts +42 -9
- package/src/tracking/types.ts +45 -2
- package/src/utils/ExplorerClient.ts +27 -10
- package/src/utils/bridgeUtils.test.ts +9 -0
- package/src/utils/bridgeUtils.ts +75 -6
- package/src/utils/gasEstimation.ts +272 -0
- package/src/utils/tokenUtils.ts +12 -0
- package/dist/tracking/index.d.ts +0 -7
- package/dist/tracking/index.d.ts.map +0 -1
- package/dist/tracking/index.js +0 -6
- package/dist/tracking/index.js.map +0 -1
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -5
- package/dist/utils/index.js.map +0 -1
- package/src/tracking/index.ts +0 -36
- package/src/utils/index.ts +0 -4
|
@@ -6,16 +6,20 @@ import Sinon from 'sinon';
|
|
|
6
6
|
import type { MultiProvider, Token, WarpCore } from '@hyperlane-xyz/sdk';
|
|
7
7
|
|
|
8
8
|
import type { RebalancerConfig } from '../config/RebalancerConfig.js';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_INTENT_TTL_MS,
|
|
11
|
+
RebalancerStrategyOptions,
|
|
12
|
+
} from '../config/types.js';
|
|
10
13
|
import { RebalancerContextFactory } from '../factories/RebalancerContextFactory.js';
|
|
14
|
+
import type { ExternalBridgeRegistry } from '../interfaces/IExternalBridge.js';
|
|
11
15
|
import { MonitorEventType } from '../interfaces/IMonitor.js';
|
|
12
16
|
import type { IRebalancer } from '../interfaces/IRebalancer.js';
|
|
13
17
|
import type { IStrategy } from '../interfaces/IStrategy.js';
|
|
14
18
|
import { Metrics } from '../metrics/Metrics.js';
|
|
15
19
|
import { Monitor } from '../monitor/Monitor.js';
|
|
16
20
|
import { TEST_ADDRESSES, getTestAddress } from '../test/helpers.js';
|
|
17
|
-
import type { IActionTracker } from '../tracking/
|
|
18
|
-
import { InflightContextAdapter } from '../tracking/
|
|
21
|
+
import type { IActionTracker } from '../tracking/IActionTracker.js';
|
|
22
|
+
import { InflightContextAdapter } from '../tracking/InflightContextAdapter.js';
|
|
19
23
|
|
|
20
24
|
import {
|
|
21
25
|
RebalancerService,
|
|
@@ -46,6 +50,7 @@ function createMockRebalancerConfig(): RebalancerConfig {
|
|
|
46
50
|
},
|
|
47
51
|
},
|
|
48
52
|
],
|
|
53
|
+
intentTTL: DEFAULT_INTENT_TTL_MS,
|
|
49
54
|
} as RebalancerConfig;
|
|
50
55
|
}
|
|
51
56
|
|
|
@@ -85,6 +90,7 @@ function createMockWarpCore(): WarpCore {
|
|
|
85
90
|
|
|
86
91
|
function createMockRebalancer(): IRebalancer & { rebalance: Sinon.SinonStub } {
|
|
87
92
|
return {
|
|
93
|
+
rebalancerType: 'movableCollateral' as const,
|
|
88
94
|
rebalance: Sinon.stub().resolves([]),
|
|
89
95
|
};
|
|
90
96
|
}
|
|
@@ -114,6 +120,10 @@ function createMockActionTracker(): IActionTracker {
|
|
|
114
120
|
syncTransfers: Sinon.stub().resolves(),
|
|
115
121
|
syncRebalanceIntents: Sinon.stub().resolves(),
|
|
116
122
|
syncRebalanceActions: Sinon.stub().resolves(),
|
|
123
|
+
syncInventoryMovementActions: Sinon.stub().resolves({
|
|
124
|
+
completed: 0,
|
|
125
|
+
failed: 0,
|
|
126
|
+
}),
|
|
117
127
|
logStoreContents: Sinon.stub().resolves(),
|
|
118
128
|
getInProgressTransfers: Sinon.stub().resolves([]),
|
|
119
129
|
getActiveRebalanceIntents: Sinon.stub().resolves([]),
|
|
@@ -123,6 +133,10 @@ function createMockActionTracker(): IActionTracker {
|
|
|
123
133
|
getRebalanceIntent: Sinon.stub().resolves(undefined),
|
|
124
134
|
getRebalanceAction: Sinon.stub().resolves(undefined),
|
|
125
135
|
getInProgressActions: Sinon.stub().resolves([]),
|
|
136
|
+
getPartiallyFulfilledInventoryIntents: Sinon.stub().resolves([]),
|
|
137
|
+
getActionsByType: Sinon.stub().resolves([]),
|
|
138
|
+
getActionsForIntent: Sinon.stub().resolves([]),
|
|
139
|
+
getInflightInventoryMovements: Sinon.stub().resolves(0n),
|
|
126
140
|
};
|
|
127
141
|
}
|
|
128
142
|
|
|
@@ -168,7 +182,12 @@ function createMockContextFactory(
|
|
|
168
182
|
getWarpCore: () => warpCore,
|
|
169
183
|
getTokenForChain: (chain: string) =>
|
|
170
184
|
warpCore.tokens.find((t) => t.chainName === chain),
|
|
171
|
-
createRebalancer: () => rebalancer,
|
|
185
|
+
createRebalancer: (_actionTracker: IActionTracker) => rebalancer,
|
|
186
|
+
createRebalancers: async (_actionTracker: IActionTracker) => ({
|
|
187
|
+
rebalancers: [rebalancer],
|
|
188
|
+
externalBridgeRegistry: {},
|
|
189
|
+
inventoryConfig: undefined,
|
|
190
|
+
}),
|
|
172
191
|
createStrategy: async () => strategy,
|
|
173
192
|
createMonitor: () => monitor,
|
|
174
193
|
createMetrics: async () => overrides.metrics ?? ({} as Metrics),
|
|
@@ -176,6 +195,33 @@ function createMockContextFactory(
|
|
|
176
195
|
tracker: actionTracker,
|
|
177
196
|
adapter: inflightAdapter,
|
|
178
197
|
}),
|
|
198
|
+
createOrchestrator: (options: {
|
|
199
|
+
strategy: IStrategy;
|
|
200
|
+
actionTracker: IActionTracker;
|
|
201
|
+
inflightContextAdapter: InflightContextAdapter;
|
|
202
|
+
rebalancers: IRebalancer[];
|
|
203
|
+
externalBridgeRegistry: Partial<ExternalBridgeRegistry>;
|
|
204
|
+
metrics?: Metrics;
|
|
205
|
+
}) => ({
|
|
206
|
+
executeCycle: Sinon.stub().callsFake(async (_event: any) => {
|
|
207
|
+
// Simulate orchestrator behavior: call strategy, then rebalancer, then record metrics
|
|
208
|
+
const strategyWithGetRoutes = options.strategy as any;
|
|
209
|
+
const routes = strategyWithGetRoutes.getRebalancingRoutes?.() ?? [];
|
|
210
|
+
if (routes.length > 0 && options.rebalancers[0]) {
|
|
211
|
+
const results = await options.rebalancers[0].rebalance(routes);
|
|
212
|
+
if (options.metrics && results) {
|
|
213
|
+
results.forEach((result: any) => {
|
|
214
|
+
if (result.success) {
|
|
215
|
+
(options.metrics as any).recordRebalancerSuccess?.();
|
|
216
|
+
} else {
|
|
217
|
+
(options.metrics as any).recordRebalancerFailure?.();
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return { success: true };
|
|
223
|
+
}),
|
|
224
|
+
}),
|
|
179
225
|
} as unknown as RebalancerContextFactory;
|
|
180
226
|
}
|
|
181
227
|
|
|
@@ -189,13 +235,11 @@ interface DaemonTestSetup {
|
|
|
189
235
|
async function setupDaemonTest(
|
|
190
236
|
sandbox: Sinon.SinonSandbox,
|
|
191
237
|
options: {
|
|
192
|
-
intentIds?: string[];
|
|
193
238
|
rebalanceResults: Array<{
|
|
194
239
|
route: {
|
|
195
240
|
origin: string;
|
|
196
241
|
destination: string;
|
|
197
242
|
amount: bigint;
|
|
198
|
-
intentId: string;
|
|
199
243
|
bridge: string;
|
|
200
244
|
};
|
|
201
245
|
success: boolean;
|
|
@@ -212,14 +256,6 @@ async function setupDaemonTest(
|
|
|
212
256
|
},
|
|
213
257
|
): Promise<DaemonTestSetup> {
|
|
214
258
|
const actionTracker = createMockActionTracker();
|
|
215
|
-
let intentIndex = 0;
|
|
216
|
-
(actionTracker.createRebalanceIntent as Sinon.SinonStub).callsFake(
|
|
217
|
-
async () => ({
|
|
218
|
-
id: options.intentIds?.[intentIndex] ?? `intent-${intentIndex + 1}`,
|
|
219
|
-
status: 'not_started' as const,
|
|
220
|
-
...(intentIndex++, {}),
|
|
221
|
-
}),
|
|
222
|
-
);
|
|
223
259
|
|
|
224
260
|
const rebalancer = createMockRebalancer();
|
|
225
261
|
rebalancer.rebalance.resolves(options.rebalanceResults);
|
|
@@ -253,6 +289,7 @@ async function setupDaemonTest(
|
|
|
253
289
|
const service = new RebalancerService(
|
|
254
290
|
createMockMultiProvider(),
|
|
255
291
|
undefined,
|
|
292
|
+
undefined,
|
|
256
293
|
{} as any,
|
|
257
294
|
createMockRebalancerConfig(),
|
|
258
295
|
{ mode: 'daemon', checkFrequency: 60000, logger: testLogger },
|
|
@@ -312,6 +349,7 @@ describe('RebalancerService', () => {
|
|
|
312
349
|
const service = new RebalancerService(
|
|
313
350
|
createMockMultiProvider(),
|
|
314
351
|
undefined,
|
|
352
|
+
undefined,
|
|
315
353
|
{} as any,
|
|
316
354
|
createMockRebalancerConfig(),
|
|
317
355
|
config,
|
|
@@ -347,6 +385,7 @@ describe('RebalancerService', () => {
|
|
|
347
385
|
const service = new RebalancerService(
|
|
348
386
|
createMockMultiProvider(),
|
|
349
387
|
undefined,
|
|
388
|
+
undefined,
|
|
350
389
|
{} as any,
|
|
351
390
|
createMockRebalancerConfig(),
|
|
352
391
|
config,
|
|
@@ -373,6 +412,7 @@ describe('RebalancerService', () => {
|
|
|
373
412
|
const service = new RebalancerService(
|
|
374
413
|
createMockMultiProvider(),
|
|
375
414
|
undefined,
|
|
415
|
+
undefined,
|
|
376
416
|
{} as any,
|
|
377
417
|
createMockRebalancerConfig(),
|
|
378
418
|
config,
|
|
@@ -399,6 +439,7 @@ describe('RebalancerService', () => {
|
|
|
399
439
|
const service = new RebalancerService(
|
|
400
440
|
createMockMultiProvider(),
|
|
401
441
|
undefined,
|
|
442
|
+
undefined,
|
|
402
443
|
{} as any,
|
|
403
444
|
createMockRebalancerConfig(),
|
|
404
445
|
config,
|
|
@@ -439,6 +480,7 @@ describe('RebalancerService', () => {
|
|
|
439
480
|
},
|
|
440
481
|
},
|
|
441
482
|
],
|
|
483
|
+
intentTTL: DEFAULT_INTENT_TTL_MS,
|
|
442
484
|
} as RebalancerConfig;
|
|
443
485
|
|
|
444
486
|
const config: RebalancerServiceConfig = {
|
|
@@ -449,6 +491,7 @@ describe('RebalancerService', () => {
|
|
|
449
491
|
const service = new RebalancerService(
|
|
450
492
|
createMockMultiProvider(),
|
|
451
493
|
undefined,
|
|
494
|
+
undefined,
|
|
452
495
|
{} as any,
|
|
453
496
|
configWithoutBridge,
|
|
454
497
|
config,
|
|
@@ -476,6 +519,7 @@ describe('RebalancerService', () => {
|
|
|
476
519
|
const service = new RebalancerService(
|
|
477
520
|
createMockMultiProvider(),
|
|
478
521
|
undefined,
|
|
522
|
+
undefined,
|
|
479
523
|
{} as any,
|
|
480
524
|
createMockRebalancerConfig(),
|
|
481
525
|
config,
|
|
@@ -505,6 +549,7 @@ describe('RebalancerService', () => {
|
|
|
505
549
|
const service = new RebalancerService(
|
|
506
550
|
createMockMultiProvider(),
|
|
507
551
|
undefined,
|
|
552
|
+
undefined,
|
|
508
553
|
{} as any,
|
|
509
554
|
createMockRebalancerConfig(),
|
|
510
555
|
config,
|
|
@@ -530,6 +575,7 @@ describe('RebalancerService', () => {
|
|
|
530
575
|
const service = new RebalancerService(
|
|
531
576
|
createMockMultiProvider(),
|
|
532
577
|
undefined,
|
|
578
|
+
undefined,
|
|
533
579
|
{} as any,
|
|
534
580
|
createMockRebalancerConfig(),
|
|
535
581
|
config,
|
|
@@ -559,6 +605,7 @@ describe('RebalancerService', () => {
|
|
|
559
605
|
const service = new RebalancerService(
|
|
560
606
|
createMockMultiProvider(),
|
|
561
607
|
undefined,
|
|
608
|
+
undefined,
|
|
562
609
|
{} as any,
|
|
563
610
|
createMockRebalancerConfig(),
|
|
564
611
|
config,
|
|
@@ -591,6 +638,7 @@ describe('RebalancerService', () => {
|
|
|
591
638
|
const service = new RebalancerService(
|
|
592
639
|
createMockMultiProvider(),
|
|
593
640
|
undefined,
|
|
641
|
+
undefined,
|
|
594
642
|
{} as any,
|
|
595
643
|
createMockRebalancerConfig(),
|
|
596
644
|
config,
|
|
@@ -674,6 +722,7 @@ describe('RebalancerService', () => {
|
|
|
674
722
|
const service = new RebalancerService(
|
|
675
723
|
createMockMultiProvider(),
|
|
676
724
|
undefined,
|
|
725
|
+
undefined,
|
|
677
726
|
{} as any,
|
|
678
727
|
createMockRebalancerConfig(),
|
|
679
728
|
config,
|
|
@@ -766,6 +815,7 @@ describe('RebalancerService', () => {
|
|
|
766
815
|
const service = new RebalancerService(
|
|
767
816
|
createMockMultiProvider(),
|
|
768
817
|
undefined,
|
|
818
|
+
undefined,
|
|
769
819
|
{} as any,
|
|
770
820
|
createMockRebalancerConfig(),
|
|
771
821
|
config,
|
|
@@ -875,6 +925,7 @@ describe('RebalancerService', () => {
|
|
|
875
925
|
const service = new RebalancerService(
|
|
876
926
|
createMockMultiProvider(),
|
|
877
927
|
undefined,
|
|
928
|
+
undefined,
|
|
878
929
|
{} as any,
|
|
879
930
|
createMockRebalancerConfig(),
|
|
880
931
|
config,
|
|
@@ -891,65 +942,24 @@ describe('RebalancerService', () => {
|
|
|
891
942
|
});
|
|
892
943
|
|
|
893
944
|
expect(recordRebalancerFailure.calledOnce).to.be.true;
|
|
894
|
-
expect(recordRebalancerSuccess.
|
|
945
|
+
expect(recordRebalancerSuccess.calledOnce).to.be.true;
|
|
895
946
|
});
|
|
896
947
|
});
|
|
897
948
|
|
|
898
|
-
describe('daemon mode
|
|
899
|
-
it('should call
|
|
900
|
-
const {
|
|
901
|
-
intentIds: ['intent-123'],
|
|
902
|
-
rebalanceResults: [
|
|
903
|
-
{
|
|
904
|
-
route: {
|
|
905
|
-
origin: 'ethereum',
|
|
906
|
-
destination: 'arbitrum',
|
|
907
|
-
amount: 1000n,
|
|
908
|
-
intentId: 'intent-123',
|
|
909
|
-
bridge: TEST_ADDRESSES.bridge,
|
|
910
|
-
},
|
|
911
|
-
success: false,
|
|
912
|
-
error: 'Gas estimation failed',
|
|
913
|
-
},
|
|
914
|
-
],
|
|
915
|
-
strategyRoutes: [
|
|
916
|
-
{
|
|
917
|
-
origin: 'ethereum',
|
|
918
|
-
destination: 'arbitrum',
|
|
919
|
-
amount: 1000n,
|
|
920
|
-
bridge: TEST_ADDRESSES.bridge,
|
|
921
|
-
},
|
|
922
|
-
],
|
|
923
|
-
});
|
|
924
|
-
|
|
925
|
-
await triggerCycle();
|
|
926
|
-
|
|
927
|
-
expect((actionTracker.failRebalanceIntent as Sinon.SinonStub).calledOnce)
|
|
928
|
-
.to.be.true;
|
|
929
|
-
expect(
|
|
930
|
-
(actionTracker.failRebalanceIntent as Sinon.SinonStub).calledWith(
|
|
931
|
-
'intent-123',
|
|
932
|
-
),
|
|
933
|
-
).to.be.true;
|
|
934
|
-
});
|
|
935
|
-
|
|
936
|
-
it('should call createRebalanceAction with correct intentId when route succeeds', async () => {
|
|
937
|
-
const { actionTracker, triggerCycle } = await setupDaemonTest(sandbox, {
|
|
938
|
-
intentIds: ['intent-456'],
|
|
949
|
+
describe('daemon mode rebalancer calls', () => {
|
|
950
|
+
it('should call rebalancer with routes from strategy', async () => {
|
|
951
|
+
const { rebalancer, triggerCycle } = await setupDaemonTest(sandbox, {
|
|
939
952
|
rebalanceResults: [
|
|
940
953
|
{
|
|
941
954
|
route: {
|
|
942
955
|
origin: 'ethereum',
|
|
943
956
|
destination: 'arbitrum',
|
|
944
957
|
amount: 1000n,
|
|
945
|
-
intentId: 'intent-456',
|
|
946
958
|
bridge: TEST_ADDRESSES.bridge,
|
|
947
959
|
},
|
|
948
960
|
success: true,
|
|
949
961
|
messageId:
|
|
950
962
|
'0x1111111111111111111111111111111111111111111111111111111111111111',
|
|
951
|
-
txHash:
|
|
952
|
-
'0x2222222222222222222222222222222222222222222222222222222222222222',
|
|
953
963
|
},
|
|
954
964
|
],
|
|
955
965
|
strategyRoutes: [
|
|
@@ -964,42 +974,33 @@ describe('RebalancerService', () => {
|
|
|
964
974
|
|
|
965
975
|
await triggerCycle();
|
|
966
976
|
|
|
967
|
-
expect(
|
|
968
|
-
|
|
969
|
-
).to.
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
expect(callArgs.intentId).to.equal('intent-456');
|
|
977
|
+
expect(rebalancer.rebalance.calledOnce).to.be.true;
|
|
978
|
+
const routesPassedToRebalancer = rebalancer.rebalance.firstCall.args[0];
|
|
979
|
+
expect(routesPassedToRebalancer).to.have.lengthOf(1);
|
|
980
|
+
expect(routesPassedToRebalancer[0].origin).to.equal('ethereum');
|
|
981
|
+
expect(routesPassedToRebalancer[0].destination).to.equal('arbitrum');
|
|
973
982
|
});
|
|
974
983
|
|
|
975
|
-
it('should
|
|
976
|
-
const {
|
|
977
|
-
intentIds: ['intent-1', 'intent-2'],
|
|
984
|
+
it('should call rebalancer with multiple routes', async () => {
|
|
985
|
+
const { rebalancer, triggerCycle } = await setupDaemonTest(sandbox, {
|
|
978
986
|
rebalanceResults: [
|
|
979
987
|
{
|
|
980
988
|
route: {
|
|
981
989
|
origin: 'ethereum',
|
|
982
990
|
destination: 'arbitrum',
|
|
983
991
|
amount: 1000n,
|
|
984
|
-
intentId: 'intent-1',
|
|
985
992
|
bridge: TEST_ADDRESSES.bridge,
|
|
986
993
|
},
|
|
987
994
|
success: true,
|
|
988
|
-
messageId:
|
|
989
|
-
'0x1111111111111111111111111111111111111111111111111111111111111111',
|
|
990
|
-
txHash:
|
|
991
|
-
'0x2222222222222222222222222222222222222222222222222222222222222222',
|
|
992
995
|
},
|
|
993
996
|
{
|
|
994
997
|
route: {
|
|
995
998
|
origin: 'arbitrum',
|
|
996
999
|
destination: 'ethereum',
|
|
997
1000
|
amount: 500n,
|
|
998
|
-
intentId: 'intent-2',
|
|
999
1001
|
bridge: TEST_ADDRESSES.bridge,
|
|
1000
1002
|
},
|
|
1001
|
-
success:
|
|
1002
|
-
error: 'Insufficient funds',
|
|
1003
|
+
success: true,
|
|
1003
1004
|
},
|
|
1004
1005
|
],
|
|
1005
1006
|
strategyRoutes: [
|
|
@@ -1020,61 +1021,20 @@ describe('RebalancerService', () => {
|
|
|
1020
1021
|
|
|
1021
1022
|
await triggerCycle();
|
|
1022
1023
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
).to.be.true;
|
|
1027
|
-
expect(
|
|
1028
|
-
(actionTracker.createRebalanceAction as Sinon.SinonStub).firstCall
|
|
1029
|
-
.args[0].intentId,
|
|
1030
|
-
).to.equal('intent-1');
|
|
1031
|
-
|
|
1032
|
-
// Verify failRebalanceIntent called for intent-2 (failure)
|
|
1033
|
-
expect((actionTracker.failRebalanceIntent as Sinon.SinonStub).calledOnce)
|
|
1034
|
-
.to.be.true;
|
|
1035
|
-
expect(
|
|
1036
|
-
(actionTracker.failRebalanceIntent as Sinon.SinonStub).calledWith(
|
|
1037
|
-
'intent-2',
|
|
1038
|
-
),
|
|
1039
|
-
).to.be.true;
|
|
1024
|
+
expect(rebalancer.rebalance.calledOnce).to.be.true;
|
|
1025
|
+
const routesPassedToRebalancer = rebalancer.rebalance.firstCall.args[0];
|
|
1026
|
+
expect(routesPassedToRebalancer).to.have.lengthOf(2);
|
|
1040
1027
|
});
|
|
1041
1028
|
|
|
1042
|
-
it('should
|
|
1029
|
+
it('should not call rebalancer when no routes proposed', async () => {
|
|
1043
1030
|
const { rebalancer, triggerCycle } = await setupDaemonTest(sandbox, {
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
{
|
|
1047
|
-
route: {
|
|
1048
|
-
origin: 'ethereum',
|
|
1049
|
-
destination: 'arbitrum',
|
|
1050
|
-
amount: 1000n,
|
|
1051
|
-
intentId: 'generated-intent-id',
|
|
1052
|
-
bridge: TEST_ADDRESSES.bridge,
|
|
1053
|
-
},
|
|
1054
|
-
success: true,
|
|
1055
|
-
messageId:
|
|
1056
|
-
'0x1111111111111111111111111111111111111111111111111111111111111111',
|
|
1057
|
-
},
|
|
1058
|
-
],
|
|
1059
|
-
strategyRoutes: [
|
|
1060
|
-
{
|
|
1061
|
-
origin: 'ethereum',
|
|
1062
|
-
destination: 'arbitrum',
|
|
1063
|
-
amount: 1000n,
|
|
1064
|
-
bridge: TEST_ADDRESSES.bridge,
|
|
1065
|
-
},
|
|
1066
|
-
],
|
|
1031
|
+
rebalanceResults: [],
|
|
1032
|
+
strategyRoutes: [],
|
|
1067
1033
|
});
|
|
1068
1034
|
|
|
1069
1035
|
await triggerCycle();
|
|
1070
1036
|
|
|
1071
|
-
|
|
1072
|
-
expect(rebalancer.rebalance.calledOnce).to.be.true;
|
|
1073
|
-
const routesPassedToRebalancer = rebalancer.rebalance.firstCall.args[0];
|
|
1074
|
-
expect(routesPassedToRebalancer).to.have.lengthOf(1);
|
|
1075
|
-
expect(routesPassedToRebalancer[0].intentId).to.equal(
|
|
1076
|
-
'generated-intent-id',
|
|
1077
|
-
);
|
|
1037
|
+
expect(rebalancer.rebalance.called).to.be.false;
|
|
1078
1038
|
});
|
|
1079
1039
|
});
|
|
1080
1040
|
|
|
@@ -1093,6 +1053,7 @@ describe('RebalancerService', () => {
|
|
|
1093
1053
|
const service = new RebalancerService(
|
|
1094
1054
|
createMockMultiProvider(),
|
|
1095
1055
|
undefined,
|
|
1056
|
+
undefined,
|
|
1096
1057
|
{} as any,
|
|
1097
1058
|
createMockRebalancerConfig(),
|
|
1098
1059
|
config,
|
|
@@ -1130,6 +1091,7 @@ describe('RebalancerService', () => {
|
|
|
1130
1091
|
const service = new RebalancerService(
|
|
1131
1092
|
createMockMultiProvider(),
|
|
1132
1093
|
undefined,
|
|
1094
|
+
undefined,
|
|
1133
1095
|
{} as any,
|
|
1134
1096
|
createMockRebalancerConfig(),
|
|
1135
1097
|
config,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { randomUUID } from 'crypto';
|
|
2
1
|
import { Logger } from 'pino';
|
|
3
2
|
|
|
4
3
|
import { IRegistry } from '@hyperlane-xyz/registry';
|
|
@@ -15,20 +14,24 @@ import {
|
|
|
15
14
|
getStrategyChainNames,
|
|
16
15
|
} from '../config/types.js';
|
|
17
16
|
import { RebalancerContextFactory } from '../factories/RebalancerContextFactory.js';
|
|
17
|
+
import type { ExternalBridgeRegistry } from '../interfaces/IExternalBridge.js';
|
|
18
18
|
import {
|
|
19
19
|
MonitorEvent,
|
|
20
20
|
MonitorEventType,
|
|
21
21
|
MonitorPollingError,
|
|
22
22
|
MonitorStartError,
|
|
23
23
|
} from '../interfaces/IMonitor.js';
|
|
24
|
-
import type { IRebalancer
|
|
25
|
-
import type {
|
|
24
|
+
import type { IRebalancer } from '../interfaces/IRebalancer.js';
|
|
25
|
+
import type {
|
|
26
|
+
IStrategy,
|
|
27
|
+
MovableCollateralRoute,
|
|
28
|
+
} from '../interfaces/IStrategy.js';
|
|
26
29
|
import { Metrics } from '../metrics/Metrics.js';
|
|
27
|
-
import { Monitor } from '../monitor/Monitor.js';
|
|
28
|
-
|
|
29
|
-
import { RebalancerOrchestrator } from './RebalancerOrchestrator.js';
|
|
30
|
+
import { type InventoryMonitorConfig, Monitor } from '../monitor/Monitor.js';
|
|
31
|
+
import type { IActionTracker } from '../tracking/IActionTracker.js';
|
|
30
32
|
import { InflightContextAdapter } from '../tracking/InflightContextAdapter.js';
|
|
31
|
-
|
|
33
|
+
|
|
34
|
+
import type { RebalancerOrchestrator } from './RebalancerOrchestrator.js';
|
|
32
35
|
|
|
33
36
|
export interface RebalancerServiceConfig {
|
|
34
37
|
/** Execution mode: 'manual' for one-off execution, 'daemon' for continuous monitoring */
|
|
@@ -118,10 +121,10 @@ export class RebalancerService {
|
|
|
118
121
|
private mode: 'manual' | 'daemon';
|
|
119
122
|
private actionTracker?: IActionTracker;
|
|
120
123
|
private inflightContextAdapter?: InflightContextAdapter;
|
|
121
|
-
private orchestrator
|
|
122
|
-
|
|
124
|
+
private orchestrator?: RebalancerOrchestrator;
|
|
123
125
|
constructor(
|
|
124
126
|
private readonly multiProvider: MultiProvider,
|
|
127
|
+
private readonly inventoryMultiProvider: MultiProvider | undefined,
|
|
125
128
|
private readonly multiProtocolProvider: MultiProtocolProvider | undefined,
|
|
126
129
|
private readonly registry: IRegistry,
|
|
127
130
|
private readonly rebalancerConfig: RebalancerConfig,
|
|
@@ -146,17 +149,12 @@ export class RebalancerService {
|
|
|
146
149
|
this.contextFactory = await RebalancerContextFactory.create(
|
|
147
150
|
this.rebalancerConfig,
|
|
148
151
|
this.multiProvider,
|
|
152
|
+
this.inventoryMultiProvider,
|
|
149
153
|
this.multiProtocolProvider,
|
|
150
154
|
this.registry,
|
|
151
155
|
this.logger,
|
|
152
156
|
);
|
|
153
157
|
|
|
154
|
-
// Create monitor (always needed for daemon mode)
|
|
155
|
-
if (this.mode === 'daemon') {
|
|
156
|
-
const checkFrequency = this.config.checkFrequency ?? 60_000;
|
|
157
|
-
this.monitor = this.contextFactory.createMonitor(checkFrequency);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
158
|
// Create metrics if enabled
|
|
161
159
|
if (this.config.withMetrics) {
|
|
162
160
|
this.metrics = await this.contextFactory.createMetrics(
|
|
@@ -168,16 +166,8 @@ export class RebalancerService {
|
|
|
168
166
|
// Create strategy
|
|
169
167
|
this.strategy = await this.contextFactory.createStrategy(this.metrics);
|
|
170
168
|
|
|
171
|
-
// Create rebalancer (unless in monitor-only mode)
|
|
172
|
-
if (!this.config.monitorOnly) {
|
|
173
|
-
this.rebalancer = this.contextFactory.createRebalancer(this.metrics);
|
|
174
|
-
} else {
|
|
175
|
-
this.logger.warn(
|
|
176
|
-
'Running in monitorOnly mode: no transactions will be executed.',
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
169
|
// Create or use provided ActionTracker for tracking inflight actions
|
|
170
|
+
// Must be created BEFORE rebalancer since rebalancer needs it
|
|
181
171
|
if (this.config.actionTracker) {
|
|
182
172
|
// Use externally provided ActionTracker (e.g., for simulation/testing)
|
|
183
173
|
this.actionTracker = this.config.actionTracker;
|
|
@@ -196,14 +186,49 @@ export class RebalancerService {
|
|
|
196
186
|
this.logger.info('ActionTracker initialized');
|
|
197
187
|
}
|
|
198
188
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
189
|
+
// Create rebalancers (both movableCollateral and inventory if configured)
|
|
190
|
+
let rebalancers: IRebalancer[] = [];
|
|
191
|
+
let externalBridgeRegistry: Partial<ExternalBridgeRegistry> = {};
|
|
192
|
+
let inventoryConfig: InventoryMonitorConfig | undefined;
|
|
193
|
+
|
|
194
|
+
if (!this.config.monitorOnly) {
|
|
195
|
+
const result = await this.contextFactory.createRebalancers(
|
|
196
|
+
this.actionTracker,
|
|
197
|
+
this.metrics,
|
|
198
|
+
);
|
|
199
|
+
rebalancers = result.rebalancers;
|
|
200
|
+
externalBridgeRegistry = result.externalBridgeRegistry;
|
|
201
|
+
inventoryConfig = result.inventoryConfig;
|
|
202
|
+
|
|
203
|
+
if (rebalancers.length > 0) {
|
|
204
|
+
this.logger.info(`${rebalancers.length} rebalancer(s) created`);
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
this.logger.warn(
|
|
208
|
+
'Running in monitorOnly mode: no transactions will be executed.',
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Set instance variable for backward compatibility with executeManual
|
|
213
|
+
// (Task 5 will remove this when refactoring executeManual)
|
|
214
|
+
if (rebalancers.length > 0) {
|
|
215
|
+
this.rebalancer = rebalancers[0];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (this.mode === 'daemon') {
|
|
219
|
+
const checkFrequency = this.config.checkFrequency ?? 60_000;
|
|
220
|
+
this.monitor = this.contextFactory.createMonitor(
|
|
221
|
+
checkFrequency,
|
|
222
|
+
inventoryConfig,
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
this.orchestrator = this.contextFactory.createOrchestrator({
|
|
227
|
+
strategy: this.strategy,
|
|
202
228
|
actionTracker: this.actionTracker,
|
|
203
229
|
inflightContextAdapter: this.inflightContextAdapter,
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
logger: this.logger,
|
|
230
|
+
rebalancers,
|
|
231
|
+
externalBridgeRegistry: externalBridgeRegistry,
|
|
207
232
|
metrics: this.metrics,
|
|
208
233
|
});
|
|
209
234
|
|
|
@@ -266,14 +291,15 @@ export class RebalancerService {
|
|
|
266
291
|
originConfig.override?.[destination]?.bridge ?? originConfig.bridge;
|
|
267
292
|
|
|
268
293
|
try {
|
|
269
|
-
const
|
|
270
|
-
intentId: randomUUID(),
|
|
294
|
+
const manualRoute: MovableCollateralRoute & { intentId: string } = {
|
|
271
295
|
origin,
|
|
272
296
|
destination,
|
|
273
297
|
amount: BigInt(toWei(amount, originToken.decimals)),
|
|
298
|
+
executionType: 'movableCollateral',
|
|
274
299
|
bridge,
|
|
300
|
+
intentId: `manual-${Date.now()}`,
|
|
275
301
|
};
|
|
276
|
-
await this.rebalancer.rebalance([
|
|
302
|
+
await this.rebalancer.rebalance([manualRoute]);
|
|
277
303
|
this.logger.info(
|
|
278
304
|
`✅ Manual rebalance from ${origin} to ${destination} for amount ${amount} submitted successfully.`,
|
|
279
305
|
);
|
|
@@ -345,7 +371,15 @@ export class RebalancerService {
|
|
|
345
371
|
process.exit(0);
|
|
346
372
|
}
|
|
347
373
|
|
|
374
|
+
/**
|
|
375
|
+
* Handle token info events from monitor by delegating to orchestrator
|
|
376
|
+
*/
|
|
348
377
|
private async onTokenInfo(event: MonitorEvent): Promise<void> {
|
|
378
|
+
if (!this.orchestrator) {
|
|
379
|
+
this.logger.error('Orchestrator not initialized');
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
349
383
|
await this.orchestrator.executeCycle(event);
|
|
350
384
|
}
|
|
351
385
|
|
|
@@ -285,7 +285,6 @@ describe('Collateral Deficit E2E', function () {
|
|
|
285
285
|
expect(intentToArbitrum!.destination).to.equal(DOMAIN_IDS.anvil2);
|
|
286
286
|
expect(intentToArbitrum!.amount).to.equal(400000000n);
|
|
287
287
|
expect(intentToArbitrum!.status).to.equal('in_progress');
|
|
288
|
-
expect(intentToArbitrum!.fulfilledAmount).to.equal(0n);
|
|
289
288
|
|
|
290
289
|
// Capture intent ID for completion verification
|
|
291
290
|
const rebalanceIntentId = intentToArbitrum!.id;
|
|
@@ -357,7 +356,7 @@ describe('Collateral Deficit E2E', function () {
|
|
|
357
356
|
hyperlaneCore,
|
|
358
357
|
{
|
|
359
358
|
dispatchTx: rebalanceTxReceipt,
|
|
360
|
-
messageId: actionToArbitrum!.messageId
|
|
359
|
+
messageId: actionToArbitrum!.messageId!,
|
|
361
360
|
origin: 'anvil1',
|
|
362
361
|
destination: 'anvil2',
|
|
363
362
|
},
|
|
@@ -388,11 +387,10 @@ describe('Collateral Deficit E2E', function () {
|
|
|
388
387
|
);
|
|
389
388
|
expect(completedAction!.status).to.equal('complete');
|
|
390
389
|
|
|
391
|
-
// Assert: Intent is now complete
|
|
390
|
+
// Assert: Intent is now complete
|
|
392
391
|
const completedIntent =
|
|
393
392
|
await context.tracker.getRebalanceIntent(rebalanceIntentId);
|
|
394
393
|
expect(completedIntent!.status).to.equal('complete');
|
|
395
|
-
expect(completedIntent!.fulfilledAmount).to.equal(400000000n);
|
|
396
394
|
|
|
397
395
|
// Assert: No more in-progress actions
|
|
398
396
|
const remainingActions = await context.tracker.getInProgressActions();
|