@hyperlane-xyz/rebalancer 0.1.0-beta.5a8bd28ab

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 (202) hide show
  1. package/README.md +178 -0
  2. package/dist/config/RebalancerConfig.d.ts +12 -0
  3. package/dist/config/RebalancerConfig.d.ts.map +1 -0
  4. package/dist/config/RebalancerConfig.js +29 -0
  5. package/dist/config/RebalancerConfig.js.map +1 -0
  6. package/dist/config/RebalancerConfig.test.d.ts +2 -0
  7. package/dist/config/RebalancerConfig.test.d.ts.map +1 -0
  8. package/dist/config/RebalancerConfig.test.js +325 -0
  9. package/dist/config/RebalancerConfig.test.js.map +1 -0
  10. package/dist/core/Rebalancer.d.ts +23 -0
  11. package/dist/core/Rebalancer.d.ts.map +1 -0
  12. package/dist/core/Rebalancer.js +290 -0
  13. package/dist/core/Rebalancer.js.map +1 -0
  14. package/dist/core/RebalancerService.d.ts +115 -0
  15. package/dist/core/RebalancerService.d.ts.map +1 -0
  16. package/dist/core/RebalancerService.js +227 -0
  17. package/dist/core/RebalancerService.js.map +1 -0
  18. package/dist/core/WithInflightGuard.d.ts +20 -0
  19. package/dist/core/WithInflightGuard.d.ts.map +1 -0
  20. package/dist/core/WithInflightGuard.js +47 -0
  21. package/dist/core/WithInflightGuard.js.map +1 -0
  22. package/dist/core/WithInflightGuard.test.d.ts +2 -0
  23. package/dist/core/WithInflightGuard.test.d.ts.map +1 -0
  24. package/dist/core/WithInflightGuard.test.js +64 -0
  25. package/dist/core/WithInflightGuard.test.js.map +1 -0
  26. package/dist/core/WithSemaphore.d.ts +22 -0
  27. package/dist/core/WithSemaphore.d.ts.map +1 -0
  28. package/dist/core/WithSemaphore.js +67 -0
  29. package/dist/core/WithSemaphore.js.map +1 -0
  30. package/dist/core/WithSemaphore.test.d.ts +2 -0
  31. package/dist/core/WithSemaphore.test.d.ts.map +1 -0
  32. package/dist/core/WithSemaphore.test.js +83 -0
  33. package/dist/core/WithSemaphore.test.js.map +1 -0
  34. package/dist/factories/RebalancerContextFactory.d.ts +41 -0
  35. package/dist/factories/RebalancerContextFactory.d.ts.map +1 -0
  36. package/dist/factories/RebalancerContextFactory.js +115 -0
  37. package/dist/factories/RebalancerContextFactory.js.map +1 -0
  38. package/dist/index.d.ts +33 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +35 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/interfaces/IMetrics.d.ts +5 -0
  43. package/dist/interfaces/IMetrics.d.ts.map +1 -0
  44. package/dist/interfaces/IMetrics.js +2 -0
  45. package/dist/interfaces/IMetrics.js.map +1 -0
  46. package/dist/interfaces/IMonitor.d.ts +51 -0
  47. package/dist/interfaces/IMonitor.d.ts.map +1 -0
  48. package/dist/interfaces/IMonitor.js +14 -0
  49. package/dist/interfaces/IMonitor.js.map +1 -0
  50. package/dist/interfaces/IRebalancer.d.ts +15 -0
  51. package/dist/interfaces/IRebalancer.d.ts.map +1 -0
  52. package/dist/interfaces/IRebalancer.js +2 -0
  53. package/dist/interfaces/IRebalancer.js.map +1 -0
  54. package/dist/interfaces/IStrategy.d.ts +11 -0
  55. package/dist/interfaces/IStrategy.d.ts.map +1 -0
  56. package/dist/interfaces/IStrategy.js +2 -0
  57. package/dist/interfaces/IStrategy.js.map +1 -0
  58. package/dist/metrics/Metrics.d.ts +31 -0
  59. package/dist/metrics/Metrics.d.ts.map +1 -0
  60. package/dist/metrics/Metrics.js +302 -0
  61. package/dist/metrics/Metrics.js.map +1 -0
  62. package/dist/metrics/PriceGetter.d.ts +10 -0
  63. package/dist/metrics/PriceGetter.d.ts.map +1 -0
  64. package/dist/metrics/PriceGetter.js +41 -0
  65. package/dist/metrics/PriceGetter.js.map +1 -0
  66. package/dist/metrics/scripts/metrics.d.ts +14 -0
  67. package/dist/metrics/scripts/metrics.d.ts.map +1 -0
  68. package/dist/metrics/scripts/metrics.js +198 -0
  69. package/dist/metrics/scripts/metrics.js.map +1 -0
  70. package/dist/metrics/types.d.ts +24 -0
  71. package/dist/metrics/types.d.ts.map +1 -0
  72. package/dist/metrics/types.js +2 -0
  73. package/dist/metrics/types.js.map +1 -0
  74. package/dist/metrics/utils/metrics.d.ts +12 -0
  75. package/dist/metrics/utils/metrics.d.ts.map +1 -0
  76. package/dist/metrics/utils/metrics.js +28 -0
  77. package/dist/metrics/utils/metrics.js.map +1 -0
  78. package/dist/monitor/Monitor.d.ts +26 -0
  79. package/dist/monitor/Monitor.d.ts.map +1 -0
  80. package/dist/monitor/Monitor.js +116 -0
  81. package/dist/monitor/Monitor.js.map +1 -0
  82. package/dist/service.d.ts +3 -0
  83. package/dist/service.d.ts.map +1 -0
  84. package/dist/service.js +125 -0
  85. package/dist/service.js.map +1 -0
  86. package/dist/strategy/BaseStrategy.d.ts +34 -0
  87. package/dist/strategy/BaseStrategy.d.ts.map +1 -0
  88. package/dist/strategy/BaseStrategy.js +127 -0
  89. package/dist/strategy/BaseStrategy.js.map +1 -0
  90. package/dist/strategy/MinAmountStrategy.d.ts +27 -0
  91. package/dist/strategy/MinAmountStrategy.d.ts.map +1 -0
  92. package/dist/strategy/MinAmountStrategy.js +103 -0
  93. package/dist/strategy/MinAmountStrategy.js.map +1 -0
  94. package/dist/strategy/MinAmountStrategy.test.d.ts +2 -0
  95. package/dist/strategy/MinAmountStrategy.test.d.ts.map +1 -0
  96. package/dist/strategy/MinAmountStrategy.test.js +472 -0
  97. package/dist/strategy/MinAmountStrategy.test.js.map +1 -0
  98. package/dist/strategy/StrategyFactory.d.ts +16 -0
  99. package/dist/strategy/StrategyFactory.d.ts.map +1 -0
  100. package/dist/strategy/StrategyFactory.js +25 -0
  101. package/dist/strategy/StrategyFactory.js.map +1 -0
  102. package/dist/strategy/StrategyFactory.test.d.ts +2 -0
  103. package/dist/strategy/StrategyFactory.test.d.ts.map +1 -0
  104. package/dist/strategy/StrategyFactory.test.js +80 -0
  105. package/dist/strategy/StrategyFactory.test.js.map +1 -0
  106. package/dist/strategy/WeightedStrategy.d.ts +23 -0
  107. package/dist/strategy/WeightedStrategy.d.ts.map +1 -0
  108. package/dist/strategy/WeightedStrategy.js +61 -0
  109. package/dist/strategy/WeightedStrategy.js.map +1 -0
  110. package/dist/strategy/WeightedStrategy.test.d.ts +2 -0
  111. package/dist/strategy/WeightedStrategy.test.d.ts.map +1 -0
  112. package/dist/strategy/WeightedStrategy.test.js +307 -0
  113. package/dist/strategy/WeightedStrategy.test.js.map +1 -0
  114. package/dist/strategy/index.d.ts +5 -0
  115. package/dist/strategy/index.d.ts.map +1 -0
  116. package/dist/strategy/index.js +5 -0
  117. package/dist/strategy/index.js.map +1 -0
  118. package/dist/test/helpers.d.ts +8 -0
  119. package/dist/test/helpers.d.ts.map +1 -0
  120. package/dist/test/helpers.js +33 -0
  121. package/dist/test/helpers.js.map +1 -0
  122. package/dist/utils/ExplorerClient.d.ts +14 -0
  123. package/dist/utils/ExplorerClient.d.ts.map +1 -0
  124. package/dist/utils/ExplorerClient.js +82 -0
  125. package/dist/utils/ExplorerClient.js.map +1 -0
  126. package/dist/utils/balanceUtils.d.ts +13 -0
  127. package/dist/utils/balanceUtils.d.ts.map +1 -0
  128. package/dist/utils/balanceUtils.js +43 -0
  129. package/dist/utils/balanceUtils.js.map +1 -0
  130. package/dist/utils/balanceUtils.test.d.ts +2 -0
  131. package/dist/utils/balanceUtils.test.d.ts.map +1 -0
  132. package/dist/utils/balanceUtils.test.js +54 -0
  133. package/dist/utils/balanceUtils.test.js.map +1 -0
  134. package/dist/utils/bridgeUtils.d.ts +19 -0
  135. package/dist/utils/bridgeUtils.d.ts.map +1 -0
  136. package/dist/utils/bridgeUtils.js +20 -0
  137. package/dist/utils/bridgeUtils.js.map +1 -0
  138. package/dist/utils/bridgeUtils.test.d.ts +2 -0
  139. package/dist/utils/bridgeUtils.test.d.ts.map +1 -0
  140. package/dist/utils/bridgeUtils.test.js +77 -0
  141. package/dist/utils/bridgeUtils.test.js.map +1 -0
  142. package/dist/utils/errors.d.ts +4 -0
  143. package/dist/utils/errors.d.ts.map +1 -0
  144. package/dist/utils/errors.js +6 -0
  145. package/dist/utils/errors.js.map +1 -0
  146. package/dist/utils/files.d.ts +35 -0
  147. package/dist/utils/files.d.ts.map +1 -0
  148. package/dist/utils/files.js +190 -0
  149. package/dist/utils/files.js.map +1 -0
  150. package/dist/utils/generalUtils.d.ts +3 -0
  151. package/dist/utils/generalUtils.d.ts.map +1 -0
  152. package/dist/utils/generalUtils.js +9 -0
  153. package/dist/utils/generalUtils.js.map +1 -0
  154. package/dist/utils/index.d.ts +5 -0
  155. package/dist/utils/index.d.ts.map +1 -0
  156. package/dist/utils/index.js +5 -0
  157. package/dist/utils/index.js.map +1 -0
  158. package/dist/utils/tokenUtils.d.ts +14 -0
  159. package/dist/utils/tokenUtils.d.ts.map +1 -0
  160. package/dist/utils/tokenUtils.js +21 -0
  161. package/dist/utils/tokenUtils.js.map +1 -0
  162. package/package.json +70 -0
  163. package/src/config/RebalancerConfig.test.ts +388 -0
  164. package/src/config/RebalancerConfig.ts +39 -0
  165. package/src/core/Rebalancer.ts +471 -0
  166. package/src/core/RebalancerService.ts +333 -0
  167. package/src/core/WithInflightGuard.test.ts +131 -0
  168. package/src/core/WithInflightGuard.ts +67 -0
  169. package/src/core/WithSemaphore.test.ts +112 -0
  170. package/src/core/WithSemaphore.ts +92 -0
  171. package/src/factories/RebalancerContextFactory.ts +210 -0
  172. package/src/index.ts +68 -0
  173. package/src/interfaces/IMetrics.ts +5 -0
  174. package/src/interfaces/IMonitor.ts +63 -0
  175. package/src/interfaces/IRebalancer.ts +20 -0
  176. package/src/interfaces/IStrategy.ts +13 -0
  177. package/src/metrics/Metrics.ts +558 -0
  178. package/src/metrics/PriceGetter.ts +74 -0
  179. package/src/metrics/scripts/metrics.ts +298 -0
  180. package/src/metrics/types.ts +27 -0
  181. package/src/metrics/utils/metrics.ts +33 -0
  182. package/src/monitor/Monitor.ts +174 -0
  183. package/src/service.ts +154 -0
  184. package/src/strategy/BaseStrategy.ts +210 -0
  185. package/src/strategy/MinAmountStrategy.test.ts +625 -0
  186. package/src/strategy/MinAmountStrategy.ts +170 -0
  187. package/src/strategy/StrategyFactory.test.ts +109 -0
  188. package/src/strategy/StrategyFactory.ts +48 -0
  189. package/src/strategy/WeightedStrategy.test.ts +408 -0
  190. package/src/strategy/WeightedStrategy.ts +93 -0
  191. package/src/strategy/index.ts +4 -0
  192. package/src/test/helpers.ts +46 -0
  193. package/src/utils/ExplorerClient.ts +99 -0
  194. package/src/utils/balanceUtils.test.ts +74 -0
  195. package/src/utils/balanceUtils.ts +69 -0
  196. package/src/utils/bridgeUtils.test.ts +92 -0
  197. package/src/utils/bridgeUtils.ts +42 -0
  198. package/src/utils/errors.ts +5 -0
  199. package/src/utils/files.ts +276 -0
  200. package/src/utils/generalUtils.ts +13 -0
  201. package/src/utils/index.ts +4 -0
  202. package/src/utils/tokenUtils.ts +26 -0
