Skip to content

sannicolasshaneka/safemoon-contract-analysis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

Safemoon智能合约深度解析:DeFi代币经济学与技术实现 自动流动性池|持币奖励|销毁机制|交易税| Web3技术研究 |DAPP开发定制|合约设计|快速上线|TG:recoverybtc

💡 本文由领先的区块链技术服务商 Crypto8848 技术团队出品。我们专注于 DeFi、DApp、算法 Token 等 Web3 核心技术开发,提供全方位的区块链解决方案。Telegram:@recoverybtc

目录

  1. 项目概述
  2. 合约架构
  3. 核心功能实现
  4. 反射机制原理
  5. 自动流动性机制
  6. 多级费用系统
  7. 安全机制
  8. 性能优化
  9. 部署指南
  10. 测试用例
  11. 完整代码注释

项目概述

SafeMoon是一个创新的DeFi代币项目,于2021年3月8日在币安智能链(BSC)上线。在2021年牛市期间,SafeMoon创造了惊人的市场表现:

  • 在2021年3月12日至4月20日期间,价格飙升超过55,000%
  • 市值一度达到57亿美元
  • 曾超越「狗狗币」(Dogecoin)成为搜索量最大的加密货币
  • 后因流动性池锁定问题导致价格暴跌近50%

SafeMoon最大的创新在于其独特的代币经济学模型和分红机制,这也引发了市场上大量的模仿项目。其核心特点包括:

  • 惩罚交易、奖励持有:合约会对交易行为收取费用,并将部分费用分配给持币者
  • 自动流动性添加:交易税的一部分会自动注入流动性池
  • 被动收益:用户只需持有代币,无需任何操作即可获得分红收益

通过这种创新的代币经济学模型,SafeMoon实现了以下核心特性:

  1. 反射机制(Reflection)

    • 持有者可以通过持有获得被动收益
    • 交易费用的一部分会按比例分配给所有持有者
    • 长期持有者获得更多收益
  2. 自动流动性生成(Auto LP)

    • 每笔交易自动向流动性池注入资金
    • 提高代币价格稳定性
    • 降低大额交易的价格影响
  3. 多级费用系统

    • 交易费用分配给反射、流动性池和项目发展基金
    • 动态调节的费率机制
    • 防止投机和倾销

合约架构

1. 核心合约结构

SafeMoon Token Contract
├── 代币基础功能 (ERC20/BEP20)
├── 反射机制模块
├── 自动流动性模块
└── 费用处理模块

2. 依赖关系

  • SafeMathUpgradeable:安全数学运算
  • AddressUpgradeable:地址相关操作
  • IERC20:代币标准接口
  • IPancakeRouter02:DEX路由接口
  • IPancakePair:交易对接口

3. 状态变量

  • 代币信息(名称、符号、总供应量)
  • 费率配置
  • 排除名单(不参与反射/费用)
  • 流动性池地址
  • 路由合约地址

核心功能实现

1. 反射机制

struct ReflectionValues {
    uint256 rAmount;      // 反射数量
    uint256 rTransferAmount; // 实际转账数量
    uint256 rFee;         // 反射费用
    uint256 tTransferAmount; // 代币转账数量
    uint256 tFee;         // 代币费用
    uint256 tLiquidity;   // 流动性数量
}

2. 自动流动性

  • 收集交易费用
  • 将BNB和代币添加到流动性池
  • 锁定LP代币

3. 费用处理

  • 计算各类费用
  • 分配反射收益
  • 处理流动性注入

反射机制原理

1. 数学模型

反射机制基于以下公式:

反射率 = 总反射数量 / 代币总供应量

即: Rrate = totalReflections / totalSupply

参数说明:

  • Rrate: 反射率 - 决定每个持有者能获得的反射收益比例
  • totalReflections: 总反射数量 - 所有交易产生的反射总量
  • totalSupply: 代币总供应量 - 当前流通的代币总量

这个公式表示:

  1. 每个代币持有者获得的反射比例取决于其持有的代币数量
  2. 反射率是动态的,会随着交易而变化
  3. 总反射量会随着每笔交易的费用而增加

2. 实现细节

  1. 跟踪总反射量
  2. 计算每个地址的反射份额
  3. 动态更新反射率

自动流动性机制

1. 工作流程

  1. 收集交易费用
  2. 累积到阈值
  3. 自动添加流动性
  4. 锁定LP代币

2. 关键代码

// 添加流动性的核心逻辑
function swapAndLiquify(uint256 contractTokenBalance) private {
    // 将一半代币换成BNB
    uint256 half = contractTokenBalance.div(2);
    uint256 otherHalf = contractTokenBalance.sub(half);
    
    // 添加流动性
    // ...
}

多级费用系统

1. 费用结构

  • 反射费用:奖励持有者
  • 流动性费用:增加流动性
  • 营销费用:项目发展

2. 动态调节

  • 基于交易量调整费率
  • 特殊地址豁免机制
  • 紧急调整功能

安全机制

1. 权限控制

  • 所有者权限限制
  • 多重签名机制
  • 时间锁定

2. 防护措施

  • 重入攻击防护
  • 整数溢出保护
  • 地址验证

3. 紧急功能

  • 交易暂停
  • 费率调整
  • 黑名单管理

性能优化

1. Gas优化

  • 批量操作合并
  • 存储优化
  • 循环优化

2. 计算优化

  • 缓存中间结果
  • 避免重复计算
  • 使用位运算

部署指南

1. 前期准备

  • 配置参数
  • 依赖检查
  • 网络选择

2. 部署步骤

  1. 部署主合约
  2. 初始化参数
  3. 配置路由
  4. 添加初始流动性

3. 验证检查

  • 功能测试
  • 安全审计
  • 性能测试

测试用例

1. 单元测试

  • 基础功能测试
  • 反射机制测试
  • 流动性测试

2. 集成测试

  • 交易流程测试
  • 费用系统测试
  • 紧急功能测试

3. 压力测试

  • 大额交易测试
  • 高频交易测试
  • 极限条件测试

完整代码注释

核心合约结构

contract Safemoon is ISafemoon, Initializable, ContextUpgradeable, OwnableUpgradeable {
    // 使用安全数学库
    using SafeMathUpgradeable for uint256;
    using AddressUpgradeable for address;

    // 费用等级结构体
    struct FeeTier {
        uint256 ecoSystemFee;    // 生态系统费用
        uint256 liquidityFee;    // 流动性费用
        uint256 taxFee;          // 税费
        uint256 ownerFee;        // 所有者费用
        uint256 burnFee;         // 销毁费用
        address ecoSystem;       // 生态系统地址
        address owner;           // 所有者地址
    }

    // 反射值结构体
    struct FeeValues {
        uint256 rAmount;         // 反射总量
        uint256 rTransferAmount; // 反射转账量
        uint256 rFee;           // 反射费用
        uint256 tTransferAmount;// 代币转账量
        uint256 tEchoSystem;    // 生态系统费用
        uint256 tLiquidity;     // 流动性费用
        uint256 tFee;           // 税费
        uint256 tOwner;         // 所有者费用
        uint256 tBurn;          // 销毁费用
    }
}

关键状态变量

    // 反射值映射
    mapping(address => uint256) private _rOwned;
    // 代币余额映射
    mapping(address => uint256) private _tOwned;
    // 授权映射
    mapping(address => mapping(address => uint256)) private _allowances;
    // 免费用地址映射
    mapping(address => bool) private _isExcludedFromFee;
    // 排除地址映射
    mapping(address => bool) private _isExcluded;
    // 黑名单地址映射
    mapping(address => bool) private _isBlacklisted;
    // 地址费用等级映射
    mapping(address => uint256) private _accountsTier;

    // 常量和配置
    uint256 private constant MAX = ~uint256(0);
    uint256 private _tTotal;      // 代币总供应量
    uint256 private _rTotal;      // 反射值总量
    uint256 private _maxFee;      // 最大费用
    uint256 public _maxTxAmount;  // 最大交易量

核心功能实现

1. 初始化函数

    function __Safemoon_v2_init_unchained() internal initializer {
        // 设置代币基本信息
        _name = "SafeMoon";
        _symbol = "SFM";
        _decimals = 9;

        // 初始化总供应量和反射值
        _tTotal = 1000000 * 10**6 * 10**9;
        _rTotal = (MAX - (MAX % _tTotal));
        _maxFee = 1000;

        // 设置交易限制
        _maxTxAmount = 5000 * 10**6 * 10**9;
        numTokensSellToAddToLiquidity = 500 * 10**6 * 10**9;

        // 设置基础地址
        _burnAddress = 0x000000000000000000000000000000000000dEaD;
        _initializerAccount = _msgSender();
        _rOwned[_initializerAccount] = _rTotal;

        // 初始化费用豁免
        _isExcludedFromFee[owner()] = true;
        _isExcludedFromFee[address(this)] = true;

        // 初始化费用等级
        __Safemoon_tiers_init();

        emit Transfer(address(0), _msgSender(), _tTotal);
    }

