通缩币代码注释-爱生活的程序员

通缩币代码注释

依赖@openzeppelin/contracts:3.3.0。
剩下的三个依赖都是UniswapV2中的。

// SPDX-License-Identifier: Unlicensed
pragma solidity ^0.6.12;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/EnumerableSet.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./IUniswapV2Factory.sol";
import "./IUniswapV2Pair.sol";
import "./IUniswapV2Router02.sol";


contract WKM is Context, IERC20, Ownable {
    using SafeMath for uint256;
    using Address for address;

    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; // 排除列表
    address[] private _excluded; // 排除列表
   
    uint256 private constant MAX = ~uint256(0);
    uint256 private _tTotal = 1000000000 * 10**6 * 10**9; // 排除流通量[实际流通量]
    uint256 private _rTotal = (MAX - (MAX % _tTotal)); // 默认余额
    uint256 private _tFeeTotal; // 累计手续费

    string private _name = "WKMoon";
    string private _symbol = "WKM";
    uint8 private _decimals = 9;
    
    uint256 public _taxFee = 5;
    uint256 private _previousTaxFee = _taxFee;
    
    uint256 public _liquidityFee = 5;
    uint256 private _previousLiquidityFee = _liquidityFee;

    IUniswapV2Router02 public immutable uniswapV2Router;
    address public immutable uniswapV2Pair;
    
    bool inSwapAndLiquify;
    bool public swapAndLiquifyEnabled = true;
    
    uint256 public _maxTxAmount = 5000000 * 10**6 * 10**9; // 最大持有手续费 
    uint256 private numTokensSellToAddToLiquidity = 500000 * 10**6 * 10**9; // 大于该值可进行添加Uni流动性
    
    event MinTokensBeforeSwapUpdated(uint256 minTokensBeforeSwap);
    event SwapAndLiquifyEnabledUpdated(bool enabled);
    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensIntoLiqudity
    );
    // 添加流动性操作锁,防止重入
    modifier lockTheSwap {
        inSwapAndLiquify = true;
        _;
        inSwapAndLiquify = false;
    }
    
    constructor (address router) public {
        _rOwned[_msgSender()] = _rTotal;  // 把币mint给创建者

        // #如果router地址不是swapRouter地址合约部署不成功
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(router);
        // 创建在Uniswap上的 该Token兑换ETH的交易对
        uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
            .createPair(address(this), _uniswapV2Router.WETH());

        // set the rest of the contract variables
        uniswapV2Router = _uniswapV2Router;
        
        // 合约创建者和该合约交易不需要手续费
        _isExcludedFromFee[owner()] = true; 
        _isExcludedFromFee[address(this)] = true; 
        
        emit Transfer(address(0), _msgSender(), _tTotal);
    }
    // 名称
    function name() public view returns (string memory) {
        return _name;
    }
    // 缩写
    function symbol() public view returns (string memory) {
        return _symbol;
    }
    // 精度
    function decimals() public view returns (uint8) {
        return _decimals;
    }
    // 流通量
    function totalSupply() public view override returns (uint256) {
        return _tTotal;
    }
    // 余额
    function balanceOf(address account) public view override returns (uint256) {
        // 用户是否被排除 
        if (_isExcluded[account]) return _tOwned[account]; // 为排除余额
        return tokenFromReflection(_rOwned[account]); // 用默认余额计算实际余额
    }
    // 转账
    function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }
    // 查询授权
    function allowance(address owner, address spender) public view override returns (uint256) {
        return _allowances[owner][spender];
    }
    // 授权
    function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }
    // 授权转账
    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }
    // 增加授权
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }
    // 减少授权
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }
    // 是否被排除
    function isExcludedFromReward(address account) public view returns (bool) {
        return _isExcluded[account];
    }
    // 累计手续费
    function totalFees() public view returns (uint256) {
        return _tFeeTotal;
    }
    // 用户把余额变成手续费
    function deliver(uint256 tAmount) public {
        address sender = _msgSender(); // 操作人
        // 排除地址不能进行操作
        require(!_isExcluded[sender], "Excluded addresses cannot call this function");
        // 计算对应的默认数量
        (uint256 rAmount,,,,,) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount); // 扣除余额
        _rTotal = _rTotal.sub(rAmount); // 减少流通量
        _tFeeTotal = _tFeeTotal.add(tAmount); // 添加手续费总量
    }
    // 计算排除数量对应的默认数量 或者到账的默认数量
    function reflectionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) {
        require(tAmount <= _tTotal, "Amount must be less than supply");
        if (!deductTransferFee) {
            (uint256 rAmount,,,,,) = _getValues(tAmount);
            return rAmount;
        } else {
            (,uint256 rTransferAmount,,,,) = _getValues(tAmount);
            return rTransferAmount;
        }
    }
    // 计算实际余额
    function tokenFromReflection(uint256 rAmount) public view returns(uint256) {
        require(rAmount <= _rTotal, "Amount must be less than total reflections");
        uint256 currentRate =  _getRate();
        return rAmount.div(currentRate);
    }
    // 把一个账户进行排除操作
    function excludeFromReward(address account) public onlyOwner() {
        // require(account != 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, 'We can not exclude Uniswap router.');
        require(!_isExcluded[account], "Account is already excluded");
        if(_rOwned[account] > 0) {
            _tOwned[account] = tokenFromReflection(_rOwned[account]);
        }
        _isExcluded[account] = true;
        _excluded.push(account);
    }
    // 取消一个排除账户的排除状态
    function includeInReward(address account) external onlyOwner() {
        require(_isExcluded[account], "Account is already excluded");
        for (uint256 i = 0; i < _excluded.length; i++) {
            if (_excluded[i] == account) {
                _excluded[i] = _excluded[_excluded.length - 1];
                _tOwned[account] = 0; // 排除余额变成0
                _isExcluded[account] = false;
                _excluded.pop();
                break;
            }
        }
    }
    // 不收用户手续费
    function excludeFromFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = true;
    }
    // 收用户手续费
    function includeInFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = false;
    }
    // 查询是否收用户手续费 true不收
    function isExcludedFromFee(address account) public view returns(bool) {
        return _isExcludedFromFee[account];
    }
    // 设置转账手续费
    function setTaxFeePercent(uint256 taxFee) external onlyOwner() {
        _taxFee = taxFee;
    }
    // 设置流动性手续费
    function setLiquidityFeePercent(uint256 liquidityFee) external onlyOwner() {
        _liquidityFee = liquidityFee;
    }
    // 设置最大接收手续费的手续百分比
    function setMaxTxPercent(uint256 maxTxPercent) external onlyOwner() {
        _maxTxAmount = _tTotal.mul(maxTxPercent).div(
            10**2
        );
    }
    // 是否添加Uni流动性
    function setSwapAndLiquifyEnabled(bool _enabled) public onlyOwner {
        swapAndLiquifyEnabled = _enabled;
        emit SwapAndLiquifyEnabledUpdated(_enabled);
    }
    
    // 接受ETH
    receive() external payable {}
    // 把默认余额转换到排除余额
    function _reflectFee(uint256 rFee, uint256 tFee) private {
        _rTotal = _rTotal.sub(rFee);
        _tFeeTotal = _tFeeTotal.add(tFee);
    }
    // 计算排除数量的 默认数量 默认到账数量 默认转账手续费 排除到账数量 排除转账手续费 排除流动性费用
    function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256, uint256) {
        // 交易手续费 流动性手续费 到账数量
        (uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getTValues(tAmount); 
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, tLiquidity, _getRate());
        return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee, tLiquidity);
    }
    // 用排除数量计算交易的 交易手续费 流动性手续费 到账数量
    function _getTValues(uint256 tAmount) private view returns (uint256, uint256, uint256) {
        uint256 tFee = calculateTaxFee(tAmount); // 计算交易手续费
        uint256 tLiquidity = calculateLiquidityFee(tAmount); // 计算流动性手续费
        uint256 tTransferAmount = tAmount.sub(tFee).sub(tLiquidity); // 到账数量
        return (tTransferAmount, tFee, tLiquidity);
    }
    // 把排除的[数量、到账手续费、交易手续费]计算出对应的默认数量
    function _getRValues(uint256 tAmount, uint256 tFee, uint256 tLiquidity, uint256 currentRate) private pure returns (uint256, uint256, uint256) {
        uint256 rAmount = tAmount.mul(currentRate); // 用排除数量计算默认数量
        uint256 rFee = tFee.mul(currentRate); // 排除手续费计算默认手续费
        uint256 rLiquidity = tLiquidity.mul(currentRate); // 流动性手续费计算排除流动性手续费
        uint256 rTransferAmount = rAmount.sub(rFee).sub(rLiquidity); // 到账数量
        return (rAmount, rTransferAmount, rFee);
    }
    // 获取默认流通量和排除流通量的比例
    function _getRate() private view returns(uint256) {
        (uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
        return rSupply.div(tSupply);
    }
    // 计算有效的默认流通量和排除流通量
    function _getCurrentSupply() private view returns(uint256, uint256) {
        uint256 rSupply = _rTotal; // 默认流通量
        uint256 tSupply = _tTotal; // 排除流通量
        for (uint256 i = 0; i < _excluded.length; i++) { // 循环排除列表
            // 用户余额大于流通量
            if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (_rTotal, _tTotal);
            rSupply = rSupply.sub(_rOwned[_excluded[i]]); // 去除排除用户的默认流通量
            tSupply = tSupply.sub(_tOwned[_excluded[i]]); // 去除排除用户的排除流通量
        }
        // 默认流通量 小于 实际流通量
        if (rSupply < _rTotal.div(_tTotal)) return (_rTotal, _tTotal);
        return (rSupply, tSupply);
    }
    // 添加流动性 用于在Uni上添加流动性
    function _takeLiquidity(uint256 tLiquidity) private {
        uint256 currentRate =  _getRate();
        uint256 rLiquidity = tLiquidity.mul(currentRate); // 计算对应的默认数量
        _rOwned[address(this)] = _rOwned[address(this)].add(rLiquidity); // 把这部分数量给合约
        if(_isExcluded[address(this)]) // 如果合约被排除
            _tOwned[address(this)] = _tOwned[address(this)].add(tLiquidity); // 添加排除余额
    }
    // 计算转账需要的手续费
    function calculateTaxFee(uint256 _amount) private view returns (uint256) {
        return _amount.mul(_taxFee).div(
            10**2
        );
    }
    // 计算流动性手续费
    function calculateLiquidityFee(uint256 _amount) private view returns (uint256) {
        return _amount.mul(_liquidityFee).div(
            10**2
        );
    }
    // 设置手续费率为0并备份
    function removeAllFee() private {
        if(_taxFee == 0 && _liquidityFee == 0) return;
        
        _previousTaxFee = _taxFee;
        _previousLiquidityFee = _liquidityFee;
        
        _taxFee = 0;
        _liquidityFee = 0;
    }
    // 恢复手续费率
    function restoreAllFee() private {
        _taxFee = _previousTaxFee;
        _liquidityFee = _previousLiquidityFee;
    }
    
    // 授权
    function _approve(address owner, address spender, uint256 amount) private {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }
    // 转账
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");
        if(from != owner() && to != owner()) // 如果转账有合约创建者参与
            require(amount <= _maxTxAmount, "Transfer amount exceeds the maxTxAmount."); // 转账数量大于总量 回滚

        // is the token balance of this contract address over the min number of
        // tokens that we need to initiate a swap + liquidity lock?
        // also, don't get caught in a circular liquidity event.
        // also, don't swap & liquify if sender is uniswap pair.
        uint256 contractTokenBalance = balanceOf(address(this)); // 合约token余额[收到的手续费]
        
        if(contractTokenBalance >= _maxTxAmount) { // 手续费数量大于最大手续费数量
            contractTokenBalance = _maxTxAmount; // 该值等于最大值
        }
        
        bool overMinTokenBalance = contractTokenBalance >= numTokensSellToAddToLiquidity;
        if (
            overMinTokenBalance && // 手续费超量
            !inSwapAndLiquify && // 当前合约没有进行流通性添加操作
            from != uniswapV2Pair && // 发起转账用户不是Uni的交易对
            swapAndLiquifyEnabled // 开启了添加流动性
        ) {
            contractTokenBalance = numTokensSellToAddToLiquidity;
            // 添加流动性
            swapAndLiquify(contractTokenBalance);
        }
        
        //indicates if fee should be deducted from transfer
        bool takeFee = true; // 收取手续费
        
        // if any account belongs to _isExcludedFromFee account then remove the fee
        // 如果任何帐户属于费用帐户,则删除费用
        if(_isExcludedFromFee[from] || _isExcludedFromFee[to]){
            takeFee = false;
        }
        
        //transfer amount, it will take tax, burn, liquidity fee
        _tokenTransfer(from,to,amount,takeFee);
    }
    // 把传入的数量用来添加流动性
    function swapAndLiquify(uint256 contractTokenBalance) private lockTheSwap {
        // 把合约余额分成两半
        uint256 half = contractTokenBalance.div(2);
        uint256 otherHalf = contractTokenBalance.sub(half);

        // 获取合同的当前ETH余额。
        // 这样,我们就可以准确地获取掉期产生的ETH金额,而不会使流动性事件包括任何手动发送到合同的ETH
        uint256 initialBalance = address(this).balance;

        // 把传入数量的一半用来卖出ETH
        swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered

        // 获取换到的ETH数量
        uint256 newBalance = address(this).balance.sub(initialBalance);

        // 把剩余一半的token和换到的ETH来添加流动性
        addLiquidity(otherHalf, newBalance);
        
        emit SwapAndLiquify(half, newBalance, otherHalf);
    }
    // 卖出token
    function swapTokensForEth(uint256 tokenAmount) private {
        // 构造交易路径
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();
        // 授权Uni使用token
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // 交换
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }
    // 在Uni上添加token-ETH的流动性
    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // add the liquidity
        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            owner(),
            block.timestamp
        );
    }

    //this method is responsible for taking all fee, if takeFee is true
    // 转账 发送者 接收者 数量 是否接收手续费
    function _tokenTransfer(address sender, address recipient, uint256 amount,bool takeFee) private {
        if(!takeFee) // 如果不收手续费
            removeAllFee(); // 设置手续费率为0
        
        if (_isExcluded[sender] && !_isExcluded[recipient]) { // 发送者是排除账户 接受者不是
            _transferFromExcluded(sender, recipient, amount); // 发起者是排除这的转账
        } 
        else if (!_isExcluded[sender] && _isExcluded[recipient]) { // 接收者是排除账户 发送者不是
            _transferToExcluded(sender, recipient, amount);   // 
        } 
        else if (!_isExcluded[sender] && !_isExcluded[recipient]) { // 两者都不是排除账户
            _transferStandard(sender, recipient, amount);
        } 
        else if (_isExcluded[sender] && _isExcluded[recipient]) { // 两者都是排除账户
            _transferBothExcluded(sender, recipient, amount);
        } 
        else {
            _transferStandard(sender, recipient, amount);
        }
        
        if(!takeFee) // 如果不接收手续费
            restoreAllFee(); // 恢复手续费率
    }
    /**
     * 下边几个方法的区别主要是 排除账户需要更新两个余额,普通账户更新默认余额即可 
     */
    // 排除账户之间转账
    function _transferBothExcluded(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
        _tOwned[sender] = _tOwned[sender].sub(tAmount); // 扣除排除余额
        _rOwned[sender] = _rOwned[sender].sub(rAmount); // 扣除默认余额
        _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount); // 添加排除余额
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); // 添加默认余额  
        _takeLiquidity(tLiquidity); // 添加流动性
        _reflectFee(rFee, tFee); // 添加手续费
        emit Transfer(sender, recipient, tTransferAmount);
    }
    // 普通用户之间转账
    function _transferStandard(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);
        _takeLiquidity(tLiquidity);
        _reflectFee(rFee, tFee);
        emit Transfer(sender, recipient, tTransferAmount);
    }
    // 普通用户转给排除账户
    function _transferToExcluded(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
        _rOwned[sender] = _rOwned[sender].sub(rAmount);
        _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount);           
        _takeLiquidity(tLiquidity);
        _reflectFee(rFee, tFee);
        emit Transfer(sender, recipient, tTransferAmount);
    }
    // 发起者是排除这的转账
    function _transferFromExcluded(address sender, address recipient, uint256 tAmount) private {
        (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee, uint256 tLiquidity) = _getValues(tAmount);
        _tOwned[sender] = _tOwned[sender].sub(tAmount); // 扣款
        _rOwned[sender] = _rOwned[sender].sub(rAmount); // 扣款
        _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); // 添加余额
        _takeLiquidity(tLiquidity); // 添加流动性
        _reflectFee(rFee, tFee); // 添加手续费
        emit Transfer(sender, recipient, tTransferAmount);
    }
}
本文由 爱生活的程序员 作者:qq小助手 发表,其版权均为 爱生活的程序员 所有,文章内容系作者个人观点,不代表 爱生活的程序员 对观点赞同或支持。如需转载,请注明文章来源。

发表回复

©2020 鲁ICP备14034693号-2