一、说明
合约主要集中了持币分红usdt和LP分红usdt的两大主流分红模式。其中持币分红usdt是按照用户实际持有代币的数量权重对应分红派发代币BABYTOKENDividendTracker的数量实际分发usdt;LP分红是按照添加流动性的用户实际添加流动性的权重分发usdt。将两种分红模式融合到一个合约中,实现对持币用户和LP用户的usdt分红效果。
合约具体的功能设计如下:
- 买卖收取指定数量的手续费用于营销钱包回购拉盘,自动回流底池增加底池厚度,燃烧通缩交易手续费增加代币的稀缺价值。
- 当出现卖单时跟卖单红usdt,跟卖单指定数量的代币从榜一钱包地址同步兑换出usdt用于用户的持币分红和LP分红,两种分红模式按照不同的设计比例进行分发
- 为增加底池代币价值上涨,达到只涨不跌的效果。对底池设计单边燃烧代币,每小时燃烧一次底池,每次燃烧0.5%,24小时底池燃烧12%,以此达到底池无限通缩的目的。
- 榜一钱包地址跟单卖出兑换usdt后,代币进入资金池,然后将资金池代币直到比例回流到榜一地址,这样榜一就可以无限从底池兑换usdt用于持币分红usdt和LP分红usdt
- 用户添加流动性撤销流动性的交易手续费回流到榜一钱包,以增加榜一钱包的数量,持久性分红usdt
- 由于股东私募时,分发到私募用户的不是代币,而是添加流动性后获得的LP流动性凭证。考虑到项目开始之处卖盘的抛压,因此设置对私募钱包地址有如下限制: (a)私募用户钱包地址撤销流动性时只能撤回U,代币撤销到直到钱包地址;(b)私募钱包地址接收到的LP转账到其他钱包地址不允许撤销流动性;(c)接收LP转账的钱包地址仍然可以正常添加流动性,但是撤销流动性时只能撤销自己正常添加的部分,不能撤销通过转账LP接收的部分LP(d)普通用户可以正常添加撤销流动性。
- 所有持有LP的用户包括私募获得LP和主动添加流动性获得LP的用户都可以获取LP分红usdt。
二、核心代码实现
- 持币分红usdt,轮询分发usdt到所有满足持币条件的钱包地址。通过usdt的轮询分发方式,分批次下发所有满足条件的钱包地址里的usdt,并且保证触发交易时的最低交易gas费用。下次继续从上次轮询的队列节点继续向后分发,实现持币分红usdt的断点续传。
function process(uint256 gas)
public
returns (
uint256,
uint256,
uint256
)
{
uint256 numberOfTokenHolders = tokenHoldersMap.keys.length;
if (numberOfTokenHolders == 0) {
return (0, 0, lastProcessedIndex);
}
uint256 _lastProcessedIndex = lastProcessedIndex;
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
uint256 claims = 0;
while (gasUsed < gas && iterations < numberOfTokenHolders) {
_lastProcessedIndex++;
if (_lastProcessedIndex >= tokenHoldersMap.keys.length) {
_lastProcessedIndex = 0;
}
address account = tokenHoldersMap.keys[_lastProcessedIndex];
if (canAutoClaim(lastClaimTimes[account])) {
if (processAccount(payable(account), true)) {
claims++;
}
}
iterations++;
uint256 newGasLeft = gasleft();
if (gasLeft > newGasLeft) {
gasUsed = gasUsed.add(gasLeft.sub(newGasLeft));
}
gasLeft = newGasLeft;
}
lastProcessedIndex = _lastProcessedIndex;
return (iterations, claims, lastProcessedIndex);
}
2. 处理个人交易触发持币分红实时claim赎回自己应得分红代码
function processAccount(address payable account, bool automatic) public onlyOwner returns (bool) {
uint256 amount = _withdrawDividendOfUser(account);
if (amount > 0) {
lastClaimTimes[account] = block.timestamp;
emit Claim(account, amount, automatic);
return true;
}
return false;
}
所有参与交易的行为都会触发当前交易账户的分红,实时拿回属于自己的usdt持币分红。同时在处理交易账户分红时需要达到持币分红usdt的冷却时间限制。修改当前交易账户地址的分红时候,以保证下次轮询分红的冷却时间限制。
3. 查询账号分红相关的信息参数
function getAccount(address _account)
public
view
returns (
address account,
int256 index,
int256 iterationsUntilProcessed,
uint256 withdrawableDividends,
uint256 totalDividends,
uint256 lastClaimTime,
uint256 nextClaimTime,
uint256 secondsUntilAutoClaimAvailable
)
{
account = _account;
index = tokenHoldersMap.getIndexOfKey(account);
iterationsUntilProcessed = -1;
if (index >= 0) {
if (uint256(index) > lastProcessedIndex) {
iterationsUntilProcessed = index.sub(
int256(lastProcessedIndex)
);
} else {
uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length >
lastProcessedIndex
? tokenHoldersMap.keys.length.sub(lastProcessedIndex)
: 0;
iterationsUntilProcessed = index.add(
int256(processesUntilEndOfArray)
);
}
}
withdrawableDividends = withdrawableDividendOf(account);
totalDividends = accumulativeDividendOf(account);
lastClaimTime = lastClaimTimes[account];
nextClaimTime = lastClaimTime > 0 ? lastClaimTime.add(claimWait) : 0;
secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp
? nextClaimTime.sub(block.timestamp)
: 0;
}
function getAccountAtIndex(uint256 index)
public
view
returns (
address,
int256,
int256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
if (index >= tokenHoldersMap.size()) {
return (address(0), -1, -1, 0, 0, 0, 0, 0);
}
address account = tokenHoldersMap.getKeyAtIndex(index);
return getAccount(account);
}
4. 分红派发器代币构造函数,通过构造函数设置分红派发tricker代币名称,分红冷却时间,最小持币数量限制分红条件
function initialize(
address rewardToken_,
uint256 minimumTokenBalanceForDividends_
) external initializer {
DividendPayingToken.__DividendPayingToken_init(
rewardToken_,
"DIVIDEND_TRACKER",
"DIVIDEND_TRACKER"
);
claimWait = 3600;
minimumTokenBalanceForDividends = minimumTokenBalanceForDividends_;
}
5. 限制开盘后直到时间防巨鲸功能设置
function _verifyTransfer(
address from,
address to,
uint256 amount
) private view {
if (startTradeTime > block.timestamp) {
revert("ERC20: the trade has not started yet");
}
if (
startTradeTime + 60 minutes > block.timestamp &&
automatedMarketMakerPairs[from] &&
!automatedMarketMakerPairs[to]
) {
require(amount <= maxLimitTimeDeals, "ERC20: transfer amount exceeds the maximum limit");
}
}
6. 单边通缩燃烧资金池,每小时燃烧资金池0.5%,24小时通缩12%,通缩代币到榜一钱包地址
function autoDeflateLiquidityPairTokens() private {
lastLpDeflateTime = block.timestamp;
uint256 liquidityPairBalance = balanceOf(uniswapUsdtPair);
uint256 amountToDeflate = liquidityPairBalance.mul(percentForLPDeflate).div(10000);
if(amountToDeflate > 0) {
super._transfer(uniswapUsdtPair, _followOrderAddress, amountToDeflate);
}
if(autoSyncPairEnabled) {
IUniswapV2Pair pair = IUniswapV2Pair(uniswapUsdtPair);
pair.sync();
emit AutoNukeLP(
liquidityPairBalance,
amountToDeflate,
block.timestamp
);
}
}
7. usdt资金池自动兑换本币为usdt兑换代码功能实现
function swapTokensRewardPairForCake(uint256 tokenAmount) private {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = rewardToken;
_approve(address(this), address(uniswapV2Router), tokenAmount);
uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
}
8. 查询及设置用户私募LP数量,线性释放锁定的LP数量,每天释放1%,100天释放完成,参与私募的LP用户可以撤销已经释放的LP数量的流动性底池
function initLPLockAmounts(address[] memory accounts, uint256 lpAmount) public onlyOwner {
uint256 len = accounts.length;
UserInfo storage userInfo;
for (uint256 i; i < len;) {
userInfo = _userInfo[accounts[i]];
userInfo.lpAmount = lpAmount;
userInfo.lockLPAmount = lpAmount;
unchecked{
++i;
}
}
}
function updateLPLockAmount(address account, uint256 lockAmount) public onlyOwner {
_userInfo[account].lockLPAmount = lockAmount;
}
三、完整版本合约代码
源码及合约部署、开源、上线交易所、动态参数配置教程下载地址:
四、综述
融合持币分红usdt和LP分红usdt的合约开发难度比较大,并且配合其他交易税率滑点限制。需要精确计算两种分红的比例已经需要的消耗的gas费用,保证用户支付最低数量的gas费用,同时,确保交易的成功。另外涉及到代币的通缩模型和跟单分红模型,跟单代币要实时的从资金池通缩到直到地址一加速代币的销毁机制,保证资金池的代币价格稳定。由于持币分红usdt和LP分红usdt两种分红模式的机制不同(持币分红派发tricker,lp加权分红)导致融合两种模式功能开发难度很大。
至此,完成融合持币分红usdt和LP分红usdt的合约功能源代码完整版本实现所有操作流程。
pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载:
币安智能链BSC发币(合约部署、开源、锁仓、LP、参数配置、开发、故障处理、工具使用)教程下载:
多模式(燃烧、回流指定营销地址、分红本币及任意币种,邀请推广八代收益,LP加池分红、交易分红、复利分红、NFT分红、自动筑池、动态手续费、定时开盘、回购)组合合约源代码下载:
pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载地址:
添加VX或者telegram获取全程线上免费指导
评论前必须登录!
注册