@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
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import { pino } from 'pino';
|
|
3
|
+
import { Token, TokenStandard, } from '@hyperlane-xyz/sdk';
|
|
4
|
+
import { extractBridgeConfigs } from '../test/helpers.js';
|
|
5
|
+
import { CollateralDeficitStrategy } from './CollateralDeficitStrategy.js';
|
|
6
|
+
const testLogger = pino({ level: 'silent' });
|
|
7
|
+
const BRIDGE1 = '0x1234567890123456789012345678901234567890';
|
|
8
|
+
const BRIDGE2 = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd';
|
|
9
|
+
const OTHER_BRIDGE = '0x9876543210987654321098765432109876543210';
|
|
10
|
+
describe('CollateralDeficitStrategy', () => {
|
|
11
|
+
let chain1;
|
|
12
|
+
let chain2;
|
|
13
|
+
let chain3;
|
|
14
|
+
const tokensByChainName = {};
|
|
15
|
+
const tokenArgs = {
|
|
16
|
+
name: 'USDC',
|
|
17
|
+
decimals: 6, // USDC has 6 decimals
|
|
18
|
+
symbol: 'USDC',
|
|
19
|
+
standard: TokenStandard.ERC20,
|
|
20
|
+
addressOrDenom: '',
|
|
21
|
+
};
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
chain1 = 'chain1';
|
|
24
|
+
chain2 = 'chain2';
|
|
25
|
+
chain3 = 'chain3';
|
|
26
|
+
tokensByChainName[chain1] = new Token({ ...tokenArgs, chainName: chain1 });
|
|
27
|
+
tokensByChainName[chain2] = new Token({ ...tokenArgs, chainName: chain2 });
|
|
28
|
+
tokensByChainName[chain3] = new Token({ ...tokenArgs, chainName: chain3 });
|
|
29
|
+
});
|
|
30
|
+
describe('constructor', () => {
|
|
31
|
+
it('should throw an error when less than two chains are configured', () => {
|
|
32
|
+
expect(() => new CollateralDeficitStrategy({
|
|
33
|
+
[chain1]: {
|
|
34
|
+
bridge: BRIDGE1,
|
|
35
|
+
buffer: '1000',
|
|
36
|
+
},
|
|
37
|
+
}, tokensByChainName, testLogger, {})).to.throw('At least two chains must be configured');
|
|
38
|
+
});
|
|
39
|
+
it('should create a strategy with valid config', () => {
|
|
40
|
+
const strategy = new CollateralDeficitStrategy({
|
|
41
|
+
[chain1]: {
|
|
42
|
+
bridge: BRIDGE1,
|
|
43
|
+
buffer: '1000',
|
|
44
|
+
},
|
|
45
|
+
[chain2]: {
|
|
46
|
+
bridge: BRIDGE2,
|
|
47
|
+
buffer: '500',
|
|
48
|
+
},
|
|
49
|
+
}, tokensByChainName, testLogger, {});
|
|
50
|
+
expect(strategy).to.be.instanceOf(CollateralDeficitStrategy);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe('getCategorizedBalances', () => {
|
|
54
|
+
it('should detect deficit when balance is negative and add buffer', () => {
|
|
55
|
+
const strategy = new CollateralDeficitStrategy({
|
|
56
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
57
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
58
|
+
}, tokensByChainName, testLogger, {});
|
|
59
|
+
const rawBalances = {
|
|
60
|
+
[chain1]: -5000000n, // -5 USDC (6 decimals)
|
|
61
|
+
[chain2]: 10000000n, // 10 USDC
|
|
62
|
+
};
|
|
63
|
+
const result = strategy['getCategorizedBalances'](rawBalances);
|
|
64
|
+
// chain1: deficit = |-5 USDC| + 1000 USDC = 1005 USDC = 1005000000 (wei)
|
|
65
|
+
expect(result.deficits).to.have.lengthOf(1);
|
|
66
|
+
expect(result.deficits[0].chain).to.equal(chain1);
|
|
67
|
+
expect(result.deficits[0].amount).to.equal(1005000000n);
|
|
68
|
+
// chain2: surplus = 10 USDC
|
|
69
|
+
expect(result.surpluses).to.have.lengthOf(1);
|
|
70
|
+
expect(result.surpluses[0].chain).to.equal(chain2);
|
|
71
|
+
expect(result.surpluses[0].amount).to.equal(10000000n);
|
|
72
|
+
});
|
|
73
|
+
it('should treat zero balance as neither surplus nor deficit', () => {
|
|
74
|
+
const strategy = new CollateralDeficitStrategy({
|
|
75
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
76
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
77
|
+
}, tokensByChainName, testLogger, {});
|
|
78
|
+
const rawBalances = {
|
|
79
|
+
[chain1]: 0n,
|
|
80
|
+
[chain2]: 10000000n,
|
|
81
|
+
};
|
|
82
|
+
const result = strategy['getCategorizedBalances'](rawBalances);
|
|
83
|
+
expect(result.deficits).to.have.lengthOf(0);
|
|
84
|
+
expect(result.surpluses).to.have.lengthOf(1);
|
|
85
|
+
expect(result.surpluses[0].chain).to.equal(chain2);
|
|
86
|
+
});
|
|
87
|
+
it('should treat positive balance as surplus', () => {
|
|
88
|
+
const strategy = new CollateralDeficitStrategy({
|
|
89
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
90
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
91
|
+
}, tokensByChainName, testLogger, {});
|
|
92
|
+
const rawBalances = {
|
|
93
|
+
[chain1]: 5000000n, // 5 USDC
|
|
94
|
+
[chain2]: 10000000n, // 10 USDC
|
|
95
|
+
};
|
|
96
|
+
const result = strategy['getCategorizedBalances'](rawBalances);
|
|
97
|
+
expect(result.deficits).to.have.lengthOf(0);
|
|
98
|
+
expect(result.surpluses).to.have.lengthOf(2);
|
|
99
|
+
});
|
|
100
|
+
it('should filter pending rebalances by configured bridges and simulate', () => {
|
|
101
|
+
const config = {
|
|
102
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
103
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
104
|
+
};
|
|
105
|
+
const bridgeConfigs = extractBridgeConfigs(config);
|
|
106
|
+
const strategy = new CollateralDeficitStrategy(config, tokensByChainName, testLogger, bridgeConfigs);
|
|
107
|
+
const rawBalances = {
|
|
108
|
+
[chain1]: -10000000n, // -10 USDC before simulation
|
|
109
|
+
[chain2]: 20000000n, // 20 USDC
|
|
110
|
+
};
|
|
111
|
+
const pendingRebalances = [
|
|
112
|
+
{
|
|
113
|
+
origin: chain2,
|
|
114
|
+
destination: chain1,
|
|
115
|
+
amount: 5000000n, // 5 USDC pending to chain1
|
|
116
|
+
bridge: BRIDGE2, // Matches chain2's bridge for chain2->chain1 route
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
const result = strategy['getCategorizedBalances'](rawBalances, pendingRebalances);
|
|
120
|
+
// After simulation: chain1 = -10 + 5 = -5 USDC (destination increase)
|
|
121
|
+
// Deficit = |-5| + 1000 = 1005 USDC
|
|
122
|
+
expect(result.deficits).to.have.lengthOf(1);
|
|
123
|
+
expect(result.deficits[0].chain).to.equal(chain1);
|
|
124
|
+
expect(result.deficits[0].amount).to.equal(1005000000n);
|
|
125
|
+
// chain2 after simulation: 20 USDC (no change - origin already deducted on-chain)
|
|
126
|
+
// Simulation only adds to destination, doesn't subtract from origin
|
|
127
|
+
expect(result.surpluses).to.have.lengthOf(1);
|
|
128
|
+
expect(result.surpluses[0].chain).to.equal(chain2);
|
|
129
|
+
expect(result.surpluses[0].amount).to.equal(20000000n);
|
|
130
|
+
});
|
|
131
|
+
it('should filter out pending rebalances with different bridge', () => {
|
|
132
|
+
const config = {
|
|
133
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
134
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
135
|
+
};
|
|
136
|
+
const bridgeConfigs = extractBridgeConfigs(config);
|
|
137
|
+
const strategy = new CollateralDeficitStrategy(config, tokensByChainName, testLogger, bridgeConfigs);
|
|
138
|
+
const rawBalances = {
|
|
139
|
+
[chain1]: -10000000n,
|
|
140
|
+
[chain2]: 20000000n,
|
|
141
|
+
};
|
|
142
|
+
const pendingRebalances = [
|
|
143
|
+
{
|
|
144
|
+
origin: chain2,
|
|
145
|
+
destination: chain1,
|
|
146
|
+
amount: 5000000n,
|
|
147
|
+
bridge: OTHER_BRIDGE, // Does NOT match chain2's configured bridge for chain2->chain1
|
|
148
|
+
},
|
|
149
|
+
];
|
|
150
|
+
const result = strategy['getCategorizedBalances'](rawBalances, pendingRebalances);
|
|
151
|
+
// Pending rebalance should be filtered out, so no simulation
|
|
152
|
+
// Deficit = |-10| + 1000 = 1010 USDC
|
|
153
|
+
expect(result.deficits).to.have.lengthOf(1);
|
|
154
|
+
expect(result.deficits[0].amount).to.equal(1010000000n);
|
|
155
|
+
// chain2: no subtraction, stays at 20 USDC
|
|
156
|
+
expect(result.surpluses[0].amount).to.equal(20000000n);
|
|
157
|
+
});
|
|
158
|
+
it('should handle pending rebalance that fully covers deficit', () => {
|
|
159
|
+
const config = {
|
|
160
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
161
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
162
|
+
};
|
|
163
|
+
const bridgeConfigs = extractBridgeConfigs(config);
|
|
164
|
+
const strategy = new CollateralDeficitStrategy(config, tokensByChainName, testLogger, bridgeConfigs);
|
|
165
|
+
const rawBalances = {
|
|
166
|
+
[chain1]: -5000000n, // -5 USDC
|
|
167
|
+
[chain2]: 20000000n,
|
|
168
|
+
};
|
|
169
|
+
const pendingRebalances = [
|
|
170
|
+
{
|
|
171
|
+
origin: chain2,
|
|
172
|
+
destination: chain1,
|
|
173
|
+
amount: 10000000n, // 10 USDC pending - more than enough
|
|
174
|
+
bridge: BRIDGE2, // Matches chain2's configured bridge for chain2->chain1
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
const result = strategy['getCategorizedBalances'](rawBalances, pendingRebalances);
|
|
178
|
+
// After simulation: chain1 = -5 + 10 = 5 USDC (positive, no deficit)
|
|
179
|
+
expect(result.deficits).to.have.lengthOf(0);
|
|
180
|
+
expect(result.surpluses).to.have.lengthOf(2); // Both chains have surplus
|
|
181
|
+
});
|
|
182
|
+
it('should handle multiple chains with mixed balances', () => {
|
|
183
|
+
const strategy = new CollateralDeficitStrategy({
|
|
184
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
185
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
186
|
+
[chain3]: { bridge: BRIDGE1, buffer: '2000' },
|
|
187
|
+
}, tokensByChainName, testLogger, {});
|
|
188
|
+
const rawBalances = {
|
|
189
|
+
[chain1]: -5000000n, // -5 USDC -> deficit
|
|
190
|
+
[chain2]: 10000000n, // 10 USDC -> surplus
|
|
191
|
+
[chain3]: -3000000n, // -3 USDC -> deficit
|
|
192
|
+
};
|
|
193
|
+
const result = strategy['getCategorizedBalances'](rawBalances);
|
|
194
|
+
expect(result.deficits).to.have.lengthOf(2);
|
|
195
|
+
expect(result.surpluses).to.have.lengthOf(1);
|
|
196
|
+
// chain1: deficit = 5 + 1000 = 1005 USDC
|
|
197
|
+
const chain1Deficit = result.deficits.find((d) => d.chain === chain1);
|
|
198
|
+
expect(chain1Deficit?.amount).to.equal(1005000000n);
|
|
199
|
+
// chain3: deficit = 3 + 2000 = 2003 USDC
|
|
200
|
+
const chain3Deficit = result.deficits.find((d) => d.chain === chain3);
|
|
201
|
+
expect(chain3Deficit?.amount).to.equal(2003000000n);
|
|
202
|
+
});
|
|
203
|
+
it('should handle empty pending rebalances array', () => {
|
|
204
|
+
const strategy = new CollateralDeficitStrategy({
|
|
205
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
206
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
207
|
+
}, tokensByChainName, testLogger, {});
|
|
208
|
+
const rawBalances = {
|
|
209
|
+
[chain1]: -5000000n,
|
|
210
|
+
[chain2]: 10000000n,
|
|
211
|
+
};
|
|
212
|
+
const result = strategy['getCategorizedBalances'](rawBalances, []);
|
|
213
|
+
// No simulation should occur
|
|
214
|
+
expect(result.deficits).to.have.lengthOf(1);
|
|
215
|
+
expect(result.deficits[0].amount).to.equal(1005000000n);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
describe('getRebalancingRoutes', () => {
|
|
219
|
+
it('should set bridge field on output routes', () => {
|
|
220
|
+
const config = {
|
|
221
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
222
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
223
|
+
};
|
|
224
|
+
const bridgeConfigs = extractBridgeConfigs(config);
|
|
225
|
+
const strategy = new CollateralDeficitStrategy(config, tokensByChainName, testLogger, bridgeConfigs);
|
|
226
|
+
// Start with positive balances
|
|
227
|
+
const rawBalances = {
|
|
228
|
+
[chain1]: 2000000n, // 2 USDC
|
|
229
|
+
[chain2]: 20000000n, // 20 USDC
|
|
230
|
+
};
|
|
231
|
+
// Pending transfer will drain chain1 to create deficit
|
|
232
|
+
const inflightContext = {
|
|
233
|
+
pendingTransfers: [
|
|
234
|
+
{
|
|
235
|
+
origin: chain2,
|
|
236
|
+
destination: chain1,
|
|
237
|
+
amount: 7000000n, // 7 USDC pending to chain1
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
pendingRebalances: [],
|
|
241
|
+
};
|
|
242
|
+
// After reserveCollateral: chain1 = 2 - 7 = -5 USDC (deficit)
|
|
243
|
+
const routes = strategy.getRebalancingRoutes(rawBalances, inflightContext);
|
|
244
|
+
expect(routes).to.have.lengthOf(1);
|
|
245
|
+
expect(routes[0].origin).to.equal(chain2);
|
|
246
|
+
expect(routes[0].destination).to.equal(chain1);
|
|
247
|
+
expect(routes[0].bridge).to.equal(BRIDGE2); // Uses chain2's (origin) bridge
|
|
248
|
+
});
|
|
249
|
+
it('should generate routes from surplus to deficit chains', () => {
|
|
250
|
+
const config = {
|
|
251
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
252
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
253
|
+
[chain3]: { bridge: BRIDGE1, buffer: '100' },
|
|
254
|
+
};
|
|
255
|
+
const bridgeConfigs = extractBridgeConfigs(config);
|
|
256
|
+
const strategy = new CollateralDeficitStrategy(config, tokensByChainName, testLogger, bridgeConfigs);
|
|
257
|
+
// Start with positive balances
|
|
258
|
+
const rawBalances = {
|
|
259
|
+
[chain1]: 5000000n, // 5 USDC
|
|
260
|
+
[chain2]: 20000000n, // 20 USDC
|
|
261
|
+
[chain3]: 5000000n, // 5 USDC
|
|
262
|
+
};
|
|
263
|
+
// Pending transfer will create deficit on chain1
|
|
264
|
+
const inflightContext = {
|
|
265
|
+
pendingTransfers: [
|
|
266
|
+
{
|
|
267
|
+
origin: chain2,
|
|
268
|
+
destination: chain1,
|
|
269
|
+
amount: 15000000n, // 15 USDC pending to chain1
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
pendingRebalances: [],
|
|
273
|
+
};
|
|
274
|
+
// After reserveCollateral: chain1 = 5 - 15 = -10 USDC (deficit)
|
|
275
|
+
const routes = strategy.getRebalancingRoutes(rawBalances, inflightContext);
|
|
276
|
+
// Should have route(s) from surplus chains (chain2, chain3) to deficit chain (chain1)
|
|
277
|
+
expect(routes.length).to.be.greaterThan(0);
|
|
278
|
+
routes.forEach((route) => {
|
|
279
|
+
expect([chain2, chain3]).to.include(route.origin);
|
|
280
|
+
expect(route.destination).to.equal(chain1);
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
describe('filterByConfiguredBridges', () => {
|
|
285
|
+
it('should filter rebalances by configured bridge for route', () => {
|
|
286
|
+
const config = {
|
|
287
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
288
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
289
|
+
};
|
|
290
|
+
const bridgeConfigs = extractBridgeConfigs(config);
|
|
291
|
+
const strategy = new CollateralDeficitStrategy(config, tokensByChainName, testLogger, bridgeConfigs);
|
|
292
|
+
const pendingRebalances = [
|
|
293
|
+
{
|
|
294
|
+
origin: chain2,
|
|
295
|
+
destination: chain1,
|
|
296
|
+
amount: 5000000n,
|
|
297
|
+
bridge: BRIDGE2,
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
origin: chain1,
|
|
301
|
+
destination: chain2,
|
|
302
|
+
amount: 3000000n,
|
|
303
|
+
bridge: OTHER_BRIDGE,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
origin: chain2,
|
|
307
|
+
destination: chain1,
|
|
308
|
+
amount: 2000000n,
|
|
309
|
+
},
|
|
310
|
+
];
|
|
311
|
+
const filtered = strategy['filterByConfiguredBridges'](pendingRebalances);
|
|
312
|
+
expect(filtered).to.have.lengthOf(2);
|
|
313
|
+
expect(filtered[0].bridge).to.equal(BRIDGE2);
|
|
314
|
+
expect(filtered[1].bridge).to.be.undefined;
|
|
315
|
+
});
|
|
316
|
+
it('should include rebalance when bridge matches configured bridge for the route', () => {
|
|
317
|
+
const config = {
|
|
318
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
319
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
320
|
+
};
|
|
321
|
+
const bridgeConfigs = extractBridgeConfigs(config);
|
|
322
|
+
const strategy = new CollateralDeficitStrategy(config, tokensByChainName, testLogger, bridgeConfigs);
|
|
323
|
+
const pendingRebalances = [
|
|
324
|
+
{
|
|
325
|
+
origin: chain2,
|
|
326
|
+
destination: chain1,
|
|
327
|
+
amount: 5000000n,
|
|
328
|
+
bridge: BRIDGE2,
|
|
329
|
+
},
|
|
330
|
+
];
|
|
331
|
+
const filtered = strategy['filterByConfiguredBridges'](pendingRebalances);
|
|
332
|
+
expect(filtered).to.have.lengthOf(1);
|
|
333
|
+
expect(filtered[0].bridge).to.equal(BRIDGE2);
|
|
334
|
+
});
|
|
335
|
+
it('should exclude rebalance when bridge does not match configured bridge for the route', () => {
|
|
336
|
+
const config = {
|
|
337
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
338
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
339
|
+
};
|
|
340
|
+
const bridgeConfigs = extractBridgeConfigs(config);
|
|
341
|
+
const strategy = new CollateralDeficitStrategy(config, tokensByChainName, testLogger, bridgeConfigs);
|
|
342
|
+
// Route from chain2 → chain1 with a different bridge
|
|
343
|
+
const pendingRebalances = [
|
|
344
|
+
{
|
|
345
|
+
origin: chain2,
|
|
346
|
+
destination: chain1,
|
|
347
|
+
amount: 5000000n,
|
|
348
|
+
bridge: BRIDGE1, // Does NOT match configured bridge for chain2->chain1 (should be BRIDGE2)
|
|
349
|
+
},
|
|
350
|
+
];
|
|
351
|
+
const filtered = strategy['filterByConfiguredBridges'](pendingRebalances);
|
|
352
|
+
expect(filtered).to.have.lengthOf(0);
|
|
353
|
+
});
|
|
354
|
+
it('should return empty array for undefined pending rebalances', () => {
|
|
355
|
+
const strategy = new CollateralDeficitStrategy({
|
|
356
|
+
[chain1]: { bridge: BRIDGE1, buffer: '1000' },
|
|
357
|
+
[chain2]: { bridge: BRIDGE2, buffer: '500' },
|
|
358
|
+
}, tokensByChainName, testLogger, {});
|
|
359
|
+
const filtered = strategy['filterByConfiguredBridges'](undefined);
|
|
360
|
+
expect(filtered).to.have.lengthOf(0);
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
//# sourceMappingURL=CollateralDeficitStrategy.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollateralDeficitStrategy.test.js","sourceRoot":"","sources":["../../src/strategy/CollateralDeficitStrategy.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Logger } from 'pino';
|
|
2
|
+
import type { IStrategy, InflightContext, RawBalances, StrategyRoute } from '../interfaces/IStrategy.js';
|
|
3
|
+
/**
|
|
4
|
+
* Composite strategy that runs multiple sub-strategies sequentially.
|
|
5
|
+
*
|
|
6
|
+
* Key behavior: Routes from earlier strategies are passed as proposedRebalances
|
|
7
|
+
* to later strategies, allowing coordination between strategies.
|
|
8
|
+
*
|
|
9
|
+
* Requires at least 2 sub-strategies.
|
|
10
|
+
*/
|
|
11
|
+
export declare class CompositeStrategy implements IStrategy {
|
|
12
|
+
private readonly strategies;
|
|
13
|
+
readonly name = "composite";
|
|
14
|
+
protected readonly logger: Logger;
|
|
15
|
+
constructor(strategies: IStrategy[], logger: Logger);
|
|
16
|
+
getRebalancingRoutes(rawBalances: RawBalances, inflightContext?: InflightContext): StrategyRoute[];
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=CompositeStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompositeStrategy.d.ts","sourceRoot":"","sources":["../../src/strategy/CompositeStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,WAAW,EACX,aAAa,EACd,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,iBAAkB,YAAW,SAAS;IAK/C,OAAO,CAAC,QAAQ,CAAC,UAAU;IAJ7B,QAAQ,CAAC,IAAI,eAAe;IAC5B,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAGf,UAAU,EAAE,SAAS,EAAE,EACxC,MAAM,EAAE,MAAM;IAehB,oBAAoB,CAClB,WAAW,EAAE,WAAW,EACxB,eAAe,CAAC,EAAE,eAAe,GAChC,aAAa,EAAE;CA4DnB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composite strategy that runs multiple sub-strategies sequentially.
|
|
3
|
+
*
|
|
4
|
+
* Key behavior: Routes from earlier strategies are passed as proposedRebalances
|
|
5
|
+
* to later strategies, allowing coordination between strategies.
|
|
6
|
+
*
|
|
7
|
+
* Requires at least 2 sub-strategies.
|
|
8
|
+
*/
|
|
9
|
+
export class CompositeStrategy {
|
|
10
|
+
strategies;
|
|
11
|
+
name = 'composite';
|
|
12
|
+
logger;
|
|
13
|
+
constructor(strategies, logger) {
|
|
14
|
+
this.strategies = strategies;
|
|
15
|
+
if (strategies.length < 2) {
|
|
16
|
+
throw new Error('CompositeStrategy requires at least 2 sub-strategies');
|
|
17
|
+
}
|
|
18
|
+
this.logger = logger.child({ class: CompositeStrategy.name });
|
|
19
|
+
this.logger.info({
|
|
20
|
+
strategyCount: strategies.length,
|
|
21
|
+
strategies: strategies.map((s) => s.name),
|
|
22
|
+
}, 'CompositeStrategy created');
|
|
23
|
+
}
|
|
24
|
+
getRebalancingRoutes(rawBalances, inflightContext) {
|
|
25
|
+
const allRoutes = [];
|
|
26
|
+
// Track routes from earlier strategies in this cycle as proposedRebalances
|
|
27
|
+
// These are NOT yet executed, so strategies need to simulate both origin and destination
|
|
28
|
+
let accumulatedProposedRebalances = [];
|
|
29
|
+
for (let i = 0; i < this.strategies.length; i++) {
|
|
30
|
+
const strategy = this.strategies[i];
|
|
31
|
+
// Build context with:
|
|
32
|
+
// - pendingRebalances: actual in-flight intents (origin tx confirmed, passed through from caller)
|
|
33
|
+
// - proposedRebalances: routes from earlier strategies in THIS cycle (not yet executed)
|
|
34
|
+
const contextForStrategy = {
|
|
35
|
+
pendingTransfers: inflightContext?.pendingTransfers ?? [],
|
|
36
|
+
pendingRebalances: inflightContext?.pendingRebalances ?? [],
|
|
37
|
+
proposedRebalances: accumulatedProposedRebalances,
|
|
38
|
+
};
|
|
39
|
+
this.logger.debug({
|
|
40
|
+
strategyIndex: i,
|
|
41
|
+
strategyName: strategy.name,
|
|
42
|
+
pendingRebalancesCount: contextForStrategy.pendingRebalances.length,
|
|
43
|
+
proposedRebalancesCount: accumulatedProposedRebalances.length,
|
|
44
|
+
}, 'Running sub-strategy');
|
|
45
|
+
const routes = strategy.getRebalancingRoutes(rawBalances, contextForStrategy);
|
|
46
|
+
this.logger.debug({
|
|
47
|
+
strategyIndex: i,
|
|
48
|
+
strategyName: strategy.name,
|
|
49
|
+
routeCount: routes.length,
|
|
50
|
+
}, 'Sub-strategy returned routes');
|
|
51
|
+
// Add routes to proposedRebalances for next strategy
|
|
52
|
+
accumulatedProposedRebalances = [
|
|
53
|
+
...accumulatedProposedRebalances,
|
|
54
|
+
...routes,
|
|
55
|
+
];
|
|
56
|
+
// Add to final result
|
|
57
|
+
allRoutes.push(...routes);
|
|
58
|
+
}
|
|
59
|
+
this.logger.info({ totalRoutes: allRoutes.length }, 'CompositeStrategy merged routes from all sub-strategies');
|
|
60
|
+
return allRoutes;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=CompositeStrategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompositeStrategy.js","sourceRoot":"","sources":["../../src/strategy/CompositeStrategy.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAiB;IAKT;IAJV,IAAI,GAAG,WAAW,CAAC;IACT,MAAM,CAAS;IAElC,YACmB,UAAuB,EACxC,MAAc;QADG,eAAU,GAAV,UAAU,CAAa;QAGxC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM,CAAC,IAAI,CACd;YACE,aAAa,EAAE,UAAU,CAAC,MAAM;YAChC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAC1C,EACD,2BAA2B,CAC5B,CAAC;IACJ,CAAC;IAED,oBAAoB,CAClB,WAAwB,EACxB,eAAiC;QAEjC,MAAM,SAAS,GAAoB,EAAE,CAAC;QAEtC,2EAA2E;QAC3E,yFAAyF;QACzF,IAAI,6BAA6B,GAAoB,EAAE,CAAC;QAExD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAEpC,sBAAsB;YACtB,kGAAkG;YAClG,wFAAwF;YACxF,MAAM,kBAAkB,GAAoB;gBAC1C,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,IAAI,EAAE;gBACzD,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,IAAI,EAAE;gBAC3D,kBAAkB,EAAE,6BAA6B;aAClD,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CACf;gBACE,aAAa,EAAE,CAAC;gBAChB,YAAY,EAAE,QAAQ,CAAC,IAAI;gBAC3B,sBAAsB,EAAE,kBAAkB,CAAC,iBAAiB,CAAC,MAAM;gBACnE,uBAAuB,EAAE,6BAA6B,CAAC,MAAM;aAC9D,EACD,sBAAsB,CACvB,CAAC;YAEF,MAAM,MAAM,GAAG,QAAQ,CAAC,oBAAoB,CAC1C,WAAW,EACX,kBAAkB,CACnB,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CACf;gBACE,aAAa,EAAE,CAAC;gBAChB,YAAY,EAAE,QAAQ,CAAC,IAAI;gBAC3B,UAAU,EAAE,MAAM,CAAC,MAAM;aAC1B,EACD,8BAA8B,CAC/B,CAAC;YAEF,qDAAqD;YACrD,6BAA6B,GAAG;gBAC9B,GAAG,6BAA6B;gBAChC,GAAG,MAAM;aACV,CAAC;YAEF,sBAAsB;YACtB,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,EAAE,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,EACjC,yDAAyD,CAC1D,CAAC;QAEF,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompositeStrategy.test.d.ts","sourceRoot":"","sources":["../../src/strategy/CompositeStrategy.test.ts"],"names":[],"mappings":""}
|