From 6bc2b57cd067bd88aed894e21adfcac7fa97b21f Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Thu, 18 Jul 2024 06:52:37 +0200 Subject: [PATCH 1/3] fix(ProfitClient): Fix fill amount USD computation The ProfitClient currently assumes that the value of a fill can be determined from the input token price * the output amount of the output token. This is roughly correct for most Across deposits, but falls over when the deposit includes an in-protocol swap to an output token with a different number of decimals. This was exposed on an Optimism deposit for inputToken USDC, outputToken AERO on Base. Deposit hash: 0x4a3febcfb764467d9eae261b3a3938137db383289fe328050a2871eb407e1147 --- src/clients/ProfitClient.ts | 29 ++++++++++++++++++++--------- src/relayer/Relayer.ts | 11 +++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/clients/ProfitClient.ts b/src/clients/ProfitClient.ts index a7a92f272f..9ec08d00a9 100644 --- a/src/clients/ProfitClient.ts +++ b/src/clients/ProfitClient.ts @@ -17,6 +17,7 @@ import { BigNumber, formatFeePct, getCurrentTime, + getNetworkName, isDefined, min, winston, @@ -390,16 +391,26 @@ export class ProfitClient { } // Return USD amount of fill amount for deposited token, should always return in wei as the units. - getFillAmountInUsd(deposit: Deposit, fillAmount = deposit.outputAmount): BigNumber { - const l1TokenInfo = this.hubPoolClient.getTokenInfoForDeposit(deposit); - if (!l1TokenInfo) { - const { inputToken } = deposit; - throw new Error( - `ProfitClient#getFillAmountInUsd missing l1TokenInfo for deposit with origin token: ${inputToken}` - ); + getFillAmountInUsd( + deposit: Pick, + ): BigNumber | undefined { + const { destinationChainId, outputToken, outputAmount } = deposit; + let l1Token: L1Token; + + try { + l1Token = this.hubPoolClient.getL1TokenInfoForL2Token(outputToken, destinationChainId); + } catch { + this.logger.info({ + at: "ProfitClient#getFillAmountInUsd", + message: `Cannot resolve output token ${outputToken} on ${getNetworkName(destinationChainId)}.`, + }); + return undefined; } - const tokenPriceInUsd = this.getPriceOfToken(l1TokenInfo.symbol); - return fillAmount.mul(tokenPriceInUsd).div(bn10.pow(l1TokenInfo.decimals)); + + const tokenPriceInUsd = this.getPriceOfToken(l1Token.symbol); + + // The USD amount of a fill must be normalised to 18 decimals, so factor out the token's own decimal promotion. + return outputAmount.mul(tokenPriceInUsd).div(bn10.pow(l1Token.decimals)); } async getFillProfitability( diff --git a/src/relayer/Relayer.ts b/src/relayer/Relayer.ts index 3abd00f517..48a3d3a903 100644 --- a/src/relayer/Relayer.ts +++ b/src/relayer/Relayer.ts @@ -102,6 +102,17 @@ export class Relayer { // Ensure that the individual deposit meets the minimum deposit confirmation requirements for its value. const fillAmountUsd = profitClient.getFillAmountInUsd(deposit); + if (!isDefined(fillAmountUsd)) { + this.logger.debug({ + at: "Relayer::evaluateFill", + message: `Skipping ${srcChain} deposit due to unresolved output token fill amount.`, + destinationChainId, + outputToken: deposit.outputToken, + transactionHash: deposit.transactionHash, + }); + return false; + } + const { minConfirmations } = minDepositConfirmations[originChainId].find(({ usdThreshold }) => usdThreshold.gte(fillAmountUsd) ); From 6c38dd85a07c4c0b4ab62380da6a4b902f10444b Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Thu, 18 Jul 2024 11:01:30 +0200 Subject: [PATCH 2/3] lint --- src/clients/ProfitClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clients/ProfitClient.ts b/src/clients/ProfitClient.ts index 9ec08d00a9..a07fb8bf70 100644 --- a/src/clients/ProfitClient.ts +++ b/src/clients/ProfitClient.ts @@ -392,7 +392,7 @@ export class ProfitClient { // Return USD amount of fill amount for deposited token, should always return in wei as the units. getFillAmountInUsd( - deposit: Pick, + deposit: Pick ): BigNumber | undefined { const { destinationChainId, outputToken, outputAmount } = deposit; let l1Token: L1Token; From f4ad1c0b023b82bb9f4c04b5c27cbac690247b79 Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:35:27 +0200 Subject: [PATCH 3/3] Tweak log message --- 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 48a3d3a903..00eac7fab8 100644 --- a/src/relayer/Relayer.ts +++ b/src/relayer/Relayer.ts @@ -105,7 +105,7 @@ export class Relayer { if (!isDefined(fillAmountUsd)) { this.logger.debug({ at: "Relayer::evaluateFill", - message: `Skipping ${srcChain} deposit due to unresolved output token fill amount.`, + message: `Skipping ${srcChain} deposit due to uncertain fill amount.`, destinationChainId, outputToken: deposit.outputToken, transactionHash: deposit.transactionHash,