@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.
Files changed (213) hide show
  1. package/dist/bridges/LiFiBridge.d.ts +67 -0
  2. package/dist/bridges/LiFiBridge.d.ts.map +1 -0
  3. package/dist/bridges/LiFiBridge.js +386 -0
  4. package/dist/bridges/LiFiBridge.js.map +1 -0
  5. package/dist/config/RebalancerConfig.d.ts +8 -2
  6. package/dist/config/RebalancerConfig.d.ts.map +1 -1
  7. package/dist/config/RebalancerConfig.js +9 -4
  8. package/dist/config/RebalancerConfig.js.map +1 -1
  9. package/dist/config/RebalancerConfig.test.js +135 -1
  10. package/dist/config/RebalancerConfig.test.js.map +1 -1
  11. package/dist/config/types.d.ts +1023 -304
  12. package/dist/config/types.d.ts.map +1 -1
  13. package/dist/config/types.js +113 -10
  14. package/dist/config/types.js.map +1 -1
  15. package/dist/core/InventoryRebalancer.d.ts +190 -0
  16. package/dist/core/InventoryRebalancer.d.ts.map +1 -0
  17. package/dist/core/InventoryRebalancer.js +892 -0
  18. package/dist/core/InventoryRebalancer.js.map +1 -0
  19. package/dist/core/InventoryRebalancer.test.d.ts +2 -0
  20. package/dist/core/InventoryRebalancer.test.d.ts.map +1 -0
  21. package/dist/core/InventoryRebalancer.test.js +1382 -0
  22. package/dist/core/InventoryRebalancer.test.js.map +1 -0
  23. package/dist/core/Rebalancer.d.ts +11 -4
  24. package/dist/core/Rebalancer.d.ts.map +1 -1
  25. package/dist/core/Rebalancer.js +92 -9
  26. package/dist/core/Rebalancer.js.map +1 -1
  27. package/dist/core/Rebalancer.test.js +82 -49
  28. package/dist/core/Rebalancer.test.js.map +1 -1
  29. package/dist/core/RebalancerOrchestrator.d.ts +30 -9
  30. package/dist/core/RebalancerOrchestrator.d.ts.map +1 -1
  31. package/dist/core/RebalancerOrchestrator.js +79 -71
  32. package/dist/core/RebalancerOrchestrator.js.map +1 -1
  33. package/dist/core/RebalancerOrchestrator.test.d.ts +2 -0
  34. package/dist/core/RebalancerOrchestrator.test.d.ts.map +1 -0
  35. package/dist/core/RebalancerOrchestrator.test.js +719 -0
  36. package/dist/core/RebalancerOrchestrator.test.js.map +1 -0
  37. package/dist/core/RebalancerService.d.ts +7 -3
  38. package/dist/core/RebalancerService.d.ts.map +1 -1
  39. package/dist/core/RebalancerService.js +44 -24
  40. package/dist/core/RebalancerService.js.map +1 -1
  41. package/dist/core/RebalancerService.test.js +74 -110
  42. package/dist/core/RebalancerService.test.js.map +1 -1
  43. package/dist/e2e/collateral-deficit.e2e-test.js +1 -3
  44. package/dist/e2e/collateral-deficit.e2e-test.js.map +1 -1
  45. package/dist/e2e/composite.e2e-test.js.map +1 -1
  46. package/dist/e2e/harness/BridgeSetup.d.ts +6 -0
  47. package/dist/e2e/harness/BridgeSetup.d.ts.map +1 -1
  48. package/dist/e2e/harness/BridgeSetup.js +10 -1
  49. package/dist/e2e/harness/BridgeSetup.js.map +1 -1
  50. package/dist/e2e/harness/ForkIndexer.d.ts.map +1 -1
  51. package/dist/e2e/harness/ForkIndexer.js +1 -0
  52. package/dist/e2e/harness/ForkIndexer.js.map +1 -1
  53. package/dist/e2e/harness/TestHelpers.d.ts.map +1 -1
  54. package/dist/e2e/harness/TestHelpers.js +1 -4
  55. package/dist/e2e/harness/TestHelpers.js.map +1 -1
  56. package/dist/e2e/harness/TestRebalancer.d.ts +1 -1
  57. package/dist/e2e/harness/TestRebalancer.d.ts.map +1 -1
  58. package/dist/e2e/harness/TestRebalancer.js +9 -9
  59. package/dist/e2e/harness/TestRebalancer.js.map +1 -1
  60. package/dist/e2e/minAmount.e2e-test.js +0 -1
  61. package/dist/e2e/minAmount.e2e-test.js.map +1 -1
  62. package/dist/e2e/weighted.e2e-test.js +0 -1
  63. package/dist/e2e/weighted.e2e-test.js.map +1 -1
  64. package/dist/factories/RebalancerContextFactory.d.ts +48 -6
  65. package/dist/factories/RebalancerContextFactory.d.ts.map +1 -1
  66. package/dist/factories/RebalancerContextFactory.js +171 -17
  67. package/dist/factories/RebalancerContextFactory.js.map +1 -1
  68. package/dist/index.d.ts +6 -6
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +2 -2
  71. package/dist/index.js.map +1 -1
  72. package/dist/interfaces/IExternalBridge.d.ts +101 -0
  73. package/dist/interfaces/IExternalBridge.d.ts.map +1 -0
  74. package/dist/interfaces/IExternalBridge.js +2 -0
  75. package/dist/interfaces/IExternalBridge.js.map +1 -0
  76. package/dist/interfaces/IMonitor.d.ts +1 -0
  77. package/dist/interfaces/IMonitor.d.ts.map +1 -1
  78. package/dist/interfaces/IRebalancer.d.ts +25 -25
  79. package/dist/interfaces/IRebalancer.d.ts.map +1 -1
  80. package/dist/interfaces/IStrategy.d.ts +36 -3
  81. package/dist/interfaces/IStrategy.d.ts.map +1 -1
  82. package/dist/interfaces/IStrategy.js +12 -1
  83. package/dist/interfaces/IStrategy.js.map +1 -1
  84. package/dist/metrics/PriceGetter.js +1 -1
  85. package/dist/metrics/PriceGetter.js.map +1 -1
  86. package/dist/metrics/scripts/metrics.d.ts +3 -3
  87. package/dist/monitor/Monitor.d.ts +12 -2
  88. package/dist/monitor/Monitor.d.ts.map +1 -1
  89. package/dist/monitor/Monitor.js +46 -1
  90. package/dist/monitor/Monitor.js.map +1 -1
  91. package/dist/service.js +40 -17
  92. package/dist/service.js.map +1 -1
  93. package/dist/strategy/BaseStrategy.d.ts +12 -6
  94. package/dist/strategy/BaseStrategy.d.ts.map +1 -1
  95. package/dist/strategy/BaseStrategy.js +56 -21
  96. package/dist/strategy/BaseStrategy.js.map +1 -1
  97. package/dist/strategy/CollateralDeficitStrategy.d.ts +1 -1
  98. package/dist/strategy/CollateralDeficitStrategy.d.ts.map +1 -1
  99. package/dist/strategy/CollateralDeficitStrategy.js +19 -11
  100. package/dist/strategy/CollateralDeficitStrategy.js.map +1 -1
  101. package/dist/strategy/CollateralDeficitStrategy.test.js +135 -2
  102. package/dist/strategy/CollateralDeficitStrategy.test.js.map +1 -1
  103. package/dist/strategy/CompositeStrategy.test.js +13 -0
  104. package/dist/strategy/CompositeStrategy.test.js.map +1 -1
  105. package/dist/strategy/MinAmountStrategy.test.js +4 -0
  106. package/dist/strategy/MinAmountStrategy.test.js.map +1 -1
  107. package/dist/strategy/StrategyFactory.d.ts +2 -1
  108. package/dist/strategy/StrategyFactory.d.ts.map +1 -1
  109. package/dist/strategy/StrategyFactory.js +24 -8
  110. package/dist/strategy/StrategyFactory.js.map +1 -1
  111. package/dist/strategy/WeightedStrategy.test.js +6 -0
  112. package/dist/strategy/WeightedStrategy.test.js.map +1 -1
  113. package/dist/test/helpers.d.ts +8 -7
  114. package/dist/test/helpers.d.ts.map +1 -1
  115. package/dist/test/helpers.js +23 -5
  116. package/dist/test/helpers.js.map +1 -1
  117. package/dist/test/lifiMocks.d.ts +51 -0
  118. package/dist/test/lifiMocks.d.ts.map +1 -0
  119. package/dist/test/lifiMocks.js +130 -0
  120. package/dist/test/lifiMocks.js.map +1 -0
  121. package/dist/tracking/ActionTracker.d.ts +34 -1
  122. package/dist/tracking/ActionTracker.d.ts.map +1 -1
  123. package/dist/tracking/ActionTracker.js +233 -26
  124. package/dist/tracking/ActionTracker.js.map +1 -1
  125. package/dist/tracking/ActionTracker.test.js +380 -19
  126. package/dist/tracking/ActionTracker.test.js.map +1 -1
  127. package/dist/tracking/IActionTracker.d.ts +48 -3
  128. package/dist/tracking/IActionTracker.d.ts.map +1 -1
  129. package/dist/tracking/InflightContextAdapter.d.ts.map +1 -1
  130. package/dist/tracking/InflightContextAdapter.js +24 -7
  131. package/dist/tracking/InflightContextAdapter.js.map +1 -1
  132. package/dist/tracking/InflightContextAdapter.test.js +7 -4
  133. package/dist/tracking/InflightContextAdapter.test.js.map +1 -1
  134. package/dist/tracking/types.d.ts +33 -2
  135. package/dist/tracking/types.d.ts.map +1 -1
  136. package/dist/utils/ExplorerClient.d.ts +3 -1
  137. package/dist/utils/ExplorerClient.d.ts.map +1 -1
  138. package/dist/utils/ExplorerClient.js +16 -8
  139. package/dist/utils/ExplorerClient.js.map +1 -1
  140. package/dist/utils/bridgeUtils.d.ts +27 -4
  141. package/dist/utils/bridgeUtils.d.ts.map +1 -1
  142. package/dist/utils/bridgeUtils.js +38 -0
  143. package/dist/utils/bridgeUtils.js.map +1 -1
  144. package/dist/utils/bridgeUtils.test.js +9 -0
  145. package/dist/utils/bridgeUtils.test.js.map +1 -1
  146. package/dist/utils/gasEstimation.d.ts +65 -0
  147. package/dist/utils/gasEstimation.d.ts.map +1 -0
  148. package/dist/utils/gasEstimation.js +176 -0
  149. package/dist/utils/gasEstimation.js.map +1 -0
  150. package/dist/utils/tokenUtils.d.ts +9 -1
  151. package/dist/utils/tokenUtils.d.ts.map +1 -1
  152. package/dist/utils/tokenUtils.js +11 -0
  153. package/dist/utils/tokenUtils.js.map +1 -1
  154. package/package.json +9 -7
  155. package/src/bridges/LiFiBridge.ts +538 -0
  156. package/src/config/RebalancerConfig.test.ts +162 -0
  157. package/src/config/RebalancerConfig.ts +21 -3
  158. package/src/config/types.ts +147 -10
  159. package/src/core/InventoryRebalancer.test.ts +1721 -0
  160. package/src/core/InventoryRebalancer.ts +1265 -0
  161. package/src/core/Rebalancer.test.ts +84 -30
  162. package/src/core/Rebalancer.ts +144 -23
  163. package/src/core/RebalancerOrchestrator.test.ts +869 -0
  164. package/src/core/RebalancerOrchestrator.ts +146 -95
  165. package/src/core/RebalancerService.test.ts +86 -124
  166. package/src/core/RebalancerService.ts +67 -33
  167. package/src/e2e/collateral-deficit.e2e-test.ts +2 -4
  168. package/src/e2e/composite.e2e-test.ts +5 -5
  169. package/src/e2e/harness/BridgeSetup.ts +28 -1
  170. package/src/e2e/harness/ForkIndexer.ts +1 -0
  171. package/src/e2e/harness/TestHelpers.ts +1 -4
  172. package/src/e2e/harness/TestRebalancer.ts +10 -7
  173. package/src/e2e/minAmount.e2e-test.ts +1 -2
  174. package/src/e2e/weighted.e2e-test.ts +1 -2
  175. package/src/factories/RebalancerContextFactory.ts +294 -24
  176. package/src/index.ts +22 -5
  177. package/src/interfaces/IExternalBridge.ts +115 -0
  178. package/src/interfaces/IMonitor.ts +1 -0
  179. package/src/interfaces/IRebalancer.ts +45 -29
  180. package/src/interfaces/IStrategy.ts +50 -3
  181. package/src/metrics/PriceGetter.ts +1 -1
  182. package/src/monitor/Monitor.ts +81 -2
  183. package/src/service.ts +59 -18
  184. package/src/strategy/BaseStrategy.ts +77 -24
  185. package/src/strategy/CollateralDeficitStrategy.test.ts +181 -4
  186. package/src/strategy/CollateralDeficitStrategy.ts +42 -15
  187. package/src/strategy/CompositeStrategy.test.ts +13 -0
  188. package/src/strategy/MinAmountStrategy.test.ts +4 -0
  189. package/src/strategy/StrategyFactory.ts +33 -6
  190. package/src/strategy/WeightedStrategy.test.ts +6 -0
  191. package/src/test/helpers.ts +39 -14
  192. package/src/test/lifiMocks.ts +174 -0
  193. package/src/tracking/ActionTracker.test.ts +443 -19
  194. package/src/tracking/ActionTracker.ts +339 -28
  195. package/src/tracking/IActionTracker.ts +59 -3
  196. package/src/tracking/InflightContextAdapter.test.ts +7 -4
  197. package/src/tracking/InflightContextAdapter.ts +42 -9
  198. package/src/tracking/types.ts +45 -2
  199. package/src/utils/ExplorerClient.ts +27 -10
  200. package/src/utils/bridgeUtils.test.ts +9 -0
  201. package/src/utils/bridgeUtils.ts +75 -6
  202. package/src/utils/gasEstimation.ts +272 -0
  203. package/src/utils/tokenUtils.ts +12 -0
  204. package/dist/tracking/index.d.ts +0 -7
  205. package/dist/tracking/index.d.ts.map +0 -1
  206. package/dist/tracking/index.js +0 -6
  207. package/dist/tracking/index.js.map +0 -1
  208. package/dist/utils/index.d.ts +0 -5
  209. package/dist/utils/index.d.ts.map +0 -1
  210. package/dist/utils/index.js +0 -5
  211. package/dist/utils/index.js.map +0 -1
  212. package/src/tracking/index.ts +0 -36
  213. package/src/utils/index.ts +0 -4
