From 0ba024d44ea9e655e2bda6e8837bb14380314bac Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:12:02 +0200 Subject: [PATCH 1/8] fix(relayer): Invert gasLimit nullification The relayer has had a bug for a while where it is incorrectly dropping the precomputed gas limit for non-message fills. Instead, it was retaining the limit for message fills. This can lead to unnecessary transaction simulation later on, increasing RPC consumption and potentially delaying fills. --- src/relayer/Relayer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/relayer/Relayer.ts b/src/relayer/Relayer.ts index 7049ebb83..2d8da1728 100644 --- a/src/relayer/Relayer.ts +++ b/src/relayer/Relayer.ts @@ -695,7 +695,7 @@ export class Relayer { // Update local balance to account for the enqueued fill. tokenClient.decrementLocalBalance(destinationChainId, outputToken, outputAmount); - const gasLimit = isMessageEmpty(resolveDepositMessage(deposit)) ? undefined : _gasLimit; + const gasLimit = isMessageEmpty(resolveDepositMessage(deposit)) ? _gasLimit : undefined; this.fillRelay(deposit, repaymentChainId, realizedLpFeePct, gasLimit); } } else if (selfRelay) { From 267013cfbd8d05d1a85f724c28aae7ad4c27466c Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:42:47 +0200 Subject: [PATCH 2/8] Bump test gasLimit 100k -> 150k --- test/mocks/MockProfitClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mocks/MockProfitClient.ts b/test/mocks/MockProfitClient.ts index e20a31a21..661f540aa 100644 --- a/test/mocks/MockProfitClient.ts +++ b/test/mocks/MockProfitClient.ts @@ -7,7 +7,7 @@ import { MockHubPoolClient } from "./MockHubPoolClient"; type TransactionCostEstimate = sdkUtils.TransactionCostEstimate; -const defaultFillCost = toBN(100_000); // gas +const defaultFillCost = toBN(150_000); // gas const defaultGasPrice = bnOne; // wei per gas export class MockProfitClient extends ProfitClient { From 31e699f79ab06cf84ad4eec871bdac5c6a53a375 Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:52:38 +0200 Subject: [PATCH 3/8] Drop override entirely --- src/relayer/Relayer.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/relayer/Relayer.ts b/src/relayer/Relayer.ts index 2d8da1728..72311727c 100644 --- a/src/relayer/Relayer.ts +++ b/src/relayer/Relayer.ts @@ -667,7 +667,7 @@ export class Relayer { l1Token, lpFees ); - const { relayerFeePct, gasCost, gasLimit: _gasLimit, lpFeePct: realizedLpFeePct } = repaymentChainProfitability; + const { relayerFeePct, gasCost, gasLimit, lpFeePct: realizedLpFeePct } = repaymentChainProfitability; if (!isDefined(repaymentChainId)) { profitClient.captureUnprofitableFill(deposit, realizedLpFeePct, relayerFeePct, gasCost); } else { @@ -695,7 +695,6 @@ export class Relayer { // Update local balance to account for the enqueued fill. tokenClient.decrementLocalBalance(destinationChainId, outputToken, outputAmount); - const gasLimit = isMessageEmpty(resolveDepositMessage(deposit)) ? _gasLimit : undefined; this.fillRelay(deposit, repaymentChainId, realizedLpFeePct, gasLimit); } } else if (selfRelay) { From 6bf012a7fa1e3309f8a5aa23519dfda25f892b31 Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Fri, 25 Oct 2024 17:28:17 +0200 Subject: [PATCH 4/8] Pre-simulate all tokens --- src/clients/ProfitClient.ts | 59 ++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/src/clients/ProfitClient.ts b/src/clients/ProfitClient.ts index ec5907e52..aae048d9b 100644 --- a/src/clients/ProfitClient.ts +++ b/src/clients/ProfitClient.ts @@ -91,7 +91,7 @@ export class ProfitClient { private unprofitableFills: { [chainId: number]: UnprofitableFill[] } = {}; // Track total gas costs of a relay on each chain. - protected totalGasCosts: { [chainId: number]: TransactionCostEstimate } = {}; + protected totalGasCosts: { [chainId: number]: { [outputToken: string]: TransactionCostEstimate } } = {}; // Queries needed to fetch relay gas costs. private relayerFeeQueries: { [chainId: number]: relayFeeCalculator.QueryInterface } = {}; @@ -217,12 +217,12 @@ export class ProfitClient { } async getTotalGasCost(deposit: Deposit): Promise { - const { destinationChainId: chainId } = deposit; + const { destinationChainId, outputToken } = deposit; // If there's no attached message, gas consumption from previous fills can be used in most cases. - // @todo: Simulate this per-token in future, because some ERC20s consume more gas. - if (isMessageEmpty(resolveDepositMessage(deposit)) && isDefined(this.totalGasCosts[chainId])) { - return this.totalGasCosts[chainId]; + const gasCost = this.totalGasCosts[destinationChainId]?.[outputToken]; + if (isMessageEmpty(resolveDepositMessage(deposit)) && isDefined(gasCost)) { + return gasCost; } return this._getTotalGasCost(deposit, this.relayerAddress); @@ -582,19 +582,11 @@ export class ProfitClient { const outputAmount = toBN(100); // Avoid rounding to zero but ensure the relayer has sufficient balance to estimate. const currentTime = getCurrentTime(); - // Prefer USDC on mainnet because it's consistent in terms of gas estimation (no unwrap conditional). - // Prefer WETH on testnet because it's more likely to be configured for the destination SpokePool. - // The relayer _cannot_ be the recipient because the SpokePool skips the ERC20 transfer. Instead, use - // the main RL address because it has all supported tokens and approvals in place on all chains. - const testSymbols = { - [CHAIN_IDs.BLAST]: "USDB", - [CHAIN_IDs.LISK]: "USDT", // USDC is not yet supported on Lisk, so revert to USDT. @todo: Update. - [CHAIN_IDs.REDSTONE]: "WETH", // Redstone only supports WETH. - [CHAIN_IDs.WORLD_CHAIN]: "WETH", // USDC deferred on World Chain. - }; + const ignoredTokens = ["BADGER", "BOBA"]; + const l1Tokens = hubPoolClient.getL1Tokens().filter(({ symbol }) => !ignoredTokens.includes(symbol)); + const prodRelayer = process.env.RELAYER_FILL_SIMULATION_ADDRESS ?? PROD_RELAYER; - const [defaultTestSymbol, relayer] = - this.hubPoolClient.chainId === CHAIN_IDs.MAINNET ? ["USDC", prodRelayer] : ["WETH", TEST_RELAYER]; + const relayer = this.hubPoolClient.chainId === CHAIN_IDs.MAINNET ? prodRelayer : TEST_RELAYER; // @dev The relayer _cannot_ be the recipient because the SpokePool skips the ERC20 transfer. Instead, // use the main RL address because it has all supported tokens and approvals in place on all chains. @@ -617,18 +609,31 @@ export class ProfitClient { toLiteChain: false, }; + const spokeTokens = Object.fromEntries( + enabledChainIds.map((destinationChainId) => { + const spokeTokens = + destinationChainId === hubPoolClient.chainId + ? l1Tokens.map(({ address }) => address) + : l1Tokens + .map(({ address }) => { + try { + return hubPoolClient.getL2TokenForL1TokenAtBlock(address, destinationChainId); + } catch { + return undefined; + } + }) + .filter(isDefined); + return [destinationChainId, spokeTokens]; + }) + ); + // Pre-fetch total gas costs for relays on enabled chains. await sdkUtils.mapAsync(enabledChainIds, async (destinationChainId) => { - const symbol = testSymbols[destinationChainId] ?? defaultTestSymbol; - const hubToken = TOKEN_SYMBOLS_MAP[symbol].addresses[this.hubPoolClient.chainId]; - const outputToken = - destinationChainId === hubPoolClient.chainId - ? hubToken - : hubPoolClient.getL2TokenForL1TokenAtBlock(hubToken, destinationChainId); - assert(isDefined(outputToken), `Chain ${destinationChainId} SpokePool is not configured for ${symbol}`); - - const deposit = { ...sampleDeposit, destinationChainId, outputToken }; - this.totalGasCosts[destinationChainId] = await this._getTotalGasCost(deposit, relayer); + this.totalGasCosts[destinationChainId] ??= {}; + await sdkUtils.mapAsync(spokeTokens[destinationChainId], async (outputToken) => { + const deposit = { ...sampleDeposit, destinationChainId, outputToken }; + this.totalGasCosts[destinationChainId][outputToken] = await this._getTotalGasCost(deposit, relayer); + }); }); this.logger.debug({ From 958691fbc156c6f59baefa5832bf05d39654b594 Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Thu, 16 Jan 2025 13:22:00 +0000 Subject: [PATCH 5/8] lint --- src/relayer/Relayer.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/relayer/Relayer.ts b/src/relayer/Relayer.ts index e59af759d..aebad2ebe 100644 --- a/src/relayer/Relayer.ts +++ b/src/relayer/Relayer.ts @@ -675,13 +675,7 @@ export class Relayer { l1Token, lpFees ); - const { - relayerFeePct, - gasCost, - gasLimit, - lpFeePct, - gasPrice, - } = repaymentChainProfitability; + const { relayerFeePct, gasCost, gasLimit, lpFeePct, gasPrice } = repaymentChainProfitability; if (!isDefined(repaymentChainId)) { profitClient.captureUnprofitableFill(deposit, lpFeePct, relayerFeePct, gasCost); } else { From d6f5a41f2c879bc40c4913cd5f2cd69bdab9316f Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Thu, 16 Jan 2025 18:14:27 +0000 Subject: [PATCH 6/8] fixes --- src/clients/ProfitClient.ts | 11 +++++++++-- src/relayer/Relayer.ts | 17 ++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/clients/ProfitClient.ts b/src/clients/ProfitClient.ts index 591ee4c8c..4c4a09a77 100644 --- a/src/clients/ProfitClient.ts +++ b/src/clients/ProfitClient.ts @@ -232,7 +232,7 @@ export class ProfitClient { return this._getTotalGasCost(deposit, this.relayerAddress); } - getGasCostsForChain(chainId: number): TransactionCostEstimate { + getGasCostsForChain(chainId: number): { [token: string]: TransactionCostEstimate } { return this.totalGasCosts[chainId]; } @@ -654,8 +654,15 @@ export class ProfitClient { }) ); + type GasCostLog = sdkUtils.TransactionCostEstimate & { + scaledNativeGasCost: BigNumber; + scaledTokenGasCost: BigNumber; + gasPadding: string; + gasMultiplier: string; + }; + // Pre-fetch total gas costs for relays on enabled chains. - const totalGasCostsToLog: { [destinationChainId: number]: {} } = {}; + const totalGasCostsToLog: { [destinationChainId: number]: { [token: string]: GasCostLog } } = {}; await sdkUtils.mapAsync(enabledChainIds, async (destinationChainId) => { this.totalGasCosts[destinationChainId] ??= {}; await sdkUtils.mapAsync(spokeTokens[destinationChainId], async (outputToken) => { diff --git a/src/relayer/Relayer.ts b/src/relayer/Relayer.ts index aebad2ebe..140d86483 100644 --- a/src/relayer/Relayer.ts +++ b/src/relayer/Relayer.ts @@ -727,7 +727,7 @@ export class Relayer { deposit, destinationChainId, lpFeePct, - this.clients.profitClient.getGasCostsForChain(destinationChainId).gasPrice + this.clients.profitClient.getGasCostsForChain(destinationChainId)[deposit.outputToken].gasPrice ); } else { // TokenClient.getBalance returns that we don't have enough balance to submit the fast fill. @@ -985,7 +985,7 @@ export class Relayer { deposit: Deposit, repaymentChainId: number, realizedLpFeePct: BigNumber, - gasPrice: BigNumber, + gasPrice?: BigNumber, gasLimit?: BigNumber ): void { const { spokePoolClients } = this.clients; @@ -1387,7 +1387,7 @@ export class Relayer { deposit: Deposit, repaymentChainId: number, realizedLpFeePct: BigNumber, - gasPrice: BigNumber + gasPrice?: BigNumber ): string { let mrkdwn = this.constructBaseFillMarkdown(deposit, realizedLpFeePct, gasPrice) + @@ -1405,7 +1405,7 @@ export class Relayer { return mrkdwn; } - private constructBaseFillMarkdown(deposit: Deposit, _realizedLpFeePct: BigNumber, _gasPriceGwei: BigNumber): string { + private constructBaseFillMarkdown(deposit: Deposit, _realizedLpFeePct: BigNumber, gasPrice?: BigNumber): string { const { symbol, decimals } = this.clients.hubPoolClient.getTokenInfoForDeposit(deposit); const srcChain = getNetworkName(deposit.originChainId); const dstChain = getNetworkName(deposit.destinationChainId); @@ -1422,11 +1422,14 @@ export class Relayer { const { symbol: outputTokenSymbol, decimals: outputTokenDecimals } = this.clients.hubPoolClient.getTokenInfoForAddress(deposit.outputToken, deposit.destinationChainId); const _outputAmount = createFormatFunction(2, 4, false, outputTokenDecimals)(deposit.outputAmount.toString()); + msg += ` and output ${_outputAmount} ${outputTokenSymbol}, with depositor ${depositor}.` + - ` Realized LP fee: ${realizedLpFeePct}%, total fee: ${totalFeePct}%. Gas price used in profit calc: ${formatGwei( - _gasPriceGwei.toString() - )} Gwei.`; + ` Realized LP fee: ${realizedLpFeePct}%, total fee: ${totalFeePct}%.`; + + if (isDefined(gasPrice)) { + msg += ` Gas price: ${formatGwei(gasPrice.toString())} Gwei.`; + } return msg; } From 61c99770e15e16951ddd59bbf460a3d8db22603f Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Thu, 16 Jan 2025 20:55:40 +0000 Subject: [PATCH 7/8] Fix test --- test/ProfitClient.ConsiderProfitability.ts | 45 ++++++++++++---------- test/mocks/MockProfitClient.ts | 37 ++++++++++-------- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/test/ProfitClient.ConsiderProfitability.ts b/test/ProfitClient.ConsiderProfitability.ts index cc38639d8..5a00b2b0b 100644 --- a/test/ProfitClient.ConsiderProfitability.ts +++ b/test/ProfitClient.ConsiderProfitability.ts @@ -82,7 +82,7 @@ describe("ProfitClient: Consider relay profit", () => { const tokenGasCost = nativeGasCost.mul(gasPrice).div(toBN(10).pow(9)); profitClient.setTokenPrice(gasToken.address, gasTokenPriceUsd); - profitClient.setGasCost(chainId, { nativeGasCost, tokenGasCost, gasPrice }); + profitClient.setGasCost(chainId, v3DepositTemplate.outputToken, { nativeGasCost, tokenGasCost, gasPrice }); return { nativeGasCost, tokenGasCost, gasPrice, gasTokenPriceUsd }; }; @@ -103,13 +103,18 @@ describe("ProfitClient: Consider relay profit", () => { // Quirk: Use the chainId as the gas price in Gwei. This gives a range of // gas prices to test with, since there's a spread in the chainId numbers. - const gasCost: { [chainId: number]: TransactionCostEstimate } = Object.fromEntries( + const gasCost: { [chainId: number]: { [token: string]: TransactionCostEstimate } } = Object.fromEntries( chainIds.map((chainId) => { const nativeGasCost = toBN(100_000); // Assume 100k gas for a single fill const gasTokenPrice = toBN(chainId); const gasPrice = gasTokenPrice; - const tokenGasCost = nativeGasCost.mul(gasPrice); - return [chainId, { nativeGasCost, tokenGasCost, gasPrice }]; + const _tokenGasCost = nativeGasCost.mul(gasPrice); + const tokenGasCost = Object.fromEntries( + Object.values(tokens).map(({ address }) => + [address, { nativeGasCost, tokenGasCost: _tokenGasCost, gasPrice }] + ) + ); + return [chainId, tokenGasCost]; }) ); @@ -260,8 +265,8 @@ describe("ProfitClient: Consider relay profit", () => { it("Return uint256Max when gas cost fails to be fetched", async () => { const destinationChainId = 137; - profitClient.setGasCost(destinationChainId, undefined); const deposit = { ...v3DepositTemplate, destinationChainId }; + profitClient.setGasCost(destinationChainId, deposit.outputToken, undefined); const { nativeGasCost, tokenGasCost } = await profitClient.getTotalGasCost(deposit); expect(nativeGasCost.eq(uint256Max)).to.be.true; expect(tokenGasCost.eq(uint256Max)).to.be.true; @@ -280,9 +285,9 @@ describe("ProfitClient: Consider relay profit", () => { spyLogger.debug({ message: `Verify exception on chain ${destinationChainId} gas cost estimation failure.` }); const destinationGasCost = await profitClient.getTotalGasCost(deposit); - profitClient.setGasCost(destinationChainId, undefined); + profitClient.setGasCost(destinationChainId, deposit.outputToken, undefined); await assertPromiseError(profitClient.calculateFillProfitability(deposit, zeroLPFee, minRelayerFeePct)); - profitClient.setGasCost(destinationChainId, destinationGasCost); + profitClient.setGasCost(destinationChainId, deposit.outputToken, destinationGasCost); spyLogger.debug({ message: `Verifying exception on chain ${destinationChainId} token price lookup failure.` }); const l1TokenPrice = profitClient.getPriceOfToken(l1Token.address); @@ -302,11 +307,11 @@ describe("ProfitClient: Consider relay profit", () => { for (const originChainId of chainIds) { for (const destinationChainId of chainIds.filter((chainId) => chainId !== originChainId)) { - const { nativeGasCost: baseNativeGasCost, gasPrice } = gasCost[destinationChainId]; + const { outputToken } = v3DepositTemplate; for (const token of Object.values(tokens)) { const inputToken = randomAddress(); - const outputToken = randomAddress(); + const { nativeGasCost: baseNativeGasCost, gasPrice } = gasCost[destinationChainId][token.address]; const outputAmount = toBN(1).mul(bn10.pow(token.decimals)); const inputAmount = outputAmount @@ -340,7 +345,7 @@ describe("ProfitClient: Consider relay profit", () => { const nativeGasCost = baseNativeGasCost.mul(gasCostMultiplier).div(fixedPoint); const tokenGasCost = nativeGasCost.mul(gasPrice); const gasCostUsd = tokenGasCost.mul(gasTokenPriceUsd).div(fixedPoint); - profitClient.setGasCost(destinationChainId, { nativeGasCost, tokenGasCost, gasPrice }); + profitClient.setGasCost(destinationChainId, deposit.outputToken, { nativeGasCost, tokenGasCost, gasPrice }); const gasCostPct = gasCostUsd.mul(fixedPoint).div(outputAmountUsd); @@ -375,16 +380,14 @@ describe("ProfitClient: Consider relay profit", () => { for (const originChainId of chainIds) { for (const destinationChainId of chainIds.filter((chainId) => chainId !== originChainId)) { - const { tokenGasCost } = gasCost[destinationChainId]; - const gasToken = profitClient.resolveGasToken(destinationChainId); - const gasTokenPriceUsd = profitClient.getPriceOfToken(gasToken.symbol); - const gasCostUsd = tokenGasCost.mul(gasTokenPriceUsd).div(bn10.pow(gasToken.decimals)); - for (const token of Object.values(tokens)) { - const inputToken = randomAddress(); - const outputToken = randomAddress(); - const outputAmount = toBN(1).mul(bn10.pow(token.decimals)); + const { tokenGasCost } = gasCost[destinationChainId][token.address]; + const gasToken = profitClient.resolveGasToken(destinationChainId); + const gasTokenPriceUsd = profitClient.getPriceOfToken(gasToken.symbol); + const gasCostUsd = tokenGasCost.mul(gasTokenPriceUsd).div(bn10.pow(gasToken.decimals)); + + const outputAmount = bn10.pow(token.decimals); const inputAmount = outputAmount .mul(fixedPoint) .div(fixedPoint.sub(lpFeePct.add(relayerFeePct).add(gasFeePct))); @@ -392,13 +395,13 @@ describe("ProfitClient: Consider relay profit", () => { ...v3DepositTemplate, originChainId, destinationChainId, - inputToken, + inputToken: randomAddress(), inputAmount, - outputToken, + outputToken: token.address, outputAmount, }; hubPoolClient.setTokenMapping(token.address, deposit.originChainId, deposit.inputToken); - hubPoolClient.mapTokenInfo(deposit.outputToken, token.symbol, token.decimals); + hubPoolClient.mapTokenInfo(token.address, token.symbol, token.decimals); const tokenPriceUsd = profitClient.getPriceOfToken(token.symbol); // Normalise any tokens with <18 decimals to 18 decimals. diff --git a/test/mocks/MockProfitClient.ts b/test/mocks/MockProfitClient.ts index acf195f9e..941b6dbbd 100644 --- a/test/mocks/MockProfitClient.ts +++ b/test/mocks/MockProfitClient.ts @@ -1,5 +1,6 @@ import { utils as sdkUtils } from "@across-protocol/sdk"; -import { ProfitClient } from "../../src/clients"; +import { Contract } from "ethers"; +import { HubPoolClient, ProfitClient } from "../../src/clients"; import { SpokePoolClientsByChain } from "../../src/interfaces"; import { bnOne, isDefined, TOKEN_SYMBOLS_MAP } from "../../src/utils"; import { BigNumber, toBN, toBNWei, winston } from "../utils"; @@ -36,6 +37,12 @@ export class MockProfitClient extends ProfitClient { gasPadding ); + const defaultGasCost = { + nativeGasCost: defaultFillCost, + tokenGasCost: defaultGasPrice.mul(defaultFillCost), + gasPrice: defaultGasPrice, + }; + // Initialise with known mainnet ERC20s Object.entries(TOKEN_SYMBOLS_MAP).forEach(([symbol, { decimals, addresses }]) => { const address = addresses[hubPoolClient.chainId]; @@ -45,6 +52,14 @@ export class MockProfitClient extends ProfitClient { if (this.hubPoolClient instanceof MockHubPoolClient) { this.hubPoolClient.addL1Token({ symbol, decimals, address }); } + + Object.values(spokePoolClients).map(({ chainId }) => { + this.setGasCost(chainId, address, defaultGasCost); // gas/fill + + const gasToken = this.resolveGasToken(chainId); + this.setTokenPrice(gasToken.address, defaultGasPrice); // usd wei + }); + } else { logger.debug({ at: "MockProfitClient", @@ -54,17 +69,6 @@ export class MockProfitClient extends ProfitClient { }); // Some tests run against mocked chains, so hack in the necessary parts - const defaultGasCost = { - nativeGasCost: defaultFillCost, - tokenGasCost: defaultGasPrice.mul(defaultFillCost), - gasPrice: defaultGasPrice, - }; - Object.values(spokePoolClients).map(({ chainId }) => { - this.setGasCost(chainId, defaultGasCost); // gas/fill - - const gasToken = this.resolveGasToken(chainId); - this.setTokenPrice(gasToken.address, defaultGasPrice); // usd wei - }); } async initToken(erc20: Contract): Promise { @@ -94,15 +98,16 @@ export class MockProfitClient extends ProfitClient { }); } - setGasCost(chainId: number, gas?: TransactionCostEstimate): void { + setGasCost(chainId: number, token: string, gas?: TransactionCostEstimate): void { + this.totalGasCosts[chainId] ??= {}; if (gas) { - this.totalGasCosts[chainId] = gas; + this.totalGasCosts[chainId][token] = gas; } else { - delete this.totalGasCosts[chainId]; + delete this.totalGasCosts[chainId][token]; } } - setGasCosts(gasCosts: { [chainId: number]: TransactionCostEstimate }): void { + setGasCosts(gasCosts: { [chainId: number]: { [token: string]: TransactionCostEstimate } }): void { this.totalGasCosts = gasCosts; } From 8650567b345e18d9b8a3f73755352d7baabb086f Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Thu, 16 Jan 2025 21:23:26 +0000 Subject: [PATCH 8/8] lint --- test/ProfitClient.ConsiderProfitability.ts | 5 +---- test/mocks/MockProfitClient.ts | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/test/ProfitClient.ConsiderProfitability.ts b/test/ProfitClient.ConsiderProfitability.ts index 5a00b2b0b..c91ae38d2 100644 --- a/test/ProfitClient.ConsiderProfitability.ts +++ b/test/ProfitClient.ConsiderProfitability.ts @@ -110,9 +110,7 @@ describe("ProfitClient: Consider relay profit", () => { const gasPrice = gasTokenPrice; const _tokenGasCost = nativeGasCost.mul(gasPrice); const tokenGasCost = Object.fromEntries( - Object.values(tokens).map(({ address }) => - [address, { nativeGasCost, tokenGasCost: _tokenGasCost, gasPrice }] - ) + Object.values(tokens).map(({ address }) => [address, { nativeGasCost, tokenGasCost: _tokenGasCost, gasPrice }]) ); return [chainId, tokenGasCost]; }) @@ -381,7 +379,6 @@ describe("ProfitClient: Consider relay profit", () => { for (const originChainId of chainIds) { for (const destinationChainId of chainIds.filter((chainId) => chainId !== originChainId)) { for (const token of Object.values(tokens)) { - const { tokenGasCost } = gasCost[destinationChainId][token.address]; const gasToken = profitClient.resolveGasToken(destinationChainId); const gasTokenPriceUsd = profitClient.getPriceOfToken(gasToken.symbol); diff --git a/test/mocks/MockProfitClient.ts b/test/mocks/MockProfitClient.ts index 941b6dbbd..a23795054 100644 --- a/test/mocks/MockProfitClient.ts +++ b/test/mocks/MockProfitClient.ts @@ -59,7 +59,6 @@ export class MockProfitClient extends ProfitClient { const gasToken = this.resolveGasToken(chainId); this.setTokenPrice(gasToken.address, defaultGasPrice); // usd wei }); - } else { logger.debug({ at: "MockProfitClient",