@across-protocol/sdk 4.2.6-alpha.3 → 4.2.7
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/arch/svm/utils.d.ts +3 -0
- package/dist/cjs/arch/svm/utils.js +59 -1
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +40 -19
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +2 -1
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +7 -3
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +3 -3
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js +24 -22
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
- package/dist/esm/arch/svm/utils.d.ts +19 -0
- package/dist/esm/arch/svm/utils.js +72 -1
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js +40 -24
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +2 -1
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +7 -3
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +4 -13
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.js +25 -23
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
- package/dist/types/arch/svm/utils.d.ts +19 -0
- package/dist/types/arch/svm/utils.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +2 -1
- package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
- package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +4 -13
- package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/arch/svm/utils.ts +45 -0
- package/src/clients/BundleDataClient/BundleDataClient.ts +34 -24
- package/src/clients/BundleDataClient/utils/FillUtils.ts +36 -24
- package/src/relayFeeCalculator/relayFeeCalculator.ts +25 -22
|
@@ -127,7 +127,7 @@ export declare class RelayFeeCalculator {
|
|
|
127
127
|
* a message & recipient contract is provided as this function may not simulate with
|
|
128
128
|
* the correct parameters to see a full fill.
|
|
129
129
|
*/
|
|
130
|
-
gasFeePercent(deposit: Deposit,
|
|
130
|
+
gasFeePercent(deposit: Deposit, outputAmount: BigNumberish, simulateZeroFill?: boolean, relayerAddress?: string, _tokenPrice?: number, tokenMapping?: {
|
|
131
131
|
ACX: {
|
|
132
132
|
name: string;
|
|
133
133
|
symbol: string;
|
|
@@ -423,16 +423,7 @@ export declare class RelayFeeCalculator {
|
|
|
423
423
|
VLR: {
|
|
424
424
|
name: string;
|
|
425
425
|
symbol: string;
|
|
426
|
-
decimals: number;
|
|
427
|
-
* Type guard to check if a config is a CapitalCostConfigOverride or a CapitalCostConfig.
|
|
428
|
-
* @param config CapitalCostConfig or CapitalCostConfigOverride
|
|
429
|
-
* @returns true if the config is a CapitalCostConfigOverride, false otherwise.
|
|
430
|
-
* @private
|
|
431
|
-
* @dev This is a type guard that is used to check if a config is a CapitalCostConfigOverride or a CapitalCostConfig.
|
|
432
|
-
* This is needed because the config can be either a CapitalCostConfig or a CapitalCostConfigOverride. If it's a
|
|
433
|
-
* CapitalCostConfig, then we need to convert it to a CapitalCostConfigOverride with the default config set with no route
|
|
434
|
-
* overrides.
|
|
435
|
-
*/
|
|
426
|
+
decimals: number;
|
|
436
427
|
addresses: {
|
|
437
428
|
[x: number]: string;
|
|
438
429
|
};
|
|
@@ -530,7 +521,7 @@ export declare class RelayFeeCalculator {
|
|
|
530
521
|
coingeckoId: string;
|
|
531
522
|
};
|
|
532
523
|
}, gasPrice?: BigNumberish, gasLimit?: BigNumberish, _tokenGasCost?: BigNumberish, transport?: Transport): Promise<BigNumber>;
|
|
533
|
-
capitalFeePercent(
|
|
524
|
+
capitalFeePercent(_outputAmount: BigNumberish, _tokenSymbol: string, _originRoute?: ChainIdAsString, _destinationRoute?: ChainIdAsString): BigNumber;
|
|
534
525
|
/**
|
|
535
526
|
* Checks for configuration conflicts across all token symbols and their associated chain configurations.
|
|
536
527
|
* This method examines the capital costs configuration for each token and identifies any overlapping
|
|
@@ -558,7 +549,7 @@ export declare class RelayFeeCalculator {
|
|
|
558
549
|
* @param gasUnits Optional gas units to use for the simulation
|
|
559
550
|
* @returns A resulting `RelayerFeeDetails` object
|
|
560
551
|
*/
|
|
561
|
-
relayerFeeDetails(deposit: Deposit,
|
|
552
|
+
relayerFeeDetails(deposit: Deposit, outputAmount?: BigNumberish, simulateZeroFill?: boolean, relayerAddress?: string, _tokenPrice?: number, gasPrice?: BigNumberish, gasUnits?: BigNumberish, tokenGasCost?: BigNumberish): Promise<RelayerFeeDetails>;
|
|
562
553
|
}
|
|
563
554
|
export {};
|
|
564
555
|
//# sourceMappingURL=relayFeeCalculator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relayFeeCalculator.d.ts","sourceRoot":"","sources":["../../../src/relayFeeCalculator/relayFeeCalculator.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EACL,SAAS,EACT,YAAY,EAEZ,uBAAuB,
|
|
1
|
+
{"version":3,"file":"relayFeeCalculator.d.ts","sourceRoot":"","sources":["../../../src/relayFeeCalculator/relayFeeCalculator.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/arch/svm/utils.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
getAddressEncoder,
|
|
8
8
|
getProgramDerivedAddress,
|
|
9
9
|
getU64Encoder,
|
|
10
|
+
getU32Encoder,
|
|
10
11
|
isAddress,
|
|
11
12
|
type TransactionSigner,
|
|
12
13
|
} from "@solana/kit";
|
|
@@ -215,6 +216,50 @@ export async function getRoutePda(originToken: Address, seed: bigint, routeChain
|
|
|
215
216
|
return pda;
|
|
216
217
|
}
|
|
217
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Returns the PDA for the SVM Spoke's transfer liability account.
|
|
221
|
+
* @param programId the address of the spoke pool.
|
|
222
|
+
* @param originToken the address of the corresponding token.
|
|
223
|
+
*/
|
|
224
|
+
export async function getTransferLiabilityPda(programId: Address, originToken: Address): Promise<Address> {
|
|
225
|
+
const addressEncoder = getAddressEncoder();
|
|
226
|
+
const [pda] = await getProgramDerivedAddress({
|
|
227
|
+
programAddress: programId,
|
|
228
|
+
seeds: ["transfer_liability", addressEncoder.encode(originToken)],
|
|
229
|
+
});
|
|
230
|
+
return pda;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Returns the PDA for the SVM Spoke's root bundle account.
|
|
235
|
+
* @param programId the address of the spoke pool.
|
|
236
|
+
* @param statePda the spoke pool's state pda.
|
|
237
|
+
* @param rootBundleId the associated root bundle ID.
|
|
238
|
+
*/
|
|
239
|
+
export async function getRootBundlePda(programId: Address, state: Address, rootBundleId: number): Promise<Address> {
|
|
240
|
+
const intEncoder = getU32Encoder();
|
|
241
|
+
const addressEncoder = getAddressEncoder();
|
|
242
|
+
const [pda] = await getProgramDerivedAddress({
|
|
243
|
+
programAddress: programId,
|
|
244
|
+
seeds: ["root_bundle", addressEncoder.encode(state), intEncoder.encode(rootBundleId)],
|
|
245
|
+
});
|
|
246
|
+
return pda;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Returns the PDA for the SVM Spoke's instruction params account.
|
|
251
|
+
* @param programId the address of the spoke pool.
|
|
252
|
+
* @param signer the signer of the authenticated call.
|
|
253
|
+
*/
|
|
254
|
+
export async function getInstructionParamsPda(programId: Address, signer: Address): Promise<Address> {
|
|
255
|
+
const addressEncoder = getAddressEncoder();
|
|
256
|
+
const [pda] = await getProgramDerivedAddress({
|
|
257
|
+
programAddress: programId,
|
|
258
|
+
seeds: ["instruction_params", addressEncoder.encode(signer)],
|
|
259
|
+
});
|
|
260
|
+
return pda;
|
|
261
|
+
}
|
|
262
|
+
|
|
218
263
|
/**
|
|
219
264
|
* Returns the PDA for the Event Authority.
|
|
220
265
|
* @returns The PDA for the Event Authority.
|
|
@@ -94,10 +94,9 @@ function updateBundleFillsV3(
|
|
|
94
94
|
repaymentAddress: string
|
|
95
95
|
): void {
|
|
96
96
|
// We shouldn't pass any unrepayable fills into this function, so we perform an extra safety check.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
);
|
|
97
|
+
if (chainIsEvm(repaymentChainId) && !isValidEvmAddress(fill.relayer)) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
101
100
|
if (!dict?.[repaymentChainId]?.[repaymentToken]) {
|
|
102
101
|
assign(dict, [repaymentChainId, repaymentToken], {
|
|
103
102
|
fills: [],
|
|
@@ -460,13 +459,15 @@ export class BundleDataClient {
|
|
|
460
459
|
assert(isDefined(matchingDeposit), "Deposit not found for fill.");
|
|
461
460
|
|
|
462
461
|
const spokeClient = this.spokePoolClients[_fill.destinationChainId];
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
462
|
+
let provider;
|
|
463
|
+
if (isEVMSpokePoolClient(spokeClient)) {
|
|
464
|
+
provider = spokeClient.spokePool.provider;
|
|
465
|
+
} else if (isSVMSpokePoolClient(spokeClient)) {
|
|
466
|
+
provider = spokeClient.svmEventsClient.getRpc();
|
|
466
467
|
}
|
|
467
468
|
const fill = await verifyFillRepayment(
|
|
468
469
|
_fill,
|
|
469
|
-
|
|
470
|
+
provider!,
|
|
470
471
|
matchingDeposit,
|
|
471
472
|
this.clients.hubPoolClient,
|
|
472
473
|
bundleEndBlockForMainnet
|
|
@@ -971,17 +972,20 @@ export class BundleDataClient {
|
|
|
971
972
|
assert(isDefined(deposits) && deposits.length > 0, "Deposit should exist in relay hash dictionary.");
|
|
972
973
|
v3RelayHashes[relayDataHash].fill = fill;
|
|
973
974
|
if (fill.blockNumber >= destinationChainBlockRange[0]) {
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
975
|
+
let provider;
|
|
976
|
+
if (isEVMSpokePoolClient(destinationClient)) {
|
|
977
|
+
provider = destinationClient.spokePool.provider;
|
|
978
|
+
} else if (isSVMSpokePoolClient(destinationClient)) {
|
|
979
|
+
provider = destinationClient.svmEventsClient.getRpc();
|
|
977
980
|
}
|
|
978
981
|
const fillToRefund = await verifyFillRepayment(
|
|
979
982
|
fill,
|
|
980
|
-
|
|
983
|
+
provider!,
|
|
981
984
|
deposits[0],
|
|
982
985
|
this.clients.hubPoolClient,
|
|
983
986
|
bundleEndBlockForMainnet
|
|
984
987
|
);
|
|
988
|
+
|
|
985
989
|
if (!isDefined(fillToRefund)) {
|
|
986
990
|
bundleUnrepayableFillsV3.push(fill);
|
|
987
991
|
// We don't return here yet because we still need to mark unexecutable slow fill leaves
|
|
@@ -1075,14 +1079,16 @@ export class BundleDataClient {
|
|
|
1075
1079
|
}
|
|
1076
1080
|
v3RelayHashes[relayDataHash].deposits = [matchedDeposit];
|
|
1077
1081
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1082
|
+
let provider;
|
|
1083
|
+
if (isEVMSpokePoolClient(destinationClient)) {
|
|
1084
|
+
provider = destinationClient.spokePool.provider;
|
|
1085
|
+
} else if (isSVMSpokePoolClient(destinationClient)) {
|
|
1086
|
+
provider = destinationClient.svmEventsClient.getRpc();
|
|
1081
1087
|
}
|
|
1082
1088
|
|
|
1083
1089
|
const fillToRefund = await verifyFillRepayment(
|
|
1084
1090
|
fill,
|
|
1085
|
-
|
|
1091
|
+
provider!,
|
|
1086
1092
|
matchedDeposit,
|
|
1087
1093
|
this.clients.hubPoolClient,
|
|
1088
1094
|
bundleEndBlockForMainnet
|
|
@@ -1257,13 +1263,15 @@ export class BundleDataClient {
|
|
|
1257
1263
|
// include this pre fill if the fill is in an older bundle.
|
|
1258
1264
|
if (fill) {
|
|
1259
1265
|
if (fill.blockNumber < destinationChainBlockRange[0]) {
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1266
|
+
let provider;
|
|
1267
|
+
if (isEVMSpokePoolClient(destinationClient)) {
|
|
1268
|
+
provider = destinationClient.spokePool.provider;
|
|
1269
|
+
} else if (isSVMSpokePoolClient(destinationClient)) {
|
|
1270
|
+
provider = destinationClient.svmEventsClient.getRpc();
|
|
1263
1271
|
}
|
|
1264
1272
|
const fillToRefund = await verifyFillRepayment(
|
|
1265
1273
|
fill,
|
|
1266
|
-
|
|
1274
|
+
provider!,
|
|
1267
1275
|
deposits[0],
|
|
1268
1276
|
this.clients.hubPoolClient,
|
|
1269
1277
|
bundleEndBlockForMainnet
|
|
@@ -1314,13 +1322,15 @@ export class BundleDataClient {
|
|
|
1314
1322
|
const prefill = await this.findMatchingFillEvent(deposit, destinationClient);
|
|
1315
1323
|
assert(isDefined(prefill), `findFillEvent# Cannot find prefill: ${relayDataHash}`);
|
|
1316
1324
|
assert(getRelayEventKey(prefill) === relayDataHash, "Relay hashes should match.");
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1325
|
+
let provider;
|
|
1326
|
+
if (isEVMSpokePoolClient(destinationClient)) {
|
|
1327
|
+
provider = destinationClient.spokePool.provider;
|
|
1328
|
+
} else if (isSVMSpokePoolClient(destinationClient)) {
|
|
1329
|
+
provider = destinationClient.svmEventsClient.getRpc();
|
|
1320
1330
|
}
|
|
1321
1331
|
const verifiedFill = await verifyFillRepayment(
|
|
1322
1332
|
prefill,
|
|
1323
|
-
|
|
1333
|
+
provider!,
|
|
1324
1334
|
deposit,
|
|
1325
1335
|
this.clients.hubPoolClient,
|
|
1326
1336
|
bundleEndBlockForMainnet
|
|
@@ -4,6 +4,7 @@ import { providers } from "ethers";
|
|
|
4
4
|
import { DepositWithBlock, Fill, FillWithBlock } from "../../../interfaces";
|
|
5
5
|
import { isSlowFill, isValidEvmAddress, isDefined, chainIsEvm } from "../../../utils";
|
|
6
6
|
import { HubPoolClient } from "../../HubPoolClient";
|
|
7
|
+
import { SVMProvider } from "../../../arch/svm";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @notice FillRepaymentInformation is a fill with additional properties required to determine where it can
|
|
@@ -65,7 +66,7 @@ export function getRefundInformationFromFill(
|
|
|
65
66
|
*/
|
|
66
67
|
export async function verifyFillRepayment(
|
|
67
68
|
_fill: FillWithBlock,
|
|
68
|
-
destinationChainProvider: providers.Provider,
|
|
69
|
+
destinationChainProvider: providers.Provider | SVMProvider,
|
|
69
70
|
matchedDeposit: DepositWithBlock,
|
|
70
71
|
hubPoolClient: HubPoolClient,
|
|
71
72
|
bundleEndBlockForMainnet: number
|
|
@@ -91,32 +92,43 @@ export async function verifyFillRepayment(
|
|
|
91
92
|
if (_repaymentAddressNeedsToBeOverwritten(fill)) {
|
|
92
93
|
// TODO: Handle case where fill was sent on non-EVM chain, in which case the following call would fail
|
|
93
94
|
// or return something unexpected. We'd want to return undefined here.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
!matchedDeposit.fromLiteChain &&
|
|
105
|
-
hubPoolClient.areTokensEquivalent(fill.inputToken, fill.originChainId, fill.outputToken, fill.destinationChainId)
|
|
106
|
-
) {
|
|
107
|
-
repaymentChainId = fill.destinationChainId;
|
|
108
|
-
}
|
|
109
|
-
// If we can't switch the chain, then we need to verify that the msg.sender is a valid address on the repayment chain.
|
|
110
|
-
// Because we already checked that the `destinationRelayer` was a valid EVM address above, we only need to check
|
|
111
|
-
// that the repayment chain is an EVM chain.
|
|
112
|
-
else {
|
|
113
|
-
if (!chainIsEvm(repaymentChainId)) {
|
|
95
|
+
if (chainIsEvm(fill.destinationChainId)) {
|
|
96
|
+
assert(
|
|
97
|
+
destinationChainProvider instanceof providers.Provider,
|
|
98
|
+
`BundleDataClient#verifyFillRepayment: unexpected destination chain provider for chain ID ${fill.destinationChainId}`
|
|
99
|
+
);
|
|
100
|
+
const fillTransaction = await destinationChainProvider.getTransaction(fill.txnRef);
|
|
101
|
+
const destinationRelayer = fillTransaction?.from;
|
|
102
|
+
// Repayment chain is still an EVM chain, but the msg.sender is a bytes32 address, so the fill is invalid.
|
|
103
|
+
if (!isDefined(destinationRelayer) || !isValidEvmAddress(destinationRelayer)) {
|
|
114
104
|
return undefined;
|
|
115
105
|
}
|
|
106
|
+
// If we can switch the repayment chain to the destination chain, then do so. We should only switch if the
|
|
107
|
+
// destination chain has a valid repayment token that is equivalent to the deposited input token. This would
|
|
108
|
+
// also be the same mapping as the repayment token on the repayment chain.
|
|
109
|
+
if (
|
|
110
|
+
!matchedDeposit.fromLiteChain &&
|
|
111
|
+
hubPoolClient.areTokensEquivalent(
|
|
112
|
+
fill.inputToken,
|
|
113
|
+
fill.originChainId,
|
|
114
|
+
fill.outputToken,
|
|
115
|
+
fill.destinationChainId
|
|
116
|
+
)
|
|
117
|
+
) {
|
|
118
|
+
repaymentChainId = fill.destinationChainId;
|
|
119
|
+
}
|
|
120
|
+
// If we can't switch the chain, then we need to verify that the msg.sender is a valid address on the repayment chain.
|
|
121
|
+
// Because we already checked that the `destinationRelayer` was a valid EVM address above, we only need to check
|
|
122
|
+
// that the repayment chain is an EVM chain.
|
|
123
|
+
else {
|
|
124
|
+
if (!chainIsEvm(repaymentChainId)) {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
fill.relayer = destinationRelayer;
|
|
129
|
+
} else {
|
|
130
|
+
return undefined;
|
|
116
131
|
}
|
|
117
|
-
fill.relayer = destinationRelayer;
|
|
118
|
-
|
|
119
|
-
// @todo: If chainIsSvm:
|
|
120
132
|
}
|
|
121
133
|
|
|
122
134
|
// Repayment address is now valid and repayment chain is either origin chain for lite chain or the destination
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
toBNWei,
|
|
23
23
|
isZeroAddress,
|
|
24
24
|
compareAddressesSimple,
|
|
25
|
+
ConvertDecimals,
|
|
25
26
|
chainIsSvm,
|
|
26
27
|
} from "../utils";
|
|
27
28
|
import { Transport } from "viem";
|
|
@@ -251,7 +252,7 @@ export class RelayFeeCalculator {
|
|
|
251
252
|
*/
|
|
252
253
|
async gasFeePercent(
|
|
253
254
|
deposit: Deposit,
|
|
254
|
-
|
|
255
|
+
outputAmount: BigNumberish,
|
|
255
256
|
simulateZeroFill = false,
|
|
256
257
|
relayerAddress = getDefaultSimulatedRelayerAddress(deposit.destinationChainId),
|
|
257
258
|
_tokenPrice?: number,
|
|
@@ -261,7 +262,7 @@ export class RelayFeeCalculator {
|
|
|
261
262
|
_tokenGasCost?: BigNumberish,
|
|
262
263
|
transport?: Transport
|
|
263
264
|
): Promise<BigNumber> {
|
|
264
|
-
if (toBN(
|
|
265
|
+
if (toBN(outputAmount).eq(bnZero)) return MAX_BIG_INT;
|
|
265
266
|
|
|
266
267
|
const { inputToken, destinationChainId, originChainId } = deposit;
|
|
267
268
|
// It's fine if we resolve a destination token which is not the "canonical" L1 token (e.g. USDB for DAI or USDC.e for USDC), since `getTokenInfo` will re-map
|
|
@@ -284,7 +285,7 @@ export class RelayFeeCalculator {
|
|
|
284
285
|
|
|
285
286
|
// Reduce the output amount to simulate a full fill with a lower value to estimate
|
|
286
287
|
// the fill cost accurately without risking a failure due to insufficient balance.
|
|
287
|
-
const simulatedAmount = simulateZeroFill ? safeOutputAmount : toBN(
|
|
288
|
+
const simulatedAmount = simulateZeroFill ? safeOutputAmount : toBN(outputAmount);
|
|
288
289
|
deposit = { ...deposit, outputAmount: simulatedAmount };
|
|
289
290
|
|
|
290
291
|
const getGasCosts = this.queries
|
|
@@ -314,19 +315,19 @@ export class RelayFeeCalculator {
|
|
|
314
315
|
throw error;
|
|
315
316
|
}),
|
|
316
317
|
]);
|
|
317
|
-
const gasFeesInToken = nativeToToken(tokenGasCost, tokenPrice,
|
|
318
|
-
return percent(gasFeesInToken,
|
|
318
|
+
const gasFeesInToken = nativeToToken(tokenGasCost, tokenPrice, outputTokenInfo.decimals, this.nativeTokenDecimals);
|
|
319
|
+
return percent(gasFeesInToken, outputAmount.toString());
|
|
319
320
|
}
|
|
320
321
|
|
|
321
322
|
// Note: these variables are unused now, but may be needed in future versions of this function that are more complex.
|
|
322
323
|
capitalFeePercent(
|
|
323
|
-
|
|
324
|
+
_outputAmount: BigNumberish,
|
|
324
325
|
_tokenSymbol: string,
|
|
325
326
|
_originRoute?: ChainIdAsString,
|
|
326
327
|
_destinationRoute?: ChainIdAsString
|
|
327
328
|
): BigNumber {
|
|
328
329
|
// If amount is 0, then the capital fee % should be the max 100%
|
|
329
|
-
if (toBN(
|
|
330
|
+
if (toBN(_outputAmount).eq(toBN(0))) return MAX_BIG_INT;
|
|
330
331
|
|
|
331
332
|
// V0: Ensure that there is a capital fee available for the token.
|
|
332
333
|
// If not, then we should throw an error because this is indicative
|
|
@@ -366,7 +367,7 @@ export class RelayFeeCalculator {
|
|
|
366
367
|
);
|
|
367
368
|
|
|
368
369
|
// Scale amount "y" to 18 decimals.
|
|
369
|
-
const y = toBN(
|
|
370
|
+
const y = toBN(_outputAmount).mul(toBNWei("1", 18 - config.decimals));
|
|
370
371
|
// At a minimum, the fee will be equal to lower bound fee * y
|
|
371
372
|
const minCharge = toBN(config.lowerBound).mul(y).div(fixedPointAdjustment);
|
|
372
373
|
|
|
@@ -490,7 +491,7 @@ export class RelayFeeCalculator {
|
|
|
490
491
|
*/
|
|
491
492
|
async relayerFeeDetails(
|
|
492
493
|
deposit: Deposit,
|
|
493
|
-
|
|
494
|
+
outputAmount?: BigNumberish,
|
|
494
495
|
simulateZeroFill = false,
|
|
495
496
|
relayerAddress = getDefaultSimulatedRelayerAddress(deposit.destinationChainId),
|
|
496
497
|
_tokenPrice?: number,
|
|
@@ -500,18 +501,19 @@ export class RelayFeeCalculator {
|
|
|
500
501
|
): Promise<RelayerFeeDetails> {
|
|
501
502
|
// If the amount to relay is not provided, then we
|
|
502
503
|
// should use the full deposit amount.
|
|
503
|
-
|
|
504
|
-
const { inputToken, originChainId } = deposit;
|
|
504
|
+
outputAmount ??= deposit.outputAmount;
|
|
505
|
+
const { inputToken, originChainId, outputToken, destinationChainId } = deposit;
|
|
505
506
|
// We can perform a simple lookup with `getTokenInfo` here without resolving the exact token to resolve since we only need to
|
|
506
507
|
// resolve the L1 token symbol and not the L2 token decimals.
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
508
|
+
const inputTokenInfo = getTokenInfo(inputToken, originChainId);
|
|
509
|
+
const outputTokenInfo = getTokenInfo(outputToken, destinationChainId);
|
|
510
|
+
if (!isDefined(inputTokenInfo) || !isDefined(outputTokenInfo)) {
|
|
511
|
+
throw new Error(`Could not find token information for ${inputToken} or ${outputToken}`);
|
|
510
512
|
}
|
|
511
513
|
|
|
512
514
|
const gasFeePercent = await this.gasFeePercent(
|
|
513
515
|
deposit,
|
|
514
|
-
|
|
516
|
+
outputAmount,
|
|
515
517
|
simulateZeroFill,
|
|
516
518
|
relayerAddress,
|
|
517
519
|
_tokenPrice,
|
|
@@ -520,14 +522,15 @@ export class RelayFeeCalculator {
|
|
|
520
522
|
gasUnits,
|
|
521
523
|
tokenGasCost
|
|
522
524
|
);
|
|
523
|
-
const
|
|
525
|
+
const outToInDecimals = ConvertDecimals(outputTokenInfo.decimals, inputTokenInfo.decimals);
|
|
526
|
+
const gasFeeTotal = gasFeePercent.mul(outToInDecimals(outputAmount.toString())).div(fixedPointAdjustment);
|
|
524
527
|
const capitalFeePercent = this.capitalFeePercent(
|
|
525
|
-
|
|
526
|
-
|
|
528
|
+
outputAmount,
|
|
529
|
+
inputTokenInfo.symbol,
|
|
527
530
|
deposit.originChainId.toString(),
|
|
528
531
|
deposit.destinationChainId.toString()
|
|
529
532
|
);
|
|
530
|
-
const capitalFeeTotal = capitalFeePercent.mul(
|
|
533
|
+
const capitalFeeTotal = capitalFeePercent.mul(outToInDecimals(outputAmount.toString())).div(fixedPointAdjustment);
|
|
531
534
|
const relayFeePercent = gasFeePercent.add(capitalFeePercent);
|
|
532
535
|
const relayFeeTotal = gasFeeTotal.add(capitalFeeTotal);
|
|
533
536
|
|
|
@@ -546,12 +549,12 @@ export class RelayFeeCalculator {
|
|
|
546
549
|
isAmountTooLow = true;
|
|
547
550
|
} else {
|
|
548
551
|
minDeposit = gasFeeTotal.mul(fixedPointAdjustment).div(maxGasFeePercent);
|
|
549
|
-
isAmountTooLow = toBN(
|
|
552
|
+
isAmountTooLow = toBN(outputAmount).lt(minDeposit);
|
|
550
553
|
}
|
|
551
554
|
|
|
552
555
|
return {
|
|
553
|
-
amountToRelay:
|
|
554
|
-
tokenSymbol:
|
|
556
|
+
amountToRelay: outputAmount.toString(),
|
|
557
|
+
tokenSymbol: inputTokenInfo.symbol,
|
|
555
558
|
gasFeePercent: gasFeePercent.toString(),
|
|
556
559
|
gasFeeTotal: gasFeeTotal.toString(),
|
|
557
560
|
gasDiscountPercent: this.gasDiscountPercent,
|