@@ -1,52 +1,81 @@
1
1
  import { Logger } from 'pino';
2
2
 
3
- import { type MultiProvider } from '@hyperlane-xyz/sdk';
4
-
5
3
  import { RebalancerConfig } from '../config/RebalancerConfig.js';
6
4
  import { getStrategyChainNames } from '../config/types.js';
7
- import { type MonitorEvent } from '../interfaces/IMonitor.js';
8
- import type { IRebalancer, RebalanceRoute } from '../interfaces/IRebalancer.js';
5
+ import type { ExternalBridgeRegistry } from '../interfaces/IExternalBridge.js';
6
+ import {
7
+ type ConfirmedBlockTags,
8
+ type MonitorEvent,
9
+ } from '../interfaces/IMonitor.js';
10
+ import type {
11
+ ExecutionResult,
12
+ IRebalancer,
13
+ RebalancerType,
14
+ } from '../interfaces/IRebalancer.js';
9
15
  import type { IStrategy, StrategyRoute } from '../interfaces/IStrategy.js';
10
- import { Metrics } from '../metrics/Metrics.js';
11
16
  import {
12
- type IActionTracker,
13
- InflightContextAdapter,
14
- } from '../tracking/index.js';
17
+ isInventoryRoute,
18
+ isMovableCollateralRoute,
19
+ } from '../interfaces/IStrategy.js';
20
+ import { Metrics } from '../metrics/Metrics.js';
21
+ import type { IActionTracker } from '../tracking/IActionTracker.js';
22
+ import { InflightContextAdapter } from '../tracking/InflightContextAdapter.js';
15
23
  import { getRawBalances } from '../utils/balanceUtils.js';
