@across-protocol/sdk 4.0.2 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +3 -3
  2. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +38 -18
  3. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  4. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +3 -0
  5. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +20 -10
  6. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  7. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +14 -2
  8. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +4 -1
  9. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  10. package/dist/cjs/clients/SpokePoolClient.js +155 -88
  11. package/dist/cjs/clients/SpokePoolClient.js.map +1 -1
  12. package/dist/cjs/clients/mocks/MockSpokePoolClient.d.ts +20 -6
  13. package/dist/cjs/clients/mocks/MockSpokePoolClient.js +77 -35
  14. package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
  15. package/dist/cjs/constants.d.ts +2 -1
  16. package/dist/cjs/constants.js +3 -2
  17. package/dist/cjs/constants.js.map +1 -1
  18. package/dist/cjs/interfaces/SpokePool.d.ts +6 -2
  19. package/dist/cjs/interfaces/SpokePool.js.map +1 -1
  20. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -3
  21. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  22. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  23. package/dist/cjs/utils/AddressUtils.d.ts +1 -0
  24. package/dist/cjs/utils/AddressUtils.js +5 -1
  25. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  26. package/dist/cjs/utils/CachingUtils.js +1 -1
  27. package/dist/cjs/utils/CachingUtils.js.map +1 -1
  28. package/dist/cjs/utils/DepositUtils.d.ts +1 -1
  29. package/dist/cjs/utils/DepositUtils.js +11 -8
  30. package/dist/cjs/utils/DepositUtils.js.map +1 -1
  31. package/dist/cjs/utils/FlowUtils.d.ts +4 -3
  32. package/dist/cjs/utils/FlowUtils.js +5 -1
  33. package/dist/cjs/utils/FlowUtils.js.map +1 -1
  34. package/dist/cjs/utils/SpokeUtils.d.ts +9 -3
  35. package/dist/cjs/utils/SpokeUtils.js +22 -2
  36. package/dist/cjs/utils/SpokeUtils.js.map +1 -1
  37. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +3 -3
  38. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +42 -24
  39. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  40. package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +3 -0
  41. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +20 -11
  42. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  43. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +14 -2
  44. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +4 -1
  45. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  46. package/dist/esm/clients/SpokePoolClient.js +172 -92
  47. package/dist/esm/clients/SpokePoolClient.js.map +1 -1
  48. package/dist/esm/clients/mocks/MockSpokePoolClient.d.ts +20 -6
  49. package/dist/esm/clients/mocks/MockSpokePoolClient.js +79 -37
  50. package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
  51. package/dist/esm/constants.d.ts +2 -1
  52. package/dist/esm/constants.js +6 -1
  53. package/dist/esm/constants.js.map +1 -1
  54. package/dist/esm/interfaces/SpokePool.d.ts +6 -2
  55. package/dist/esm/interfaces/SpokePool.js.map +1 -1
  56. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -3
  57. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  58. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  59. package/dist/esm/utils/AddressUtils.d.ts +1 -0
  60. package/dist/esm/utils/AddressUtils.js +7 -4
  61. package/dist/esm/utils/AddressUtils.js.map +1 -1
  62. package/dist/esm/utils/CachingUtils.js +2 -2
  63. package/dist/esm/utils/CachingUtils.js.map +1 -1
  64. package/dist/esm/utils/DepositUtils.d.ts +1 -1
  65. package/dist/esm/utils/DepositUtils.js +12 -9
  66. package/dist/esm/utils/DepositUtils.js.map +1 -1
  67. package/dist/esm/utils/FlowUtils.d.ts +4 -3
  68. package/dist/esm/utils/FlowUtils.js +6 -1
  69. package/dist/esm/utils/FlowUtils.js.map +1 -1
  70. package/dist/esm/utils/SpokeUtils.d.ts +16 -3
  71. package/dist/esm/utils/SpokeUtils.js +27 -1
  72. package/dist/esm/utils/SpokeUtils.js.map +1 -1
  73. package/dist/esm/utils/abi/typechain/Multicall3.d.ts +4 -1
  74. package/dist/esm/utils/abi/typechain/factories/Multicall3__factory.js.map +1 -1
  75. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +3 -3
  76. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  77. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +3 -0
  78. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  79. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +14 -2
  80. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
  81. package/dist/types/clients/SpokePoolClient.d.ts.map +1 -1
  82. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts +20 -6
  83. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts.map +1 -1
  84. package/dist/types/constants.d.ts +2 -1
  85. package/dist/types/constants.d.ts.map +1 -1
  86. package/dist/types/interfaces/SpokePool.d.ts +6 -2
  87. package/dist/types/interfaces/SpokePool.d.ts.map +1 -1
  88. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -3
  89. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts.map +1 -1
  90. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  91. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  92. package/dist/types/utils/AddressUtils.d.ts +1 -0
  93. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  94. package/dist/types/utils/DepositUtils.d.ts +1 -1
  95. package/dist/types/utils/DepositUtils.d.ts.map +1 -1
  96. package/dist/types/utils/FlowUtils.d.ts +4 -3
  97. package/dist/types/utils/FlowUtils.d.ts.map +1 -1
  98. package/dist/types/utils/SpokeUtils.d.ts +16 -3
  99. package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
  100. package/dist/types/utils/abi/typechain/Multicall3.d.ts +4 -1
  101. package/dist/types/utils/abi/typechain/Multicall3.d.ts.map +1 -1
  102. package/dist/types/utils/abi/typechain/common.d.ts.map +1 -1
  103. package/dist/types/utils/abi/typechain/factories/Multicall3__factory.d.ts.map +1 -1
  104. package/package.json +1 -1
  105. package/src/clients/BundleDataClient/BundleDataClient.ts +47 -30
  106. package/src/clients/BundleDataClient/utils/FillUtils.ts +26 -13
  107. package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +7 -1
  108. package/src/clients/SpokePoolClient.ts +119 -41
  109. package/src/clients/mocks/MockSpokePoolClient.ts +134 -36
  110. package/src/constants.ts +6 -1
  111. package/src/interfaces/SpokePool.ts +6 -2
  112. package/src/relayFeeCalculator/chain-queries/baseQuery.ts +6 -3
  113. package/src/relayFeeCalculator/relayFeeCalculator.ts +1 -1
  114. package/src/utils/AddressUtils.ts +8 -4
  115. package/src/utils/CachingUtils.ts +2 -2
  116. package/src/utils/DepositUtils.ts +8 -3
  117. package/src/utils/FlowUtils.ts +10 -4
  118. package/src/utils/SpokeUtils.ts +33 -3
