@across-protocol/sdk 4.0.0-beta.31 → 4.0.0-beta.33

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.
@@ -1 +1 @@
1
- {"version":3,"file":"BundleDataClient.d.ts","sourceRoot":"","sources":["../../../../src/clients/BundleDataClient/BundleDataClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BundleDataClient.d.ts","sourceRoot":"","sources":["../../../../src/clients/BundleDataClient/BundleDataClient.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@across-protocol/sdk",
3
3
  "author": "UMA Team",
4
- "version": "4.0.0-beta.31",
4
+ "version": "4.0.0-beta.33",
5
5
  "license": "AGPL-3.0",
6
6
  "homepage": "https://docs.across.to/reference/sdk",
7
7
  "files": [
@@ -817,7 +817,6 @@ export class BundleDataClient {
817
817
 
818
818
  // Prerequisite step: Load all deposit events from the current or older bundles into the v3RelayHashes dictionary
819
819
  // for convenient matching with fills.
820
- let depositCounter = 0;
821
820
  for (const originChainId of allChainIds) {
822
821
  const originClient = spokePoolClients[originChainId];
823
822
  const originChainBlockRange = getBlockRangeForChain(blockRangesForChains, originChainId, chainIds);
@@ -827,13 +826,9 @@ export class BundleDataClient {
827
826
  continue;
828
827
  }
829
828
  originClient.getDepositsForDestinationChainWithDuplicates(destinationChainId).forEach((deposit) => {
830
- // Only evaluate deposits that are in this bundle or in previous bundles. This means we cannot issue fill
831
- // refunds or slow fills here for deposits that are in future bundles (i.e. "pre-fills"). Instead, we'll
832
- // evaluate these pre-fills once the deposit is inside the "current" bundle block range.
833
829
  if (deposit.blockNumber > originChainBlockRange[1] || isZeroValueDeposit(deposit)) {
834
830
  return;
835
831
  }
836
- depositCounter++;
837
832
  const relayDataHash = this.getRelayHashFromEvent(deposit);
838
833
 
839
834
  if (!v3RelayHashes[relayDataHash]) {
@@ -846,16 +841,8 @@ export class BundleDataClient {
846
841
  v3RelayHashes[relayDataHash].deposits!.push(deposit);
847
842
  }
848
843
 
849
- // Once we've saved the deposit hash into v3RelayHashes, then we can exit early here if the inputAmount
850
- // is 0 because there can be no expired amount to refund and no unexecutable slow fill amount to return
851
- // if this deposit did expire. Input amount can only be zero at this point if the message is non-empty,
852
- // but the message doesn't matter for expired deposits and unexecutable slow fills.
853
- if (deposit.inputAmount.eq(0)) {
854
- return;
855
- }
856
-
857
- // Evaluate all expired deposits after fetching fill statuses,
858
- // since we can't know for certain whether an expired deposit was filled a long time ago.
844
+ // Account for duplicate deposits by concatenating the relayDataHash with the count of the number of times
845
+ // we have seen it so far.
859
846
  const newBundleDepositHash = `${relayDataHash}@${v3RelayHashes[relayDataHash].deposits!.length - 1}`;
860
847
  const decodedBundleDepositHash = decodeBundleDepositHash(newBundleDepositHash);
861
848
  assert(
@@ -874,11 +861,24 @@ export class BundleDataClient {
874
861
  }
875
862
  this.logger.debug({
876
863
  at: "BundleDataClient#loadData",
877
- message: `Processed ${depositCounter} deposits in ${performance.now() - start}ms.`,
864
+ message: `Processed ${bundleDepositHashes.length + olderDepositHashes.length} deposits in ${
865
+ performance.now() - start
866
+ }ms.`,
878
867
  });
879
868
  start = performance.now();
880
869
 
881
- // Process fills now that we've populated relay hash dictionary with deposits:
870
+ // Process fills and maintain the following the invariants:
871
+ // - Every single fill whose type is not SlowFill in the bundle block range whose relay data matches
872
+ // with a deposit in the same or an older range produces a refund to the filler,
873
+ // unless the specified filler address cannot be repaid on the repayment chain.
874
+ // - Fills can match with duplicate deposits, so for every matched fill whose type is not SlowFill
875
+ // in the bundle block range, produce a refund to the filler for each matched deposit.
876
+ // - For every SlowFill in the block range that matches with multiple deposits, produce a refund to the depositor
877
+ // for every deposit except except the first.
878
+
879
+ // Assumptions about fills:
880
+ // - Duplicate fills for the same relay data hash are impossible to send.
881
+ // - Fills can only be sent before the deposit's fillDeadline.
882
882
  const validatedBundleV3Fills: (V3FillWithBlock & { quoteTimestamp: number })[] = [];
883
883
  const validatedBundleSlowFills: V3DepositWithBlock[] = [];
884
884
  const validatedBundleUnexecutableSlowFills: V3DepositWithBlock[] = [];
@@ -894,8 +894,6 @@ export class BundleDataClient {
894
894
  const destinationChainBlockRange = getBlockRangeForChain(blockRangesForChains, destinationChainId, chainIds);
895
895
  const originChainBlockRange = getBlockRangeForChain(blockRangesForChains, originChainId, chainIds);
896
896
 
897
- // Keep track of fast fills that replaced slow fills, which we'll use to create "unexecutable" slow fills
898
- // if the slow fill request was sent in a prior bundle.
899
897
  const fastFillsReplacingSlowFills: string[] = [];
900
898
  await forEachAsync(
901
899
  destinationClient
@@ -915,8 +913,6 @@ export class BundleDataClient {
915
913
  isDefined(v3RelayHashes[relayDataHash].deposits) && v3RelayHashes[relayDataHash].deposits!.length > 0,
916
914
  "Deposit should exist in relay hash dictionary."
917
915
  );
918
- // At this point, the v3RelayHashes entry already existed meaning that there is a matching deposit,
919
- // so this fill can no longer be filled on-chain.
920
916
  v3RelayHashes[relayDataHash].fill = fill;
921
917
  if (fill.blockNumber >= destinationChainBlockRange[0]) {
922
918
  const fillToRefund = await verifyFillRepayment(
@@ -926,8 +922,6 @@ export class BundleDataClient {
926
922
  allChainIds
927
923
  );
928
924
  if (!isDefined(fillToRefund)) {
929
- // We won't repay the fill but the depositor has received funds so we don't need to make a
930
- // payment.
931
925
  bundleUnrepayableFillsV3.push(fill);
932
926
  // We don't return here yet because we still need to mark unexecutable slow fill leaves
933
927
  // or duplicate deposits. However, we won't issue a fast fill refund.
@@ -935,7 +929,7 @@ export class BundleDataClient {
935
929
  v3RelayHashes[relayDataHash].fill = fillToRefund;
936
930
  validatedBundleV3Fills.push({
937
931
  ...fillToRefund,
938
- quoteTimestamp: v3RelayHashes[relayDataHash].deposits![0].quoteTimestamp, // ! due to assert above
932
+ quoteTimestamp: v3RelayHashes[relayDataHash].deposits![0].quoteTimestamp,
939
933
  });
940
934
 
941
935
  // Now that we know this deposit has been filled on-chain, identify any duplicate deposits
@@ -948,7 +942,6 @@ export class BundleDataClient {
948
942
  // a current bundle fill.
949
943
  const duplicateDeposits = v3RelayHashes[relayDataHash].deposits!.slice(1);
950
944
  duplicateDeposits.forEach((duplicateDeposit) => {
951
- // If fill is a slow fill, refund deposit to depositor, otherwise refund to filler.
952
945
  if (isSlowFill(fill)) {
953
946
  updateExpiredDepositsV3(expiredDepositsToRefundV3, duplicateDeposit);
954
947
  } else {
@@ -963,7 +956,6 @@ export class BundleDataClient {
963
956
  // If fill replaced a slow fill request, then mark it as one that might have created an
964
957
  // unexecutable slow fill. We can't know for sure until we check the slow fill request
965
958
  // events.
966
- // slow fill requests for deposits from or to lite chains are considered invalid
967
959
  if (
968
960
  fill.relayExecutionInfo.fillType === FillType.ReplacedSlowFill &&
969
961
  _canCreateSlowFillLeaf(v3RelayHashes[relayDataHash].deposits![0])
@@ -985,7 +977,7 @@ export class BundleDataClient {
985
977
  slowFillRequest: undefined,
986
978
  };
987
979
 
988
- // TODO: We might be able to remove the following historical query once we deprecate the deposit()
980
+ // TODO: We can remove the following historical query once we deprecate the deposit()
989
981
  // function since there won't be any old, unexpired deposits anymore assuming the spoke pool client
990
982
  // lookbacks have been validated, which they should be before we run this function.
991
983
 
@@ -1043,7 +1035,6 @@ export class BundleDataClient {
1043
1035
  // infinite deadlines are impossible to send via unsafeDeposit().
1044
1036
  }
1045
1037
 
1046
- // slow fill requests for deposits from or to lite chains are considered invalid
1047
1038
  if (
1048
1039
  fill.relayExecutionInfo.fillType === FillType.ReplacedSlowFill &&
1049
1040
  _canCreateSlowFillLeaf(matchedDeposit)
@@ -1055,8 +1046,14 @@ export class BundleDataClient {
1055
1046
  }
1056
1047
  );
1057
1048
 
1058
- // Process slow fill requests. One invariant we need to maintain is that we cannot create slow fill requests
1059
- // for deposits that would expire in this bundle.
1049
+ // Process slow fill requests and produce slow fill leaves while maintaining the following the invariants:
1050
+ // - Slow fill leaves cannot be produced for deposits that have expired in this bundle.
1051
+ // - Slow fill leaves cannot be produced for deposits that have been filled.
1052
+
1053
+ // Assumptions about fills:
1054
+ // - Duplicate slow fill requests for the same relay data hash are impossible to send.
1055
+ // - Slow fill requests can only be sent before the deposit's fillDeadline.
1056
+ // - Slow fill requests for a deposit that has been filled.
1060
1057
  await forEachAsync(
1061
1058
  destinationClient
1062
1059
  .getSlowFillRequestsForOriginChain(originChainId)
@@ -1069,34 +1066,24 @@ export class BundleDataClient {
1069
1066
 
1070
1067
  if (v3RelayHashes[relayDataHash]) {
1071
1068
  if (!v3RelayHashes[relayDataHash].slowFillRequest) {
1072
- // At this point, the v3RelayHashes entry already existed meaning that there is either a matching
1073
- // fill or deposit.
1074
1069
  v3RelayHashes[relayDataHash].slowFillRequest = slowFillRequest;
1075
1070
  if (v3RelayHashes[relayDataHash].fill) {
1076
- // If there is a fill matching the relay hash, then this slow fill request can't be used
1077
- // to create a slow fill for a filled deposit. This takes advantage of the fact that
1078
- // slow fill requests must precede fills, so if there is a matching fill for this request's
1079
- // relay data, then this slow fill will be unexecutable.
1071
+ // Exiting here assumes that slow fill requests must precede fills, so if there was a fill
1072
+ // following this slow fill request, then we would have already seen it. We don't need to check
1073
+ // for a fill older than this slow fill request.
1080
1074
  return;
1081
1075
  }
1082
1076
  assert(
1083
1077
  isDefined(v3RelayHashes[relayDataHash].deposits) && v3RelayHashes[relayDataHash].deposits!.length > 0,
1084
1078
  "Deposit should exist in relay hash dictionary."
1085
1079
  );
1086
- // The ! is safe here because we've already checked that the deposit exists in the relay hash dictionary.
1087
1080
  const matchedDeposit = v3RelayHashes[relayDataHash].deposits![0];
1088
1081
 
1089
- // If there is no fill matching the relay hash, then this might be a valid slow fill request
1090
- // that we should produce a slow fill leaf for. Check if the slow fill request is in the
1091
- // destination chain block range.
1092
1082
  if (
1093
1083
  slowFillRequest.blockNumber >= destinationChainBlockRange[0] &&
1094
1084
  _canCreateSlowFillLeaf(matchedDeposit) &&
1095
- // Deposit must not have expired in this bundle.
1096
1085
  !_depositIsExpired(matchedDeposit)
1097
1086
  ) {
1098
- // At this point, the v3RelayHashes entry already existed meaning that there is a matching deposit,
1099
- // so this slow fill request relay data is correct.
1100
1087
  validatedBundleSlowFills.push(matchedDeposit);
1101
1088
  }
1102
1089
  } else {
@@ -1112,7 +1099,7 @@ export class BundleDataClient {
1112
1099
  slowFillRequest: slowFillRequest,
1113
1100
  };
1114
1101
 
1115
- // TODO: We might be able to remove the following historical query once we deprecate the deposit()
1102
+ // TODO: We can remove the following historical query once we deprecate the deposit()
1116
1103
  // function since there won't be any old, unexpired deposits anymore assuming the spoke pool client
1117
1104
  // lookbacks have been validated, which they should be before we run this function.
1118
1105
 
@@ -1130,7 +1117,6 @@ export class BundleDataClient {
1130
1117
  ) {
1131
1118
  const historicalDeposit = await queryHistoricalDepositForFill(originClient, slowFillRequest);
1132
1119
  if (!historicalDeposit.found) {
1133
- // TODO: Invalid slow fill request. Maybe worth logging.
1134
1120
  return;
1135
1121
  }
1136
1122
  const matchedDeposit: V3DepositWithBlock = historicalDeposit.deposit;
@@ -1149,11 +1135,7 @@ export class BundleDataClient {
1149
1135
  );
1150
1136
  v3RelayHashes[relayDataHash].deposits = [matchedDeposit];
1151
1137
 
1152
- if (
1153
- !_canCreateSlowFillLeaf(matchedDeposit) ||
1154
- // Deposit must not have expired in this bundle.
1155
- _depositIsExpired(matchedDeposit)
1156
- ) {
1138
+ if (!_canCreateSlowFillLeaf(matchedDeposit) || _depositIsExpired(matchedDeposit)) {
1157
1139
  return;
1158
1140
  }
1159
1141
  validatedBundleSlowFills.push(matchedDeposit);
@@ -1161,13 +1143,27 @@ export class BundleDataClient {
1161
1143
  }
1162
1144
  );
1163
1145
 
1164
- // Deposits can be submitted an arbitrary amount of time after matching fills and slow fill requests.
1165
- // Therefore, let's go through each deposit in this bundle again and check a few things in order:
1166
- // - Has the deposit been filled ? If so, then we need to issue a relayer refund for
1167
- // this "pre-fill" if the fill took place in a previous bundle.
1168
- // - Or, has the deposit expired in this bundle? If so, then we need to issue an expiry refund.
1169
- // - And finally, has the deposit been slow filled? If so, then we need to issue a slow fill leaf
1170
- // for this "pre-slow-fill-request" if this request took place in a previous bundle.
1146
+ // Process deposits and maintain the following invariants:
1147
+ // - Deposits matching fills that are not type SlowFill from previous bundle block ranges should produce
1148
+ // refunds for those fills.
1149
+ // - Deposits matching fills that are type SlowFill from previous bundle block ranges should be refunded to the
1150
+ // depositor.
1151
+ // - All deposits expiring in this bundle, even those sent in prior bundle block ranges, should be refunded
1152
+ // to the depositor.
1153
+ // - An expired deposit cannot be refunded if the deposit was filled.
1154
+ // - If a deposit from a prior bundle expired in this bundle, had a slow fill request created for it
1155
+ // in a prior bundle, and has not been filled yet, then an unexecutable slow fill leaf has been created
1156
+ // and needs to be refunded to the HubPool.
1157
+ // - Deposits matching slow fill requests from previous bundle block ranges should produce slow fills
1158
+ // if the deposit has not been filled.
1159
+
1160
+ // Assumptions:
1161
+ // - If the deposit has a matching fill or slow fill request in the bundle then we have already stored
1162
+ // it in the relay hashes dictionary.
1163
+ // - We've created refunds for all fills in this bundle matching a deposit.
1164
+ // - We've created slow fill leaves for all slow fill requests in this bundle matching an unfilled deposit.
1165
+ // - Deposits for the same relay data hash can be sent an arbitrary amount of times.
1166
+ // - Deposits can be sent an arbitrary amount of time after a fill has been sent for the matching relay data.
1171
1167
  await mapAsync(bundleDepositHashes, async (depositHash) => {
1172
1168
  const { relayDataHash, index } = decodeBundleDepositHash(depositHash);
1173
1169
  const { deposits, fill, slowFillRequest } = v3RelayHashes[relayDataHash];
@@ -1180,40 +1176,25 @@ export class BundleDataClient {
1180
1176
  return;
1181
1177
  }
1182
1178
 
1183
- // We are willing to refund a pre-fill multiple times for each duplicate deposit.
1184
- // This is because a duplicate deposit for a pre-fill cannot get
1185
- // refunded to the depositor anymore because its fill status on-chain has changed to Filled. Therefore
1186
- // any duplicate deposits result in a net loss of funds for the depositor and effectively pay out
1187
- // the pre-filler.
1188
-
1189
- // If fill exists in memory, then the only case in which we need to create a refund is if the
1190
- // the fill occurred in a previous bundle. There are no expiry refunds for filled deposits.
1179
+ // If fill is in the current bundle then we can assume there is already a refund for it, so only
1180
+ // include this pre fill if the fill is in an older bundle.
1191
1181
  if (fill) {
1192
1182
  if (canRefundPrefills && fill.blockNumber < destinationChainBlockRange[0]) {
1193
- // If fill is in the current bundle then we can assume there is already a refund for it, so only
1194
- // include this pre fill if the fill is in an older bundle. If fill is after this current bundle, then
1195
- // we won't consider it, following the previous treatment of fills after the bundle block range.
1196
- if (!isSlowFill(fill)) {
1197
- const fillToRefund = await verifyFillRepayment(
1198
- fill,
1199
- destinationClient.spokePool.provider,
1200
- v3RelayHashes[relayDataHash].deposits![0],
1201
- allChainIds
1202
- );
1203
- if (!isDefined(fillToRefund)) {
1204
- // We won't repay the fill but the depositor has received funds so we don't need to make a
1205
- // payment.
1206
- bundleUnrepayableFillsV3.push(fill);
1207
- } else {
1208
- v3RelayHashes[relayDataHash].fill = fillToRefund;
1209
- validatedBundleV3Fills.push({
1210
- ...fillToRefund,
1211
- quoteTimestamp: deposit.quoteTimestamp,
1212
- });
1213
- }
1183
+ const fillToRefund = await verifyFillRepayment(
1184
+ fill,
1185
+ destinationClient.spokePool.provider,
1186
+ v3RelayHashes[relayDataHash].deposits![0],
1187
+ allChainIds
1188
+ );
1189
+ if (!isDefined(fillToRefund)) {
1190
+ bundleUnrepayableFillsV3.push(fill);
1191
+ } else if (!isSlowFill(fill)) {
1192
+ v3RelayHashes[relayDataHash].fill = fillToRefund;
1193
+ validatedBundleV3Fills.push({
1194
+ ...fillToRefund,
1195
+ quoteTimestamp: deposit.quoteTimestamp,
1196
+ });
1214
1197
  } else {
1215
- // Slow fills cannot result in refunds to a relayer to refund the deposit. Slow fills also
1216
- // were created after the deposit was sent, so we can assume this deposit is a duplicate.
1217
1198
  updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
1218
1199
  }
1219
1200
  }
@@ -1221,10 +1202,10 @@ export class BundleDataClient {
1221
1202
  }
1222
1203
 
1223
1204
  // If a slow fill request exists in memory, then we know the deposit has not been filled because fills
1224
- // must follow slow fill requests and we would have seen the fill already if it existed. Therefore,
1225
- // we can conclude that either the deposit has expired and we need to create a deposit expiry refund, or
1226
- // we need to create a slow fill leaf for the deposit. The latter should only happen if the slow fill request
1227
- // took place in a prior bundle otherwise we would have already created a slow fill leaf for it.
1205
+ // must follow slow fill requests and we would have seen the fill already if it existed.,
1206
+ // We can conclude that either the deposit has expired or we need to create a slow fill leaf for the
1207
+ // deposit because it has not been filled. Slow fill leaves were already created for requests sent
1208
+ // in the current bundle so only create new slow fill leaves for prior bundle deposits.
1228
1209
  if (slowFillRequest) {
1229
1210
  if (_depositIsExpired(deposit)) {
1230
1211
  updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
@@ -1245,13 +1226,8 @@ export class BundleDataClient {
1245
1226
  // because the spoke pool client lookback would have returned this entire bundle of events and stored
1246
1227
  // them into the relay hash dictionary.
1247
1228
  const fillStatus = await _getFillStatusForDeposit(deposit, destinationChainBlockRange[1]);
1248
-
1249
- // If deposit was filled, then we need to issue a refund for the fill and also any duplicate deposits
1250
- // in the same bundle.
1251
1229
  if (fillStatus === FillStatus.Filled) {
1252
- // We need to find the fill event to issue a refund to the right relayer and repayment chain,
1253
- // or msg.sender if relayer address is invalid for the repayment chain. We don't need to
1254
- // verify the fill block is before the bundle end block on the destination chain because
1230
+ // We don't need to verify the fill block is before the bundle end block on the destination chain because
1255
1231
  // we queried the fillStatus at the end block. Therefore, if the fill took place after the end block,
1256
1232
  // then we wouldn't be in this branch of the code.
1257
1233
  const prefill = await this.findMatchingFillEvent(deposit, destinationClient);
@@ -1272,29 +1248,17 @@ export class BundleDataClient {
1272
1248
  quoteTimestamp: deposit.quoteTimestamp,
1273
1249
  });
1274
1250
  } else {
1275
- // Slow fills cannot result in refunds to a relayer to refund the deposit. Slow fills also
1276
- // were created after the deposit was sent, so we can assume this deposit is a duplicate.
1277
1251
  updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
1278
1252
  }
1279
1253
  }
1280
- }
1281
- // If deposit is not filled and its newly expired, we can create a deposit refund for it.
1282
- // We don't check that fillDeadline >= bundleBlockTimestamps[destinationChainId][0] because
1283
- // that would eliminate any deposits in this bundle with a very low fillDeadline like equal to 0
1284
- // for example. Those should be included in this bundle of refunded deposits.
1285
- else if (_depositIsExpired(deposit)) {
1254
+ } else if (_depositIsExpired(deposit)) {
1286
1255
  updateExpiredDepositsV3(expiredDepositsToRefundV3, deposit);
1287
- }
1288
- // If slow fill requested, then issue a slow fill leaf for the deposit.
1289
- else if (
1256
+ } else if (
1290
1257
  fillStatus === FillStatus.RequestedSlowFill &&
1258
+ // Don't create duplicate slow fill requests for the same deposit.
1291
1259
  validatedBundleSlowFills.every((d) => this.getRelayHashFromEvent(d) !== relayDataHash)
1292
1260
  ) {
1293
- // Input and Output tokens must be equivalent on the deposit for this to be slow filled.
1294
- // Slow fill requests for deposits from or to lite chains are considered invalid
1295
1261
  if (canRefundPrefills && _canCreateSlowFillLeaf(deposit)) {
1296
- // If deposit newly expired, then we can't create a slow fill leaf for it but we can
1297
- // create a deposit refund for it.
1298
1262
  validatedBundleSlowFills.push(deposit);
1299
1263
  }
1300
1264
  }
@@ -1351,7 +1315,7 @@ export class BundleDataClient {
1351
1315
 
1352
1316
  // Only look for deposits that were mined before this bundle and that are newly expired.
1353
1317
  // If the fill deadline is lower than the bundle start block on the destination chain, then
1354
- // we should assume it was marked "newly expired" and refunded in a previous bundle.
1318
+ // we should assume it was refunded in a previous bundle.
1355
1319
  if (
1356
1320
  // If there is a valid fill that we saw matching this deposit, then it does not need a refund.
1357
1321
  !fill &&
@@ -1460,6 +1424,7 @@ export class BundleDataClient {
1460
1424
  if (validatedBundleSlowFills.slice(0, idx).some((d) => this.getRelayHashFromEvent(d) === relayDataHash)) {
1461
1425
  return;
1462
1426
  }
1427
+ assert(!_depositIsExpired(deposit), "Cannot create slow fill leaf for expired deposit.");
1463
1428
  updateBundleSlowFills(bundleSlowFillsV3, { ...deposit, lpFeePct });
1464
1429
  });
1465
1430
  v3UnexecutableSlowFillLpFees.forEach(({ realizedLpFeePct: lpFeePct }, idx) => {