@hyperlane-xyz/rebalancer 0.1.2 → 1.0.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/README.md +134 -14
- package/dist/config/RebalancerConfig.d.ts +2 -2
- package/dist/config/RebalancerConfig.d.ts.map +1 -1
- package/dist/config/RebalancerConfig.js +4 -3
- package/dist/config/RebalancerConfig.js.map +1 -1
- package/dist/config/RebalancerConfig.test.js +434 -163
- package/dist/config/RebalancerConfig.test.js.map +1 -1
- package/dist/config/types.d.ts +1650 -290
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +124 -46
- package/dist/config/types.js.map +1 -1
- package/dist/core/Rebalancer.d.ts +14 -7
- package/dist/core/Rebalancer.d.ts.map +1 -1
- package/dist/core/Rebalancer.js +168 -99
- package/dist/core/Rebalancer.js.map +1 -1
- package/dist/core/Rebalancer.test.d.ts +2 -0
- package/dist/core/Rebalancer.test.d.ts.map +1 -0
- package/dist/core/Rebalancer.test.js +391 -0
- package/dist/core/Rebalancer.test.js.map +1 -0
- package/dist/core/RebalancerService.d.ts +16 -2
- package/dist/core/RebalancerService.d.ts.map +1 -1
- package/dist/core/RebalancerService.js +164 -21
- package/dist/core/RebalancerService.js.map +1 -1
- package/dist/core/RebalancerService.test.d.ts +2 -0
- package/dist/core/RebalancerService.test.d.ts.map +1 -0
- package/dist/core/RebalancerService.test.js +809 -0
- package/dist/core/RebalancerService.test.js.map +1 -0
- package/dist/factories/RebalancerContextFactory.d.ts +11 -0
- package/dist/factories/RebalancerContextFactory.d.ts.map +1 -1
- package/dist/factories/RebalancerContextFactory.js +60 -13
- 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 +4 -3
- package/dist/index.js.map +1 -1
- package/dist/interfaces/IMonitor.d.ts +6 -8
- package/dist/interfaces/IMonitor.d.ts.map +1 -1
- package/dist/interfaces/IMonitor.js.map +1 -1
- package/dist/interfaces/IRebalancer.d.ts +20 -4
- package/dist/interfaces/IRebalancer.d.ts.map +1 -1
- package/dist/interfaces/IStrategy.d.ts +18 -2
- package/dist/interfaces/IStrategy.d.ts.map +1 -1
- package/dist/metrics/Metrics.d.ts +4 -2
- package/dist/metrics/Metrics.d.ts.map +1 -1
- package/dist/metrics/Metrics.js +21 -1
- package/dist/metrics/Metrics.js.map +1 -1
- package/dist/metrics/scripts/metrics.d.ts +2 -0
- package/dist/metrics/scripts/metrics.d.ts.map +1 -1
- package/dist/metrics/scripts/metrics.js +12 -0
- package/dist/metrics/scripts/metrics.js.map +1 -1
- package/dist/monitor/Monitor.d.ts +8 -3
- package/dist/monitor/Monitor.d.ts.map +1 -1
- package/dist/monitor/Monitor.js +75 -15
- package/dist/monitor/Monitor.js.map +1 -1
- package/dist/strategy/BaseStrategy.d.ts +51 -5
- package/dist/strategy/BaseStrategy.d.ts.map +1 -1
- package/dist/strategy/BaseStrategy.js +199 -19
- package/dist/strategy/BaseStrategy.js.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.d.ts +65 -0
- package/dist/strategy/CollateralDeficitStrategy.d.ts.map +1 -0
- package/dist/strategy/CollateralDeficitStrategy.js +245 -0
- package/dist/strategy/CollateralDeficitStrategy.js.map +1 -0
- package/dist/strategy/CollateralDeficitStrategy.test.d.ts +2 -0
- package/dist/strategy/CollateralDeficitStrategy.test.d.ts.map +1 -0
- package/dist/strategy/CollateralDeficitStrategy.test.js +364 -0
- package/dist/strategy/CollateralDeficitStrategy.test.js.map +1 -0
- package/dist/strategy/CompositeStrategy.d.ts +18 -0
- package/dist/strategy/CompositeStrategy.d.ts.map +1 -0
- package/dist/strategy/CompositeStrategy.js +63 -0
- package/dist/strategy/CompositeStrategy.js.map +1 -0
- package/dist/strategy/CompositeStrategy.test.d.ts +2 -0
- package/dist/strategy/CompositeStrategy.test.d.ts.map +1 -0
- package/dist/strategy/CompositeStrategy.test.js +265 -0
- package/dist/strategy/CompositeStrategy.test.js.map +1 -0
- package/dist/strategy/MinAmountStrategy.d.ts +12 -5
- package/dist/strategy/MinAmountStrategy.d.ts.map +1 -1
- package/dist/strategy/MinAmountStrategy.js +23 -14
- package/dist/strategy/MinAmountStrategy.js.map +1 -1
- package/dist/strategy/MinAmountStrategy.test.js +88 -20
- package/dist/strategy/MinAmountStrategy.test.js.map +1 -1
- package/dist/strategy/StrategyFactory.d.ts +15 -6
- package/dist/strategy/StrategyFactory.d.ts.map +1 -1
- package/dist/strategy/StrategyFactory.js +48 -10
- package/dist/strategy/StrategyFactory.js.map +1 -1
- package/dist/strategy/StrategyFactory.test.js +2 -2
- package/dist/strategy/StrategyFactory.test.js.map +1 -1
- package/dist/strategy/WeightedStrategy.d.ts +13 -4
- package/dist/strategy/WeightedStrategy.d.ts.map +1 -1
- package/dist/strategy/WeightedStrategy.js +18 -6
- package/dist/strategy/WeightedStrategy.js.map +1 -1
- package/dist/strategy/WeightedStrategy.test.js +108 -18
- package/dist/strategy/WeightedStrategy.test.js.map +1 -1
- package/dist/strategy/index.d.ts +2 -0
- package/dist/strategy/index.d.ts.map +1 -1
- package/dist/strategy/index.js +2 -0
- package/dist/strategy/index.js.map +1 -1
- package/dist/test/helpers.d.ts +93 -3
- package/dist/test/helpers.d.ts.map +1 -1
- package/dist/test/helpers.js +267 -10
- package/dist/test/helpers.js.map +1 -1
- package/dist/tracking/ActionTracker.d.ts +49 -0
- package/dist/tracking/ActionTracker.d.ts.map +1 -0
- package/dist/tracking/ActionTracker.js +422 -0
- package/dist/tracking/ActionTracker.js.map +1 -0
- package/dist/tracking/ActionTracker.test.d.ts +2 -0
- package/dist/tracking/ActionTracker.test.d.ts.map +1 -0
- package/dist/tracking/ActionTracker.test.js +637 -0
- package/dist/tracking/ActionTracker.test.js.map +1 -0
- package/dist/tracking/IActionTracker.d.ts +101 -0
- package/dist/tracking/IActionTracker.d.ts.map +1 -0
- package/dist/tracking/IActionTracker.js +2 -0
- package/dist/tracking/IActionTracker.js.map +1 -0
- package/dist/tracking/InflightContextAdapter.d.ts +18 -0
- package/dist/tracking/InflightContextAdapter.d.ts.map +1 -0
- package/dist/tracking/InflightContextAdapter.js +35 -0
- package/dist/tracking/InflightContextAdapter.js.map +1 -0
- package/dist/tracking/InflightContextAdapter.test.d.ts +2 -0
- package/dist/tracking/InflightContextAdapter.test.d.ts.map +1 -0
- package/dist/tracking/InflightContextAdapter.test.js +172 -0
- package/dist/tracking/InflightContextAdapter.test.js.map +1 -0
- package/dist/tracking/index.d.ts +7 -0
- package/dist/tracking/index.d.ts.map +1 -0
- package/dist/tracking/index.js +6 -0
- package/dist/tracking/index.js.map +1 -0
- package/dist/tracking/store/IStore.d.ts +41 -0
- package/dist/tracking/store/IStore.d.ts.map +1 -0
- package/dist/tracking/store/IStore.js +2 -0
- package/dist/tracking/store/IStore.js.map +1 -0
- package/dist/tracking/store/InMemoryStore.d.ts +21 -0
- package/dist/tracking/store/InMemoryStore.d.ts.map +1 -0
- package/dist/tracking/store/InMemoryStore.js +40 -0
- package/dist/tracking/store/InMemoryStore.js.map +1 -0
- package/dist/tracking/store/InMemoryStore.test.d.ts +2 -0
- package/dist/tracking/store/InMemoryStore.test.d.ts.map +1 -0
- package/dist/tracking/store/InMemoryStore.test.js +290 -0
- package/dist/tracking/store/InMemoryStore.test.js.map +1 -0
- package/dist/tracking/store/index.d.ts +3 -0
- package/dist/tracking/store/index.d.ts.map +1 -0
- package/dist/tracking/store/index.js +2 -0
- package/dist/tracking/store/index.js.map +1 -0
- package/dist/tracking/types.d.ts +43 -0
- package/dist/tracking/types.d.ts.map +1 -0
- package/dist/tracking/types.js +2 -0
- package/dist/tracking/types.js.map +1 -0
- package/dist/utils/ExplorerClient.d.ts +39 -1
- package/dist/utils/ExplorerClient.d.ts.map +1 -1
- package/dist/utils/ExplorerClient.js +205 -2
- package/dist/utils/ExplorerClient.js.map +1 -1
- package/dist/utils/balanceUtils.js +2 -2
- package/dist/utils/balanceUtils.js.map +1 -1
- package/dist/utils/balanceUtils.test.js +1 -0
- package/dist/utils/balanceUtils.test.js.map +1 -1
- package/dist/utils/bridgeUtils.d.ts +1 -3
- package/dist/utils/bridgeUtils.d.ts.map +1 -1
- package/dist/utils/bridgeUtils.js +1 -5
- package/dist/utils/bridgeUtils.js.map +1 -1
- package/dist/utils/bridgeUtils.test.js +3 -14
- package/dist/utils/bridgeUtils.test.js.map +1 -1
- package/package.json +11 -9
- package/src/config/RebalancerConfig.test.ts +459 -163
- package/src/config/RebalancerConfig.ts +5 -3
- package/src/config/types.ts +159 -52
- package/src/core/Rebalancer.test.ts +632 -0
- package/src/core/Rebalancer.ts +247 -157
- package/src/core/RebalancerService.test.ts +1144 -0
- package/src/core/RebalancerService.ts +245 -23
- package/src/factories/RebalancerContextFactory.ts +115 -14
- package/src/index.ts +16 -4
- package/src/interfaces/IMonitor.ts +15 -8
- package/src/interfaces/IRebalancer.ts +22 -4
- package/src/interfaces/IStrategy.ts +23 -2
- package/src/metrics/Metrics.ts +26 -5
- package/src/metrics/scripts/metrics.ts +14 -0
- package/src/monitor/Monitor.ts +109 -22
- package/src/strategy/BaseStrategy.ts +316 -26
- package/src/strategy/CollateralDeficitStrategy.test.ts +551 -0
- package/src/strategy/CollateralDeficitStrategy.ts +390 -0
- package/src/strategy/CompositeStrategy.test.ts +405 -0
- package/src/strategy/CompositeStrategy.ts +102 -0
- package/src/strategy/MinAmountStrategy.test.ts +189 -88
- package/src/strategy/MinAmountStrategy.ts +44 -13
- package/src/strategy/StrategyFactory.test.ts +2 -2
- package/src/strategy/StrategyFactory.ts +91 -8
- package/src/strategy/WeightedStrategy.test.ts +187 -72
- package/src/strategy/WeightedStrategy.ts +41 -7
- package/src/strategy/index.ts +2 -0
- package/src/test/helpers.ts +418 -14
- package/src/tracking/ActionTracker.test.ts +783 -0
- package/src/tracking/ActionTracker.ts +647 -0
- package/src/tracking/IActionTracker.ts +140 -0
- package/src/tracking/InflightContextAdapter.test.ts +203 -0
- package/src/tracking/InflightContextAdapter.ts +42 -0
- package/src/tracking/index.ts +36 -0
- package/src/tracking/store/IStore.ts +48 -0
- package/src/tracking/store/InMemoryStore.test.ts +338 -0
- package/src/tracking/store/InMemoryStore.ts +58 -0
- package/src/tracking/store/index.ts +2 -0
- package/src/tracking/types.ts +74 -0
- package/src/utils/ExplorerClient.ts +266 -3
- package/src/utils/balanceUtils.test.ts +1 -0
- package/src/utils/balanceUtils.ts +2 -2
- package/src/utils/bridgeUtils.test.ts +3 -15
- package/src/utils/bridgeUtils.ts +0 -10
- package/dist/core/WithInflightGuard.d.ts +0 -20
- package/dist/core/WithInflightGuard.d.ts.map +0 -1
- package/dist/core/WithInflightGuard.js +0 -47
- package/dist/core/WithInflightGuard.js.map +0 -1
- package/dist/core/WithInflightGuard.test.d.ts +0 -2
- package/dist/core/WithInflightGuard.test.d.ts.map +0 -1
- package/dist/core/WithInflightGuard.test.js +0 -64
- package/dist/core/WithInflightGuard.test.js.map +0 -1
- package/dist/core/WithSemaphore.d.ts +0 -22
- package/dist/core/WithSemaphore.d.ts.map +0 -1
- package/dist/core/WithSemaphore.js +0 -67
- package/dist/core/WithSemaphore.js.map +0 -1
- package/dist/core/WithSemaphore.test.d.ts +0 -2
- package/dist/core/WithSemaphore.test.d.ts.map +0 -1
- package/dist/core/WithSemaphore.test.js +0 -83
- package/dist/core/WithSemaphore.test.js.map +0 -1
- package/src/core/WithInflightGuard.test.ts +0 -131
- package/src/core/WithInflightGuard.ts +0 -67
- package/src/core/WithSemaphore.test.ts +0 -111
- package/src/core/WithSemaphore.ts +0 -92
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { fromZodError } from 'zod-validation-error';
|
|
2
2
|
|
|
3
|
-
import { isObjEmpty } from '@hyperlane-xyz/utils';
|
|
4
3
|
import { readYamlOrJson } from '@hyperlane-xyz/utils/fs';
|
|
5
4
|
|
|
6
5
|
import {
|
|
7
6
|
type RebalancerConfigFileInput,
|
|
8
7
|
RebalancerConfigSchema,
|
|
9
8
|
type StrategyConfig,
|
|
9
|
+
getStrategyChainNames,
|
|
10
10
|
} from './types.js';
|
|
11
11
|
|
|
12
12
|
export class RebalancerConfig {
|
|
13
13
|
constructor(
|
|
14
14
|
public readonly warpRouteId: string,
|
|
15
|
-
public readonly strategyConfig: StrategyConfig,
|
|
15
|
+
public readonly strategyConfig: StrategyConfig[],
|
|
16
16
|
) {}
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -30,7 +30,9 @@ export class RebalancerConfig {
|
|
|
30
30
|
|
|
31
31
|
const { warpRouteId, strategy } = validationResult.data;
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
// Check that at least one chain is configured across all strategies
|
|
34
|
+
const chainNames = getStrategyChainNames(strategy);
|
|
35
|
+
if (chainNames.length === 0) {
|
|
34
36
|
throw new Error('No chains configured');
|
|
35
37
|
}
|
|
36
38
|
|
package/src/config/types.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { z } from 'zod';
|
|
|
3
3
|
export enum RebalancerStrategyOptions {
|
|
4
4
|
Weighted = 'weighted',
|
|
5
5
|
MinAmount = 'minAmount',
|
|
6
|
+
CollateralDeficit = 'collateralDeficit',
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
// Weighted strategy config schema
|
|
@@ -36,11 +37,8 @@ const RebalancerBridgeConfigSchema = z.object({
|
|
|
36
37
|
.number()
|
|
37
38
|
.positive()
|
|
38
39
|
.transform((val) => val * 1_000)
|
|
39
|
-
.describe('Expected time in seconds for bridge to process a transfer'),
|
|
40
|
-
bridgeIsWarp: z
|
|
41
|
-
.boolean()
|
|
42
40
|
.optional()
|
|
43
|
-
.describe('
|
|
41
|
+
.describe('Expected time in seconds for bridge to process a transfer'),
|
|
44
42
|
});
|
|
45
43
|
|
|
46
44
|
export const RebalancerBaseChainConfigSchema =
|
|
@@ -59,6 +57,11 @@ const MinAmountChainConfigSchema = RebalancerBaseChainConfigSchema.extend({
|
|
|
59
57
|
minAmount: RebalancerMinAmountConfigSchema,
|
|
60
58
|
});
|
|
61
59
|
|
|
60
|
+
const CollateralDeficitChainConfigSchema =
|
|
61
|
+
RebalancerBaseChainConfigSchema.extend({
|
|
62
|
+
buffer: z.string().or(z.number()),
|
|
63
|
+
});
|
|
64
|
+
|
|
62
65
|
const WeightedStrategySchema = z.object({
|
|
63
66
|
rebalanceStrategy: z.literal(RebalancerStrategyOptions.Weighted),
|
|
64
67
|
chains: z.record(z.string(), WeightedChainConfigSchema),
|
|
@@ -69,75 +72,122 @@ const MinAmountStrategySchema = z.object({
|
|
|
69
72
|
chains: z.record(z.string(), MinAmountChainConfigSchema),
|
|
70
73
|
});
|
|
71
74
|
|
|
75
|
+
const CollateralDeficitStrategySchema = z.object({
|
|
76
|
+
rebalanceStrategy: z.literal(RebalancerStrategyOptions.CollateralDeficit),
|
|
77
|
+
chains: z.record(z.string(), CollateralDeficitChainConfigSchema),
|
|
78
|
+
});
|
|
79
|
+
|
|
72
80
|
export type WeightedStrategy = z.infer<typeof WeightedStrategySchema>;
|
|
73
81
|
export type MinAmountStrategy = z.infer<typeof MinAmountStrategySchema>;
|
|
82
|
+
export type CollateralDeficitStrategy = z.infer<
|
|
83
|
+
typeof CollateralDeficitStrategySchema
|
|
84
|
+
>;
|
|
74
85
|
|
|
75
86
|
export type WeightedStrategyConfig = WeightedStrategy['chains'];
|
|
76
87
|
export type MinAmountStrategyConfig = MinAmountStrategy['chains'];
|
|
88
|
+
export type CollateralDeficitStrategyConfig =
|
|
89
|
+
CollateralDeficitStrategy['chains'];
|
|
77
90
|
|
|
78
91
|
export const StrategyConfigSchema = z.discriminatedUnion('rebalanceStrategy', [
|
|
79
92
|
WeightedStrategySchema,
|
|
80
93
|
MinAmountStrategySchema,
|
|
94
|
+
CollateralDeficitStrategySchema,
|
|
81
95
|
]);
|
|
82
96
|
|
|
97
|
+
// Accept either a single strategy (backwards compatible) or an array of strategies
|
|
98
|
+
// Normalizes to array internally so the rest of the code doesn't need to change
|
|
99
|
+
export const RebalancerStrategySchema = z
|
|
100
|
+
.union([
|
|
101
|
+
StrategyConfigSchema, // Old format: single object
|
|
102
|
+
z.array(StrategyConfigSchema).min(1), // New format: array
|
|
103
|
+
])
|
|
104
|
+
.transform((val) => (Array.isArray(val) ? val : [val]));
|
|
105
|
+
|
|
83
106
|
export const RebalancerConfigSchema = z
|
|
84
107
|
.object({
|
|
85
108
|
warpRouteId: z.string(),
|
|
86
|
-
strategy:
|
|
109
|
+
strategy: RebalancerStrategySchema,
|
|
87
110
|
})
|
|
88
111
|
.superRefine((config, ctx) => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
ctx.addIssue({
|
|
99
|
-
code: z.ZodIssueCode.custom,
|
|
100
|
-
message: `Chain '${chainName}' has an override for '${overrideChainName}', but '${overrideChainName}' is not defined in the config`,
|
|
101
|
-
path: [
|
|
102
|
-
'strategy',
|
|
103
|
-
'chains',
|
|
104
|
-
chainName,
|
|
105
|
-
'override',
|
|
106
|
-
overrideChainName,
|
|
107
|
-
],
|
|
108
|
-
});
|
|
109
|
-
}
|
|
112
|
+
// CollateralDeficitStrategy must be first in composite if it is used
|
|
113
|
+
if (config.strategy.length > 1) {
|
|
114
|
+
const hasCollateralDeficit = config.strategy.some(
|
|
115
|
+
(s) =>
|
|
116
|
+
s.rebalanceStrategy === RebalancerStrategyOptions.CollateralDeficit,
|
|
117
|
+
);
|
|
118
|
+
const collateralDeficitFirst =
|
|
119
|
+
config.strategy[0].rebalanceStrategy ===
|
|
120
|
+
RebalancerStrategyOptions.CollateralDeficit;
|
|
110
121
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
'chains',
|
|
119
|
-
chainName,
|
|
120
|
-
'override',
|
|
121
|
-
overrideChainName,
|
|
122
|
-
],
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
122
|
+
if (hasCollateralDeficit && !collateralDeficitFirst) {
|
|
123
|
+
ctx.addIssue({
|
|
124
|
+
code: z.ZodIssueCode.custom,
|
|
125
|
+
message:
|
|
126
|
+
'CollateralDeficitStrategy must be first when used in composite strategy',
|
|
127
|
+
path: ['strategy'],
|
|
128
|
+
});
|
|
126
129
|
}
|
|
127
130
|
}
|
|
128
131
|
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
// Validate each strategy in the array
|
|
133
|
+
for (
|
|
134
|
+
let strategyIndex = 0;
|
|
135
|
+
strategyIndex < config.strategy.length;
|
|
136
|
+
strategyIndex++
|
|
131
137
|
) {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
const strategy = config.strategy[strategyIndex];
|
|
139
|
+
const chainNames = new Set(Object.keys(strategy.chains));
|
|
140
|
+
|
|
141
|
+
// Check each chain's overrides
|
|
142
|
+
for (const [chainName, chainConfig] of Object.entries(strategy.chains)) {
|
|
143
|
+
if ('override' in chainConfig && chainConfig.override) {
|
|
144
|
+
for (const overrideChainName of Object.keys(chainConfig.override)) {
|
|
145
|
+
// Each override key must reference a valid chain
|
|
146
|
+
if (!chainNames.has(overrideChainName)) {
|
|
147
|
+
ctx.addIssue({
|
|
148
|
+
code: z.ZodIssueCode.custom,
|
|
149
|
+
message: `Chain '${chainName}' has an override for '${overrideChainName}', but '${overrideChainName}' is not defined in the config`,
|
|
150
|
+
path: [
|
|
151
|
+
'strategy',
|
|
152
|
+
strategyIndex,
|
|
153
|
+
'chains',
|
|
154
|
+
chainName,
|
|
155
|
+
'override',
|
|
156
|
+
overrideChainName,
|
|
157
|
+
],
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Override shouldn't be self-referencing
|
|
162
|
+
if (chainName === overrideChainName) {
|
|
163
|
+
ctx.addIssue({
|
|
164
|
+
code: z.ZodIssueCode.custom,
|
|
165
|
+
message: `Chain '${chainName}' has an override for '${chainName}', but '${chainName}' is self-referencing`,
|
|
166
|
+
path: [
|
|
167
|
+
'strategy',
|
|
168
|
+
strategyIndex,
|
|
169
|
+
'chains',
|
|
170
|
+
chainName,
|
|
171
|
+
'override',
|
|
172
|
+
overrideChainName,
|
|
173
|
+
],
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (strategy.rebalanceStrategy === RebalancerStrategyOptions.MinAmount) {
|
|
181
|
+
const minAmountChainsTypes = Object.values(strategy.chains).map(
|
|
182
|
+
(c) => c.minAmount.type,
|
|
183
|
+
);
|
|
184
|
+
if (new Set(minAmountChainsTypes).size > 1) {
|
|
185
|
+
ctx.addIssue({
|
|
186
|
+
code: z.ZodIssueCode.custom,
|
|
187
|
+
message: `All chains must use the same minAmount type.`,
|
|
188
|
+
path: ['strategy', strategyIndex, 'chains'],
|
|
189
|
+
});
|
|
190
|
+
}
|
|
141
191
|
}
|
|
142
192
|
}
|
|
143
193
|
});
|
|
@@ -149,8 +199,65 @@ export type RebalancerWeightedChainConfig = z.infer<
|
|
|
149
199
|
export type RebalancerMinAmountChainConfig = z.infer<
|
|
150
200
|
typeof RebalancerMinAmountConfigSchema
|
|
151
201
|
>;
|
|
202
|
+
export type CollateralDeficitChainConfig = z.infer<
|
|
203
|
+
typeof CollateralDeficitChainConfigSchema
|
|
204
|
+
>;
|
|
152
205
|
|
|
153
206
|
export type StrategyConfig = z.infer<typeof StrategyConfigSchema>;
|
|
154
207
|
|
|
155
208
|
export type RebalancerConfig = z.infer<typeof RebalancerConfigSchema>;
|
|
156
209
|
export type RebalancerConfigFileInput = z.input<typeof RebalancerConfigSchema>;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get all unique chain names from strategy config array.
|
|
213
|
+
*/
|
|
214
|
+
export function getStrategyChainNames(strategies: StrategyConfig[]): string[] {
|
|
215
|
+
const chainSet = new Set<string>();
|
|
216
|
+
for (const strategy of strategies) {
|
|
217
|
+
Object.keys(strategy.chains).forEach((chain) => chainSet.add(chain));
|
|
218
|
+
}
|
|
219
|
+
return Array.from(chainSet);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get chain config from the first strategy that has it.
|
|
224
|
+
* Returns undefined if no strategy has the chain.
|
|
225
|
+
*/
|
|
226
|
+
export function getStrategyChainConfig(
|
|
227
|
+
strategies: StrategyConfig[],
|
|
228
|
+
chainName: string,
|
|
229
|
+
): StrategyConfig['chains'][string] | undefined {
|
|
230
|
+
for (const strategy of strategies) {
|
|
231
|
+
if (chainName in strategy.chains) {
|
|
232
|
+
return strategy.chains[chainName];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Get all unique bridge addresses from all strategies and their overrides.
|
|
240
|
+
* This is used by ActionTracker to detect inflight rebalances across all configured bridges.
|
|
241
|
+
*/
|
|
242
|
+
export function getAllBridges(strategies: StrategyConfig[]): string[] {
|
|
243
|
+
const bridges = new Set<string>();
|
|
244
|
+
|
|
245
|
+
for (const strategy of strategies) {
|
|
246
|
+
for (const chainConfig of Object.values(strategy.chains)) {
|
|
247
|
+
if (chainConfig.bridge) {
|
|
248
|
+
bridges.add(chainConfig.bridge);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (chainConfig.override) {
|
|
252
|
+
for (const overrideConfig of Object.values(chainConfig.override)) {
|
|
253
|
+
const override = overrideConfig as { bridge?: string };
|
|
254
|
+
if (override.bridge) {
|
|
255
|
+
bridges.add(override.bridge);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return Array.from(bridges);
|
|
263
|
+
}
|