@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.
- package/dist/bridges/LiFiBridge.d.ts +67 -0
- package/dist/bridges/LiFiBridge.d.ts.map +1 -0
- package/dist/bridges/LiFiBridge.js +386 -0
- package/dist/bridges/LiFiBridge.js.map +1 -0
- package/dist/config/RebalancerConfig.d.ts +8 -2
- package/dist/config/RebalancerConfig.d.ts.map +1 -1
- package/dist/config/RebalancerConfig.js +9 -4
- package/dist/config/RebalancerConfig.js.map +1 -1
- package/dist/config/RebalancerConfig.test.js +135 -1
- package/dist/config/RebalancerConfig.test.js.map +1 -1
- package/dist/config/types.d.ts +1023 -304
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +113 -10
- package/dist/config/types.js.map +1 -1
- package/dist/core/InventoryRebalancer.d.ts +190 -0
- package/dist/core/InventoryRebalancer.d.ts.map +1 -0
- package/dist/core/InventoryRebalancer.js +892 -0
- package/dist/core/InventoryRebalancer.js.map +1 -0
- package/dist/core/InventoryRebalancer.test.d.ts +2 -0
- package/dist/core/InventoryRebalancer.test.d.ts.map +1 -0
- package/dist/core/InventoryRebalancer.test.js +1382 -0
- package/dist/core/InventoryRebalancer.test.js.map +1 -0
- package/dist/core/Rebalancer.d.ts +11 -4
- package/dist/core/Rebalancer.d.ts.map +1 -1
- package/dist/core/Rebalancer.js +92 -9
- package/dist/core/Rebalancer.js.map +1 -1
- package/dist/core/Rebalancer.test.js +82 -49
- package/dist/core/Rebalancer.test.js.map +1 -1
- package/dist/core/RebalancerOrchestrator.d.ts +30 -9
- package/dist/core/RebalancerOrchestrator.d.ts.map +1 -1
- package/dist/core/RebalancerOrchestrator.js +79 -71
- package/dist/core/RebalancerOrchestrator.js.map +1 -1
- package/dist/core/RebalancerOrchestrator.test.d.ts +2 -0
- package/dist/core/RebalancerOrchestrator.test.d.ts.map +1 -0
- package/dist/core/RebalancerOrchestrator.test.js +719 -0
- package/dist/core/RebalancerOrchestrator.test.js.map +1 -0
- package/dist/core/RebalancerService.d.ts +7 -3
- package/dist/core/RebalancerService.d.ts.map +1 -1
- package/dist/core/RebalancerService.js +44 -24
- package/dist/core/RebalancerService.js.map +1 -1
- package/dist/core/RebalancerService.test.js +74 -110
- package/dist/core/RebalancerService.test.js.map +1 -1
- package/dist/e2e/collateral-deficit.e2e-test.js +1 -3
- package/dist/e2e/collateral-deficit.e2e-test.js.map +1 -1
- package/dist/e2e/composite.e2e-test.js.map +1 -1
- package/dist/e2e/harness/BridgeSetup.d.ts +6 -0
- package/dist/e2e/harness/BridgeSetup.d.ts.map +1 -1
- package/dist/e2e/harness/BridgeSetup.js +10 -1
- package/dist/e2e/harness/BridgeSetup.js.map +1 -1
- package/dist/e2e/harness/ForkIndexer.d.ts.map +1 -1
- package/dist/e2e/harness/ForkIndexer.js +1 -0
- package/dist/e2e/harness/ForkIndexer.js.map +1 -1
- package/dist/e2e/harness/TestHelpers.d.ts.map +1 -1
- package/dist/e2e/harness/TestHelpers.js +1 -4
- package/dist/e2e/harness/TestHelpers.js.map +1 -1
- package/dist/e2e/harness/TestRebalancer.d.ts +1 -1
- package/dist/e2e/harness/TestRebalancer.d.ts.map +1 -1
- package/dist/e2e/harness/TestRebalancer.js +9 -9
- package/dist/e2e/harness/TestRebalancer.js.map +1 -1
- package/dist/e2e/minAmount.e2e-test.js +0 -1
- package/dist/e2e/minAmount.e2e-test.js.map +1 -1
- package/dist/e2e/weighted.e2e-test.js +0 -1
- package/dist/e2e/weighted.e2e-test.js.map +1 -1
- package/dist/factories/RebalancerContextFactory.d.ts +48 -6
- package/dist/factories/RebalancerContextFactory.d.ts.map +1 -1
- package/dist/factories/RebalancerContextFactory.js +171 -17
- 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 +2 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces/IExternalBridge.d.ts +101 -0
- package/dist/interfaces/IExternalBridge.d.ts.map +1 -0
- package/dist/interfaces/IExternalBridge.js +2 -0
- package/dist/interfaces/IExternalBridge.js.map +1 -0
- package/dist/interfaces/IMonitor.d.ts +1 -0
- package/dist/interfaces/IMonitor.d.ts.map +1 -1
- package/dist/interfaces/IRebalancer.d.ts +25 -25
- package/dist/interfaces/IRebalancer.d.ts.map +1 -1
- package/dist/interfaces/IStrategy.d.ts +36 -3
- package/dist/interfaces/IStrategy.d.ts.map +1 -1
- package/dist/interfaces/IStrategy.js +12 -1
- package/dist/interfaces/IStrategy.js.map +1 -1
- package/dist/metrics/PriceGetter.js +1 -1
- package/dist/metrics/PriceGetter.js.map +1 -1
- package/dist/metrics/scripts/metrics.d.ts +3 -3
- package/dist/monitor/Monitor.d.ts +12 -2
- package/dist/monitor/Monitor.d.ts.map +1 -1
- package/dist/monitor/Monitor.js +46 -1
- package/dist/monitor/Monitor.js.map +1 -1
- package/dist/service.js +40 -17
- package/dist/service.js.map +1 -1
- package/dist/strategy/BaseStrategy.d.ts +12 -6
- package/dist/strategy/BaseStrategy.d.ts.map +1 -1
- package/dist/strategy/BaseStrategy.js +56 -21
- package/dist/strategy/BaseStrategy.js.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.d.ts +1 -1
- package/dist/strategy/CollateralDeficitStrategy.d.ts.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.js +19 -11
- package/dist/strategy/CollateralDeficitStrategy.js.map +1 -1
- package/dist/strategy/CollateralDeficitStrategy.test.js +135 -2
- package/dist/strategy/CollateralDeficitStrategy.test.js.map +1 -1
- package/dist/strategy/CompositeStrategy.test.js +13 -0
- package/dist/strategy/CompositeStrategy.test.js.map +1 -1
- package/dist/strategy/MinAmountStrategy.test.js +4 -0
- package/dist/strategy/MinAmountStrategy.test.js.map +1 -1
- package/dist/strategy/StrategyFactory.d.ts +2 -1
- package/dist/strategy/StrategyFactory.d.ts.map +1 -1
- package/dist/strategy/StrategyFactory.js +24 -8
- package/dist/strategy/StrategyFactory.js.map +1 -1
- package/dist/strategy/WeightedStrategy.test.js +6 -0
- package/dist/strategy/WeightedStrategy.test.js.map +1 -1
- package/dist/test/helpers.d.ts +8 -7
- package/dist/test/helpers.d.ts.map +1 -1
- package/dist/test/helpers.js +23 -5
- package/dist/test/helpers.js.map +1 -1
- package/dist/test/lifiMocks.d.ts +51 -0
- package/dist/test/lifiMocks.d.ts.map +1 -0
- package/dist/test/lifiMocks.js +130 -0
- package/dist/test/lifiMocks.js.map +1 -0
- package/dist/tracking/ActionTracker.d.ts +34 -1
- package/dist/tracking/ActionTracker.d.ts.map +1 -1
- package/dist/tracking/ActionTracker.js +233 -26
- package/dist/tracking/ActionTracker.js.map +1 -1
- package/dist/tracking/ActionTracker.test.js +380 -19
- package/dist/tracking/ActionTracker.test.js.map +1 -1
- package/dist/tracking/IActionTracker.d.ts +48 -3
- package/dist/tracking/IActionTracker.d.ts.map +1 -1
- package/dist/tracking/InflightContextAdapter.d.ts.map +1 -1
- package/dist/tracking/InflightContextAdapter.js +24 -7
- package/dist/tracking/InflightContextAdapter.js.map +1 -1
- package/dist/tracking/InflightContextAdapter.test.js +7 -4
- package/dist/tracking/InflightContextAdapter.test.js.map +1 -1
- package/dist/tracking/types.d.ts +33 -2
- package/dist/tracking/types.d.ts.map +1 -1
- package/dist/utils/ExplorerClient.d.ts +3 -1
- package/dist/utils/ExplorerClient.d.ts.map +1 -1
- package/dist/utils/ExplorerClient.js +16 -8
- package/dist/utils/ExplorerClient.js.map +1 -1
- package/dist/utils/bridgeUtils.d.ts +27 -4
- package/dist/utils/bridgeUtils.d.ts.map +1 -1
- package/dist/utils/bridgeUtils.js +38 -0
- package/dist/utils/bridgeUtils.js.map +1 -1
- package/dist/utils/bridgeUtils.test.js +9 -0
- package/dist/utils/bridgeUtils.test.js.map +1 -1
- package/dist/utils/gasEstimation.d.ts +65 -0
- package/dist/utils/gasEstimation.d.ts.map +1 -0
- package/dist/utils/gasEstimation.js +176 -0
- package/dist/utils/gasEstimation.js.map +1 -0
- package/dist/utils/tokenUtils.d.ts +9 -1
- package/dist/utils/tokenUtils.d.ts.map +1 -1
- package/dist/utils/tokenUtils.js +11 -0
- package/dist/utils/tokenUtils.js.map +1 -1
- package/package.json +9 -7
- package/src/bridges/LiFiBridge.ts +538 -0
- package/src/config/RebalancerConfig.test.ts +162 -0
- package/src/config/RebalancerConfig.ts +21 -3
- package/src/config/types.ts +147 -10
- package/src/core/InventoryRebalancer.test.ts +1721 -0
- package/src/core/InventoryRebalancer.ts +1265 -0
- package/src/core/Rebalancer.test.ts +84 -30
- package/src/core/Rebalancer.ts +144 -23
- package/src/core/RebalancerOrchestrator.test.ts +869 -0
- package/src/core/RebalancerOrchestrator.ts +146 -95
- package/src/core/RebalancerService.test.ts +86 -124
- package/src/core/RebalancerService.ts +67 -33
- package/src/e2e/collateral-deficit.e2e-test.ts +2 -4
- package/src/e2e/composite.e2e-test.ts +5 -5
- package/src/e2e/harness/BridgeSetup.ts +28 -1
- package/src/e2e/harness/ForkIndexer.ts +1 -0
- package/src/e2e/harness/TestHelpers.ts +1 -4
- package/src/e2e/harness/TestRebalancer.ts +10 -7
- package/src/e2e/minAmount.e2e-test.ts +1 -2
- package/src/e2e/weighted.e2e-test.ts +1 -2
- package/src/factories/RebalancerContextFactory.ts +294 -24
- package/src/index.ts +22 -5
- package/src/interfaces/IExternalBridge.ts +115 -0
- package/src/interfaces/IMonitor.ts +1 -0
- package/src/interfaces/IRebalancer.ts +45 -29
- package/src/interfaces/IStrategy.ts +50 -3
- package/src/metrics/PriceGetter.ts +1 -1
- package/src/monitor/Monitor.ts +81 -2
- package/src/service.ts +59 -18
- package/src/strategy/BaseStrategy.ts +77 -24
- package/src/strategy/CollateralDeficitStrategy.test.ts +181 -4
- package/src/strategy/CollateralDeficitStrategy.ts +42 -15
- package/src/strategy/CompositeStrategy.test.ts +13 -0
- package/src/strategy/MinAmountStrategy.test.ts +4 -0
- package/src/strategy/StrategyFactory.ts +33 -6
- package/src/strategy/WeightedStrategy.test.ts +6 -0
- package/src/test/helpers.ts +39 -14
- package/src/test/lifiMocks.ts +174 -0
- package/src/tracking/ActionTracker.test.ts +443 -19
- package/src/tracking/ActionTracker.ts +339 -28
- package/src/tracking/IActionTracker.ts +59 -3
- package/src/tracking/InflightContextAdapter.test.ts +7 -4
- package/src/tracking/InflightContextAdapter.ts +42 -9
- package/src/tracking/types.ts +45 -2
- package/src/utils/ExplorerClient.ts +27 -10
- package/src/utils/bridgeUtils.test.ts +9 -0
- package/src/utils/bridgeUtils.ts +75 -6
- package/src/utils/gasEstimation.ts +272 -0
- package/src/utils/tokenUtils.ts +12 -0
- package/dist/tracking/index.d.ts +0 -7
- package/dist/tracking/index.d.ts.map +0 -1
- package/dist/tracking/index.js +0 -6
- package/dist/tracking/index.js.map +0 -1
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -5
- package/dist/utils/index.js.map +0 -1
- package/src/tracking/index.ts +0 -36
- package/src/utils/index.ts +0 -4
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { BigNumber } from 'ethers';
|
|
2
|
+
import type { Logger } from 'pino';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
type AnnotatedEV5Transaction,
|
|
6
|
+
type ChainName,
|
|
7
|
+
type InterchainGasQuote,
|
|
8
|
+
type MultiProvider,
|
|
9
|
+
type Token,
|
|
10
|
+
TokenStandard,
|
|
11
|
+
} from '@hyperlane-xyz/sdk';
|
|
12
|
+
import { addBufferToGasLimit, isZeroishAddress } from '@hyperlane-xyz/utils';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Fallback gas limit for transferRemote when eth_estimateGas fails.
|
|
16
|
+
* Conservative estimate for cross-chain token transfers.
|
|
17
|
+
*/
|
|
18
|
+
export const FALLBACK_TRANSFER_REMOTE_GAS_LIMIT = 300_000n;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Cost multiplier for minimum viable transfer.
|
|
22
|
+
* A transfer must be worth at least this multiple of its cost to be worthwhile.
|
|
23
|
+
*/
|
|
24
|
+
export const MIN_VIABLE_COST_MULTIPLIER = 2n;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Transfer cost estimate for native token transfers.
|
|
28
|
+
* Contains all cost components needed for transfer decisions.
|
|
29
|
+
*/
|
|
30
|
+
export interface TransferCostEstimate {
|
|
31
|
+
/** IGP cost for the Hyperlane message */
|
|
32
|
+
igpCost: bigint;
|
|
33
|
+
/** Estimated gas cost for the transferRemote transaction (with buffer) */
|
|
34
|
+
gasCost: bigint;
|
|
35
|
+
/** Token fee cost (native denom only) */
|
|
36
|
+
tokenFeeCost: bigint;
|
|
37
|
+
/** Total cost = igpCost + gasCost + tokenFeeCost */
|
|
38
|
+
totalCost: bigint;
|
|
39
|
+
/** Maximum transferable amount after reserving costs (availableInventory - totalCost) */
|
|
40
|
+
maxTransferable: bigint;
|
|
41
|
+
/** Minimum viable transfer (totalCost * MIN_VIABLE_COST_MULTIPLIER) */
|
|
42
|
+
minViableTransfer: bigint;
|
|
43
|
+
/** Gas quote from adapter (for passing to executeTransferRemote) */
|
|
44
|
+
gasQuote?: InterchainGasQuote;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Estimate gas for a transferRemote transaction using eth_estimateGas.
|
|
49
|
+
* Falls back to conservative estimate if estimation fails.
|
|
50
|
+
*
|
|
51
|
+
* @param originChain - Chain where transferRemote will be called
|
|
52
|
+
* @param destinationChain - Chain where the Hyperlane message goes
|
|
53
|
+
* @param amount - Amount to transfer
|
|
54
|
+
* @param multiProvider - MultiProvider for chain access
|
|
55
|
+
* @param warpCoreMultiProvider - MultiProvider from WarpCore for adapter access
|
|
56
|
+
* @param getTokenForChain - Function to get token for a chain
|
|
57
|
+
* @param inventorySigner - Address of the inventory signer
|
|
58
|
+
* @param logger - Logger instance
|
|
59
|
+
* @returns Estimated gas limit for the transaction
|
|
60
|
+
*/
|
|
61
|
+
export async function estimateTransferRemoteGas(
|
|
62
|
+
originChain: ChainName,
|
|
63
|
+
destinationChain: ChainName,
|
|
64
|
+
amount: bigint,
|
|
65
|
+
multiProvider: MultiProvider,
|
|
66
|
+
warpCoreMultiProvider: any,
|
|
67
|
+
getTokenForChain: (chain: ChainName) => Token | undefined,
|
|
68
|
+
inventorySigner: string,
|
|
69
|
+
logger: Logger,
|
|
70
|
+
): Promise<bigint> {
|
|
71
|
+
const originToken = getTokenForChain(originChain);
|
|
72
|
+
if (!originToken) {
|
|
73
|
+
logger.warn(
|
|
74
|
+
{ originChain },
|
|
75
|
+
'No token found for origin chain, using fallback gas limit',
|
|
76
|
+
);
|
|
77
|
+
return FALLBACK_TRANSFER_REMOTE_GAS_LIMIT;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const destinationDomain = multiProvider.getDomainId(destinationChain);
|
|
82
|
+
const adapter = originToken.getHypAdapter(warpCoreMultiProvider);
|
|
83
|
+
|
|
84
|
+
// Quote the IGP gas first (needed for the full transaction)
|
|
85
|
+
const gasQuote = await adapter.quoteTransferRemoteGas({
|
|
86
|
+
destination: destinationDomain,
|
|
87
|
+
sender: inventorySigner,
|
|
88
|
+
recipient: inventorySigner,
|
|
89
|
+
amount,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Populate with minimal amount for gas estimation
|
|
93
|
+
// Gas cost is independent of transfer size (just a require check in _transferFromSender),
|
|
94
|
+
// and using minimal amount prevents eth_estimateGas from failing when account balance < requested amount
|
|
95
|
+
// Note: getHypAdapter returns IHypTokenAdapter<unknown> for protocol-agnostic support.
|
|
96
|
+
// For EVM chains (which inventory rebalancing uses), the actual type is AnnotatedEV5Transaction.
|
|
97
|
+
const populatedTx = (await adapter.populateTransferRemoteTx({
|
|
98
|
+
destination: destinationDomain,
|
|
99
|
+
recipient: inventorySigner,
|
|
100
|
+
weiAmountOrId: 1n,
|
|
101
|
+
interchainGas: gasQuote,
|
|
102
|
+
})) as AnnotatedEV5Transaction;
|
|
103
|
+
|
|
104
|
+
// Estimate gas using the provider
|
|
105
|
+
const provider = multiProvider.getProvider(originChain);
|
|
106
|
+
const gasEstimate = await provider.estimateGas({
|
|
107
|
+
to: populatedTx.to,
|
|
108
|
+
data: populatedTx.data,
|
|
109
|
+
value: populatedTx.value,
|
|
110
|
+
from: inventorySigner,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const estimatedGas = BigInt(gasEstimate.toString());
|
|
114
|
+
|
|
115
|
+
logger.debug(
|
|
116
|
+
{
|
|
117
|
+
originChain,
|
|
118
|
+
destinationChain,
|
|
119
|
+
amount: amount.toString(),
|
|
120
|
+
estimatedGas: estimatedGas.toString(),
|
|
121
|
+
},
|
|
122
|
+
'Estimated transferRemote gas via eth_estimateGas',
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return estimatedGas;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
logger.warn(
|
|
128
|
+
{
|
|
129
|
+
originChain,
|
|
130
|
+
destinationChain,
|
|
131
|
+
error: (error as Error).message,
|
|
132
|
+
fallbackGas: FALLBACK_TRANSFER_REMOTE_GAS_LIMIT.toString(),
|
|
133
|
+
},
|
|
134
|
+
'Gas estimation failed, using fallback gas limit',
|
|
135
|
+
);
|
|
136
|
+
return FALLBACK_TRANSFER_REMOTE_GAS_LIMIT;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Calculate all transfer costs for a transferRemote operation.
|
|
142
|
+
* Consolidates IGP costs, gas costs, and derived values (max transferable, min viable).
|
|
143
|
+
*
|
|
144
|
+
* @param originChain - Chain to transfer from (where transferRemote is called)
|
|
145
|
+
* @param destinationChain - Chain to transfer to (Hyperlane message destination)
|
|
146
|
+
* @param availableInventory - Available token balance on origin chain
|
|
147
|
+
* @param requestedAmount - Requested transfer amount
|
|
148
|
+
* @param multiProvider - MultiProvider for chain access
|
|
149
|
+
* @param warpCoreMultiProvider - MultiProvider from WarpCore for adapter access
|
|
150
|
+
* @param getTokenForChain - Function to get token for a chain
|
|
151
|
+
* @param inventorySigner - Address of the inventory signer
|
|
152
|
+
* @param isNativeTokenStandard - Function to check if token standard is native
|
|
153
|
+
* @param logger - Logger instance
|
|
154
|
+
* @returns Cost estimate with all components and derived values
|
|
155
|
+
*/
|
|
156
|
+
export async function calculateTransferCosts(
|
|
157
|
+
originChain: ChainName,
|
|
158
|
+
destinationChain: ChainName,
|
|
159
|
+
availableInventory: bigint,
|
|
160
|
+
requestedAmount: bigint,
|
|
161
|
+
multiProvider: MultiProvider,
|
|
162
|
+
warpCoreMultiProvider: any,
|
|
163
|
+
getTokenForChain: (chain: ChainName) => Token | undefined,
|
|
164
|
+
inventorySigner: string,
|
|
165
|
+
isNativeTokenStandard: (standard: TokenStandard) => boolean,
|
|
166
|
+
logger: Logger,
|
|
167
|
+
): Promise<TransferCostEstimate> {
|
|
168
|
+
const originToken = getTokenForChain(originChain);
|
|
169
|
+
if (!originToken) {
|
|
170
|
+
throw new Error(`No token found for origin chain: ${originChain}`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const destinationDomain = multiProvider.getDomainId(destinationChain);
|
|
174
|
+
const adapter = originToken.getHypAdapter(warpCoreMultiProvider);
|
|
175
|
+
|
|
176
|
+
// Always quote IGP for the gas quote (needed for populateTransferRemoteTx)
|
|
177
|
+
const gasQuote = await adapter.quoteTransferRemoteGas({
|
|
178
|
+
destination: destinationDomain,
|
|
179
|
+
sender: inventorySigner,
|
|
180
|
+
recipient: inventorySigner,
|
|
181
|
+
amount: requestedAmount,
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// For non-native tokens, no cost reservation needed from token balance
|
|
185
|
+
if (!isNativeTokenStandard(originToken.standard)) {
|
|
186
|
+
return {
|
|
187
|
+
igpCost: 0n,
|
|
188
|
+
gasCost: 0n,
|
|
189
|
+
tokenFeeCost: 0n,
|
|
190
|
+
totalCost: 0n,
|
|
191
|
+
maxTransferable:
|
|
192
|
+
availableInventory < requestedAmount
|
|
193
|
+
? availableInventory
|
|
194
|
+
: requestedAmount,
|
|
195
|
+
minViableTransfer: 0n,
|
|
196
|
+
gasQuote,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// For native tokens, calculate costs
|
|
201
|
+
const igpCost = gasQuote.igpQuote.amount;
|
|
202
|
+
|
|
203
|
+
// Extract token fee cost (native denom only)
|
|
204
|
+
const tokenFeeCost =
|
|
205
|
+
!gasQuote.tokenFeeQuote?.addressOrDenom ||
|
|
206
|
+
isZeroishAddress(gasQuote.tokenFeeQuote.addressOrDenom)
|
|
207
|
+
? (gasQuote.tokenFeeQuote?.amount ?? 0n)
|
|
208
|
+
: 0n;
|
|
209
|
+
|
|
210
|
+
// Estimate gas with buffer
|
|
211
|
+
const estimatedGasLimit = await estimateTransferRemoteGas(
|
|
212
|
+
originChain,
|
|
213
|
+
destinationChain,
|
|
214
|
+
requestedAmount,
|
|
215
|
+
multiProvider,
|
|
216
|
+
warpCoreMultiProvider,
|
|
217
|
+
getTokenForChain,
|
|
218
|
+
inventorySigner,
|
|
219
|
+
logger,
|
|
220
|
+
);
|
|
221
|
+
const bufferedGasLimit = addBufferToGasLimit(
|
|
222
|
+
BigNumber.from(estimatedGasLimit.toString()),
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Get gas price and calculate cost
|
|
226
|
+
const provider = multiProvider.getProvider(originChain);
|
|
227
|
+
const feeData = await provider.getFeeData();
|
|
228
|
+
const gasPrice = feeData.maxFeePerGas ?? feeData.gasPrice ?? 0n;
|
|
229
|
+
const gasCost = bufferedGasLimit.toBigInt() * BigInt(gasPrice.toString());
|
|
230
|
+
|
|
231
|
+
const totalCost = igpCost + gasCost + tokenFeeCost;
|
|
232
|
+
|
|
233
|
+
// Calculate derived values
|
|
234
|
+
let maxTransferable: bigint;
|
|
235
|
+
if (availableInventory <= totalCost) {
|
|
236
|
+
maxTransferable = 0n;
|
|
237
|
+
} else {
|
|
238
|
+
const maxAfterReservation = availableInventory - totalCost;
|
|
239
|
+
maxTransferable =
|
|
240
|
+
maxAfterReservation < requestedAmount
|
|
241
|
+
? maxAfterReservation
|
|
242
|
+
: requestedAmount;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const minViableTransfer = totalCost * MIN_VIABLE_COST_MULTIPLIER;
|
|
246
|
+
|
|
247
|
+
logger.debug(
|
|
248
|
+
{
|
|
249
|
+
originChain,
|
|
250
|
+
destinationChain,
|
|
251
|
+
availableInventory: availableInventory.toString(),
|
|
252
|
+
requestedAmount: requestedAmount.toString(),
|
|
253
|
+
igpCost: igpCost.toString(),
|
|
254
|
+
gasCost: gasCost.toString(),
|
|
255
|
+
tokenFeeCost: tokenFeeCost.toString(),
|
|
256
|
+
totalCost: totalCost.toString(),
|
|
257
|
+
maxTransferable: maxTransferable.toString(),
|
|
258
|
+
minViableTransfer: minViableTransfer.toString(),
|
|
259
|
+
},
|
|
260
|
+
'Calculated transfer costs for native token',
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
igpCost,
|
|
265
|
+
gasCost,
|
|
266
|
+
tokenFeeCost,
|
|
267
|
+
totalCost,
|
|
268
|
+
maxTransferable,
|
|
269
|
+
minViableTransfer,
|
|
270
|
+
gasQuote,
|
|
271
|
+
};
|
|
272
|
+
}
|
package/src/utils/tokenUtils.ts
CHANGED
|
@@ -5,6 +5,18 @@ const REBALANCEABLE_TOKEN_COLLATERALIZED_STANDARDS = new Set<TokenStandard>([
|
|
|
5
5
|
TokenStandard.EvmHypNative,
|
|
6
6
|
]);
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Check if a token's balance is the same as native gas balance.
|
|
10
|
+
* For these tokens, we must reserve funds for IGP when calculating max transferable.
|
|
11
|
+
*
|
|
12
|
+
* @param standard - The token standard to check.
|
|
13
|
+
* @returns `true` if the token is a native token standard, `false` otherwise.
|
|
14
|
+
*/
|
|
15
|
+
export function isNativeTokenStandard(standard: TokenStandard): boolean {
|
|
16
|
+
// EvmHypNative covers all native token types including scaled variants
|
|
17
|
+
return standard === TokenStandard.EvmHypNative;
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
/**
|
|
9
21
|
* @dev This function exists because the rebalancer currently only supports a subset of collateralized token standards
|
|
10
22
|
* (see `REBALANCEABLE_TOKEN_COLLATERALIZED_STANDARDS` vs. all possible `TOKEN_COLLATERALIZED_STANDARDS`).
|
package/dist/tracking/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export type { IStore } from './store/index.js';
|
|
2
|
-
export { InMemoryStore } from './store/index.js';
|
|
3
|
-
export type { Identifiable, CrossChainAction, Timestamped, TrackedActionBase, TransferStatus, RebalanceIntentStatus, RebalanceActionStatus, Transfer, RebalanceIntent, RebalanceAction, ITransferStore, IRebalanceIntentStore, IRebalanceActionStore, } from './types.js';
|
|
4
|
-
export { ActionTracker, type ActionTrackerConfig } from './ActionTracker.js';
|
|
5
|
-
export type { IActionTracker, CreateRebalanceIntentParams, CreateRebalanceActionParams, } from './IActionTracker.js';
|
|
6
|
-
export { InflightContextAdapter } from './InflightContextAdapter.js';
|
|
7
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tracking/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,YAAY,EAEV,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EAEjB,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EAErB,QAAQ,EACR,eAAe,EACf,eAAe,EAEf,cAAc,EACd,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,YAAY,EACV,cAAc,EACd,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/tracking/index.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { InMemoryStore } from './store/index.js';
|
|
2
|
-
// Export ActionTracker components
|
|
3
|
-
export { ActionTracker } from './ActionTracker.js';
|
|
4
|
-
// Export InflightContextAdapter
|
|
5
|
-
export { InflightContextAdapter } from './InflightContextAdapter.js';
|
|
6
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tracking/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAuBjD,kCAAkC;AAClC,OAAO,EAAE,aAAa,EAA4B,MAAM,oBAAoB,CAAC;AAQ7E,gCAAgC;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/utils/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC"}
|
package/dist/utils/index.js
DELETED
package/dist/utils/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC"}
|
package/src/tracking/index.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// Export all store components
|
|
2
|
-
export type { IStore } from './store/index.js';
|
|
3
|
-
export { InMemoryStore } from './store/index.js';
|
|
4
|
-
|
|
5
|
-
// Export types
|
|
6
|
-
export type {
|
|
7
|
-
// Base interfaces
|
|
8
|
-
Identifiable,
|
|
9
|
-
CrossChainAction,
|
|
10
|
-
Timestamped,
|
|
11
|
-
TrackedActionBase,
|
|
12
|
-
// Status types
|
|
13
|
-
TransferStatus,
|
|
14
|
-
RebalanceIntentStatus,
|
|
15
|
-
RebalanceActionStatus,
|
|
16
|
-
// Entity types
|
|
17
|
-
Transfer,
|
|
18
|
-
RebalanceIntent,
|
|
19
|
-
RebalanceAction,
|
|
20
|
-
// Store type aliases
|
|
21
|
-
ITransferStore,
|
|
22
|
-
IRebalanceIntentStore,
|
|
23
|
-
IRebalanceActionStore,
|
|
24
|
-
} from './types.js';
|
|
25
|
-
|
|
26
|
-
// Export ActionTracker components
|
|
27
|
-
export { ActionTracker, type ActionTrackerConfig } from './ActionTracker.js';
|
|
28
|
-
|
|
29
|
-
export type {
|
|
30
|
-
IActionTracker,
|
|
31
|
-
CreateRebalanceIntentParams,
|
|
32
|
-
CreateRebalanceActionParams,
|
|
33
|
-
} from './IActionTracker.js';
|
|
34
|
-
|
|
35
|
-
// Export InflightContextAdapter
|
|
36
|
-
export { InflightContextAdapter } from './InflightContextAdapter.js';
|
package/src/utils/index.ts
DELETED