@hyperlane-xyz/rebalancer 27.2.12 → 27.2.13

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 (91) hide show
  1. package/dist/core/InventoryRebalancer.d.ts +11 -19
  2. package/dist/core/InventoryRebalancer.d.ts.map +1 -1
  3. package/dist/core/InventoryRebalancer.js +336 -268
  4. package/dist/core/InventoryRebalancer.js.map +1 -1
  5. package/dist/core/InventoryRebalancer.test.js +397 -23
  6. package/dist/core/InventoryRebalancer.test.js.map +1 -1
  7. package/dist/core/Rebalancer.d.ts.map +1 -1
  8. package/dist/core/Rebalancer.js +12 -6
  9. package/dist/core/Rebalancer.js.map +1 -1
  10. package/dist/core/Rebalancer.test.js +51 -0
  11. package/dist/core/Rebalancer.test.js.map +1 -1
  12. package/dist/core/RebalancerOrchestrator.test.js +0 -1
  13. package/dist/core/RebalancerOrchestrator.test.js.map +1 -1
  14. package/dist/core/RebalancerService.d.ts +2 -3
  15. package/dist/core/RebalancerService.d.ts.map +1 -1
  16. package/dist/core/RebalancerService.js +3 -2
  17. package/dist/core/RebalancerService.js.map +1 -1
  18. package/dist/core/RebalancerService.test.js +24 -0
  19. package/dist/core/RebalancerService.test.js.map +1 -1
  20. package/dist/e2e/harness/TestHelpers.js +1 -2
  21. package/dist/e2e/harness/TestHelpers.js.map +1 -1
  22. package/dist/factories/RebalancerContextFactory.d.ts +4 -5
  23. package/dist/factories/RebalancerContextFactory.d.ts.map +1 -1
  24. package/dist/factories/RebalancerContextFactory.js +12 -7
  25. package/dist/factories/RebalancerContextFactory.js.map +1 -1
  26. package/dist/factories/RebalancerContextFactory.test.js +99 -2
  27. package/dist/factories/RebalancerContextFactory.test.js.map +1 -1
  28. package/dist/interfaces/IRebalancer.d.ts +4 -2
  29. package/dist/interfaces/IRebalancer.d.ts.map +1 -1
  30. package/dist/metrics/scripts/metrics.d.ts +1 -1
  31. package/dist/monitor/Monitor.d.ts.map +1 -1
  32. package/dist/monitor/Monitor.js +14 -6
  33. package/dist/monitor/Monitor.js.map +1 -1
  34. package/dist/strategy/BaseStrategy.d.ts.map +1 -1
  35. package/dist/strategy/BaseStrategy.js +13 -11
  36. package/dist/strategy/BaseStrategy.js.map +1 -1
  37. package/dist/strategy/CollateralDeficitStrategy.d.ts.map +1 -1
  38. package/dist/strategy/CollateralDeficitStrategy.js +2 -2
  39. package/dist/strategy/CollateralDeficitStrategy.js.map +1 -1
  40. package/dist/strategy/MinAmountStrategy.d.ts +1 -0
  41. package/dist/strategy/MinAmountStrategy.d.ts.map +1 -1
  42. package/dist/strategy/MinAmountStrategy.js +12 -8
  43. package/dist/strategy/MinAmountStrategy.js.map +1 -1
  44. package/dist/strategy/MinAmountStrategy.test.js +189 -2
  45. package/dist/strategy/MinAmountStrategy.test.js.map +1 -1
  46. package/dist/test/helpers.d.ts +11 -3
  47. package/dist/test/helpers.d.ts.map +1 -1
  48. package/dist/test/helpers.js +9 -11
  49. package/dist/test/helpers.js.map +1 -1
  50. package/dist/test/lifiMocks.d.ts.map +1 -1
  51. package/dist/test/lifiMocks.js +5 -2
  52. package/dist/test/lifiMocks.js.map +1 -1
  53. package/dist/tracking/ActionTracker.d.ts.map +1 -1
  54. package/dist/tracking/ActionTracker.js +2 -1
  55. package/dist/tracking/ActionTracker.js.map +1 -1
  56. package/dist/tracking/ActionTracker.test.js +39 -0
  57. package/dist/tracking/ActionTracker.test.js.map +1 -1
  58. package/dist/utils/balanceUtils.d.ts +7 -1
  59. package/dist/utils/balanceUtils.d.ts.map +1 -1
  60. package/dist/utils/balanceUtils.js +39 -1
  61. package/dist/utils/balanceUtils.js.map +1 -1
  62. package/dist/utils/balanceUtils.test.js +55 -1
  63. package/dist/utils/balanceUtils.test.js.map +1 -1
  64. package/dist/utils/blockTag.d.ts +3 -3
  65. package/dist/utils/blockTag.d.ts.map +1 -1
  66. package/dist/utils/blockTag.js +1 -1
  67. package/dist/utils/blockTag.js.map +1 -1
  68. package/package.json +7 -7
  69. package/src/core/InventoryRebalancer.test.ts +503 -38
  70. package/src/core/InventoryRebalancer.ts +483 -350
  71. package/src/core/Rebalancer.test.ts +84 -0
  72. package/src/core/Rebalancer.ts +22 -6
  73. package/src/core/RebalancerOrchestrator.test.ts +0 -1
  74. package/src/core/RebalancerService.test.ts +35 -0
  75. package/src/core/RebalancerService.ts +9 -5
  76. package/src/e2e/harness/TestHelpers.ts +3 -3
  77. package/src/factories/RebalancerContextFactory.test.ts +143 -6
  78. package/src/factories/RebalancerContextFactory.ts +29 -17
  79. package/src/interfaces/IRebalancer.ts +4 -1
  80. package/src/monitor/Monitor.ts +19 -6
  81. package/src/strategy/BaseStrategy.ts +18 -15
  82. package/src/strategy/CollateralDeficitStrategy.ts +4 -3
  83. package/src/strategy/MinAmountStrategy.test.ts +238 -2
  84. package/src/strategy/MinAmountStrategy.ts +29 -17
  85. package/src/test/helpers.ts +13 -12
  86. package/src/test/lifiMocks.ts +5 -2
  87. package/src/tracking/ActionTracker.test.ts +47 -0
  88. package/src/tracking/ActionTracker.ts +2 -1
  89. package/src/utils/balanceUtils.test.ts +87 -1
  90. package/src/utils/balanceUtils.ts +73 -2
  91. package/src/utils/blockTag.ts +9 -4
