@across-protocol/sdk 4.0.2 → 4.0.3

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 (118) hide show
  1. package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +3 -3
  2. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +38 -18
  3. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  4. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +3 -0
  5. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +20 -10
  6. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  7. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +14 -2
  8. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +4 -1
  9. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  10. package/dist/cjs/clients/SpokePoolClient.js +155 -88
  11. package/dist/cjs/clients/SpokePoolClient.js.map +1 -1
  12. package/dist/cjs/clients/mocks/MockSpokePoolClient.d.ts +20 -6
  13. package/dist/cjs/clients/mocks/MockSpokePoolClient.js +77 -35
  14. package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
  15. package/dist/cjs/constants.d.ts +2 -1
  16. package/dist/cjs/constants.js +3 -2
  17. package/dist/cjs/constants.js.map +1 -1
  18. package/dist/cjs/interfaces/SpokePool.d.ts +6 -2
  19. package/dist/cjs/interfaces/SpokePool.js.map +1 -1
  20. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -3
  21. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  22. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  23. package/dist/cjs/utils/AddressUtils.d.ts +1 -0
  24. package/dist/cjs/utils/AddressUtils.js +5 -1
  25. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  26. package/dist/cjs/utils/CachingUtils.js +1 -1
  27. package/dist/cjs/utils/CachingUtils.js.map +1 -1
  28. package/dist/cjs/utils/DepositUtils.d.ts +1 -1
  29. package/dist/cjs/utils/DepositUtils.js +11 -8
  30. package/dist/cjs/utils/DepositUtils.js.map +1 -1
  31. package/dist/cjs/utils/FlowUtils.d.ts +4 -3
  32. package/dist/cjs/utils/FlowUtils.js +5 -1
  33. package/dist/cjs/utils/FlowUtils.js.map +1 -1
  34. package/dist/cjs/utils/SpokeUtils.d.ts +9 -3
  35. package/dist/cjs/utils/SpokeUtils.js +22 -2
  36. package/dist/cjs/utils/SpokeUtils.js.map +1 -1
  37. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +3 -3
  38. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +42 -24
  39. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  40. package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +3 -0
  41. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +20 -11
  42. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  43. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +14 -2
  44. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +4 -1
  45. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  46. package/dist/esm/clients/SpokePoolClient.js +172 -92
  47. package/dist/esm/clients/SpokePoolClient.js.map +1 -1
  48. package/dist/esm/clients/mocks/MockSpokePoolClient.d.ts +20 -6
  49. package/dist/esm/clients/mocks/MockSpokePoolClient.js +79 -37
  50. package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
  51. package/dist/esm/constants.d.ts +2 -1
  52. package/dist/esm/constants.js +6 -1
  53. package/dist/esm/constants.js.map +1 -1
  54. package/dist/esm/interfaces/SpokePool.d.ts +6 -2
  55. package/dist/esm/interfaces/SpokePool.js.map +1 -1
  56. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -3
  57. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  58. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  59. package/dist/esm/utils/AddressUtils.d.ts +1 -0
  60. package/dist/esm/utils/AddressUtils.js +7 -4
  61. package/dist/esm/utils/AddressUtils.js.map +1 -1
  62. package/dist/esm/utils/CachingUtils.js +2 -2
  63. package/dist/esm/utils/CachingUtils.js.map +1 -1
  64. package/dist/esm/utils/DepositUtils.d.ts +1 -1
  65. package/dist/esm/utils/DepositUtils.js +12 -9
  66. package/dist/esm/utils/DepositUtils.js.map +1 -1
  67. package/dist/esm/utils/FlowUtils.d.ts +4 -3
  68. package/dist/esm/utils/FlowUtils.js +6 -1
  69. package/dist/esm/utils/FlowUtils.js.map +1 -1
  70. package/dist/esm/utils/SpokeUtils.d.ts +16 -3
  71. package/dist/esm/utils/SpokeUtils.js +27 -1
  72. package/dist/esm/utils/SpokeUtils.js.map +1 -1
  73. package/dist/esm/utils/abi/typechain/Multicall3.d.ts +4 -1
  74. package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.js.map +1 -1
  75. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +3 -3
  76. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  77. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +3 -0
  78. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  79. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +14 -2
  80. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
  81. package/dist/types/clients/SpokePoolClient.d.ts.map +1 -1
  82. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts +20 -6
  83. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts.map +1 -1
  84. package/dist/types/constants.d.ts +2 -1
  85. package/dist/types/constants.d.ts.map +1 -1
  86. package/dist/types/interfaces/SpokePool.d.ts +6 -2
  87. package/dist/types/interfaces/SpokePool.d.ts.map +1 -1
  88. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -3
  89. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts.map +1 -1
  90. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  91. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  92. package/dist/types/utils/AddressUtils.d.ts +1 -0
  93. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  94. package/dist/types/utils/DepositUtils.d.ts +1 -1
  95. package/dist/types/utils/DepositUtils.d.ts.map +1 -1
  96. package/dist/types/utils/FlowUtils.d.ts +4 -3
  97. package/dist/types/utils/FlowUtils.d.ts.map +1 -1
  98. package/dist/types/utils/SpokeUtils.d.ts +16 -3
  99. package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
  100. package/dist/types/utils/abi/typechain/Multicall3.d.ts +4 -1
  101. package/dist/types/utils/abi/typechain/Multicall3.d.ts.map +1 -1
  102. package/dist/types/utils/abi/typechain/common.d.ts.map +1 -1
  103. package/dist/types/utils/abi/typechain/factories/Multicall3__factory.d.ts.map +1 -1
  104. package/package.json +1 -1
  105. package/src/clients/BundleDataClient/BundleDataClient.ts +47 -30
  106. package/src/clients/BundleDataClient/utils/FillUtils.ts +26 -13
  107. package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +7 -1
  108. package/src/clients/SpokePoolClient.ts +119 -41
  109. package/src/clients/mocks/MockSpokePoolClient.ts +134 -36
  110. package/src/constants.ts +6 -1
  111. package/src/interfaces/SpokePool.ts +6 -2
  112. package/src/relayFeeCalculator/chain-queries/baseQuery.ts +6 -3
  113. package/src/relayFeeCalculator/relayFeeCalculator.ts +1 -1
  114. package/src/utils/AddressUtils.ts +8 -4
  115. package/src/utils/CachingUtils.ts +2 -2
  116. package/src/utils/DepositUtils.ts +8 -3
  117. package/src/utils/FlowUtils.ts +10 -4
  118. package/src/utils/SpokeUtils.ts +33 -3
