@across-protocol/sdk 4.0.3-beta.0 → 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 (106) 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.js +127 -80
  11. package/dist/cjs/clients/SpokePoolClient.js.map +1 -1
  12. package/dist/cjs/clients/mocks/MockSpokePoolClient.d.ts +16 -2
  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 +4 -2
  19. package/dist/cjs/package.json +1 -0
  20. package/dist/cjs/utils/AddressUtils.d.ts +1 -0
  21. package/dist/cjs/utils/AddressUtils.js +5 -1
  22. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  23. package/dist/cjs/utils/CachingUtils.js +1 -1
  24. package/dist/cjs/utils/CachingUtils.js.map +1 -1
  25. package/dist/cjs/utils/DepositUtils.d.ts +1 -1
  26. package/dist/cjs/utils/DepositUtils.js +11 -8
  27. package/dist/cjs/utils/DepositUtils.js.map +1 -1
  28. package/dist/cjs/utils/FlowUtils.d.ts +4 -3
  29. package/dist/cjs/utils/FlowUtils.js +5 -1
  30. package/dist/cjs/utils/FlowUtils.js.map +1 -1
  31. package/dist/cjs/utils/SpokeUtils.d.ts +6 -3
  32. package/dist/cjs/utils/SpokeUtils.js +2 -2
  33. package/dist/cjs/utils/SpokeUtils.js.map +1 -1
  34. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +2 -1
  35. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +29 -13
  36. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  37. package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +1 -1
  38. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +2 -2
  39. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  40. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +6 -3
  41. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +3 -2
  42. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  43. package/dist/esm/clients/SpokePoolClient.js +135 -85
  44. package/dist/esm/clients/SpokePoolClient.js.map +1 -1
  45. package/dist/esm/clients/mocks/MockSpokePoolClient.d.ts +16 -2
  46. package/dist/esm/clients/mocks/MockSpokePoolClient.js +79 -37
  47. package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
  48. package/dist/esm/constants.d.ts +2 -1
  49. package/dist/esm/constants.js +6 -1
  50. package/dist/esm/constants.js.map +1 -1
  51. package/dist/esm/interfaces/SpokePool.d.ts +4 -2
  52. package/dist/esm/package.json +1 -0
  53. package/dist/esm/utils/AddressUtils.d.ts +1 -0
  54. package/dist/esm/utils/AddressUtils.js +7 -4
  55. package/dist/esm/utils/AddressUtils.js.map +1 -1
  56. package/dist/esm/utils/CachingUtils.js +2 -2
  57. package/dist/esm/utils/CachingUtils.js.map +1 -1
  58. package/dist/esm/utils/DepositUtils.d.ts +1 -1
  59. package/dist/esm/utils/DepositUtils.js +12 -9
  60. package/dist/esm/utils/DepositUtils.js.map +1 -1
  61. package/dist/esm/utils/FlowUtils.d.ts +4 -3
  62. package/dist/esm/utils/FlowUtils.js +6 -1
  63. package/dist/esm/utils/FlowUtils.js.map +1 -1
  64. package/dist/esm/utils/SpokeUtils.d.ts +6 -3
  65. package/dist/esm/utils/SpokeUtils.js +2 -2
  66. package/dist/esm/utils/SpokeUtils.js.map +1 -1
  67. package/dist/esm/utils/abi/typechain/Multicall3.d.ts +4 -1
  68. package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.js.map +1 -1
  69. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +2 -1
  70. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  71. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +1 -1
  72. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  73. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +6 -3
  74. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
  75. package/dist/types/clients/SpokePoolClient.d.ts.map +1 -1
  76. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts +16 -2
  77. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts.map +1 -1
  78. package/dist/types/constants.d.ts +2 -1
  79. package/dist/types/constants.d.ts.map +1 -1
  80. package/dist/types/interfaces/SpokePool.d.ts +4 -2
  81. package/dist/types/interfaces/SpokePool.d.ts.map +1 -1
  82. package/dist/types/utils/AddressUtils.d.ts +1 -0
  83. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  84. package/dist/types/utils/DepositUtils.d.ts +1 -1
  85. package/dist/types/utils/DepositUtils.d.ts.map +1 -1
  86. package/dist/types/utils/FlowUtils.d.ts +4 -3
  87. package/dist/types/utils/FlowUtils.d.ts.map +1 -1
  88. package/dist/types/utils/SpokeUtils.d.ts +6 -3
  89. package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
  90. package/dist/types/utils/abi/typechain/Multicall3.d.ts +4 -1
  91. package/dist/types/utils/abi/typechain/Multicall3.d.ts.map +1 -1
  92. package/dist/types/utils/abi/typechain/common.d.ts.map +1 -1
  93. package/dist/types/utils/abi/typechain/factories/Multicall3__factory.d.ts.map +1 -1
  94. package/package.json +1 -1
  95. package/src/clients/BundleDataClient/BundleDataClient.ts +30 -13
  96. package/src/clients/BundleDataClient/utils/FillUtils.ts +2 -2
  97. package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +6 -3
  98. package/src/clients/SpokePoolClient.ts +67 -23
  99. package/src/clients/mocks/MockSpokePoolClient.ts +125 -29
  100. package/src/constants.ts +6 -1
  101. package/src/interfaces/SpokePool.ts +4 -2
  102. package/src/utils/AddressUtils.ts +8 -4
  103. package/src/utils/CachingUtils.ts +2 -2
  104. package/src/utils/DepositUtils.ts +8 -3
  105. package/src/utils/FlowUtils.ts +10 -4
  106. 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
 