@@ -1,12 +1,68 @@
1
1
  import { type Logger } from 'pino';
2
2
 
3
- import { type ChainName } from '@hyperlane-xyz/sdk';
3
+ import {
4
+ type IToken,
5
+ alignLocalAmountToMessage,
6
+ messageAmountFromLocal,
7
+ minLocalAmountForMessage,
8
+ normalizeScale,
9
+ scalesEqual,
10
+ type ChainName,
11
+ type NormalizedScale,
12
+ type ScaleAlignment,
13
+ type Token,
14
+ } from '@hyperlane-xyz/sdk';
15
+ import { toWei } from '@hyperlane-xyz/utils';
4
16
 
5
17
  import { type MonitorEvent } from '../interfaces/IMonitor.js';
6
18
  import { type RawBalances } from '../interfaces/IStrategy.js';
7
19
 
8
20
  import { isCollateralizedTokenEligibleForRebalancing } from './tokenUtils.js';
9
21
 
22
+ export function getTokenScale(token: Token): NormalizedScale {
23
+ return normalizeScale(token.scale);
24
+ }
25
+
26
+ export function isIdentityScale(token: Token): boolean {
27
+ return scalesEqual(token.scale, undefined);
28
+ }
29
+
30
+ export function normalizeToCanonical(
31
+ localAmount: bigint,
32
+ tokenOrScale: Token | IToken | NormalizedScale,
33
+ ): bigint {
34
+ return messageAmountFromLocal(localAmount, getScaleInput(tokenOrScale));
35
+ }
36
+
37
+ export function denormalizeToLocal(
38
+ canonicalAmount: bigint,
39
+ tokenOrScale: Token | IToken | NormalizedScale,
40
+ ): bigint {
41
+ // Use ceil semantics so the returned local amount always produces at least
42
+ // the requested canonical progress once the token router floors on outbound.
43
+ return minLocalAmountForMessage(canonicalAmount, getScaleInput(tokenOrScale));
44
+ }
45
+
46
+ export function alignLocalToCanonical(
47
+ localAmount: bigint,
48
+ tokenOrScale: Token | IToken | NormalizedScale,
49
+ ): ScaleAlignment {
50
+ return alignLocalAmountToMessage(localAmount, getScaleInput(tokenOrScale));
51
+ }
52
+
53
+ export function normalizeConfiguredAmount(
54
+ amount: string | number,
55
+ token: Token,
56
+ ): bigint {
57
+ return normalizeToCanonical(BigInt(toWei(amount, token.decimals)), token);
58
+ }
59
+
60
+ function getScaleInput(tokenOrScale: Token | IToken | NormalizedScale) {
61
+ return 'numerator' in tokenOrScale && 'denominator' in tokenOrScale
62
+ ? tokenOrScale
63
+ : tokenOrScale.scale;
64
+ }
65
+
10
66
  /**
11
67
  * Returns the raw balances required by the strategies from the monitor event
12
68
  * @param chains - The chains that should be included in the raw balances (e.g. the chains in the rebalancer config)
@@ -58,7 +114,22 @@ export function getRawBalances(
58
114
  );
59
115
  }
60
116
 
61
- balances[token.chainName] = bridgedSupply;
117
+ const normalizedBalance = normalizeToCanonical(bridgedSupply, token);
118
+ balances[token.chainName] = normalizedBalance;
119
+
120
+ if (!isIdentityScale(token)) {
121
+ logger.debug(
122
+ {
123
+ context: getRawBalances.name,
124
+ chain: token.chainName,
125
+ tokenSymbol: token.symbol,
126
+ bridgedSupply: bridgedSupply.toString(),
127
+ normalizedBalance: normalizedBalance.toString(),
128
+ scale: getTokenScale(token),
129
+ },
130
+ 'Normalized bridged supply to canonical units',
131
+ );
132
+ }
62
133
  }
63
134
 
64
135
  return balances;
@@ -2,8 +2,10 @@ import type { Logger } from 'pino';
2
2
 
3
3
  import { providers } from 'ethers';
4
4
 
5
- import { EthJsonRpcBlockParameterTag } from '@hyperlane-xyz/sdk';
6
- import type { MinimalProviderRegistry } from '@hyperlane-xyz/sdk/providers/MinimalProviderRegistry';
5
+ import {
6
+ EthJsonRpcBlockParameterTag,
7
+ type MultiProtocolProvider,
8
+ } from '@hyperlane-xyz/sdk';
7
9
  import { ProtocolType } from '@hyperlane-xyz/utils';
8
10
  import type { ConfirmedBlockTag } from '../interfaces/IMonitor.js';
9
11
 
@@ -11,13 +13,16 @@ import type { ConfirmedBlockTag } from '../interfaces/IMonitor.js';
11
13
  * Get the confirmed block tag for a chain, accounting for reorg period.
12
14
  * Returns a block number that is safe from reorgs, or a named tag like 'finalized'.
13
15
  *
14
- * @param multiProvider - MinimalProviderRegistry instance
16
+ * @param multiProvider - Provider registry with chain metadata and ethers access
15
17
  * @param chainName - Name of the chain
16
18
  * @param logger - Optional logger for warnings
17
19
  * @returns Confirmed block tag (number, named tag, or undefined on error)
18
20
  */
19
21
  export async function getConfirmedBlockTag(
20
- multiProvider: MinimalProviderRegistry,
22
+ multiProvider: Pick<
23
+ MultiProtocolProvider,
24
+ 'getChainMetadata' | 'getEthersV5Provider'
25
+ >,
21
26
  chainName: string,
22
27
  logger?: Logger,
23
28
  ): Promise<ConfirmedBlockTag> {