@@ -53,6 +53,30 @@ export function getRepaymentChainId(fill: Fill, matchedDeposit: Deposit): number
53
53
  return matchedDeposit.fromLiteChain ? matchedDeposit.originChainId : fill.repaymentChainId;
54
54
  }
55
55
 
56
+ export function forceDestinationRepayment(
57
+ repaymentChainId: number,
58
+ matchedDeposit: Deposit & { quoteBlockNumber: number },
59
+ hubPoolClient: HubPoolClient
60
+ ): boolean {
61
+ if (!matchedDeposit.fromLiteChain) {
62
+ try {
63
+ const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(
64
+ matchedDeposit.inputToken,
65
+ matchedDeposit.originChainId,
66
+ matchedDeposit.quoteBlockNumber
67
+ );
68
+ hubPoolClient.getL2TokenForL1TokenAtBlock(l1TokenCounterpart, repaymentChainId, matchedDeposit.quoteBlockNumber);
69
+ // Repayment token could be found, this is a valid repayment chain.
70
+ return false;
71
+ } catch {
72
+ // Repayment token doesn't exist on repayment chain via PoolRebalanceRoutes, impossible to repay filler there.
73
+ return true;
74
+ }
75
+ } else {
76
+ return false;
77
+ }
78
+ }
79
+
56
80
  // Verify that a fill sent to an EVM chain has a 20 byte address. If the fill does not, then attempt
57
81
  // to repay the `msg.sender` of the relay transaction. Otherwise, return undefined.
