@across-protocol/sdk 4.0.3-beta.0 → 4.0.4

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 (109) hide show
  1. package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +2 -1
  2. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +25 -9
  3. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  4. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +1 -1
  5. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +4 -4
  6. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  7. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +6 -3
  8. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +5 -4
  9. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  10. package/dist/cjs/clients/SpokePoolClient.d.ts +1 -1
  11. package/dist/cjs/clients/SpokePoolClient.js +130 -84
  12. package/dist/cjs/clients/SpokePoolClient.js.map +1 -1
  13. package/dist/cjs/clients/mocks/MockSpokePoolClient.d.ts +16 -2
  14. package/dist/cjs/clients/mocks/MockSpokePoolClient.js +77 -35
  15. package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
  16. package/dist/cjs/constants.d.ts +2 -1
  17. package/dist/cjs/constants.js +3 -2
  18. package/dist/cjs/constants.js.map +1 -1
  19. package/dist/cjs/interfaces/SpokePool.d.ts +4 -2
  20. package/dist/cjs/package.json +1 -0
  21. package/dist/cjs/utils/AddressUtils.d.ts +1 -0
  22. package/dist/cjs/utils/AddressUtils.js +5 -1
  23. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  24. package/dist/cjs/utils/CachingUtils.js +1 -1
  25. package/dist/cjs/utils/CachingUtils.js.map +1 -1
  26. package/dist/cjs/utils/DepositUtils.d.ts +1 -1
  27. package/dist/cjs/utils/DepositUtils.js +11 -8
  28. package/dist/cjs/utils/DepositUtils.js.map +1 -1
  29. package/dist/cjs/utils/FlowUtils.d.ts +4 -3
  30. package/dist/cjs/utils/FlowUtils.js +5 -1
  31. package/dist/cjs/utils/FlowUtils.js.map +1 -1
  32. package/dist/cjs/utils/SpokeUtils.d.ts +6 -3
  33. package/dist/cjs/utils/SpokeUtils.js +2 -2
  34. package/dist/cjs/utils/SpokeUtils.js.map +1 -1
  35. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +2 -1
  36. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +29 -13
  37. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  38. package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +1 -1
  39. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +2 -2
  40. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  41. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +6 -3
  42. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +3 -2
  43. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  44. package/dist/esm/clients/SpokePoolClient.d.ts +1 -6
  45. package/dist/esm/clients/SpokePoolClient.js +138 -94
  46. package/dist/esm/clients/SpokePoolClient.js.map +1 -1
  47. package/dist/esm/clients/mocks/MockSpokePoolClient.d.ts +16 -2
  48. package/dist/esm/clients/mocks/MockSpokePoolClient.js +79 -37
  49. package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
  50. package/dist/esm/constants.d.ts +2 -1
  51. package/dist/esm/constants.js +6 -1
  52. package/dist/esm/constants.js.map +1 -1
  53. package/dist/esm/interfaces/SpokePool.d.ts +4 -2
  54. package/dist/esm/package.json +1 -0
  55. package/dist/esm/utils/AddressUtils.d.ts +1 -0
  56. package/dist/esm/utils/AddressUtils.js +7 -4
  57. package/dist/esm/utils/AddressUtils.js.map +1 -1
  58. package/dist/esm/utils/CachingUtils.js +2 -2
  59. package/dist/esm/utils/CachingUtils.js.map +1 -1
  60. package/dist/esm/utils/DepositUtils.d.ts +1 -1
  61. package/dist/esm/utils/DepositUtils.js +12 -9
  62. package/dist/esm/utils/DepositUtils.js.map +1 -1
  63. package/dist/esm/utils/FlowUtils.d.ts +4 -3
  64. package/dist/esm/utils/FlowUtils.js +6 -1
  65. package/dist/esm/utils/FlowUtils.js.map +1 -1
  66. package/dist/esm/utils/SpokeUtils.d.ts +6 -3
  67. package/dist/esm/utils/SpokeUtils.js +2 -2
  68. package/dist/esm/utils/SpokeUtils.js.map +1 -1
  69. package/dist/esm/utils/abi/typechain/Multicall3.d.ts +4 -1
  70. package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.js.map +1 -1
  71. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +2 -1
  72. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  73. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +1 -1
  74. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  75. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +6 -3
  76. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
  77. package/dist/types/clients/SpokePoolClient.d.ts +1 -6
  78. package/dist/types/clients/SpokePoolClient.d.ts.map +1 -1
  79. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts +16 -2
  80. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts.map +1 -1
  81. package/dist/types/constants.d.ts +2 -1
  82. package/dist/types/constants.d.ts.map +1 -1
  83. package/dist/types/interfaces/SpokePool.d.ts +4 -2
  84. package/dist/types/interfaces/SpokePool.d.ts.map +1 -1
  85. package/dist/types/utils/AddressUtils.d.ts +1 -0
  86. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  87. package/dist/types/utils/DepositUtils.d.ts +1 -1
  88. package/dist/types/utils/DepositUtils.d.ts.map +1 -1
  89. package/dist/types/utils/FlowUtils.d.ts +4 -3
  90. package/dist/types/utils/FlowUtils.d.ts.map +1 -1
  91. package/dist/types/utils/SpokeUtils.d.ts +6 -3
  92. package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
  93. package/dist/types/utils/abi/typechain/Multicall3.d.ts +4 -1
  94. package/dist/types/utils/abi/typechain/Multicall3.d.ts.map +1 -1
  95. package/dist/types/utils/abi/typechain/common.d.ts.map +1 -1
  96. package/dist/types/utils/abi/typechain/factories/Multicall3__factory.d.ts.map +1 -1
  97. package/package.json +1 -1
  98. package/src/clients/BundleDataClient/BundleDataClient.ts +30 -13
  99. package/src/clients/BundleDataClient/utils/FillUtils.ts +2 -2
  100. package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +6 -3
  101. package/src/clients/SpokePoolClient.ts +71 -34
  102. package/src/clients/mocks/MockSpokePoolClient.ts +125 -29
  103. package/src/constants.ts +6 -1
  104. package/src/interfaces/SpokePool.ts +4 -2
  105. package/src/utils/AddressUtils.ts +8 -4
  106. package/src/utils/CachingUtils.ts +2 -2
  107. package/src/utils/DepositUtils.ts +8 -3
  108. package/src/utils/FlowUtils.ts +10 -4
  109. package/src/utils/SpokeUtils.ts +7 -4