@@ -0,0 +1,170 @@
1
+ import { BigNumber } from 'bignumber.js';
2
+ import { Logger } from 'pino';
3
+
4
+ import {
5
+ type ChainMap,
6
+ type MinAmountStrategyConfig,
7
+ RebalancerMinAmountType,
8
+ type Token,
9
+ } from '@hyperlane-xyz/sdk';
10
+ import { fromWei, toWei } from '@hyperlane-xyz/utils';
11
+
12
+ import type { RawBalances } from '../interfaces/IStrategy.js';
13
+ import { Metrics } from '../metrics/Metrics.js';
14
+
15
+ import { BaseStrategy, type Delta } from './BaseStrategy.js';
16
+
17
+ /**
18
+ * Strategy implementation that rebalance based on minimum amounts
19
+ * It ensures each chain has at least the specified minimum amount
20
+ */
21
+ export class MinAmountStrategy extends BaseStrategy {
22
+ private readonly config: MinAmountStrategyConfig = {};
23
+ protected readonly logger: Logger;
24
+
25
+ constructor(
26
+ config: MinAmountStrategyConfig,
27
+ private readonly tokensByChainName: ChainMap<Token>,
28
+ initialTotalCollateral: bigint,
29
+ logger: Logger,
30
+ metrics?: Metrics,
31
+ ) {
32
+ const chains = Object.keys(config);
33
+ const log = logger.child({ class: MinAmountStrategy.name });
34
+ super(chains, log, metrics);
35
+ this.logger = log;
36
+
37
+ const minAmountType = config[chains[0]].minAmount.type;
38
+ this.validateAmounts(initialTotalCollateral, minAmountType, config);
39
+
40
+ for (const chain of chains) {
41
+ const { min, target } = config[chain].minAmount;
42
+
43
+ // check range constraints
44
+ if (BigNumber(target).lt(min)) {
45
+ throw new Error(
46
+ `Target (${target}) must be greater than or equal to min (${min}) for chain ${chain}`,
47
+ );
48
+ }
49
+
50
+ if (BigNumber(min).lt(0)) {
51
+ throw new Error(
52
+ `Minimum amount (${min}) cannot be negative for chain ${chain}`,
53
+ );
54
+ }
55
+
56
+ if (BigNumber(target).lt(0)) {
57
+ throw new Error(
58
+ `Target amount (${target}) cannot be negative for chain ${chain}`,
59
+ );
60
+ }
61
+ }
62
+
63
+ this.config = config;
64
+ this.logger.info('MinAmountStrategy created');
65
+ }
66
+
67
+ /**
68
+ * Gets balances categorized by surplus and deficit based on minimum amounts and targets
69
+ * - For absolute values: Uses exact token amounts
70
+ * - For relative values: Uses percentages of total balance across all chains
71
+ */
72
+ protected getCategorizedBalances(rawBalances: RawBalances): {
73
+ surpluses: Delta[];
74
+ deficits: Delta[];
75
+ } {
76
+ const totalCollateral = this.chains.reduce(
77
+ (sum, chain) => sum + rawBalances[chain],
78
+ 0n,
79
+ );
80
+
81
+ return this.chains.reduce(
82
+ (acc, chain) => {
83
+ const config = this.config[chain];
84
+ const balance = rawBalances[chain];
85
+ let minAmount: bigint;
86
+ let targetAmount: bigint;
87
+
88
+ if (config.minAmount.type === RebalancerMinAmountType.Absolute) {
89
+ const token = this.getTokenByChainName(chain);
90
+
91
+ minAmount = BigInt(toWei(config.minAmount.min, token.decimals));
92
+ targetAmount = BigInt(toWei(config.minAmount.target, token.decimals));
93
+ } else {
94
+ minAmount = BigInt(
95
+ BigNumber(totalCollateral.toString())
96
+ .times(config.minAmount.min)
97
+ .toFixed(0, BigNumber.ROUND_FLOOR),
98
+ );
99
+ targetAmount = BigInt(
100
+ BigNumber(totalCollateral.toString())
101
+ .times(config.minAmount.target)
102
+ .toFixed(0, BigNumber.ROUND_FLOOR),
103
+ );
104
+ }
105
+
106
+ // If balance is less than minAmount, it has a deficit
107
+ if (balance < minAmount) {
108
+ acc.deficits.push({ chain, amount: targetAmount - balance });
109
+ } else {
110
+ // Any chain with more than minAmount potentially has surplus
111
+ const surplus = balance - minAmount;
112
+ if (surplus > 0n) {
113
+ acc.surpluses.push({ chain, amount: surplus });
114
+ }
115
+ }
116
+
117
+ return acc;
118
+ },
119
+ {
120
+ surpluses: [] as Delta[],
121
+ deficits: [] as Delta[],
122
+ },
123
+ );
124
+ }
125
+
126
+ protected getTokenByChainName(chainName: string): Token {
127
+ const token = this.tokensByChainName[chainName];
128
+
129
+ if (token === undefined) {
130
+ throw new Error(`Token not found for chain ${chainName}`);
131
+ }
132
+
133
+ return token;
134
+ }
135
+
136
+ private validateAmounts(
137
+ totalCollateral: bigint,
138
+ minAmountType: RebalancerMinAmountType,
139
+ config?: MinAmountStrategyConfig,
140
+ ): void {
141
+ config ??= this.config;
142
+
143
+ if (minAmountType === RebalancerMinAmountType.Absolute) {
144
+ let totalTargets = 0n;
145
+ let decimals: number = 0;
146
+
147
+ for (const chainName of this.chains) {
148
+ const token = this.getTokenByChainName(chainName);
149
+ // all the tokens have the same amount of decimals
150
+ decimals = token.decimals;
151
+
152
+ totalTargets += BigInt(
153
+ toWei(config[chainName].minAmount.target, token.decimals),
154
+ );
155
+ }
156
+
157
+ if (totalTargets > totalCollateral) {
158
+ throw new Error(
159
+ `Consider reducing the targets as the sum (${fromWei(
160
+ totalTargets.toString(),
161
+ decimals,
162
+ )}) is greater than sum of collaterals (${fromWei(
163
+ totalCollateral.toString(),
164
+ decimals,
165
+ )})`,
166
+ );
167
+ }
168
+ }
169
+ }
170
+ }
@@ -0,0 +1,109 @@
1
+ import { expect } from 'chai';
2
+ import { ethers } from 'ethers';
3
+ import { pino } from 'pino';
4
+
5
+ import {
6
+ type ChainMap,
7
+ MinAmountStrategyConfig,
8
+ RebalancerMinAmountType,
9
+ RebalancerStrategyOptions,
10
+ StrategyConfig,
11
+ Token,
12
+ TokenStandard,
13
+ WeightedStrategyConfig,
14
+ } from '@hyperlane-xyz/sdk';
15
+
16
+ import { MinAmountStrategy } from './MinAmountStrategy.js';
17
+ import { StrategyFactory } from './StrategyFactory.js';
18
+ import { WeightedStrategy } from './WeightedStrategy.js';
19
+
20
+ const testLogger = pino({ level: 'silent' });
21
+
22
+ describe('StrategyFactory', () => {
23
+ const chain1 = 'chain1';
24
+ const chain2 = 'chain2';
25
+ const totalCollateral = BigInt(20e18);
26
+
27
+ const tokensByChainName: ChainMap<Token> = {};
28
+ const tokenArgs = {
29
+ name: 'token',
30
+ decimals: 18,
31
+ symbol: 'TOKEN',
32
+ standard: TokenStandard.ERC20,
33
+ addressOrDenom: '',
34
+ };
35
+ tokensByChainName[chain1] = new Token({ ...tokenArgs, chainName: chain1 });
36
+ tokensByChainName[chain2] = new Token({ ...tokenArgs, chainName: chain2 });
37
+
38
+ describe('createStrategy', () => {
39
+ it('creates a WeightedStrategy when given weighted configuration', () => {
40
+ const config: WeightedStrategyConfig = {
41
+ [chain1]: {
42
+ weighted: {
43
+ weight: 100n,
44
+ tolerance: 0n,
45
+ },
46
+ bridge: ethers.constants.AddressZero,
47
+ bridgeLockTime: 1,
48
+ },
49
+ [chain2]: {
50
+ weighted: {
51
+ weight: 100n,
52
+ tolerance: 0n,
53
+ },
54
+ bridge: ethers.constants.AddressZero,
55
+ bridgeLockTime: 1,
56
+ },
57
+ };
58
+
59
+ const strategyConfig: StrategyConfig = {
60
+ rebalanceStrategy: RebalancerStrategyOptions.Weighted,
61
+ chains: config,
62
+ };
63
+
64
+ const strategy = StrategyFactory.createStrategy(
65
+ strategyConfig,
66
+ tokensByChainName,
67
+ totalCollateral,
68
+ testLogger,
69
+ );
70
+ expect(strategy).to.be.instanceOf(WeightedStrategy);
71
+ });
72
+
73
+ it('creates a MinAmountStrategy when given minAmount configuration', () => {
74
+ const config: MinAmountStrategyConfig = {
75
+ [chain1]: {
76
+ minAmount: {
77
+ min: 8,
78
+ target: 10,
79
+ type: RebalancerMinAmountType.Absolute,
80
+ },
81
+ bridge: ethers.constants.AddressZero,
82
+ bridgeLockTime: 1,
83
+ },
84
+ [chain2]: {
85
+ minAmount: {
86
+ min: 8,
87
+ target: 10,
88
+ type: RebalancerMinAmountType.Absolute,
89
+ },
90
+ bridge: ethers.constants.AddressZero,
91
+ bridgeLockTime: 1,
92
+ },
93
+ };
94
+
95
+ const strategyConfig: StrategyConfig = {
96
+ rebalanceStrategy: RebalancerStrategyOptions.MinAmount,
97
+ chains: config,
98
+ };
99
+
100
+ const strategy = StrategyFactory.createStrategy(
101
+ strategyConfig,
102
+ tokensByChainName,
103
+ totalCollateral,
104
+ testLogger,
105
+ );
106
+ expect(strategy).to.be.instanceOf(MinAmountStrategy);
107
+ });
108
+ });
109
+ });
@@ -0,0 +1,48 @@
1
+ import { Logger } from 'pino';
2
+
3
+ import {
4
+ ChainMap,
5
+ RebalancerStrategyOptions,
6
+ StrategyConfig,
7
+ Token,
8
+ } from '@hyperlane-xyz/sdk';
9
+
10
+ import { type IStrategy } from '../interfaces/IStrategy.js';
11
+ import { Metrics } from '../metrics/Metrics.js';
12
+
13
+ import { MinAmountStrategy } from './MinAmountStrategy.js';
14
+ import { WeightedStrategy } from './WeightedStrategy.js';
15
+
16
+ export class StrategyFactory {
17
+ /**
18
+ * @param strategyConfig A discriminated union of strategy-specific configurations.
19
+ * @param tokensByChainName - A map of chain->token to ease the lookup of token by chain
20
+ * @param initialTotalCollateral - The initial total collateral of the rebalancer
21
+ * @param logger - The logger to use for the strategy
22
+ * @param metrics - The metrics to use for the strategy
23
+ * @returns A concrete strategy implementation
24
+ */
25
+ static createStrategy(
26
+ strategyConfig: StrategyConfig,
27
+ tokensByChainName: ChainMap<Token>,
28
+ initialTotalCollateral: bigint,
29
+ logger: Logger,
30
+ metrics?: Metrics,
31
+ ): IStrategy {
32
+ switch (strategyConfig.rebalanceStrategy) {
33
+ case RebalancerStrategyOptions.Weighted:
34
+ return new WeightedStrategy(strategyConfig.chains, logger, metrics);
35
+ case RebalancerStrategyOptions.MinAmount:
36
+ return new MinAmountStrategy(
37
+ strategyConfig.chains,
38
+ tokensByChainName,
39
+ initialTotalCollateral,
40
+ logger,
41
+ metrics,
42
+ );
43
+ default: {
44
+ throw new Error('Unsupported strategy type');
45
+ }
46
+ }
47
+ }
48
+ }