58
82
  export async function verifyFillRepayment(
@@ -72,19 +96,8 @@ export async function verifyFillRepayment(
72
96
 
73
97
  // If repayment chain doesn't have a Pool Rebalance Route for the input token, then change the repayment
74
98
  // chain to the destination chain.
75
- if (!isSlowFill(fill) && !matchedDeposit.fromLiteChain) {
76
- try {
77
- const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(
78
- fill.inputToken,
79
- fill.originChainId,
80
- matchedDeposit.quoteBlockNumber
81
- );
82
- hubPoolClient.getL2TokenForL1TokenAtBlock(l1TokenCounterpart, repaymentChainId, matchedDeposit.quoteBlockNumber);
83
- // Repayment token could be found, this is a valid repayment chain.
84
- } catch {
85
- // Repayment token doesn't exist on repayment chain via PoolRebalanceRoutes, impossible to repay filler there.
86
- repaymentChainId = fill.destinationChainId;
87
- }
99
+ if (forceDestinationRepayment(repaymentChainId, matchedDeposit, hubPoolClient)) {
100
+ repaymentChainId = fill.destinationChainId;
88
101
  }
89
102
 
90
103
  if (!isValidEvmAddress(fill.relayer)) {
@@ -1,4 +1,5 @@
1
1
  import {
2
+ Infer,
2
3
  object,
3
4
  number,
4
5
  optional,
@@ -13,6 +14,7 @@ import {
13
14
  union,
14
15
  type,
15
16
  } from "superstruct";
17
+ import { UNDEFINED_MESSAGE_HASH } from "../../../constants";
16
18
  import { BigNumber } from "../../../utils";
17
19
 
18
20
  const PositiveIntegerStringSS = pattern(string(), /\d+/);
@@ -54,6 +56,7 @@ const SortableEventSS = {
54
56
  };
55
57
 
56
58
  const V3DepositSS = {
59
+ messageHash: defaulted(string(), UNDEFINED_MESSAGE_HASH),
57
60
  fromLiteChain: defaulted(boolean(), false),
58
61
  toLiteChain: defaulted(boolean(), false),
59
62
  destinationChainId: number(),
@@ -83,16 +86,17 @@ const V3RelayExecutionEventInfoSS = object({
83
86
  fillType: FillTypeSS,
84
87
  updatedRecipient: string(),
85
88
  updatedMessage: string(),
89
+ updatedMessageHash: defaulted(string(), UNDEFINED_MESSAGE_HASH),
86
90
  });
87
91
 
88
92
  const V3FillSS = {
89
93
  ...V3RelayDataSS,
94
+ messageHash: defaulted(string(), UNDEFINED_MESSAGE_HASH),
90
95
  destinationChainId: number(),
91
96
  relayer: string(),
92
97
  repaymentChainId: number(),
93
98
  relayExecutionInfo: V3RelayExecutionEventInfoSS,
94
99
  quoteTimestamp: number(),
95
- messageHash: optional(string()),
96
100
  };
97
101
 
98
102
  const V3FillWithBlockSS = {
@@ -132,3 +136,5 @@ export const BundleDataSS = type({
132
136
  bundleSlowFillsV3: nestedV3DepositRecordWithLpFeePctSS,
133
137
  bundleFillsV3: nestedV3BundleFillsSS,
134
138
  });
139
+
140
+ export type BundleData = Infer<typeof BundleDataSS>;
@@ -9,11 +9,15 @@ import {
9
9
  MAX_BIG_INT,
10
10
  MakeOptional,
11
11
  assign,
12
- getRelayDataHash,
12
+ getRelayEventKey,
13
13
  isDefined,
14
14
  toBN,
15
15
  bnOne,
16
+ getMessageHash,
16
17
  isUnsafeDepositId,
18
+ isSlowFill,
19
+ isValidEvmAddress,
20
+ isZeroAddress,
17
21
  } from "../utils";
18
22
  import {
19
23
  paginatedEventQuery,
@@ -43,6 +47,7 @@ import { getBlockRangeForDepositId, getDepositIdAtBlock, relayFillStatus } from
43
47
  import { BaseAbstractClient, isUpdateFailureReason, UpdateFailureReason } from "./BaseAbstractClient";
44
48
  import { HubPoolClient } from "./HubPoolClient";
45
49
  import { AcrossConfigStoreClient } from "./AcrossConfigStoreClient";
50
+ import { getRepaymentChainId, forceDestinationRepayment } from "./BundleDataClient/utils/FillUtils";
46
51
 
47
52
  type SpokePoolUpdateSuccess = {
48
53
  success: true;
@@ -143,7 +148,7 @@ export class SpokePoolClient extends BaseAbstractClient {
143
148
  * unless the original deposit is a duplicate.
144
149
  */
145
150
  private _getDuplicateDeposits(deposit: DepositWithBlock): DepositWithBlock[] {
146
- const depositHash = this.getDepositHash(deposit);
151
+ const depositHash = getRelayEventKey(deposit);
147
152
  return this.duplicateDepositHashes[depositHash] ?? [];
148
153
  }
149
154
 
@@ -297,8 +302,7 @@ export class SpokePoolClient extends BaseAbstractClient {
297
302
  * @returns The corresponding deposit if found, undefined otherwise.
298
303
  */
299
304
  public getDeposit(depositId: BigNumber): DepositWithBlock | undefined {
300
- const depositHash = this.getDepositHash({ depositId, originChainId: this.chainId });
301
- return this.depositHashes[depositHash];
305
+ return Object.values(this.depositHashes).find(({ depositId: _depositId }) => _depositId.eq(depositId));
302
306
  }
303
307
 
304
308
  /**
@@ -307,7 +311,8 @@ export class SpokePoolClient extends BaseAbstractClient {
307
311
  * @returns The corresponding SlowFIllRequest event if found, otherwise undefined.
308
312
  */
309
313
  public getSlowFillRequest(relayData: RelayData): SlowFillRequestWithBlock | undefined {
310
- const hash = getRelayDataHash(relayData, this.chainId);
314
+ const messageHash = getMessageHash(relayData.message);
315
+ const hash = getRelayEventKey({ ...relayData, messageHash, destinationChainId: this.chainId });
311
316
  return this.slowFillRequests[hash];
312
317
  }
313
318
 
@@ -336,7 +341,7 @@ export class SpokePoolClient extends BaseAbstractClient {
336
341
  * @returns The corresponding deposit if found, undefined otherwise.
337
342
  */
338
343
  public getDepositForFill(fill: Fill): DepositWithBlock | undefined {
339
- const deposit = this.depositHashes[this.getDepositHash(fill)];
344
+ const deposit = this.depositHashes[getRelayEventKey(fill)];
340
345
  const match = validateFillForDeposit(fill, deposit);
341
346
  if (match.valid) {
342
347
  return deposit;
@@ -359,7 +364,7 @@ export class SpokePoolClient extends BaseAbstractClient {
359
364
  * @returns A valid fill for the deposit, or undefined.
360
365
  */
361
366
  public getFillForDeposit(deposit: Deposit): FillWithBlock | undefined {
362
- const fills = this.depositHashesToFills[this.getDepositHash(deposit)];
367
+ const fills = this.depositHashesToFills[getRelayEventKey(deposit)];
363
368
  return fills?.find((fill) => validateFillForDeposit(fill, deposit));
364
369
  }
365
370
 
@@ -376,23 +381,44 @@ export class SpokePoolClient extends BaseAbstractClient {
376
381
  invalidFills: Fill[];
377
382
  } {
378
383
  const { outputAmount } = deposit;
379
- const fillsForDeposit = this.depositHashesToFills[this.getDepositHash(deposit)];
384
+ const fillsForDeposit = this.depositHashesToFills[getRelayEventKey(deposit)];
380
385
 
381
386
  // If no fills then the full amount is remaining.
382
387
  if (fillsForDeposit === undefined || fillsForDeposit.length === 0) {
383
388
  return { unfilledAmount: outputAmount, fillCount: 0, invalidFills: [] };
384
389
  }
385
390
 
386
- const { validFills, invalidFills } = fillsForDeposit.reduce(
387
- (groupedFills: { validFills: Fill[]; invalidFills: Fill[] }, fill: Fill) => {
391
+ const { validFills, invalidFills, unrepayableFills } = fillsForDeposit.reduce(
392
+ (groupedFills: { validFills: Fill[]; invalidFills: Fill[]; unrepayableFills: Fill[] }, fill: Fill) => {
388
393
  if (validateFillForDeposit(fill, deposit).valid) {
394
+ const repaymentChainId = getRepaymentChainId(fill, deposit);
395
+ // In order to keep this function sync, we can't call verifyFillRepayment so we'll log any fills that
396
+ // we'll have to overwrite repayment information for. This includes fills for lite chains where the
397
+ // repayment address is invalid, and fills for non-lite chains where the repayment address is valid or
398
+ // the repayment chain is invalid. We don't check that the origin chain is a valid EVM chain for
399
+ // lite chain deposits yet because only EVM chains are supported on Across...for now. This means
400
+ // this logic will have to be revisited when we add SVM to log properly.
401
+ if (
402
+ this.hubPoolClient &&
403
+ !isSlowFill(fill) &&
404
+ (!isValidEvmAddress(fill.relayer) ||
405
+ forceDestinationRepayment(
406
+ repaymentChainId,
407
+ { ...deposit, quoteBlockNumber: this.hubPoolClient!.latestBlockSearched },
408
+ this.hubPoolClient
409
+ ))
410
+ ) {
411
+ groupedFills.unrepayableFills.push(fill);
412
+ }
413
+ // This fill is still valid and means that the deposit cannot be filled on-chain anymore, but it
414
+ // also can be unrepayable which we should want to log.
389
415
  groupedFills.validFills.push(fill);
390
416
  } else {
391
417
  groupedFills.invalidFills.push(fill);
392
418
  }
393
419
  return groupedFills;
394
420
  },
395
- { validFills: [], invalidFills: [] }
421
+ { validFills: [], invalidFills: [], unrepayableFills: [] }
396
422
  );
397
423
 
398
424
  // Log any invalid deposits with same deposit id but different params.
@@ -407,6 +433,17 @@ export class SpokePoolClient extends BaseAbstractClient {
407
433
  notificationPath: "across-invalid-fills",
408
434
  });
409
435
  }
436
+ const unrepayableFillsForDeposit = unrepayableFills.filter((x) => x.depositId.eq(deposit.depositId));
437
+ if (unrepayableFillsForDeposit.length > 0) {
438
+ this.logger.warn({
439
+ at: "SpokePoolClient",
440
+ chainId: this.chainId,
441
+ message: "Unrepayable fills found where we need to switch repayment address and or chain",
442
+ deposit,
443
+ unrepayableFills: Object.fromEntries(unrepayableFillsForDeposit.map((x) => [x.relayer, x])),
444
+ notificationPath: "across-unrepayable-fills",
445
+ });
446
+ }
410
447
 
411
448
  // If all fills are invalid we can consider this unfilled.
412
449
  if (validFills.length === 0) {
@@ -574,12 +611,17 @@ export class SpokePoolClient extends BaseAbstractClient {
574
611
  }
575
612
  }
576
613
 
577
- if (eventsToQuery.includes("V3FundsDeposited")) {
578
- const depositEvents = queryResults[eventsToQuery.indexOf("V3FundsDeposited")] ?? [];
614
+ // Performs the indexing of a deposit-like spoke pool event.
615
+ const queryDepositEvents = async (eventName: string) => {
616
+ const depositEvents = queryResults[eventsToQuery.indexOf(eventName)] ?? [];
579
617
  if (depositEvents.length > 0) {
580
- this.log("debug", `Using ${depositEvents.length} newly queried deposit events for chain ${this.chainId}`, {
581
- earliestEvent: depositEvents[0].blockNumber,
582
- });
618
+ this.log(
619
+ "debug",
620
+ `Using ${depositEvents.length} newly queried ${eventName} deposit events for chain ${this.chainId}`,
621
+ {
622
+ earliestEvent: depositEvents[0].blockNumber,
623
+ }
624
+ );
583
625
  }
584
626
 
585
627
  // For each deposit, resolve its quoteTimestamp to a block number on the HubPool.
@@ -593,6 +635,7 @@ export class SpokePoolClient extends BaseAbstractClient {
593
635
  // Derive and append the common properties that are not part of the onchain event.
594
636
  const deposit = {
595
637
  ...spreadEventWithBlockNumber(event),
638
+ messageHash: getMessageHash(event.args.message),
596
639
  quoteBlockNumber,
597
640
  originChainId: this.chainId,
598
641
  // The following properties are placeholders to be updated immediately.
@@ -603,15 +646,15 @@ export class SpokePoolClient extends BaseAbstractClient {
603
646
  deposit.fromLiteChain = this.isOriginLiteChain(deposit);
604
647
  deposit.toLiteChain = this.isDestinationLiteChain(deposit);
605
648
 
606
- if (deposit.outputToken === ZERO_ADDRESS) {
649
+ if (isZeroAddress(deposit.outputToken)) {
607
650
  deposit.outputToken = this.getDestinationTokenForDeposit(deposit);
608
651
  }
609
652
 
610
- if (this.depositHashes[this.getDepositHash(deposit)] !== undefined) {
611
- assign(this.duplicateDepositHashes, [this.getDepositHash(deposit)], [deposit]);
653
+ if (this.depositHashes[getRelayEventKey(deposit)] !== undefined) {
654
+ assign(this.duplicateDepositHashes, [getRelayEventKey(deposit)], [deposit]);
612
655
  continue;
613
656
  }
614
- assign(this.depositHashes, [this.getDepositHash(deposit)], deposit);
657
+ assign(this.depositHashes, [getRelayEventKey(deposit)], deposit);
615
658
 
616
659
  if (deposit.depositId.lt(this.earliestDepositIdQueried) && !isUnsafeDepositId(deposit.depositId)) {
617
660
  this.earliestDepositIdQueried = deposit.depositId;
@@ -620,11 +663,17 @@ export class SpokePoolClient extends BaseAbstractClient {
620
663
  this.latestDepositIdQueried = deposit.depositId;
621
664
  }
622
665
  }
666
+ };
667
+
668
+ for (const event of ["V3FundsDeposited", "FundsDeposited"]) {
669
+ if (eventsToQuery.includes(event)) {
670
+ await queryDepositEvents(event);
671
+ }
623
672
  }
624
673
 
625
- // Update deposits with speed up requests from depositor.
626
- if (eventsToQuery.includes("RequestedSpeedUpV3Deposit")) {
627
- const speedUpEvents = queryResults[eventsToQuery.indexOf("RequestedSpeedUpV3Deposit")] ?? [];
674
+ // Performs indexing of a "speed up deposit"-like event.
675
+ const querySpeedUpDepositEvents = (eventName: string) => {
676
+ const speedUpEvents = queryResults[eventsToQuery.indexOf(eventName)] ?? [];
628
677
 
629
678
  for (const event of speedUpEvents) {
630
679
  const speedUp = { ...spreadEventWithBlockNumber(event), originChainId: this.chainId } as SpeedUpWithBlock;
@@ -632,38 +681,54 @@ export class SpokePoolClient extends BaseAbstractClient {
632
681
 
633
682
  // Find deposit hash matching this speed up event and update the deposit data associated with the hash,
634
683
  // if the hash+data exists.
635
- const depositHash = this.getDepositHash(speedUp);
684
+ const deposit = this.getDeposit(speedUp.depositId);
636
685
 
637
686
  // We can assume all deposits in this lookback window are loaded in-memory already so if the depositHash
638
687
  // is not mapped to a deposit, then we can throw away the speedup as it can't be applied to anything.
639
- const depositDataAssociatedWithSpeedUp = this.depositHashes[depositHash];
640
- if (isDefined(depositDataAssociatedWithSpeedUp)) {
641
- this.depositHashes[depositHash] = this.appendMaxSpeedUpSignatureToDeposit(depositDataAssociatedWithSpeedUp);
688
+ if (isDefined(deposit)) {
689
+ const eventKey = getRelayEventKey(deposit);
690
+ this.depositHashes[eventKey] = this.appendMaxSpeedUpSignatureToDeposit(deposit);
642
691
  }
643
692
  }
644
- }
693
+ };
694
+
695
+ // Update deposits with speed up requests from depositor.
696
+ ["RequestedSpeedUpV3Deposit", "RequestedSpeedUpDeposit"].forEach((event) => {
697
+ if (eventsToQuery.includes(event)) {
698
+ querySpeedUpDepositEvents(event);
699
+ }
700
+ });
645
701
 
646
- if (eventsToQuery.includes("RequestedV3SlowFill")) {
647
- const slowFillRequests = queryResults[eventsToQuery.indexOf("RequestedV3SlowFill")];
702
+ // Performs indexing of "requested slow fill"-like events.
703
+ const queryRequestedSlowFillEvents = (eventName: string) => {
704
+ const slowFillRequests = queryResults[eventsToQuery.indexOf(eventName)];
648
705
  for (const event of slowFillRequests) {
649
706
  const slowFillRequest = {
650
707
  ...spreadEventWithBlockNumber(event),
651
708
  destinationChainId: this.chainId,
652
709
  } as SlowFillRequestWithBlock;
653
710
 
654
- const relayDataHash = getRelayDataHash(slowFillRequest, this.chainId);
655
- if (this.slowFillRequests[relayDataHash] !== undefined) {
656
- continue;
711
+ if (eventName === "RequestedV3SlowFill") {
712
+ slowFillRequest.messageHash = getMessageHash(slowFillRequest.message);
657
713
  }
658
- this.slowFillRequests[relayDataHash] = slowFillRequest;
714
+
715
+ const depositHash = getRelayEventKey({ ...slowFillRequest, destinationChainId: this.chainId });
716
+ this.slowFillRequests[depositHash] ??= slowFillRequest;
659
717
  }
660
- }
718
+ };
719
+
720
+ ["RequestedV3SlowFill", "RequestedSlowFill"].forEach((event) => {
721
+ if (eventsToQuery.includes(event)) {
722
+ queryRequestedSlowFillEvents(event);
723
+ }
724
+ });
661
725
 
662
- if (eventsToQuery.includes("FilledV3Relay")) {
663
- const fillEvents = queryResults[eventsToQuery.indexOf("FilledV3Relay")] ?? [];
726
+ // Performs indexing of filled relay-like events.
727
+ const queryFilledRelayEvents = (eventName: string) => {
728
+ const fillEvents = queryResults[eventsToQuery.indexOf(eventName)] ?? [];
664
729
 
665
730
  if (fillEvents.length > 0) {
666
- this.log("debug", `Using ${fillEvents.length} newly queried fill events for chain ${this.chainId}`, {
731
+ this.log("debug", `Using ${fillEvents.length} newly queried ${eventName} events for chain ${this.chainId}`, {
667
732
  earliestEvent: fillEvents[0].blockNumber,
668
733
  });
669
734
  }
@@ -673,13 +738,26 @@ export class SpokePoolClient extends BaseAbstractClient {
673
738
  for (const event of fillEvents) {
674
739
  const fill = {
675
740
  ...spreadEventWithBlockNumber(event),
741
+ messageHash: getMessageHash(event.args["message"]),
676
742
  destinationChainId: this.chainId,
677
743
  } as FillWithBlock;
678
744
 
745
+ if (eventName === "FilledV3Relay") {
746
+ fill.messageHash = getMessageHash(event.args.message);
747
+ fill.relayExecutionInfo.updatedMessageHash = getMessageHash(event.args.relayExecutionInfo.updatedMessage);
748
+ }
749
+
679
750
  assign(this.fills, [fill.originChainId], [fill]);
680
- assign(this.depositHashesToFills, [this.getDepositHash(fill)], [fill]);
751
+ assign(this.depositHashesToFills, [getRelayEventKey(fill)], [fill]);
681
752
  }
682
- }
753
+ };
754
+
755
+ // Update observed fills with ingested event data.
756
+ ["FilledV3Relay", "FilledRelay"].forEach((event) => {
757
+ if (eventsToQuery.includes(event)) {
758
+ queryFilledRelayEvents(event);
759
+ }
760
+ });
683
761
 
684
762
  if (eventsToQuery.includes("EnabledDepositRoute")) {
685
763
  const enableDepositsEvents = queryResults[eventsToQuery.indexOf("EnabledDepositRoute")];
@@ -859,7 +937,7 @@ export class SpokePoolClient extends BaseAbstractClient {
859
937
  toLiteChain: true, // To be updated immediately afterwards.
860
938
  } as DepositWithBlock;
861
939
 
862
- if (deposit.outputToken === ZERO_ADDRESS) {
940
+ if (isZeroAddress(deposit.outputToken)) {
863
941
  deposit.outputToken = this.getDestinationTokenForDeposit(deposit);
864
942
  }
865
943
  deposit.fromLiteChain = this.isOriginLiteChain(deposit);