The origin tracer is paused. The library is open and still growing.What’s paused, and when it returns

← All articles

Contract-Execution Economics

Key takeaways

  • fee_limit is the caller's ceiling: the most TRX they will let a contract call burn on Energy, set before the transaction is broadcast.
  • A call that runs out of Energy reverts — its state changes are undone — but the Energy it already consumed is not refunded. A failed contract call still costs, and it still lands on-chain.
  • A contract's deployer can pay part or all of each call's Energy through consume_user_resource_percent and origin_energy_limit — so a wallet can transact heavily through a sponsored contract while burning almost nothing itself.
  • The ceiling, the outcome, and the payer are all readable, and each says something: intent, a costed failure, and whether a contract subsidizes its users.

A plain TRX transfer either happens or it doesn’t, and its cost is trivial and fixed. A contract call is different on both counts: it can consume a large and unpredictable amount of Energy, and it can fail after spending most of it. That combination is why contract execution has its own economics. The caller sets a ceiling. Failure has a defined price. And a contract’s deployer can pick up the bill for its users.

None of this is exotic, and all of it is visible after the fact. This article walks through those three parts and what each tells a reader. The Energy resource itself, and the staked-then-burned order every charge follows, is covered in what a transaction actually costs; here the subject is the economics specific to executing a contract.

fee_limit: the caller’s ceiling

Every contract call carries a fee_limit, which the TRON documentation describes as capping “the Energy budget that the caller can cover for this transaction, expressed in sun.” It is a safety cap. A call draws Energy from the caller’s staked pool first and then, if that runs short, burns TRX to buy the rest — and fee_limit is the hard stop on that burn. Once the Energy a call would need exceeds what the caller’s stake plus fee_limit can cover, the call stops.

The value is bounded. A valid fee_limit runs from 0 up to a governance-set maximum: 15,000 TRX (15,000,000,000 sun) as of 2026. That maximum is a chain parameter, and an SR proposal could change it. The cap exists because a caller cannot always predict how much Energy a contract will burn, and an unbounded call could drain an account on a single mistake.

For a reader, fee_limit is the one number in a contract call that records the caller’s intent: how far the signer was willing to go, decided before broadcast. It is part of the transaction’s signed envelope, fixed at signing and visible whether or not the call succeeded.

Running out of Energy: revert, but pay

The rule that surprises people is what a failed call costs.

When a contract call exhausts the Energy available to it, execution stops and the transaction reverts — every state change it made is rolled back, as if the call had never run. But the Energy is gone. In an ordinary out-of-Energy revert, “only the Energy for the instructions executed up to that point is deducted,” and that consumed Energy “is not refunded.” The caller paid for the computation the machine actually performed, and got none of the result.

Contract call BURNS ENERGY AS IT RUNS Out of Energy EXECUTION STOPS [ RUNS DRY ] [ EFFECTS UNDONE ] [ CHARGE STANDS ] State rolled back AS IF THE CALL NEVER RAN Energy not refunded CHARGED FOR WORK DONE A PAID, RECORDED FAILURE KEY THE STATE UNWINDS — THE COST DOES NOT
The state unwinds; the cost does not. A revert is a paid failure, not a free one.

The harsher case is an unexpected interruption, a call that crashes or times out instead of cleanly running dry. There, “the system will deduct all available Energy for the transaction as a penalty”: everything the call could have drawn, whether it was actually used or not. Either way the direction is the same. Computation is charged for as it happens, and a revert undoes the effects without undoing the charge.

This changes how a failed transaction reads. A reverted contract call sits on-chain as a real, costed transaction, carrying the Energy it burned and the fee_limit the caller set. It records that an attempt was made, how much the caller was prepared to spend, and that it did not complete.

By default the caller pays the whole Energy bill. A contract’s deployer can change that.

Two parameters, set on the contract, split the cost. consume_user_resource_percent is an integer from 0 to 100, the share of each call’s Energy the caller pays. Set it to 60 and the caller covers 60% while the deployer covers the other 40%; set it to 0 and the caller pays nothing and the deployer covers everything. origin_energy_limit caps the deployer’s exposure: the most Energy the deployer will cover on a single call. The deployer’s share comes out of the deployer’s own available Energy, and is the smaller of their configured share, that limit, and what they actually have staked.

ENERGY FOR ONE CALL — SPLIT AT THE PERCENT Caller pays consume_user_resource_percent % AN INTEGER FROM 0 TO 100, SET ON THE CONTRACT Deployer sponsors THE REMAINING % KEY CAPPED BY origin_energy_limit AND THE DEPLOYER'S AVAILABLE ENERGY SET PERCENT TO 0 → THE CALLER PAYS NOTHING
The percentage draws the line; the deployer's cap and stake decide how much of their side they can actually cover.

The effect is that a well-funded contract can let its users transact almost for free. A caller interacting with a fully-sponsored contract burns little or no Energy of their own, no matter how much contract activity they generate; the cost lands on the deployer’s staked Energy instead. When the deployer’s Energy or their origin_energy_limit runs out, the caller’s share climbs back toward the full amount, so the sponsorship holds only while there is Energy behind it.

What the economics reveal

The ceiling is intent. A call’s fee_limit records how much the caller was willing to spend before they knew the outcome. It is present on successes and failures alike, and it runs higher on calls the signer expected to be expensive.

A revert, for its part, is a paid and recorded event. A failed contract call sits on-chain with real Energy burned, marking an attempt that was made and did not land — which can be worth as much to a reader as a success, and sometimes more.

The payer tells you who is subsidizing whom. A wallet that runs heavy contract activity with almost no Energy footprint still generates a bill; the contracts it uses are paying it. A contract that sponsors execution is spending to attract that activity, and the arrangement is legible in who burned the Energy.

There is more in these numbers than a fee amount. A contract call records what the caller intended, whether the attempt succeeded, and whose resources paid for it. A plain reading of “a contract was called” leaves all three out.

Sources

  • FeeLimit & Energy cost — TRON Developer Hubfee_limit as the cap on “the Energy budget that the caller can cover for this transaction, expressed in sun,” set in sun rather than TRX, with the ceiling a chain parameter: “The maximum allowed value is currently 15,000 TRX on Mainnet (15 × 10⁹ sun) — but this is a chain parameter (getMaxFeeLimit, parameter #47).” Also the contract-sponsorship model: consume_user_resource_percent (0–100, the caller’s share), origin_energy_limit (the deployer’s per-call cap), the deployer/caller split formula, and wallet/updatesetting. This page absorbed the former /docs/feelimit and /docs/energy-consumption-mechanism.
  • Resource Model — java-tron documentation — out-of-Energy behavior (revert with the consumed Energy “not refunded”; an unexpected interruption deducts all available Energy as a penalty) and the staked-Energy-then-burn consumption order capped by fee_limit.