@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.
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +23 -29
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js +89 -92
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/clients/BundleDataClient/BundleDataClient.ts +79 -114
|
@@ -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
|
@@ -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
|
-
//
|
|
850
|
-
//
|
|
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 ${
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
1059
|
-
// for deposits that
|
|
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
|
-
//
|
|
1077
|
-
//
|
|
1078
|
-
//
|
|
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
|
|
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
|
-
//
|
|
1165
|
-
//
|
|
1166
|
-
//
|
|
1167
|
-
//
|
|
1168
|
-
//
|
|
1169
|
-
// -
|
|
1170
|
-
//
|
|
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
|
-
//
|
|
1184
|
-
//
|
|
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
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
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
|
|
1225
|
-
//
|
|
1226
|
-
//
|
|
1227
|
-
//
|
|
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
|
|
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
|
|
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) => {
|