@across-protocol/sdk 4.1.45-beta.0 → 4.1.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +0 -2
  2. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +13 -38
  3. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  4. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +1 -1
  5. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  6. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +2 -3
  7. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +13 -13
  8. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  9. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  10. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js +2 -2
  11. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
  12. package/dist/cjs/clients/HubPoolClient.d.ts +1 -2
  13. package/dist/cjs/clients/HubPoolClient.js +0 -5
  14. package/dist/cjs/clients/HubPoolClient.js.map +1 -1
  15. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +6 -5
  16. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  17. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +0 -2
  18. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +14 -42
  19. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  20. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +1 -1
  21. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  22. package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +2 -3
  23. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +13 -13
  24. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  25. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  26. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js +2 -2
  27. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
  28. package/dist/esm/clients/HubPoolClient.d.ts +1 -16
  29. package/dist/esm/clients/HubPoolClient.js +0 -20
  30. package/dist/esm/clients/HubPoolClient.js.map +1 -1
  31. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +7 -6
  32. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  33. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +0 -2
  34. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  35. package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts.map +1 -1
  36. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +2 -3
  37. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  38. package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  39. package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts.map +1 -1
  40. package/dist/types/clients/HubPoolClient.d.ts +1 -16
  41. package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
  42. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
  43. package/package.json +1 -1
  44. package/src/clients/BundleDataClient/BundleDataClient.ts +19 -49
  45. package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +7 -1
  46. package/src/clients/BundleDataClient/utils/FillUtils.ts +23 -18
  47. package/src/clients/BundleDataClient/utils/PoolRebalanceUtils.ts +3 -2
  48. package/src/clients/HubPoolClient.ts +3 -24
  49. package/src/clients/SpokePoolClient/SpokePoolClient.ts +17 -5