@@ -45,6 +45,7 @@ import {
45
45
  import winston from "winston";
46
46
  import {
47
47
  _buildPoolRebalanceRoot,
48
+ BundleData,
48
49
  BundleDataSS,
49
50
  getEndBlockBuffers,
50
51
  getRefundInformationFromFill,
@@ -53,12 +54,11 @@ import {
53
54
  isChainDisabled,
54
55
  PoolRebalanceRoot,
55
56
  prettyPrintV3SpokePoolEvents,
56
- UNDEFINED_MESSAGE_HASH,
57
57
  V3DepositWithBlock,
58
58
  V3FillWithBlock,
59
59
  verifyFillRepayment,
60
60
  } from "./utils";
61
- import { PRE_FILL_MIN_CONFIG_STORE_VERSION } from "../../constants";
61
+ import { PRE_FILL_MIN_CONFIG_STORE_VERSION, UNDEFINED_MESSAGE_HASH } from "../../constants";
62
62
 
63
63
  // max(uint256) - 1
64
64
  export const INFINITE_FILL_DEADLINE = bnUint32Max;
@@ -209,6 +209,33 @@ export class BundleDataClient {
209
209
  return `bundles-${BundleDataClient.getArweaveClientKey(blockRangesForChains)}`;
210
210
  }
211
211
 
212
+ // Post-populate any missing message hashes.
213
+ // @todo This can be removed once the legacy types hurdle is cleared (earliest 7 days post migration).
214
+ backfillMessageHashes(data: Pick<BundleData, "bundleDepositsV3" | "bundleFillsV3">): void {
215
+ Object.values(data.bundleDepositsV3).forEach((x) =>
216
+ Object.values(x).forEach((deposits) =>
217
+ deposits.forEach((deposit) => {
218
+ if (deposit.messageHash === UNDEFINED_MESSAGE_HASH) {
219
+ deposit.messageHash = getMessageHash(deposit.message);
220
+ }
221
+ })
222
+ )
223
+ );
224
+
225
+ Object.values(data.bundleFillsV3).forEach((x) =>
226
+ Object.values(x).forEach(({ fills }) =>
227
+ fills.forEach((fill) => {
228
+ if (fill.messageHash === UNDEFINED_MESSAGE_HASH) {
229
+ fill.messageHash = getMessageHash(fill.message);
230
+ }
231
+ if (fill.relayExecutionInfo.updatedMessageHash === UNDEFINED_MESSAGE_HASH) {
232
+ fill.relayExecutionInfo.updatedMessageHash = getMessageHash(fill.relayExecutionInfo.updatedMessage);
233
+ }
234
+ })
235
+ )
236
+ );
237
+ }
238
+
212
239
  private async loadPersistedDataFromArweave(
213
240
  blockRangesForChains: number[][]
214
241
  ): Promise<LoadDataReturnValue | undefined> {
@@ -241,17 +268,7 @@ export class BundleDataClient {
241
268
 
242
269
  const data = persistedData[0].data;
243
270
 
244
- // Post-populate any missing message hashes.
245
- // @todo This can be removed once the legacy types hurdle is cleared (earliest 7 days post migration).
246
- Object.values(data.bundleDepositsV3).forEach((x) =>
247
- Object.values(x).forEach((deposits) =>
248
- deposits.forEach((deposit) => {
249
- if (deposit.messageHash === UNDEFINED_MESSAGE_HASH) {
250
- deposit.messageHash = getMessageHash(deposit.message);
251
- }
252
- })
253
- )
254
- );
271
+ this.backfillMessageHashes(data);
255
272
 
256
273
  const bundleData = {
257
274
  bundleFillsV3: convertTypedStringRecordIntoNumericRecord(data.bundleFillsV3),
@@ -53,7 +53,7 @@ export function getRepaymentChainId(fill: Fill, matchedDeposit: Deposit): number
53
53
  return matchedDeposit.fromLiteChain ? matchedDeposit.originChainId : fill.repaymentChainId;
54
54
  }
55
55
 
56
- export function willOverwriteRepaymentChain(
56
+ export function forceDestinationRepayment(
57
57
  repaymentChainId: number,
58
58
  matchedDeposit: Deposit & { quoteBlockNumber: number },
59
59
  hubPoolClient: HubPoolClient
@@ -96,7 +96,7 @@ export async function verifyFillRepayment(
96
96
 
97
97
  // If repayment chain doesn't have a Pool Rebalance Route for the input token, then change the repayment
98
98
  // chain to the destination chain.
99
- if (!isSlowFill(fill) && willOverwriteRepaymentChain(repaymentChainId, matchedDeposit, hubPoolClient)) {
99
+ if (forceDestinationRepayment(repaymentChainId, matchedDeposit, hubPoolClient)) {
100
100
  repaymentChainId = fill.destinationChainId;
101
101
  }
102
102
 
@@ -1,4 +1,5 @@
1
1
  import {
2
+ Infer,
2
3
  object,
3
4
  number,
4
5
  optional,
@@ -13,10 +14,9 @@ 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
- export const UNDEFINED_MESSAGE_HASH = "";
19
-
20
20
  const PositiveIntegerStringSS = pattern(string(), /\d+/);
21
21
  const Web3AddressSS = pattern(string(), /^0x[a-fA-F0-9]{40}$/);
22
22
 
@@ -86,16 +86,17 @@ const V3RelayExecutionEventInfoSS = object({
86
86
  fillType: FillTypeSS,
87
87
  updatedRecipient: string(),
88
88
  updatedMessage: string(),
89
+ updatedMessageHash: defaulted(string(), UNDEFINED_MESSAGE_HASH),
89
90
  });
90
91
 
91
92
  const V3FillSS = {
92
93
  ...V3RelayDataSS,
94
+ messageHash: defaulted(string(), UNDEFINED_MESSAGE_HASH),
93
95
  destinationChainId: number(),
94
96
  relayer: string(),
95
97
  repaymentChainId: number(),
96
98
  relayExecutionInfo: V3RelayExecutionEventInfoSS,
97
99
  quoteTimestamp: number(),
98
- messageHash: optional(string()),
99
100
  };
100
101
 
101
102
  const V3FillWithBlockSS = {
@@ -135,3 +136,5 @@ export const BundleDataSS = type({
135
136
  bundleSlowFillsV3: nestedV3DepositRecordWithLpFeePctSS,
136
137
  bundleFillsV3: nestedV3BundleFillsSS,
137
138
  });
139
+
140
+ export type BundleData = Infer<typeof BundleDataSS>;
@@ -17,6 +17,7 @@ import {
17
17
  isUnsafeDepositId,
18
18
  isSlowFill,
19
19
  isValidEvmAddress,
20
+ isZeroAddress,
20
21
  } from "../utils";
21
22
  import {
22
23
  paginatedEventQuery,
@@ -46,7 +47,7 @@ import { getBlockRangeForDepositId, getDepositIdAtBlock, relayFillStatus } from
46
47
  import { BaseAbstractClient, isUpdateFailureReason, UpdateFailureReason } from "./BaseAbstractClient";
47
48
  import { HubPoolClient } from "./HubPoolClient";
48
49
  import { AcrossConfigStoreClient } from "./AcrossConfigStoreClient";
49
- import { getRepaymentChainId, overwriteRepaymentChain, willOverwriteRepaymentChain } from "./BundleDataClient/utils/FillUtils";
50
+ import { getRepaymentChainId, forceDestinationRepayment } from "./BundleDataClient/utils/FillUtils";
50
51
 
51
52
  type SpokePoolUpdateSuccess = {
52
53
  success: true;
@@ -310,7 +311,8 @@ export class SpokePoolClient extends BaseAbstractClient {
310
311
  * @returns The corresponding SlowFIllRequest event if found, otherwise undefined.
311
312
  */
312
313
  public getSlowFillRequest(relayData: RelayData): SlowFillRequestWithBlock | undefined {
313
- const hash = getRelayEventKey({ ...relayData, destinationChainId: this.chainId });
314
+ const messageHash = getMessageHash(relayData.message);
315
+ const hash = getRelayEventKey({ ...relayData, messageHash, destinationChainId: this.chainId });
314
316
  return this.slowFillRequests[hash];
315
317
  }
316
318
 
@@ -356,14 +358,8 @@ export class SpokePoolClient extends BaseAbstractClient {
356
358
  return;
357
359
  }
358
360
 
359
- /**
360
- * Find a valid fill for a given deposit.
361
- * @param deposit A deposit event.
362
- * @returns A valid fill for the deposit, or undefined.
363
- */
364
- public getFillForDeposit(deposit: Deposit): FillWithBlock | undefined {
365
- const fills = this.depositHashesToFills[getRelayEventKey(deposit)];
366
- return fills?.find((fill) => validateFillForDeposit(fill, deposit));
361
+ public getFillsForDeposit(deposit: Deposit): FillWithBlock[] {
362
+ return this.depositHashesToFills[this.getDepositHash(deposit)];
367
363
  }
368
364
 
369
365
  /**
@@ -379,8 +375,7 @@ export class SpokePoolClient extends BaseAbstractClient {
379
375
  invalidFills: Fill[];
380
376
  } {
381
377
  const { outputAmount } = deposit;
382
- const fillsForDeposit = this.depositHashesToFills[getRelayEventKey(deposit)];
383
-
378
+ const fillsForDeposit = this.depositHashesToFills[this.getDepositHash(deposit)];
384
379
  // If no fills then the full amount is remaining.
385
380
  if (fillsForDeposit === undefined || fillsForDeposit.length === 0) {
386
381
  return { unfilledAmount: outputAmount, fillCount: 0, invalidFills: [] };
@@ -400,7 +395,7 @@ export class SpokePoolClient extends BaseAbstractClient {
400
395
  this.hubPoolClient &&
401
396
  !isSlowFill(fill) &&
402
397
  (!isValidEvmAddress(fill.relayer) ||
403
- willOverwriteRepaymentChain(
398
+ forceDestinationRepayment(
404
399
  repaymentChainId,
405
400
  { ...deposit, quoteBlockNumber: this.hubPoolClient!.latestBlockSearched },
406
401
  this.hubPoolClient
@@ -609,12 +604,17 @@ export class SpokePoolClient extends BaseAbstractClient {
609
604
  }
610
605
  }
611
606
 
612
- if (eventsToQuery.includes("V3FundsDeposited")) {
613
- const depositEvents = queryResults[eventsToQuery.indexOf("V3FundsDeposited")] ?? [];
607
+ // Performs the indexing of a deposit-like spoke pool event.
608
+ const queryDepositEvents = async (eventName: string) => {
609
+ const depositEvents = queryResults[eventsToQuery.indexOf(eventName)] ?? [];
614
610
  if (depositEvents.length > 0) {
615
- this.log("debug", `Using ${depositEvents.length} newly queried deposit events for chain ${this.chainId}`, {
616
- earliestEvent: depositEvents[0].blockNumber,
617
- });
611
+ this.log(
612
+ "debug",
613
+ `Using ${depositEvents.length} newly queried ${eventName} deposit events for chain ${this.chainId}`,
614
+ {
615
+ earliestEvent: depositEvents[0].blockNumber,
616
+ }
617
+ );
618
618
  }
619
619
 
620
620
  // For each deposit, resolve its quoteTimestamp to a block number on the HubPool.
@@ -628,7 +628,7 @@ export class SpokePoolClient extends BaseAbstractClient {
628
628
  // Derive and append the common properties that are not part of the onchain event.
629
629
  const deposit = {
630
630
  ...spreadEventWithBlockNumber(event),
631
- messageHash: getMessageHash(event.args["message"]),
631
+ messageHash: getMessageHash(event.args.message),
632
632
  quoteBlockNumber,
633
633
  originChainId: this.chainId,
634
634
  // The following properties are placeholders to be updated immediately.
@@ -639,7 +639,7 @@ export class SpokePoolClient extends BaseAbstractClient {
639
639
  deposit.fromLiteChain = this.isOriginLiteChain(deposit);
640
640
  deposit.toLiteChain = this.isDestinationLiteChain(deposit);
641
641
 
642
- if (deposit.outputToken === ZERO_ADDRESS) {
642
+ if (isZeroAddress(deposit.outputToken)) {
643
643
  deposit.outputToken = this.getDestinationTokenForDeposit(deposit);
644
644
  }
645
645
 
@@ -656,11 +656,17 @@ export class SpokePoolClient extends BaseAbstractClient {
656
656
  this.latestDepositIdQueried = deposit.depositId;
657
657
  }
658
658
  }
659
+ };
660
+
661
+ for (const event of ["V3FundsDeposited", "FundsDeposited"]) {
662
+ if (eventsToQuery.includes(event)) {
663
+ await queryDepositEvents(event);
664
+ }
659
665
  }
660
666
 
661
- // Update deposits with speed up requests from depositor.
662
- if (eventsToQuery.includes("RequestedSpeedUpV3Deposit")) {
663
- const speedUpEvents = queryResults[eventsToQuery.indexOf("RequestedSpeedUpV3Deposit")] ?? [];
667
+ // Performs indexing of a "speed up deposit"-like event.
668
+ const querySpeedUpDepositEvents = (eventName: string) => {
669
+ const speedUpEvents = queryResults[eventsToQuery.indexOf(eventName)] ?? [];
664
670
 
665
671
  for (const event of speedUpEvents) {
666
672
  const speedUp = { ...spreadEventWithBlockNumber(event), originChainId: this.chainId } as SpeedUpWithBlock;
@@ -677,27 +683,45 @@ export class SpokePoolClient extends BaseAbstractClient {
677
683
  this.depositHashes[eventKey] = this.appendMaxSpeedUpSignatureToDeposit(deposit);
678
684
  }
679
685
  }
680
- }
686
+ };
687
+
688
+ // Update deposits with speed up requests from depositor.
689
+ ["RequestedSpeedUpV3Deposit", "RequestedSpeedUpDeposit"].forEach((event) => {
690
+ if (eventsToQuery.includes(event)) {
691
+ querySpeedUpDepositEvents(event);
692
+ }
693
+ });
681
694
 
682
- if (eventsToQuery.includes("RequestedV3SlowFill")) {
683
- const slowFillRequests = queryResults[eventsToQuery.indexOf("RequestedV3SlowFill")];
695
+ // Performs indexing of "requested slow fill"-like events.
696
+ const queryRequestedSlowFillEvents = (eventName: string) => {
697
+ const slowFillRequests = queryResults[eventsToQuery.indexOf(eventName)];
684
698
  for (const event of slowFillRequests) {
685
699
  const slowFillRequest = {
686
700
  ...spreadEventWithBlockNumber(event),
687
- messageHash: getMessageHash(event.args["message"]),
688
701
  destinationChainId: this.chainId,
689
702
  } as SlowFillRequestWithBlock;
690
703
 
704
+ if (eventName === "RequestedV3SlowFill") {
705
+ slowFillRequest.messageHash = getMessageHash(slowFillRequest.message);
706
+ }
707
+
691
708
  const depositHash = getRelayEventKey({ ...slowFillRequest, destinationChainId: this.chainId });
692
709
  this.slowFillRequests[depositHash] ??= slowFillRequest;
693
710
  }
694
- }
711
+ };
712
+
713
+ ["RequestedV3SlowFill", "RequestedSlowFill"].forEach((event) => {
714
+ if (eventsToQuery.includes(event)) {
715
+ queryRequestedSlowFillEvents(event);
716
+ }
717
+ });
695
718
 
696
- if (eventsToQuery.includes("FilledV3Relay")) {
697
- const fillEvents = queryResults[eventsToQuery.indexOf("FilledV3Relay")] ?? [];
719
+ // Performs indexing of filled relay-like events.
720
+ const queryFilledRelayEvents = (eventName: string) => {
721
+ const fillEvents = queryResults[eventsToQuery.indexOf(eventName)] ?? [];
698
722
 
699
723
  if (fillEvents.length > 0) {
700
- this.log("debug", `Using ${fillEvents.length} newly queried fill events for chain ${this.chainId}`, {
724
+ this.log("debug", `Using ${fillEvents.length} newly queried ${eventName} events for chain ${this.chainId}`, {
701
725
  earliestEvent: fillEvents[0].blockNumber,
702
726
  });
703
727
  }
@@ -707,13 +731,26 @@ export class SpokePoolClient extends BaseAbstractClient {
707
731
  for (const event of fillEvents) {
708
732
  const fill = {
709
733
  ...spreadEventWithBlockNumber(event),
734
+ messageHash: getMessageHash(event.args["message"]),
710
735
  destinationChainId: this.chainId,
711
736
  } as FillWithBlock;
712
737
 
738
+ if (eventName === "FilledV3Relay") {
739
+ fill.messageHash = getMessageHash(event.args.message);
740
+ fill.relayExecutionInfo.updatedMessageHash = getMessageHash(event.args.relayExecutionInfo.updatedMessage);
741
+ }
742
+
713
743
  assign(this.fills, [fill.originChainId], [fill]);
714
- assign(this.depositHashesToFills, [getRelayEventKey(fill)], [fill]);
744
+ assign(this.depositHashesToFills, [this.getDepositHash(fill)], [fill]);
715
745
  }
716
- }
746
+ };
747
+
748
+ // Update observed fills with ingested event data.
749
+ ["FilledV3Relay", "FilledRelay"].forEach((event) => {
750
+ if (eventsToQuery.includes(event)) {
751
+ queryFilledRelayEvents(event);
752
+ }
753
+ });
717
754
 
718
755
  if (eventsToQuery.includes("EnabledDepositRoute")) {
719
756
  const enableDepositsEvents = queryResults[eventsToQuery.indexOf("EnabledDepositRoute")];
@@ -893,7 +930,7 @@ export class SpokePoolClient extends BaseAbstractClient {
893
930
  toLiteChain: true, // To be updated immediately afterwards.
894
931
  } as DepositWithBlock;
895
932
 
896
- if (deposit.outputToken === ZERO_ADDRESS) {
933
+ if (isZeroAddress(deposit.outputToken)) {
897
934
  deposit.outputToken = this.getDestinationTokenForDeposit(deposit);
898
935
  }
899
936
  deposit.fromLiteChain = this.isOriginLiteChain(deposit);
@@ -12,12 +12,23 @@ import {
12
12
  SlowFillRequest,
13
13
  SortableEvent,
14
14
  Fill,
15
- FillWithBlock,
16
15
  SlowFillLeaf,
17
16
  SpeedUp,
18
17
  TokensBridged,
19
18
  } from "../../interfaces";
20
- import { toBN, toBNWei, getCurrentTime, randomAddress, BigNumber, bnZero, bnOne, bnMax } from "../../utils";
19
+ import {
20
+ toBN,
21
+ toBNWei,
22
+ getCurrentTime,
23
+ getMessageHash,
24
+ randomAddress,
25
+ BigNumber,
26
+ bnZero,
27
+ bnMax,
28
+ bnOne,
29
+ toAddress,
30
+ toBytes32,
31
+ } from "../../utils";
21
32
  import { SpokePoolClient, SpokePoolUpdate } from "../SpokePoolClient";
22
33
  import { HubPoolClient } from "../HubPoolClient";
23
34
  import { EventManager, EventOverrides, getEventManager } from "./MockEvents";
@@ -119,18 +130,28 @@ export class MockSpokePoolClient extends SpokePoolClient {
119
130
  EnabledDepositRoute: "address,uint256,bool",
120
131
  };
121
132
 
133
+ deposit(deposit: Omit<Deposit, "messageHash"> & Partial<SortableEvent>): Log {
134
+ return this._deposit("FundsDeposited", deposit);
135
+ }
136
+
122
137
  depositV3(deposit: Omit<Deposit, "messageHash"> & Partial<SortableEvent>): Log {
123
- const event = "V3FundsDeposited";
138
+ return this._deposit("V3FundsDeposited", deposit);
139
+ }
124
140
 
141
+ protected _deposit(event: string, deposit: Omit<Deposit, "messageHash"> & Partial<SortableEvent>): Log {
125
142
  const { blockNumber, transactionIndex } = deposit;
126
- let { depositId, depositor, destinationChainId, inputToken, inputAmount, outputToken, outputAmount } = deposit;
143
+ let { depositId, destinationChainId, inputAmount, outputAmount } = deposit;
127
144
  depositId ??= this.numberOfDeposits;
128
145
  this.numberOfDeposits = depositId.add(bnOne);
129
146
 
130
147
  destinationChainId ??= random(1, 42161, false);
131
- depositor ??= randomAddress();
132
- inputToken ??= randomAddress();
133
- outputToken ??= inputToken;
148
+ const addressModifier = event === "FundsDeposited" ? toBytes32 : toAddress;
149
+ const depositor = addressModifier(deposit.depositor ?? randomAddress());
150
+ const recipient = addressModifier(deposit.recipient ?? depositor);
151
+ const inputToken = addressModifier(deposit.inputToken ?? randomAddress());
152
+ const outputToken = addressModifier(deposit.outputToken ?? inputToken);
153
+ const exclusiveRelayer = addressModifier(deposit.exclusiveRelayer ?? ZERO_ADDRESS);
154
+
134
155
  inputAmount ??= toBNWei(random(1, 1000, false));
135
156
  outputAmount ??= inputAmount.mul(toBN("0.95"));
136
157
 
@@ -142,14 +163,14 @@ export class MockSpokePoolClient extends SpokePoolClient {
142
163
  originChainId: deposit.originChainId ?? this.chainId,
143
164
  destinationChainId,
144
165
  depositor,
145
- recipient: deposit.recipient ?? depositor,
166
+ recipient,
146
167
  inputToken,
147
168
  inputAmount,
148
169
  outputToken,
149
170
  outputAmount,
150
171
  quoteTimestamp,
151
172
  fillDeadline: deposit.fillDeadline ?? quoteTimestamp + 3600,
152
- exclusiveRelayer: deposit.exclusiveRelayer ?? ZERO_ADDRESS,
173
+ exclusiveRelayer,
153
174
  exclusivityDeadline: deposit.exclusivityDeadline ?? quoteTimestamp + 600,
154
175
  message,
155
176
  };
@@ -164,26 +185,47 @@ export class MockSpokePoolClient extends SpokePoolClient {
164
185
  });
165
186
  }
166
187
 
167
- fillV3Relay(fill: Omit<Fill, "messageHash"> & Partial<SortableEvent>): Log {
168
- const event = "FilledV3Relay";
188
+ fillV3Relay(fill: Omit<Fill, "messageHash"> & { message: string } & Partial<SortableEvent>): Log {
189
+ return this._fillRelay("FilledV3Relay", fill);
190
+ }
169
191
 
192
+ fillRelay(fill: Omit<Fill, "messageHash"> & { message: string } & Partial<SortableEvent>): Log {
193
+ return this._fillRelay("FilledRelay", fill);
194
+ }
195
+
196
+ protected _fillRelay(
197
+ event: string,
198
+ fill: Omit<Fill, "messageHash"> & { message: string } & Partial<SortableEvent>
199
+ ): Log {
170
200
  const { blockNumber, transactionIndex } = fill;
171
- let { originChainId, depositId, inputToken, inputAmount, outputAmount, fillDeadline, relayer } = fill;
201
+ let { originChainId, depositId, inputAmount, outputAmount, fillDeadline } = fill;
172
202
  originChainId ??= random(1, 42161, false);
173
203
  depositId ??= BigNumber.from(random(1, 100_000, false));
174
- inputToken ??= randomAddress();
175
204
  inputAmount ??= toBNWei(random(1, 1000, false));
176
205
  outputAmount ??= inputAmount;
177
206
  fillDeadline ??= getCurrentTime() + 60;
178
- relayer ??= randomAddress();
179
207
 
180
- const topics = [originChainId, depositId, relayer];
181
- const recipient = fill.recipient ?? randomAddress();
208
+ const addressModifier = event === "FilledRelay" ? toBytes32 : toAddress;
209
+ const depositor = addressModifier(fill.depositor ?? randomAddress());
210
+ const recipient = addressModifier(fill.recipient ?? depositor);
211
+ const inputToken = addressModifier(fill.inputToken ?? randomAddress());
212
+ const outputToken = addressModifier(fill.outputToken ?? ZERO_ADDRESS);
213
+ const exclusiveRelayer = addressModifier(fill.exclusiveRelayer ?? ZERO_ADDRESS);
214
+ const relayer = addressModifier(fill.relayer ?? randomAddress());
215
+
216
+ const topics = [originChainId, depositId, relayer]; // @todo verify
182
217
  const message = fill["message"] ?? "0x";
218
+ const updatedMessage = fill.relayExecutionInfo?.updatedMessage ?? message;
183
219
 
184
- const args = {
220
+ const relayExecutionInfo = {
221
+ updatedRecipient: fill.relayExecutionInfo?.updatedRecipient ?? recipient,
222
+ updatedOutputAmount: fill.relayExecutionInfo?.updatedOutputAmount ?? outputAmount,
223
+ fillType: fill.relayExecutionInfo?.fillType ?? FillType.FastFill,
224
+ };
225
+
226
+ const _args = {
185
227
  inputToken,
186
- outputToken: fill.outputToken ?? ZERO_ADDRESS, // resolved via HubPoolClient.
228
+ outputToken,
187
229
  inputAmount: fill.inputAmount,
188
230
  outputAmount: fill.outputAmount,
189
231
  repaymentChainId: fill.repaymentChainId ?? this.chainId,
@@ -191,19 +233,40 @@ export class MockSpokePoolClient extends SpokePoolClient {
191
233
  depositId,
192
234
  fillDeadline,
193
235
  exclusivityDeadline: fill.exclusivityDeadline ?? fillDeadline,
194
- exclusiveRelayer: fill.exclusiveRelayer ?? ZERO_ADDRESS,
236
+ exclusiveRelayer,
195
237
  relayer,
196
- depositor: fill.depositor ?? randomAddress(),
238
+ depositor,
197
239
  recipient,
198
240
  message,
199
241
  relayExecutionInfo: {
200
242
  updatedRecipient: fill.relayExecutionInfo?.updatedRecipient ?? recipient,
201
- updatedMessage: fill.relayExecutionInfo?.updatedMessage ?? message,
243
+ updatedMessage,
244
+ updatedMessageHash: getMessageHash(updatedMessage),
202
245
  updatedOutputAmount: fill.relayExecutionInfo?.updatedOutputAmount ?? outputAmount,
203
246
  fillType: fill.relayExecutionInfo?.fillType ?? FillType.FastFill,
204
247
  },
205
248
  };
206
249
 
250
+ const args =
251
+ event === "FilledRelay"
252
+ ? {
253
+ ..._args,
254
+ messageHash: getMessageHash(message),
255
+ relayExecutionInfo: {
256
+ ...relayExecutionInfo,
257
+ updatedMessageHash: fill.relayExecutionInfo.updatedMessageHash ?? getMessageHash(fill.message),
258
+ },
259
+ }
260
+ : {
261
+ // FilledV3Relay
262
+ ..._args,
263
+ message,
264
+ relayExecutionInfo: {
265
+ ...relayExecutionInfo,
266
+ updatedMessage: fill.relayExecutionInfo?.updatedMessage ?? message,
267
+ },
268
+ };
269
+
207
270
  return this.eventManager.generateEvent({
208
271
  event,
209
272
  address: this.spokePool.address,
@@ -215,15 +278,28 @@ export class MockSpokePoolClient extends SpokePoolClient {
215
278
  }
216
279
 
217
280
  speedUpV3Deposit(speedUp: SpeedUp): Log {
218
- const event = "RequestedSpeedUpV3Deposit";
219
- const topics = [speedUp.depositId, speedUp.depositor];
281
+ return this._speedUpDeposit("RequestedSpeedUpV3Deposit", speedUp);
282
+ }
283
+
284
+ speedUpDeposit(speedUp: SpeedUp): Log {
285
+ return this._speedUpDeposit("RequestedSpeedUpDeposit", speedUp);
286
+ }
287
+
288
+ protected _speedUpDeposit(event: string, speedUp: SpeedUp): Log {
289
+ const addressModifier = event === "RequestedSpeedUpDeposit" ? toBytes32 : toAddress;
290
+ const depositor = addressModifier(speedUp.depositor);
291
+ const topics = [speedUp.depositId, depositor];
220
292
  const args = { ...speedUp };
221
293
 
222
294
  return this.eventManager.generateEvent({
223
295
  event,
224
296
  address: this.spokePool.address,
225
297
  topics: topics.map((topic) => topic.toString()),
226
- args,
298
+ args: {
299
+ ...args,
300
+ depositor,
301
+ updatedRecipient: addressModifier(speedUp.updatedRecipient),
302
+ },
227
303
  });
228
304
  }
229
305
 
@@ -241,17 +317,36 @@ export class MockSpokePoolClient extends SpokePoolClient {
241
317
  }
242
318
 
243
319
  requestV3SlowFill(request: Omit<SlowFillRequest, "messageHash"> & Partial<SortableEvent>): Log {
244
- const event = "RequestedV3SlowFill";
320
+ return this._requestSlowFill("RequestedV3SlowFill", request);
321
+ }
322
+
323
+ requestSlowFill(request: Omit<SlowFillRequest, "messageHash"> & Partial<SortableEvent>): Log {
324
+ return this._requestSlowFill("RequestedSlowFill", request);
325
+ }
245
326
 
327
+ protected _requestSlowFill(
328
+ event: string,
329
+ request: Omit<SlowFillRequest, "messageHash"> & Partial<SortableEvent>
330
+ ): Log {
246
331
  const { originChainId, depositId } = request;
247
332
  const topics = [originChainId, depositId];
248
333
  const args = { ...request };
249
334
 
335
+ const addressModifier = event === "RequestedSlowFill" ? toBytes32 : toAddress;
336
+ const depositor = addressModifier(args.depositor ?? randomAddress());
337
+
250
338
  return this.eventManager.generateEvent({
251
339
  event,
252
340
  address: this.spokePool.address,
253
341
  topics: topics.map((topic) => topic.toString()),
254
- args,
342
+ args: {
343
+ ...args,
344
+ depositor,
345
+ recipient: addressModifier(args.recipient ?? depositor),
346
+ inputToken: addressModifier(args.inputToken ?? randomAddress()),
347
+ outputToken: addressModifier(args.outputToken ?? ZERO_ADDRESS),
348
+ exclusiveRelayer: addressModifier(args.exclusiveRelayer ?? ZERO_ADDRESS),
349
+ },
255
350
  blockNumber: request.blockNumber,
256
351
  transactionIndex: request.transactionIndex,
257
352
  });
@@ -259,8 +354,8 @@ export class MockSpokePoolClient extends SpokePoolClient {
259
354
 
260
355
  // This is a simple wrapper around fillV3Relay().
261
356
  // rootBundleId and proof are discarded here - we have no interest in verifying that.
262
- executeV3SlowRelayLeaf(leaf: SlowFillLeaf): Log {
263
- const fill: Fill = {
357
+ executeV3SlowRelayLeaf(leaf: Omit<SlowFillLeaf, "messageHash">): Log {
358
+ const fill = {
264
359
  ...leaf.relayData,
265
360
  destinationChainId: this.chainId,
266
361
  relayer: ZERO_ADDRESS,
@@ -269,11 +364,12 @@ export class MockSpokePoolClient extends SpokePoolClient {
269
364
  updatedRecipient: leaf.relayData.recipient,
270
365
  updatedOutputAmount: leaf.updatedOutputAmount,
271
366
  updatedMessage: leaf.relayData.message,
367
+ updatedMessageHash: getMessageHash(leaf.relayData.message),
272
368
  fillType: FillType.SlowFill,
273
369
  },
274
370
  };
275
371
 
276
- return this.fillV3Relay(fill as FillWithBlock);
372
+ return this.fillV3Relay(fill);
277
373
  }
278
374
 
279
375
  executeRelayerRefundLeaf(refund: RelayerRefundExecution & Partial<SortableEvent>): Log {
package/src/constants.ts CHANGED
@@ -35,7 +35,11 @@ export const PRE_FILL_MIN_CONFIG_STORE_VERSION = 5;
35
35
  export const ARWEAVE_TAG_APP_NAME = "across-protocol";
36
36
 
37
37
  // A hardcoded version number used, by default, to tag all Arweave records.
38
- export const ARWEAVE_TAG_APP_VERSION = 3;
38
+ // Version 3:
39
+ // - Changed depositId number -> string (uint32 -> uint256).
40
+ // Version 4:
41
+ // - Dropped message field from Fill event data.
42
+ export const ARWEAVE_TAG_APP_VERSION = 4;
39
43
 
40
44
  /**
41
45
  * A default list of chain Ids that the protocol supports. This is outlined
@@ -56,6 +60,7 @@ export const DEFAULT_SIMULATED_RELAYER_ADDRESS_TEST = "0x9A8f92a830A5cB89a3816e3
56
60
  export const DEFAULT_ARWEAVE_STORAGE_ADDRESS = "Z6hjBM8FHu90lYWB8o5jR1dfX92FlV2WBaND9xgp8Lg";
57
61
 
58
62
  export const EMPTY_MESSAGE = "0x";
63
+ export const UNDEFINED_MESSAGE_HASH = "";
59
64
 
60
65
  export const BRIDGED_USDC_SYMBOLS = [
61
66
  TOKEN_SYMBOLS_MAP["USDC.e"].symbol,
@@ -52,11 +52,13 @@ export enum FillType {
52
52
  export interface RelayExecutionEventInfo {
53
53
  updatedRecipient: string;
54
54
  updatedOutputAmount: BigNumber;
55
- updatedMessage: string;
55
+ updatedMessage?: string;
56
+ updatedMessageHash: string;
56
57
  fillType: FillType;
57
58
  }
58
59
 
59
- export interface Fill extends RelayData {
60
+ export interface Fill extends Omit<RelayData, "message"> {
61
+ messageHash: string;
60
62
  destinationChainId: number;
61
63
  relayer: string;
62
64
  repaymentChainId: number;