@across-protocol/sdk 4.1.46-beta.0 → 4.1.46-beta.2

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 (128) hide show
  1. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  2. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +15 -11
  3. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
  4. package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +0 -2
  5. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +75 -47
  6. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  7. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +10 -1
  8. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  9. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +7 -7
  10. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +48 -37
  11. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  12. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  13. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js +2 -2
  14. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
  15. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +48 -20
  16. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +8 -6
  17. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  18. package/dist/cjs/clients/HubPoolClient.d.ts +3 -2
  19. package/dist/cjs/clients/HubPoolClient.js +65 -32
  20. package/dist/cjs/clients/HubPoolClient.js.map +1 -1
  21. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js +1 -1
  22. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  23. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.d.ts +1 -0
  24. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +20 -6
  25. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  26. package/dist/cjs/clients/mocks/MockConfigStoreClient.js +2 -2
  27. package/dist/cjs/clients/mocks/MockConfigStoreClient.js.map +1 -1
  28. package/dist/cjs/clients/mocks/MockHubPoolClient.d.ts +3 -3
  29. package/dist/cjs/clients/mocks/MockHubPoolClient.js +35 -7
  30. package/dist/cjs/clients/mocks/MockHubPoolClient.js.map +1 -1
  31. package/dist/cjs/clients/mocks/MockSpokePoolClient.js +5 -5
  32. package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
  33. package/dist/cjs/interfaces/Common.d.ts +2 -2
  34. package/dist/cjs/utils/AddressUtils.d.ts +1 -0
  35. package/dist/cjs/utils/AddressUtils.js +3 -0
  36. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  37. package/dist/cjs/utils/DepositUtils.d.ts +1 -0
  38. package/dist/cjs/utils/DepositUtils.js +5 -1
  39. package/dist/cjs/utils/DepositUtils.js.map +1 -1
  40. package/dist/cjs/utils/EventUtils.d.ts +2 -1
  41. package/dist/cjs/utils/EventUtils.js +21 -12
  42. package/dist/cjs/utils/EventUtils.js.map +1 -1
  43. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  44. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +15 -11
  45. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
  46. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +0 -2
  47. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +82 -52
  48. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  49. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +16 -1
  50. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  51. package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +28 -7
  52. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +84 -51
  53. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  54. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  55. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js +2 -2
  56. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
  57. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +48 -20
  58. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +5 -3
  59. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  60. package/dist/esm/clients/HubPoolClient.d.ts +3 -16
  61. package/dist/esm/clients/HubPoolClient.js +77 -52
  62. package/dist/esm/clients/HubPoolClient.js.map +1 -1
  63. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js +2 -2
  64. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  65. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.d.ts +1 -0
  66. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +29 -15
  67. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  68. package/dist/esm/clients/mocks/MockConfigStoreClient.js +3 -3
  69. package/dist/esm/clients/mocks/MockConfigStoreClient.js.map +1 -1
  70. package/dist/esm/clients/mocks/MockHubPoolClient.d.ts +3 -3
  71. package/dist/esm/clients/mocks/MockHubPoolClient.js +35 -7
  72. package/dist/esm/clients/mocks/MockHubPoolClient.js.map +1 -1
  73. package/dist/esm/clients/mocks/MockSpokePoolClient.js +5 -5
  74. package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
  75. package/dist/esm/interfaces/Common.d.ts +2 -2
  76. package/dist/esm/utils/AddressUtils.d.ts +1 -0
  77. package/dist/esm/utils/AddressUtils.js +3 -0
  78. package/dist/esm/utils/AddressUtils.js.map +1 -1
  79. package/dist/esm/utils/DepositUtils.d.ts +1 -0
  80. package/dist/esm/utils/DepositUtils.js +5 -1
  81. package/dist/esm/utils/DepositUtils.js.map +1 -1
  82. package/dist/esm/utils/EventUtils.d.ts +2 -1
  83. package/dist/esm/utils/EventUtils.js +18 -10
  84. package/dist/esm/utils/EventUtils.js.map +1 -1
  85. package/dist/types/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  86. package/dist/types/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts.map +1 -1
  87. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +0 -2
  88. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  89. package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts.map +1 -1
  90. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +28 -7
  91. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  92. package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  93. package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts.map +1 -1
  94. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +48 -20
  95. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
  96. package/dist/types/clients/HubPoolClient.d.ts +3 -16
  97. package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
  98. package/dist/types/clients/SpokePoolClient/EVMSpokePoolClient.d.ts.map +1 -1
  99. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts +1 -0
  100. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
  101. package/dist/types/clients/mocks/MockConfigStoreClient.d.ts.map +1 -1
  102. package/dist/types/clients/mocks/MockHubPoolClient.d.ts +3 -3
  103. package/dist/types/clients/mocks/MockHubPoolClient.d.ts.map +1 -1
  104. package/dist/types/interfaces/Common.d.ts +2 -2
  105. package/dist/types/interfaces/Common.d.ts.map +1 -1
  106. package/dist/types/utils/AddressUtils.d.ts +1 -0
  107. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  108. package/dist/types/utils/DepositUtils.d.ts +1 -0
  109. package/dist/types/utils/DepositUtils.d.ts.map +1 -1
  110. package/dist/types/utils/EventUtils.d.ts +2 -1
  111. package/dist/types/utils/EventUtils.d.ts.map +1 -1
  112. package/package.json +1 -1
  113. package/src/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.ts +17 -15
  114. package/src/clients/BundleDataClient/BundleDataClient.ts +144 -62
  115. package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +36 -1
  116. package/src/clients/BundleDataClient/utils/FillUtils.ts +132 -72
  117. package/src/clients/BundleDataClient/utils/PoolRebalanceUtils.ts +3 -2
  118. package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +7 -3
  119. package/src/clients/HubPoolClient.ts +97 -62
  120. package/src/clients/SpokePoolClient/EVMSpokePoolClient.ts +2 -1
  121. package/src/clients/SpokePoolClient/SpokePoolClient.ts +55 -17
  122. package/src/clients/mocks/MockConfigStoreClient.ts +10 -3
  123. package/src/clients/mocks/MockHubPoolClient.ts +41 -10
  124. package/src/clients/mocks/MockSpokePoolClient.ts +5 -5
  125. package/src/interfaces/Common.ts +2 -2
  126. package/src/utils/AddressUtils.ts +4 -0
  127. package/src/utils/DepositUtils.ts +6 -1
  128. package/src/utils/EventUtils.ts +19 -13
