Skip to content

getBatchTxValue() doesn't include feeAmount for ETH_FEE_PROXY_CONTRACT, causing "Not enough funds" error #1672

@MantisClone

Description

@MantisClone

Problem

getBatchTxValue() doesn't include feeAmount when calculating the transaction value for ETH_FEE_PROXY_CONTRACT payments. This causes all native ETH batch payments with a fee to fail with "Not enough funds" during gas estimation.

The function calculates: requestAmount only
The contract requires: requestAmount + feeAmount

When a batch contains multiple ETH payments where any has a non-zero feeAmount, the transaction value is short by exactly that fee amount.

Buggy code (batch-conversion-proxy.ts lines 306-319):

const getBatchTxValue = (enrichedRequests: EnrichedRequest[]) => {
  return enrichedRequests.reduce((prev, curr) => {
    if (
      curr.paymentNetworkId !== ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ETH_PROXY &&
      curr.paymentNetworkId !== ExtensionTypes.PAYMENT_NETWORK_ID.ETH_FEE_PROXY_CONTRACT
    )
      return prev;
    return prev.add(
      curr.paymentNetworkId === ExtensionTypes.PAYMENT_NETWORK_ID.ANY_TO_ETH_PROXY
        ? curr.paymentSettings.maxToSpend
        : getAmountToPay(curr.request),  // ❌ Missing feeAmount
    );
  }, BigNumber.from(0));
};

Contract check (BatchNoConversionPayments.sol line 179):

require(address(this).balance >= rD.requestAmount + rD.feeAmount, 'Not enough funds');

Proposed Solution

Include feeAmount for ETH_FEE_PROXY_CONTRACT:

// ETH_FEE_PROXY_CONTRACT: include both amount AND fee
const { feeAmount } = getRequestPaymentValues(curr.request);
return prev.add(getAmountToPay(curr.request)).add(BigNumber.from(feeAmount || '0'));

Considerations

Verified with two test cases (batch of 2 payments: one with feeAmount, one without):

Test Payment 1 Payment 1 Fee Payment 2 TX Value Needed Shortfall
10 ETH 10 ETH 0.002 ETH 0.005 ETH 10.005 ETH 10.007 ETH 0.002 ETH
1 ETH 1 ETH 0.0002 ETH 0.0005 ETH 1.0005 ETH 1.0007 ETH 0.0002 ETH

Shortfall equals Payment 1's feeAmount in both cases.

Contract execution trace (1 ETH example):

  1. Payment 1: require(1.0005 >= 1.0002) ✅ → balance = 0.0003 ETH
  2. Payment 2: require(0.0003 >= 0.0005)FAIL

Impact:

  • Severity: High - payments completely blocked
  • Scope: All native ETH batch payments where any request has a non-zero feeAmount
  • Workaround: None

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

✅ Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions