Tron: Spend a prebuilt TriggerSmartContract call - #1088
Open
j0ntz wants to merge 2 commits into
Open
Conversation
Lets the CLI hand an engine a prebuilt payload, which is how a TRON contract call reaches makeSpend outside of a swap plugin.
Contributor
Author
2 tasks
j0ntz
force-pushed
the
jon/rango-tron-contract-call
branch
from
August 14, 2026 17:24
6536d5e to
c5df3b5
Compare
j0ntz
marked this pull request as ready for review
August 14, 2026 17:24
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
j0ntz
force-pushed
the
jon/rango-tron-contract-call
branch
from
August 14, 2026 17:34
c5df3b5 to
3e34fb7
Compare
j0ntz
force-pushed
the
jon/rango-tron-contract-call
branch
from
August 14, 2026 17:46
3e34fb7 to
7650f82
Compare
j0ntz
force-pushed
the
jon/rango-tron-contract-call
branch
from
August 14, 2026 18:01
7650f82 to
599badd
Compare
j0ntz
force-pushed
the
jon/rango-tron-contract-call
branch
from
August 14, 2026 18:17
599badd to
43377eb
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 43377eb. Configure here.
makeSpend only read otherParams for the staking actions, so a DEX swap that arrives as a finished contract call fell through to the transfer encoders and was signed as a transfer instead. Detect the payload and hand it to the transaction builder untouched, keeping signTx unchanged. Energy is estimated by dry-running the call's own data, since the canonical TRC20 transfer estimate says nothing about an arbitrary contract call.
j0ntz
force-pushed
the
jon/rango-tron-contract-call
branch
from
August 14, 2026 18:25
43377eb to
f265426
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Description
Asana: https://app.asana.com/0/1215088146871429/1216839790397157
TronEngine.makeSpendonly readotherParamsfor the four staking actions. Everythingelse fell through to
makeTransferJson/encodeTRC20Transfer, so a DEX swap thatarrives as a finished
TriggerSmartContractcall was silently rewritten into a plaintransfer and never executed the swap.
What changed
asTronContractCallOtherParams(tronTypes.ts) recognizes{ contractJson, feeLimit?, note? }where
contractJsonis aTriggerSmartContract. Every level uses.withRest, so the payloadreaches the transaction builder byte-identical to what the provider sent —
parameter.type_urlis load-bearing here, it is serialized into the signed raw data.
makeContractCallTransactionbuilds the transaction through the existingtxBuilder({ contractJson, feeLimit, note })and returnsotherParamsunchanged, sosignTx(
getOtherParams→txBuilder→ sign) needed no change. It refuses a payload whoseowner_addressis not this wallet.fee as
parentNetworkFee; a mainnet call reports the contract's owncall_valueplus the fee,since that is the TRX the chain actually moves.
calcTxFeegainedcontractCallOpts. The existing energy estimate dry-runs a canonicaltransfer(address,uint256), which says nothing about a swap router, so a contract call isestimated from its own
dataandcall_value. A failed dry run falls back to the existingdefault rather than blocking the spend, because a call that depends on an approval which has
not been broadcast yet cannot be simulated. The existing token-transfer estimate is untouched.
make-spendcommand takes--otherParams <json>, so the new path can be drivenoutside a swap plugin.
Testing
Unit tests (
test/tron/tronContractCall.test.ts) use the real Rango payload from the task:the cleaner accepts it, rejects staking and transfer payloads, and the built raw data matches
the provider's
raw_data_hexandtxIDbyte-for-byte.Driven end to end on the iOS sim against edge-exchange-plugins#484:
a TRX → USDT swap through Rango reached the success scene, and on-chain
42fd4970…9650
is a
TriggerSmartContractwithcontractRet: SUCCESS,call_value39.148 TRX, selectorcef95229against the Sun Swap router, and the same transaction delivered 13.004043 USDT.Screenshots in a comment below.
Note
Medium Risk
Changes the Tron spend path for
otherParamscontract calls and fee math; guards reduce silent mis-sends, but wrong validation or accounting could still affect real swap spends and TRX balances.Overview
Tron DEX swaps no longer get rewritten into plain TRX/TRC20 transfers when a swap plugin passes a finished
TriggerSmartContractinotherParams.makeSpendnow routes valid payloads throughmakeContractCallTransaction, which signs the provider’scontractJsonbyte-identical via the existingtxBuilderpath.Fee estimation adds
contractCallOptstocalcTxFee: energy is dry-run with/wallet/triggerconstantcontractusing the call’s owndataandcall_value, with revert detection onretandresult.message, and a default fallback when simulation fails (e.g. pending approval). Malformed contract-call attempts are blocked byasTronContractCallIntentso they error instead of falling through to a transfer to the contract address.The CLI
make-spendcommand accepts--otherParamsJSON for testing this path outside swap plugins.Reviewed by Cursor Bugbot for commit f265426. Bugbot is set up for automated code reviews on this repo. Configure here.