@@ -17,6 +17,7 @@ import {
17
17
  isZeroAddress,
18
18
  toAddress,
19
19
  validateFillForDeposit,
20
+ chainIsEvm,
20
21
  } from "../../utils";
21
22
  import {
22
23
  duplicateEvent,
@@ -41,7 +42,7 @@ import {
41
42
  } from "../../interfaces";
42
43
  import { BaseAbstractClient, UpdateFailureReason } from "../BaseAbstractClient";
43
44
  import { AcrossConfigStoreClient } from "../AcrossConfigStoreClient";
44
- import { getRepaymentChainId, forceDestinationRepayment } from "../BundleDataClient";
45
+ import { getRefundInformationFromFill } from "../BundleDataClient";
45
46
  import { HubPoolClient } from "../HubPoolClient";
46
47
 
47
48
  export type SpokePoolUpdateSuccess = {
@@ -365,22 +366,25 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
365
366
  fill: FillWithBlock
366
367
  ) => {
367
368
  if (validateFillForDeposit(fill, deposit).valid) {
368
- const repaymentChainId = getRepaymentChainId(fill, deposit);
369
- // In order to keep this function sync, we can't call verifyFillRepayment so we'll log any fills that
370
- // we'll have to overwrite repayment information for. This includes fills for lite chains where the
371
- // repayment address is invalid, and fills for non-lite chains where the repayment address is valid or
372
- // the repayment chain is invalid. We don't check that the origin chain is a valid EVM chain for
373
- // lite chain deposits yet because only EVM chains are supported on Across...for now. This means
374
- // this logic will have to be revisited when we add SVM to log properly.
369
+ const fillRepaymentData = {
370
+ ...fill,
371
+ fromLiteChain: deposit.fromLiteChain,
372
+ };
373
+ const { chainToSendRefundTo: repaymentChainId } = getRefundInformationFromFill(
374
+ fillRepaymentData,
375
+ this.hubPoolClient!,
376
+ this.hubPoolClient!.latestBlockSearched
377
+ );
378
+ // In order to keep this function sync, we can't call verifyFillRepayment so we'll log any fills where
379
+ // the filler-specified repayment chain and repayment address is not a valid repayment upon
380
+ // first glance. In other words, the repayment address is not a valid EVM address or the repayment chain
381
+ // is not a valid EVM chain. In the case where the repayment address is not a valid EVM address, the dataworker
382
+ // might be able to overwrite the repayment address to the msg.sender on the fill txn, but to keep this
383
+ // functioon synchronous, we can't make that decision now. So this function might log some false positives.
375
384
  if (
376
385
  this.hubPoolClient &&
377
386
  !isSlowFill(fill) &&
378
- (!isValidEvmAddress(fill.relayer) ||
379
- forceDestinationRepayment(
380
- repaymentChainId,
381
- { ...deposit, quoteBlockNumber: this.hubPoolClient!.latestBlockSearched },
382
- this.hubPoolClient
383
- ))
387
+ (!chainIsEvm(repaymentChainId) || !isValidEvmAddress(fill.relayer))
384
388
  ) {
385
389
  groupedFills.unrepayableFills.push(fill);
386
390
  }
@@ -397,7 +401,7 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
397
401
 
398
402
  // Log any invalid deposits with same deposit id but different params.
399
403
  const invalidFillsForDeposit = invalidFills.filter((x) => {
400
- const txnUid = `${x.transactionHash}:${x.logIndex}`;
404
+ const txnUid = `${x.txnRef}:${x.logIndex}`;
401
405
  // if txnUid doesn't exist in the invalidFills set, add it now, but log the corresponding fill.
402
406
  const newInvalidFill = x.depositId.eq(deposit.depositId) && !this.invalidFills.has(txnUid);
403
407
  if (newInvalidFill) {
@@ -450,6 +454,29 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
450
454
  return `${event.depositId.toString()}-${event.originChainId}`;
451
455
  }
452
456
 
457
+ protected canResolveZeroAddressOutputToken(deposit: DepositWithBlock): boolean {
458
+ if (
459
+ !this.hubPoolClient?.l2TokenHasPoolRebalanceRoute(
460
+ deposit.inputToken,
461
+ deposit.originChainId,
462
+ deposit.quoteBlockNumber
463
+ )
464
+ ) {
465
+ return false;
466
+ } else {
467
+ const l1Token = this.hubPoolClient?.getL1TokenForL2TokenAtBlock(
468
+ deposit.inputToken,
469
+ deposit.originChainId,
470
+ deposit.quoteBlockNumber
471
+ );
472
+ return this.hubPoolClient.l2TokenEnabledForL1TokenAtBlock(
473
+ l1Token,
474
+ deposit.destinationChainId,
475
+ deposit.quoteBlockNumber
476
+ );
477
+ }
478
+ }
479
+
453
480
  /**
454
481
  * A wrapper over the `_update` method that handles errors and logs. This method additionally calls into the
455
482
  * HubPoolClient to update the state of this client with data from the HubPool contract.
@@ -709,8 +736,19 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
709
736
  * @returns The destination token.
710
737
  */
711
738
  protected getDestinationTokenForDeposit(deposit: DepositWithBlock): string {
712
- // If there is no rate model client return address(0).
713
- return this.hubPoolClient?.getL2TokenForDeposit(deposit) ?? ZERO_ADDRESS;
739
+ if (!this.canResolveZeroAddressOutputToken(deposit)) {
740
+ return ZERO_ADDRESS;
741
+ }
742
+ // L1 token should be resolved if we get here:
743
+ const l1Token = this.hubPoolClient!.getL1TokenForL2TokenAtBlock(
744
+ deposit.inputToken,
745
+ deposit.originChainId,
746
+ deposit.quoteBlockNumber
747
+ )!;
748
+ return (
749
+ this.hubPoolClient!.getL2TokenForL1TokenAtBlock(l1Token, deposit.destinationChainId, deposit.quoteBlockNumber) ??
750
+ ZERO_ADDRESS
751
+ );
714
752
  }
715
753
 
716
754
  /**
@@ -2,7 +2,14 @@ import assert from "assert";
2
2
  import winston from "winston";
3
3
  import { Contract, ethers } from "ethers";
4
4
  import { Log } from "../../interfaces";
5
- import { getCurrentTime, EventSearchConfig, MakeOptional, isDefined, utf8ToHex } from "../../utils";
5
+ import {
6
+ getCurrentTime,
7
+ EventSearchConfig,
8
+ MakeOptional,
9
+ isDefined,
10
+ utf8ToHex,
11
+ spreadEventWithBlockNumber,
12
+ } from "../../utils";
6
13
  import {
7
14
  AcrossConfigStoreClient,
8
15
  ConfigStoreUpdate,
@@ -92,9 +99,9 @@ export class MockConfigStoreClient extends AcrossConfigStoreClient {
92
99
  chainId: this.chainId as number,
93
100
  searchEndBlock: this.eventSearchConfig.toBlock || latestBlockSearched,
94
101
  events: {
95
- updatedGlobalConfigEvents: events["UpdatedGlobalConfig"],
102
+ updatedGlobalConfigEvents: events["UpdatedGlobalConfig"].map(spreadEventWithBlockNumber),
96
103
  globalConfigUpdateTimes,
97
- updatedTokenConfigEvents: events["UpdatedTokenConfig"],
104
+ updatedTokenConfigEvents: events["UpdatedTokenConfig"].map(spreadEventWithBlockNumber),
98
105
  },
99
106
  });
100
107
  }
@@ -23,8 +23,7 @@ export class MockHubPoolClient extends HubPoolClient {
23
23
  private realizedLpFeePctOverride = false;
24
24
 
25
25
  private l1TokensMock: L1Token[] = []; // L1Tokens and their associated info.
26
- private tokenInfoToReturn: L1Token = { address: "", decimals: 0, symbol: "" };
27
-
26
+
28
27
  private spokePoolTokens: { [l1Token: string]: { [chainId: number]: string } } = {};
29
28
 
30
29
  private eventManager: EventManager;
@@ -91,15 +90,27 @@ export class MockHubPoolClient extends HubPoolClient {
91
90
  return this.l1TokensMock;
92
91
  }
93
92
 
94
- getTokenInfoForAddress() {
95
- return this.tokenInfoToReturn;
96
- }
97
-
98
93
  setTokenMapping(l1Token: string, chainId: number, l2Token: string) {
99
94
  this.spokePoolTokens[l1Token] ??= {};
100
95
  this.spokePoolTokens[l1Token][chainId] = l2Token;
101
96
  }
102
97
 
98
+ l2TokenEnabledForL1TokenAtBlock(l1Token: string, destinationChainId: number, hubBlockNumber: number): boolean {
99
+ if (this.spokePoolTokens[l1Token]?.[destinationChainId]) {
100
+ return true;
101
+ } else {
102
+ return super.l2TokenEnabledForL1TokenAtBlock(l1Token, destinationChainId, hubBlockNumber);
103
+ }
104
+ }
105
+ l2TokenHasPoolRebalanceRoute(l2Token: string, chainId: number, hubPoolBlock: number): boolean {
106
+ const l1Token = Object.keys(this.spokePoolTokens).find(
107
+ (l1Token) => this.spokePoolTokens[l1Token]?.[chainId] === l2Token
108
+ );
109
+ if (!l1Token) {
110
+ return super.l2TokenHasPoolRebalanceRoute(l2Token, chainId, hubPoolBlock);
111
+ } else return true;
112
+ }
113
+
103
114
  deleteTokenMapping(l1Token: string, chainId: number) {
104
115
  delete this.spokePoolTokens[l1Token]?.[chainId];
105
116
  }
@@ -120,10 +131,6 @@ export class MockHubPoolClient extends HubPoolClient {
120
131
  return this.l1TokensMock.find((token) => token.address === l1Token);
121
132
  }
122
133
 
123
- setTokenInfoToReturn(tokenInfo: L1Token) {
124
- this.tokenInfoToReturn = tokenInfo;
125
- }
126
-
127
134
  _update(eventNames: string[]): Promise<HubPoolUpdate> {
128
135
  // Generate new "on chain" responses.
129
136
  const latestBlockSearched = this.eventManager.blockNumber;
@@ -162,6 +169,30 @@ export class MockHubPoolClient extends HubPoolClient {
162
169
  RootBundleExecuted: "uint256,uint256,uint256,address[],uint256[],int256[],int256[],address",
163
170
  };
164
171
 
172
+ setCrossChainContractsEvent(
173
+ l2ChainId: number,
174
+ adapter: string,
175
+ spokePool: string,
176
+ overrides: EventOverrides = {}
177
+ ): Log {
178
+ const event = "CrossChainContractsSet";
179
+
180
+ const topics: string[] = [];
181
+ const args = {
182
+ l2ChainId,
183
+ adapter,
184
+ spokePool,
185
+ };
186
+
187
+ return this.eventManager.generateEvent({
188
+ event,
189
+ address: this.hubPool.address,
190
+ topics: topics.map((topic) => topic.toString()),
191
+ args,
192
+ blockNumber: overrides.blockNumber,
193
+ });
194
+ }
195
+
165
196
  setPoolRebalanceRoute(
166
197
  destinationChainId: number,
167
198
  l1Token: string,
@@ -129,7 +129,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
129
129
  }
130
130
 
131
131
  protected _deposit(event: string, deposit: Omit<Deposit, "messageHash"> & Partial<SortableEvent>): Log {
132
- const { blockNumber, transactionIndex } = deposit;
132
+ const { blockNumber, txnIndex } = deposit;
133
133
  let { depositId, destinationChainId, inputAmount, outputAmount } = deposit;
134
134
  depositId ??= this.numberOfDeposits;
135
135
  this.numberOfDeposits = depositId.add(bnOne);
@@ -171,7 +171,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
171
171
  topics: topics.map((topic) => topic.toString()),
172
172
  args,
173
173
  blockNumber,
174
- transactionIndex,
174
+ transactionIndex: txnIndex,
175
175
  });
176
176
  }
177
177
 
@@ -187,7 +187,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
187
187
  event: string,
188
188
  fill: Omit<Fill, "messageHash"> & { message: string } & Partial<SortableEvent>
189
189
  ): Log {
190
- const { blockNumber, transactionIndex } = fill;
190
+ const { blockNumber, txnIndex } = fill;
191
191
  let { originChainId, depositId, inputAmount, outputAmount, fillDeadline } = fill;
192
192
  originChainId ??= random(1, 42161, false);
193
193
  depositId ??= BigNumber.from(random(1, 100_000, false));
@@ -260,7 +260,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
260
260
  topics: topics.map((topic) => topic.toString()),
261
261
  args,
262
262
  blockNumber,
263
- transactionIndex,
263
+ transactionIndex: txnIndex,
264
264
  });
265
265
  }
266
266
 
@@ -335,7 +335,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
335
335
  exclusiveRelayer: addressModifier(args.exclusiveRelayer ?? ZERO_ADDRESS),
336
336
  },
337
337
  blockNumber: request.blockNumber,
338
- transactionIndex: request.transactionIndex,
338
+ transactionIndex: request.txnIndex,
339
339
  });
340
340
  }
341
341
 
@@ -9,9 +9,9 @@ export type Log = _Log & {
9
9
 
10
10
  export interface SortableEvent {
11
11
  blockNumber: number;
12
- transactionIndex: number;
12
+ txnIndex: number;
13
13
  logIndex: number;
14
- transactionHash: string;
14
+ txnRef: string;
15
15
  }
16
16
 
17
17
  export interface BigNumberForToken {
@@ -241,6 +241,10 @@ export class SvmAddress extends Address {
241
241
  return this.toBase58();
242
242
  }
243
243
 
244
+ override toEvmAddress(): string {
245
+ return toAddress(`0x${this.toBytes32().slice(-40)}`);
246
+ }
247
+
244
248
  // Constructs a new SvmAddress type.
245
249
  static from(bs58Address: string): SvmAddress {
246
250
  return new this(bs58.decode(bs58Address));
@@ -2,7 +2,7 @@ import assert from "assert";
2
2
  import { SpokePoolClient } from "../clients";
3
3
  import { DEFAULT_CACHING_TTL, EMPTY_MESSAGE, UNDEFINED_MESSAGE_HASH, ZERO_BYTES } from "../constants";
4
4
  import { CachingMechanismInterface, Deposit, DepositWithBlock, Fill, RelayData, SlowFillRequest } from "../interfaces";
5
- import { getMessageHash, isUnsafeDepositId } from "./SpokeUtils";
5
+ import { getMessageHash, isUnsafeDepositId, isZeroAddress } from "./SpokeUtils";
6
6
  import { getNetworkName } from "./NetworkUtils";
7
7
  import { bnZero } from "./BigNumberUtils";
8
8
  import { getDepositInCache, getDepositKey, setDepositInCache } from "./CachingUtils";
@@ -208,6 +208,11 @@ export function isZeroValueDeposit(deposit: Pick<Deposit, "inputAmount" | "messa
208
208
  return deposit.inputAmount.eq(0) && isMessageEmpty(deposit.message);
209
209
  }
210
210
 
211
+ export function invalidOutputToken(deposit: Pick<DepositWithBlock, "outputToken">): boolean {
212
+ // If the output token is zero address, then it is invalid.
213
+ return isZeroAddress(deposit.outputToken);
214
+ }
215
+
211
216
  export function isZeroValueFillOrSlowFillRequest(
212
217
  e: Pick<Fill | SlowFillRequest, "inputAmount" | "messageHash">
213
218
  ): boolean {
@@ -204,13 +204,19 @@ export function getPaginatedBlockRanges({
204
204
  return ranges;
205
205
  }
206
206
 
207
+ export function logToSortableEvent(log: Log): SortableEvent {
208
+ return {
209
+ txnIndex: log.transactionIndex,
210
+ txnRef: log.transactionHash,
211
+ logIndex: log.logIndex,
212
+ blockNumber: log.blockNumber,
213
+ };
214
+ }
215
+
207
216
  export function spreadEventWithBlockNumber(event: Log): SortableEvent {
208
217
  return {
209
218
  ...spreadEvent(event.args),
210
- blockNumber: event.blockNumber,
211
- transactionIndex: event.transactionIndex,
212
- logIndex: event.logIndex,
213
- transactionHash: event.transactionHash,
219
+ ...logToSortableEvent(event),
214
220
  };
215
221
  }
216
222
 
@@ -226,8 +232,8 @@ export function sortEventsAscendingInPlace<T extends SortableEvent>(events: T[])
226
232
  if (ex.blockNumber !== ey.blockNumber) {
227
233
  return ex.blockNumber - ey.blockNumber;
228
234
  }
229
- if (ex.transactionIndex !== ey.transactionIndex) {
230
- return ex.transactionIndex - ey.transactionIndex;
235
+ if (ex.txnIndex !== ey.txnIndex) {
236
+ return ex.txnIndex - ey.txnIndex;
231
237
  }
232
238
  return ex.logIndex - ey.logIndex;
233
239
  });
@@ -245,8 +251,8 @@ export function sortEventsDescendingInPlace<T extends SortableEvent>(events: T[]
245
251
  if (ex.blockNumber !== ey.blockNumber) {
246
252
  return ey.blockNumber - ex.blockNumber;
247
253
  }
248
- if (ex.transactionIndex !== ey.transactionIndex) {
249
- return ey.transactionIndex - ex.transactionIndex;
254
+ if (ex.txnIndex !== ey.txnIndex) {
255
+ return ey.txnIndex - ex.txnIndex;
250
256
  }
251
257
  return ey.logIndex - ex.logIndex;
252
258
  });
@@ -257,16 +263,16 @@ export function isEventOlder<T extends SortableEvent>(ex: T, ey: T): boolean {
257
263
  if (ex.blockNumber !== ey.blockNumber) {
258
264
  return ex.blockNumber < ey.blockNumber;
259
265
  }
260
- if (ex.transactionIndex !== ey.transactionIndex) {
261
- return ex.transactionIndex < ey.transactionIndex;
266
+ if (ex.txnIndex !== ey.txnIndex) {
267
+ return ex.txnIndex < ey.txnIndex;
262
268
  }
263
269
  return ex.logIndex < ey.logIndex;
264
270
  }
265
271
 
266
- export function getTransactionHashes(events: SortableEvent[]): string[] {
267
- return [...Array.from(new Set(events.map((e) => e.transactionHash)))];
272
+ export function getTransactionRefs(events: SortableEvent[]): string[] {
273
+ return [...Array.from(new Set(events.map((e) => e.txnRef)))];
268
274
  }
269
275
 
270
276
  export function duplicateEvent(a: SortableEvent, b: SortableEvent): boolean {
271
- return a.transactionHash === b.transactionHash && a.logIndex === b.logIndex;
277
+ return a.txnRef === b.txnRef && a.logIndex === b.logIndex;
272
278
  }