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 of msg.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 TokenA

    • Referrer collects: 0

  • With Referrer:

    • Protocol collects: 1000 * 100 / 100000 = 1 TokenA

    • Referrer 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

  1. Continuous Income: Earn a share from every transaction made by referred users.

  2. Diversified Earnings: Potential to receive rewards in various tokens.

  3. No Staking Required: No need to lock up any funds.

  4. Automated Execution: Smart contracts handle automatic distribution.

Benefits for Users

  1. Reduced Costs: While the total fee is the same, there's an incentive through referrer sharing.

  2. Support Referrers: Helps referrers earn income.

  3. One-Time Setup: Referral relationships are permanent.

Benefits for the Protocol

  1. User Growth: Incentivizes users to promote the platform.

  2. Network Effect: Referral relationships form a user network.

  3. Fee Optimization: Optimizes the fee structure through the sharing mechanism.

Technical Implementation Details

Security Considerations

Using 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

const 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

  1. Promotion Strategy: Focus on promoting to active traders.

  2. Diversification: Refer different types of users to gain diversified earnings.

  3. Long-Term Perspective: Referral relationships are permanent; focus on long-term income.

For Users

  1. Set Timely: Set a referrer before your first transaction.

  2. Choose Active Referrers: Select referrers who can provide support.

  3. Understand Impact: Understand how the referral system affects trading costs.

For Developers

  1. UI Prompts: Prompt users to set a referrer in the interface.

  2. Earnings Display: Provide a function for referrers to query their earnings.

  3. Event Listening: Listen for events to display referrer earnings in real-time.

Summary

JAMM DEX's referral system is an innovative incentive mechanism that:

  1. Automates Execution: Fees are automatically distributed via smart contracts.

  2. Win-Win Mechanism: Referrers earn income, and users receive support.

  3. Permanent Effect: Once set, it is effective indefinitely.

  4. Transparent and Public: All distributions are verifiable on-chain.

  5. Secure and Reliable: Multiple security mechanisms protect referral relationships.

This system provides strong growth momentum for the JAMM DEX ecosystem.