Skip to main content

Common Issues

This guide helps you diagnose and fix common transaction problems on Paxeer Network.

Transaction Stuck in Mempool

Symptoms

  • Transaction shows as “pending” for extended period
  • Transaction doesn’t get mined
  • No confirmation after several minutes

Cause

The max fee per gas is too low compared to the current base fee.

Solution

Send a new transaction with the same nonce but higher fee:
import { ethers } from 'ethers';

async function replaceTransaction(originalTx, newMaxFee) {
  const signer = await provider.getSigner();
  
  // Get the nonce from the stuck transaction
  const nonce = await originalTx.nonce;
  
  // Send new transaction with same nonce, higher fee
  const newTx = await signer.sendTransaction({
    ...originalTx,
    nonce: nonce,
    maxFeePerGas: newMaxFee, // Higher than before
    maxPriorityFeePerGas: ethers.parseUnits('2', 'gwei'), // Higher priority
  });
  
  console.log('Replacement tx:', newTx.hash);
  return await newTx.wait();
}
When replacing or canceling a transaction, you must use the same nonce as the original transaction. The replacement must also have a higher gas price (typically 10%+ more).

Out of Gas Error

Symptoms

  • Transaction reverts with “out of gas” error
  • Transaction receipt shows status: 0

Cause

The gas limit was set too low for the transaction’s execution.

Solution

1

Re-estimate Gas

const gasEstimate = await provider.estimateGas(tx);
console.log('Required gas:', gasEstimate.toString());
2

Add Sufficient Buffer

const gasLimit = gasEstimate * 150n / 100n; // 50% buffer
3

Check for Contract Issues

If gas estimates are extremely high:
  • Contract may have infinite loops
  • Contract may be poorly optimized
  • Transaction may be calling expensive operations

Insufficient Funds

Symptoms

  • Error: “insufficient funds for gas * price + value”
  • Transaction rejected before sending

Cause

Account doesn’t have enough PAX to cover: (gasLimit × maxFeePerGas) + value

Solution

async function checkSufficientBalance(tx) {
  const signer = await provider.getSigner();
  const address = await signer.getAddress();
  
  // Get current balance
  const balance = await provider.getBalance(address);
  
  // Calculate required balance
  const gasEstimate = await provider.estimateGas(tx);
  const feeData = await provider.getFeeData();
  const maxCost = gasEstimate * feeData.maxFeePerGas;
  const totalRequired = maxCost + (tx.value || 0n);
  
  console.log('Current balance:', ethers.formatEther(balance), 'PAX');
  console.log('Required balance:', ethers.formatEther(totalRequired), 'PAX');
  
  if (balance < totalRequired) {
    throw new Error(`Insufficient funds. Need ${ethers.formatEther(totalRequired - balance)} more PAX`);
  }
  
  return true;
}

// Usage
await checkSufficientBalance(tx);

Transaction Reverted

Symptoms

  • Transaction mined but status: 0 (failed)
  • Receipt shows gas used but state didn’t change

Cause

Contract execution failed due to:
  • Failed require() or assert() statement
  • Out of gas during execution
  • External call failure
  • Invalid operation

Debugging Steps

1

Check Transaction Receipt

const receipt = await provider.getTransactionReceipt(txHash);

if (receipt.status === 0) {
  console.log('Transaction failed!');
  console.log('Gas used:', receipt.gasUsed.toString());
  console.log('Block:', receipt.blockNumber);
}
2

Simulate Transaction

Use eth_call to simulate before sending:
try {
  const result = await provider.call(tx);
  console.log('Simulation successful:', result);
} catch (error) {
  console.error('Simulation failed:', error.message);
  // Don't send the transaction
}
3

Check Logs and Events

const receipt = await provider.getTransactionReceipt(txHash);

receipt.logs.forEach(log => {
  console.log('Event emitted:', log);
});
4

Use Block Explorer

View detailed error messages on PaxeerScan:
https://scan.paxeer.app/tx/0x...

Nonce Issues

Nonce Too Low

Error: “nonce too low” Cause: Transaction uses a nonce that’s already been used. Solution:
// Get the correct nonce
const nonce = await provider.getTransactionCount(address, 'pending');

