@across-protocol/sdk 4.1.29 → 4.1.31

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 (47) hide show
  1. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +2 -2
  2. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  3. package/dist/cjs/clients/SpokePoolClient.d.ts +0 -3
  4. package/dist/cjs/clients/SpokePoolClient.js +5 -64
  5. package/dist/cjs/clients/SpokePoolClient.js.map +1 -1
  6. package/dist/cjs/relayFeeCalculator/chain-queries/factory.d.ts +9 -9
  7. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +9 -9
  8. package/dist/cjs/utils/CachingUtils.js +2 -2
  9. package/dist/cjs/utils/CachingUtils.js.map +1 -1
  10. package/dist/cjs/utils/DepositUtils.d.ts +14 -1
  11. package/dist/cjs/utils/DepositUtils.js +51 -3
  12. package/dist/cjs/utils/DepositUtils.js.map +1 -1
  13. package/dist/cjs/utils/SpokeUtils.d.ts +2 -18
  14. package/dist/cjs/utils/SpokeUtils.js +25 -130
  15. package/dist/cjs/utils/SpokeUtils.js.map +1 -1
  16. package/dist/cjs/utils/TokenUtils.d.ts +18 -18
  17. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +2 -2
  18. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  19. package/dist/esm/clients/SpokePoolClient.d.ts +1 -15
  20. package/dist/esm/clients/SpokePoolClient.js +8 -83
  21. package/dist/esm/clients/SpokePoolClient.js.map +1 -1
  22. package/dist/esm/relayFeeCalculator/chain-queries/factory.d.ts +9 -9
  23. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +9 -9
  24. package/dist/esm/utils/CachingUtils.js +1 -1
  25. package/dist/esm/utils/CachingUtils.js.map +1 -1
  26. package/dist/esm/utils/DepositUtils.d.ts +21 -1
  27. package/dist/esm/utils/DepositUtils.js +61 -2
  28. package/dist/esm/utils/DepositUtils.js.map +1 -1
  29. package/dist/esm/utils/SpokeUtils.d.ts +9 -36
  30. package/dist/esm/utils/SpokeUtils.js +31 -185
  31. package/dist/esm/utils/SpokeUtils.js.map +1 -1
  32. package/dist/esm/utils/TokenUtils.d.ts +18 -18
  33. package/dist/types/clients/SpokePoolClient.d.ts +1 -15
  34. package/dist/types/clients/SpokePoolClient.d.ts.map +1 -1
  35. package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts +9 -9
  36. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +9 -9
  37. package/dist/types/utils/DepositUtils.d.ts +21 -1
  38. package/dist/types/utils/DepositUtils.d.ts.map +1 -1
  39. package/dist/types/utils/SpokeUtils.d.ts +9 -36
  40. package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
  41. package/dist/types/utils/TokenUtils.d.ts +18 -18
  42. package/package.json +2 -2
  43. package/src/clients/BundleDataClient/BundleDataClient.ts +2 -2
  44. package/src/clients/SpokePoolClient.ts +15 -70
  45. package/src/utils/CachingUtils.ts +1 -1
  46. package/src/utils/DepositUtils.ts +73 -3
  47. package/src/utils/SpokeUtils.ts +21 -210
@@ -1,10 +1,9 @@
1
1
  import assert from "assert";
2
2
  import { BytesLike, Contract, PopulatedTransaction, providers, utils as ethersUtils } from "ethers";
3
- import { CHAIN_IDs, MAX_SAFE_DEPOSIT_ID, UNDEFINED_MESSAGE_HASH, ZERO_ADDRESS, ZERO_BYTES } from "../constants";
3
+ import { CHAIN_IDs, MAX_SAFE_DEPOSIT_ID, ZERO_ADDRESS, ZERO_BYTES } from "../constants";
4
4
  import { Deposit, FillStatus, FillWithBlock, RelayData } from "../interfaces";
5
- import { SpokePoolClient } from "../clients";
6
5
  import { chunk } from "./ArrayUtils";
