费用结构

JAMM DEX 实现了灵活的多级费率系统,允许不同的交易对根据其特性选择合适的费率等级。这种设计为不同风险和流动性需求的资产提供了优化的交易体验。

费率等级

支持的费率

JAMMFactory.sol 中定义了四种预设的费率等级:

// Supported fee tiers
uint24 public constant FEE_0_5_PERCENT = 50;   // 0.5% fee
uint24 public constant FEE_1_PERCENT = 100;    // 1.0% fee
uint24 public constant FEE_2_PERCENT = 200;    // 2.0% fee
uint24 public constant FEE_3_PERCENT = 300;    // 3.0% fee

费率验证

在创建交易对时,系统会验证费率的有效性:

// from JAMMFactory.sol
require(
    fee == FEE_0_5_PERCENT ||
        fee == FEE_1_PERCENT ||
        fee == FEE_2_PERCENT ||
        fee == FEE_3_PERCENT,
    "JAMMFactory: INVALID_FEE"
);

费用计算

交易费用

交易费用在计算交换数量时从输入代币中扣除。这个逻辑在 JAMMLibrary.sol 中实现:

// from JAMMLibrary.sol
function getAmountOut(
    uint amountIn,
    uint reserveIn,
    uint reserveOut,
    uint24 fee
) internal pure returns (uint amountOut) {
    require(amountIn > 0, "JAMMLibrary: INSUFFICIENT_INPUT_AMOUNT");
    require(reserveIn > 0 && reserveOut > 0, "JAMMLibrary: INSUFFICIENT_LIQUIDITY");
    
    // Fee is deducted from the input amount
    uint amountInWithFee = amountIn * (10000 - fee);
    uint numerator = amountInWithFee * reserveOut;
    uint denominator = reserveIn * 10000 + amountInWithFee;
    amountOut = numerator / denominator;
}

费用分配机制

JAMM DEX 实现了独特的双重费用分配机制,在 JAMMPair.sol_collectFee 函数中实现,根据是否有推荐人来决定费用分配:

// 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
        _safeTransferFee(token0, feeTo, (amount0In * fee) / 50000);
        _safeTransferFee(token1, feeTo, (amount1In * fee) / 50000);
    } else {
        // Case 2: With 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 {
            IJAMMFactory(factory).setReferrer(_referrer);
            _safeTransferFee(token0, _referrer, (amount0In * fee) / 100000);
            _safeTransferFee(token1, _referrer, (amount1In * fee) / 100000);
        }
    }
}

费用分配详解

无推荐人情况

  • 协议费用: 从输入代币中收取 (amountIn * fee) / 50000

  • 推荐人费用: 0。

有推荐人情况

  • 协议费用: 从输入代币中收取 (amountIn * fee) / 100000

  • 推荐人费用: 从输入代币中收取 (amountIn * fee) / 100000

  • 费用在协议和推荐人之间平分。

协议费用机制 (Protocol Fee)

除了直接的交易费用,JAMM DEX 还可以通过铸造新的LP代币来收取协议费用。这部分费用流向 mintTo 地址,由 _mintFee 函数管理。

// from JAMMPair.sol
function _mintFee(
    uint112 _reserve0,
    uint112 _reserve1
) private returns (bool feeOn) {
    address mintTo = IJAMMFactory(factory).mintTo();
    feeOn = mintTo != address(0);
    uint _kLast = kLast;
    if (feeOn) {
        if (_kLast != 0) {
            uint rootK = Math.sqrt(uint(_reserve0) * uint(_reserve1));
            uint rootKLast = Math.sqrt(_kLast);
            if (rootK > rootKLast) {
                // calculate liquidity to mint as protocol fee
                uint numerator = totalSupply * (rootK - rootKLast) * 8;
                uint denominator = rootK * 17 + rootKLast * 8;
                uint liquidity = numerator / denominator;
                if (liquidity > 0) _mint(mintTo, liquidity);
            }
        }
    } else if (_kLast != 0) {
        kLast = 0;
    }
}

协议费用计算

协议费用基于流动性池的增长(k值的增加)来计算。当池子的总价值因累积的交易费而增长时,协议会按比例铸造新的LP代币作为收入。

恒定乘积验证 (K-Value Check)

在每次交换后,系统会验证恒定乘积公式,确保扣除费用后的平衡。JAMMPair.sol 中的 swap 函数包含了这个检查:

// from JAMMPair.sol
{
    balance0 = IERC20(token0).balanceOf(address(this));
    balance1 = IERC20(token1).balanceOf(address(this));
    
    // adjust balances for fee calculation
    uint balance0Adjusted = (balance0 * 10000 - (amount0In * fee * 4) / 5);
    uint balance1Adjusted = (balance1 * 10000 - (amount1In * fee * 4) / 5);
    
    // ensure the product of adjusted balances is not less than the previous reserves product
    require(
        balance0Adjusted * balance1Adjusted >=
            uint(_reserve0) * uint(_reserve1) * (10000 ** 2),
        "JAMM: K"
    );
}

费率选择指南

0.5% 费率

  • 适用场景: 稳定币对(如USDC/USDT),高流动性、低波动性资产。

  • 特点: 交易成本最低,适合大额交易和套利。

1.0% 费率

  • 适用场景: 主流代币对(如JU/USDC),中等波动性资产。

  • 特点: 标准费率,平衡用户成本和LP收益。

2.0% 费率

  • 适用场景: 中等风险的代币对,新兴项目代币。

  • 特点: 为LP提供更高收益,以补偿较高的无常损失风险。

3.0% 费率

  • 适用场景: 高风险、高波动性代币,小众或实验性代币。

  • 特点: LP收益率最高,以补偿高风险和高无常损失。

费用事件

每次费用转账都会触发 Fee 事件:

// from JAMMPair.sol
event Fee(
    address indexed sender,
    address indexed referrer,
    address token,
    uint amount
);

function _safeTransferFee(address token, address to, uint value) private {
    _safeTransfer(token, to, value);
    if (value > 0) {
        emit Fee(tx.origin, to, token, value);
    }
}

这个事件记录了费用分配的详细信息,便于链上数据分析和追踪。

JAMM DEX的费用结构具有以下特点:

  1. 多级费率: 四种预定义费率满足不同资产的需求。

  2. 推荐人激励: 独特的费用分成机制激励社区推广。

  3. 协议可持续性: 通过LP代币铸造收取协议费用,确保长期发展。

  4. 透明性: 所有费用计算和分配都在链上公开进行。

  5. 灵活性: 允许为不同类型的资产对选择最合适的费率。

Last updated