@across-protocol/sdk 4.3.111-alpha.4 → 4.3.111
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/cjs/addressAggregator/adapters/abstract.js +64 -50
- package/dist/cjs/addressAggregator/adapters/abstract.js.map +1 -1
- package/dist/cjs/addressAggregator/adapters/bybit.js +29 -16
- package/dist/cjs/addressAggregator/adapters/bybit.js.map +1 -1
- package/dist/cjs/addressAggregator/adapters/env.js +15 -11
- package/dist/cjs/addressAggregator/adapters/env.js.map +1 -1
- package/dist/cjs/addressAggregator/adapters/file.js +45 -32
- package/dist/cjs/addressAggregator/adapters/file.js.map +1 -1
- package/dist/cjs/addressAggregator/adapters/index.js +1 -1
- package/dist/cjs/addressAggregator/adapters/risklabs.js +36 -22
- package/dist/cjs/addressAggregator/adapters/risklabs.js.map +1 -1
- package/dist/cjs/addressAggregator/index.js +87 -57
- package/dist/cjs/addressAggregator/index.js.map +1 -1
- package/dist/cjs/apiClient/abstractClient.js +8 -9
- package/dist/cjs/apiClient/abstractClient.js.map +1 -1
- package/dist/cjs/apiClient/index.js +1 -1
- package/dist/cjs/apiClient/mockedClient.js +29 -23
- package/dist/cjs/apiClient/mockedClient.js.map +1 -1
- package/dist/cjs/apiClient/productionClient.js +103 -65
- package/dist/cjs/apiClient/productionClient.js.map +1 -1
- package/dist/cjs/arch/evm/BlockUtils.js +208 -122
- package/dist/cjs/arch/evm/BlockUtils.js.map +1 -1
- package/dist/cjs/arch/evm/MessageUtils.js +1 -1
- package/dist/cjs/arch/evm/MessageUtils.js.map +1 -1
- package/dist/cjs/arch/evm/SpokeUtils.js +288 -134
- package/dist/cjs/arch/evm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/evm/index.js +1 -1
- package/dist/cjs/arch/evm/utils/index.js +1 -1
- package/dist/cjs/arch/evm/utils/wait.js +49 -38
- package/dist/cjs/arch/evm/utils/wait.js.map +1 -1
- package/dist/cjs/arch/index.js +1 -1
- package/dist/cjs/arch/svm/BlockUtils.js +158 -102
- package/dist/cjs/arch/svm/BlockUtils.js.map +1 -1
- package/dist/cjs/arch/svm/MessageUtils.js +2 -2
- package/dist/cjs/arch/svm/MessageUtils.js.map +1 -1
- package/dist/cjs/arch/svm/SpokeUtils.js +1147 -708
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/svm/encoders.js +1 -1
- package/dist/cjs/arch/svm/encoders.js.map +1 -1
- package/dist/cjs/arch/svm/eventsClient.js +236 -174
- package/dist/cjs/arch/svm/eventsClient.js.map +1 -1
- package/dist/cjs/arch/svm/index.js +1 -1
- package/dist/cjs/arch/svm/provider.js +3 -3
- package/dist/cjs/arch/svm/provider.js.map +1 -1
- package/dist/cjs/arch/svm/utils.js +355 -166
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/cjs/caching/Arweave/ArweaveClient.js +246 -168
- package/dist/cjs/caching/Arweave/ArweaveClient.js.map +1 -1
- package/dist/cjs/caching/Arweave/index.js +1 -1
- package/dist/cjs/caching/IPFS/PinataIPFSClient.js +49 -40
- package/dist/cjs/caching/IPFS/PinataIPFSClient.js.map +1 -1
- package/dist/cjs/caching/IPFS/index.js +1 -1
- package/dist/cjs/caching/Memory/MemoryCacheClient.js +18 -13
- package/dist/cjs/caching/Memory/MemoryCacheClient.js.map +1 -1
- package/dist/cjs/caching/Memory/index.js +1 -1
- package/dist/cjs/caching/index.js +1 -1
- package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +381 -302
- package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
- package/dist/cjs/clients/AcrossConfigStoreClient/index.js +1 -1
- package/dist/cjs/clients/BaseAbstractClient.js +83 -58
- package/dist/cjs/clients/BaseAbstractClient.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +900 -709
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/index.js +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +128 -95
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +53 -48
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/MerkleTreeUtils.js +8 -10
- package/dist/cjs/clients/BundleDataClient/utils/MerkleTreeUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js +90 -67
- package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +24 -46
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/index.js +1 -1
- package/dist/cjs/clients/HubPoolClient.js +708 -526
- package/dist/cjs/clients/HubPoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js +179 -133
- package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js +183 -124
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +389 -357
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClientManager.js +8 -9
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClientManager.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/index.js +3 -3
- package/dist/cjs/clients/SpokePoolClient/index.js.map +1 -1
- package/dist/cjs/clients/index.js +1 -1
- package/dist/cjs/clients/mocks/MockConfigStoreClient.js +67 -58
- package/dist/cjs/clients/mocks/MockConfigStoreClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockEvents.js +52 -47
- package/dist/cjs/clients/mocks/MockEvents.js.map +1 -1
- package/dist/cjs/clients/mocks/MockHubPoolClient.js +185 -142
- package/dist/cjs/clients/mocks/MockHubPoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSpokePoolClient.js +192 -208
- package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.js +143 -140
- package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.js +73 -57
- package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/index.js +1 -1
- package/dist/cjs/coingecko/Coingecko.js +437 -285
- package/dist/cjs/coingecko/Coingecko.js.map +1 -1
- package/dist/cjs/coingecko/index.js +1 -1
- package/dist/cjs/constants.js +30 -23
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/contracts/acrossConfigStore.js +48 -27
- package/dist/cjs/contracts/acrossConfigStore.js.map +1 -1
- package/dist/cjs/contracts/hubPool.js +20 -36
- package/dist/cjs/contracts/hubPool.js.map +1 -1
- package/dist/cjs/contracts/index.js +1 -1
- package/dist/cjs/contracts/utils.js +8 -6
- package/dist/cjs/contracts/utils.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/arbitrum.js +16 -7
- package/dist/cjs/gasPriceOracle/adapters/arbitrum.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/ethereum.js +45 -26
- package/dist/cjs/gasPriceOracle/adapters/ethereum.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/linea-viem.js +28 -16
- package/dist/cjs/gasPriceOracle/adapters/linea-viem.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/polygon.js +112 -73
- package/dist/cjs/gasPriceOracle/adapters/polygon.js.map +1 -1
- package/dist/cjs/gasPriceOracle/adapters/solana.js +33 -20
- package/dist/cjs/gasPriceOracle/adapters/solana.js.map +1 -1
- package/dist/cjs/gasPriceOracle/oracle.js +104 -77
- package/dist/cjs/gasPriceOracle/oracle.js.map +1 -1
- package/dist/cjs/gasPriceOracle/types.js +3 -3
- package/dist/cjs/gasPriceOracle/types.js.map +1 -1
- package/dist/cjs/gasPriceOracle/util.js +8 -8
- package/dist/cjs/gasPriceOracle/util.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/interfaces/index.js +1 -1
- package/dist/cjs/lpFeeCalculator/index.js +1 -1
- package/dist/cjs/lpFeeCalculator/lpFeeCalculator.js +35 -33
- package/dist/cjs/lpFeeCalculator/lpFeeCalculator.js.map +1 -1
- package/dist/cjs/lpFeeCalculator/rateModel.js +9 -7
- package/dist/cjs/lpFeeCalculator/rateModel.js.map +1 -1
- package/dist/cjs/merkleDistributor/MerkleDistributor.js +18 -20
- package/dist/cjs/merkleDistributor/MerkleDistributor.js.map +1 -1
- package/dist/cjs/merkleDistributor/index.js +1 -1
- package/dist/cjs/merkleDistributor/model/index.js +1 -1
- package/dist/cjs/pool/TransactionManager.js +100 -45
- package/dist/cjs/pool/TransactionManager.js.map +1 -1
- package/dist/cjs/pool/index.js +1 -1
- package/dist/cjs/pool/poolClient.js +731 -464
- package/dist/cjs/pool/poolClient.js.map +1 -1
- package/dist/cjs/pool/uma/across/index.js +1 -1
- package/dist/cjs/pool/uma/across/transactionManager.js +100 -45
- package/dist/cjs/pool/uma/across/transactionManager.js.map +1 -1
- package/dist/cjs/pool/uma/clients/erc20/client.js +16 -18
- package/dist/cjs/pool/uma/clients/erc20/client.js.map +1 -1
- package/dist/cjs/pool/uma/clients/erc20/index.js +1 -1
- package/dist/cjs/pool/uma/clients/index.js +1 -1
- package/dist/cjs/pool/uma/index.js +1 -1
- package/dist/cjs/pool/uma/oracle/index.js +1 -1
- package/dist/cjs/pool/uma/oracle/utils.js +5 -4
- package/dist/cjs/pool/uma/oracle/utils.js.map +1 -1
- package/dist/cjs/pool/uma/utils.js +30 -11
- package/dist/cjs/pool/uma/utils.js.map +1 -1
- package/dist/cjs/priceClient/adapters/acrossApi.js +39 -22
- package/dist/cjs/priceClient/adapters/acrossApi.js.map +1 -1
- package/dist/cjs/priceClient/adapters/baseAdapter.js +73 -49
- package/dist/cjs/priceClient/adapters/baseAdapter.js.map +1 -1
- package/dist/cjs/priceClient/adapters/coingecko.js +61 -34
- package/dist/cjs/priceClient/adapters/coingecko.js.map +1 -1
- package/dist/cjs/priceClient/adapters/default.js +31 -16
- package/dist/cjs/priceClient/adapters/default.js.map +1 -1
- package/dist/cjs/priceClient/adapters/defiLlama.js +74 -40
- package/dist/cjs/priceClient/adapters/defiLlama.js.map +1 -1
- package/dist/cjs/priceClient/adapters/index.js +1 -1
- package/dist/cjs/priceClient/index.js +1 -1
- package/dist/cjs/priceClient/priceClient.js +159 -110
- package/dist/cjs/priceClient/priceClient.js.map +1 -1
- package/dist/cjs/providers/alchemy.js +19 -17
- package/dist/cjs/providers/alchemy.js.map +1 -1
- package/dist/cjs/providers/cachedProvider.js +129 -88
- package/dist/cjs/providers/cachedProvider.js.map +1 -1
- package/dist/cjs/providers/drpc.js +11 -9
- package/dist/cjs/providers/drpc.js.map +1 -1
- package/dist/cjs/providers/index.js +1 -1
- package/dist/cjs/providers/infura.js +12 -10
- package/dist/cjs/providers/infura.js.map +1 -1
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.js +15 -7
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/MockRateLimitedSolanaRpcFactory.js +14 -6
- package/dist/cjs/providers/mocks/MockRateLimitedSolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/MockRetrySolanaRpcFactory.js +15 -7
- package/dist/cjs/providers/mocks/MockRetrySolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/MockSolanaRpcFactory.js +66 -42
- package/dist/cjs/providers/mocks/MockSolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/index.js +1 -1
- package/dist/cjs/providers/mocks/mockEthersProvider.js +31 -29
- package/dist/cjs/providers/mocks/mockEthersProvider.js.map +1 -1
- package/dist/cjs/providers/quicknode.js +21 -19
- package/dist/cjs/providers/quicknode.js.map +1 -1
- package/dist/cjs/providers/rateLimitedProvider.js +79 -64
- package/dist/cjs/providers/rateLimitedProvider.js.map +1 -1
- package/dist/cjs/providers/retryProvider.js +246 -163
- package/dist/cjs/providers/retryProvider.js.map +1 -1
- package/dist/cjs/providers/solana/baseRpcFactories.js +18 -14
- package/dist/cjs/providers/solana/baseRpcFactories.js.map +1 -1
- package/dist/cjs/providers/solana/cachedRpcFactory.js +112 -70
- package/dist/cjs/providers/solana/cachedRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/defaultRpcFactory.js +15 -8
- package/dist/cjs/providers/solana/defaultRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/index.js +1 -1
- package/dist/cjs/providers/solana/quorumFallbackRpcFactory.js +191 -135
- package/dist/cjs/providers/solana/quorumFallbackRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/rateLimitedRpcFactory.js +90 -67
- package/dist/cjs/providers/solana/rateLimitedRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/retryRpcFactory.js +79 -52
- package/dist/cjs/providers/solana/retryRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/utils.js +2 -2
- package/dist/cjs/providers/solana/utils.js.map +1 -1
- package/dist/cjs/providers/speedProvider.js +53 -31
- package/dist/cjs/providers/speedProvider.js.map +1 -1
- package/dist/cjs/providers/types.js +1 -1
- package/dist/cjs/providers/types.js.map +1 -1
- package/dist/cjs/providers/utils.js +28 -26
- package/dist/cjs/providers/utils.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js +162 -108
- package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/customGasToken.js +26 -14
- package/dist/cjs/relayFeeCalculator/chain-queries/customGasToken.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.js +29 -20
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/index.js +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js +137 -88
- package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/index.js +1 -1
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js +297 -199
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
- package/dist/cjs/typeguards/error.js +7 -5
- package/dist/cjs/typeguards/error.js.map +1 -1
- package/dist/cjs/typeguards/index.js +1 -1
- package/dist/cjs/utils/AddressUtils.js +144 -117
- package/dist/cjs/utils/AddressUtils.js.map +1 -1
- package/dist/cjs/utils/ArrayUtils.js +78 -21
- package/dist/cjs/utils/ArrayUtils.js.map +1 -1
- package/dist/cjs/utils/BigNumberUtils.js +10 -9
- package/dist/cjs/utils/BigNumberUtils.js.map +1 -1
- package/dist/cjs/utils/BlockExplorerUtils.js +30 -26
- package/dist/cjs/utils/BlockExplorerUtils.js.map +1 -1
- package/dist/cjs/utils/BlockFinder.js +5 -2
- package/dist/cjs/utils/BlockFinder.js.map +1 -1
- package/dist/cjs/utils/BlockUtils.js +41 -24
- package/dist/cjs/utils/BlockUtils.js.map +1 -1
- package/dist/cjs/utils/BundleUtils.js +24 -21
- package/dist/cjs/utils/BundleUtils.js.map +1 -1
- package/dist/cjs/utils/CCTPUtils.js +126 -62
- package/dist/cjs/utils/CCTPUtils.js.map +1 -1
- package/dist/cjs/utils/CachingUtils.js +42 -20
- package/dist/cjs/utils/CachingUtils.js.map +1 -1
- package/dist/cjs/utils/ContractUtils.js +5 -5
- package/dist/cjs/utils/ContractUtils.js.map +1 -1
- package/dist/cjs/utils/DepositUtils.js +99 -122
- package/dist/cjs/utils/DepositUtils.js.map +1 -1
- package/dist/cjs/utils/EventUtils.js +70 -49
- package/dist/cjs/utils/EventUtils.js.map +1 -1
- package/dist/cjs/utils/FormattingUtils.js +32 -26
- package/dist/cjs/utils/FormattingUtils.js.map +1 -1
- package/dist/cjs/utils/HyperLiquidUtils.js +23 -10
- package/dist/cjs/utils/HyperLiquidUtils.js.map +1 -1
- package/dist/cjs/utils/IPFSUtils.js +34 -16
- package/dist/cjs/utils/IPFSUtils.js.map +1 -1
- package/dist/cjs/utils/JSONUtils.js +6 -6
- package/dist/cjs/utils/JSONUtils.js.map +1 -1
- package/dist/cjs/utils/LogUtils.js +12 -10
- package/dist/cjs/utils/LogUtils.js.map +1 -1
- package/dist/cjs/utils/Multicall.js +115 -56
- package/dist/cjs/utils/Multicall.js.map +1 -1
- package/dist/cjs/utils/NetworkUtils.js +28 -12
- package/dist/cjs/utils/NetworkUtils.js.map +1 -1
- package/dist/cjs/utils/NumberUtils.js +3 -1
- package/dist/cjs/utils/NumberUtils.js.map +1 -1
- package/dist/cjs/utils/ObjectUtils.js +41 -27
- package/dist/cjs/utils/ObjectUtils.js.map +1 -1
- package/dist/cjs/utils/Profiler.js +83 -80
- package/dist/cjs/utils/Profiler.js.map +1 -1
- package/dist/cjs/utils/ReviverUtils.js +9 -5
- package/dist/cjs/utils/ReviverUtils.js.map +1 -1
- package/dist/cjs/utils/SpokeUtils.js +84 -84
- package/dist/cjs/utils/SpokeUtils.js.map +1 -1
- package/dist/cjs/utils/TokenUtils.js +64 -41
- package/dist/cjs/utils/TokenUtils.js.map +1 -1
- package/dist/cjs/utils/TypeGuards.js +1 -1
- package/dist/cjs/utils/TypeGuards.js.map +1 -1
- package/dist/cjs/utils/ValidatorUtils.js +7 -7
- package/dist/cjs/utils/ValidatorUtils.js.map +1 -1
- package/dist/cjs/utils/abi/contracts/index.js +1 -1
- package/dist/cjs/utils/abi/index.js +22 -12
- package/dist/cjs/utils/abi/index.js.map +1 -1
- package/dist/cjs/utils/abi/typechain/factories/Multicall3__factory.js +12 -9
- package/dist/cjs/utils/abi/typechain/factories/Multicall3__factory.js.map +1 -1
- package/dist/cjs/utils/abi/typechain/index.js +1 -1
- package/dist/cjs/utils/common.js +53 -40
- package/dist/cjs/utils/common.js.map +1 -1
- package/dist/cjs/utils/index.js +1 -1
- package/dist/esm/addressAggregator/adapters/abstract.js +64 -48
- package/dist/esm/addressAggregator/adapters/abstract.js.map +1 -1
- package/dist/esm/addressAggregator/adapters/bybit.js +29 -15
- package/dist/esm/addressAggregator/adapters/bybit.js.map +1 -1
- package/dist/esm/addressAggregator/adapters/env.js +14 -9
- package/dist/esm/addressAggregator/adapters/env.js.map +1 -1
- package/dist/esm/addressAggregator/adapters/file.js +43 -29
- package/dist/esm/addressAggregator/adapters/file.js.map +1 -1
- package/dist/esm/addressAggregator/adapters/risklabs.js +35 -20
- package/dist/esm/addressAggregator/adapters/risklabs.js.map +1 -1
- package/dist/esm/addressAggregator/index.js +83 -52
- package/dist/esm/addressAggregator/index.js.map +1 -1
- package/dist/esm/addressAggregator/types.js +1 -1
- package/dist/esm/addressAggregator/types.js.map +1 -1
- package/dist/esm/apiClient/abstractClient.js +9 -15
- package/dist/esm/apiClient/abstractClient.js.map +1 -1
- package/dist/esm/apiClient/mockedClient.js +26 -21
- package/dist/esm/apiClient/mockedClient.js.map +1 -1
- package/dist/esm/apiClient/productionClient.js +101 -61
- package/dist/esm/apiClient/productionClient.js.map +1 -1
- package/dist/esm/arch/evm/BlockUtils.js +217 -139
- package/dist/esm/arch/evm/BlockUtils.js.map +1 -1
- package/dist/esm/arch/evm/SpokeUtils.js +289 -146
- package/dist/esm/arch/evm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/evm/utils/wait.js +46 -34
- package/dist/esm/arch/evm/utils/wait.js.map +1 -1
- package/dist/esm/arch/svm/BlockUtils.js +166 -118
- package/dist/esm/arch/svm/BlockUtils.js.map +1 -1
- package/dist/esm/arch/svm/SpokeUtils.js +1150 -738
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/constants.js +1 -1
- package/dist/esm/arch/svm/constants.js.map +1 -1
- package/dist/esm/arch/svm/eventsClient.js +232 -172
- package/dist/esm/arch/svm/eventsClient.js.map +1 -1
- package/dist/esm/arch/svm/provider.js +1 -1
- package/dist/esm/arch/svm/provider.js.map +1 -1
- package/dist/esm/arch/svm/utils.js +345 -155
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/esm/caching/Arweave/ArweaveClient.js +256 -182
- package/dist/esm/caching/Arweave/ArweaveClient.js.map +1 -1
- package/dist/esm/caching/IPFS/PinataIPFSClient.js +48 -47
- package/dist/esm/caching/IPFS/PinataIPFSClient.js.map +1 -1
- package/dist/esm/caching/Memory/MemoryCacheClient.js +19 -13
- package/dist/esm/caching/Memory/MemoryCacheClient.js.map +1 -1
- package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +408 -333
- package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
- package/dist/esm/clients/BaseAbstractClient.js +92 -66
- package/dist/esm/clients/BaseAbstractClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js +1054 -927
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +131 -102
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +59 -57
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/MerkleTreeUtils.js +5 -7
- package/dist/esm/clients/BundleDataClient/utils/MerkleTreeUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js +94 -75
- package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +23 -45
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
- package/dist/esm/clients/HubPoolClient.js +740 -581
- package/dist/esm/clients/HubPoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js +178 -133
- package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js +183 -126
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +399 -372
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SpokePoolClientManager.js +9 -9
- package/dist/esm/clients/SpokePoolClient/SpokePoolClientManager.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/index.js +2 -2
- package/dist/esm/clients/SpokePoolClient/index.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/types.js +2 -2
- package/dist/esm/clients/SpokePoolClient/types.js.map +1 -1
- package/dist/esm/clients/mocks/MockConfigStoreClient.js +64 -53
- package/dist/esm/clients/mocks/MockConfigStoreClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockEvents.js +49 -42
- package/dist/esm/clients/mocks/MockEvents.js.map +1 -1
- package/dist/esm/clients/mocks/MockHubPoolClient.js +182 -138
- package/dist/esm/clients/mocks/MockHubPoolClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSpokePoolClient.js +188 -202
- package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSvmCpiEventsClient.js +132 -127
- package/dist/esm/clients/mocks/MockSvmCpiEventsClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSvmSpokePoolClient.js +69 -53
- package/dist/esm/clients/mocks/MockSvmSpokePoolClient.js.map +1 -1
- package/dist/esm/coingecko/Coingecko.js +443 -298
- package/dist/esm/coingecko/Coingecko.js.map +1 -1
- package/dist/esm/constants.js +47 -40
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/contracts/acrossConfigStore.js +46 -24
- package/dist/esm/contracts/acrossConfigStore.js.map +1 -1
- package/dist/esm/contracts/hubPool.js +18 -34
- package/dist/esm/contracts/hubPool.js.map +1 -1
- package/dist/esm/contracts/utils.js +5 -3
- package/dist/esm/contracts/utils.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/arbitrum.js +14 -6
- package/dist/esm/gasPriceOracle/adapters/arbitrum.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/ethereum.js +42 -22
- package/dist/esm/gasPriceOracle/adapters/ethereum.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/linea-viem.js +25 -13
- package/dist/esm/gasPriceOracle/adapters/linea-viem.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/polygon.js +108 -72
- package/dist/esm/gasPriceOracle/adapters/polygon.js.map +1 -1
- package/dist/esm/gasPriceOracle/adapters/solana.js +31 -22
- package/dist/esm/gasPriceOracle/adapters/solana.js.map +1 -1
- package/dist/esm/gasPriceOracle/oracle.js +96 -70
- package/dist/esm/gasPriceOracle/oracle.js.map +1 -1
- package/dist/esm/gasPriceOracle/types.js +2 -2
- package/dist/esm/gasPriceOracle/types.js.map +1 -1
- package/dist/esm/gasPriceOracle/util.js +4 -4
- package/dist/esm/gasPriceOracle/util.js.map +1 -1
- package/dist/esm/lpFeeCalculator/lpFeeCalculator.js +33 -30
- package/dist/esm/lpFeeCalculator/lpFeeCalculator.js.map +1 -1
- package/dist/esm/lpFeeCalculator/rateModel.js +9 -7
- package/dist/esm/lpFeeCalculator/rateModel.js.map +1 -1
- package/dist/esm/merkleDistributor/MerkleDistributor.js +17 -18
- package/dist/esm/merkleDistributor/MerkleDistributor.js.map +1 -1
- package/dist/esm/pool/TransactionManager.js +100 -45
- package/dist/esm/pool/TransactionManager.js.map +1 -1
- package/dist/esm/pool/poolClient.js +740 -479
- package/dist/esm/pool/poolClient.js.map +1 -1
- package/dist/esm/pool/uma/across/constants.js +2 -2
- package/dist/esm/pool/uma/across/constants.js.map +1 -1
- package/dist/esm/pool/uma/across/transactionManager.js +100 -45
- package/dist/esm/pool/uma/across/transactionManager.js.map +1 -1
- package/dist/esm/pool/uma/clients/erc20/client.js +13 -15
- package/dist/esm/pool/uma/clients/erc20/client.js.map +1 -1
- package/dist/esm/pool/uma/oracle/utils.js +3 -2
- package/dist/esm/pool/uma/oracle/utils.js.map +1 -1
- package/dist/esm/pool/uma/utils.js +28 -9
- package/dist/esm/pool/uma/utils.js.map +1 -1
- package/dist/esm/priceClient/adapters/acrossApi.js +40 -21
- package/dist/esm/priceClient/adapters/acrossApi.js.map +1 -1
- package/dist/esm/priceClient/adapters/baseAdapter.js +72 -46
- package/dist/esm/priceClient/adapters/baseAdapter.js.map +1 -1
- package/dist/esm/priceClient/adapters/coingecko.js +61 -33
- package/dist/esm/priceClient/adapters/coingecko.js.map +1 -1
- package/dist/esm/priceClient/adapters/default.js +31 -15
- package/dist/esm/priceClient/adapters/default.js.map +1 -1
- package/dist/esm/priceClient/adapters/defiLlama.js +73 -38
- package/dist/esm/priceClient/adapters/defiLlama.js.map +1 -1
- package/dist/esm/priceClient/priceClient.js +158 -109
- package/dist/esm/priceClient/priceClient.js.map +1 -1
- package/dist/esm/providers/alchemy.js +18 -16
- package/dist/esm/providers/alchemy.js.map +1 -1
- package/dist/esm/providers/cachedProvider.js +134 -99
- package/dist/esm/providers/cachedProvider.js.map +1 -1
- package/dist/esm/providers/constants.js +3 -3
- package/dist/esm/providers/constants.js.map +1 -1
- package/dist/esm/providers/drpc.js +10 -8
- package/dist/esm/providers/drpc.js.map +1 -1
- package/dist/esm/providers/infura.js +11 -9
- package/dist/esm/providers/infura.js.map +1 -1
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.js +15 -6
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/MockRateLimitedSolanaRpcFactory.js +14 -5
- package/dist/esm/providers/mocks/MockRateLimitedSolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/MockRetrySolanaRpcFactory.js +15 -6
- package/dist/esm/providers/mocks/MockRetrySolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/MockSolanaRpcFactory.js +66 -41
- package/dist/esm/providers/mocks/MockSolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/mockEthersProvider.js +30 -27
- package/dist/esm/providers/mocks/mockEthersProvider.js.map +1 -1
- package/dist/esm/providers/quicknode.js +20 -18
- package/dist/esm/providers/quicknode.js.map +1 -1
- package/dist/esm/providers/rateLimitedProvider.js +80 -68
- package/dist/esm/providers/rateLimitedProvider.js.map +1 -1
- package/dist/esm/providers/retryProvider.js +259 -186
- package/dist/esm/providers/retryProvider.js.map +1 -1
- package/dist/esm/providers/solana/baseRpcFactories.js +19 -13
- package/dist/esm/providers/solana/baseRpcFactories.js.map +1 -1
- package/dist/esm/providers/solana/cachedRpcFactory.js +112 -75
- package/dist/esm/providers/solana/cachedRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/defaultRpcFactory.js +14 -6
- package/dist/esm/providers/solana/defaultRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/quorumFallbackRpcFactory.js +202 -149
- package/dist/esm/providers/solana/quorumFallbackRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/rateLimitedRpcFactory.js +90 -70
- package/dist/esm/providers/solana/rateLimitedRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/retryRpcFactory.js +74 -50
- package/dist/esm/providers/solana/retryRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/utils.js +1 -1
- package/dist/esm/providers/solana/utils.js.map +1 -1
- package/dist/esm/providers/speedProvider.js +51 -28
- package/dist/esm/providers/speedProvider.js.map +1 -1
- package/dist/esm/providers/types.js +2 -2
- package/dist/esm/providers/types.js.map +1 -1
- package/dist/esm/providers/utils.js +20 -17
- package/dist/esm/providers/utils.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js +152 -98
- package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/customGasToken.js +26 -13
- package/dist/esm/relayFeeCalculator/chain-queries/customGasToken.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/factory.js +19 -9
- package/dist/esm/relayFeeCalculator/chain-queries/factory.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js +128 -83
- package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.js +299 -211
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
- package/dist/esm/typeguards/error.js +5 -3
- package/dist/esm/typeguards/error.js.map +1 -1
- package/dist/esm/utils/AddressUtils.js +147 -115
- package/dist/esm/utils/AddressUtils.js.map +1 -1
- package/dist/esm/utils/ArrayUtils.js +78 -21
- package/dist/esm/utils/ArrayUtils.js.map +1 -1
- package/dist/esm/utils/BigNumberUtils.js +12 -11
- package/dist/esm/utils/BigNumberUtils.js.map +1 -1
- package/dist/esm/utils/BlockExplorerUtils.js +23 -19
- package/dist/esm/utils/BlockExplorerUtils.js.map +1 -1
- package/dist/esm/utils/BlockFinder.js +6 -2
- package/dist/esm/utils/BlockFinder.js.map +1 -1
- package/dist/esm/utils/BlockUtils.js +40 -31
- package/dist/esm/utils/BlockUtils.js.map +1 -1
- package/dist/esm/utils/BundleUtils.js +24 -21
- package/dist/esm/utils/BundleUtils.js.map +1 -1
- package/dist/esm/utils/CCTPUtils.js +123 -62
- package/dist/esm/utils/CCTPUtils.js.map +1 -1
- package/dist/esm/utils/CachingUtils.js +38 -17
- package/dist/esm/utils/CachingUtils.js.map +1 -1
- package/dist/esm/utils/ContractUtils.js +3 -3
- package/dist/esm/utils/ContractUtils.js.map +1 -1
- package/dist/esm/utils/DepositUtils.js +98 -121
- package/dist/esm/utils/DepositUtils.js.map +1 -1
- package/dist/esm/utils/EventUtils.js +69 -52
- package/dist/esm/utils/EventUtils.js.map +1 -1
- package/dist/esm/utils/FormattingUtils.js +26 -20
- package/dist/esm/utils/FormattingUtils.js.map +1 -1
- package/dist/esm/utils/HyperLiquidUtils.js +22 -8
- package/dist/esm/utils/HyperLiquidUtils.js.map +1 -1
- package/dist/esm/utils/IPFSUtils.js +35 -16
- package/dist/esm/utils/IPFSUtils.js.map +1 -1
- package/dist/esm/utils/JSONUtils.js +4 -4
- package/dist/esm/utils/JSONUtils.js.map +1 -1
- package/dist/esm/utils/LogUtils.js +12 -8
- package/dist/esm/utils/LogUtils.js.map +1 -1
- package/dist/esm/utils/Multicall.js +110 -50
- package/dist/esm/utils/Multicall.js.map +1 -1
- package/dist/esm/utils/NetworkUtils.js +28 -12
- package/dist/esm/utils/NetworkUtils.js.map +1 -1
- package/dist/esm/utils/NumberUtils.js +3 -1
- package/dist/esm/utils/NumberUtils.js.map +1 -1
- package/dist/esm/utils/ObjectUtils.js +41 -27
- package/dist/esm/utils/ObjectUtils.js.map +1 -1
- package/dist/esm/utils/Profiler.js +82 -77
- package/dist/esm/utils/Profiler.js.map +1 -1
- package/dist/esm/utils/ReviverUtils.js +7 -3
- package/dist/esm/utils/ReviverUtils.js.map +1 -1
- package/dist/esm/utils/SpokeUtils.js +78 -83
- package/dist/esm/utils/SpokeUtils.js.map +1 -1
- package/dist/esm/utils/TokenUtils.js +57 -33
- package/dist/esm/utils/TokenUtils.js.map +1 -1
- package/dist/esm/utils/ValidatorUtils.js +4 -4
- package/dist/esm/utils/ValidatorUtils.js.map +1 -1
- package/dist/esm/utils/abi/index.js +20 -10
- package/dist/esm/utils/abi/index.js.map +1 -1
- package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.js +12 -8
- package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.js.map +1 -1
- package/dist/esm/utils/common.js +52 -38
- package/dist/esm/utils/common.js.map +1 -1
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/gasPriceOracle/oracle.d.ts.map +1 -1
- package/dist/types/utils/Multicall.d.ts.map +1 -1
- package/dist/types/utils/NetworkUtils.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/constants.ts +1 -0
- package/src/gasPriceOracle/oracle.ts +1 -0
- package/src/utils/Multicall.ts +1 -0
- package/src/utils/NetworkUtils.ts +8 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { __assign, __awaiter, __extends, __generator, __spreadArray } from "tslib";
|
|
1
2
|
import assert from "assert";
|
|
2
3
|
import _ from "lodash";
|
|
3
4
|
import { DEFAULT_CACHING_SAFE_LAG, DEFAULT_CACHING_TTL, TOKEN_SYMBOLS_MAP } from "../constants";
|
|
@@ -5,42 +6,39 @@ import * as lpFeeCalculator from "../lpFeeCalculator";
|
|
|
5
6
|
import { EVMBlockFinder } from "../arch/evm";
|
|
6
7
|
import { BigNumber, bnZero, dedupArray, assign, fetchTokenInfo, getCachedBlockForTimestamp, getCurrentTime, isDefined, mapAsync, paginatedEventQuery, shouldCache, sortEventsDescending, spreadEventWithBlockNumber, toBN, getTokenInfo, getUsdcSymbol, chainIsSvm, getDeployedAddress, SvmAddress, EvmAddress, } from "../utils";
|
|
7
8
|
import { BaseAbstractClient, isUpdateFailureReason, UpdateFailureReason } from "./BaseAbstractClient";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
hubPool
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.blockFinder = new EVMBlockFinder(provider);
|
|
42
|
-
}
|
|
43
|
-
hubPoolEventFilters() {
|
|
9
|
+
var HubPoolClient = /** @class */ (function (_super) {
|
|
10
|
+
__extends(HubPoolClient, _super);
|
|
11
|
+
function HubPoolClient(logger, hubPool, configStoreClient, deploymentBlock, chainId, eventSearchConfig, configOverride, cachingMechanism) {
|
|
12
|
+
if (deploymentBlock === void 0) { deploymentBlock = 0; }
|
|
13
|
+
if (chainId === void 0) { chainId = 1; }
|
|
14
|
+
if (eventSearchConfig === void 0) { eventSearchConfig = { from: 0, maxLookBack: 0 }; }
|
|
15
|
+
if (configOverride === void 0) { configOverride = {
|
|
16
|
+
ignoredHubExecutedBundles: [],
|
|
17
|
+
ignoredHubProposedBundles: [],
|
|
18
|
+
}; }
|
|
19
|
+
var _this = _super.call(this, eventSearchConfig, cachingMechanism) || this;
|
|
20
|
+
_this.logger = logger;
|
|
21
|
+
_this.hubPool = hubPool;
|
|
22
|
+
_this.configStoreClient = configStoreClient;
|
|
23
|
+
_this.deploymentBlock = deploymentBlock;
|
|
24
|
+
_this.chainId = chainId;
|
|
25
|
+
_this.configOverride = configOverride;
|
|
26
|
+
_this.l1Tokens = []; // L1Tokens and their associated info.
|
|
27
|
+
// @dev `token` here is a 20-byte hex sting
|
|
28
|
+
_this.lpTokens = {};
|
|
29
|
+
_this.proposedRootBundles = [];
|
|
30
|
+
_this.canceledRootBundles = [];
|
|
31
|
+
_this.disputedRootBundles = [];
|
|
32
|
+
_this.executedRootBundles = [];
|
|
33
|
+
_this.crossChainContracts = {};
|
|
34
|
+
_this.l1TokensToDestinationTokensWithBlock = {};
|
|
35
|
+
_this.latestHeightSearched = Math.min(deploymentBlock - 1, 0);
|
|
36
|
+
_this.firstHeightToSearch = eventSearchConfig.from;
|
|
37
|
+
var provider = _this.hubPool.provider;
|
|
38
|
+
_this.blockFinder = new EVMBlockFinder(provider);
|
|
39
|
+
return _this;
|
|
40
|
+
}
|
|
41
|
+
HubPoolClient.prototype.hubPoolEventFilters = function () {
|
|
44
42
|
return {
|
|
45
43
|
SetPoolRebalanceRoute: this.hubPool.filters.SetPoolRebalanceRoute(),
|
|
46
44
|
L1TokenEnabledForLiquidityProvision: this.hubPool.filters.L1TokenEnabledForLiquidityProvision(),
|
|
@@ -50,107 +48,118 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
50
48
|
RootBundleExecuted: this.hubPool.filters.RootBundleExecuted(),
|
|
51
49
|
CrossChainContractsSet: this.hubPool.filters.CrossChainContractsSet(),
|
|
52
50
|
};
|
|
53
|
-
}
|
|
54
|
-
hasPendingProposal() {
|
|
51
|
+
};
|
|
52
|
+
HubPoolClient.prototype.hasPendingProposal = function () {
|
|
55
53
|
return this.pendingRootBundle !== undefined;
|
|
56
|
-
}
|
|
57
|
-
getPendingRootBundle() {
|
|
54
|
+
};
|
|
55
|
+
HubPoolClient.prototype.getPendingRootBundle = function () {
|
|
58
56
|
return this.pendingRootBundle;
|
|
59
|
-
}
|
|
60
|
-
getProposedRootBundles() {
|
|
57
|
+
};
|
|
58
|
+
HubPoolClient.prototype.getProposedRootBundles = function () {
|
|
61
59
|
return this.proposedRootBundles;
|
|
62
|
-
}
|
|
63
|
-
getCancelledRootBundles() {
|
|
60
|
+
};
|
|
61
|
+
HubPoolClient.prototype.getCancelledRootBundles = function () {
|
|
64
62
|
return this.canceledRootBundles;
|
|
65
|
-
}
|
|
66
|
-
getDisputedRootBundles() {
|
|
63
|
+
};
|
|
64
|
+
HubPoolClient.prototype.getDisputedRootBundles = function () {
|
|
67
65
|
return this.disputedRootBundles;
|
|
68
|
-
}
|
|
69
|
-
getExecutedRootBundles() {
|
|
66
|
+
};
|
|
67
|
+
HubPoolClient.prototype.getExecutedRootBundles = function () {
|
|
70
68
|
return this.executedRootBundles;
|
|
71
|
-
}
|
|
72
|
-
getSpokePoolForBlock(chain, block
|
|
69
|
+
};
|
|
70
|
+
HubPoolClient.prototype.getSpokePoolForBlock = function (chain, block) {
|
|
71
|
+
if (block === void 0) { block = Number.MAX_SAFE_INTEGER; }
|
|
73
72
|
if (!this.crossChainContracts[chain]) {
|
|
74
|
-
throw new Error(
|
|
73
|
+
throw new Error("No cross chain contracts set for ".concat(chain));
|
|
75
74
|
}
|
|
76
|
-
|
|
75
|
+
var mostRecentSpokePoolUpdateBeforeBlock = sortEventsDescending(this.crossChainContracts[chain]).find(function (crossChainContract) { return crossChainContract.blockNumber <= block; });
|
|
77
76
|
if (!mostRecentSpokePoolUpdateBeforeBlock) {
|
|
78
|
-
throw new Error(
|
|
77
|
+
throw new Error("No cross chain contract found before block ".concat(block, " for chain ").concat(chain));
|
|
79
78
|
}
|
|
80
79
|
else {
|
|
81
80
|
return mostRecentSpokePoolUpdateBeforeBlock.spokePool;
|
|
82
81
|
}
|
|
83
|
-
}
|
|
84
|
-
getSpokePoolActivationBlock(chain, spokePool) {
|
|
82
|
+
};
|
|
83
|
+
HubPoolClient.prototype.getSpokePoolActivationBlock = function (chain, spokePool) {
|
|
85
84
|
// Return first time that this spoke pool was registered in the HubPool as a cross chain contract. We can use
|
|
86
85
|
// this block as the oldest block that we should query for SpokePoolClient purposes.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
var mostRecentSpokePoolUpdateBeforeBlock = this.crossChainContracts[chain].find(function (crossChainContract) {
|
|
87
|
+
return crossChainContract.spokePool.eq(spokePool);
|
|
88
|
+
});
|
|
89
|
+
return mostRecentSpokePoolUpdateBeforeBlock === null || mostRecentSpokePoolUpdateBeforeBlock === void 0 ? void 0 : mostRecentSpokePoolUpdateBeforeBlock.blockNumber;
|
|
90
|
+
};
|
|
90
91
|
// Returns the latest L2 token to use for an L1 token as of the input hub block.
|
|
91
|
-
getL2TokenForL1TokenAtBlock(l1Token, destinationChainId, latestHubBlock
|
|
92
|
-
|
|
92
|
+
HubPoolClient.prototype.getL2TokenForL1TokenAtBlock = function (l1Token, destinationChainId, latestHubBlock) {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
if (latestHubBlock === void 0) { latestHubBlock = Number.MAX_SAFE_INTEGER; }
|
|
95
|
+
if (!((_b = (_a = this.l1TokensToDestinationTokensWithBlock) === null || _a === void 0 ? void 0 : _a[l1Token.toNative()]) === null || _b === void 0 ? void 0 : _b[destinationChainId])) {
|
|
93
96
|
return undefined;
|
|
94
97
|
}
|
|
95
98
|
// Find the last mapping published before the target block.
|
|
96
|
-
|
|
99
|
+
var l2Token = this.l1TokensToDestinationTokensWithBlock[l1Token.toNative()][destinationChainId].find(function (mapping) { return mapping.blockNumber <= latestHubBlock; });
|
|
97
100
|
return !isDefined(l2Token) || l2Token.l2Token.isZeroAddress() ? undefined : l2Token.l2Token;
|
|
98
|
-
}
|
|
101
|
+
};
|
|
99
102
|
// Returns the latest L1 token to use for an L2 token as of the input hub block.
|
|
100
|
-
getL1TokenForL2TokenAtBlock(l2Token, destinationChainId, latestHubBlock
|
|
101
|
-
|
|
103
|
+
HubPoolClient.prototype.getL1TokenForL2TokenAtBlock = function (l2Token, destinationChainId, latestHubBlock) {
|
|
104
|
+
var _this = this;
|
|
105
|
+
if (latestHubBlock === void 0) { latestHubBlock = Number.MAX_SAFE_INTEGER; }
|
|
106
|
+
var l2Tokens = Object.keys(this.l1TokensToDestinationTokensWithBlock).flatMap(function (l1Token) {
|
|
107
|
+
var _a;
|
|
102
108
|
// Get the latest L2 token mapping for the given L1 token.
|
|
103
109
|
// @dev Since tokens on L2s (like Solana) can have 32 byte addresses, filter on the lower 20 bytes of the token only.
|
|
104
|
-
|
|
110
|
+
var sortedL2Tokens = sortEventsDescending(((_a = _this.l1TokensToDestinationTokensWithBlock[l1Token][destinationChainId]) !== null && _a !== void 0 ? _a : []).filter(function (dstTokenWithBlock) { return dstTokenWithBlock.blockNumber <= latestHubBlock; }));
|
|
105
111
|
// If the latest L2 token mapping is equal to the target L2 token, return it.
|
|
106
112
|
return sortedL2Tokens.length > 0 && sortedL2Tokens[0].l2Token.truncateToBytes20() === l2Token.truncateToBytes20()
|
|
107
113
|
? sortedL2Tokens[0]
|
|
108
114
|
: [];
|
|
109
115
|
});
|
|
110
116
|
return l2Tokens.length === 0 ? undefined : sortEventsDescending(l2Tokens)[0].l1Token;
|
|
111
|
-
}
|
|
112
|
-
getL1TokenForDeposit(deposit) {
|
|
117
|
+
};
|
|
118
|
+
HubPoolClient.prototype.getL1TokenForDeposit = function (deposit) {
|
|
113
119
|
// L1-->L2 token mappings are set via PoolRebalanceRoutes which occur on mainnet,
|
|
114
120
|
// so we use the latest token mapping. This way if a very old deposit is filled, the relayer can use the
|
|
115
121
|
// latest L2 token mapping to find the L1 token counterpart.
|
|
116
122
|
return this.getL1TokenForL2TokenAtBlock(deposit.inputToken, deposit.originChainId, deposit.quoteBlockNumber);
|
|
117
|
-
}
|
|
118
|
-
l2TokenEnabledForL1Token(l1Token, destinationChainId) {
|
|
123
|
+
};
|
|
124
|
+
HubPoolClient.prototype.l2TokenEnabledForL1Token = function (l1Token, destinationChainId) {
|
|
119
125
|
return this.l2TokenEnabledForL1TokenAtBlock(l1Token, destinationChainId, Number.MAX_SAFE_INTEGER);
|
|
120
|
-
}
|
|
121
|
-
l2TokenEnabledForL1TokenAtBlock(l1Token, destinationChainId, hubBlockNumber) {
|
|
126
|
+
};
|
|
127
|
+
HubPoolClient.prototype.l2TokenEnabledForL1TokenAtBlock = function (l1Token, destinationChainId, hubBlockNumber) {
|
|
128
|
+
var _a, _b, _c;
|
|
122
129
|
// Find the last mapping published before the target block.
|
|
123
|
-
|
|
130
|
+
var l2Token = sortEventsDescending((_c = (_b = (_a = this.l1TokensToDestinationTokensWithBlock) === null || _a === void 0 ? void 0 : _a[l1Token.toNative()]) === null || _b === void 0 ? void 0 : _b[destinationChainId]) !== null && _c !== void 0 ? _c : []).find(function (mapping) { return mapping.blockNumber <= hubBlockNumber; });
|
|
124
131
|
return isDefined(l2Token) && !l2Token.l2Token.isZeroAddress();
|
|
125
|
-
}
|
|
126
|
-
l2TokenHasPoolRebalanceRoute(l2Token, l2ChainId, hubPoolBlock
|
|
127
|
-
|
|
132
|
+
};
|
|
133
|
+
HubPoolClient.prototype.l2TokenHasPoolRebalanceRoute = function (l2Token, l2ChainId, hubPoolBlock) {
|
|
134
|
+
if (hubPoolBlock === void 0) { hubPoolBlock = this.latestHeightSearched; }
|
|
135
|
+
var l1Token = this.getL1TokenForL2TokenAtBlock(l2Token, l2ChainId, hubPoolBlock);
|
|
128
136
|
return isDefined(l1Token);
|
|
129
|
-
}
|
|
137
|
+
};
|
|
130
138
|
/**
|
|
131
139
|
* @dev If tokenAddress + chain do not exist in TOKEN_SYMBOLS_MAP then this will throw.
|
|
132
140
|
* @param tokenAddress Token address on `chain`
|
|
133
141
|
* @param chainId Chain where the `tokenAddress` exists in TOKEN_SYMBOLS_MAP.
|
|
134
142
|
* @returns Token info for the given token address on the L2 chain including symbol and decimal.
|
|
135
143
|
*/
|
|
136
|
-
getTokenInfoForAddress(address, chainId) {
|
|
137
|
-
|
|
144
|
+
HubPoolClient.prototype.getTokenInfoForAddress = function (address, chainId) {
|
|
145
|
+
var _a;
|
|
146
|
+
var tokenInfo = getTokenInfo(address, chainId);
|
|
138
147
|
// @dev Temporarily handle case where an L2 token for chain ID can map to more than one TOKEN_SYMBOLS_MAP
|
|
139
148
|
// entry. For example, L2 Bridged USDC maps to both the USDC and USDC.e/USDbC entries in TOKEN_SYMBOLS_MAP.
|
|
140
149
|
if (tokenInfo.symbol.toLowerCase() === "usdc" && chainId !== this.chainId) {
|
|
141
|
-
tokenInfo.symbol = getUsdcSymbol(address, chainId)
|
|
150
|
+
tokenInfo.symbol = (_a = getUsdcSymbol(address, chainId)) !== null && _a !== void 0 ? _a : "UNKNOWN USDC";
|
|
142
151
|
}
|
|
143
152
|
return tokenInfo;
|
|
144
|
-
}
|
|
153
|
+
};
|
|
145
154
|
/**
|
|
146
155
|
* Resolve a given timestamp to a block number on the HubPool chain.
|
|
147
156
|
* @param timestamp A single timestamp to be resolved to a block number on the HubPool chain.
|
|
148
157
|
* @returns The block number corresponding to the supplied timestamp.
|
|
149
158
|
*/
|
|
150
|
-
getBlockNumber(timestamp) {
|
|
151
|
-
|
|
159
|
+
HubPoolClient.prototype.getBlockNumber = function (timestamp) {
|
|
160
|
+
var hints = { lowBlock: this.deploymentBlock };
|
|
152
161
|
return getCachedBlockForTimestamp(this.chainId, timestamp, this.blockFinder, this.cachingMechanism, hints);
|
|
153
|
-
}
|
|
162
|
+
};
|
|
154
163
|
/**
|
|
155
164
|
* For an array of timestamps, resolve each unique timestamp to a block number on the HubPool chain.
|
|
156
165
|
* @dev Inputs are filtered for uniqueness and sorted to improve BlockFinder efficiency.
|
|
@@ -158,18 +167,55 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
158
167
|
* @param timestamps Array of timestamps to be resolved to a block number on the HubPool chain.
|
|
159
168
|
* @returns A mapping of quoteTimestamp -> HubPool block number.
|
|
160
169
|
*/
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
HubPoolClient.prototype.getBlockNumbers = function (timestamps) {
|
|
171
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
172
|
+
var sortedTimestamps, blockNumbers, _i, sortedTimestamps_1, timestamp, _a, _b;
|
|
173
|
+
return __generator(this, function (_c) {
|
|
174
|
+
switch (_c.label) {
|
|
175
|
+
case 0:
|
|
176
|
+
sortedTimestamps = dedupArray(timestamps).sort(function (x, y) { return x - y; });
|
|
177
|
+
blockNumbers = {};
|
|
178
|
+
_i = 0, sortedTimestamps_1 = sortedTimestamps;
|
|
179
|
+
_c.label = 1;
|
|
180
|
+
case 1:
|
|
181
|
+
if (!(_i < sortedTimestamps_1.length)) return [3 /*break*/, 4];
|
|
182
|
+
timestamp = sortedTimestamps_1[_i];
|
|
183
|
+
_a = blockNumbers;
|
|
184
|
+
_b = timestamp;
|
|
185
|
+
return [4 /*yield*/, this.getBlockNumber(timestamp)];
|
|
186
|
+
case 2:
|
|
187
|
+
_a[_b] = _c.sent();
|
|
188
|
+
_c.label = 3;
|
|
189
|
+
case 3:
|
|
190
|
+
_i++;
|
|
191
|
+
return [3 /*break*/, 1];
|
|
192
|
+
case 4: return [2 /*return*/, blockNumbers];
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
HubPoolClient.prototype.getCurrentPoolUtilization = function (l1Token) {
|
|
198
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
199
|
+
var blockNumber, _a;
|
|
200
|
+
var _b;
|
|
201
|
+
return __generator(this, function (_c) {
|
|
202
|
+
switch (_c.label) {
|
|
203
|
+
case 0:
|
|
204
|
+
if (!((_b = this.latestHeightSearched) !== null && _b !== void 0)) return [3 /*break*/, 1];
|
|
205
|
+
_a = _b;
|
|
206
|
+
return [3 /*break*/, 3];
|
|
207
|
+
case 1: return [4 /*yield*/, this.hubPool.provider.getBlockNumber()];
|
|
208
|
+
case 2:
|
|
209
|
+
_a = (_c.sent());
|
|
210
|
+
_c.label = 3;
|
|
211
|
+
case 3:
|
|
212
|
+
blockNumber = _a;
|
|
213
|
+
return [4 /*yield*/, this.getUtilization(l1Token, blockNumber, bnZero, getCurrentTime(), 0)];
|
|
214
|
+
case 4: return [2 /*return*/, _c.sent()];
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
};
|
|
173
219
|
/**
|
|
174
220
|
* For a HubPool token at a specific block number, compute the relevant utilization.
|
|
175
221
|
* @param hubPoolToken HubPool token to query utilization for.
|
|
@@ -179,190 +225,261 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
179
225
|
* @param timeToCache Age at which the response is able to be cached.
|
|
180
226
|
* @returns HubPool utilization at `blockNumber` after optional `amount` increase in utilization.
|
|
181
227
|
*/
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const utilizationTimestamps = {};
|
|
225
|
-
// Map each HubPool token to utilization at a particular block number.
|
|
226
|
-
let utilization = {};
|
|
227
|
-
let quoteBlocks = {};
|
|
228
|
-
// Map SpokePool token addresses to HubPool token addresses.
|
|
229
|
-
// Note: Should only be accessed via `getHubPoolToken()` or `getHubPoolTokens()`.
|
|
230
|
-
const hubPoolTokens = {};
|
|
231
|
-
const getHubPoolToken = (deposit, quoteBlockNumber) => {
|
|
232
|
-
const tokenKey = `${deposit.originChainId}-${deposit.inputToken}`;
|
|
233
|
-
const l1Token = this.getL1TokenForDeposit({ ...deposit, quoteBlockNumber });
|
|
234
|
-
if (!isDefined(l1Token)) {
|
|
235
|
-
return undefined;
|
|
236
|
-
}
|
|
237
|
-
return (hubPoolTokens[tokenKey] ??= l1Token);
|
|
238
|
-
};
|
|
239
|
-
// Filter hubPoolTokens for duplicates by reverting to their native string
|
|
240
|
-
// representation. This is required for deduplication to work reliably.
|
|
241
|
-
const getHubPoolTokens = () => dedupArray(Object.values(hubPoolTokens)
|
|
242
|
-
.filter(isDefined)
|
|
243
|
-
.map((token) => token.toNative())).map((token) => EvmAddress.from(token));
|
|
244
|
-
// Helper to resolve the unique hubPoolToken & quoteTimestamp mappings.
|
|
245
|
-
const resolveUniqueQuoteTimestamps = (deposit) => {
|
|
246
|
-
const { quoteTimestamp } = deposit;
|
|
247
|
-
// Resolve the HubPool token address for this origin chainId/token pair, if it isn't already known.
|
|
248
|
-
const quoteBlockNumber = quoteBlocks[quoteTimestamp];
|
|
249
|
-
const hubPoolToken = getHubPoolToken(deposit, quoteBlockNumber);
|
|
250
|
-
if (!hubPoolToken) {
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
// Append the quoteTimestamp for this HubPool token, if it isn't already enqueued.
|
|
254
|
-
const token = hubPoolToken.toNative();
|
|
255
|
-
utilizationTimestamps[token] ??= [];
|
|
256
|
-
if (!utilizationTimestamps[token].includes(quoteTimestamp)) {
|
|
257
|
-
utilizationTimestamps[token].push(quoteTimestamp);
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
// Helper to resolve existing HubPool token utilisation for an array of unique block numbers.
|
|
261
|
-
// Produces a mapping of blockNumber -> utilization for a specific token.
|
|
262
|
-
const resolveUtilization = async (hubPoolToken) => {
|
|
263
|
-
return Object.fromEntries(await mapAsync(utilizationTimestamps[hubPoolToken.toNative()], async (quoteTimestamp) => {
|
|
264
|
-
const blockNumber = quoteBlocks[quoteTimestamp];
|
|
265
|
-
const utilization = await this.getUtilization(hubPoolToken, blockNumber, bnZero, // amount
|
|
266
|
-
quoteTimestamp, timeToCache);
|
|
267
|
-
return [blockNumber, utilization];
|
|
268
|
-
}));
|
|
269
|
-
};
|
|
270
|
-
// Helper compute the realizedLpFeePct of an individual deposit based on pre-retrieved batch data.
|
|
271
|
-
const computeRealizedLpFeePct = async (deposit) => {
|
|
272
|
-
const { originChainId, paymentChainId, inputAmount, quoteTimestamp } = deposit;
|
|
273
|
-
const quoteBlock = quoteBlocks[quoteTimestamp];
|
|
274
|
-
if (paymentChainId === undefined || paymentChainId === originChainId) {
|
|
275
|
-
return { quoteBlock, realizedLpFeePct: bnZero };
|
|
276
|
-
}
|
|
277
|
-
const hubPoolToken = getHubPoolToken(deposit, quoteBlock);
|
|
278
|
-
if (hubPoolToken === undefined) {
|
|
279
|
-
throw new Error(`Cannot computeRealizedLpFeePct for deposit with no pool rebalance route for input token ${deposit.inputToken} on ${originChainId}`);
|
|
280
|
-
}
|
|
281
|
-
const rateModel = this.configStoreClient.getRateModelForBlockNumber(hubPoolToken, originChainId, paymentChainId, quoteBlock);
|
|
282
|
-
const preUtilization = utilization[hubPoolToken.toNative()][quoteBlock];
|
|
283
|
-
const postUtilization = await this.getUtilization(hubPoolToken, quoteBlock, inputAmount, quoteTimestamp, timeToCache);
|
|
284
|
-
const realizedLpFeePct = lpFeeCalculator.calculateRealizedLpFeePct(rateModel, preUtilization, postUtilization);
|
|
285
|
-
return { quoteBlock, realizedLpFeePct };
|
|
286
|
-
};
|
|
287
|
-
/**
|
|
288
|
-
* Execution flow starts here.
|
|
289
|
-
*/
|
|
290
|
-
const timeToCache = this.configOverride.timeToCache ?? DEFAULT_CACHING_SAFE_LAG;
|
|
291
|
-
// Filter all deposits for unique quoteTimestamps, to be resolved to a blockNumber in parallel.
|
|
292
|
-
const quoteTimestamps = dedupArray(deposits.map(({ quoteTimestamp }) => quoteTimestamp));
|
|
293
|
-
quoteBlocks = await this.getBlockNumbers(quoteTimestamps);
|
|
294
|
-
// Identify the unique hubPoolToken & quoteTimestamp mappings. This is used to optimise subsequent HubPool queries.
|
|
295
|
-
deposits.forEach((deposit) => resolveUniqueQuoteTimestamps(deposit));
|
|
296
|
-
// For each token / quoteBlock pair, resolve the utilisation for each quoted block.
|
|
297
|
-
// This can be reused for each deposit with the same HubPool token and quoteTimestamp pair.
|
|
298
|
-
utilization = Object.fromEntries(await mapAsync(getHubPoolTokens(), async (hubPoolToken) => [
|
|
299
|
-
hubPoolToken.toNative(),
|
|
300
|
-
await resolveUtilization(hubPoolToken),
|
|
301
|
-
]));
|
|
302
|
-
// For each deposit, compute the post-relay HubPool utilisation independently.
|
|
303
|
-
// @dev The caller expects to receive an array in the same length and ordering as the input `deposits`.
|
|
304
|
-
return await mapAsync(deposits, async (deposit) => {
|
|
305
|
-
const quoteBlock = quoteBlocks[deposit.quoteTimestamp];
|
|
306
|
-
if (this.l2TokenHasPoolRebalanceRoute(deposit.inputToken, deposit.originChainId, quoteBlock)) {
|
|
307
|
-
return await computeRealizedLpFeePct(deposit);
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
return {
|
|
311
|
-
quoteBlock,
|
|
312
|
-
realizedLpFeePct: bnZero,
|
|
313
|
-
};
|
|
314
|
-
}
|
|
228
|
+
HubPoolClient.prototype.getUtilization = function (hubPoolToken, blockNumber, depositAmount, timestamp, timeToCache) {
|
|
229
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
230
|
+
var resolver, cache, key, result, utilization;
|
|
231
|
+
var _this = this;
|
|
232
|
+
return __generator(this, function (_a) {
|
|
233
|
+
switch (_a.label) {
|
|
234
|
+
case 0:
|
|
235
|
+
resolver = function () {
|
|
236
|
+
var overrides = { blockTag: blockNumber };
|
|
237
|
+
var token = hubPoolToken.toNative();
|
|
238
|
+
// For zero amount, just get the utilisation at `blockNumber`.
|
|
239
|
+
return depositAmount.eq(bnZero)
|
|
240
|
+
? _this.hubPool.callStatic.liquidityUtilizationCurrent(token, overrides)
|
|
241
|
+
: _this.hubPool.callStatic.liquidityUtilizationPostRelay(token, depositAmount, overrides);
|
|
242
|
+
};
|
|
243
|
+
cache = this.cachingMechanism;
|
|
244
|
+
// If there is no cache or the timestamp is not old enough to be cached, just resolve the function.
|
|
245
|
+
if (!cache || !shouldCache(getCurrentTime(), timestamp, timeToCache)) {
|
|
246
|
+
return [2 /*return*/, resolver()];
|
|
247
|
+
}
|
|
248
|
+
key = depositAmount.eq(bnZero)
|
|
249
|
+
? "utilization_".concat(hubPoolToken.toNative(), "_").concat(blockNumber)
|
|
250
|
+
: "utilization_".concat(hubPoolToken.toNative(), "_").concat(blockNumber, "_").concat(depositAmount.toString());
|
|
251
|
+
return [4 /*yield*/, cache.get(key)];
|
|
252
|
+
case 1:
|
|
253
|
+
result = _a.sent();
|
|
254
|
+
if (isDefined(result)) {
|
|
255
|
+
return [2 /*return*/, BigNumber.from(result)];
|
|
256
|
+
}
|
|
257
|
+
return [4 /*yield*/, resolver()];
|
|
258
|
+
case 2:
|
|
259
|
+
utilization = _a.sent();
|
|
260
|
+
if (!(cache && shouldCache(getCurrentTime(), timestamp, timeToCache))) return [3 /*break*/, 4];
|
|
261
|
+
// If we should cache the result, store it for up to DEFAULT_CACHING_TTL.
|
|
262
|
+
return [4 /*yield*/, cache.set(key, "".concat(utilization.toString()), DEFAULT_CACHING_TTL)];
|
|
263
|
+
case 3:
|
|
264
|
+
// If we should cache the result, store it for up to DEFAULT_CACHING_TTL.
|
|
265
|
+
_a.sent();
|
|
266
|
+
_a.label = 4;
|
|
267
|
+
case 4: return [2 /*return*/, utilization];
|
|
268
|
+
}
|
|
269
|
+
});
|
|
315
270
|
});
|
|
316
|
-
}
|
|
317
|
-
|
|
271
|
+
};
|
|
272
|
+
HubPoolClient.prototype.computeRealizedLpFeePct = function (deposit) {
|
|
273
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
274
|
+
var lpFee;
|
|
275
|
+
return __generator(this, function (_a) {
|
|
276
|
+
switch (_a.label) {
|
|
277
|
+
case 0: return [4 /*yield*/, this.batchComputeRealizedLpFeePct([deposit])];
|
|
278
|
+
case 1:
|
|
279
|
+
lpFee = (_a.sent())[0];
|
|
280
|
+
return [2 /*return*/, lpFee];
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
};
|
|
285
|
+
HubPoolClient.prototype.batchComputeRealizedLpFeePct = function (deposits) {
|
|
286
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
287
|
+
var utilizationTimestamps, utilization, quoteBlocks, hubPoolTokens, getHubPoolToken, getHubPoolTokens, resolveUniqueQuoteTimestamps, resolveUtilization, computeRealizedLpFeePct, timeToCache, quoteTimestamps, _a, _b;
|
|
288
|
+
var _this = this;
|
|
289
|
+
var _c;
|
|
290
|
+
return __generator(this, function (_d) {
|
|
291
|
+
switch (_d.label) {
|
|
292
|
+
case 0:
|
|
293
|
+
assert(deposits.length > 0, "No deposits supplied to batchComputeRealizedLpFeePct");
|
|
294
|
+
if (!isDefined(this.currentTime)) {
|
|
295
|
+
throw new Error("HubPoolClient has not set a currentTime");
|
|
296
|
+
}
|
|
297
|
+
utilizationTimestamps = {};
|
|
298
|
+
utilization = {};
|
|
299
|
+
quoteBlocks = {};
|
|
300
|
+
hubPoolTokens = {};
|
|
301
|
+
getHubPoolToken = function (deposit, quoteBlockNumber) {
|
|
302
|
+
var _a;
|
|
303
|
+
var tokenKey = "".concat(deposit.originChainId, "-").concat(deposit.inputToken);
|
|
304
|
+
var l1Token = _this.getL1TokenForDeposit(__assign(__assign({}, deposit), { quoteBlockNumber: quoteBlockNumber }));
|
|
305
|
+
if (!isDefined(l1Token)) {
|
|
306
|
+
return undefined;
|
|
307
|
+
}
|
|
308
|
+
return ((_a = hubPoolTokens[tokenKey]) !== null && _a !== void 0 ? _a : (hubPoolTokens[tokenKey] = l1Token));
|
|
309
|
+
};
|
|
310
|
+
getHubPoolTokens = function () {
|
|
311
|
+
return dedupArray(Object.values(hubPoolTokens)
|
|
312
|
+
.filter(isDefined)
|
|
313
|
+
.map(function (token) { return token.toNative(); })).map(function (token) { return EvmAddress.from(token); });
|
|
314
|
+
};
|
|
315
|
+
resolveUniqueQuoteTimestamps = function (deposit) {
|
|
316
|
+
var _a;
|
|
317
|
+
var quoteTimestamp = deposit.quoteTimestamp;
|
|
318
|
+
// Resolve the HubPool token address for this origin chainId/token pair, if it isn't already known.
|
|
319
|
+
var quoteBlockNumber = quoteBlocks[quoteTimestamp];
|
|
320
|
+
var hubPoolToken = getHubPoolToken(deposit, quoteBlockNumber);
|
|
321
|
+
if (!hubPoolToken) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
// Append the quoteTimestamp for this HubPool token, if it isn't already enqueued.
|
|
325
|
+
var token = hubPoolToken.toNative();
|
|
326
|
+
(_a = utilizationTimestamps[token]) !== null && _a !== void 0 ? _a : (utilizationTimestamps[token] = []);
|
|
327
|
+
if (!utilizationTimestamps[token].includes(quoteTimestamp)) {
|
|
328
|
+
utilizationTimestamps[token].push(quoteTimestamp);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
resolveUtilization = function (hubPoolToken) { return __awaiter(_this, void 0, void 0, function () {
|
|
332
|
+
var _a, _b;
|
|
333
|
+
var _this = this;
|
|
334
|
+
return __generator(this, function (_c) {
|
|
335
|
+
switch (_c.label) {
|
|
336
|
+
case 0:
|
|
337
|
+
_b = (_a = Object).fromEntries;
|
|
338
|
+
return [4 /*yield*/, mapAsync(utilizationTimestamps[hubPoolToken.toNative()], function (quoteTimestamp) { return __awaiter(_this, void 0, void 0, function () {
|
|
339
|
+
var blockNumber, utilization;
|
|
340
|
+
return __generator(this, function (_a) {
|
|
341
|
+
switch (_a.label) {
|
|
342
|
+
case 0:
|
|
343
|
+
blockNumber = quoteBlocks[quoteTimestamp];
|
|
344
|
+
return [4 /*yield*/, this.getUtilization(hubPoolToken, blockNumber, bnZero, // amount
|
|
345
|
+
quoteTimestamp, timeToCache)];
|
|
346
|
+
case 1:
|
|
347
|
+
utilization = _a.sent();
|
|
348
|
+
return [2 /*return*/, [blockNumber, utilization]];
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
}); })];
|
|
352
|
+
case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}); };
|
|
356
|
+
computeRealizedLpFeePct = function (deposit) { return __awaiter(_this, void 0, void 0, function () {
|
|
357
|
+
var originChainId, paymentChainId, inputAmount, quoteTimestamp, quoteBlock, hubPoolToken, rateModel, preUtilization, postUtilization, realizedLpFeePct;
|
|
358
|
+
return __generator(this, function (_a) {
|
|
359
|
+
switch (_a.label) {
|
|
360
|
+
case 0:
|
|
361
|
+
originChainId = deposit.originChainId, paymentChainId = deposit.paymentChainId, inputAmount = deposit.inputAmount, quoteTimestamp = deposit.quoteTimestamp;
|
|
362
|
+
quoteBlock = quoteBlocks[quoteTimestamp];
|
|
363
|
+
if (paymentChainId === undefined || paymentChainId === originChainId) {
|
|
364
|
+
return [2 /*return*/, { quoteBlock: quoteBlock, realizedLpFeePct: bnZero }];
|
|
365
|
+
}
|
|
366
|
+
hubPoolToken = getHubPoolToken(deposit, quoteBlock);
|
|
367
|
+
if (hubPoolToken === undefined) {
|
|
368
|
+
throw new Error("Cannot computeRealizedLpFeePct for deposit with no pool rebalance route for input token ".concat(deposit.inputToken, " on ").concat(originChainId));
|
|
369
|
+
}
|
|
370
|
+
rateModel = this.configStoreClient.getRateModelForBlockNumber(hubPoolToken, originChainId, paymentChainId, quoteBlock);
|
|
371
|
+
preUtilization = utilization[hubPoolToken.toNative()][quoteBlock];
|
|
372
|
+
return [4 /*yield*/, this.getUtilization(hubPoolToken, quoteBlock, inputAmount, quoteTimestamp, timeToCache)];
|
|
373
|
+
case 1:
|
|
374
|
+
postUtilization = _a.sent();
|
|
375
|
+
realizedLpFeePct = lpFeeCalculator.calculateRealizedLpFeePct(rateModel, preUtilization, postUtilization);
|
|
376
|
+
return [2 /*return*/, { quoteBlock: quoteBlock, realizedLpFeePct: realizedLpFeePct }];
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
}); };
|
|
380
|
+
timeToCache = (_c = this.configOverride.timeToCache) !== null && _c !== void 0 ? _c : DEFAULT_CACHING_SAFE_LAG;
|
|
381
|
+
quoteTimestamps = dedupArray(deposits.map(function (_a) {
|
|
382
|
+
var quoteTimestamp = _a.quoteTimestamp;
|
|
383
|
+
return quoteTimestamp;
|
|
384
|
+
}));
|
|
385
|
+
return [4 /*yield*/, this.getBlockNumbers(quoteTimestamps)];
|
|
386
|
+
case 1:
|
|
387
|
+
quoteBlocks = _d.sent();
|
|
388
|
+
// Identify the unique hubPoolToken & quoteTimestamp mappings. This is used to optimise subsequent HubPool queries.
|
|
389
|
+
deposits.forEach(function (deposit) { return resolveUniqueQuoteTimestamps(deposit); });
|
|
390
|
+
_b = (_a = Object).fromEntries;
|
|
391
|
+
return [4 /*yield*/, mapAsync(getHubPoolTokens(), function (hubPoolToken) { return __awaiter(_this, void 0, void 0, function () {
|
|
392
|
+
var _a;
|
|
393
|
+
return __generator(this, function (_b) {
|
|
394
|
+
switch (_b.label) {
|
|
395
|
+
case 0:
|
|
396
|
+
_a = [hubPoolToken.toNative()];
|
|
397
|
+
return [4 /*yield*/, resolveUtilization(hubPoolToken)];
|
|
398
|
+
case 1: return [2 /*return*/, _a.concat([
|
|
399
|
+
_b.sent()
|
|
400
|
+
])];
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
}); })];
|
|
404
|
+
case 2:
|
|
405
|
+
// For each token / quoteBlock pair, resolve the utilisation for each quoted block.
|
|
406
|
+
// This can be reused for each deposit with the same HubPool token and quoteTimestamp pair.
|
|
407
|
+
utilization = _b.apply(_a, [_d.sent()]);
|
|
408
|
+
return [4 /*yield*/, mapAsync(deposits, function (deposit) { return __awaiter(_this, void 0, void 0, function () {
|
|
409
|
+
var quoteBlock;
|
|
410
|
+
return __generator(this, function (_a) {
|
|
411
|
+
switch (_a.label) {
|
|
412
|
+
case 0:
|
|
413
|
+
quoteBlock = quoteBlocks[deposit.quoteTimestamp];
|
|
414
|
+
if (!this.l2TokenHasPoolRebalanceRoute(deposit.inputToken, deposit.originChainId, quoteBlock)) return [3 /*break*/, 2];
|
|
415
|
+
return [4 /*yield*/, computeRealizedLpFeePct(deposit)];
|
|
416
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
417
|
+
case 2: return [2 /*return*/, {
|
|
418
|
+
quoteBlock: quoteBlock,
|
|
419
|
+
realizedLpFeePct: bnZero,
|
|
420
|
+
}];
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}); })];
|
|
424
|
+
case 3:
|
|
425
|
+
// For each deposit, compute the post-relay HubPool utilisation independently.
|
|
426
|
+
// @dev The caller expects to receive an array in the same length and ordering as the input `deposits`.
|
|
427
|
+
return [2 /*return*/, _d.sent()];
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
};
|
|
432
|
+
HubPoolClient.prototype.getL1Tokens = function () {
|
|
318
433
|
return this.l1Tokens;
|
|
319
|
-
}
|
|
320
|
-
getTokenInfoForL1Token(l1Token) {
|
|
321
|
-
return this.l1Tokens.find((token)
|
|
322
|
-
}
|
|
323
|
-
getLpTokenInfoForL1Token(l1Token) {
|
|
434
|
+
};
|
|
435
|
+
HubPoolClient.prototype.getTokenInfoForL1Token = function (l1Token) {
|
|
436
|
+
return this.l1Tokens.find(function (token) { return token.address.eq(l1Token); });
|
|
437
|
+
};
|
|
438
|
+
HubPoolClient.prototype.getLpTokenInfoForL1Token = function (l1Token) {
|
|
324
439
|
return this.lpTokens[l1Token.toNative()];
|
|
325
|
-
}
|
|
326
|
-
areTokensEquivalent(tokenA, chainIdA, tokenB, chainIdB, hubPoolBlock
|
|
440
|
+
};
|
|
441
|
+
HubPoolClient.prototype.areTokensEquivalent = function (tokenA, chainIdA, tokenB, chainIdB, hubPoolBlock) {
|
|
442
|
+
if (hubPoolBlock === void 0) { hubPoolBlock = this.latestHeightSearched; }
|
|
327
443
|
if (!this.l2TokenHasPoolRebalanceRoute(tokenA, chainIdA, hubPoolBlock) ||
|
|
328
444
|
!this.l2TokenHasPoolRebalanceRoute(tokenB, chainIdB, hubPoolBlock)) {
|
|
329
445
|
return false;
|
|
330
446
|
}
|
|
331
447
|
// Resolve both SpokePool tokens back to their respective HubPool tokens and verify that they match.
|
|
332
|
-
|
|
333
|
-
|
|
448
|
+
var l1TokenA = this.getL1TokenForL2TokenAtBlock(tokenA, chainIdA, hubPoolBlock);
|
|
449
|
+
var l1TokenB = this.getL1TokenForL2TokenAtBlock(tokenB, chainIdB, hubPoolBlock);
|
|
334
450
|
if (!isDefined(l1TokenA) || !isDefined(l1TokenB) || !l1TokenA.eq(l1TokenB)) {
|
|
335
451
|
return false;
|
|
336
452
|
}
|
|
337
453
|
// Resolve both HubPool tokens back to a current SpokePool token and verify that they match.
|
|
338
|
-
|
|
339
|
-
|
|
454
|
+
var _tokenA = this.getL2TokenForL1TokenAtBlock(l1TokenA, chainIdA, hubPoolBlock);
|
|
455
|
+
var _tokenB = this.getL2TokenForL1TokenAtBlock(l1TokenB, chainIdB, hubPoolBlock);
|
|
340
456
|
return isDefined(_tokenA) && isDefined(_tokenB) && tokenA.eq(_tokenA) && tokenB.eq(_tokenB);
|
|
341
|
-
}
|
|
342
|
-
getSpokeActivationBlockForChain(chainId) {
|
|
343
|
-
|
|
344
|
-
|
|
457
|
+
};
|
|
458
|
+
HubPoolClient.prototype.getSpokeActivationBlockForChain = function (chainId) {
|
|
459
|
+
var _a;
|
|
460
|
+
return (_a = this.getSpokePoolActivationBlock(chainId, this.getSpokePoolForBlock(chainId))) !== null && _a !== void 0 ? _a : 0;
|
|
461
|
+
};
|
|
345
462
|
// Root bundles are valid if all of their pool rebalance leaves have been executed before the next bundle, or the
|
|
346
463
|
// latest mainnet block to search. Whichever comes first.
|
|
347
|
-
isRootBundleValid(rootBundle, latestMainnetBlock) {
|
|
348
|
-
|
|
349
|
-
|
|
464
|
+
HubPoolClient.prototype.isRootBundleValid = function (rootBundle, latestMainnetBlock) {
|
|
465
|
+
var nextRootBundle = this.getFollowingRootBundle(rootBundle);
|
|
466
|
+
var executedLeafCount = this.getExecutedLeavesForRootBundle(rootBundle, nextRootBundle ? Math.min(nextRootBundle.blockNumber, latestMainnetBlock) : latestMainnetBlock);
|
|
350
467
|
return executedLeafCount.length === rootBundle.poolRebalanceLeafCount;
|
|
351
|
-
}
|
|
468
|
+
};
|
|
352
469
|
// This should find the ProposeRootBundle event whose bundle block number for `chain` is closest to the `block`
|
|
353
470
|
// without being smaller. It returns the bundle block number for the chain or undefined if not matched.
|
|
354
|
-
getRootBundleEvalBlockNumberContainingBlock(latestMainnetBlock, block, chain, chainIdListOverride) {
|
|
355
|
-
|
|
356
|
-
|
|
471
|
+
HubPoolClient.prototype.getRootBundleEvalBlockNumberContainingBlock = function (latestMainnetBlock, block, chain, chainIdListOverride) {
|
|
472
|
+
var chainIdList = chainIdListOverride !== null && chainIdListOverride !== void 0 ? chainIdListOverride : this.configStoreClient.getChainIdIndicesForBlock(latestMainnetBlock);
|
|
473
|
+
var endingBlockNumber;
|
|
357
474
|
// Search proposed root bundles in reverse chronological order.
|
|
358
|
-
for (
|
|
359
|
-
|
|
360
|
-
|
|
475
|
+
for (var i = this.proposedRootBundles.length - 1; i >= 0; i--) {
|
|
476
|
+
var rootBundle = this.proposedRootBundles[i];
|
|
477
|
+
var nextRootBundle = this.getFollowingRootBundle(rootBundle);
|
|
361
478
|
if (!this.isRootBundleValid(rootBundle, nextRootBundle ? nextRootBundle.blockNumber : latestMainnetBlock)) {
|
|
362
479
|
continue;
|
|
363
480
|
}
|
|
364
481
|
// 0 is the default value bundleEvalBlockNumber.
|
|
365
|
-
|
|
482
|
+
var bundleEvalBlockNumber = this.getBundleEndBlockForChain(rootBundle, chain, chainIdList);
|
|
366
483
|
// Since we're iterating from newest to oldest, bundleEvalBlockNumber is only decreasing, and if the
|
|
367
484
|
// bundleEvalBlockNumber is smaller than the target block, then we should return the last set `endingBlockNumber`.
|
|
368
485
|
if (bundleEvalBlockNumber <= block) {
|
|
@@ -374,18 +491,18 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
374
491
|
endingBlockNumber = bundleEvalBlockNumber;
|
|
375
492
|
}
|
|
376
493
|
return endingBlockNumber;
|
|
377
|
-
}
|
|
494
|
+
};
|
|
378
495
|
// TODO: This might not be necessary since the cumulative root bundle count doesn't grow fast enough, but consider
|
|
379
496
|
// using _.findLast/_.find instead of resorting the arrays if these functions begin to take a lot time.
|
|
380
|
-
getProposedRootBundlesInBlockRange(startingBlock, endingBlock) {
|
|
381
|
-
return this.proposedRootBundles.filter((bundle)
|
|
382
|
-
}
|
|
383
|
-
getCancelledRootBundlesInBlockRange(startingBlock, endingBlock) {
|
|
384
|
-
return sortEventsDescending(this.canceledRootBundles).filter((bundle)
|
|
385
|
-
}
|
|
386
|
-
getDisputedRootBundlesInBlockRange(startingBlock, endingBlock) {
|
|
387
|
-
return sortEventsDescending(this.disputedRootBundles).filter((bundle)
|
|
388
|
-
}
|
|
497
|
+
HubPoolClient.prototype.getProposedRootBundlesInBlockRange = function (startingBlock, endingBlock) {
|
|
498
|
+
return this.proposedRootBundles.filter(function (bundle) { return bundle.blockNumber >= startingBlock && bundle.blockNumber <= endingBlock; });
|
|
499
|
+
};
|
|
500
|
+
HubPoolClient.prototype.getCancelledRootBundlesInBlockRange = function (startingBlock, endingBlock) {
|
|
501
|
+
return sortEventsDescending(this.canceledRootBundles).filter(function (bundle) { return bundle.blockNumber >= startingBlock && bundle.blockNumber <= endingBlock; });
|
|
502
|
+
};
|
|
503
|
+
HubPoolClient.prototype.getDisputedRootBundlesInBlockRange = function (startingBlock, endingBlock) {
|
|
504
|
+
return sortEventsDescending(this.disputedRootBundles).filter(function (bundle) { return bundle.blockNumber >= startingBlock && bundle.blockNumber <= endingBlock; });
|
|
505
|
+
};
|
|
389
506
|
/**
|
|
390
507
|
* Retrieves token mappings that were modified within a specified block range.
|
|
391
508
|
* @param startingBlock - The starting block of the range (inclusive).
|
|
@@ -393,108 +510,115 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
393
510
|
* @returns An array of destination tokens, each containing the `l2ChainId`, that
|
|
394
511
|
* were modified within the given block range.
|
|
395
512
|
*/
|
|
396
|
-
getTokenMappingsModifiedInBlockRange(startingBlock, endingBlock) {
|
|
513
|
+
HubPoolClient.prototype.getTokenMappingsModifiedInBlockRange = function (startingBlock, endingBlock) {
|
|
397
514
|
// This function iterates over `l1TokensToDestinationTokensWithBlock`, a nested
|
|
398
515
|
// structure of L1 tokens mapped to destination chain IDs, each containing lists
|
|
399
516
|
// of destination tokens with associated block numbers.
|
|
400
517
|
return (Object.values(this.l1TokensToDestinationTokensWithBlock)
|
|
401
|
-
.flatMap((destinationTokens)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
})
|
|
518
|
+
.flatMap(function (destinationTokens) {
|
|
519
|
+
// Map through destination chain IDs and their associated tokens
|
|
520
|
+
return Object.entries(destinationTokens).flatMap(function (_a) {
|
|
521
|
+
var destinationChainId = _a[0], tokensWithBlock = _a[1];
|
|
522
|
+
// Map the tokens to add the l2ChainId field for each token
|
|
523
|
+
return tokensWithBlock.map(function (token) { return (__assign(__assign({}, token), { l2ChainId: Number(destinationChainId) })); });
|
|
524
|
+
});
|
|
525
|
+
})
|
|
409
526
|
// Filter out tokens whose blockNumber is outside the block range
|
|
410
|
-
.filter((token)
|
|
411
|
-
}
|
|
412
|
-
getLatestProposedRootBundle() {
|
|
527
|
+
.filter(function (token) { return token.blockNumber >= startingBlock && token.blockNumber <= endingBlock; }));
|
|
528
|
+
};
|
|
529
|
+
HubPoolClient.prototype.getLatestProposedRootBundle = function () {
|
|
413
530
|
return this.proposedRootBundles[this.proposedRootBundles.length - 1];
|
|
414
|
-
}
|
|
415
|
-
getFollowingRootBundle(currentRootBundle) {
|
|
416
|
-
|
|
531
|
+
};
|
|
532
|
+
HubPoolClient.prototype.getFollowingRootBundle = function (currentRootBundle) {
|
|
533
|
+
var index = _.findLastIndex(this.proposedRootBundles, function (bundle) { return bundle.blockNumber === currentRootBundle.blockNumber; });
|
|
417
534
|
// If index of current root bundle is not found or is the last bundle, return undefined.
|
|
418
535
|
if (index === -1 || index === this.proposedRootBundles.length - 1) {
|
|
419
536
|
return undefined;
|
|
420
537
|
}
|
|
421
538
|
return this.proposedRootBundles[index + 1];
|
|
422
|
-
}
|
|
423
|
-
getExecutedLeavesForRootBundle(rootBundle, latestMainnetBlockToSearch) {
|
|
424
|
-
return this.executedRootBundles.filter((executedLeaf)
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
539
|
+
};
|
|
540
|
+
HubPoolClient.prototype.getExecutedLeavesForRootBundle = function (rootBundle, latestMainnetBlockToSearch) {
|
|
541
|
+
return this.executedRootBundles.filter(function (executedLeaf) {
|
|
542
|
+
return executedLeaf.blockNumber <= latestMainnetBlockToSearch &&
|
|
543
|
+
// Note: We can use > instead of >= here because a leaf can never be executed in same block as its root
|
|
544
|
+
// proposal due to bundle liveness enforced by HubPool. This importantly avoids the edge case
|
|
545
|
+
// where the execution all leaves occurs in the same block as the next proposal, leading us to think
|
|
546
|
+
// that the next proposal is fully executed when its not.
|
|
547
|
+
executedLeaf.blockNumber > rootBundle.blockNumber;
|
|
548
|
+
});
|
|
549
|
+
};
|
|
550
|
+
HubPoolClient.prototype.getValidatedRootBundles = function (latestMainnetBlock) {
|
|
551
|
+
var _this = this;
|
|
552
|
+
if (latestMainnetBlock === void 0) { latestMainnetBlock = Number.MAX_SAFE_INTEGER; }
|
|
553
|
+
return this.proposedRootBundles.filter(function (rootBundle) {
|
|
433
554
|
if (rootBundle.blockNumber > latestMainnetBlock) {
|
|
434
555
|
return false;
|
|
435
556
|
}
|
|
436
|
-
return
|
|
557
|
+
return _this.isRootBundleValid(rootBundle, latestMainnetBlock);
|
|
437
558
|
});
|
|
438
|
-
}
|
|
439
|
-
getLatestFullyExecutedRootBundle(latestMainnetBlock) {
|
|
559
|
+
};
|
|
560
|
+
HubPoolClient.prototype.getLatestFullyExecutedRootBundle = function (latestMainnetBlock) {
|
|
561
|
+
var _this = this;
|
|
440
562
|
// Search for latest ProposeRootBundleExecuted event followed by all of its RootBundleExecuted event suggesting
|
|
441
563
|
// that all pool rebalance leaves were executed. This ignores any proposed bundles that were partially executed.
|
|
442
|
-
return _.findLast(this.proposedRootBundles, (rootBundle)
|
|
564
|
+
return _.findLast(this.proposedRootBundles, function (rootBundle) {
|
|
443
565
|
if (rootBundle.blockNumber > latestMainnetBlock) {
|
|
444
566
|
return false;
|
|
445
567
|
}
|
|
446
|
-
return
|
|
568
|
+
return _this.isRootBundleValid(rootBundle, latestMainnetBlock);
|
|
447
569
|
});
|
|
448
|
-
}
|
|
449
|
-
getEarliestFullyExecutedRootBundle(latestMainnetBlock, startBlock
|
|
450
|
-
|
|
570
|
+
};
|
|
571
|
+
HubPoolClient.prototype.getEarliestFullyExecutedRootBundle = function (latestMainnetBlock, startBlock) {
|
|
572
|
+
var _this = this;
|
|
573
|
+
if (startBlock === void 0) { startBlock = 0; }
|
|
574
|
+
return this.proposedRootBundles.find(function (rootBundle) {
|
|
451
575
|
if (rootBundle.blockNumber > latestMainnetBlock) {
|
|
452
576
|
return false;
|
|
453
577
|
}
|
|
454
578
|
if (rootBundle.blockNumber < startBlock) {
|
|
455
579
|
return false;
|
|
456
580
|
}
|
|
457
|
-
return
|
|
581
|
+
return _this.isRootBundleValid(rootBundle, latestMainnetBlock);
|
|
458
582
|
});
|
|
459
|
-
}
|
|
583
|
+
};
|
|
460
584
|
// If n is negative, then return the Nth latest executed bundle, otherwise return the Nth earliest
|
|
461
585
|
// executed bundle. Latest means most recent, earliest means oldest. N cannot be 0.
|
|
462
586
|
// `startBlock` can be used to set the starting point from which we look forwards or backwards, depending
|
|
463
587
|
// on whether n is positive or negative.
|
|
464
|
-
getNthFullyExecutedRootBundle(n, startBlock) {
|
|
588
|
+
HubPoolClient.prototype.getNthFullyExecutedRootBundle = function (n, startBlock) {
|
|
465
589
|
if (n === 0) {
|
|
466
590
|
throw new Error("n cannot be 0");
|
|
467
591
|
}
|
|
468
592
|
if (!this.latestHeightSearched) {
|
|
469
593
|
throw new Error("HubPoolClient::getNthFullyExecutedRootBundle client not updated");
|
|
470
594
|
}
|
|
471
|
-
|
|
595
|
+
var bundleToReturn;
|
|
472
596
|
// If n is negative, then return the Nth latest executed bundle, otherwise return the Nth earliest
|
|
473
597
|
// executed bundle.
|
|
474
598
|
if (n < 0) {
|
|
475
|
-
|
|
476
|
-
for (
|
|
599
|
+
var nextLatestMainnetBlock = startBlock !== null && startBlock !== void 0 ? startBlock : this.latestHeightSearched;
|
|
600
|
+
for (var i = 0; i < Math.abs(n); i++) {
|
|
477
601
|
bundleToReturn = this.getLatestFullyExecutedRootBundle(nextLatestMainnetBlock);
|
|
478
|
-
|
|
602
|
+
var bundleBlockNumber = bundleToReturn ? bundleToReturn.blockNumber : 0;
|
|
479
603
|
// Subtract 1 so that next `getLatestFullyExecutedRootBundle` call filters out the root bundle we just found
|
|
480
604
|
// because its block number is > nextLatestMainnetBlock.
|
|
481
605
|
nextLatestMainnetBlock = Math.max(0, bundleBlockNumber - 1);
|
|
482
606
|
}
|
|
483
607
|
}
|
|
484
608
|
else {
|
|
485
|
-
|
|
486
|
-
for (
|
|
609
|
+
var nextStartBlock = startBlock !== null && startBlock !== void 0 ? startBlock : 0;
|
|
610
|
+
for (var i = 0; i < n; i++) {
|
|
487
611
|
bundleToReturn = this.getEarliestFullyExecutedRootBundle(this.latestHeightSearched, nextStartBlock);
|
|
488
|
-
|
|
612
|
+
var bundleBlockNumber = bundleToReturn ? bundleToReturn.blockNumber : 0;
|
|
489
613
|
// Add 1 so that next `getEarliestFullyExecutedRootBundle` call filters out the root bundle we just found
|
|
490
614
|
// because its block number is < nextStartBlock.
|
|
491
615
|
nextStartBlock = Math.min(bundleBlockNumber + 1, this.latestHeightSearched);
|
|
492
616
|
}
|
|
493
617
|
}
|
|
494
618
|
return bundleToReturn;
|
|
495
|
-
}
|
|
496
|
-
getLatestBundleEndBlockForChain(chainIdList, latestMainnetBlock, chainId) {
|
|
497
|
-
|
|
619
|
+
};
|
|
620
|
+
HubPoolClient.prototype.getLatestBundleEndBlockForChain = function (chainIdList, latestMainnetBlock, chainId) {
|
|
621
|
+
var latestFullyExecutedPoolRebalanceRoot = this.getLatestFullyExecutedRootBundle(latestMainnetBlock);
|
|
498
622
|
// If no event, then we can return a conservative default starting block like 0,
|
|
499
623
|
// or we could throw an Error.
|
|
500
624
|
if (!latestFullyExecutedPoolRebalanceRoot) {
|
|
@@ -504,308 +628,341 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
504
628
|
// bundleEvaluationBlockNumbers array using CHAIN_ID_LIST. For each chainId, their starting block number is that
|
|
505
629
|
// chain's bundleEvaluationBlockNumber + 1 in this past proposal event.
|
|
506
630
|
return this.getBundleEndBlockForChain(latestFullyExecutedPoolRebalanceRoot, chainId, chainIdList);
|
|
507
|
-
}
|
|
508
|
-
getNextBundleStartBlockNumber(chainIdList, latestMainnetBlock, chainId) {
|
|
509
|
-
|
|
631
|
+
};
|
|
632
|
+
HubPoolClient.prototype.getNextBundleStartBlockNumber = function (chainIdList, latestMainnetBlock, chainId) {
|
|
633
|
+
var endBlock = this.getLatestBundleEndBlockForChain(chainIdList, latestMainnetBlock, chainId);
|
|
510
634
|
// This assumes that chain ID's are only added to the chain ID list over time, and that chains are never
|
|
511
635
|
// deleted.
|
|
512
636
|
return endBlock > 0 ? endBlock + 1 : 0;
|
|
513
|
-
}
|
|
637
|
+
};
|
|
514
638
|
// @dev Returns the start block of the next bundle assuming that if there is a currently outstanding root bundle proposal, it will pass liveness.
|
|
515
|
-
getOptimisticBundleStartBlockNumber(chainIdList, latestMainnetBlock, chainId) {
|
|
639
|
+
HubPoolClient.prototype.getOptimisticBundleStartBlockNumber = function (chainIdList, latestMainnetBlock, chainId) {
|
|
516
640
|
// If there is no pending root bundle, then return block ranges based on the latest fully executed root bundle.
|
|
517
641
|
if (!this.hasPendingProposal()) {
|
|
518
642
|
return this.getNextBundleStartBlockNumber(chainIdList, latestMainnetBlock, chainId);
|
|
519
643
|
}
|
|
520
644
|
// We cannot normally index `this.proposedRootBundles` since a bundle there may have been previously disputed, so only index `this.proposedRootBundles`
|
|
521
645
|
// if we have a pending proposal, since this must mean that the pending root bundle is the most recent proposed root bundle.
|
|
522
|
-
|
|
646
|
+
var latestProposedBundle = this.proposedRootBundles[this.proposedRootBundles.length - 1];
|
|
523
647
|
// If there is no previous root bundle, then return 0.
|
|
524
648
|
if (!isDefined(latestProposedBundle)) {
|
|
525
649
|
return 0;
|
|
526
650
|
}
|
|
527
651
|
// Otherwise, get the bundle end block for the optimistic bundle.
|
|
528
|
-
|
|
652
|
+
var optimisticEndBlock = this.getBundleEndBlockForChain(latestProposedBundle, chainId, chainIdList);
|
|
529
653
|
// As above, this assumes that chain ID's are only added to the chain ID list over time, and that chains are never
|
|
530
654
|
// deleted.
|
|
531
655
|
return optimisticEndBlock > 0 ? optimisticEndBlock + 1 : 0;
|
|
532
|
-
}
|
|
533
|
-
getLatestExecutedRootBundleContainingL1Token(block, chain, l1Token) {
|
|
656
|
+
};
|
|
657
|
+
HubPoolClient.prototype.getLatestExecutedRootBundleContainingL1Token = function (block, chain, l1Token) {
|
|
534
658
|
// Search ExecutedRootBundles in descending block order to find the most recent event before the target block.
|
|
535
|
-
return sortEventsDescending(this.executedRootBundles).find((executedLeaf)
|
|
659
|
+
return sortEventsDescending(this.executedRootBundles).find(function (executedLeaf) {
|
|
536
660
|
return (executedLeaf.blockNumber <= block &&
|
|
537
661
|
executedLeaf.chainId === chain &&
|
|
538
|
-
executedLeaf.l1Tokens.some((token)
|
|
662
|
+
executedLeaf.l1Tokens.some(function (token) { return token.eq(l1Token); }));
|
|
539
663
|
});
|
|
540
|
-
}
|
|
541
|
-
getRunningBalanceBeforeBlockForChain(block, chain, l1Token) {
|
|
542
|
-
|
|
664
|
+
};
|
|
665
|
+
HubPoolClient.prototype.getRunningBalanceBeforeBlockForChain = function (block, chain, l1Token) {
|
|
666
|
+
var executedRootBundle = this.getLatestExecutedRootBundleContainingL1Token(block, chain, l1Token);
|
|
543
667
|
return this.getRunningBalanceForToken(l1Token, executedRootBundle);
|
|
544
|
-
}
|
|
545
|
-
getRunningBalanceForToken(l1Token, executedRootBundle) {
|
|
546
|
-
|
|
668
|
+
};
|
|
669
|
+
HubPoolClient.prototype.getRunningBalanceForToken = function (l1Token, executedRootBundle) {
|
|
670
|
+
var runningBalance = toBN(0);
|
|
547
671
|
if (executedRootBundle) {
|
|
548
|
-
|
|
672
|
+
var indexOfL1Token = executedRootBundle.l1Tokens.findIndex(function (tokenInBundle) { return tokenInBundle.eq(l1Token); });
|
|
549
673
|
if (indexOfL1Token !== -1) {
|
|
550
674
|
runningBalance = executedRootBundle.runningBalances[indexOfL1Token];
|
|
551
675
|
}
|
|
552
676
|
}
|
|
553
|
-
return { runningBalance };
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
return
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
}
|
|
620
|
-
// No need to touch `this.isUpdated` because it should already be set from a previous update.
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
const { events, currentTime, pendingRootBundleProposal, searchEndBlock } = update;
|
|
624
|
-
if (eventsToQuery.includes("CrossChainContractsSet")) {
|
|
625
|
-
for (const event of events["CrossChainContractsSet"]) {
|
|
626
|
-
const args = spreadEventWithBlockNumber(event);
|
|
627
|
-
const dataToAdd = {
|
|
628
|
-
spokePool: EvmAddress.from(args.spokePool),
|
|
629
|
-
blockNumber: args.blockNumber,
|
|
630
|
-
txnRef: args.txnRef,
|
|
631
|
-
logIndex: args.logIndex,
|
|
632
|
-
txnIndex: args.txnIndex,
|
|
633
|
-
l2ChainId: args.l2ChainId,
|
|
634
|
-
};
|
|
635
|
-
// If the chain is SVM then the resulting SpokePool address will be inferred based on the lower 20
|
|
636
|
-
// bytes of the address. Matching addresses will be promoted to a full 32-byte SvmAddress type.
|
|
637
|
-
if (chainIsSvm(args.l2ChainId)) {
|
|
638
|
-
const solanaSpokePool = getDeployedAddress("SvmSpoke", args.l2ChainId);
|
|
639
|
-
if (!solanaSpokePool) {
|
|
640
|
-
throw new Error(`SVM spoke pool not found for chain ${args.l2ChainId}`);
|
|
641
|
-
}
|
|
642
|
-
const svmSpoke = SvmAddress.from(solanaSpokePool);
|
|
643
|
-
const truncatedAddress = svmSpoke.truncateToBytes20();
|
|
644
|
-
// Verify the event address matches our expected truncated address
|
|
645
|
-
if (args.spokePool.toLowerCase() !== truncatedAddress.toLowerCase()) {
|
|
646
|
-
throw new Error(`SVM spoke pool address mismatch for chain ${args.l2ChainId}. ` +
|
|
647
|
-
`Expected ${truncatedAddress}, got ${args.spokePool}`);
|
|
648
|
-
}
|
|
649
|
-
dataToAdd.spokePool = svmSpoke;
|
|
650
|
-
}
|
|
651
|
-
assign(this.crossChainContracts, [args.l2ChainId], [dataToAdd]);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
if (eventsToQuery.includes("SetPoolRebalanceRoute")) {
|
|
655
|
-
for (const event of events["SetPoolRebalanceRoute"]) {
|
|
656
|
-
const args = spreadEventWithBlockNumber(event);
|
|
657
|
-
// If the destination chain is SVM, then we need to convert the destination token to the Solana address.
|
|
658
|
-
// This is because the HubPool contract only holds a truncated address for the USDC token and currently
|
|
659
|
-
// only supports USDC as a destination token for Solana.
|
|
660
|
-
let destinationToken = EvmAddress.from(args.destinationToken);
|
|
661
|
-
if (chainIsSvm(args.destinationChainId)) {
|
|
662
|
-
const usdcTokenSol = TOKEN_SYMBOLS_MAP.USDC.addresses[args.destinationChainId];
|
|
663
|
-
const svmUsdc = SvmAddress.from(usdcTokenSol);
|
|
664
|
-
if (destinationToken.truncateToBytes20() !== svmUsdc.truncateToBytes20()) {
|
|
665
|
-
throw new Error(`SVM USDC address mismatch for chain ${args.destinationChainId}. ` +
|
|
666
|
-
`Expected ${svmUsdc.truncateToBytes20()}, got ${destinationToken}`);
|
|
667
|
-
}
|
|
668
|
-
destinationToken = svmUsdc;
|
|
669
|
-
}
|
|
670
|
-
const newRoute = {
|
|
671
|
-
l1Token: EvmAddress.from(args.l1Token),
|
|
672
|
-
l2Token: destinationToken,
|
|
673
|
-
blockNumber: args.blockNumber,
|
|
674
|
-
txnIndex: args.txnIndex,
|
|
675
|
-
logIndex: args.logIndex,
|
|
676
|
-
txnRef: args.txnRef,
|
|
677
|
-
};
|
|
678
|
-
if (this.l1TokensToDestinationTokensWithBlock[args.l1Token]?.[args.destinationChainId]) {
|
|
679
|
-
// Events are most likely coming in descending orders already but just in case we sort them again.
|
|
680
|
-
this.l1TokensToDestinationTokensWithBlock[args.l1Token][args.destinationChainId] = sortEventsDescending([
|
|
681
|
-
...this.l1TokensToDestinationTokensWithBlock[args.l1Token][args.destinationChainId],
|
|
682
|
-
newRoute,
|
|
683
|
-
]);
|
|
684
|
-
}
|
|
685
|
-
else {
|
|
686
|
-
assign(this.l1TokensToDestinationTokensWithBlock, [args.l1Token, args.destinationChainId], [newRoute]);
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
// For each enabled Lp token fetch the token symbol and decimals from the token contract. Note this logic will
|
|
691
|
-
// only run iff a new token has been enabled. Will only append iff the info is not there already.
|
|
692
|
-
// Filter out any duplicate addresses. This might happen due to enabling, disabling and re-enabling a token.
|
|
693
|
-
if (eventsToQuery.includes("L1TokenEnabledForLiquidityProvision")) {
|
|
694
|
-
const uniqueL1Tokens = dedupArray(events["L1TokenEnabledForLiquidityProvision"].map((event) => String(event.args["l1Token"])));
|
|
695
|
-
const [tokenInfo, lpTokenInfo] = await Promise.all([
|
|
696
|
-
Promise.all(uniqueL1Tokens.map(async (l1Token) => {
|
|
697
|
-
const tokenInfo = await fetchTokenInfo(l1Token, this.hubPool.provider);
|
|
698
|
-
return {
|
|
699
|
-
...tokenInfo,
|
|
700
|
-
address: EvmAddress.from(l1Token),
|
|
701
|
-
};
|
|
702
|
-
})),
|
|
703
|
-
Promise.all(uniqueL1Tokens.map(async (l1Token) => await this.hubPool.pooledTokens(l1Token, { blockTag: update.searchEndBlock }))),
|
|
704
|
-
]);
|
|
705
|
-
for (const info of tokenInfo) {
|
|
706
|
-
if (!this.l1Tokens.find((token) => token.address.eq(info.address))) {
|
|
707
|
-
if (info.decimals > 0 && info.decimals <= 18) {
|
|
708
|
-
this.l1Tokens.push(info);
|
|
709
|
-
}
|
|
710
|
-
else {
|
|
711
|
-
throw new Error(`Unsupported HubPool token: ${JSON.stringify(info)}`);
|
|
712
|
-
}
|
|
677
|
+
return { runningBalance: runningBalance };
|
|
678
|
+
};
|
|
679
|
+
HubPoolClient.prototype._update = function (eventNames) {
|
|
680
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
681
|
+
var hubPoolEvents, searchConfig, supportedEvents, eventSearchConfigs, timerStart, hubPool, multicallFunctions, _a, multicallOutput, events, _b, currentTime, pendingRootBundleProposal, _events;
|
|
682
|
+
var _this = this;
|
|
683
|
+
return __generator(this, function (_c) {
|
|
684
|
+
switch (_c.label) {
|
|
685
|
+
case 0:
|
|
686
|
+
hubPoolEvents = this.hubPoolEventFilters();
|
|
687
|
+
return [4 /*yield*/, this.updateSearchConfig(this.hubPool.provider)];
|
|
688
|
+
case 1:
|
|
689
|
+
searchConfig = _c.sent();
|
|
690
|
+
if (isUpdateFailureReason(searchConfig)) {
|
|
691
|
+
return [2 /*return*/, { success: false, reason: searchConfig }];
|
|
692
|
+
}
|
|
693
|
+
supportedEvents = Object.keys(hubPoolEvents);
|
|
694
|
+
if (eventNames.some(function (eventName) { return !supportedEvents.includes(eventName); })) {
|
|
695
|
+
return [2 /*return*/, { success: false, reason: UpdateFailureReason.BadRequest }];
|
|
696
|
+
}
|
|
697
|
+
eventSearchConfigs = eventNames.map(function (eventName) {
|
|
698
|
+
var _searchConfig = __assign({}, searchConfig); // shallow copy
|
|
699
|
+
// By default, an event's query range is controlled by the `searchConfig` passed in during
|
|
700
|
+
// instantiation. However, certain events generally must be queried back to HubPool genesis.
|
|
701
|
+
var overrideEvents = ["CrossChainContractsSet", "L1TokenEnabledForLiquidityProvision", "SetPoolRebalanceRoute"];
|
|
702
|
+
if (overrideEvents.includes(eventName) && !_this.isUpdated) {
|
|
703
|
+
_searchConfig.from = _this.deploymentBlock;
|
|
704
|
+
}
|
|
705
|
+
return {
|
|
706
|
+
eventName: eventName,
|
|
707
|
+
filter: hubPoolEvents[eventName],
|
|
708
|
+
searchConfig: _searchConfig,
|
|
709
|
+
};
|
|
710
|
+
});
|
|
711
|
+
this.logger.debug({
|
|
712
|
+
at: "HubPoolClient",
|
|
713
|
+
message: "Updating HubPool client",
|
|
714
|
+
searchConfig: eventSearchConfigs.map(function (_a) {
|
|
715
|
+
var eventName = _a.eventName, searchConfig = _a.searchConfig;
|
|
716
|
+
return ({ eventName: eventName, searchConfig: searchConfig });
|
|
717
|
+
}),
|
|
718
|
+
});
|
|
719
|
+
timerStart = Date.now();
|
|
720
|
+
hubPool = this.hubPool;
|
|
721
|
+
multicallFunctions = ["getCurrentTime", "rootBundleProposal"];
|
|
722
|
+
return [4 /*yield*/, Promise.all(__spreadArray([
|
|
723
|
+
hubPool.callStatic.multicall(multicallFunctions.map(function (f) { return hubPool.interface.encodeFunctionData(f); }), { blockTag: searchConfig.to })
|
|
724
|
+
], eventSearchConfigs.map(function (config) { return paginatedEventQuery(hubPool, config.filter, config.searchConfig); }), true))];
|
|
725
|
+
case 2:
|
|
726
|
+
_a = _c.sent(), multicallOutput = _a[0], events = _a.slice(1);
|
|
727
|
+
_b = multicallFunctions.map(function (fn, idx) {
|
|
728
|
+
var output = hubPool.interface.decodeFunctionResult(fn, multicallOutput[idx]);
|
|
729
|
+
return output.length > 1 ? output : output[0];
|
|
730
|
+
}), currentTime = _b[0], pendingRootBundleProposal = _b[1];
|
|
731
|
+
this.logger.debug({
|
|
732
|
+
at: "HubPoolClient#_update",
|
|
733
|
+
message: "Time to query new events from RPC for ".concat(this.chainId, ": ").concat(Date.now() - timerStart, " ms"),
|
|
734
|
+
});
|
|
735
|
+
_events = Object.fromEntries(eventNames.map(function (eventName, idx) { return [eventName, events[idx]]; }));
|
|
736
|
+
return [2 /*return*/, {
|
|
737
|
+
success: true,
|
|
738
|
+
currentTime: currentTime,
|
|
739
|
+
pendingRootBundleProposal: __assign(__assign({}, pendingRootBundleProposal), { proposer: EvmAddress.from(pendingRootBundleProposal.proposer) }),
|
|
740
|
+
searchEndBlock: searchConfig.to,
|
|
741
|
+
events: _events,
|
|
742
|
+
}];
|
|
713
743
|
}
|
|
714
|
-
}
|
|
715
|
-
uniqueL1Tokens.forEach((token, i) => {
|
|
716
|
-
this.lpTokens[token] = {
|
|
717
|
-
lastLpFeeUpdate: lpTokenInfo[i].lastLpFeeUpdate,
|
|
718
|
-
liquidReserves: lpTokenInfo[i].liquidReserves,
|
|
719
|
-
};
|
|
720
744
|
});
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
}
|
|
736
|
-
if (eventsToQuery.includes("RootBundleDisputed")) {
|
|
737
|
-
this.disputedRootBundles.push(...events["RootBundleDisputed"].map((event) => spreadEventWithBlockNumber(event)));
|
|
738
|
-
}
|
|
739
|
-
if (eventsToQuery.includes("RootBundleExecuted")) {
|
|
740
|
-
for (const event of events["RootBundleExecuted"]) {
|
|
741
|
-
if (this.configOverride.ignoredHubExecutedBundles.includes(event.blockNumber)) {
|
|
742
|
-
continue;
|
|
743
|
-
}
|
|
744
|
-
// Set running balances and incentive balances for this bundle.
|
|
745
|
-
const executedRootBundle = spreadEventWithBlockNumber(event);
|
|
746
|
-
const { l1Tokens, runningBalances } = executedRootBundle;
|
|
747
|
-
const nTokens = l1Tokens.length;
|
|
748
|
-
// Safeguard
|
|
749
|
-
if (![nTokens, nTokens * 2].includes(runningBalances.length)) {
|
|
750
|
-
throw new Error(`Invalid runningBalances length: ${runningBalances.length}.` +
|
|
751
|
-
` Expected ${nTokens} or ${nTokens * 2} for chain ${this.chainId} transaction ${event.transactionHash}`);
|
|
752
|
-
}
|
|
753
|
-
executedRootBundle.runningBalances = runningBalances.slice(0, nTokens);
|
|
754
|
-
this.executedRootBundles.push({
|
|
755
|
-
...executedRootBundle,
|
|
756
|
-
l1Tokens: l1Tokens.map((l1Token) => EvmAddress.from(l1Token)),
|
|
757
|
-
});
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
// If the contract's current rootBundleProposal() value has an unclaimedPoolRebalanceLeafCount > 0, then
|
|
761
|
-
// it means that either the root bundle proposal is in the challenge period and can be disputed, or it has
|
|
762
|
-
// passed the challenge period and pool rebalance leaves can be executed. Once all leaves are executed, the
|
|
763
|
-
// unclaimed count will drop to 0 and at that point there is nothing more that we can do with this root bundle
|
|
764
|
-
// besides proposing another one.
|
|
765
|
-
if (eventsToQuery.includes("ProposeRootBundle")) {
|
|
766
|
-
if (pendingRootBundleProposal.unclaimedPoolRebalanceLeafCount > 0) {
|
|
767
|
-
const mostRecentProposedRootBundle = this.proposedRootBundles[this.proposedRootBundles.length - 1];
|
|
768
|
-
this.pendingRootBundle = {
|
|
769
|
-
poolRebalanceRoot: pendingRootBundleProposal.poolRebalanceRoot,
|
|
770
|
-
relayerRefundRoot: pendingRootBundleProposal.relayerRefundRoot,
|
|
771
|
-
slowRelayRoot: pendingRootBundleProposal.slowRelayRoot,
|
|
772
|
-
proposer: pendingRootBundleProposal.proposer,
|
|
773
|
-
unclaimedPoolRebalanceLeafCount: pendingRootBundleProposal.unclaimedPoolRebalanceLeafCount,
|
|
774
|
-
challengePeriodEndTimestamp: pendingRootBundleProposal.challengePeriodEndTimestamp,
|
|
775
|
-
bundleEvaluationBlockNumbers: mostRecentProposedRootBundle.bundleEvaluationBlockNumbers.map((block) => {
|
|
776
|
-
// Ideally, the HubPool.sol contract should limit the size of the elements within the
|
|
777
|
-
// bundleEvaluationBlockNumbers array. But because it doesn't, we wrap the cast of BN --> Number
|
|
778
|
-
// in a try/catch statement and return some value that would always be disputable.
|
|
779
|
-
// This catches the denial of service attack vector where a malicious proposer proposes with bundle block
|
|
780
|
-
// evaluation block numbers larger than what BigNumber::toNumber() can handle.
|
|
781
|
-
try {
|
|
782
|
-
return block.toNumber();
|
|
745
|
+
});
|
|
746
|
+
};
|
|
747
|
+
HubPoolClient.prototype.update = function () {
|
|
748
|
+
return __awaiter(this, arguments, void 0, function (eventsToQuery) {
|
|
749
|
+
var update, events, currentTime, pendingRootBundleProposal, searchEndBlock, _i, _a, event_1, args, dataToAdd, solanaSpokePool, svmSpoke, truncatedAddress, _b, _c, event_2, args, destinationToken, usdcTokenSol, svmUsdc, newRoute, uniqueL1Tokens, _d, tokenInfo, lpTokenInfo_1, _loop_1, this_1, _e, tokenInfo_1, info, _f, _g, event_3, executedRootBundle, l1Tokens, runningBalances, nTokens, mostRecentProposedRootBundle;
|
|
750
|
+
var _h, _j, _k;
|
|
751
|
+
var _this = this;
|
|
752
|
+
var _l;
|
|
753
|
+
if (eventsToQuery === void 0) { eventsToQuery = Object.keys(this.hubPoolEventFilters()); }
|
|
754
|
+
return __generator(this, function (_m) {
|
|
755
|
+
switch (_m.label) {
|
|
756
|
+
case 0:
|
|
757
|
+
if (!this.configStoreClient.isUpdated) {
|
|
758
|
+
throw new Error("ConfigStoreClient not updated");
|
|
783
759
|
}
|
|
784
|
-
|
|
785
|
-
|
|
760
|
+
return [4 /*yield*/, this._update(eventsToQuery)];
|
|
761
|
+
case 1:
|
|
762
|
+
update = _m.sent();
|
|
763
|
+
if (!update.success) {
|
|
764
|
+
if (update.reason !== UpdateFailureReason.AlreadyUpdated) {
|
|
765
|
+
throw new Error("Unable to update HubPoolClient: ".concat(update.reason));
|
|
766
|
+
}
|
|
767
|
+
// No need to touch `this.isUpdated` because it should already be set from a previous update.
|
|
768
|
+
return [2 /*return*/];
|
|
786
769
|
}
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
770
|
+
events = update.events, currentTime = update.currentTime, pendingRootBundleProposal = update.pendingRootBundleProposal, searchEndBlock = update.searchEndBlock;
|
|
771
|
+
if (eventsToQuery.includes("CrossChainContractsSet")) {
|
|
772
|
+
for (_i = 0, _a = events["CrossChainContractsSet"]; _i < _a.length; _i++) {
|
|
773
|
+
event_1 = _a[_i];
|
|
774
|
+
args = spreadEventWithBlockNumber(event_1);
|
|
775
|
+
dataToAdd = {
|
|
776
|
+
spokePool: EvmAddress.from(args.spokePool),
|
|
777
|
+
blockNumber: args.blockNumber,
|
|
778
|
+
txnRef: args.txnRef,
|
|
779
|
+
logIndex: args.logIndex,
|
|
780
|
+
txnIndex: args.txnIndex,
|
|
781
|
+
l2ChainId: args.l2ChainId,
|
|
782
|
+
};
|
|
783
|
+
// If the chain is SVM then the resulting SpokePool address will be inferred based on the lower 20
|
|
784
|
+
// bytes of the address. Matching addresses will be promoted to a full 32-byte SvmAddress type.
|
|
785
|
+
if (chainIsSvm(args.l2ChainId)) {
|
|
786
|
+
solanaSpokePool = getDeployedAddress("SvmSpoke", args.l2ChainId);
|
|
787
|
+
if (!solanaSpokePool) {
|
|
788
|
+
throw new Error("SVM spoke pool not found for chain ".concat(args.l2ChainId));
|
|
789
|
+
}
|
|
790
|
+
svmSpoke = SvmAddress.from(solanaSpokePool);
|
|
791
|
+
truncatedAddress = svmSpoke.truncateToBytes20();
|
|
792
|
+
// Verify the event address matches our expected truncated address
|
|
793
|
+
if (args.spokePool.toLowerCase() !== truncatedAddress.toLowerCase()) {
|
|
794
|
+
throw new Error("SVM spoke pool address mismatch for chain ".concat(args.l2ChainId, ". ") +
|
|
795
|
+
"Expected ".concat(truncatedAddress, ", got ").concat(args.spokePool));
|
|
796
|
+
}
|
|
797
|
+
dataToAdd.spokePool = svmSpoke;
|
|
798
|
+
}
|
|
799
|
+
assign(this.crossChainContracts, [args.l2ChainId], [dataToAdd]);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
if (eventsToQuery.includes("SetPoolRebalanceRoute")) {
|
|
803
|
+
for (_b = 0, _c = events["SetPoolRebalanceRoute"]; _b < _c.length; _b++) {
|
|
804
|
+
event_2 = _c[_b];
|
|
805
|
+
args = spreadEventWithBlockNumber(event_2);
|
|
806
|
+
destinationToken = EvmAddress.from(args.destinationToken);
|
|
807
|
+
if (chainIsSvm(args.destinationChainId)) {
|
|
808
|
+
usdcTokenSol = TOKEN_SYMBOLS_MAP.USDC.addresses[args.destinationChainId];
|
|
809
|
+
svmUsdc = SvmAddress.from(usdcTokenSol);
|
|
810
|
+
if (destinationToken.truncateToBytes20() !== svmUsdc.truncateToBytes20()) {
|
|
811
|
+
throw new Error("SVM USDC address mismatch for chain ".concat(args.destinationChainId, ". ") +
|
|
812
|
+
"Expected ".concat(svmUsdc.truncateToBytes20(), ", got ").concat(destinationToken));
|
|
813
|
+
}
|
|
814
|
+
destinationToken = svmUsdc;
|
|
815
|
+
}
|
|
816
|
+
newRoute = {
|
|
817
|
+
l1Token: EvmAddress.from(args.l1Token),
|
|
818
|
+
l2Token: destinationToken,
|
|
819
|
+
blockNumber: args.blockNumber,
|
|
820
|
+
txnIndex: args.txnIndex,
|
|
821
|
+
logIndex: args.logIndex,
|
|
822
|
+
txnRef: args.txnRef,
|
|
823
|
+
};
|
|
824
|
+
if ((_l = this.l1TokensToDestinationTokensWithBlock[args.l1Token]) === null || _l === void 0 ? void 0 : _l[args.destinationChainId]) {
|
|
825
|
+
// Events are most likely coming in descending orders already but just in case we sort them again.
|
|
826
|
+
this.l1TokensToDestinationTokensWithBlock[args.l1Token][args.destinationChainId] = sortEventsDescending(__spreadArray(__spreadArray([], this.l1TokensToDestinationTokensWithBlock[args.l1Token][args.destinationChainId], true), [
|
|
827
|
+
newRoute,
|
|
828
|
+
], false));
|
|
829
|
+
}
|
|
830
|
+
else {
|
|
831
|
+
assign(this.l1TokensToDestinationTokensWithBlock, [args.l1Token, args.destinationChainId], [newRoute]);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (!eventsToQuery.includes("L1TokenEnabledForLiquidityProvision")) return [3 /*break*/, 3];
|
|
836
|
+
uniqueL1Tokens = dedupArray(events["L1TokenEnabledForLiquidityProvision"].map(function (event) { return String(event.args["l1Token"]); }));
|
|
837
|
+
return [4 /*yield*/, Promise.all([
|
|
838
|
+
Promise.all(uniqueL1Tokens.map(function (l1Token) { return __awaiter(_this, void 0, void 0, function () {
|
|
839
|
+
var tokenInfo;
|
|
840
|
+
return __generator(this, function (_a) {
|
|
841
|
+
switch (_a.label) {
|
|
842
|
+
case 0: return [4 /*yield*/, fetchTokenInfo(l1Token, this.hubPool.provider)];
|
|
843
|
+
case 1:
|
|
844
|
+
tokenInfo = _a.sent();
|
|
845
|
+
return [2 /*return*/, __assign(__assign({}, tokenInfo), { address: EvmAddress.from(l1Token) })];
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
}); })),
|
|
849
|
+
Promise.all(uniqueL1Tokens.map(function (l1Token) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
850
|
+
switch (_a.label) {
|
|
851
|
+
case 0: return [4 /*yield*/, this.hubPool.pooledTokens(l1Token, { blockTag: update.searchEndBlock })];
|
|
852
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
853
|
+
}
|
|
854
|
+
}); }); })),
|
|
855
|
+
])];
|
|
856
|
+
case 2:
|
|
857
|
+
_d = _m.sent(), tokenInfo = _d[0], lpTokenInfo_1 = _d[1];
|
|
858
|
+
_loop_1 = function (info) {
|
|
859
|
+
if (!this_1.l1Tokens.find(function (token) { return token.address.eq(info.address); })) {
|
|
860
|
+
if (info.decimals > 0 && info.decimals <= 18) {
|
|
861
|
+
this_1.l1Tokens.push(info);
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
throw new Error("Unsupported HubPool token: ".concat(JSON.stringify(info)));
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
this_1 = this;
|
|
869
|
+
for (_e = 0, tokenInfo_1 = tokenInfo; _e < tokenInfo_1.length; _e++) {
|
|
870
|
+
info = tokenInfo_1[_e];
|
|
871
|
+
_loop_1(info);
|
|
872
|
+
}
|
|
873
|
+
uniqueL1Tokens.forEach(function (token, i) {
|
|
874
|
+
_this.lpTokens[token] = {
|
|
875
|
+
lastLpFeeUpdate: lpTokenInfo_1[i].lastLpFeeUpdate,
|
|
876
|
+
liquidReserves: lpTokenInfo_1[i].liquidReserves,
|
|
877
|
+
};
|
|
878
|
+
});
|
|
879
|
+
_m.label = 3;
|
|
880
|
+
case 3:
|
|
881
|
+
if (eventsToQuery.includes("ProposeRootBundle")) {
|
|
882
|
+
(_h = this.proposedRootBundles).push.apply(_h, events["ProposeRootBundle"]
|
|
883
|
+
.filter(function (event) { return !_this.configOverride.ignoredHubProposedBundles.includes(event.blockNumber); })
|
|
884
|
+
.map(function (_event) {
|
|
885
|
+
var args = spreadEventWithBlockNumber(_event);
|
|
886
|
+
return __assign(__assign({}, args), { proposer: EvmAddress.from(args.proposer) });
|
|
887
|
+
}));
|
|
888
|
+
}
|
|
889
|
+
if (eventsToQuery.includes("RootBundleCanceled")) {
|
|
890
|
+
(_j = this.canceledRootBundles).push.apply(_j, events["RootBundleCanceled"].map(function (event) { return spreadEventWithBlockNumber(event); }));
|
|
891
|
+
}
|
|
892
|
+
if (eventsToQuery.includes("RootBundleDisputed")) {
|
|
893
|
+
(_k = this.disputedRootBundles).push.apply(_k, events["RootBundleDisputed"].map(function (event) { return spreadEventWithBlockNumber(event); }));
|
|
894
|
+
}
|
|
895
|
+
if (eventsToQuery.includes("RootBundleExecuted")) {
|
|
896
|
+
for (_f = 0, _g = events["RootBundleExecuted"]; _f < _g.length; _f++) {
|
|
897
|
+
event_3 = _g[_f];
|
|
898
|
+
if (this.configOverride.ignoredHubExecutedBundles.includes(event_3.blockNumber)) {
|
|
899
|
+
continue;
|
|
900
|
+
}
|
|
901
|
+
executedRootBundle = spreadEventWithBlockNumber(event_3);
|
|
902
|
+
l1Tokens = executedRootBundle.l1Tokens, runningBalances = executedRootBundle.runningBalances;
|
|
903
|
+
nTokens = l1Tokens.length;
|
|
904
|
+
// Safeguard
|
|
905
|
+
if (![nTokens, nTokens * 2].includes(runningBalances.length)) {
|
|
906
|
+
throw new Error("Invalid runningBalances length: ".concat(runningBalances.length, ".") +
|
|
907
|
+
" Expected ".concat(nTokens, " or ").concat(nTokens * 2, " for chain ").concat(this.chainId, " transaction ").concat(event_3.transactionHash));
|
|
908
|
+
}
|
|
909
|
+
executedRootBundle.runningBalances = runningBalances.slice(0, nTokens);
|
|
910
|
+
this.executedRootBundles.push(__assign(__assign({}, executedRootBundle), { l1Tokens: l1Tokens.map(function (l1Token) { return EvmAddress.from(l1Token); }) }));
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
// If the contract's current rootBundleProposal() value has an unclaimedPoolRebalanceLeafCount > 0, then
|
|
914
|
+
// it means that either the root bundle proposal is in the challenge period and can be disputed, or it has
|
|
915
|
+
// passed the challenge period and pool rebalance leaves can be executed. Once all leaves are executed, the
|
|
916
|
+
// unclaimed count will drop to 0 and at that point there is nothing more that we can do with this root bundle
|
|
917
|
+
// besides proposing another one.
|
|
918
|
+
if (eventsToQuery.includes("ProposeRootBundle")) {
|
|
919
|
+
if (pendingRootBundleProposal.unclaimedPoolRebalanceLeafCount > 0) {
|
|
920
|
+
mostRecentProposedRootBundle = this.proposedRootBundles[this.proposedRootBundles.length - 1];
|
|
921
|
+
this.pendingRootBundle = {
|
|
922
|
+
poolRebalanceRoot: pendingRootBundleProposal.poolRebalanceRoot,
|
|
923
|
+
relayerRefundRoot: pendingRootBundleProposal.relayerRefundRoot,
|
|
924
|
+
slowRelayRoot: pendingRootBundleProposal.slowRelayRoot,
|
|
925
|
+
proposer: pendingRootBundleProposal.proposer,
|
|
926
|
+
unclaimedPoolRebalanceLeafCount: pendingRootBundleProposal.unclaimedPoolRebalanceLeafCount,
|
|
927
|
+
challengePeriodEndTimestamp: pendingRootBundleProposal.challengePeriodEndTimestamp,
|
|
928
|
+
bundleEvaluationBlockNumbers: mostRecentProposedRootBundle.bundleEvaluationBlockNumbers.map(function (block) {
|
|
929
|
+
// Ideally, the HubPool.sol contract should limit the size of the elements within the
|
|
930
|
+
// bundleEvaluationBlockNumbers array. But because it doesn't, we wrap the cast of BN --> Number
|
|
931
|
+
// in a try/catch statement and return some value that would always be disputable.
|
|
932
|
+
// This catches the denial of service attack vector where a malicious proposer proposes with bundle block
|
|
933
|
+
// evaluation block numbers larger than what BigNumber::toNumber() can handle.
|
|
934
|
+
try {
|
|
935
|
+
return block.toNumber();
|
|
936
|
+
}
|
|
937
|
+
catch (_a) {
|
|
938
|
+
return 0;
|
|
939
|
+
}
|
|
940
|
+
}),
|
|
941
|
+
proposalBlockNumber: mostRecentProposedRootBundle.blockNumber,
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
else {
|
|
945
|
+
this.pendingRootBundle = undefined;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
this.currentTime = currentTime;
|
|
949
|
+
this.latestHeightSearched = searchEndBlock;
|
|
950
|
+
this.firstHeightToSearch = update.searchEndBlock + 1; // Next iteration should start off from where this one ended.
|
|
951
|
+
this.eventSearchConfig.to = undefined; // Caller can re-set on subsequent updates if necessary.
|
|
952
|
+
this.isUpdated = true;
|
|
953
|
+
this.logger.debug({ at: "HubPoolClient::update", message: "HubPool client updated!", searchEndBlock: searchEndBlock, currentTime: currentTime });
|
|
954
|
+
return [2 /*return*/];
|
|
955
|
+
}
|
|
956
|
+
});
|
|
957
|
+
});
|
|
958
|
+
};
|
|
802
959
|
// Returns end block for `chainId` in ProposedRootBundle.bundleBlockEvalNumbers. Looks up chainId
|
|
803
960
|
// in chainId list, gets the index where its located, and returns the value of the index in
|
|
804
961
|
// bundleBlockEvalNumbers. Returns 0 if `chainId` can't be found in `chainIdList` and if index doesn't
|
|
805
962
|
// exist in bundleBlockEvalNumbers.
|
|
806
|
-
getBundleEndBlockForChain(proposeRootBundleEvent, chainId, chainIdList) {
|
|
807
|
-
|
|
808
|
-
|
|
963
|
+
HubPoolClient.prototype.getBundleEndBlockForChain = function (proposeRootBundleEvent, chainId, chainIdList) {
|
|
964
|
+
var bundleEvaluationBlockNumbers = proposeRootBundleEvent.bundleEvaluationBlockNumbers;
|
|
965
|
+
var chainIdIndex = chainIdList.indexOf(chainId);
|
|
809
966
|
if (chainIdIndex === -1) {
|
|
810
967
|
return 0;
|
|
811
968
|
}
|
|
@@ -816,6 +973,8 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
816
973
|
return 0;
|
|
817
974
|
}
|
|
818
975
|
return bundleEvaluationBlockNumbers[chainIdIndex].toNumber();
|
|
819
|
-
}
|
|
820
|
-
|
|
976
|
+
};
|
|
977
|
+
return HubPoolClient;
|
|
978
|
+
}(BaseAbstractClient));
|
|
979
|
+
export { HubPoolClient };
|
|
821
980
|
//# sourceMappingURL=HubPoolClient.js.map
|