一、说明
在defi智能合约开发过程中一中买入操作和撤销流动性LP联动的需求如下:用户实际买入代币数量按照当前价格换算成usdt后,从资金池撤销买入数量金本位10%的LP流动性。其中,撤销的LP流动性中usdt用于分红给所有满足条件的钱包地址,撤销的代币自动进入黑洞销毁掉。该需求涉及到代币的买入和撤销流动性进行联动,并且撤销流动的动作需要通过合约自动执行,而不是手动去撤销LP,所有操作完全通过智能合约实现,不借助底层的dapp辅助功能。
二、功能需要说明
- 因为代币的买入操作是不允许对资金池有任何的操作行为的包括添加,撤销,单边燃烧底池。
- 撤销流动性LP的动作需要跟买入动作进行联动,因此,就需要将每次买入的数量保存到一个消息队列中,遵守先进先出的原则。每次卖出时消费掉队列中的一个金本位的买入数量。
- 撤销LP的动作需要在卖出时触发,合并兑换相关的交易税费回流到营销钱包
三、核心代码实现
- 业务合约_transfer函数中调用代理合约撤销流动性LP的功能实现
if (from != address(this) && !canSwap && pancakePair == to && takeFee && tradingEnabled && lastTradeValue.length > 0) {
// redeem lp
uint256 rmValue = lastTradeValue[0];
if(rmValue > IERC20(usdtAddress).balanceOf(pancakePair).mul(diviLimitRate).div(100)) {
removeLastTradeValue(0);
} else {
try ITreasury(treasuryAddress).divident(rmValue) returns(bool res) {
if(res) {
removeLastTradeValue(0);
}
} catch {}
}
}
注:代理合约自动撤销流动性LP的动作必须是在卖出时,并且不能在添加流动性,更不能在买入和撤销流动性过程中实现。
2. 根据用户实际向黑洞地址dead转账的代币数量核算为金本位usdt后,向用户mint指定数量的分红派发tricker
function safeMint(address account, uint256 amount) external _onlyStar updateReward(account) {
if(_isExcludeFromRewards[account]) return ;
uint256 relVal = calculateValue(amount);
if(accountStakeValue[account].add(relVal) < minRewardRequiredValAmount) {
return;
}
accountStakeValue[account] = accountStakeValue[account].add(relVal);
lastStakeTime[account] = block.timestamp;
addRewardProvider(account);
_mint(account, amount);
}
原理与持币分红usdt的原理类似,都是根据用户实际持币或者打入黑洞地址的代币数量铸造mint相等数量的tricker。
3. 轮询给所有代币打入黑洞获取usdt分红的钱包地址,分发usdt到对应的钱包
function processReward(uint256 gas) external _onlyStar {
if (block.number < _nodeRewardLastBlockNo.add(_nodeRewardBlockDebt)){
return ;
}
if (totalSupply() <= 0 || rewardPerTokenStored <= 0) {
return;
}
address shareHolder;
uint256 shareholderCount = getRewardProviderLength();
uint256 gasUsed = 0;
uint256 iterations = 0;
uint256 gasLeft = gasleft();
uint256 holdMinRequiredAmount = minRewardRequiredValAmount;
while (gasUsed < gas && iterations < shareholderCount) {
if (_currentRewardNodeIndex >= shareholderCount) {
_currentRewardNodeIndex = 0;
}
shareHolder = rewardTokenProviders[_currentRewardNodeIndex];
if (!_isExcludeFromRewards[shareHolder]) {
if (accountStakeValue[shareHolder] >= holdMinRequiredAmount) {
getReward(shareHolder);
}
}
gasUsed = gasUsed + (gasLeft - gasleft());
gasLeft = gasleft();
_currentRewardNodeIndex++;
iterations++;
}
_nodeRewardLastBlockNo = block.number;
}
在该函数中通过全局变量的轮询,保证了每次轮询后保留下一次轮询的起点,直到所有地址轮询完成再开启下一次轮询分红usdt。
4. 确保用户在分红达到一定数量后,停止获取分红,淘汰出局的moderfy代码:
function earn(address account) public view returns(uint256) {
uint256 userStakeReward = balanceOf(account).mul(rewardPerTokenStored.sub(userRewardPerTokenPaid[account])).div(1e18);
uint256 userReweardLimit = accountStakeValue[account].mul(multiple);
if(userStakeReward.add(userRewardTotalPaid[account]) > userReweardLimit) {
userStakeReward = userReweardLimit.sub(userRewardTotalPaid[account]);
}
return userStakeReward;
}
5. 代理合约中自动撤销流动性LP的功能代码实现
function divident(uint256 amount) external _onlyOwner returns(bool) {
if(IERC20(dividentAddress).totalSupply() <= 0) return false;
uint256 removeAmount = valueToLiquidityAmount(amount.mul(removeRate).div(100));
if(lpToken.balanceOf(address(this)) < removeAmount) return false;
// Approve tokenA and tokenB to be spent by the PancakeSwap Router
uint256 beforeThisToken = Token.balanceOf(address(this));
uint256 beforeUsdtAmount = USDTToken.balanceOf(address(this));
lpToken.approve(address(pancakeRouter), removeAmount);
// Remove liquidity
pancakeRouter.removeLiquidity(
address(Token),
address(USDTToken),
removeAmount,
0,
0,
address(this),
block.timestamp
);
uint256 thisTokenAmount = Token.balanceOf(address(this)).sub(beforeThisToken);
uint256 usdtAmount = USDTToken.balanceOf(address(this)).sub(beforeUsdtAmount);
Token.transfer(deadAddress, thisTokenAmount);
USDTToken.transfer(address(dividentAddress), usdtAmount);
IDividentToken(dividentAddress).distributeReward(usdtAmount);
return true;
}
四、完整版本合约代码
源码及合约部署、开源、上线交易所、动态参数配置教程下载地址:
至此,完成DEFI合约开发中根据用户买入代币的数量由合约自动撤销对应比率的LP流动性用于分红usdt所有操作流程。
pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载:
币安智能链BSC发币(合约部署、开源、锁仓、LP、参数配置、开发、故障处理、工具使用)教程下载:
多模式(燃烧、回流指定营销地址、分红本币及任意币种,邀请推广八代收益,LP加池分红、交易分红、复利分红、NFT分红、自动筑池、动态手续费、定时开盘、回购)组合合约源代码下载:
pdf+视频币安智能链BSC发币教程及多模式组合合约源代码下载地址:
添加VX或者telegram获取全程线上免费指导
评论前必须登录!
注册