7
- import { BigNumber, toBN, bnOne, bnZero } from "./BigNumberUtils";
6
+ import { BigNumber, toBN, bnZero } from "./BigNumberUtils";
8
7
  import { keccak256 } from "./common";
9
8
  import { isMessageEmpty } from "./DepositUtils";
10
9
  import { isDefined } from "./TypeGuards";
@@ -60,219 +59,31 @@ export function populateV3Relay(
60
59
  }
61
60
 
62
61
  /**
63
- * Concatenate all fields from a Deposit, Fill or SlowFillRequest into a single string.
64
- * This can be used to identify a bridge event in a mapping. This is used instead of the actual keccak256 hash
65
- * (getRelayDataHash()) for two reasons: performance and the fact that only Deposit includes the `message` field, which
66
- * is required to compute a complete RelayData hash.
67
- * note: This function should _not_ be used to query the SpokePool.fillStatuses mapping.
62
+ * Retrieves the chain time at a particular block.
63
+ * @returns The time at the specified block tag.
68
64
  */
69
- export function getRelayEventKey(
70
- data: Omit<RelayData, "message"> & { messageHash: string; destinationChainId: number }
71
- ): string {
72
- return [
73
- data.depositor,
74
- data.recipient,
75
- data.exclusiveRelayer,
76
- data.inputToken,
77
- data.outputToken,
78
- data.inputAmount,
79
- data.outputAmount,
80
- data.originChainId,
81
- data.destinationChainId,
82
- data.depositId,
83
- data.fillDeadline,
84
- data.exclusivityDeadline,
85
- data.messageHash,
86
- ]
87
- .map(String)
88
- .join("-");
89
- }
90
-
91
- const RELAYDATA_KEYS = [
92
- "depositId",
93
- "originChainId",
94
- "destinationChainId",
95
- "depositor",
96
- "recipient",
97
- "inputToken",
98
- "inputAmount",
99
- "outputToken",
100
- "outputAmount",
101
- "fillDeadline",
102
- "exclusivityDeadline",
103
- "exclusiveRelayer",
104
- "messageHash",
105
- ] as const;
106
-
107
- // Ensure that each deposit element is included with the same value in the fill. This includes all elements defined
108
- // by the depositor as well as destinationToken, which are pulled from other clients.
109
- export function validateFillForDeposit(
110
- relayData: Omit<RelayData, "message"> & { messageHash: string; destinationChainId: number },
111
- deposit?: Omit<Deposit, "quoteTimestamp" | "fromLiteChain" | "toLiteChain">
112
- ): { valid: true } | { valid: false; reason: string } {
113
- if (deposit === undefined) {
114
- return { valid: false, reason: "Deposit is undefined" };
115
- }
116
-
117
- // Note: this short circuits when a key is found where the comparison doesn't match.
118
- // TODO: if we turn on "strict" in the tsconfig, the elements of FILL_DEPOSIT_COMPARISON_KEYS will be automatically
119
- // validated against the fields in Fill and Deposit, generating an error if there is a discrepency.
120
- let invalidKey = RELAYDATA_KEYS.find((key) => relayData[key].toString() !== deposit[key].toString());
121
-
122
- // There should be no paths for `messageHash` to be unset, but mask it off anyway.
123
- if (!isDefined(invalidKey) && [relayData.messageHash, deposit.messageHash].includes(UNDEFINED_MESSAGE_HASH)) {
124
- invalidKey = "messageHash";
125
- }
126
-
127
- return isDefined(invalidKey)
128
- ? { valid: false, reason: `${invalidKey} mismatch (${relayData[invalidKey]} != ${deposit[invalidKey]})` }
129
- : { valid: true };
65
+ export async function getTimeAt(provider: providers.Provider, blockNumber: number): Promise<number> {
66
+ const block = await provider.getBlock(blockNumber);
67
+ return block.timestamp;
130
68
  }
131
69
 
132
70
  /**
133
- * Find the block range that contains the deposit ID. This is a binary search that searches for the block range
134
- * that contains the deposit ID.
135
- * @param targetDepositId The target deposit ID to search for.
136
- * @param initLow The initial lower bound of the block range to search.
137
- * @param initHigh The initial upper bound of the block range to search.
138
- * @param maxSearches The maximum number of searches to perform. This is used to prevent infinite loops.
139
- * @returns The block range that contains the deposit ID.
140
- * @note // We want to find the block range that satisfies these conditions:
141
- * // - the low block has deposit count <= targetDepositId
142
- * // - the high block has a deposit count > targetDepositId.
143
- * // This way the caller can search for a V3FundsDeposited event between [low, high] that will always
144
- * // contain the event emitted when deposit ID was incremented to targetDepositId + 1. This is the same transaction
145
- * // where the deposit with deposit ID = targetDepositId was created.
71
+ * Return maximum of fill deadline buffer at start and end of block range.
72
+ * @param spokePool SpokePool contract instance
73
+ * @param startBlock start block
74
+ * @param endBlock end block
75
+ * @returns maximum of fill deadline buffer at start and end block
146
76
  */
147
- export async function getBlockRangeForDepositId(
148
- targetDepositId: BigNumber,
149
- initLow: number,
150
- initHigh: number,
151
- maxSearches: number,
152
- spokePool: SpokePoolClient
153
- ): Promise<{
154
- low: number;
155
- high: number;
156
- }> {
157
- // We can only perform this search when we have a safe deposit ID.
158
- if (isUnsafeDepositId(targetDepositId))
159
- throw new Error(
160
- `Target deposit ID ${targetDepositId} is deterministic and therefore unresolvable via a binary search.`
161
- );
162
-
163
- // Resolve the deployment block number.
164
- const deploymentBlock = spokePool.deploymentBlock;
165
-
166
- // Set the initial high block to the most recent block number or the initial high block, whichever is smaller.
167
- initHigh = Math.min(initHigh, spokePool.latestBlockSearched);
168
-
169
- // We will now set a list of sanity checks to ensure that the binary search will not fail
170
- // due to invalid input parameters.
171
- // If any of these sanity checks fail, then we will throw an error.
172
- (
173
- [
174
- // Sanity check to ensure that the spoke pool client is updated
175
- [spokePool.isUpdated, "Spoke pool client is not updated"],
176
- // Sanity check to ensure that initHigh is greater than or equal to initLow.
177
- [initLow <= initHigh, "Binary search failed because low > high"],
178
- // Sanity check to ensure that init Low is greater than or equal to zero.
179
- [initLow >= deploymentBlock, "Binary search failed because low must be >= deploymentBlock"],
180
- // Sanity check to ensure that maxSearches is greater than zero.
181
- [maxSearches > 0, "maxSearches must be > 0"],
182
- // Sanity check to ensure that deploymentBlock is greater than or equal to zero.
183
- [deploymentBlock >= 0, "deploymentBlock must be >= 0"],
184
- ] as [boolean, string][]
185
- ).forEach(([condition, errorMessage]) => {
186
- // If the condition is false, then we will throw an error.
187
- if (!condition) {
188
- throw new Error(errorMessage);
189
- }
190
- });
191
-
192
- // Define a mapping of block numbers to number of deposits at that block. This saves repeated lookups.
193
- const queriedIds: Record<number, BigNumber> = {};
194
-
195
- // Define a llambda function to get the deposit ID at a block number. This function will first check the
196
- // queriedIds cache to see if the deposit ID at the block number has already been queried. If not, it will
197
- // make an eth_call request to get the deposit ID at the block number. It will then cache the deposit ID
198
- // in the queriedIds cache.
199
- const _getDepositIdAtBlock = async (blockNumber: number): Promise<BigNumber> => {
200
- queriedIds[blockNumber] ??= await spokePool._getDepositIdAtBlock(blockNumber);
201
- return queriedIds[blockNumber];
202
- };
203
-
204
- // Get the the deposit ID at the low block, and the deposit ID at the high block in parallel.
205
- const [highestDepositIdInRange, lowestDepositIdInRange] = await Promise.all([
206
- _getDepositIdAtBlock(initHigh),
207
- _getDepositIdAtBlock(Math.max(deploymentBlock, initLow - 1)),
77
+ export async function getMaxFillDeadlineInRange(
78
+ spokePool: Contract,
79
+ startBlock: number,
80
+ endBlock: number
81
+ ): Promise<number> {
82
+ const fillDeadlineBuffers = await Promise.all([
83
+ spokePool.fillDeadlineBuffer({ blockTag: startBlock }),
84
+ spokePool.fillDeadlineBuffer({ blockTag: endBlock }),
208
85
  ]);
209
-
210
- // If the deposit ID at the initial high block is less than the target deposit ID, then we know that
211
- // the target deposit ID must be greater than the initial high block, so we can throw an error.
212
- if (highestDepositIdInRange.lte(targetDepositId)) {
213
- // initLow = 5: Deposits Num: 10
214
- // // targetId = 11 <- fail (triggers this error) // 10 <= 11
215
- // // targetId = 10 <- fail (triggers this error) // 10 <= 10
216
- // // targetId = 09 <- pass (does not trigger this error) // 10 <= 09
217
- throw new Error(
218
- `Target depositId is greater than the initial high block (${targetDepositId} > ${highestDepositIdInRange})`
219
- );
220
- }
221
-
222
- // If the deposit ID at the initial low block is greater than the target deposit ID, then we know that
223
- // the target deposit ID must be less than the initial low block, so we can throw an error.
224
- if (lowestDepositIdInRange.gt(targetDepositId)) {
225
- // initLow = 5: Deposits Num: 10
226
- // initLow-1 = 4: Deposits Num: 2
227
- // // targetId = 1 <- fail (triggers this error)
228
- // // targetId = 2 <- pass (does not trigger this error)
229
- // // targetId = 3 <- pass (does not trigger this error)
230
- throw new Error(
231
- `Target depositId is less than the initial low block (${targetDepositId.toString()} > ${lowestDepositIdInRange})`
232
- );
233
- }
234
-
235
- // Define the low and high block numbers for the binary search.
236
- let low = initLow;
237
- let high = initHigh;
238
- // Define the number of searches performed so far.
239
- let searches = 0;
240
-
241
- do {
242
- // Resolve the mid point of the block range.
243
- const mid = Math.floor((low + high) / 2);
244
-
245
- // Get the deposit ID at the mid point.
246
- const midDepositId = await _getDepositIdAtBlock(mid);
247
-
248
- // Let's define the latest ID of the current midpoint block.
249
- const accountedIdByMidBlock = midDepositId.sub(bnOne);
250
-
251
- // If our target deposit ID is less than the smallest range of our
252
- // midpoint deposit ID range, then we know that the target deposit ID
253
- // must be in the lower half of the block range.
254
- if (targetDepositId.lte(accountedIdByMidBlock)) {
255
- high = mid;
256
- }
257
- // If our target deposit ID is greater than the largest range of our
258
- // midpoint deposit ID range, then we know that the target deposit ID
259
- // must be in the upper half of the block range.
260
- else {
261
- low = mid + 1;
262
- }
263
-
264
- // We want to iterate until we've either found the block range or we've
265
- // exceeded the maximum number of searches.
266
- } while (++searches <= maxSearches && low < high);
267
-
268
- // Sanity check to ensure that our low was not greater than our high.
269
- if (low > high) {
270
- throw new Error(`Binary search failed (${low} > ${high}). SHOULD NEVER HAPPEN (but here we are)`);
271
- }
272
-
273
- // We've either found the block range or we've exceeded the maximum number of searches.
274
- // In either case, the block range is [low, high] so we can return it.
275
- return { low, high };
86
+ return Math.max(fillDeadlineBuffers[0], fillDeadlineBuffers[1]);
276
87
  }
277
88
 
278
89
  /**