Skip to content

CRITICAL: TRON TRC20 Fee Estimation Underestimates by 24-48x, Causing Failed Transactions #11270

@coderabbitai

Description

@coderabbitai

Problem

The TRON chain adapter's getFeeData() method returns fixed fees of 0.268 TRX for ALL transactions, including TRC20 token transfers. In reality, TRC20 transfers cost 6-15 TRX (depending on energy, bandwidth, and memo requirements), resulting in a 24-48x underestimation.

Impact

  • UI displays misleading fees (~$0.05 instead of ~$1.50-$3.00)
  • Transactions broadcast and fail on-chain with OUT_OF_ENERGY errors
  • Users lose 3-4 TRX in partial execution fees
  • Thorchain swaps fail due to insufficient balance for memo fees

Real-World Cost Comparison

Transaction Type getFeeData Returns Actual Cost Error
TRX transfer 0.268 TRX 0.268 TRX ✅ Correct
TRC20 transfer (no memo) 0.268 TRX 6.4-13 TRX ❌ 24-48x
TRC20 transfer (with memo) 0.268 TRX 8-15 TRX ❌ 30-56x

Root Cause

The getFeeData() implementation ignores the input parameter and always calls getPriorityFees(), which returns a hardcoded 268 SUN value for all transaction types.

Critical TODO comments:

// TODO: CRITICAL - Fix fee estimation for TRC20 tokens
// Current implementation returns FIXED 0.268 TRX for all transactions
// Reality: TRC20 transfers cost 6-15 TRX (energy + bandwidth + memo)
// This causes UI to show wrong fees and transactions to fail on-chain
// See TRON_FEE_ESTIMATION_ISSUES.md for detailed analysis and fix
async getFeeData(

Implementation TODOs:

// TODO: Use _input.chainSpecific.contractAddress to detect TRC20
// TODO: Call estimateTRC20TransferFee() for TRC20 tokens
// TODO: Build actual transaction with memo to get accurate bandwidth
// TODO: Add 1 TRX memo fee if _input.chainSpecific.memo present
const { fast, average, slow, estimatedBandwidth } =
await this.providers.http.getPriorityFees()

Solution

The unchained-client already has the necessary methods:

  • estimateTRC20TransferFee() - Estimates energy for TRC20
  • estimateFees() - Estimates bandwidth for TRX
  • getChainPrices() - Gets live energy/bandwidth prices

These methods need to be integrated into getFeeData() to:

  1. Detect TRC20 vs TRX transfers via contractAddress
  2. Estimate energy costs for TRC20 tokens
  3. Build actual transaction to calculate accurate bandwidth
  4. Add 1 TRX memo fee when memo is present

Detailed Analysis

Comprehensive documentation with cost breakdown, failed transaction examples, and implementation guidance:
https://github.com/shapeshift/web/blob/3fc225562368f3632d482e3e90cc30e8760ac4f2/packages/chain-adapters/src/tron/TRON_FEE_ESTIMATION_ISSUES.md

Priority

HIGH - Users are actively losing TRX on failed transactions due to inaccurate fee estimates.


Note: This issue exists in the develop branch and was not introduced by PR #11266.

Metadata

Metadata

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