@@ -400,7 +402,7 @@ export class SpokePoolClient extends BaseAbstractClient {
400
402
  this.hubPoolClient &&
401
403
  !isSlowFill(fill) &&
402
404
  (!isValidEvmAddress(fill.relayer) ||
403
- willOverwriteRepaymentChain(
405
+ forceDestinationRepayment(
404
406
  repaymentChainId,
405
407
  { ...deposit, quoteBlockNumber: this.hubPoolClient!.latestBlockSearched },
406
408
  this.hubPoolClient
@@ -609,12 +611,17 @@ export class SpokePoolClient extends BaseAbstractClient {
609
611
  }
610
612
  }
611
613
 
612
- if (eventsToQuery.includes("V3FundsDeposited")) {
613
- 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)] ?? [];
614
617
  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
- });
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
+ );
618
625
  }
619
626
 
620
627
  // For each deposit, resolve its quoteTimestamp to a block number on the HubPool.
@@ -628,7 +635,7 @@ export class SpokePoolClient extends BaseAbstractClient {
628
635
  // Derive and append the common properties that are not part of the onchain event.
629
636
  const deposit = {
630
637
  ...spreadEventWithBlockNumber(event),
631
- messageHash: getMessageHash(event.args["message"]),
638
+ messageHash: getMessageHash(event.args.message),
632
639
  quoteBlockNumber,
633
640
  originChainId: this.chainId,
634
641
  // The following properties are placeholders to be updated immediately.
@@ -639,7 +646,7 @@ export class SpokePoolClient extends BaseAbstractClient {
639
646
  deposit.fromLiteChain = this.isOriginLiteChain(deposit);
640
647
  deposit.toLiteChain = this.isDestinationLiteChain(deposit);
641
648
 
642
- if (deposit.outputToken === ZERO_ADDRESS) {
649
+ if (isZeroAddress(deposit.outputToken)) {
643
650
  deposit.outputToken = this.getDestinationTokenForDeposit(deposit);
644
651
  }
645
652
 
@@ -656,11 +663,17 @@ export class SpokePoolClient extends BaseAbstractClient {
656
663
  this.latestDepositIdQueried = deposit.depositId;
657
664
  }
658
665
  }
666
+ };
667
+
668
+ for (const event of ["V3FundsDeposited", "FundsDeposited"]) {
669
+ if (eventsToQuery.includes(event)) {
670
+ await queryDepositEvents(event);
671
+ }
659
672
  }
660
673
 
661
- // Update deposits with speed up requests from depositor.
662
- if (eventsToQuery.includes("RequestedSpeedUpV3Deposit")) {
663
- 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)] ?? [];
664
677
 
665
678
  for (const event of speedUpEvents) {
666
679
  const speedUp = { ...spreadEventWithBlockNumber(event), originChainId: this.chainId } as SpeedUpWithBlock;
@@ -677,27 +690,45 @@ export class SpokePoolClient extends BaseAbstractClient {
677
690
  this.depositHashes[eventKey] = this.appendMaxSpeedUpSignatureToDeposit(deposit);
678
691
  }
679
692
  }
680
- }
693
+ };
681
694
 
682
- if (eventsToQuery.includes("RequestedV3SlowFill")) {
683
- const slowFillRequests = queryResults[eventsToQuery.indexOf("RequestedV3SlowFill")];
695
+ // Update deposits with speed up requests from depositor.
696
+ ["RequestedSpeedUpV3Deposit", "RequestedSpeedUpDeposit"].forEach((event) => {
697
+ if (eventsToQuery.includes(event)) {
698
+ querySpeedUpDepositEvents(event);
699
+ }
700
+ });
701
+
702
+ // Performs indexing of "requested slow fill"-like events.
703
+ const queryRequestedSlowFillEvents = (eventName: string) => {
704
+ const slowFillRequests = queryResults[eventsToQuery.indexOf(eventName)];
684
705
  for (const event of slowFillRequests) {
685
706
  const slowFillRequest = {
686
707
  ...spreadEventWithBlockNumber(event),
687
- messageHash: getMessageHash(event.args["message"]),
688
708
  destinationChainId: this.chainId,
689
709
  } as SlowFillRequestWithBlock;
690
710
 
711
+ if (eventName === "RequestedV3SlowFill") {
712
+ slowFillRequest.messageHash = getMessageHash(slowFillRequest.message);
713
+ }
714
+
691
715
  const depositHash = getRelayEventKey({ ...slowFillRequest, destinationChainId: this.chainId });
692
716
  this.slowFillRequests[depositHash] ??= slowFillRequest;
693
717
  }
694
- }
718
+ };
695
719
 
