Transaction fees are the XRD required to be paid to run a transaction on the Radix Public Network, e.g. transfer tokens from one account to another. Fees reflect the burden each transaction puts on the network, most notably in the areas of how work-intensive it is to compute the result, and how much permanent storage it requires. On the Radix Public Network, fees are also where royalties are accounted for. Royalties are set by developers who deploy code or run applications on the network, and allow them to collect a “use fee” every time their work gets used in a transaction.
The total fee is the sum of the costs the network assesses for running the transaction, plus the sum of any royalties specified in the various components the transaction makes use of, either directly or indirectly. In times when demand exceeds network capacity, users may specify an optional “tip” percentage which amplifies the network portion of the fee (royalty payments are unaffected); this extra amount is directly awarded to the validator leading the consensus round.
Unlike other networks, it is quite straightforward on Radix for a transaction’s fees to be paid for by someone other than the signer(s), or to have the fee payments split up among multiple parties. More details on how that works a bit further down the page.
Calculating Fees
The goal is that network fees should remain relatively stable in terms of USD cost. This is achieved by having a fee table, which describes the CostUnits associated with a given operation, and a fiat value multiplier, which is used to compute a cost in XRD for a given amount of CostUnits.
For each section of code to be run, the system determines a price for that section, taking the following steps:
- Apply the fee table to each operation in the section, and sum up the total CostUnits required to run it.
- Multiply by the fiat value multiplier to compute the base network XRD cost.
- Multiply by the user’s tip multiplier, if one was specified.
- Add any royalties incurred.
This gives the total XRD cost to run a section of code. If the transaction’s fee reserve (to be described next!) has sufficient balance to pay this, this cost is deducted from the reserve and the transaction continues execution. If not, the transaction fails at this point, and any already-spent fees are forfeited.
Changes in the market price of XRD can be addressed by updating the fiat value multiplier. Changes for the price of a particular operation are accomplished with a fee table update. In either case, these are then adopted via a coordinated protocol update as per the Radix Foundation's policy for network fee and network emissions updates
Paying Fees
Fees can be paid from any vault containing XRD. Remember that, on Radix, tokens (including XRD) aren’t directly “held” by a keypair - they’re always stored in vaults owned by components. In order to identify where a fee is being paid from, the transaction needs to call some component which will lock some XRD with which to pay the fee, establishing the fee reserve to begin paying from. Most commonly, this will be a Smart Account under the signer’s control, but it’s easy to imagine other models.
For example, someone might run a subscription service which allows users to set up a credit card with which to pay their fees. The service issues a non-fungible badge to each of its users, and subscribers pass their unique badge to the service’s on-ledger component each time they wish it to pay their fee. At the end of the month, the service charges the user’s credit card based on how much XRD it paid on their behalf. Or, more simply, say you run an exchange application which makes a profit on each trade. You might automatically lock a fee payment for a certain percentage of that profit, allowing users with sufficiently large trades to have their entire fee covered by the application. Or imagine a game which uses tokens of its own creation for the in-game economy, and has players submit transactions for certain actions, but doesn’t want its players to worry about acquiring XRD in order to pay for those transactions. The game could run a service which automatically pays the fees on behalf of its players, and recoups that cost elsewhere.
It isn’t necessary to pay the entire fee from a single source…additional XRD may be locked for fee payment throughout the course of the transaction. This allows for a model where profit-generating applications can “chip in” for some amount of the fee without necessarily having to cover the entire cost.
At this point you may be wondering how your transaction pays the cost of the operations which lead up to that first locking of a fee. The answer is that the network automatically grants a small loan to all transactions, establishing a fixed amount of CostUnits which can be consumed before the fee reserve is initially established, at which point the loan must be fully repaid in order for execution to continue. If the transaction exceeds the loan amount without locking a sufficient amount to proceed, then the transaction is simply rejected and no record of it is kept.
Transactions which successfully repay their loan, but then fail to complete (either due to a logical abort or running out of fee reserve during execution) are marked as failed. Failed transactions still spend whatever fees (and royalties, if any) were consumed up until the point they failed. If a transaction completes successfully without spending all its fee reserve, the unspent amount is returned to the vault it was locked from.
What happens to spent fees?
50% of the base network fee is burnt. Of the remaining 50%, 25% of that goes directly to the validator who lead the round, and 75% gets added to a pool which is split among the validator set at the end of each epoch according to their participation and subject to penalties for missed proposals, similar to how network emissions work.
Any tip fees are immediately paid to the validator who led the round.
Any royalties paid to a component are placed in a system-generated vault owned by that component. The component’s instantiator may claim them using a badge automatically created at instantiation time.
Any royalties paid to a blueprint creator are placed in a system-generated vault owned by the package containing the blueprint. The developer who deployed the package may claim them using a badge automatically created at deployment time.
Further reading:
- Radix Blog - How Fees Work in Babylon
- What is a transaction?
- What are the Radix Public Network and Radix Ledger?
- What is the Radix Foundation's policy for network fee and network emissions updates?
- What is the Radix Developer Royalties System?