@@ -32,7 +32,6 @@ import {
32
32
  forEachAsync,
33
33
  getBlockRangeForChain,
34
34
  getImpliedBundleBlockRanges,
35
- getMessageHash,
36
35
  getRelayEventKey,
37
36
  isSlowFill,
38
37
  mapAsync,
@@ -46,7 +45,6 @@ import {
46
45
  } from "../../utils";
47
46
  import winston from "winston";
48
47
  import {
49
- BundleData,
50
48
  BundleDataSS,
51
49
  getEndBlockBuffers,
52
50
  getRefundInformationFromFill,
@@ -58,7 +56,6 @@ import {
58
56
  V3FillWithBlock,
59
57
  verifyFillRepayment,
60
58
  } from "./utils";
61
- import { UNDEFINED_MESSAGE_HASH } from "../../constants";
62
59
  import { isEVMSpokePoolClient } from "../SpokePoolClient";
63
60
 
64
61
  // max(uint256) - 1
@@ -210,37 +207,6 @@ export class BundleDataClient {
210
207
  return `bundles-${BundleDataClient.getArweaveClientKey(blockRangesForChains)}`;
211
208
  }
212
209
 
213
- // Post-populate any missing message hashes.
214
- // @todo This can be removed once the legacy types hurdle is cleared (earliest 7 days post migration).
215
- backfillMessageHashes(data: Pick<BundleData, "bundleDepositsV3" | "bundleFillsV3">): void {
216
- Object.values(data.bundleDepositsV3).forEach((x) =>
217
- Object.values(x).forEach((deposits) =>
218
- deposits.forEach((deposit) => {
219
- if (deposit.messageHash === UNDEFINED_MESSAGE_HASH) {
220
- deposit.messageHash = getMessageHash(deposit.message);
221
- }
222
- })
223
- )
224
- );
225
-
226
- Object.values(data.bundleFillsV3).forEach((x) =>
227
- Object.values(x).forEach(({ fills }) =>
228
- fills.forEach((fill) => {
229
- if (fill.messageHash === UNDEFINED_MESSAGE_HASH && isDefined(fill.message)) {
230
- // If messageHash is undefined, fill should be of type FilledV3Relay and should have a message.
231
- fill.messageHash = getMessageHash(fill.message);
232
- }
233
- if (
234
- fill.relayExecutionInfo.updatedMessageHash === UNDEFINED_MESSAGE_HASH &&
235
- isDefined(fill.relayExecutionInfo.updatedMessage)
236
- ) {
237
- fill.relayExecutionInfo.updatedMessageHash = getMessageHash(fill.relayExecutionInfo.updatedMessage);
238
- }
239
- })
240
- )
241
- );
242
- }
243
-
244
210
  private async loadPersistedDataFromArweave(
245
211
  blockRangesForChains: number[][]
246
212
  ): Promise<LoadDataReturnValue | undefined> {
@@ -272,9 +238,6 @@ export class BundleDataClient {
272
238
  );
273
239
 
274
240
  const data = persistedData[0].data;
275
-
276
- this.backfillMessageHashes(data);
277
-
278
241
  const bundleData = {
279
242
  bundleFillsV3: convertTypedStringRecordIntoNumericRecord(data.bundleFillsV3),
280
243
  expiredDepositsToRefundV3: convertTypedStringRecordIntoNumericRecord(data.expiredDepositsToRefundV3),
@@ -359,6 +322,7 @@ export class BundleDataClient {
359
322
  // @dev This helper function should probably be moved to the InventoryClient
360
323
  async getApproximateRefundsForBlockRange(chainIds: number[], blockRanges: number[][]): Promise<CombinedRefunds> {
361
324
  const refundsForChain: CombinedRefunds = {};
325
+ const bundleEndBlockForMainnet = blockRanges[0][1];
362
326
  for (const chainId of chainIds) {
363
327
  if (this.spokePoolClients[chainId] === undefined) {
364
328
  continue;
@@ -401,7 +365,8 @@ export class BundleDataClient {
401
365
  _fill,
402
366
  spokeClient.spokePool.provider,
403
367
  matchingDeposit,
404
- this.clients.hubPoolClient
368
+ this.clients.hubPoolClient,
369
+ bundleEndBlockForMainnet
405
370
  );
406
371
  if (!isDefined(fill)) {
407
372
  return;
@@ -410,9 +375,9 @@ export class BundleDataClient {
410
375
  {
411
376
  ...fill,
412
377
  fromLiteChain: matchingDeposit.fromLiteChain,
413
- quoteBlockNumber: matchingDeposit.quoteBlockNumber,
414
378
  },
415
- this.clients.hubPoolClient
379
+ this.clients.hubPoolClient,
380
+ bundleEndBlockForMainnet
416
381
  );
417
382
  // Assume that lp fees are 0 for the sake of speed. In the future we could batch compute
418
383
  // these or make hardcoded assumptions based on the origin-repayment chain direction. This might result
@@ -675,6 +640,7 @@ export class BundleDataClient {
675
640
  }
676
641
 
677
642
  const chainIds = this.clients.configStoreClient.getChainIdIndicesForBlock(blockRangesForChains[0][0]);
643
+ const bundleEndBlockForMainnet = blockRangesForChains[0][1];
678
644
 
679
645
  if (blockRangesForChains.length > chainIds.length) {
680
646
  throw new Error(
@@ -711,7 +677,7 @@ export class BundleDataClient {
711
677
  deposit.originChainId,
712
678
  deposit.outputToken,
713
679
  deposit.destinationChainId,
714
- deposit.quoteBlockNumber
680
+ bundleEndBlockForMainnet
715
681
  ) &&
716
682
  // Cannot slow fill from or to a lite chain.
717
683
  !deposit.fromLiteChain &&
@@ -910,7 +876,8 @@ export class BundleDataClient {
910
876
  fill,
911
877
  destinationClient.spokePool.provider,
912
878
  deposits[0],
913
- this.clients.hubPoolClient
879
+ this.clients.hubPoolClient,
880
+ bundleEndBlockForMainnet
914
881
  );
915
882
  if (!isDefined(fillToRefund)) {
916
883
  bundleUnrepayableFillsV3.push(fill);
@@ -1014,7 +981,8 @@ export class BundleDataClient {
1014
981
  fill,
1015
982
  destinationClient.spokePool.provider,
1016
983
  matchedDeposit,
1017
- this.clients.hubPoolClient
984
+ this.clients.hubPoolClient,
985
+ bundleEndBlockForMainnet
1018
986
  );
1019
987
  if (!isDefined(fillToRefund)) {
1020
988
  bundleUnrepayableFillsV3.push(fill);
@@ -1194,7 +1162,8 @@ export class BundleDataClient {
1194
1162
  fill,
1195
1163
  destinationClient.spokePool.provider,
1196
1164
  deposits[0],
1197
- this.clients.hubPoolClient
1165
+ this.clients.hubPoolClient,
1166
+ bundleEndBlockForMainnet
1198
1167
  );
1199
1168
  if (!isDefined(fillToRefund)) {
1200
1169
  bundleUnrepayableFillsV3.push(fill);
@@ -1250,7 +1219,8 @@ export class BundleDataClient {
1250
1219
  prefill,
1251
1220
  destinationClient.spokePool.provider,
1252
1221
  deposit,
1253
- this.clients.hubPoolClient
1222
+ this.clients.hubPoolClient,
1223
+ bundleEndBlockForMainnet
1254
1224
  );
1255
1225
  if (!isDefined(verifiedFill)) {
1256
1226
  bundleUnrepayableFillsV3.push(prefill);
@@ -1387,9 +1357,9 @@ export class BundleDataClient {
1387
1357
  {
1388
1358
  ...fill,
1389
1359
  fromLiteChain: matchedDeposit.fromLiteChain,
1390
- quoteBlockNumber: matchedDeposit.quoteBlockNumber,
1391
1360
  },
1392
- this.clients.hubPoolClient
1361
+ this.clients.hubPoolClient,
1362
+ bundleEndBlockForMainnet
1393
1363
  );
1394
1364
  return {
1395
1365
  ...fill,
@@ -1434,9 +1404,9 @@ export class BundleDataClient {
1434
1404
  {
1435
1405
  ...fill,
1436
1406
  fromLiteChain: associatedDeposit.fromLiteChain,
1437
- quoteBlockNumber: associatedDeposit.quoteBlockNumber,
1438
1407
  },
1439
- this.clients.hubPoolClient
1408
+ this.clients.hubPoolClient,
1409
+ bundleEndBlockForMainnet
1440
1410
  );
1441
1411
  updateBundleFillsV3(bundleFillsV3, fill, realizedLpFeePct, chainToSendRefundTo, repaymentToken, fill.relayer);
1442
1412
  });
@@ -233,7 +233,13 @@ export function _buildPoolRebalanceRoot(
233
233
  ) {
234
234
  return;
235
235
  }
236
- updateRunningBalanceForDeposit(runningBalances, clients.hubPoolClient, deposit, deposit.inputAmount.mul(-1));
236
+ updateRunningBalanceForDeposit(
237
+ runningBalances,
238
+ clients.hubPoolClient,
239
+ deposit,
240
+ deposit.inputAmount.mul(-1),
241
+ mainnetBundleEndBlock
242
+ );
237
243
  });
238
244
  });
239
245
  });
@@ -9,7 +9,7 @@ import { HubPoolClient } from "../../HubPoolClient";
9
9
  * @notice FillRepaymentInformation is a fill with additional properties required to determine where it can
10
10
  * be repaid.
11
11
  */
12
- type FillRepaymentInformation = Fill & { quoteBlockNumber: number; fromLiteChain: boolean };
12
+ type FillRepaymentInformation = Fill & { fromLiteChain: boolean };
13
13
 
14
14
  /**
15
15
  * @notice Return repayment chain and repayment token for a fill, but does not verify if the returned
@@ -20,12 +20,13 @@ type FillRepaymentInformation = Fill & { quoteBlockNumber: number; fromLiteChain
20
20
  */
21
21
  export function getRefundInformationFromFill(
22
22
  relayData: FillRepaymentInformation,
23
- hubPoolClient: HubPoolClient
23
+ hubPoolClient: HubPoolClient,
24
+ bundleEndBlockForMainnet: number
24
25
  ): {
25
26
  chainToSendRefundTo: number;
26
27
  repaymentToken: string;
27
28
  } {
28
- const chainToSendRefundTo = _getRepaymentChainId(relayData, hubPoolClient);
29
+ const chainToSendRefundTo = _getRepaymentChainId(relayData, hubPoolClient, bundleEndBlockForMainnet);
29
30
  if (chainToSendRefundTo === relayData.originChainId) {
30
31
  return {
31
32
  chainToSendRefundTo,
@@ -39,13 +40,13 @@ export function getRefundInformationFromFill(
39
40
  const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(
40
41
  relayData.inputToken,
41
42
  relayData.originChainId,
42
- relayData.quoteBlockNumber
43
+ bundleEndBlockForMainnet
43
44
  );
44
45
 
45
46
  const repaymentToken = hubPoolClient.getL2TokenForL1TokenAtBlock(
46
47
  l1TokenCounterpart,
47
48
  chainToSendRefundTo,
48
- relayData.quoteBlockNumber
49
+ bundleEndBlockForMainnet
49
50
  );
50
51
  return {
51
52
  chainToSendRefundTo,
@@ -66,12 +67,12 @@ export async function verifyFillRepayment(
66
67
  _fill: FillWithBlock,
67
68
  destinationChainProvider: providers.Provider,
68
69
  matchedDeposit: DepositWithBlock,
69
- hubPoolClient: HubPoolClient
70
+ hubPoolClient: HubPoolClient,
71
+ bundleEndBlockForMainnet: number
70
72
  ): Promise<FillWithBlock | undefined> {
71
73
  const fill = {
72
74
  ..._.cloneDeep(_fill),
73
75
  fromLiteChain: matchedDeposit.fromLiteChain,
74
- quoteBlockNumber: matchedDeposit.quoteBlockNumber,
75
76
  };
76
77
 
77
78
  // Slow fills don't result in repayments so they're always valid.
@@ -79,7 +80,7 @@ export async function verifyFillRepayment(
79
80
  return fill;
80
81
  }
81
82
 
82
- let repaymentChainId = _getRepaymentChainId(fill, hubPoolClient);
83
+ let repaymentChainId = _getRepaymentChainId(fill, hubPoolClient, bundleEndBlockForMainnet);
83
84
 
84
85
  // Repayments will always go to the fill.relayer address so check if its a valid EVM address. If its not, attempt
85
86
  // to change it to the msg.sender of the FilledRelay.
@@ -122,7 +123,11 @@ export async function verifyFillRepayment(
122
123
  return fill;
123
124
  }
124
125
 
125
- function _getRepaymentChainId(relayData: FillRepaymentInformation, hubPoolClient: HubPoolClient): number {
126
+ function _getRepaymentChainId(
127
+ relayData: FillRepaymentInformation,
128
+ hubPoolClient: HubPoolClient,
129
+ bundleEndBlockForMainnet: number
130
+ ): number {
126
131
  if (relayData.fromLiteChain) {
127
132
  assert(!isSlowFill(relayData), "getRepaymentChainId: fromLiteChain and slow fill are mutually exclusive");
128
133
  return relayData.originChainId;
@@ -135,7 +140,7 @@ function _getRepaymentChainId(relayData: FillRepaymentInformation, hubPoolClient
135
140
  }
136
141
 
137
142
  // Repayment chain is valid if the input token and repayment chain are mapped to the same PoolRebalanceRoute.
138
- const repaymentTokenIsValid = _repaymentChainTokenIsValid(relayData, hubPoolClient);
143
+ const repaymentTokenIsValid = _repaymentChainTokenIsValid(relayData, hubPoolClient, bundleEndBlockForMainnet);
139
144
  if (repaymentTokenIsValid) {
140
145
  return relayData.repaymentChainId;
141
146
  }
@@ -144,26 +149,26 @@ function _getRepaymentChainId(relayData: FillRepaymentInformation, hubPoolClient
144
149
  return relayData.originChainId;
145
150
  }
146
151
 
147
- function _repaymentChainTokenIsValid(relayData: FillRepaymentInformation, hubPoolClient: HubPoolClient): boolean {
152
+ function _repaymentChainTokenIsValid(
153
+ relayData: FillRepaymentInformation,
154
+ hubPoolClient: HubPoolClient,
155
+ bundleEndBlockForMainnet: number
156
+ ): boolean {
148
157
  if (
149
- !hubPoolClient.l2TokenHasPoolRebalanceRoute(
150
- relayData.inputToken,
151
- relayData.originChainId,
152
- relayData.quoteBlockNumber
153
- )
158
+ !hubPoolClient.l2TokenHasPoolRebalanceRoute(relayData.inputToken, relayData.originChainId, bundleEndBlockForMainnet)
154
159
  ) {
155
160
  return false;
156
161
  }
157
162
  const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(
158
163
  relayData.inputToken,
159
164
  relayData.originChainId,
160
- relayData.quoteBlockNumber
165
+ bundleEndBlockForMainnet
161
166
  );
162
167
  if (
163
168
  !hubPoolClient.l2TokenEnabledForL1TokenAtBlock(
164
169
  l1TokenCounterpart,
165
170
  relayData.repaymentChainId,
166
- relayData.quoteBlockNumber
171
+ bundleEndBlockForMainnet
167
172
  )
168
173
  ) {
169
174
  return false;
@@ -163,12 +163,13 @@ export function updateRunningBalanceForDeposit(
163
163
  runningBalances: RunningBalances,
164
164
  hubPoolClient: HubPoolClient,
165
165
  deposit: V3DepositWithBlock,
166
- updateAmount: BigNumber
166
+ updateAmount: BigNumber,
167
+ mainnetBundleEndBlock: number
167
168
  ): void {
168
169
  const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(
169
170
  deposit.inputToken,
170
171
  deposit.originChainId,
171
- deposit.quoteBlockNumber
172
+ mainnetBundleEndBlock
172
173
  );
173
174
  updateRunningBalance(runningBalances, deposit.originChainId, l1TokenCounterpart, updateAmount);
174
175
  }
@@ -231,36 +231,15 @@ export class HubPoolClient extends BaseAbstractClient {
231
231
  return sortEventsDescending(l2Tokens)[0].l1Token;
232
232
  }
233
233
 
234
- /**
235
- * Returns the L1 token that should be used for an L2 Bridge event. This function is
236
- * designed to be used by the caller to associate the L2 token with its mapped L1 token
237
- * at the HubPool equivalent block number of the L2 event.
238
- * @param deposit Deposit event
239
- * @param returns string L1 token counterpart for Deposit
240
- */
241
- getL1TokenForDeposit(deposit: Pick<DepositWithBlock, "originChainId" | "inputToken" | "quoteBlockNumber">): string {
234
+ protected getL1TokenForDeposit(
235
+ deposit: Pick<DepositWithBlock, "originChainId" | "inputToken" | "quoteBlockNumber">
236
+ ): string {
242
237
  // L1-->L2 token mappings are set via PoolRebalanceRoutes which occur on mainnet,
243
238
  // so we use the latest token mapping. This way if a very old deposit is filled, the relayer can use the
244
239
  // latest L2 token mapping to find the L1 token counterpart.
245
240
  return this.getL1TokenForL2TokenAtBlock(deposit.inputToken, deposit.originChainId, deposit.quoteBlockNumber);
246
241
  }
247
242
 
248
- /**
249
- * Returns the L2 token that should be used as a counterpart to a deposit event. For example, the caller
250
- * might want to know what the refund token will be on l2ChainId for the deposit event.
251
- * @param l2ChainId Chain where caller wants to get L2 token counterpart for
252
- * @param event Deposit event
253
- * @returns string L2 token counterpart on l2ChainId
254
- */
255
- getL2TokenForDeposit(
256
- deposit: Pick<DepositWithBlock, "originChainId" | "destinationChainId" | "inputToken" | "quoteBlockNumber">,
257
- l2ChainId = deposit.destinationChainId
258
- ): string {
259
- const l1Token = this.getL1TokenForDeposit(deposit);
260
- // Use the latest hub block number to find the L2 token counterpart.
261
- return this.getL2TokenForL1TokenAtBlock(l1Token, l2ChainId, deposit.quoteBlockNumber);
262
- }
263
-
264
243
  l2TokenEnabledForL1Token(l1Token: string, destinationChainId: number): boolean {
265
244
  return this.l1TokensToDestinationTokens?.[l1Token]?.[destinationChainId] != undefined;
266
245
  }
@@ -369,11 +369,11 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
369
369
  const fillRepaymentData = {
370
370
  ...fill,
371
371
  fromLiteChain: deposit.fromLiteChain,
372
- quoteBlockNumber: this.hubPoolClient!.latestBlockSearched,
373
372
  };
374
373
  const { chainToSendRefundTo: repaymentChainId } = getRefundInformationFromFill(
375
374
  fillRepaymentData,
376
- this.hubPoolClient!
375
+ this.hubPoolClient!,
376
+ this.hubPoolClient!.latestBlockSearched
377
377
  );
378
378
  // In order to keep this function sync, we can't call verifyFillRepayment so we'll log any fills where
379
379
  // the filler-specified repayment chain and repayment address is not a valid repayment upon
@@ -464,7 +464,11 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
464
464
  ) {
465
465
  return false;
466
466
  } else {
467
- const l1Token = this.hubPoolClient?.getL1TokenForDeposit(deposit);
467
+ const l1Token = this.hubPoolClient?.getL1TokenForL2TokenAtBlock(
468
+ deposit.inputToken,
469
+ deposit.originChainId,
470
+ deposit.quoteBlockNumber
471
+ );
468
472
  return this.hubPoolClient.l2TokenEnabledForL1TokenAtBlock(
469
473
  l1Token,
470
474
  deposit.destinationChainId,
@@ -735,8 +739,16 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
735
739
  if (!this.canResolveZeroAddressOutputToken(deposit)) {
736
740
  return ZERO_ADDRESS;
737
741
  }
738
- // If there is no rate model client return address(0).
739
- return this.hubPoolClient?.getL2TokenForDeposit(deposit) ?? ZERO_ADDRESS;
742
+ // L1 token should be resolved if we get here:
743
+ const l1Token = this.hubPoolClient!.getL1TokenForL2TokenAtBlock(
744
+ deposit.inputToken,
745
+ deposit.originChainId,
746
+ deposit.quoteBlockNumber
747
+ )!;
748
+ return (
749
+ this.hubPoolClient!.getL2TokenForL1TokenAtBlock(l1Token, deposit.destinationChainId, deposit.quoteBlockNumber) ??
750
+ ZERO_ADDRESS
751
+ );
740
752
  }
741
753
 
742
754
  /**