Skip to content

fix: correct Sun.io swap fee estimation and handle TRON failure states#12045

Draft
premiumjibles wants to merge 7 commits intodevelopfrom
fix/sunio-fee-estimation-saq
Draft

fix: correct Sun.io swap fee estimation and handle TRON failure states#12045
premiumjibles wants to merge 7 commits intodevelopfrom
fix/sunio-fee-estimation-saq

Conversation

@premiumjibles
Copy link
Collaborator

@premiumjibles premiumjibles commented Feb 27, 2026

Description

Improve Sun.io swap fee estimation on TRON, which was significantly underestimating fees (showed ~6.7 TRX, actual was ~14 TRX for USDT swaps). The root cause is TRON's dynamic energy penalty — high-traffic contracts like USDT have energy_factor: 34000 (340% penalty), making operations cost 4.4x base energy. Our previous static estimate ignored this entirely.

Approach: Two-tier estimation

  1. Simulation via triggerConstantContract — simulates the actual swapExactInput call on the Sun.io router. Returns exact energy_used + energy_penalty including all dynamic penalties. Works for TRX sells and TRC20 sells where the user already has token approval.

  2. Energy penalty fallback — when simulation fails (e.g. TRC20 sell without approval, or rate quotes without a sender address), fetches the sell token's energy_factor from getcontractinfo (cached 6hrs per contract) and inflates the base energy estimate: totalEnergy = BASE_ENERGY_PER_HOP * hopCount * (1 + TOKEN_ENERGY_SHARE * energy_factor / 10000) where TOKEN_ENERGY_SHARE = 0.5 models that roughly half the transaction's energy runs on the token contract (subject to penalty).

  3. 20% safety margin applied to both paths to ensure estimates cover edge cases.

Final fee: ceil(totalEnergy * 1.2) * 0.6 * 100 + 1,100,000 sun (user energy share + bandwidth)

Also includes (from earlier commits)

  • Comprehensive TRON transaction failure state handling — treats any non-SUCCESS contractRet as failed (catches OUT_OF_ENERGY, REVERT, OUT_OF_TIME, TRANSFER_FAILED, etc.)

Expected accuracy

Scenario Estimate Actual Error
USDT sell (max penalty, fallback) ~17.8 TRX ~14 TRX +27% (safe)
No penalty token (fallback) ~5.8 TRX ~6-7 TRX ~0%
TRX sell (simulation) exact + 20% actual +20% (safe)

Issue (if applicable)

closes #12039

Risk

Medium — Changes fee estimation for Sun.io TRX swaps on TRON. No other protocols/chains affected.

Sun.io swapper on TRON chain. ButterSwap same-chain TRON swaps (status checking only).

Testing

Engineering

  1. yarn lint --fix — passes
  2. yarn type-check — passes
  3. USDT to TRX swap (1-hop, TRC20 sell): should show ~15-18 TRX fee (energy_factor fallback path)
  4. TRX to USDT swap (TRX sell): should show accurate estimate via simulation path
  5. With wallet disconnected (rate): should use energy_factor fallback, not crash

Operations

  • Connect a TRON wallet (e.g. TronLink)
  • Navigate to Trade, select TRX to USDT via Sun.io
  • Verify the network fee shown is reasonable (~15-18 TRX range, not ~6 TRX)
  • Select USDT to TRX and verify fee estimate is also reasonable
  • Execute a small swap and confirm it completes (or fails cleanly with accurate error)

Screenshots (if applicable)

N/A — logic-only changes, no UI modifications.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/sunio-fee-estimation-saq

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

premiumjibles and others added 3 commits March 1, 2026 20:17
…tates

Replace hardcoded 2000 energy estimate with dynamic calculation using
actual Sun.io contract parameters (consume_user_resource_percent,
origin_energy_limit, energy_factor). Use empirical base energy values
with 1.3x safety margin: 195k for TRX→token, 390k for TRC20→token.

Fix checkTradeStatus in both Sun.io and ButterSwap to treat any
non-SUCCESS contractRet as failed, catching OUT_OF_ENERGY, REVERT,
OUT_OF_TIME, TRANSFER_FAILED etc. instead of only checking for REVERT.

[shapeshift-saq]

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Cache chain prices (10min TTL) and contract params (1hr TTL) to reduce
  TronGrid RPC calls and avoid 429 rate limiting
- Show fee estimates even without wallet connected (rates) instead of
  "(unknown)" — only gate the recipient activation check on receiveAddress
- Adjust base energy constants based on observed transaction data:
  TRX→token 85k, TRC20→token 170k with 1.1x safety margin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simulate the actual swap call with triggerconstantcontract to get
per-route energy estimates instead of relying on static medians.
This gives accurate fees for both simple and complex routes.

- Extract convertAddressesToEvmFormat to shared utility
- Use real sender address for simulation (quotes only)
- Fall back to static estimates for rates (no wallet) or on failure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@premiumjibles premiumjibles force-pushed the fix/sunio-fee-estimation-saq branch from f952c7e to 25a588e Compare March 1, 2026 13:18
premiumjibles and others added 4 commits March 1, 2026 21:23
Strip out dynamic RPC infrastructure (triggerConstantContract simulation,
getChainPrices, getContractParams caching) that added complexity without
improving accuracy — simulation REVERTs for TRC20 sells (no allowance),
and chain params are effectively constant.

Replace with simple hop-count scaling using hardcoded constants. This still
underestimates for tokens with energy penalties (USDT has 340% penalty)
which will be addressed in a follow-up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Static hop-count estimation was 2x off for USDT swaps due to TRON's
dynamic energy penalty (energy_factor: 34000 = 340% penalty on USDT).

Two-tier approach:
1. Try triggerConstantContract simulation (exact energy including penalties)
2. If simulation fails (e.g. TRC20 sell without approval), fetch the sell
   token's energy_factor and inflate base estimate accordingly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Estimates were slightly under actual fees. Bump SAFETY_MARGIN to 1.2
to provide a more conservative buffer on both simulation and fallback
energy calculations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@NeOMakinG
Copy link
Collaborator

QA Report ✅

Tested: TRX ↔ USDT swaps on Tron via Sun.io (rate quote mode, no wallet connected)

Test 1: TRX → USDT (Sun.io)

  • Input: 100 TRX (~$28.88)
  • Output: 28.91 USDT
  • Network Fee: $5.27 (~18 TRX)
  • Price Impact: 0.09%

Fee estimation matches expected range (PR states 15-18 TRX, actual shows ~18 TRX vs old buggy ~6.7 TRX)

Test 2: USDT → TRX

  • Aggregator routes through NEAR Intents (better rate)
  • Fee: $5.71

Verification

  • Rate quote works without wallet connected (energy_factor fallback path)
  • No crashes or errors
  • Fee estimation realistic (not the old underestimate)

Approving - fee estimation fix working as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TRX trade fails when not enough gas but broadcasts anyway

2 participants