Nonce Too High

Error: “nonce too high” Cause: Transaction uses a nonce higher than expected (gap in nonces). Solution:
// Always use the next available nonce
const nonce = await provider.getTransactionCount(address, 'latest');

Nonce Management for Multiple Transactions

async function sendMultipleTransactions(transactions) {
  const signer = await provider.getSigner();
  let nonce = await provider.getTransactionCount(
    await signer.getAddress(),
    'pending'
  );

  const txPromises = transactions.map(async (tx, index) => {
    const txResponse = await signer.sendTransaction({
      ...tx,
      nonce: nonce + index,
    });
    return txResponse.wait();
  });

  return await Promise.all(txPromises);
}

Gas Price Too Low

Symptoms

  • Transaction not being picked up
  • Sitting in mempool indefinitely

Solution

Set higher fees:
const feeData = await provider.getFeeData();

// Set max fee to 2x current
const maxFeePerGas = feeData.maxFeePerGas * 2n;

// Set priority fee for faster inclusion
const maxPriorityFeePerGas = ethers.parseUnits('2', 'gwei');

RPC Error: Transaction Underpriced

Error Message

"transaction underpriced"

Cause

Priority fee is too low for current network conditions.

Solution

// Get recommended priority fee
const recommendedPriority = await provider.send('eth_maxPriorityFeePerGas', []);

// Use at least the recommended amount
const tx = await signer.sendTransaction({
  ...txData,
  maxPriorityFeePerGas: recommendedPriority,
});

Transaction Takes Too Long

Normal Confirmation Times

PriorityExpected TimeBlock Count
Low (0 gwei)10-30 seconds5-15 blocks
Standard4-10 seconds2-5 blocks
High (2x priority)2-4 seconds1-2 blocks

If Taking Longer

1

Check Transaction Status

const tx = await provider.getTransaction(txHash);

if (!tx) {
  console.log('Not yet mined');
} else if (!tx.blockNumber) {
  console.log('In mempool, waiting for block');
} else {
  console.log('Mined in block:', tx.blockNumber);
}
2

Check Network Status

Visit the network status page:
https://status.paxeer.app
3

Increase Priority Fee

If stuck, replace with higher priority fee (see above)

Contract Call Failures

Common Revert Reasons

Error: “ERC20: transfer amount exceeds allowance”Solution:
// Approve token spending first
const token = new ethers.Contract(tokenAddress, ERC20_ABI, signer);
const approveTx = await token.approve(spenderAddress, amount);
await approveTx.wait();

// Then perform the transfer
const transferTx = await token.transfer(toAddress, amount);
Error: “ERC20: transfer amount exceeds balance”Solution:
// Check balance first
const balance = await token.balanceOf(address);
if (balance < amount) {
  throw new Error('Insufficient token balance');
}
Error: Various errors about invalid inputsSolution:
  • Validate all inputs before sending
  • Check address formats (valid checksummed addresses)
  • Ensure amounts are in correct units (wei vs ether)
  • Verify array lengths and types

Debugging Tools

Using Tenderly

Simulate and debug transactions:
// Use Tenderly's simulation API
const simulation = await fetch('https://api.tenderly.co/api/v1/account/me/project/my-project/simulate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Access-Key': 'YOUR_KEY',
  },
  body: JSON.stringify({
    network_id: '229',
    from: fromAddress,
    to: toAddress,
    input: data,
    value: value.toString(),
  }),
});

const result = await simulation.json();
console.log('Simulation result:', result);

Using PaxeerScan

Check transaction details and error messages:
  1. Go to https://scan.paxeer.app
  2. Search for your transaction hash
  3. View execution trace and error messages
  4. Check event logs for clues

Prevention Checklist

Before sending transactions:
  • Estimate gas with eth_estimateGas
  • Add 10-20% buffer to gas estimate
  • Check current base fee is reasonable
  • Set appropriate priority fee
  • Verify account has sufficient balance
  • Simulate transaction with eth_call first
  • Validate all input parameters
  • Handle errors gracefully in code

Getting Help

Next Steps