Affiliate Fee Guide
Affiliate fees provide a way for interfaces to generate revenue through THORChain. These fees are collected from select transactions, sent to an affiliate collector module, and periodically distributed in a gas-efficient manner using the interface's preferred asset. These fees range from 0 to 10,000 basis points (bps), where 100 bps equals 1%, and are deducted from either the inbound or outbound transaction amount.
Overview
- Fee Structure: Affiliate fees are calculated in basis points and deducted from the transaction amount.
- THORName Requirement: A valid THORName is required to collect affiliate fees. Learn how to create a THORName here.
- Preferred Asset: By default, affiliates are paid in $RUNE, but a preferred asset can be specified using a THORName.
- Multiple Affiliates for Swaps: Swaps can support multiple affiliate fees, while single affiliate fees apply to savings deposits and RUNE pool withdrawals.
- Automatic Distribution: Affiliate fees are automatically distributed to the affiliate address within your THORName based on accumulated thresholds. No manual processing is required.
Getting Started
- Create a THORName: See the THORName Guide for instructions.
- Set Up Your Preferred Asset: Configure your preferred asset, such as USDC or BTC. By default, the affiliate asset is $RUNE.
- Enable Multiple Affiliates: Set up multiple affiliate addresses for swap transactions.
- Set the Affiliate Fee Amount: Specify the affiliate fee in basis points (0–10,000) in your transactions. See Transaction Memos for details.
- Start Using THORChain: Let the affiliate collector module handle the periodic distribution of fees.
Where the Affiliate Fee is Taken
- If the inbound swap asset is a native THORChain asset ($RUNE, synth, or trade asset), the affiliate fee amount will be deducted directly from the transaction amount.
- If the inbound swap asset is on any other chain, the network will submit a swap to $RUNE.
- If the affiliate is added to an
ADDLPtransaction, then the affiliate is included in the network as an LP. - If the affiliate is added to a RUNEPool withdrawal, it is deducted from the profit amount (positive PnL), not the principal.
How it Works
The affiliate fee system operates automatically, following these steps:
- Transaction Execution: When a transaction includes an affiliate fee, the specified amount (in basis points) is deducted from the inbound or outbound transaction amount as described above.
- Fee Collection: The deducted fee is collected in the AffiliateCollector module, where it is held in $RUNE by default.
- Threshold Check: The network continuously monitors the accumulated $RUNE for each affiliate. Once the balance exceeds
PreferredAssetOutboundFeeMultipliermultiplied by the chain's outbound fee, the system initiates a swap to the preferred asset.- Example: If the outbound fee for BTC is 0.00005 BTC and the multiplier is 200, the swap will occur when the collected $RUNE is worth 0.01 BTC.
- Preferred Asset Swap: If the affiliate's THORName specifies a preferred asset (e.g., BTC, USDC), the network swaps $RUNE to that asset before distribution. If no preferred asset is set, $RUNE is distributed directly.
- Automatic Distribution: The converted (or original) amount is sent to the affiliate's address without requiring any manual intervention.
Benefits of Automatic Distribution
- Gas Efficiency: By waiting until the threshold is met, the network minimizes gas costs associated with frequent small transactions.
- Asset Flexibility: Affiliates can specify any supported asset as their preferred payout, ensuring they receive fees in the most convenient form.
Multiple Affiliates
Interfaces can define up to a limit set by MultipleAffiliatesMaxCount for valid affiliate and affiliate basis points pairs in a swap memo. This is used if more than one affiliate needs to be paid, e.g. an interface and implementation partner. The network deducts a fee for each valid affiliate defined in the memo. Alternatively, up to 5 valid affiliates and exactly one valid basis point value can be defined, and the network will attempt to skim the same basis point fee for each affiliate.
Valid Memo Examples
-
=:ETH.ETH:0x3021c479f7f8c9f1d5c7d8523ba5e22c0bcb5430::t1/t2/t3/t4/t5:10
(Will skim 10 basis points for each of the affiliates) -
=:ETH.ETH:0x3021c479f7f8c9f1d5c7d8523ba5e22c0bcb5430::t1/thor1t2hav42urasnsvwa6x6fyezaex9f953plh72pq/t3:10/20/30
(Will skim 10 basis points fort1, 20 basis points forthor1t2hav42urasnsvwa6x6fyezaex9f953plh72pq, and 30 basis points fort3)
Invalid Memo Examples
-
=:ETH.ETH:0x3021c479f7f8c9f1d5c7d8523ba5e22c0bcb5430::t1/t2/t3/t4/t5:10/20
(5 affiliates defined, but only 2 affiliate basis point values) -
=:ETH.ETH:0x3021c479f7f8c9f1d5c7d8523ba5e22c0bcb5430::t1/t2/t3/t4/t5/t6:10
(Too many affiliates defined)
Revenue Share (REVSHARE)
In addition to the user-side affiliate fee described above, an affiliate's THORName may also be configured to receive a share of the protocol's own swap liquidity fees for swaps it routes. This is paid out of the reserve at end of block, on top of any user-side affiliate fee, and does not change what the user pays.
- The dial is the operational mimir
REVSHARE-<thorname>, in basis points, capped at 5000 (50%). - Attribution is strict-first-affiliate: only the first entry in the swap memo's affiliate list earns rev share, and only if it resolves to an active THORName (raw addresses and expired thornames are ignored).
- Liquidity fees attributable to the affiliate accumulate across streaming sub-swaps within the same block.
- At end of block the network pays
bps × accrued_liquidity_fee / 10,000from the reserve to the THORName'sAffiliateCollectorbalance, and emits arev_shareevent with attributesthorname,owner,accrued_fee,bps,payout. The event is emitted for every attributed thorname even whenbps == 0, so indexers can track gross attribution independently of payout configuration. - Payouts flow through the same
AffiliateCollectormechanics as the user-side fee, so any preferred-asset configuration on the THORName applies to rev-share payouts as well.
Eligibility
REVSHARE is opt-in by node operators on a per-affiliate basis (low-quorum operational mimir, churned out like other operational keys). To be eligible:
- Register a THORName whose name uses only
[a-zA-Z0-9-]. Thornames containing_or+register cleanly but cannot have aREVSHARE-<thorname>mimir set, because mimir keys do not accept those characters. - Coordinate with node operators (e.g. via 9R) to set
REVSHARE-<thorname>to your agreed basis points.
See ADR 027 for the full rationale and design.