持币推广多级分红燃烧通缩营销钱包分红等多个模式智能合约源码分析开源
# 摘要
持币推广多级分红燃烧通缩营销钱包分红等多个模式智能合约源码分析。详细介绍了合约所涉及到的多级推广分红、买卖滑点、销毁等模式,并对实现的代码进行详细说明。同时整个的代码在GitHub进行了开源。合约机制中用户如果想拿到更多的代币分红,需要空投或者转账给更多的钱包,并保证这些钱包参与买卖交易、Token兑换。推广层级、分红比例可以动态调整,也可以通过释放合约管理员权限(合约Owner所有者地址进行锁死)。本合约owner地址可以丢弃或者释放,也可以在释放前进行转让合约所有权。买卖滑点、分红比例、营销钱包地址等可以通过合约管理员权限进行修改。白名单用户可以免除买卖滑点。为了防止非项目方私自添加初始化的流动池,合约可以指定哪些钱包可以第一个添加流动池。 GitHub地址 (opens new window)
# 模式
发行总量:总量作为合约构造函数的参数,可以在合约部署时根据需要填写。
买卖交易兑换滑点:是指用户在对代币Token进行买卖兑换时扣除的总交易税费,交易税费可以用来销毁、推广分红、营销分配、自动加池子提供深度等。
销毁:每笔交易中的1%(用户可以自己设定) 代币将被自动销毁,以减少总供应量。你可以设定销毁的代币数量上限,以控制销毁的规模。
自动拉盘增加流动性:每笔交易中的1%(比例可以根据项目需要自己设定) 代币将自动添加到流动性池或指定的持有账户,以增加流动性和市场深度。
营销:1%(比例可以根据项目需要自己设定)的代币将分配到指定的营销钱包,用于推广和市场营销活动。
直推分红:持有一定数量的代币的用户将有资格获得买入和卖出交易的分红。这里假设只有直推用户持有一定比例的代币才有资格参与分红。
间推分红:持有一定数量的代币的间推用户将有资格获得买入和卖出交易的分红。
第三代、第四代和第五代分红等直到8代:持有一定数量的代币的第三代、第四代和第五代用户将有资格获得买入和卖出交易的分红。
# 代码分析
# 主要变量
所有定义的参数都尽量做到功能独立、灵活动态可配置,当然是在合约管理员权限没释放或者丢掉的前提下。管理员权限丢掉后合约的一切配置都是不可更改的。这也保证了合约的安全性和公平性。
uint256 public _buyLiquidityFee = 10;//买入流动池手续费
uint256 public _sellLiquidityFee = 10;//卖出流动池手续费
uint256 public _buyBurnFee = 10;//费用燃烧
uint256 public _sellBurnFee = 10;
uint256 public _sellMarketFee = 10;//市场手续费,打入营销账户
uint256 public _buyMarketFee = 10;//市场手续费,打入营销账户
uint256 public _shareFee = 10;//推广分佣费用
uint[] internal shareConfig = [4,2,1,1,1,1,0,0];//推荐人分成比例配置
uint256 shareRank=6;//max is 8//推荐人分成层级
uint256 public holdMinBalance = 500* 10**9;//持仓最小数量,大于等于该数量才能享受推广分红
uint256 public totalBuyFee = 40;//买入总手续费
uint256 public totalSellFee = 40;//卖出总手续费
address public marketAddress;//营销账户地址
mapping(address => bool) public initPoolAddress;//有权初始化池子地址
//黑洞地址
address constant public deadAddress = address(0x000000000000000000000000000000000000dEaD);
mapping (address => address) public _recommendMapping;//推荐绑定的关系
//添加池子的最小数量
uint256 public numTokensSellToAddToLiquidity = 50 * 10**9;
uint256 public _burnMax = 90000*10**9;//燃烧的最大数
IUniswapV2Router02 public immutable uniswapV2Router;//uniswap路由
address public uniswapV2Pair;//UniswapV2Pair地址
address public wbnb;
mapping(address => bool) public ammPairs;//存储交易对
address public holder;//该地址用于接收发行的代币
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 构造函数
通过构造函数可以初始化一些参数,同时利用IUniswapV2Router02、IUniswapV2Factory进行LP的创建,并通过initPoolAddress配置了有权添加池子的地址。根据设置的代币总量,把Token打入holder地址,并通过Transfer(address(0), holder, _tTotal)进行通告。
constructor (
string memory name_,string memory symbol_,uint256 totalSupply_,
uint256 minimumTokenBalanceForDividends_,uint256 burnMax_) {
_name=name_;
_symbol=symbol_;
_tTotal=totalSupply_*10**9;
numTokensSellToAddToLiquidity=minimumTokenBalanceForDividends_*10**9;
_burnMax=burnMax_*10**9;
shareRank=6;
_shareFee=10;
wbnb = address(0x55d398326f99059fF775485246999027B3197955);//0x7ef95a0FEE0Dd31b22626fA2e10Ee6A223F8a684);//usdt wbnb shib
holder = address(0x38E77e49D404334Bb01d00cf93FF3Ab3d9ef98B2);// owner
marketAddress = address(0x697efA0D06bd418a8bd8F24354A1E76bfd3Ee82C);
_buyLiquidityFee=10;
_sellLiquidityFee=10;
_buyBurnFee=10;
_sellBurnFee=10;
_buyMarketFee=20;
_sellMarketFee=20;
shareRank=6;
totalBuyFee=_shareFee;
totalBuyFee=totalBuyFee.add(_buyLiquidityFee).add(_buyBurnFee).add(_buyMarketFee);
totalSellFee=_shareFee;
totalSellFee=totalSellFee.add(_sellLiquidityFee).add(_sellBurnFee).add(_sellMarketFee);
_recommendMapping[deadAddress] = address(0xdeaddead);
_recommendMapping[holder] = deadAddress;
_recommendMapping[marketAddress] = deadAddress;
_tOwned[holder] = _tTotal;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(address(0x10ED43C718714eb63d5aA57B78B54704E256024E));
uniswapV2Router = _uniswapV2Router;
address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), wbnb);
_allowances[address(this)][address(_uniswapV2Router)] = MAX;
IERC20(wbnb).approve(address(_uniswapV2Router), MAX);
uniswapV2Pair = _uniswapV2Pair;
ammPairs[uniswapV2Pair] = true;
_isExcludedFromFee[holder] = true;
_isExcludedFromFee[address(this)] = true;
_owner = msg.sender;
initPoolAddress[address(0xad6C294BDE2f5829FC42072AEB19DB9A7Cc48cA9)] = true;
initPoolAddress[address(0xad6C294BDE2f5829FC42072AEB19DB9A7Cc48cA9)] = true;
_tokenDistributor = new TokenDistributor(wbnb);
emit Transfer(address(0), holder, _tTotal);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 绑定推广关系
对第一次买入、收到token的地址进行上下级推广关系的绑定。
//绑定推荐关系 主动买入和转账
function addRelationEx(address recommer,address user) internal {
if(
recommer != user
&& _recommendMapping[user] == address(0x0)
&& _recommendMapping[recommer] != address(0x0) ){
_recommendMapping[user] = recommer;
}
}
2
3
4
5
6
7
8
9
# 自动添加流动性
每次Token买卖或者兑换产生的添加流动性的token都放在合约账户中,当数量累计到预设的最小数量(numTokensSellToAddToLiquidity)时,触发自动添加池子的功能。因为合约中只有本币Token,如果想添加流动性需要先把一半的Token兑换成池子的另一个币对如USDT、ETH等,然后通过addLiquidity进行添加流动性,增加池子深度。
function swapAndLiquify(uint256 contractTokenBalance) private lockTheSwap{
uint256 half = contractTokenBalance.div(2);
uint256 otherHalf = contractTokenBalance.sub(half);
IERC20 baseToken = IERC20(wbnb);
uint256 initialBalance = baseToken.balanceOf(address(_tokenDistributor));
swapTokensForBaseToken(half,address(_tokenDistributor));
uint256 newBalance = baseToken.balanceOf(address(_tokenDistributor)).sub(initialBalance);
baseToken.transferFrom(address(_tokenDistributor), address(this), newBalance);
addLiquidityBaseToken(otherHalf, newBalance);
}
2
3
4
5
6
7
8
9
10
11
12
# 转账函数
所有逻辑的入口,需要判断是否为交易兑换操作,如果是添加绑定关系;根据合约账户token的余额判断是否需要添加流动性;计算滑点费用,包括燃烧费、推广费、添加池子的费用、营销钱包的费用等;如果是初始添加池子的操作,需要进行地址权限的判断;最后根据计算后的费率进行具体的转账操作。
function _transfer(
address from,
address to,
uint256 amount
) private {
require(from != address(0), "ERC20: transfer from the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
uint256 balance = balanceOf(from);
require(balance > amount, "balanceNotEnough");
if( !_isContract(to) //钱包地址、不是合约地址
&& _recommendMapping[to] == address(0) ){//未绑定推荐人
if( ammPairs[from] ){//是否是交易对
addRelationEx(holder,to);//买入时,如果未绑定推荐人,绑定holder
}else{
addRelationEx(from,to);//转账时,如果未绑定推荐人,绑定from
}
}
uint256 contractTokenBalance = balanceOf(address(this));
if(
contractTokenBalance >= numTokensSellToAddToLiquidity //判断是否达到添加流动池的数量
&& !inSwapAndLiquify //是否正在添加流动池
&& !ammPairs[from] //判断是否是交易对
&& IERC20(uniswapV2Pair).totalSupply() > numLPSellToAddToLiquidity ){//判断流动池的总数量是否大于最小添加流动池的数量
swapAndLiquify(contractTokenBalance);
}
bool takeFee = true;
if( _isExcludedFromFee[from] || _isExcludedFromFee[to]){//判断是否是免手续费账户
takeFee = false;
}
Param memory param;
param.tTransferAmount = amount;
if( takeFee ){
param.takeFee = true;
if( ammPairs[from]){//判断是否是交易对,如果是交易对代表是买入
_getBuyParam(amount,param);//获得买入参数
param.user = to;
}
if( ammPairs[to]){//判断是否是交易对,如果是交易对代表是卖出
_getSellParam(amount,param);//获得卖出参数
param.user = from;
}
/*if( !ammPairs[from] && !ammPairs[to]){
_getTransferParam(amount,param);
}*/
}
if( ammPairs[to]){//判断是否是交易对,如果是交易对代表是卖出或者添加流动池
if( IERC20(uniswapV2Pair).totalSupply() == 0 ){
require(initPoolAddress[from],"not init pool address");
}
}
_tokenTransfer(from,to,amount,param);//参数from是发起交易的地址
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 后记总结
持币推广多级分红燃烧通缩营销钱包分红等所有模式都已经在代码中实现,源代码并已经开源。本合约对推广的用户只能分红本币,如果想分红USDT、WBNB或者是大狗(doge)、柴犬(Shib)等,可以配置这些币对的lp交易对进行买入后根据比例进行分红即可。这块的会增加买入别的代币的Gas费。