2. 转账功能

    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) private {
        // 基本检查
        require(sender != address(0), "转账发送方不能为零地址");
        require(recipient != address(0), "转账接收方不能为零地址");
        require(amount > 0, "转账金额必须大于零");
        
        // 交易限额检查
        if (sender != owner() && recipient != owner())
            require(amount <= _maxTxAmount, "转账金额超过最大限制");

        // 自动流动性处理
        bool overMinTokenBalance = balanceOf(address(this)) >= numTokensSellToAddToLiquidity;
        if (
            overMinTokenBalance &&
            !inSwapAndLiquify &&
            sender != uniswapV2Pair &&
            swapAndLiquifyEnabled
        ) {
            swapAndLiquify(numTokensSellToAddToLiquidity);
        }

        // 转账处理
        bool takeFee = true;
        if (_isExcludedFromFee[sender] || _isExcludedFromFee[recipient]) {
            takeFee = false;
        }

        _tokenTransfer(sender, recipient, amount, _accountsTier[sender], takeFee);
    }

3. 反射机制实现

    function _getCurrentSupply() private view returns (uint256, uint256) {
        // 检查总量限制
        if (_rTotalExcluded > _rTotal || _tTotalExcluded > _tTotal) {
            return (_rTotal, _tTotal);
        }

        // 计算当前供应量
        uint256 rSupply = _rTotal.sub(_rTotalExcluded);
        uint256 tSupply = _tTotal.sub(_tTotalExcluded);

        // 验证反射率
        if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);

        return (rSupply, tSupply);
    }

    function _getRate() private view returns (uint256) {
        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
        return rSupply.div(tSupply);
    }

4. 流动性管理

    function swapAndLiquify(uint256 contractTokenBalance) private lockTheSwap {
        // 将代币分成两半
        uint256 half = contractTokenBalance.div(2);
        uint256 otherHalf = contractTokenBalance.sub(half);

        // 获取当前合约BNB余额
        uint256 initialBalance = address(this).balance;

        // 将一半代币换成BNB
        swapTokensForBnb(half);

        // 获取实际获得的BNB数量
        uint256 newBalance = address(this).balance.sub(initialBalance);

        // 添加流动性
        addLiquidity(otherHalf, newBalance);
    }

安全机制实现

1. 权限控制

    modifier onlyOwner() {
        require(owner() == _msgSender(), "调用者不是所有者");
        _;
    }

    modifier lockTheSwap() {
        inSwapAndLiquify = true;
        _;
        inSwapAndLiquify = false;
    }

2. 黑名单管理

    function blacklistAddress(address account) public onlyOwner {
        require(!_isBlacklisted[account], "地址已在黑名单中");
        _isBlacklisted[account] = true;
    }

    function unBlacklistAddress(address account) public onlyOwner {
        require(_isBlacklisted[account], "地址不在黑名单中");
        _isBlacklisted[account] = false;
    }

费用系统实现

    function calculateFee(uint256 _amount, uint256 _fee) private pure returns (uint256) {
        if (_fee == 0) return 0;
        return _amount.mul(_fee).div(10**4);
    }

    function removeAllFee() private {
        _previousFees = feeTiers[0];
        feeTiers[0] = _emptyFees;
    }

    function restoreAllFee() private {
        feeTiers[0] = _previousFees;
    }

升级机制

    modifier lockUpgrade() {
        require(!_upgraded, "合约已升级");
        _;
        _upgraded = true;
    }

    function migrate(address account, uint256 amount) external override {
        require(migration != address(0), "迁移尚未开始");
        require(_msgSender() == migration, "无权限执行迁移");
        _migrate(account, amount);
    }

以上是 Safemoon 智能合约的核心代码实现和详细注释。该合约通过创新的代币经济学模型,实现了反射机制、自动流动性生成、多级费用系统等特性,为持有者提供了被动收益和价格稳定性保障。同时,合约还包含了完善的安全机制和升级功能,确保了代币的安全性和可持续发展。

完整合约代码

/**
 * @title Safemoon V2 智能合约
 * @dev 实现了创新的DeFi代币经济学模型,包括:
 * 1. 反射机制 - 持有者可以获得交易费用的分红
 * 2. 自动流动性生成 - 每笔交易自动向流动性池注入资金
 * 3. 多级费用系统 - 支持不同等级的交易费用配置
 * 4. 自动销毁 - 部分交易费用会被自动销毁
 * @author Safemoon Team
 */

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.11;

/**
 * @dev SafeMathUpgradeable 库
 * 提供安全的数学运算功能,防止溢出
 * 所有的数学运算都会进行溢出检查
 */
