Referral System
Overview
JAMM DEX features an innovative referral reward system that automatically distributes fee shares via smart contracts, providing continuous incentives for referrers. This system not only encourages users to promote the platform but also helps reduce the actual trading costs for traders.
Referrer Registration Mechanism
Referrer Mapping
The JAMMFactory
contract maintains a referrer mapping:
// from JAMMFactory.sol
mapping(address => address) public referrer;
This mapping records the referrer address for each user (identified by tx.origin
).
Setting a Referrer
Users can set their referrer by calling the setReferrer
function of the JAMMFactory
contract:
// from JAMMFactory.sol
function setReferrer(address _referrer) external override {
require(referrer[tx.origin] == address(0), "JAMMFactory: REFERER_EXISTS");
referrer[tx.origin] = _referrer;
emit Referrer(tx.origin, _referrer);
}
Key Features:
Each user can set a referrer only once.
Uses
tx.origin
instead ofmsg.sender
to correctly identify the true user initiating the transaction, even if called through a contract.Once set, the referrer cannot be changed, ensuring the stability of the referral relationship.
Referrer Event
The Referrer
event is emitted when a referral relationship is established:
// from JAMMFactory.sol
event Referrer(address indexed sender, address indexed referrer);
This event records the establishment of referral relationships, facilitating tracking by front-end applications and analytics tools.
Fee Sharing Mechanism
Dual Fee System
JAMM DEX's referral system implements a unique dual fee mechanism, handled in the _collectFee
function of JAMMPair.sol
, which determines fee distribution based on the presence of a referrer:
// from JAMMPair.sol
function _collectFee(
uint amount0In,
uint amount1In,
address _referrer
) private {
address referrer = IJAMMFactory(factory).referrer(tx.origin);
address feeTo = IJAMMFactory(factory).feeTo();
if (_referrer == address(0) && referrer == address(0)) {
// Case 1: No referrer - all fees go to the protocol
_safeTransferFee(token0, feeTo, (amount0In * fee) / 50000);
_safeTransferFee(token1, feeTo, (amount1In * fee) / 50000);
} else {
// Case 2: With referrer - fees are split between protocol and referrer
_safeTransferFee(token0, feeTo, (amount0In * fee) / 100000);
_safeTransferFee(token1, feeTo, (amount1In * fee) / 100000);
if (referrer != address(0)) {
_safeTransferFee(token0, referrer, (amount0In * fee) / 100000);
_safeTransferFee(token1, referrer, (amount1In * fee) / 100000);
} else {
// If referrer is provided in swap, set it for tx.origin
IJAMMFactory(factory).setReferrer(_referrer);
_safeTransferFee(token0, _referrer, (amount0In * fee) / 100000);
_safeTransferFee(token1, _referrer, (amount1In * fee) / 100000);
}
}
}
Fee Distribution Explained
Case 1: No Referrer
Protocol Fee: Collects
(amountIn * fee) / 50000
from the input token.Referrer Fee: 0.
Case 2: With Referrer
Protocol Fee: Collects
(amountIn * fee) / 100000
from the input token.Referrer Fee: Collects
(amountIn * fee) / 100000
from the input token.The fee is split evenly between the protocol and the referrer.
Two Ways to Set a Referrer
Method 1: Pre-set
A user has already set a referrer via the setReferrer
function. In this case, the _collectFee
function will use the registered referrer associated with tx.origin
.
Method 2: Set During Transaction
A user can set a referrer via the _referrer
parameter during a transaction. If tx.origin
has not yet set a referrer, this parameter will be used to set it.
Referrer Earnings Calculation
Earnings Formula
Referrer earnings are calculated using the following formula:
Earnings per Transaction = (Input Amount * Fee Rate) / 100000
Earnings Example
For a trading pair with a 1% fee (fee = 100
):
Scenario: User swaps 1000 TokenA
Without Referrer:
Protocol collects:
1000 * 100 / 50000 = 2
TokenAReferrer collects: 0
With Referrer:
Protocol collects:
1000 * 100 / 100000 = 1
TokenAReferrer collects:
1000 * 100 / 100000 = 1
TokenA
Multi-Token Earnings
Since JAMM DEX supports swapping any ERC-20 token, referrers may receive various tokens as rewards:
// from JAMMPair.sol (_collectFee function)
_safeTransferFee(token0, referrer, (amount0In * fee) / 100000);
_safeTransferFee(token1, referrer, (amount1In * fee) / 100000);
Referrer earnings composition depends on:
The trading habits of referred users.
The types of tokens traded.
The frequency and amount of trades.
Advantages of the Referral System
Benefits for Referrers
Continuous Income: Earn a share from every transaction made by referred users.
Diversified Earnings: Potential to receive rewards in various tokens.
No Staking Required: No need to lock up any funds.
Automated Execution: Smart contracts handle automatic distribution.
Benefits for Users
Reduced Costs: While the total fee is the same, there's an incentive through referrer sharing.
Support Referrers: Helps referrers earn income.
One-Time Setup: Referral relationships are permanent.
Benefits for the Protocol
User Growth: Incentivizes users to promote the platform.
Network Effect: Referral relationships form a user network.
Fee Optimization: Optimizes the fee structure through the sharing mechanism.
Technical Implementation Details
Security Considerations
Using tx.origin
tx.origin
// from JAMMFactory.sol (referrer mapping)
address referrer = IJAMMFactory(factory).referrer(tx.origin);
The reason for using tx.origin
instead of msg.sender
:
Ensures that the true user initiating the transaction is correctly identified, even if called through a router contract.
Prevents referral relationship errors caused by contract proxies.
One-Time Setup
// from JAMMFactory.sol (setReferrer function)
require(referrer[tx.origin] == address(0), "JAMMFactory: REFERER_EXISTS");
This check ensures that:
Each user can set a referrer only once.
Prevents malicious modification of referral relationships.
Guarantees the stability of referrer earnings.
Safe Fee Transfers
// from JAMMPair.sol
function _safeTransferFee(address token, address to, uint value) private {
_safeTransfer(token, to, value);
if (value > 0) {
emit Fee(tx.origin, to, token, value);
}
}
This safe transfer function ensures that:
A secure token transfer method is used.
Fee transfer events are recorded.
Zero-value transfers are handled.
Integration Guide
Frontend Integration
Checking Referrer Status
const factory = new ethers.Contract(factoryAddress, factoryABI, provider);
const currentReferrer = await factory.referrer(userAddress);
if (currentReferrer === ethers.constants.AddressZero) {
console.log("User has not set a referrer.");
} else {
console.log("Current referrer:", currentReferrer);
}
Setting a Referrer
// Method 1: Direct call to Factory contract
const tx = await factory.setReferrer(referrerAddress);
await tx.wait();
// Method 2: Set during a swap (via Router)
const tx = await router.swapExactTokensForTokens(
amountIn,
amountOutMin,
path,
fees,
to,
referrerAddress, // Referrer address
deadline
);
Querying Referrer Earnings
Listening for Fee
Events
Fee
Eventsconst pairContract = new ethers.Contract(pairAddress, pairABI, provider);
// Listen for fees for a specific referrer
const filter = pairContract.filters.Fee(null, referrerAddress);
pairContract.on(filter, (sender, referrer, token, amount, event) => {
console.log(`Referrer ${referrer} received ${ethers.utils.formatEther(amount)} of ${token}`);
});
Calculating Historical Earnings
// Query historical Fee events
const events = await pairContract.queryFilter(
pairContract.filters.Fee(null, referrerAddress),
fromBlock,
toBlock
);
let totalRewards = {};
events.forEach(event => {
const { token, amount } = event.args;
if (!totalRewards[token]) {
totalRewards[token] = ethers.BigNumber.from(0);
}
totalRewards[token] = totalRewards[token].add(amount);
});
Best Practices
For Referrers
Promotion Strategy: Focus on promoting to active traders.
Diversification: Refer different types of users to gain diversified earnings.
Long-Term Perspective: Referral relationships are permanent; focus on long-term income.
For Users
Set Timely: Set a referrer before your first transaction.
Choose Active Referrers: Select referrers who can provide support.
Understand Impact: Understand how the referral system affects trading costs.
For Developers
UI Prompts: Prompt users to set a referrer in the interface.
Earnings Display: Provide a function for referrers to query their earnings.
Event Listening: Listen for events to display referrer earnings in real-time.
Summary
JAMM DEX's referral system is an innovative incentive mechanism that:
Automates Execution: Fees are automatically distributed via smart contracts.
Win-Win Mechanism: Referrers earn income, and users receive support.
Permanent Effect: Once set, it is effective indefinitely.
Transparent and Public: All distributions are verifiable on-chain.
Secure and Reliable: Multiple security mechanisms protect referral relationships.
This system provides strong growth momentum for the JAMM DEX ecosystem.