@@ -5,17 +5,30 @@ import winston from "winston";
5
5
  import { ZERO_ADDRESS } from "../../constants";
6
6
  import {
7
7
  Log,
8
+ Deposit,
8
9
  DepositWithBlock,
9
10
  FillType,
10
- RelayerRefundExecutionWithBlock,
11
- SlowFillRequestWithBlock,
11
+ RelayerRefundExecution,
12
+ SlowFillRequest,
13
+ SortableEvent,
12
14
  Fill,
13
- FillWithBlock,
14
15
  SlowFillLeaf,
15
16
  SpeedUp,
16
17
  TokensBridged,
17
18
  } from "../../interfaces";
18
- 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";
19
32
  import { SpokePoolClient, SpokePoolUpdate } from "../SpokePoolClient";
20
33
  import { HubPoolClient } from "../HubPoolClient";
21
34
  import { EventManager, EventOverrides, getEventManager } from "./MockEvents";
@@ -117,22 +130,32 @@ export class MockSpokePoolClient extends SpokePoolClient {
117
130
  EnabledDepositRoute: "address,uint256,bool",
118
131
  };
119
132
 
120
- depositV3(deposit: DepositWithBlock): Log {
121
- const event = "V3FundsDeposited";
133
+ deposit(deposit: Omit<Deposit, "messageHash"> & Partial<SortableEvent>): Log {
134
+ return this._deposit("FundsDeposited", deposit);
135
+ }
136
+
137
+ depositV3(deposit: Omit<Deposit, "messageHash"> & Partial<SortableEvent>): Log {
138
+ return this._deposit("V3FundsDeposited", deposit);
139
+ }
122
140
 
141
+ protected _deposit(event: string, deposit: Omit<Deposit, "messageHash"> & Partial<SortableEvent>): Log {
123
142
  const { blockNumber, transactionIndex } = deposit;
124
- let { depositId, depositor, destinationChainId, inputToken, inputAmount, outputToken, outputAmount } = deposit;
143
+ let { depositId, destinationChainId, inputAmount, outputAmount } = deposit;
125
144
  depositId ??= this.numberOfDeposits;
126
145
  this.numberOfDeposits = depositId.add(bnOne);
127
146
 
128
147
  destinationChainId ??= random(1, 42161, false);
129
- depositor ??= randomAddress();
130
- inputToken ??= randomAddress();
131
- 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
+
132
155
  inputAmount ??= toBNWei(random(1, 1000, false));
133
156
  outputAmount ??= inputAmount.mul(toBN("0.95"));
134
157
 
135
- const message = deposit["message"] ?? `${event} event at block ${blockNumber}, index ${transactionIndex}.`;
158
+ const message = deposit["message"] ?? "0x";
136
159
  const topics = [destinationChainId, depositId, depositor];
137
160
  const quoteTimestamp = deposit.quoteTimestamp ?? getCurrentTime();
138
161
  const args = {
@@ -140,14 +163,14 @@ export class MockSpokePoolClient extends SpokePoolClient {
140
163
  originChainId: deposit.originChainId ?? this.chainId,
141
164
  destinationChainId,
142
165
  depositor,
143
- recipient: deposit.recipient ?? depositor,
166
+ recipient,
144
167
  inputToken,
145
168
  inputAmount,
146
169
  outputToken,
147
170
  outputAmount,
148
171
  quoteTimestamp,
149
172
  fillDeadline: deposit.fillDeadline ?? quoteTimestamp + 3600,
150
- exclusiveRelayer: deposit.exclusiveRelayer ?? ZERO_ADDRESS,
173
+ exclusiveRelayer,
151
174
  exclusivityDeadline: deposit.exclusivityDeadline ?? quoteTimestamp + 600,
152
175
  message,
153
176
  };
@@ -162,26 +185,47 @@ export class MockSpokePoolClient extends SpokePoolClient {
162
185
  });
163
186
  }
164
187
 
165
- fillV3Relay(fill: FillWithBlock): Log {
166
- const event = "FilledV3Relay";
188
+ fillV3Relay(fill: Omit<Fill, "messageHash"> & { message: string } & Partial<SortableEvent>): Log {
189
+ return this._fillRelay("FilledV3Relay", fill);
190
+ }
191
+
192
+ fillRelay(fill: Omit<Fill, "messageHash"> & { message: string } & Partial<SortableEvent>): Log {
193
+ return this._fillRelay("FilledRelay", fill);
194
+ }
167
195
 
196
+ protected _fillRelay(
197
+ event: string,
198
+ fill: Omit<Fill, "messageHash"> & { message: string } & Partial<SortableEvent>
199
+ ): Log {
168
200
  const { blockNumber, transactionIndex } = fill;
169
- let { originChainId, depositId, inputToken, inputAmount, outputAmount, fillDeadline, relayer } = fill;
201
+ let { originChainId, depositId, inputAmount, outputAmount, fillDeadline } = fill;
170
202
  originChainId ??= random(1, 42161, false);
171
203
  depositId ??= BigNumber.from(random(1, 100_000, false));
172
- inputToken ??= randomAddress();
173
204
  inputAmount ??= toBNWei(random(1, 1000, false));
174
205
  outputAmount ??= inputAmount;
175
206
  fillDeadline ??= getCurrentTime() + 60;
176
- relayer ??= randomAddress();
177
207
 
178
- const topics = [originChainId, depositId, relayer];
179
- const recipient = fill.recipient ?? randomAddress();
180
- const message = fill["message"] ?? `${event} event at block ${blockNumber}, index ${transactionIndex}.`;
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
217
+ const message = fill["message"] ?? "0x";
218
+ const updatedMessage = fill.relayExecutionInfo?.updatedMessage ?? message;
219
+
220
+ const relayExecutionInfo = {
221
+ updatedRecipient: fill.relayExecutionInfo?.updatedRecipient ?? recipient,
222
+ updatedOutputAmount: fill.relayExecutionInfo?.updatedOutputAmount ?? outputAmount,
223
+ fillType: fill.relayExecutionInfo?.fillType ?? FillType.FastFill,
224
+ };
181
225
 
182
- const args = {
226
+ const _args = {
183
227
  inputToken,
184
- outputToken: fill.outputToken ?? ZERO_ADDRESS, // resolved via HubPoolClient.
228
+ outputToken,
185
229
  inputAmount: fill.inputAmount,
186
230
  outputAmount: fill.outputAmount,
187
231
  repaymentChainId: fill.repaymentChainId ?? this.chainId,
@@ -189,19 +233,40 @@ export class MockSpokePoolClient extends SpokePoolClient {
189
233
  depositId,
190
234
  fillDeadline,
191
235
  exclusivityDeadline: fill.exclusivityDeadline ?? fillDeadline,
192
- exclusiveRelayer: fill.exclusiveRelayer ?? ZERO_ADDRESS,
236
+ exclusiveRelayer,
193
237
  relayer,
194
- depositor: fill.depositor ?? randomAddress(),
238
+ depositor,
195
239
  recipient,
196
240
  message,
197
241
  relayExecutionInfo: {
198
242
  updatedRecipient: fill.relayExecutionInfo?.updatedRecipient ?? recipient,
199
- updatedMessage: fill.relayExecutionInfo?.updatedMessage ?? message,
243
+ updatedMessage,
244
+ updatedMessageHash: getMessageHash(updatedMessage),
200
245
  updatedOutputAmount: fill.relayExecutionInfo?.updatedOutputAmount ?? outputAmount,
201
246
  fillType: fill.relayExecutionInfo?.fillType ?? FillType.FastFill,
202
247
  },
203
248
  };
204
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
+
205
270
  return this.eventManager.generateEvent({
206
271
  event,
207
272
  address: this.spokePool.address,
@@ -213,15 +278,28 @@ export class MockSpokePoolClient extends SpokePoolClient {
213
278
  }
214
279
 
215
280
  speedUpV3Deposit(speedUp: SpeedUp): Log {
216
- const event = "RequestedSpeedUpV3Deposit";
217
- 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];
218
292
  const args = { ...speedUp };
219
293
 
220
294
  return this.eventManager.generateEvent({
221
295
  event,
222
296
  address: this.spokePool.address,
223
297
  topics: topics.map((topic) => topic.toString()),
224
- args,
298
+ args: {
299
+ ...args,
300
+ depositor,
301
+ updatedRecipient: addressModifier(speedUp.updatedRecipient),
302
+ },
225
303
  });
226
304
  }
227
305
 
@@ -238,18 +316,37 @@ export class MockSpokePoolClient extends SpokePoolClient {
238
316
  });
239
317
  }
240
318
 
241
- requestV3SlowFill(request: SlowFillRequestWithBlock): Log {
242
- const event = "RequestedV3SlowFill";
319
+ requestV3SlowFill(request: Omit<SlowFillRequest, "messageHash"> & Partial<SortableEvent>): Log {
320
+ return this._requestSlowFill("RequestedV3SlowFill", request);
321
+ }
322
+
323
+ requestSlowFill(request: Omit<SlowFillRequest, "messageHash"> & Partial<SortableEvent>): Log {
324
+ return this._requestSlowFill("RequestedSlowFill", request);
325
+ }
243
326
 
327
+ protected _requestSlowFill(
328
+ event: string,
329
+ request: Omit<SlowFillRequest, "messageHash"> & Partial<SortableEvent>
330
+ ): Log {
244
331
  const { originChainId, depositId } = request;
245
332
  const topics = [originChainId, depositId];
246
333
  const args = { ...request };
247
334
 
335
+ const addressModifier = event === "RequestedSlowFill" ? toBytes32 : toAddress;
336
+ const depositor = addressModifier(args.depositor ?? randomAddress());
337
+
248
338
  return this.eventManager.generateEvent({
249
339
  event,
250
340
  address: this.spokePool.address,
251
341
  topics: topics.map((topic) => topic.toString()),
252
- 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
+ },
253
350
  blockNumber: request.blockNumber,
254
351
  transactionIndex: request.transactionIndex,
255
352
  });
@@ -257,8 +354,8 @@ export class MockSpokePoolClient extends SpokePoolClient {
257
354
 
258
355
  // This is a simple wrapper around fillV3Relay().
259
356
  // rootBundleId and proof are discarded here - we have no interest in verifying that.
260
- executeV3SlowRelayLeaf(leaf: SlowFillLeaf): Log {
261
- const fill: Fill = {
357
+ executeV3SlowRelayLeaf(leaf: Omit<SlowFillLeaf, "messageHash">): Log {
358
+ const fill = {
262
359
  ...leaf.relayData,
263
360
  destinationChainId: this.chainId,
264
361
  relayer: ZERO_ADDRESS,
@@ -267,14 +364,15 @@ export class MockSpokePoolClient extends SpokePoolClient {
267
364
  updatedRecipient: leaf.relayData.recipient,
268
365
  updatedOutputAmount: leaf.updatedOutputAmount,
269
366
  updatedMessage: leaf.relayData.message,
367
+ updatedMessageHash: getMessageHash(leaf.relayData.message),
270
368
  fillType: FillType.SlowFill,
271
369
  },
272
370
  };
273
371
 
274
- return this.fillV3Relay(fill as FillWithBlock);
372
+ return this.fillV3Relay(fill);
275
373
  }
276
374
 
277
- executeRelayerRefundLeaf(refund: RelayerRefundExecutionWithBlock): Log {
375
+ executeRelayerRefundLeaf(refund: RelayerRefundExecution & Partial<SortableEvent>): Log {
278
376
  const event = "ExecutedRelayerRefundRoot";
279
377
 
280
378
  const chainId = refund.chainId ?? this.chainId;
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,
@@ -22,6 +22,7 @@ export interface RelayData {
22
22
  }
23
23
 
24
24
  export interface Deposit extends RelayData {
25
+ messageHash: string;
25
26
  destinationChainId: number;
26
27
  quoteTimestamp: number;
27
28
  speedUpSignature?: string;
@@ -51,11 +52,13 @@ export enum FillType {
51
52
  export interface RelayExecutionEventInfo {
52
53
  updatedRecipient: string;
53
54
  updatedOutputAmount: BigNumber;
54
- updatedMessage: string;
55
+ updatedMessage?: string;
56
+ updatedMessageHash: string;
55
57
  fillType: FillType;
56
58
  }
57
59
 
58
- export interface Fill extends RelayData {
60
+ export interface Fill extends Omit<RelayData, "message"> {
61
+ messageHash: string;
59
62
  destinationChainId: number;
60
63
  relayer: string;
61
64
  repaymentChainId: number;
@@ -77,6 +80,7 @@ export interface SpeedUp {
77
80
  export interface SpeedUpWithBlock extends SpeedUp, SortableEvent {}
78
81
 
79
82
  export interface SlowFillRequest extends RelayData {
83
+ messageHash: string;
80
84
  destinationChainId: number;
81
85
  }
82
86
  export interface SlowFillRequestWithBlock extends SlowFillRequest, SortableEvent {}
@@ -71,7 +71,7 @@ export class QueryBase implements QueryInterface {
71
71
  * @returns The gas estimate for this function call (multiplied with the optional buffer).
72
72
  */
73
73
  async getGasCosts(
74
- deposit: Deposit,
74
+ deposit: Omit<Deposit, "messageHash">,
75
75
  relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS,
76
76
  options: Partial<{
77
77
  gasPrice: BigNumberish;
@@ -121,7 +121,7 @@ export class QueryBase implements QueryInterface {
121
121
  * @returns PopulatedTransaction
122
122
  */
123
123
  getUnsignedTxFromDeposit(
124
- deposit: Deposit,
124
+ deposit: Omit<Deposit, "messageHash">,
125
125
  relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS
126
126
  ): Promise<PopulatedTransaction> {
127
127
  return populateV3Relay(this.spokePool, deposit, relayer);
@@ -133,7 +133,10 @@ export class QueryBase implements QueryInterface {
133
133
  * @param relayer Sender of PopulatedTransaction
134
134
  * @returns Estimated gas cost based on ethers.VoidSigner's gas estimation
135
135
  */
136
- async getNativeGasCost(deposit: Deposit, relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS): Promise<BigNumber> {
136
+ async getNativeGasCost(
137
+ deposit: Omit<Deposit, "messageHash">,
138
+ relayer = DEFAULT_SIMULATED_RELAYER_ADDRESS
139
+ ): Promise<BigNumber> {
137
140
  const unsignedTx = await this.getUnsignedTxFromDeposit(deposit, relayer);
138
141
  const voidSigner = new VoidSigner(relayer, this.provider);
139
142
  return voidSigner.estimateGas(unsignedTx);
@@ -22,7 +22,7 @@ import { Transport } from "viem";
22
22
  // This needs to be implemented for every chain and passed into RelayFeeCalculator
23
23
  export interface QueryInterface {
24
24
  getGasCosts: (
25
- deposit: Deposit,
25
+ deposit: Omit<Deposit, "messageHash">,
26
26
  relayer: string,
27
27
  options?: Partial<{
28
28
  gasPrice: BigNumberish;
@@ -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
  }
@@ -3,9 +3,10 @@ import { SpokePoolClient } from "../clients";
3
3
  import { DEFAULT_CACHING_TTL, EMPTY_MESSAGE, ZERO_BYTES } from "../constants";
4
4
  import { CachingMechanismInterface, Deposit, DepositWithBlock, Fill, SlowFillRequest } from "../interfaces";
5
5
  import { getNetworkName } from "./NetworkUtils";
6
+ import { bnZero } from "./BigNumberUtils";
6
7
  import { getDepositInCache, getDepositKey, setDepositInCache } from "./CachingUtils";
7
8
  import { validateFillForDeposit } from "./FlowUtils";
8
- import { isUnsafeDepositId } from "./SpokeUtils";
9
+ import { getMessageHash, isUnsafeDepositId } from "./SpokeUtils";
9
10
  import { getCurrentTime } from "./TimeUtils";
10
11
  import { isDefined } from "./TypeGuards";
11
12
  import { isDepositFormedCorrectly } from "./ValidatorUtils";
@@ -122,6 +123,8 @@ export async function queryHistoricalDepositForFill(
122
123
  }
123
124
  }
124
125
 
126
+ deposit.messageHash ??= getMessageHash(deposit.message);
127
+
125
128
  const match = validateFillForDeposit(fill, deposit);
126
129
  if (match.valid) {
127
130
  return { found: true, deposit };
@@ -146,8 +149,10 @@ export function isZeroValueDeposit(deposit: Pick<Deposit, "inputAmount" | "messa
146
149
  return deposit.inputAmount.eq(0) && isMessageEmpty(deposit.message);
147
150
  }
148
151
 
149
- export function isZeroValueFillOrSlowFillRequest(e: Pick<Fill | SlowFillRequest, "inputAmount" | "message">): boolean {
150
- return e.inputAmount.eq(0) && isFillOrSlowFillRequestMessageEmpty(e.message);
152
+ export function isZeroValueFillOrSlowFillRequest(
153
+ e: Pick<Fill | SlowFillRequest, "inputAmount" | "messageHash">
154
+ ): boolean {
155
+ return e.inputAmount.eq(bnZero) && e.messageHash === ZERO_BYTES;
151
156
  }
152
157
 
153
158
  /**
@@ -1,5 +1,6 @@
1
1
  import { isDefined } from "../utils";
2
2
  import { Deposit, RelayData } from "../interfaces";
3
+ import { UNDEFINED_MESSAGE_HASH } from "../constants";
3
4
 
4
5
  export const RELAYDATA_KEYS = [
5
6
  "depositId",
@@ -14,14 +15,14 @@ export const RELAYDATA_KEYS = [
14
15
  "fillDeadline",
15
16
  "exclusivityDeadline",
16
17
  "exclusiveRelayer",
17
- "message",
18
+ "messageHash",
18
19
  ] as const;
19
20
 
20
21
  // Ensure that each deposit element is included with the same value in the fill. This includes all elements defined
21
22
  // by the depositor as well as destinationToken, which are pulled from other clients.
22
23
  export function validateFillForDeposit(
23
- relayData: RelayData & { destinationChainId: number },
24
- deposit?: Deposit
24
+ relayData: Omit<RelayData, "message"> & { messageHash: string; destinationChainId: number },
25
+ deposit?: Omit<Deposit, "quoteTimestamp" | "fromLiteChain" | "toLiteChain">
25
26
  ): { valid: true } | { valid: false; reason: string } {
26
27
  if (deposit === undefined) {
27
28
  return { valid: false, reason: "Deposit is undefined" };
@@ -30,7 +31,12 @@ export function validateFillForDeposit(
30
31
  // Note: this short circuits when a key is found where the comparison doesn't match.
31
32
  // TODO: if we turn on "strict" in the tsconfig, the elements of FILL_DEPOSIT_COMPARISON_KEYS will be automatically
32
33
  // validated against the fields in Fill and Deposit, generating an error if there is a discrepency.
33
- const invalidKey = RELAYDATA_KEYS.find((key) => relayData[key].toString() !== deposit[key].toString());
34
+ let invalidKey = RELAYDATA_KEYS.find((key) => relayData[key].toString() !== deposit[key].toString());
35
+
36
+ // There should be no paths for `messageHash` to be unset, but mask it off anyway.
37
+ if (!isDefined(invalidKey) && [relayData.messageHash, deposit.messageHash].includes(UNDEFINED_MESSAGE_HASH)) {
38
+ invalidKey = "messageHash";
39
+ }
34
40
 
35
41
  return isDefined(invalidKey)
36
42
  ? { valid: false, reason: `${invalidKey} mismatch (${relayData[invalidKey]} != ${deposit[invalidKey]})` }
@@ -1,7 +1,7 @@
1
1
  import assert from "assert";
2
2
  import { BytesLike, Contract, PopulatedTransaction, providers, utils as ethersUtils } from "ethers";
3
3
  import { CHAIN_IDs, MAX_SAFE_DEPOSIT_ID, ZERO_ADDRESS, ZERO_BYTES } from "../constants";
4
- import { Deposit, Fill, FillStatus, FillWithBlock, RelayData, SlowFillRequest } from "../interfaces";
4
+ import { Deposit, FillStatus, FillWithBlock, RelayData } from "../interfaces";
5
5
  import { SpokePoolClient } from "../clients";
6
6
  import { chunk } from "./ArrayUtils";
7
7
  import { BigNumber, toBN, bnOne, bnZero } from "./BigNumberUtils";
@@ -21,7 +21,7 @@ type BlockTag = providers.BlockTag;
21
21
  */
22
22
  export function populateV3Relay(
23
23
  spokePool: Contract,
24
- deposit: Deposit,
24
+ deposit: Omit<Deposit, "messageHash">,
25
25
  relayer: string,
26
26
  repaymentChainId = deposit.destinationChainId
27
27
  ): Promise<PopulatedTransaction> {
@@ -57,6 +57,35 @@ export function populateV3Relay(
57
57
  return spokePool.populateTransaction.fillV3Relay(v3RelayData, repaymentChainId, { from: relayer });
58
58
  }
59
59
 
60
+ /**
61
+ * Concatenate all fields from a Deposit, Fill or SlowFillRequest into a single string.
62
+ * This can be used to identify a bridge event in a mapping. This is used instead of the actual keccak256 hash
63
+ * (getRelayDataHash()) for two reasons: performance and the fact that only Deposit includes the `message` field, which
64
+ * is required to compute a complete RelayData hash.
65
+ * note: This function should _not_ be used to query the SpokePool.fillStatuses mapping.
66
+ */
67
+ export function getRelayEventKey(
68
+ data: Omit<RelayData, "message"> & { messageHash: string; destinationChainId: number }
69
+ ): string {
70
+ return [
71
+ data.depositor,
72
+ data.recipient,
73
+ data.exclusiveRelayer,
74
+ data.inputToken,
75
+ data.outputToken,
76
+ data.inputAmount,
77
+ data.outputAmount,
78
+ data.originChainId,
79
+ data.destinationChainId,
80
+ data.depositId,
81
+ data.fillDeadline,
82
+ data.exclusivityDeadline,
83
+ data.messageHash,
84
+ ]
85
+ .map(String)
86
+ .join("-");
87
+ }
88
+
60
89
  /**
61
90
  * Find the block range that contains the deposit ID. This is a binary search that searches for the block range
62
91
  * that contains the deposit ID.
@@ -257,7 +286,7 @@ export function getRelayDataHash(relayData: RelayData, destinationChainId: numbe
257
286
  );
258
287
  }
259
288
 
260
- export function getRelayHashFromEvent(e: Deposit | Fill | SlowFillRequest): string {
289
+ export function getRelayHashFromEvent(e: RelayData & { destinationChainId: number }): string {
261
290
  return getRelayDataHash(e, e.destinationChainId);
262
291
  }
263
292
 
@@ -428,6 +457,7 @@ export async function findFillEvent(
428
457
  const fill = {
429
458
  ...spreadEventWithBlockNumber(event),
430
459
  destinationChainId,
460
+ messageHash: getMessageHash(event.args.message),
431
461
  } as FillWithBlock;
432
462
  return fill;
433
463
  }