16
24
 
25
+ import { InventoryRebalancer } from './InventoryRebalancer.js';
26
+
27
+ /**
28
+ * Result of a rebalancing cycle.
29
+ * executedCount/failedCount: Counts from movable_collateral execution ONLY
30
+ */
31
+ export interface CycleResult {
32
+ balances: Record<string, bigint>;
33
+ proposedRoutes: StrategyRoute[];
34
+ executedCount: number;
35
+ failedCount: number;
36
+ }
37
+
17
38
  export interface RebalancerOrchestratorDeps {
18
39
  strategy: IStrategy;
19
- rebalancer: IRebalancer | undefined;
20
40
  actionTracker: IActionTracker;
21
41
  inflightContextAdapter: InflightContextAdapter;
22
- multiProvider: MultiProvider;
23
42
  rebalancerConfig: RebalancerConfig;
24
43
  logger: Logger;
44
+
45
+ rebalancers: IRebalancer[];
46
+
47
+ externalBridgeRegistry?: Partial<ExternalBridgeRegistry>;
25
48
  metrics?: Metrics;
26
49
  }
27
50
 
28
51
  export class RebalancerOrchestrator {
29
52
  private readonly strategy: IStrategy;
30
- private readonly rebalancer: IRebalancer | undefined;
31
53
  private readonly actionTracker: IActionTracker;
32
54
  private readonly inflightContextAdapter: InflightContextAdapter;
33
- private readonly multiProvider: MultiProvider;
34
55
  private readonly rebalancerConfig: RebalancerConfig;
35
56
  private readonly logger: Logger;
57
+ private readonly rebalancersByType: Map<RebalancerType, IRebalancer>;
58
+ private readonly externalBridgeRegistry?: Partial<ExternalBridgeRegistry>;
36
59
  private readonly metrics?: Metrics;
37
60
 
38
61
  constructor(deps: RebalancerOrchestratorDeps) {
39
62
  this.strategy = deps.strategy;
40
- this.rebalancer = deps.rebalancer;
41
63
  this.actionTracker = deps.actionTracker;
42
64
  this.inflightContextAdapter = deps.inflightContextAdapter;
43
- this.multiProvider = deps.multiProvider;
44
65
  this.rebalancerConfig = deps.rebalancerConfig;
45
66
  this.logger = deps.logger;
67
+ this.rebalancersByType = new Map(
68
+ deps.rebalancers.map((r) => [r.rebalancerType, r]),
69
+ );
70
+ this.externalBridgeRegistry = deps.externalBridgeRegistry;
46
71
  this.metrics = deps.metrics;
47
72
  }
48
73
 
49
- async executeCycle(event: MonitorEvent): Promise<void> {
74
+ /**
75
+ * Execute a single rebalancing cycle.
76
+ * Processes monitor event, evaluates strategy, and executes routes.
77
+ */
78
+ async executeCycle(event: MonitorEvent): Promise<CycleResult> {
50
79
  this.logger.info('Polling cycle started');
51
80
 
52
81
  const { metrics } = this;
@@ -74,12 +103,17 @@ export class RebalancerOrchestrator {
74
103
  'Router balances',
75
104
  );
76
105
 
106
+ // Get inflight context for strategy decision-making
77
107
  const inflightContext = await this.getInflightContext();
108
+
78
109
  const strategyRoutes = this.strategy.getRebalancingRoutes(
79
110
  rawBalances,
80
111
  inflightContext,
81
112
  );
82
113
 
114
+ let executedCount = 0;
115
+ let failedCount = 0;
116
+
83
117
  if (strategyRoutes.length > 0) {
84
118
  this.logger.info(
85
119
  {
@@ -92,18 +126,33 @@ export class RebalancerOrchestrator {
92
126
  'Routes proposed',
93
127
  );
94
128
 
95
- if (this.rebalancer) {
96
- await this.executeWithTracking(strategyRoutes);
97
- }
129
+ const results = await this.executeWithTracking(strategyRoutes, event);
130
+ executedCount = results.executedCount;
131
+ failedCount = results.failedCount;
98
132
  } else {
99
133
  this.logger.info('No rebalancing needed');
100
134
  }
101
135
 
136
+ const inventoryRebalancer = this.rebalancersByType.get('inventory');
137
+ if (inventoryRebalancer && strategyRoutes.length === 0) {
138
+ await this.executeRoutes([], inventoryRebalancer, event);
139
+ }
140
+
102
141
  this.logger.info('Polling cycle completed');
142
+
143
+ return {
144
+ balances: rawBalances,
145
+ proposedRoutes: strategyRoutes,
146
+ executedCount,
147
+ failedCount,
148
+ };
103
149
  }
104
150
 
151
+ /**
152
+ * Sync action tracker with current chain state.
153
+ */
105
154
  private async syncActionTracker(
106
- confirmedBlockTags: MonitorEvent['confirmedBlockTags'],
155
+ confirmedBlockTags?: ConfirmedBlockTags,
107
156
  ): Promise<void> {
108
157
  try {
109
158
  await Promise.all([
@@ -111,6 +160,14 @@ export class RebalancerOrchestrator {
111
160
  this.actionTracker.syncRebalanceIntents(),
112
161
  this.actionTracker.syncRebalanceActions(confirmedBlockTags),
113
162
  ]);
163
+
164
+ // Sync inventory movement actions via external bridge API
165
+ if (this.externalBridgeRegistry) {
166
+ await this.actionTracker.syncInventoryMovementActions(
167
+ this.externalBridgeRegistry,
168
+ );
169
+ }
170
+
114
171
  await this.actionTracker.logStoreContents();
115
172
  } catch (error) {
116
173
  this.logger.warn(
@@ -120,103 +177,97 @@ export class RebalancerOrchestrator {
120
177
  }
121
178
  }
122
179
 
180
+ /**
181
+ * Get inflight context for strategy decision-making
182
+ */
123
183
  private async getInflightContext() {
124
184
  return this.inflightContextAdapter.getInflightContext();
125
185
  }
126
186
 
127
187
  private async executeWithTracking(
128
- strategyRoutes: StrategyRoute[],
129
- ): Promise<void> {
130
- if (!this.rebalancer) {
131
- this.logger.warn('Rebalancer not available, skipping execution');
132
- return;
188
+ routes: StrategyRoute[],
189
+ event: MonitorEvent,
190
+ ): Promise<{ executedCount: number; failedCount: number }> {
191
+ const movableCollateral = routes.filter(isMovableCollateralRoute);
192
+ const inventory = routes.filter(isInventoryRoute);
193
+
194
+ let executedCount = 0;
195
+ let failedCount = 0;
196
+
197
+ const movableCollateralRebalancer =
198
+ this.rebalancersByType.get('movableCollateral');
199
+ if (movableCollateral.length > 0 && movableCollateralRebalancer) {
200
+ const results = await this.executeRoutes(
201
+ movableCollateral,
202
+ movableCollateralRebalancer,
203
+ event,
204
+ );
205
+ executedCount = results.filter((r) => r.success).length;
206
+ failedCount = results.filter((r) => !r.success).length;
133
207
  }
134
208
 
135
- const rebalanceRoutes: RebalanceRoute[] = [];
136
- const intentIds: string[] = [];
137
-
138
- for (const route of strategyRoutes) {
139
- const intent = await this.actionTracker.createRebalanceIntent({
140
- origin: this.multiProvider.getDomainId(route.origin),
141
- destination: this.multiProvider.getDomainId(route.destination),
142
- amount: route.amount,
143
- bridge: route.bridge,
144
- });
145
- intentIds.push(intent.id);
146
- rebalanceRoutes.push({
147
- ...route,
148
- intentId: intent.id,
149
- });
209
+ const inventoryRebalancer = this.rebalancersByType.get('inventory');
210
+ if (inventory.length > 0 && inventoryRebalancer) {
211
+ await this.executeRoutes(inventory, inventoryRebalancer, event);
150
212
  }
151
213
 
152
- this.logger.debug(
153
- { intentCount: rebalanceRoutes.length },
154
- 'Created rebalance intents',
155
- );
214
+ return { executedCount, failedCount };
215
+ }
156
216
 
157
- let results;
158
- try {
159
- results = await this.rebalancer.rebalance(rebalanceRoutes);
160
- const failedResults = results.filter((r) => !r.success);
161
- if (failedResults.length > 0) {
162
- this.metrics?.recordRebalancerFailure();
163
- this.logger.warn(
164
- { failureCount: failedResults.length, total: results.length },
165
- 'Rebalancer cycle completed with failures',
166
- );
167
- } else {
168
- this.metrics?.recordRebalancerSuccess();
169
- this.logger.info('Rebalancer completed a cycle successfully');
170
- }
171
- } catch (error) {
172
- this.metrics?.recordRebalancerFailure();
173
- this.logger.error({ error }, 'Error while rebalancing');
174
- await Promise.all(
175
- intentIds.map((id) => this.actionTracker.failRebalanceIntent(id)),
217
+ private async executeRoutes(
218
+ routes: StrategyRoute[],
219
+ rebalancer: IRebalancer,
220
+ event: MonitorEvent,
221
+ ): Promise<ExecutionResult[]> {
222
+ if (rebalancer.rebalancerType === 'inventory' && event.inventoryBalances) {
223
+ (rebalancer as InventoryRebalancer).setInventoryBalances(
224
+ event.inventoryBalances,
176
225
  );
177
- return;
178
226
  }
179
227
 
180
- await this.processExecutionResults(results);
181
- }
228
+ try {
229
+ const results = await rebalancer.rebalance(routes);
182
230
 
183
- private async processExecutionResults(
184
- results: Awaited<ReturnType<IRebalancer['rebalance']>>,
185
- ): Promise<void> {
186
- for (const result of results) {
187
- const intentId = result.route.intentId;
188
- if (result.success && result.messageId) {
189
- await this.actionTracker.createRebalanceAction({
190
- intentId,
191
- origin: this.multiProvider.getDomainId(result.route.origin),
192
- destination: this.multiProvider.getDomainId(result.route.destination),
193
- amount: result.route.amount,
194
- messageId: result.messageId,
195
- txHash: result.txHash,
196
- });
231
+ const successful = results.filter((r) => r.success);
232
+ const failed = results.filter((r) => !r.success);
233
+
234
+ if (successful.length > 0) {
235
+ if (rebalancer.rebalancerType === 'movableCollateral') {
236
+ this.metrics?.recordRebalancerSuccess();
237
+ }
197
238
  this.logger.info(
198
- {
199
- intentId,
200
- messageId: result.messageId,
201
- txHash: result.txHash,
202
- origin: result.route.origin,
203
- destination: result.route.destination,
204
- },
205
- 'Rebalance action created successfully',
239
+ { count: successful.length, type: rebalancer.rebalancerType },
240
+ 'Rebalancer completed successfully',
206
241
  );
207
- } else {
208
- await this.actionTracker.failRebalanceIntent(intentId);
242
+ }
243
+
244
+ if (failed.length > 0) {
245
+ if (rebalancer.rebalancerType === 'movableCollateral') {
246
+ this.metrics?.recordRebalancerFailure();
247
+ }
209
248
  this.logger.warn(
210
249
  {
211
- intentId,
212
- success: result.success,
213
- error: result.error,
214
- origin: result.route.origin,
215
- destination: result.route.destination,
250
+ count: failed.length,
251
+ type: rebalancer.rebalancerType,
252
+ errors: failed.map((r) => ({
253
+ route: `${r.route.origin} -> ${r.route.destination}`,
254
+ error: r.error,
255
+ })),
216
256
  },
217
- 'Rebalance intent marked as failed',
257
+ 'Some routes failed',
218
258
  );
219
259
  }
260
+
261
+ return results;
262
+ } catch (error: any) {
263
+ if (rebalancer.rebalancerType === 'movableCollateral') {
264
+ this.metrics?.recordRebalancerFailure();
265
+ }
266
+ this.logger.error(
267
+ { error, type: rebalancer.rebalancerType },
268
+ 'Error while executing routes',
269
+ );
270
+ return [];
220
271
  }
221
272
  }
222
273
  }