Math 库

Math库是JAMM DEX中的数学运算工具库,提供了安全的基础数学运算函数。它包含了平方根计算、最小值比较以及带溢出保护的四则运算,为整个协议提供了可靠的数学基础。

库函数详解

最小值函数

function min(uint x, uint y) internal pure returns (uint z) {
    z = x < y ? x : y;
}

功能:返回两个无符号整数中的较小值

用途

  • 流动性计算中选择较小的比例

  • 限制最大值设置

  • 边界条件处理

示例

uint minAmount = Math.min(amountA, amountB);

平方根函数

function sqrt(uint y) internal pure returns (uint z) {
    if (y > 3) {
        z = y;
        uint x = y / 2 + 1;
        while (x < z) {
            z = x;
            x = (y / x + x) / 2;
        }
    } else if (y != 0) {
        z = 1;
    }
}

算法:巴比伦方法(牛顿迭代法的特例)

计算原理

  1. 初始猜测值:x₀ = y/2 + 1

  2. 迭代公式:x_{n+1} = (y/x_n + x_n) / 2

  3. x_{n+1} >= x_n时停止迭代

特殊情况处理

  • y = 0: 返回0

  • y = 1, 2, 3: 返回1

  • y > 3: 使用迭代算法

用途

  • 计算几何平均数

  • LP代币数量计算:√(amount0 × amount1)

  • 协议费用计算中的k值平方根

加法函数

安全特性

  • 检查加法溢出

  • 如果x + y < x则说明发生溢出

  • 溢出时抛出异常

注意:在Solidity 0.8.x中,内置了溢出检查,此函数主要用于兼容性

减法函数

安全特性

  • 检查减法下溢

  • 如果x - y > x则说明发生下溢

  • 下溢时抛出异常

乘法函数

安全特性

  • 检查乘法溢出

  • 通过除法验证:如果(x × y) / y ≠ x则发生溢出

  • 特殊处理y = 0的情况

除法函数

安全特性

  • 检查除零错误

  • 确保除数大于0

在JAMM DEX中的应用

流动性计算

初始流动性计算

几何平均数

  • 使用√(amount0 × amount1)计算初始LP代币数量

  • 几何平均数比算术平均数更适合乘积恒定的AMM系统

  • 减去MINIMUM_LIQUIDITY防止池子被完全清空

后续流动性计算

最小值选择

  • 确保按现有比例添加流动性

  • 防止单边添加流动性破坏价格

  • 保护流动性提供者利益

协议费用计算

k值增长计算

  • 计算当前k值的平方根

  • 计算上次k值的平方根

  • 基于k值增长计算协议费用

数学原理

巴比伦平方根算法

巴比伦方法是计算平方根的古老算法,基于以下观察:

如果xn的平方根的近似值,那么n/x也是一个近似值,且:

  • 如果x > √n,则n/x < √n

  • 如果x < √n,则n/x > √n

因此,(x + n/x) / 2是一个更好的近似值。

收敛性

  • 算法具有二次收敛性

  • 每次迭代有效数字大约翻倍

  • 对于256位整数,通常只需要几次迭代

溢出检测原理

加法溢出检测

原理:在无符号整数中,如果加法结果小于任一操作数,说明发生了环绕。

乘法溢出检测

原理:如果没有溢出,(x * y) / y应该等于x

使用示例

平方根计算

最小值选择

安全运算

性能考虑

平方根算法效率

巴比伦方法的时间复杂度:

  • 最坏情况:O(log log n)

  • 平均情况:通常3-4次迭代

  • Gas消耗:相对较低,适合链上计算

优化技巧

  1. 初始猜测优化

  2. 特殊情况处理

  3. 循环优化

测试用例

平方根测试

溢出测试

Last updated