696
- if (eventsToQuery.includes("FilledV3Relay")) {
697
- const fillEvents = queryResults[eventsToQuery.indexOf("FilledV3Relay")] ?? [];
720
+ ["RequestedV3SlowFill", "RequestedSlowFill"].forEach((event) => {
721
+ if (eventsToQuery.includes(event)) {
722
+ queryRequestedSlowFillEvents(event);
723
+ }
724
+ });
725
+
726
+ // Performs indexing of filled relay-like events.
727
+ const queryFilledRelayEvents = (eventName: string) => {
728
+ const fillEvents = queryResults[eventsToQuery.indexOf(eventName)] ?? [];
698
729
 
699
730
  if (fillEvents.length > 0) {
700
- 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}`, {
701
732
  earliestEvent: fillEvents[0].blockNumber,
702
733
  });
703
734
  }
@@ -707,13 +738,26 @@ export class SpokePoolClient extends BaseAbstractClient {
707
738
  for (const event of fillEvents) {
708
739
  const fill = {
709
740
  ...spreadEventWithBlockNumber(event),
741
+ messageHash: getMessageHash(event.args["message"]),
710
742
  destinationChainId: this.chainId,
711
743
  } as FillWithBlock;
712
744
 
745
+ if (eventName === "FilledV3Relay") {
746
+ fill.messageHash = getMessageHash(event.args.message);
747
+ fill.relayExecutionInfo.updatedMessageHash = getMessageHash(event.args.relayExecutionInfo.updatedMessage);
748
+ }
749
+
713
750
  assign(this.fills, [fill.originChainId], [fill]);
714
751
  assign(this.depositHashesToFills, [getRelayEventKey(fill)], [fill]);
715
752
  }
716
- }
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
+ });
717
761
 
718
762
  if (eventsToQuery.includes("EnabledDepositRoute")) {
719
763
  const enableDepositsEvents = queryResults[eventsToQuery.indexOf("EnabledDepositRoute")];
@@ -893,7 +937,7 @@ export class SpokePoolClient extends BaseAbstractClient {
893
937
  toLiteChain: true, // To be updated immediately afterwards.
894
938
  } as DepositWithBlock;
895
939
 
896
- if (deposit.outputToken === ZERO_ADDRESS) {
940
+ if (isZeroAddress(deposit.outputToken)) {
897
941
  deposit.outputToken = this.getDestinationTokenForDeposit(deposit);
898
942
  }
899
943
  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;
@@ -39,10 +39,14 @@ export function compareAddressesSimple(addressA?: string, addressB?: string): bo
39
39
  return addressA.toLowerCase() === addressB.toLowerCase();
40
40
  }
41
41
 
42
- // Converts an input (assumed to be) bytes32 string into a bytes20 string.
43
- // If the input is not a bytes32 but is less than type(uint160).max, then this function
44
- // will still succeed.
45
- // Throws an error if the string as an unsigned integer is greater than type(uint160).max.
42
+ // Converts an input hex data string into a bytes32 string. Note that the output bytes will be lowercase
43
+ // so that it naturally matches with ethers event data.
44
+ // Throws an error if the input string is already greater than 32 bytes.
45
+ export function toBytes32(address: string): string {
46
+ return utils.hexZeroPad(address, 32).toLowerCase();
47
+ }
48
+
49
+ // Checks if the input string can be coerced into a bytes20 evm address. Returns true if it is possible, and false otherwise.
46
50
  export function toAddress(hexString: string): string {
47
51
  // rawAddress is the address which is not properly checksummed.
48
52
  const rawAddress = utils.hexZeroPad(utils.hexStripZeros(hexString), 20);
@@ -2,7 +2,7 @@ import { DEFAULT_CACHING_SAFE_LAG, DEFAULT_CACHING_TTL } from "../constants";
2
2
  import { CachingMechanismInterface, Deposit, Fill, SlowFillRequest } from "../interfaces";
3
3
  import { assert } from "./LogUtils";
4
4
  import { composeRevivers, objectWithBigNumberReviver } from "./ReviverUtils";
5
- import { getRelayHashFromEvent } from "./SpokeUtils";
5
+ import { getRelayEventKey } from "./SpokeUtils";
6
6
  import { getCurrentTime } from "./TimeUtils";
7
7
  import { isDefined } from "./TypeGuards";
8
8
 
@@ -51,6 +51,6 @@ export async function setDepositInCache(
51
51
  * @returns The key for caching the event.
52
52
  */
53
53
  export function getDepositKey(bridgeEvent: Deposit | Fill | SlowFillRequest): string {
54
- const relayHash = getRelayHashFromEvent(bridgeEvent);
54
+ const relayHash = getRelayEventKey(bridgeEvent);
55
55
  return `deposit_${bridgeEvent.originChainId}_${bridgeEvent.depositId.toString()}_${relayHash}`;
56
56
  }