library SafeMathUpgradeable {
    /**
     * @dev 尝试两个无符号整数相加,并返回溢出标志
     * @param a 第一个操作数
     * @param b 第二个操作数
     * @return bool 是否成功(无溢出)
     * @return uint256 相加结果
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0); // 溢出检查
        return (true, c);
    }

    /**
     * @dev 尝试两个无符号整数相减,并返回溢出标志
     * @param a 被减数
     * @param b 减数
     * @return bool 是否成功(无溢出)
     * @return uint256 相减结果
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0); // 溢出检查
        return (true, a - b);
    }

    /**
     * @dev 尝试两个无符号整数相乘,并返回溢出标志
     * @param a 第一个操作数
     * @param b 第二个操作数
     * @return bool 是否成功(无溢出)
     * @return uint256 相乘结果
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas优化: 这比要求'a'不为零更便宜,但如果'b'也被测试,这个好处就会失去
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0); // 溢出检查
        return (true, c);
    }

    /**
     * @dev 尝试两个无符号整数相除,并返回除零标志
     * @param a 被除数
     * @param b 除数
     * @return bool 是否成功(非零除数)
     * @return uint256 相除结果
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0); // 除零检查
        return (true, a / b);
    }

    /**
     * @dev 尝试计算两个无符号整数的模,并返回除零标志
     * @param a 被除数
     * @param b 除数
     * @return bool 是否成功(非零除数)
     * @return uint256 取模结果
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0); // 除零检查
        return (true, a % b);
    }

    /**
     * @dev 返回两个无符号整数的和,溢出时回退
     * @param a 第一个操作数
     * @param b 第二个操作数
     * @return uint256 相加结果
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: 加法溢出");
        return c;
    }

    /**
     * @dev 返回两个无符号整数的差,溢出时回退
     * @param a 被减数
     * @param b 减数
     * @return uint256 相减结果
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: 减法溢出");
        return a - b;
    }

    /**
     * @dev 返回两个无符号整数的积,溢出时回退
     * @param a 第一个操作数
     * @param b 第二个操作数
     * @return uint256 相乘结果
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: 乘法溢出");
        return c;
    }

    /**
     * @dev 返回两个无符号整数的商,除数为零时回退
     * @param a 被除数
     * @param b 除数
     * @return uint256 相除结果
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: 除数为零");
        return a / b;
    }

    /**
     * @dev 返回两个无符号整数相除的余数,除数为零时回退
     * @param a 被除数
     * @param b 除数
     * @return uint256 取模结果
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: 模运算除数为零");
        return a % b;
    }

    /**
     * @dev 返回两个无符号整数的差,溢出时使用自定义错误消息回退
     * @param a 被减数
     * @param b 减数
     * @param errorMessage 错误消息
     * @return uint256 相减结果
     * @notice 此函数已弃用,因为它需要为错误消息不必要地分配内存
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev 返回两个无符号整数的商,除数为零时使用自定义错误消息回退
     * @param a 被除数
     * @param b 除数
     * @param errorMessage 错误消息
     * @return uint256 相除结果
     * @notice 此函数已弃用,因为它需要为错误消息不必要地分配内存
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev 返回两个无符号整数相除的余数,除数为零时使用自定义错误消息回退
     * @param a 被除数
     * @param b 除数
     * @param errorMessage 错误消息
     * @return uint256 取模结果
     * @notice 此函数已弃用,因为它需要为错误消息不必要地分配内存
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

/**
 * @dev AddressUpgradeable 库
 * 提供地址相关的工具函数
 */
library AddressUpgradeable {
    /**
     * @dev 检查地址是否是合约
     * @param account 要检查的地址
     * @return bool 是否是合约地址
     * @notice 此函数可能返回false的情况:
     * 1. 外部账户(EOA)
     * 2. 正在构建中的合约
     * 3. 将要创建合约的地址
     * 4. 曾经存在但已被销毁的合约地址
     */
    function isContract(address account) internal view returns (bool) {
        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev 发送ETH到指定地址,转发所有可用gas并在错误时回退
     * @param recipient 接收地址
     * @param amount 发送数量
     * @notice 这是Solidity transfer函数的替代品
     * 1. 移除了2300 gas的限制
     * 2. 防止重入攻击
     * 3. 使用checks-effects-interactions模式
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: 余额不足");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: 无法发送数值,接收方可能已回退");
    }

    /**
     * @dev 使用低级call执行Solidity函数调用
     * @param target 目标合约地址
     * @param data 调用数据
     * @return bytes 返回数据
     * @notice 这是安全的函数调用替代品,会传播目标的revert原因
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: 低级调用失败");
    }

    /**
     * @dev 同functionCall,但可以自定义错误消息
     * @param target 目标合约地址
     * @param data 调用数据
     * @param errorMessage 错误消息
     * @return bytes 返回数据
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev 同functionCall,但同时转账ETH
     * @param target 目标合约地址
     * @param data 调用数据
     * @param value 转账数量
     * @return bytes 返回数据
     * @notice 要求:
     * 1. 调用合约必须有足够的ETH余额
     * 2. 被调用的函数必须是payable
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: 带value的低级调用失败");
    }

    /**
     * @dev 同functionCallWithValue,但可以自定义错误消息
     * @param target 目标合约地址
     * @param data 调用数据
     * @param value 转账数量
     * @param errorMessage 错误消息
     * @return bytes 返回数据
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: 余额不足");
        require(isContract(target), "Address: 调用到非合约地址");

        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev 同functionCall,但执行staticcall
     * @param target 目标合约地址
     * @param data 调用数据
     * @return bytes 返回数据
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: 低级static调用失败");
    }

    /**
     * @dev 同functionStaticCall,但可以自定义错误消息
     * @param target 目标合约地址
     * @param data 调用数据
     * @param errorMessage 错误消息
     * @return bytes 返回数据
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: 对非合约地址进行static调用");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev 验证调用结果
     * @param success 是否成功
     * @param returndata 返回数据
     * @param errorMessage 错误消息
     * @return bytes 返回数据
     * @notice 如果调用失败,会尝试提取revert原因
     */
    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // 查找revert原因并向上传播
            if (returndata.length > 0) {
                // 最简单的方法是通过assembly传播revert原因
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

/**
 * @dev 可初始化合约的基类
 * 提供初始化机制,替代构造函数
 * 用于可升级合约
 */
abstract contract Initializable {
    /**
     * @dev 指示合约是否已经初始化
     */
    bool private _initialized;

    /**
     * @dev 指示合约是否正在初始化
     */
    bool private _initializing;

    /**
     * @dev 修饰符:保护初始化函数不被多次调用
     */
    modifier initializer() {
        require(_initializing || _isConstructor() || !_initialized, "Initializable: 合约已经初始化");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }

    /**
     * @dev 返回函数是否在构造函数中运行
     * @return bool 是否在构造函数中
     */
    function _isConstructor() private view returns (bool) {
        return !AddressUpgradeable.isContract(address(this));
    }
}

/**
 * @dev 上下文合约
 * 提供有关当前执行上下文的信息
 * 包括交易发送者和数据
 */
abstract contract ContextUpgradeable is Initializable {
    function __Context_init() internal initializer {
        __Context_init_unchained();
    }

    function __Context_init_unchained() internal initializer {}

    /**
     * @dev 获取消息发送者
     * @return address payable 发送者地址
     */
    function _msgSender() internal view virtual returns (address payable) {
        return payable(msg.sender);
    }

    /**
     * @dev 获取消息数据
     * @return bytes 消息数据
     */
    function _msgData() internal view virtual returns (bytes memory) {
        this; // 消除状态可变性警告
        return msg.data;
    }

    uint256[50] private __gap;
}

/**
 * @dev 所有权合约
 * 实现基本的访问控制机制
 * 只有合约所有者可以执行某些操作
 */
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev 初始化合约,设置部署者为初始所有者
     */
    function __Ownable_init() internal initializer {
        __Context_init_unchained();
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal initializer {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev 返回当前所有者地址
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev 修饰符:只允许所有者执行
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: 调用者不是所有者");
        _;
    }

    /**
     * @dev 放弃合约所有权
     * 将使合约没有所有者
     * 只能由当前所有者调用
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev 转移合约所有权
     * @param newOwner 新的所有者地址
     * 只能由当前所有者调用
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: 新所有者是零地址");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }

    uint256[49] private __gap;
}

/**
 * @dev Safemoon代币接口
 * 定义了代币必须实现的基本功能
 */
interface ISafemoon {
    /**
     * @dev 返回代币总供应量
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev 返回账户持有的代币数量
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev 转移代币
     * @param recipient 接收者地址
     * @param amount 转移数量
     * @return bool 是否成功
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev 返回授权额度
     * @param owner 持有者地址
     * @param spender 被授权者地址
     * @return uint256 授权数量
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev 授权代币
     * @param spender 被授权者地址
     * @param amount 授权数量
     * @return bool 是否成功
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev 通过授权转移代币
     * @param sender 发送者地址
     * @param recipient 接收者地址
     * @param amount 转移数量
     * @return bool 是否成功
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev 铸造代币
     * @param account 接收者地址
     * @param amount 铸造数量
     */
    function migrate(address account, uint256 amount) external;

    /**
     * @dev 检查是否开始迁移
     * @return bool 是否开始迁移
     */
    function isMigrationStarted() external view returns (bool);

    /**
     * @dev 转账事件
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev 授权事件
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

/**
 * @dev Uniswap V2工厂合约接口
 * 用于创建交易对
 */
interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint256);

    /**
     * @dev 创建交易对
     * @param tokenA 代币A地址
     * @param tokenB 代币B地址
     * @param to 接收LP代币的地址
     * @return pair 创建的交易对地址
     */
    function createPair(
        address tokenA,
        address tokenB,
        address to
    ) external returns (address pair);
}

/**
 * @dev Uniswap V2路由01合约接口
 * 提供基本的交易和流动性功能
 */
interface IUniswapV2Router01 {
    /**
     * @dev 返回工厂合约地址
     */
    function factory() external pure returns (address);

    /**
     * @dev 返回交易路由地址
     */
    function routerTrade() external pure returns (address);

    /**
     * @dev 返回WETH合约地址
     */
    function WETH() external pure returns (address);

    /**
     * @dev 添加ETH流动性
     * @param token 代币地址
     * @param amountTokenDesired 期望添加的代币数量
     * @param amountTokenMin 最小代币数量
     * @param amountETHMin 最小ETH数量
     * @param to 接收LP代币的地址
     * @param deadline 截止时间
     */
    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );
}

/**
 * @dev Uniswap V2路由02合约接口
 * 继承自路由01,提供更多高级功能
 */
interface IUniswapV2Router02 is IUniswapV2Router01 {}

/**
 * @dev SafeSwap交易路由接口
 * 提供安全的代币交换功能
 */
interface ISafeSwapTradeRouter {
    /**
     * @dev 交易结构体
     * @param amountIn 输入数量
     * @param amountOut 输出数量
     * @param path 交易路径
     * @param to 接收地址
     * @param deadline 截止时间
     */
    struct Trade {
        uint256 amountIn;
        uint256 amountOut;
        address[] path;
        address payable to;
        uint256 deadline;
    }

    /**
     * @dev 设置路由器地址
     */
    function setRouter(address _router) external;

    /**
     * @dev 设置费用百分比
     */
    function setFeePercent(uint256 _feePercent) external;

    /**
     * @dev 设置百分比
     */
    function sePercent(uint256 _percent) external;

    /**
     * @dev 添加费用白名单
     */
    function addFfsWhitelist(address _wl) external;

    /**
     * @dev 移除费用白名单
     */
    function removeFfsWhitelist(address _wl) external;

    /**
     * @dev 设置费用接收地址
     */
    function setFeeJar(address _feeJar) external;

    /**
     * @dev 使用精确代币数量换取ETH
     */
    function swapExactTokensForETHAndFeeAmount(Trade calldata trade) external payable;

    /**
     * @dev 使用代币换取精确ETH数量
     */
    function swapTokensForExactETHAndFeeAmount(Trade calldata trade) external payable;

    /**
     * @dev 使用精确ETH数量换取代币
     */
    function swapExactETHForTokensWithFeeAmount(Trade calldata trade, uint256 _feeAmount) external payable;

    /**
     * @dev 使用ETH换取精确代币数量
     */
    function swapETHForExactTokensWithFeeAmount(Trade calldata trade, uint256 _feeAmount) external payable;

    /**
     * @dev 使用精确代币数量换取代币
     */
    function swapExactTokensForTokensWithFeeAmount(Trade calldata trade) external payable;

    /**
     * @dev 使用代币换取精确代币数量
     */
    function swapTokensForExactTokensWithFeeAmount(Trade calldata trade) external payable;

    /**
     * @dev 获取交换费用
     */
    function getSwapFee(
        uint256 amountIn,
        uint256 _amountOut,
        address tokenA,
        address tokenB
    ) external view returns (uint256 _fee);

    /**
     * @dev 获取费用明细
     */
    function getFees(
        address[] memory _path,
        uint256 _amountIn,
        address _address
    )
        external
        view
        returns (
            uint256 totalBNBFee,
            uint256 dexFee,
            uint256 tokenAFee,
            uint256 tokenBFee
        );

    /**
     * @dev 获取交换总费用
     */
    function getSwapFees(uint256 amountIn, address[] memory path) external view returns (uint256 _fees);
}

/**
 * @title Safemoon代币合约
 * @dev 实现了创新的DeFi代币经济学模型
 */
contract Safemoon is ISafemoon, Initializable, ContextUpgradeable, OwnableUpgradeable {
    using SafeMathUpgradeable for uint256;
    using AddressUpgradeable for address;

    /**
     * @dev 费用等级结构体
     * @param ecoSystemFee 生态系统费用
     * @param liquidityFee 流动性费用
     * @param taxFee 税费
     * @param ownerFee 所有者费用
     * @param burnFee 销毁费用
     * @param ecoSystem 生态系统地址
     * @param owner 所有者地址
     */
    struct FeeTier {
        uint256 ecoSystemFee;
        uint256 liquidityFee;
        uint256 taxFee;
        uint256 ownerFee;
        uint256 burnFee;
        address ecoSystem;
        address owner;
    }

    /**
     * @dev 费用值结构体
     * 用于存储反射和转账相关的费用数值
     */
    struct FeeValues {
        uint256 rAmount;        // 反射数量
        uint256 rTransferAmount;// 反射转账数量
        uint256 rFee;          // 反射费用
        uint256 tTransferAmount;// 代币转账数量
        uint256 tEchoSystem;   // 生态系统费用
        uint256 tLiquidity;    // 流动性费用
        uint256 tFee;          // 税费
        uint256 tOwner;        // 所有者费用
        uint256 tBurn;         // 销毁费用
    }

    /**
     * @dev 代币费用值结构体
     * 用于存储代币相关的费用数值
     */
    struct tFeeValues {
        uint256 tTransferAmount;// 转账数量
        uint256 tEchoSystem;   // 生态系统费用
        uint256 tLiquidity;    // 流动性费用
        uint256 tFee;          // 税费
        uint256 tOwner;        // 所有者费用
        uint256 tBurn;         // 销毁费用
    }

    // 外部合约接口
    IUniswapV2Router02 public uniswapV2Router;            // Uniswap V2路由器
    address public uniswapV2Pair;                         // Uniswap V2交易对
    address public WBNB;                                  // WBNB代币地址
    address private migration;                            // 迁移合约地址
    address private _initializerAccount;                  // 初始化账户
    address public _burnAddress;                          // 销毁地址

    bool inSwapAndLiquify;                               // 是否正在交换和注入流动性
    bool public swapAndLiquifyEnabled;                    // 是否启用交换和注入流动性

    uint256 public _maxTxAmount;                          // 最大交易数量
    uint256 private numTokensSellToAddToLiquidity;        // 触发添加流动性的代币数量

    bool private _upgraded;                               // 是否已升级

    event MinTokensBeforeSwapUpdated(uint256 minTokensBeforeSwap);

    /**
     * @dev 修饰符:锁定交换
     * 防止重入攻击
     */
    modifier lockTheSwap() {
        inSwapAndLiquify = true;
        _;
        inSwapAndLiquify = false;
    }

    /**
     * @dev 修饰符:锁定升级
     * 确保只能升级一次
     */
    modifier lockUpgrade() {
        require(!_upgraded, "Safemoon: 已经升级");
        _;
        _upgraded = true;
    }

    /**
     * @dev 修饰符:检查等级索引
     * 确保等级索引有效
     */
    modifier checkTierIndex(uint256 _index) {
        require(feeTiers.length > _index, "Safemoon: 无效的等级索引");
        _;
    }

    /**
     * @dev 修饰符:防止黑名单地址
     * 检查地址是否在黑名单中
     */
    modifier preventBlacklisted(address _account, string memory errorMsg) {
        require(!_isBlacklisted[_account], errorMsg);
        _;
    }

    /**
     * @dev 修饰符:检查是否是路由器
     * 自动识别并标记路由器地址
     */
    modifier isRouter(address _sender) {
        {
            uint32 size;
            assembly {
                size := extcodesize(_sender)
            }
            if (size > 0) {
                uint256 senderTier = _accountsTier[_sender];
                if (senderTier == 0) {
                    IUniswapV2Router02 _routerCheck = IUniswapV2Router02(_sender);
                    try _routerCheck.factory() returns (address factory) {
                        _accountsTier[_sender] = 1;
                    } catch {}
                }
            }
        }
        _;
    }

    // 状态变量
    uint256 public numTokensToCollectBNB;                 // 触发收集BNB的代币数量
    uint256 public numOfBnbToSwapAndEvolve;              // 触发交换和进化的BNB数量

    bool inSwapAndEvolve;                                // 是否正在交换和进化
    bool public swapAndEvolveEnabled;                     // 是否启用交换和进化

    /**
     * @dev 排除的总反射和代币数量
     * 用于优化getCurrentSupply函数的性能
     * 在合约升级时需要调用updateTotalExcluded来初始化这些值
     */
    uint256 private _rTotalExcluded;                      // 排除的总反射数量
    uint256 private _tTotalExcluded;                      // 排除的总代币数量

    // 映射
    mapping(address => bool) public listIgnoreCollectBNBAddresses; // 不触发收集BNB的地址列表
    address public bridgeBurnAddress;                     // 桥接销毁地址
    mapping(address => bool) public whitelistMint;        // 铸造白名单
    bool public isPaused;                                 // 是否暂停
    mapping(address => bool) public whitelistPause;       // 暂停白名单
    mapping(address => bool) public isSFMPair;            // SFM交易对

    // 事件
    event SwapAndEvolveEnabledUpdated(bool enabled);
    event SwapAndEvolve(uint256 bnbSwapped, uint256 tokenReceived, uint256 bnbIntoLiquidity);
    event AddIgnoreCollectBNBAddress(address ignoreAddress);
    event RemoveIgnoreCollectBNBAddress(address ignoreAddress);
    event WhitelistPause(address user, bool value);
    event SetSFMPair(address pair, bool value);
    event PauseContract(bool value);

    /**
     * @dev 修饰符:只允许铸造白名单
     */
    modifier onlyWhitelistMint() {
        require(whitelistMint[msg.sender], "无效");
        _;
    }

    /**
     * @dev 修饰符:合约未暂停时
     */
    modifier whenNotPaused() {
        require(!isPaused || whitelistPause[msg.sender], "已暂停");
        _;
    }

    // 状态变量
    mapping(address => uint256) private _rOwned;           // 地址拥有的反射数量
    mapping(address => uint256) private _tOwned;           // 地址拥有的代币数量
    mapping(address => mapping(address => uint256)) private _allowances;  // 授权映射
    mapping(address => bool) private _isExcludedFromFee;   // 免费名单
    mapping(address => bool) private _isExcluded;          // 排除名单
    mapping(address => bool) private _isBlacklisted;       // 黑名单
    mapping(address => uint256) private _accountsTier;     // 账户等级

    address[] private _excluded;                           // 排除地址数组

    uint256 private constant MAX = ~uint256(0);            // 最大uint256值
    uint256 private _tTotal;                              // 总代币数量
    uint256 private _rTotal;                              // 总反射数量
    uint256 private _tFeeTotal;                           // 总费用数量
    uint256 private _maxFee;                              // 最大费用

    string private _name;                                  // 代币名称
    string private _symbol;                                // 代币符号
    uint8 private _decimals;                              // 小数位数

    FeeTier public _defaultFees;                          // 默认费用
    FeeTier private _previousFees;                        // 之前的费用
    FeeTier private _emptyFees;                           // 空费用

    FeeTier[] private feeTiers;                           // 费用等级数组

    /**
     * @dev 初始化函数
     * 替代构造函数
     */
    function initialize() public initializer {
        __Context_init_unchained();
        __Ownable_init_unchained();
        __Safemoon_v2_init_unchained();
    }

    /**
     * @dev Safemoon V2初始化函数
     * 设置代币基本参数和初始状态
     */
    function __Safemoon_v2_init_unchained() internal initializer {
        _name = "SafeMoon";
        _symbol = "SFM";
        _decimals = 9;

        _tTotal = 1000000 * 10**6 * 10**9;
        _rTotal = (MAX - (MAX % _tTotal));
        _maxFee = 1000;

        _maxTxAmount = 5000 * 10**6 * 10**9;
        numTokensSellToAddToLiquidity = 500 * 10**6 * 10**9;

        _burnAddress = 0x000000000000000000000000000000000000dEaD;
        _initializerAccount = _msgSender();
        _rOwned[_initializerAccount] = _rTotal;

        // 排除所有者和合约地址的费用
        _isExcludedFromFee[owner()] = true;
        _isExcludedFromFee[address(this)] = true;

        // 初始化费用等级
        __Safemoon_tiers_init();

        emit Transfer(address(0), _msgSender(), _tTotal);
    }

    /**
     * @dev 初始化路由器和交易对
     * @param _router 路由器地址
     */
    function initRouterAndPair(address _router) external onlyOwner {
        uniswapV2Router = IUniswapV2Router02(_router);
        WBNB = uniswapV2Router.WETH();
        // 创建新的交易对
        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this), WBNB, address(this));
    }

    /**
     * @dev 初始化费用等级
     * 设置默认和其他费用等级
     */
    function __Safemoon_tiers_init() internal initializer {
        _defaultFees = _addTier(0, 500, 500, 0, 0, address(0), address(0));
        _addTier(50, 50, 100, 0, 0, address(0), address(0));
        _addTier(50, 50, 100, 100, 0, address(0), address(0));
        _addTier(100, 125, 125, 150, 0, address(0), address(0));
    }

    /**
     * @dev 返回代币名称
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev 返回代币符号
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev 返回代币小数位数
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev 返回代币总供应量
     */
    function totalSupply() public view override returns (uint256) {
        return _tTotal;
    }

    /**
     * @dev 返回账户余额
     * @param account 查询的账户地址
     */
    function balanceOf(address account) public view override returns (uint256) {
        if (_isExcluded[account]) return _tOwned[account];
        return tokenFromReflection(_rOwned[account]);
    }

    /**
     * @dev 转移代币
     * @param recipient 接收者地址
     * @param amount 转移数量
     */
    function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev 返回授权额度
     * @param owner 持有者地址
     * @param spender 被授权者地址
     */
    function allowance(address owner, address spender) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev 授权代币
     * @param spender 被授权者地址
     * @param amount 授权数量
     */
    function approve(address spender, uint256 amount) public override whenNotPaused returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev 通过授权转移代币
     * @param sender 发送者地址
     * @param recipient 接收者地址
     * @param amount 转移数量
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()].sub(amount, "BEP20: 转账金额超过授权额度")
        );
        return true;
    }

    /**
     * @dev 检查地址是否被排除在奖励之外
     * @param account 检查的地址
     */
    function isExcludedFromReward(address account) public view returns (bool) {
        return _isExcluded[account];
    }

    /**
     * @dev 返回总费用
     */
    function totalFees() public view returns (uint256) {
        return _tFeeTotal;
    }

    /**
     * @dev 计算特定等级的代币反射值
     * @param tAmount 代币数量
     * @param _tierIndex 等级索引
     * @param deductTransferFee 是否扣除转账费用
     */
    function reflectionFromTokenInTiers(
        uint256 tAmount,
        uint256 _tierIndex,
        bool deductTransferFee
    ) public view returns (uint256) {
        require(tAmount <= _tTotal, "金额必须小于总供应量");
        if (!deductTransferFee) {
            FeeValues memory _values = _getValues(tAmount, _tierIndex);
            return _values.rAmount;
        } else {
            FeeValues memory _values = _getValues(tAmount, _tierIndex);
            return _values.rTransferAmount;
        }
    }

    /**
     * @dev 计算代币的反射值
     * @param tAmount 代币数量
     * @param deductTransferFee 是否扣除转账费用
     */
    function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns (uint256) {
        return reflectionFromTokenInTiers(tAmount, 0, deductTransferFee);
    }

    /**
     * @dev 从反射值计算代币数量
     * @param rAmount 反射值
     */
    function tokenFromReflection(uint256 rAmount) public view returns (uint256) {
        require(rAmount <= _rTotal, "金额必须小于总反射值");
        uint256 currentRate = _getRate();
        return rAmount.div(currentRate);
    }

    /**
     * @dev 将地址排除在奖励之外
     * @param account 要排除的地址
     */
    function excludeFromReward(address account) public onlyOwner {
        require(!_isExcluded[account], "无效");
        if (_rOwned[account] > 0) {
            _tOwned[account] = tokenFromReflection(_rOwned[account]);
            _tTotalExcluded = _tTotalExcluded.add(_tOwned[account]);
            _rTotalExcluded = _rTotalExcluded.add(_rOwned[account]);
        }

        _isExcluded[account] = true;
        _excluded.push(account);
    }

    /**
     * @dev 将地址包含在奖励中
     * @param account 要包含的地址
     */
    function includeInReward(address account) external onlyOwner {
        require(_isExcluded[account], "无效");
        for (uint256 i = 0; i < _excluded.length; i++) {
            if (_excluded[i] == account) {
                _excluded[i] = _excluded[_excluded.length - 1];
                _rOwned[account] = _tOwned[account] * _getRate();
                _tTotalExcluded = _tTotalExcluded.sub(_tOwned[account]);
                _rTotalExcluded = _rTotalExcluded.sub(_rOwned[account]);
                _tOwned[account] = 0;
                _isExcluded[account] = false;
                _excluded.pop();
                break;
            }
        }
    }

    /**
     * @dev 将地址排除在费用之外
     * @param account 要排除的地址
     */
    function excludeFromFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = true;
    }

    /**
     * @dev 将地址包含在费用中
     * @param account 要包含的地址
     */
    function includeInFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = false;
    }

    /**
     * @dev 将地址添加到白名单
     * @param _account 要添加的地址
     * @param _tierIndex 费用等级索引
     */
    function whitelistAddress(address _account, uint256 _tierIndex)
        public
        onlyOwner
        checkTierIndex(_tierIndex)
        preventBlacklisted(_account, "Safemoon: 选择的账户在黑名单中")
    {
        require(_account != address(0), "Safemoon: 无效地址");
        _accountsTier[_account] = _tierIndex;
    }

    /**
     * @dev 将地址从白名单中移除
     * @param _account 要移除的地址
     */
    function excludeWhitelistedAddress(address _account) public onlyOwner {
        require(_account != address(0), "Safemoon: 无效地址");
        require(_accountsTier[_account] > 0, "Safemoon: 账户不在白名单中");
        _accountsTier[_account] = 0;
    }

    /**
     * @dev 获取账户的费用等级
     * @param _account 查询的账户地址
     */
    function accountTier(address _account) public view returns (FeeTier memory) {
        return feeTiers[_accountsTier[_account]];
    }

    /**
     * @dev 检查地址是否在白名单中
     * @param _account 检查的地址
     */
    function isWhitelisted(address _account) public view returns (bool) {
        return _accountsTier[_account] > 0;
    }

    /**
     * @dev 检查费用是否超过限制
     * @param _tier 费用等级
     */
    function checkFees(FeeTier memory _tier) internal view returns (FeeTier memory) {
        uint256 _fees = _tier.ecoSystemFee.add(_tier.liquidityFee).add(_tier.taxFee).add(_tier.ownerFee).add(
            _tier.burnFee
        );
        require(_fees <= _maxFee, "Safemoon: 费用超过最大限制");

        return _tier;
    }

    /**
     * @dev 检查费用变化是否合法
     * @param _tier 费用等级
     * @param _oldFee 旧费用
     * @param _newFee 新费用
     */
    function checkFeesChanged(
        FeeTier memory _tier,
        uint256 _oldFee,
        uint256 _newFee
    ) internal view {
        uint256 _fees = _tier
            .ecoSystemFee
            .add(_tier.liquidityFee)
            .add(_tier.taxFee)
            .add(_tier.ownerFee)
            .add(_tier.burnFee)
            .sub(_oldFee)
            .add(_newFee);

        require(_fees <= _maxFee, "Safemoon: 费用超过最大限制");
    }

    /**
     * @dev 设置生态系统费用百分比
     * @param _tierIndex 费用等级索引
     * @param _ecoSystemFee 新的生态系统费用
     */
    function setEcoSystemFeePercent(uint256 _tierIndex, uint256 _ecoSystemFee)
        external
        onlyOwner
        checkTierIndex(_tierIndex)
    {
        FeeTier memory tier = feeTiers[_tierIndex];
        checkFeesChanged(tier, tier.ecoSystemFee, _ecoSystemFee);
        feeTiers[_tierIndex].ecoSystemFee = _ecoSystemFee;
        if (_tierIndex == 0) {
            _defaultFees.ecoSystemFee = _ecoSystemFee;
        }
    }

    /**
     * @dev 设置流动性费用百分比
     * @param _tierIndex 费用等级索引
     * @param _liquidityFee 新的流动性费用
     */
    function setLiquidityFeePercent(uint256 _tierIndex, uint256 _liquidityFee)
        external
        onlyOwner
        checkTierIndex(_tierIndex)
    {
        FeeTier memory tier = feeTiers[_tierIndex];
        checkFeesChanged(tier, tier.liquidityFee, _liquidityFee);
        feeTiers[_tierIndex].liquidityFee = _liquidityFee;
        if (_tierIndex == 0) {
            _defaultFees.liquidityFee = _liquidityFee;
        }
    }

    /**
     * @dev 设置税费百分比
     * @param _tierIndex 费用等级索引
     * @param _taxFee 新的税费
     */
    function setTaxFeePercent(uint256 _tierIndex, uint256 _taxFee) external onlyOwner checkTierIndex(_tierIndex) {
        FeeTier memory tier = feeTiers[_tierIndex];
        checkFeesChanged(tier, tier.taxFee, _taxFee);
        feeTiers[_tierIndex].taxFee = _taxFee;
        if (_tierIndex == 0) {
            _defaultFees.taxFee = _taxFee;
        }
    }

    /**
     * @dev 设置所有者费用百分比
     * @param _tierIndex 费用等级索引
     * @param _ownerFee 新的所有者费用
     */
    function setOwnerFeePercent(uint256 _tierIndex, uint256 _ownerFee) external onlyOwner checkTierIndex(_tierIndex) {
        FeeTier memory tier = feeTiers[_tierIndex];
        checkFeesChanged(tier, tier.ownerFee, _ownerFee);
        feeTiers[_tierIndex].ownerFee = _ownerFee;
        if (_tierIndex == 0) {
            _defaultFees.ownerFee = _ownerFee;
        }
    }

    /**
     * @dev 设置销毁费用百分比
     * @param _tierIndex 费用等级索引
     * @param _burnFee 新的销毁费用
     */
    function setBurnFeePercent(uint256 _tierIndex, uint256 _burnFee) external onlyOwner checkTierIndex(_tierIndex) {
        FeeTier memory tier = feeTiers[_tierIndex];
        checkFeesChanged(tier, tier.burnFee, _burnFee);
        feeTiers[_tierIndex].burnFee = _burnFee;
        if (_tierIndex == 0) {
            _defaultFees.burnFee = _burnFee;
        }
    }

    /**
     * @dev 设置生态系统费用接收地址
     * @param _tierIndex 费用等级索引
     * @param _ecoSystem 新的生态系统地址
     */
    function setEcoSystemFeeAddress(uint256 _tierIndex, address _ecoSystem)
        external
        onlyOwner
        checkTierIndex(_tierIndex)
    {
        require(_ecoSystem != address(0), "Safemoon: 不允许零地址");
        excludeFromReward(_ecoSystem);
        feeTiers[_tierIndex].ecoSystem = _ecoSystem;
        if (_tierIndex == 0) {
            _defaultFees.ecoSystem = _ecoSystem;
        }
    }

    /**
     * @dev 设置所有者费用接收地址
     * @param _tierIndex 费用等级索引
     * @param _owner 新的所有者地址
     */
    function setOwnerFeeAddress(uint256 _tierIndex, address _owner) external onlyOwner checkTierIndex(_tierIndex) {
        require(_owner != address(0), "Safemoon: 不允许零地址");
        excludeFromReward(_owner);
        feeTiers[_tierIndex].owner = _owner;
        if (_tierIndex == 0) {
            _defaultFees.owner = _owner;
        }
    }

    /**
     * @dev 添加新的费用等级
     * @param _ecoSystemFee 生态系统费用
     * @param _liquidityFee 流动性费用
     * @param _taxFee 税费
     * @param _ownerFee 所有者费用
     * @param _burnFee 销毁费用
     * @param _ecoSystem 生态系统地址
     * @param _owner 所有者地址
     */
    function addTier(
        uint256 _ecoSystemFee,
        uint256 _liquidityFee,
        uint256 _taxFee,
        uint256 _ownerFee,
        uint256 _burnFee,
        address _ecoSystem,
        address _owner
    ) public onlyOwner {
        _addTier(_ecoSystemFee, _liquidityFee, _taxFee, _ownerFee, _burnFee, _ecoSystem, _owner);
    }

    /**
     * @dev 内部函数:添加新的费用等级
     */
    function _addTier(
        uint256 _ecoSystemFee,
        uint256 _liquidityFee,
        uint256 _taxFee,
        uint256 _ownerFee,
        uint256 _burnFee,
        address _ecoSystem,
        address _owner
    ) internal returns (FeeTier memory) {
        FeeTier memory _newTier = checkFees(
            FeeTier(_ecoSystemFee, _liquidityFee, _taxFee, _ownerFee, _burnFee, _ecoSystem, _owner)
        );
        excludeFromReward(_ecoSystem);
        excludeFromReward(_owner);
        feeTiers.push(_newTier);

        return _newTier;
    }

    /**
     * @dev 获取指定索引的费用等级
     * @param _tierIndex 费用等级索引
     */
    function feeTier(uint256 _tierIndex) public view checkTierIndex(_tierIndex) returns (FeeTier memory) {
        return feeTiers[_tierIndex];
    }

    /**
     * @dev 将地址添加到黑名单
     * @param account 要添加的地址
     */
    function blacklistAddress(address account) public onlyOwner {
        _isBlacklisted[account] = true;
        _accountsTier[account] = 0;
    }

    /**
     * @dev 将地址从黑名单中移除
     * @param account 要移除的地址
     */
    function unBlacklistAddress(address account) public onlyOwner {
        _isBlacklisted[account] = false;
    }

    /**
     * @dev 更新路由器和交易对地址
     * @param _uniswapV2Router 新的路由器地址
     * @param _uniswapV2Pair 新的交易对地址
     */
    function updateRouterAndPair(address _uniswapV2Router, address _uniswapV2Pair) public onlyOwner {
        uniswapV2Router = IUniswapV2Router02(_uniswapV2Router);
        uniswapV2Pair = _uniswapV2Pair;
        WBNB = uniswapV2Router.WETH();
    }

    /**
     * @dev 设置默认配置
     */
    function setDefaultSettings() external onlyOwner {
        swapAndLiquifyEnabled = false;
        swapAndEvolveEnabled = true;
    }

    /**
     * @dev 设置最大交易数量百分比
     * @param maxTxPercent 最大交易百分比
     */
    function setMaxTxPercent(uint256 maxTxPercent) external onlyOwner {
        _maxTxAmount = _tTotal.mul(maxTxPercent).div(10**4);
    }

    /**
     * @dev 设置是否启用交换和进化
     * @param _enabled 是否启用
     */
    function setSwapAndEvolveEnabled(bool _enabled) public onlyOwner {
        swapAndEvolveEnabled = _enabled;
        emit SwapAndEvolveEnabledUpdated(_enabled);
    }

    /**
     * @dev 接收BNB的回退函数
     */
    receive() external payable {}

    /**
     * @dev 反射费用
     * @param rFee 反射费用数量
     * @param tFee 代币费用数量
     */
    function _reflectFee(uint256 rFee, uint256 tFee) private {
        _rTotal = _rTotal.sub(rFee);
        _tFeeTotal = _tFeeTotal.add(tFee);
    }

    /**
     * @dev 获取转账相关的各种值
     * @param tAmount 代币数量
     * @param _tierIndex 费用等级索引
     */
    function _getValues(uint256 tAmount, uint256 _tierIndex) private view returns (FeeValues memory) {
        tFeeValues memory tValues = _getTValues(tAmount, _tierIndex);
        uint256 tTransferFee = tValues.tLiquidity.add(tValues.tEchoSystem).add(tValues.tOwner).add(tValues.tBurn);
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(
            tAmount,
            tValues.tFee,
            tTransferFee,
            _getRate()
        );
        return
            FeeValues(
                rAmount,
                rTransferAmount,
                rFee,
                tValues.tTransferAmount,
                tValues.tEchoSystem,
                tValues.tLiquidity,
                tValues.tFee,
                tValues.tOwner,
                tValues.tBurn
            );
    }

    /**
     * @dev 获取代币相关的费用值
     * @param tAmount 代币数量
     * @param _tierIndex 费用等级索引
     */
    function _getTValues(uint256 tAmount, uint256 _tierIndex) private view returns (tFeeValues memory) {
        FeeTier memory tier = feeTiers[_tierIndex];
        tFeeValues memory tValues = tFeeValues(
            0,
            calculateFee(tAmount, tier.ecoSystemFee),
            calculateFee(tAmount, tier.liquidityFee),
            calculateFee(tAmount, tier.taxFee),
            calculateFee(tAmount, tier.ownerFee),
            calculateFee(tAmount, tier.burnFee)
        );

        tValues.tTransferAmount = tAmount
            .sub(tValues.tEchoSystem)
            .sub(tValues.tFee)
            .sub(tValues.tLiquidity)
            .sub(tValues.tOwner)
            .sub(tValues.tBurn);

        return tValues;
    }

    /**
     * @dev 获取反射相关的值
     * @param tAmount 代币数量
     * @param tFee 代币费用
     * @param tTransferFee 转账费用
     * @param currentRate 当前汇率
     */
    function _getRValues(
        uint256 tAmount,
        uint256 tFee,
        uint256 tTransferFee,
        uint256 currentRate
    )
        private
        pure
        returns (
            uint256,
            uint256,
            uint256
        )
    {
        uint256 rAmount = tAmount.mul(currentRate);
        uint256 rFee = tFee.mul(currentRate);
        uint256 rTransferFee = tTransferFee.mul(currentRate);
        uint256 rTransferAmount = rAmount.sub(rFee).sub(rTransferFee);
        return (rAmount, rTransferAmount, rFee);
    }

    /**
     * @dev 获取当前汇率
     * @return uint256 当前汇率
     */
    function _getRate() private view returns (uint256) {
        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
        return rSupply.div(tSupply);
    }

    /**
     * @dev 获取当前供应量
     * @return uint256, uint256 当前反射供应量和代币供应量
     */
    function _getCurrentSupply() private view returns (uint256, uint256) {
        if (_rTotalExcluded > _rTotal || _tTotalExcluded > _tTotal) {
            return (_rTotal, _tTotal);
        }
        uint256 rSupply = _rTotal.sub(_rTotalExcluded);
        uint256 tSupply = _tTotal.sub(_tTotalExcluded);

        if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);

        return (rSupply, tSupply);
    }

    /**
     * @dev 计算费用
     * @param _amount 金额
     * @param _fee 费率
     * @return uint256 费用金额
     */
    function calculateFee(uint256 _amount, uint256 _fee) private pure returns (uint256) {
        if (_fee == 0) return 0;
        return _amount.mul(_fee).div(10**4);
    }

    /**
     * @dev 移除所有费用
     */
    function removeAllFee() private {
        _previousFees = feeTiers[0];
        feeTiers[0] = _emptyFees;
    }

    /**
     * @dev 恢复所有费用
     */
    function restoreAllFee() private {
        feeTiers[0] = _previousFees;
    }

    /**
     * @dev 检查地址是否被排除在费用之外
     * @param account 检查的地址
     */
    function isExcludedFromFee(address account) public view returns (bool) {
        return _isExcludedFromFee[account];
    }

    /**
     * @dev 检查地址是否在黑名单中
     * @param account 检查的地址
     */
    function isBlacklisted(address account) public view returns (bool) {
        return _isBlacklisted[account];
    }

    /**
     * @dev 批准代币授权
     * @param owner 持有者地址
     * @param spender 被授权者地址
     * @param amount 授权数量
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    )
        private
        preventBlacklisted(owner, "Safemoon: 所有者地址在黑名单中")
        preventBlacklisted(spender, "Safemoon: 被授权者地址在黑名单中")
    {
        require(owner != address(0), "BEP20: 从零地址授权");
        require(spender != address(0), "BEP20: 授权给零地址");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev 转移代币
     * @param from 发送者地址
     * @param to 接收者地址
     * @param amount 转移数量
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    )
        private
        preventBlacklisted(_msgSender(), "Safemoon: 地址在黑名单中")
        preventBlacklisted(from, "Safemoon: 发送者地址在黑名单中")
        preventBlacklisted(to, "Safemoon: 接收者地址在黑名单中")
        isRouter(_msgSender())
    {
        require(from != address(0), "BEP20: 从零地址转账");
        require(to != address(0), "BEP20: 转账到零地址");
        require(amount > 0, "转账金额必须大于零");
        require(_canAction(from, to), "已暂停");

        if (from != owner() && to != owner())
            require(amount <= _maxTxAmount, "转账金额超过最大限制");

        // 检查合约代币余额是否超过触发自动流动性的阈值
        uint256 contractTokenBalance = balanceOf(address(this));

        if (contractTokenBalance >= _maxTxAmount) {
            contractTokenBalance = _maxTxAmount;
        }

        bool overMinTokenBalance = contractTokenBalance >= numTokensToCollectBNB;
        if (
            overMinTokenBalance &&
            !inSwapAndLiquify &&
            swapAndEvolveEnabled &&
            !_isInCollectBNBWhitelist(from) &&
            !_isInCollectBNBWhitelist(to)
        ) {
            contractTokenBalance = numTokensToCollectBNB;
            collectBNB(contractTokenBalance);
        }

        // 是否收取费用
        bool takeFee = true;

        // 如果地址在免费名单中则不收取费用
        if (_isExcludedFromFee[from] || _isExcludedFromFee[to]) {
            takeFee = false;
        }

        uint256 tierIndex = 0;

        if (takeFee) {
            tierIndex = _accountsTier[from];

            if (_msgSender() != from) {
                tierIndex = _accountsTier[_msgSender()];
            }
        }

        // 转移代币
        _tokenTransfer(from, to, amount, tierIndex, takeFee);
    }

    /**
     * @dev 检查是否可以执行操作
     * @param from 发送者地址
     * @param to 接收者地址
     */
    function _canAction(address from, address to) private view returns (bool) {
        if (!isPaused) {
            return true;
        }
        if (whitelistPause[from] && whitelistPause[to]) {
            return true;
        }
        if (whitelistPause[from] && !isSFMPair[from]) {
            return true;
        }
        return false;
    }

    /**
     * @dev 收集BNB
     * @param contractTokenBalance 合约代币余额
     */
    function collectBNB(uint256 contractTokenBalance) private lockTheSwap {
        swapTokensForBnb(contractTokenBalance);
    }

    /**
     * @dev 将代币换成BNB
     * @param tokenAmount 代币数量
     */
    function swapTokensForBnb(uint256 tokenAmount) private {
        // 生成交易路径:token -> wbnb
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

        ISafeSwapTradeRouter tradeRouter = ISafeSwapTradeRouter(uniswapV2Router.routerTrade());

        // 获取费用
        uint256 feeAmount = tradeRouter.getSwapFees(tokenAmount, path);

        _approve(address(this), address(uniswapV2Router), tokenAmount);
        _approve(address(this), address(tradeRouter), tokenAmount);
        ISafeSwapTradeRouter.Trade memory trade = ISafeSwapTradeRouter.Trade({
            amountIn: tokenAmount,
            amountOut: 0,
            path: path,
            to: payable(address(this)),
            deadline: block.timestamp
        });
        tradeRouter.swapExactTokensForETHAndFeeAmount{ value: feeAmount }(trade);
    }

    /**
     * @dev 交换和进化
     * 将合约中的BNB分成两半,一半用于购买代币,另一半用于添加流动性
     */
    function swapAndEvolve() public onlyOwner lockTheSwap {
        // 将合约余额分成两半
        uint256 contractBnbBalance = address(this).balance;
        require(contractBnbBalance >= numOfBnbToSwapAndEvolve, "BNB余额未达到交换和进化阈值");

        contractBnbBalance = numOfBnbToSwapAndEvolve;

        uint256 half = contractBnbBalance.div(2);
        uint256 otherHalf = contractBnbBalance.sub(half);

        // 记录当前余额
        uint256 initialBalance = ISafemoon(address(this)).balanceOf(msg.sender);
        
        // 用BNB换取代币
        swapBnbForTokens(half);

        // 计算获得的代币数量
        uint256 newBalance = ISafemoon(address(this)).balanceOf(msg.sender);
        uint256 swapeedToken = newBalance.sub(initialBalance);

        // 添加流动性
        _approve(msg.sender, address(this), swapeedToken);
        ISafemoon(address(this)).transferFrom(msg.sender, address(this), swapeedToken);
        addLiquidity(swapeedToken, otherHalf);
        
        emit SwapAndEvolve(half, swapeedToken, otherHalf);
    }

    /**
     * @dev 用BNB换取代币
     * @param bnbAmount BNB数量
     */
    function swapBnbForTokens(uint256 bnbAmount) private {
        // 生成交易路径:wbnb -> token
        address[] memory path = new address[](2);
        path[0] = uniswapV2Router.WETH();
        path[1] = address(this);

        ISafeSwapTradeRouter tradeRouter = ISafeSwapTradeRouter(uniswapV2Router.routerTrade());
        _approve(owner(), address(uniswapV2Router), bnbAmount);

        // 获取费用
        uint256 feeAmount = tradeRouter.getSwapFees(bnbAmount, path);
        ISafeSwapTradeRouter.Trade memory trade = ISafeSwapTradeRouter.Trade({
            amountIn: bnbAmount,
            amountOut: 0,
            path: path,
            to: payable(owner()),
            deadline: block.timestamp
        });
        tradeRouter.swapExactETHForTokensWithFeeAmount{ value: bnbAmount + feeAmount }(trade, feeAmount);
    }

    /**
     * @dev 添加流动性
     * @param tokenAmount 代币数量
     * @param bnbAmount BNB数量
     */
    function addLiquidity(uint256 tokenAmount, uint256 bnbAmount) private {
        // 批准代币转账
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // 添加流动性
        uniswapV2Router.addLiquidityETH{ value: bnbAmount }(
            address(this),
            tokenAmount,
            0, // 滑点不可避免
            0, // 滑点不可避免
            owner(),
            block.timestamp
        );
    }

    /**
     * @dev 代币转账
     * 处理所有费用的收取
     * @param sender 发送者地址
     * @param recipient 接收者地址
     * @param amount 转账数量
     * @param tierIndex 费用等级索引
     * @param takeFee 是否收取费用
     */
    function _tokenTransfer(
        address sender,
        address recipient,
        uint256 amount,
        uint256 tierIndex,
        bool takeFee
    ) private {
        if (!takeFee) removeAllFee();

        if (!_isExcluded[sender] && !_isExcluded[recipient]) {
            _transferStandard(sender, recipient, amount, tierIndex);
        } else if (_isExcluded[sender] && !_isExcluded[recipient]) {
            _transferFromExcluded(sender, recipient, amount, tierIndex);
        } else if (!_isExcluded[sender] && _isExcluded[recipient]) {
            _transferToExcluded(sender, recipient, amount, tierIndex);
        } else if (_isExcluded[sender] && _isExcluded[recipient]) {
            _transferBothExcluded(sender, recipient, amount, tierIndex);
        }

        if (!takeFee) restoreAllFee();
    }

    /**
     * @dev 在排除列表中的两个地址之间转账
     * @param sender 发送者地址
     * @param recipient 接收者地址
     * @param tAmount 转账数量
     * @param tierIndex 费用等级索引
     */
    function _transferBothExcluded(
        address sender,
        address recipient,
        uint256 tAmount,
        uint256 tierIndex
    ) private {
        FeeValues memory _values = _getValues(tAmount, tierIndex);
        _tOwned[sender] = _tOwned[sender].sub(tAmount);
        _tOwned[recipient] = _tOwned[recipient].add(_values.tTransferAmount);

        if (_values.tTransferAmount > tAmount) {
            uint256 tmpValue = _values.tTransferAmount - tAmount;
            _tTotalExcluded = _tTotalExcluded.add(tmpValue);
        } else {
            uint256 tmpValue = tAmount - _values.tTransferAmount;
            _tTotalExcluded = _tTotalExcluded.sub(tmpValue);
        }
        if (_values.rTransferAmount > _values.rAmount) {
            uint256 tmpValue = _values.rTransferAmount - _values.rAmount;
            _rTotalExcluded = _rTotalExcluded.add(tmpValue);
        } else {
            uint256 tmpValue = _values.rAmount - _values.rTransferAmount;
            _rTotalExcluded = _rTotalExcluded.sub(tmpValue);
        }

        _takeFees(sender, _values, tierIndex);
        _reflectFee(_values.rFee, _values.tFee);
        emit Transfer(sender, recipient, _values.tTransferAmount);
    }

    /**
     * @dev 标准转账
     * @param sender 发送者地址
     * @param recipient 接收者地址
     * @param tAmount 转账数量
     * @param tierIndex 费用等级索引
     */
    function _transferStandard(
        address sender,
        address recipient,
        uint256 tAmount,
        uint256 tierIndex
    ) private {
        FeeValues memory _values = _getValues(tAmount, tierIndex);
        _rOwned[sender] = _rOwned[sender].sub(_values.rAmount);
        _rOwned[recipient] = _rOwned[recipient].add(_values.rTransferAmount);
        _takeFees(sender, _values, tierIndex);
        _reflectFee(_values.rFee, _values.tFee);
        emit Transfer(sender, recipient, _values.tTransferAmount);
    }

    /**
     * @dev 向排除列表中的地址转账
     * @param sender 发送者地址
     * @param recipient 接收者地址
     * @param tAmount 转账数量
     * @param tierIndex 费用等级索引
     */
    function _transferToExcluded(
        address sender,
        address recipient,
        uint256 tAmount,
        uint256 tierIndex
    ) private {
        FeeValues memory _values = _getValues(tAmount, tierIndex);
        _rOwned[sender] = _rOwned[sender].sub(_values.rAmount);
        _tOwned[recipient] = _tOwned[recipient].add(_values.tTransferAmount);
        _tTotalExcluded = _tTotalExcluded.add(_values.tTransferAmount);
        _rTotalExcluded = _rTotalExcluded.add(_values.rTransferAmount);

        _takeFees(sender, _values, tierIndex);
        _reflectFee(_values.rFee, _values.tFee);
        emit Transfer(sender, recipient, _values.tTransferAmount);
    }

    /**
     * @dev 从排除列表中的地址转账
     * @param sender 发送者地址
     * @param recipient 接收者地址
     * @param tAmount 转账数量
     * @param tierIndex 费用等级索引
     */
    function _transferFromExcluded(
        address sender,
        address recipient,
        uint256 tAmount,
        uint256 tierIndex
    ) private {
        FeeValues memory _values = _getValues(tAmount, tierIndex);
        _tOwned[sender] = _tOwned[sender].sub(tAmount);
        _rOwned[recipient] = _rOwned[recipient].add(_values.rTransferAmount);
        _tTotalExcluded = _tTotalExcluded.sub(tAmount);
        _rTotalExcluded = _rTotalExcluded.sub(_values.rAmount);

        _takeFees(sender, _values, tierIndex);
        _reflectFee(_values.rFee, _values.tFee);
        emit Transfer(sender, recipient, _values.tTransferAmount);
    }

    /**
     * @dev 收取费用
     * @param sender 发送者地址
     * @param values 费用值
     * @param tierIndex 费用等级索引
     */
    function _takeFees(
        address sender,
        FeeValues memory values,
        uint256 tierIndex
    ) private {
        _takeFee(sender, values.tLiquidity, address(this));
        _takeFee(sender, values.tEchoSystem, feeTiers[tierIndex].ecoSystem);
        _takeFee(sender, values.tOwner, feeTiers[tierIndex].owner);
        _takeBurn(sender, values.tBurn);
    }

    /**
     * @dev 收取费用
     * @param sender 发送者地址
     * @param tAmount 代币数量
     * @param recipient 接收者地址
     */
    function _takeFee(
        address sender,
        uint256 tAmount,
        address recipient
    ) private {
        if (recipient == address(0)) return;
        if (tAmount == 0) return;

        uint256 currentRate = _getRate();
        uint256 rAmount = tAmount.mul(currentRate);
        _rOwned[recipient] = _rOwned[recipient].add(rAmount);

        if (_isExcluded[recipient]) {
            _tOwned[recipient] = _tOwned[recipient].add(tAmount);
            _tTotalExcluded = _tTotalExcluded.add(tAmount);
            _rTotalExcluded = _rTotalExcluded.add(rAmount);
        }

        emit Transfer(sender, recipient, tAmount);
    }

    /**
     * @dev 销毁代币
     * @param sender 发送者地址
     * @param _amount 销毁数量
     */
    function _takeBurn(address sender, uint256 _amount) private {
        if (_amount == 0) return;
        _tOwned[_burnAddress] = _tOwned[_burnAddress].add(_amount);
        uint256 _rAmount = _amount * _getRate();
        _rOwned[_burnAddress] = _rOwned[_burnAddress].add(_rAmount);
        if (_isExcluded[_burnAddress]) {
            _rTotalExcluded = _rTotalExcluded.add(_rAmount);
            _tTotalExcluded = _tTotalExcluded.add(_amount);
        }

        emit Transfer(sender, _burnAddress, _amount);
    }

    /**
     * @dev 设置迁移地址
     * @param _migration 迁移合约地址
     */
    function setMigrationAddress(address _migration) public onlyOwner {
        migration = _migration;
    }

    /**
     * @dev 检查是否开始迁移
     */
    function isMigrationStarted() external view override returns (bool) {
        return migration != address(0);
    }

    /**
     * @dev 迁移代币
     * @param account 账户地址
     * @param amount 迁移数量
     */
    function migrate(address account, uint256 amount)
        external
        override
        preventBlacklisted(account, "Safemoon: 迁移账户在黑名单中")
    {
        require(migration != address(0), "Safemoon: 迁移未开始");
        require(_msgSender() == migration, "Safemoon: 不允许");
        _migrate(account, amount);
    }

    /**
     * @dev 内部迁移函数
     * @param account 账户地址
     * @param amount 迁移数量
     */
    function _migrate(address account, uint256 amount) private {
        require(account != address(0), "BEP20: 铸造到零地址");
        _tokenTransfer(owner(), account, amount, 0, false);
    }

    /**
     * @dev 返回费用等级数量
     */
    function feeTiersLength() public view returns (uint256) {
        return feeTiers.length;
    }

    /**
     * @dev 更新销毁地址
     * @param _newBurnAddress 新的销毁地址
     */
    function updateBurnAddress(address _newBurnAddress) external onlyOwner {
        _burnAddress = _newBurnAddress;
        excludeFromReward(_newBurnAddress);
    }

    /**
     * @dev 提取代币
     * @param _token 代币地址
     * @param _amount 提取数量
     */
    function withdrawToken(address _token, uint256 _amount) public onlyOwner {
        ISafemoon(_token).transfer(msg.sender, _amount);
    }

    /**
     * @dev 设置触发收集BNB的代币数量
     * @param _numToken 代币数量
     */
    function setNumberOfTokenToCollectBNB(uint256 _numToken) public onlyOwner {
        numTokensToCollectBNB = _numToken;
    }

    /**
     * @dev 设置触发交换和进化的BNB数量
     * @param _numBnb BNB数量
     */
    function setNumOfBnbToSwapAndEvolve(uint256 _numBnb) public onlyOwner {
        numOfBnbToSwapAndEvolve = _numBnb;
    }

    /**
     * @dev 提取BNB
     * @param _amount 提取数量
     */
    function withdrawBnb(uint256 _amount) public onlyOwner {
        payable(msg.sender).transfer(_amount);
    }

    /**
     * @dev 添加不触发收集BNB的地址列表
     * @param _addresses 地址列表
     */
    function addListIgnoreCollectBNBOnTransferAddresses(address[] calldata _addresses) external onlyOwner {
        uint256 len = _addresses.length;
        for (uint256 i = 0; i < len; i++) {
            address addr = _addresses[i];
            if (listIgnoreCollectBNBAddresses[addr]) continue;

            listIgnoreCollectBNBAddresses[addr] = true;
            emit AddIgnoreCollectBNBAddress(addr);
        }
    }

    /**
     * @dev 移除不触发收集BNB的地址列表
     * @param _addresses 地址列表
     */
    function removeListIgnoreCollectBNBOnTransferAddresses(address[] calldata _addresses) external onlyOwner {
        uint256 len = _addresses.length;
        for (uint256 i = 0; i < len; i++) {
            address addr = _addresses[i];
            if (!listIgnoreCollectBNBAddresses[addr]) continue;

            listIgnoreCollectBNBAddresses[addr] = false;
            emit RemoveIgnoreCollectBNBAddress(addr);
        }
    }

    /**
     * @dev 检查地址是否在不触发收集BNB的白名单中
     * @param _addr 检查的地址
     */
    function _isInCollectBNBWhitelist(address _addr) private view returns (bool) {
        return listIgnoreCollectBNBAddresses[_addr];
    }

    /**
     * @dev 设置桥接销毁地址
     * @param _burn 销毁地址
     */
    function setBridgeBurnAddress(address _burn) public onlyOwner {
        bridgeBurnAddress = _burn;
    }

    /**
     * @dev 设置铸造销毁白名单
     * @param _wl 白名单地址
     * @param value 是否启用
     */
    function setWhitelistMintBurn(address _wl, bool value) public onlyOwner {
        whitelistMint[_wl] = value;
    }

    /**
     * @dev 铸造代币
     * @param user 接收者地址
     * @param amount 铸造数量
     */
    function mint(address user, uint256 amount) public whenNotPaused onlyWhitelistMint {
        if (msg.sender != owner()) {
            require(amount <= _maxTxAmount, "转账金额超过最大限制");
        }
        _tokenTransfer(bridgeBurnAddress, user, amount, 0, false);
    }

    /**
     * @dev 销毁代币
     * @param amount 销毁数量
     */
    function burn(uint256 amount) public whenNotPaused onlyWhitelistMint {
        if (msg.sender != owner()) {
            require(amount <= _maxTxAmount, "转账金额超过最大限制");
        }
        _tokenTransfer(msg.sender, bridgeBurnAddress, amount, 0, false);
    }

    /**
     * @dev 设置暂停白名单
     * @param user 用户地址
     * @param value 是否启用
     */
    function setWhitelistPause(address user, bool value) public onlyOwner {
        whitelistPause[user] = value;
        emit WhitelistPause(user, value);
    }
} 

About

Safemoon代币开发、代币开发、通缩代币开发、税收代币开发、自动流动性池代币-Safemoon类型原理分析、代码逐行分析 |DAPP开发定制|合约设计|快速上线|TG:recoverybtc

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors