From cef744a70eb6e0d43d918727e5680bf6f36fe72a Mon Sep 17 00:00:00 2001 From: Shubham Damkondwar Date: Fri, 13 Mar 2026 23:58:50 +0530 Subject: [PATCH] feat: add support for L1 fee buffers in gas calculations for multiple coin families CECHO-354 TICKET: CECHO-354 --- .gitignore | 1 + .../src/abstractEthLikeNewCoins.ts | 18 +++++++++++++----- modules/abstract-eth/src/ethLikeToken.ts | 7 +++---- modules/statics/src/tokenConfig.ts | 2 +- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 028dd2ee8e..0ca92b500e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/ +.worktrees/ .idea/ *.iml lerna-debug.log diff --git a/modules/abstract-eth/src/abstractEthLikeNewCoins.ts b/modules/abstract-eth/src/abstractEthLikeNewCoins.ts index a29761ffde..09df1c0a99 100644 --- a/modules/abstract-eth/src/abstractEthLikeNewCoins.ts +++ b/modules/abstract-eth/src/abstractEthLikeNewCoins.ts @@ -492,6 +492,11 @@ export const optionalDeps = { export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin { static hopTransactionSalt = 'bitgoHopAddressRequestSalt'; protected readonly sendMethodName: 'sendMultiSig' | 'sendMultiSigToken'; + protected readonly coinFamiliesWithL1Fees: ReadonlyArray<'opeth' | 'dogeos' | 'morpheth'> = [ + 'opeth', + 'dogeos', + 'morpheth', + ]; readonly staticsCoin?: Readonly; @@ -1516,10 +1521,9 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin { const backupKeyBalance = await this.queryAddressBalance(backupKeyAddress, params.apiKey); let totalGasNeeded = gasPrice.mul(gasLimit); - // On optimism chain, L1 fees is to be paid as well apart from L2 fees - // So we are adding the amount that can be used up as l1 fees - if (this.staticsCoin?.family === 'opeth') { - totalGasNeeded = totalGasNeeded.add(new optionalDeps.ethUtil.BN(ethGasConfigs.opethGasL1Fees)); + // On L2 chains with L1 data fees, add buffer for L1 fees + if (this.staticsCoin?.family !== undefined && this.coinFamiliesWithL1Fees.includes(this.staticsCoin.family)) { + totalGasNeeded = totalGasNeeded.add(new optionalDeps.ethUtil.BN(ethGasConfigs.l1GasFeeBuffer)); } const weiToGwei = 10 ** 9; @@ -2515,7 +2519,11 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin { async validateBalanceAndGetTxAmount(baseAddress: string, gasPrice: BN, gasLimit: BN, apiKey?: string) { const baseAddressBalance = await this.queryAddressBalance(baseAddress, apiKey); - const totalGasNeeded = gasPrice.mul(gasLimit); + let totalGasNeeded = gasPrice.mul(gasLimit); + // On L2 chains with L1 data fees, add buffer for L1 fees + if (this.staticsCoin?.family !== undefined && this.coinFamiliesWithL1Fees.includes(this.staticsCoin.family)) { + totalGasNeeded = totalGasNeeded.add(new optionalDeps.ethUtil.BN(ethGasConfigs.l1GasFeeBuffer)); + } const weiToGwei = new BN(10 ** 9); if (baseAddressBalance.lt(totalGasNeeded)) { throw new Error( diff --git a/modules/abstract-eth/src/ethLikeToken.ts b/modules/abstract-eth/src/ethLikeToken.ts index 830006e1e4..9a4fc7a66c 100644 --- a/modules/abstract-eth/src/ethLikeToken.ts +++ b/modules/abstract-eth/src/ethLikeToken.ts @@ -276,10 +276,9 @@ export class EthLikeToken extends AbstractEthLikeNewCoins { let totalGasNeeded = gasPrice.mul(gasLimit); - // On optimism chain, L1 fees is to be paid as well apart from L2 fees - // So we are adding the amount that can be used up as l1 fees - if (this.staticsCoin?.family === 'opeth') { - totalGasNeeded = totalGasNeeded.add(new optionalDeps.ethUtil.BN(ethGasConfigs.opethGasL1Fees)); + // On L2 chains with L1 data fees (opeth, morpheth, dogeos), add buffer for L1 fees + if (['opeth', 'morpheth', 'dogeos'].includes(this.staticsCoin?.family ?? '')) { + totalGasNeeded = totalGasNeeded.add(new optionalDeps.ethUtil.BN(ethGasConfigs.l1GasFeeBuffer)); } const weiToGwei = 10 ** 9; diff --git a/modules/statics/src/tokenConfig.ts b/modules/statics/src/tokenConfig.ts index dc678d06bc..21d8755c31 100644 --- a/modules/statics/src/tokenConfig.ts +++ b/modules/statics/src/tokenConfig.ts @@ -344,7 +344,7 @@ export const ethGasConfigs = { minimumGasLimit: 30000, // minimum gas limit a user can set for a send maximumGasLimit: 20000000, // Customers cannot set gas limits beyond this amount newEthLikeCoinsMinGasLimit: 400000, // minimum gas limit a user can set for a send for eth like coins like arbitrum, optimism, etc - opethGasL1Fees: 1000000000000000, // Buffer for opeth L1 gas fees + l1GasFeeBuffer: 1000000000000000, // Buffer for L1 data fees }; function getStellarTokenConfig(coin: StellarCoin): StellarTokenConfig {