币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】

  • A+
所属分类:币安BSC

chatGPT账号

币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】

一、说明

根据用户添加流动性的LP持有情况,在合约中计算用户添加和撤销流动性时间mint和burn的LP数量。更加有效的LP数量(剔除pinksale的锁仓LP,dead永久燃烧的LP)计算用户在不同时段获取的本币分红的数量。

二、核心功能代码

  1. 通过如下枚举类类库library来保存持有lp的用户钱包地址:
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastvalue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastvalue;
                // Update the index for the moved value
                set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        assembly {
            result := store
        }

        return result;
    }
}

该类库主要是针对address类型变量提供钱包地址类型变量的增、删、改、查操作功能。

2. 识别添加流动性的函数功能接口

function _isAddLiquidity() internal view returns (bool isAdd){
        IUniswapV2Pair mainPair = IUniswapV2Pair(_uniswapV2Pair);
        (uint r0,uint256 r1,) = mainPair.getReserves();

        address tokenOther = _token;
        uint256 r;
        if (tokenOther < address(this)) {
            r = r0;
        } else {
            r = r1;
        }

        uint bal = IERC20(tokenOther).balanceOf(address(mainPair));
        isAdd = bal > r;
    }

3. 识别撤销流动性的函数功能接口代码

function _isRemoveLiquidity() internal view returns (bool isRemove){
        if(_uniswapV2Pair == address(0)) return false;
        IUniswapV2Pair mainPair = IUniswapV2Pair(_uniswapV2Pair);
        (uint r0,uint256 r1,) = mainPair.getReserves();

        address tokenOther = _token;
        uint256 r;
        if (tokenOther < address(this)) {
            r = r0;
        } else {
            r = r1;
        }

        uint bal = IERC20(tokenOther).balanceOf(address(mainPair));
        isRemove = r >= bal;
    }

4. 处理LP分红本币,不同时段设置不同分红比例的函数功能源码

function process() private {
        if( getC()< lastClaimTime||theDayMint[getC()]== getMintNum()||(block.timestamp-_startTimeForSwap)<= _time ){
            return;
        }
        uint256 shareholderCount = _shareholders.length();
        
        if(shareholderCount == 0)return;
        
        uint256 tokenBal =  getMintNum();
        uint ss = everyDivi>shareholderCount?shareholderCount:everyDivi;

        IUniswapV2Pair mainPair = IUniswapV2Pair(_uniswapV2Pair);
        
        for(uint i;i<ss;i++){
            if(getC()<lastClaimTime){
                break;
            }
            if(_currentIndex >= shareholderCount){
                _currentIndex = 0;
                lastClaimTime += 1;
            }
            uint256 amount = tokenBal.mul( pairAmount[_shareholders.at(_currentIndex)] ).div(getLpTotal());
            uint256 _pairAmount = mainPair.balanceOf(_shareholders.at(_currentIndex));
            if( amount < 1e13 ||_isDividendExempt[_shareholders.at(_currentIndex)]
            ||addLPTime[_shareholders.at(_currentIndex)]+(_lpTime)>block.timestamp
            ||addLPTime[_shareholders.at(_currentIndex)]==0
            ||pairAmount[_shareholders.at(_currentIndex)] > _pairAmount) {
            //The calculated value will always be smaller than the LP value. If someone transfers LP, the judgment will fail.
                _currentIndex++;
                continue;
            }

            if(theDayMint[getC()]+amount>=tokenBal){
                amount =tokenBal>theDayMint[getC()]? (tokenBal - theDayMint[getC()]):0 ;
                //Protect the program from reporting errors
            }
            _basicTransfer(address(this),_shareholders.at(_currentIndex),amount);
            theDayMint[getC()]+=amount;
            _currentIndex++;
        }
    }

三、完整版本合约代码

币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】

源码及合约部署、开源、上线交易所、动态参数配置教程下载地址:

此处为隐藏的内容!
登录后才能查看!

 

至此,完成LP分红本币的合约处理代码实现,不同时段分红不同数量的本币所有操作流程。

pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载:

币安智能链BSC发币(合约部署、开源、锁仓、LP、参数配置、开发、故障处理、工具使用)教程下载:

币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】

多模式(燃烧、回流指定营销地址、分红本币及任意币种,邀请推广八代收益,LP加池分红、交易分红、复利分红、NFT分红、自动筑池、动态手续费、定时开盘、回购)组合合约源代码下载:

币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】

pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载地址:

此处为隐藏的内容!
登录后才能查看!

添加VX或者telegram获取全程线上免费指导

币安BSC智能链合约开发教程——LP分红本币的合约处理代码实现,不同时段分红不同数量的本币【pdf+视频BSC链合约开发教程下载】
免责声明

免责声明:

本文不代表知点网立场,且不构成投资建议,请谨慎对待。用户由此造成的损失由用户自行承担,与知点网没有任何关系;

知点网不对网站所发布内容的准确性,真实性等任何方面做任何形式的承诺和保障;

网站内所有涉及到的区块链(衍生)项目,知点网对项目的真实性,准确性等任何方面均不做任何形式的承诺和保障;

网站内所有涉及到的区块链(衍生)项目,知点网不对其构成任何投资建议,用户由此造成的损失由用户自行承担,与知点网没有任何关系;

知点区块链研究院声明:知点区块链研究院内容由知点网发布,部分来源于互联网和行业分析师投稿收录,内容为知点区块链研究院加盟专职分析师独立观点,不代表知点网立场。

本文是全系列中第219 / 223篇:行业技术

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的电报
  • 这是我的电报扫一扫
  • weinxin
chatGPT账号

发表评论

您必须登录才能发表评论!