Token 10X: Africa's First Cryptocurrency Hub
nirai inu Token
Famed from sengoku era in japan, A master of nippon and shuriken , Nirai Inu the savior of bear market.
Nirai Inu is a token on the Binance Smart Chain that never stops growing through deflationary techniques and further income generation for its ecosystem.
...
About nirai inu
Famed from sengoku era in japan, A master of nippon and shuriken , Nirai Inu the savior of bear market.
Nirai Inu is a token on the Binance Smart Chain that never stops growing through deflationary techniques and further income generation for its ecosystem.
Nirai Inu is a token on the Binance Smart Chain that never stops growing through deflationary techniques and further income generation for its ecosystem.
94 total visits
Token information and links
Circulating Supply
10000000000000000000000000000
Token Contract (BSC Chain)
0X3F9B8B9C62BD56C129EB93F1ED33B434CD58D2B3
Contract license: MIT
Launch Date
13/07/2022
KYC Information
No
Audit Information
None
Team Information
Team leader: None
Team leader contact: None
Contract source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
/**
* Standard SafeMath, stripped down to just add/sub/mul/div
*/
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c a % b); // There is no case in which this doesn't hold
return c;
}
}
/**
* BEP20 standard interface.
*/
interface IBEP20 {
function totalSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function getOwner() external view returns (address);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address _owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* Allows for contract ownership for multiple adressess
*/
abstract contract Auth {
address internal owner;
mapping (address => bool) internal authorizations;
constructor(address _owner) {
owner = _owner;
authorizations[_owner] = true;
}
/**
* Function modifier to require caller to be contract owner
*/
modifier onlyOwner() {
require(isOwner(msg.sender), "!OWNER"); _;
}
/**
* Function modifier to require caller to be authorized
*/
modifier authorized() {
require(isAuthorized(msg.sender), "!AUTHORIZED"); _;
}
/**
* Authorize address. Owner only
*/
function authorize(address account) public onlyOwner {
authorizations[account] = true;
}
/**
* Remove address authorization. Owner only
*/
function unauthorize(address account) public onlyOwner {
authorizations[account] = false;
}
/**
* Check if address is owner
*/
function isOwner(address account) public view returns (bool) {
return account == owner;
}
/**
* Return address authorization status
*/
function isAuthorized(address account) public view returns (bool) {
return authorizations[account];
}
/**
* Transfer ownership to new address. Caller must be owner. Leaves old owner authorized
*/
function transferOwnership(address payable account) public onlyOwner {
owner = account;
authorizations[account] = true;
emit OwnershipTransferred(account);
}
event OwnershipTransferred(address owner);
}
/* Standard IDEXFactory */
interface IDEXFactory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
/* Standard IDEXRouter */
interface IDEXRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
/* Interface for the DividendDistributor */
interface IDividendDistributor {
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external;
function setShare(address shareholder, uint256 amount) external;
function deposit() external payable;
function process(uint256 gas) external;
}
/* Our DividendDistributor contract responsible for distributing the earn token */
contract DividendDistributor is IDividendDistributor {
using SafeMath for uint256;
address _token;
struct Share {
uint256 amount;
uint256 totalExcluded;
uint256 totalRealised;
}
// EARN
IBEP20 BTCB = IBEP20(0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c);
address WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
IDEXRouter router;
address[] shareholders;
mapping (address => uint256) shareholderIndexes;
mapping (address => uint256) shareholderClaims;
mapping (address => Share) public shares;
uint256 public totalShares;
uint256 public totalDividends;
uint256 public totalDistributed;
uint256 public dividendsPerShare;
uint256 public dividendsPerShareAccuracyFactor = 10 ** 36;
uint256 public minPeriod = 30 * 60;
uint256 public minDistribution = 1 * (10 ** 12);
uint256 currentIndex;
bool initialized;
modifier initialization() {
require(!initialized);
_;
initialized = true;
}
modifier onlyToken() {
require(msg.sender == _token); _;
}
constructor (address _router) {
router = _router != address(0)
? IDEXRouter(_router)
: IDEXRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E);
_token = msg.sender;
}
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external override onlyToken {
minPeriod = _minPeriod;
minDistribution = _minDistribution;
}
function setShare(address shareholder, uint256 amount) external override onlyToken {
if(shares[shareholder].amount > 0){
distributeDividend(shareholder);
}
if(amount > 0 && shares[shareholder].amount == 0){
addShareholder(shareholder);
}else if(amount == 0 && shares[shareholder].amount > 0){
removeShareholder(shareholder);
}
totalShares = totalShares.sub(shares[shareholder].amount).add(amount);
shares[shareholder].amount = amount;
shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
}
function deposit() external payable override onlyToken {
uint256 balanceBefore = BTCB.balanceOf(address(this));
address[] memory path = new address[](2);
path[0] = WBNB;
path[1] = address(BTCB);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(
0,
path,
address(this),
block.timestamp
);
uint256 amount = BTCB.balanceOf(address(this)).sub(balanceBefore);
totalDividends = totalDividends.add(amount);
dividendsPerShare = dividendsPerShare.add(dividendsPerShareAccuracyFactor.mul(amount).div(totalShares));
}
function process(uint256 gas) external override onlyToken {
uint256 shareholderCount = shareholders.length;
if(shareholderCount == 0) { return; }
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
while(gasUsed < gas && iterations < shareholderCount) {
if(currentIndex >= shareholderCount){
currentIndex = 0;
}
if(shouldDistribute(shareholders[currentIndex])){
distributeDividend(shareholders[currentIndex]);
}
gasUsed = gasUsed.add(gasLeft.sub(gasleft()));
gasLeft = gasleft();
currentIndex ;
iterations ;
}
}
function shouldDistribute(address shareholder) internal view returns (bool) {
return shareholderClaims[shareholder] minPeriod < block.timestamp
&& getUnpaidEarnings(shareholder) > minDistribution;
}
function distributeDividend(address shareholder) internal {
if(shares[shareholder].amount == 0){ return; }
uint256 amount = getUnpaidEarnings(shareholder);
if(amount > 0){
totalDistributed = totalDistributed.add(amount);
BTCB.transfer(shareholder, amount);
shareholderClaims[shareholder] = block.timestamp;
shares[shareholder].totalRealised = shares[shareholder].totalRealised.add(amount);
shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
}
}
function claimDividend(address shareholder) external onlyToken{
distributeDividend(shareholder);
}
function getUnpaidEarnings(address shareholder) public view returns (uint256) {
if(shares[shareholder].amount == 0){ return 0; }
uint256 shareholderTotalDividends = getCumulativeDividends(shares[shareholder].amount);
uint256 shareholderTotalExcluded = shares[shareholder].totalExcluded;
if(shareholderTotalDividends <= shareholderTotalExcluded){ return 0; }
return shareholderTotalDividends.sub(shareholderTotalExcluded);
}
function getCumulativeDividends(uint256 share) internal view returns (uint256) {
return share.mul(dividendsPerShare).div(dividendsPerShareAccuracyFactor);
}
function addShareholder(address shareholder) internal {
shareholderIndexes[shareholder] = shareholders.length;
shareholders.push(shareholder);
}
function removeShareholder(address shareholder) internal {
shareholders[shareholderIndexes[shareholder]] = shareholders[shareholders.length-1];
shareholderIndexes[shareholders[shareholders.length-1]] = shareholderIndexes[shareholder];
shareholders.pop();
}
}
/* Token contract */
contract Nirai is IBEP20, Auth {
using SafeMath for uint256;
// Addresses
address BTCB = 0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c;
address WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
address DEAD = 0x000000000000000000000000000000000000dEaD;
address ZERO = 0x0000000000000000000000000000000000000000;
address DEV = 0x5C32718FA88D4c04B83AB46BA0490B003CeD7c00;
// These are owner by default
address private autoLiquidityReceiver;
address private marketingFeeReceiver;
// Name and symbol
string constant _name = "Nirai Inu";
string constant _symbol = "NIRAI";
uint8 constant _decimals = 18;
// Total supply
uint256 _totalSupply = 10000000000 * (10 ** _decimals); // 1m
// Max wallet and TX
uint256 public _maxBuyTxAmount = _totalSupply * 200 / 10000; // 2% (100 mil)
uint256 public _maxSellTxAmount = _totalSupply * 100 / 10000; // 1% (100 mil)
uint256 public _maxWalletToken = ( _totalSupply * 200 ) / 10000; // 2% (100 mil)
// Mappings
mapping (address => uint256) _balances;
mapping (address => mapping (address => uint256)) _allowances;
mapping (address => bool) isFeeExempt;
mapping (address => bool) isTxLimitExempt;
mapping (address => bool) isTimelockExempt;
mapping (address => bool) isDividendExempt;
mapping (address => bool) public isBlacklisted;
// Buy Fees
uint256 public liquidityFeeBuy = 2;
uint256 public buybackFeeBuy = 0;
uint256 public reflectionFeeBuy = 0;
uint256 public marketingFeeBuy = 8;
uint256 public devFeeBuy = 0;
uint256 public totalFeeBuy = 10;
// Sell fees
uint256 public liquidityFeeSell = 0;
uint256 public buybackFeeSell = 0;
uint256 public reflectionFeeSell = 0;
uint256 public marketingFeeSell = 12;
uint256 public devFeeSell = 0;
uint256 public totalFeeSell = 12;
// Fee variables
uint256 liquidityFee;
uint256 buybackFee;
uint256 reflectionFee;
uint256 marketingFee;
uint256 devFee;
uint256 totalFee;
uint256 feeDenominator = 100;
// GREED
uint256 GREEDTriggeredAt;
uint256 GREEDDuration = 3600;
// Dead blocks
uint256 deadBlocks = 1;
// Sell amount of tokens when a sell takes place
uint256 public swapThreshold = _totalSupply * 25 / 10000; // .25% of supply
// Liquidity
uint256 targetLiquidity = 20;
uint256 targetLiquidityDenominator = 100;
// Buyback settings
uint256 buybackMultiplierNumerator = 200;
uint256 buybackMultiplierDenominator = 100;
uint256 buybackMultiplierTriggeredAt;
uint256 buybackMultiplierLength = 30 minutes;
bool public autoBuybackEnabled = false;
bool public autoBuybackMultiplier = false;
uint256 autoBuybackCap;
uint256 autoBuybackAccumulator;
uint256 autoBuybackAmount;
uint256 autoBuybackBlockPeriod;
uint256 autoBuybackBlockLast;
DividendDistributor distributor;
uint256 distributorGas = 500000;
// Cooldown & timer functionality
bool public buyCooldownEnabled = false;
uint8 public cooldownTimerInterval = 30;
mapping (address => uint) private cooldownTimer;
// Other variables
IDEXRouter public router;
address public pair;
uint256 public launchedAt;
bool public tradingOpen = true;
bool public swapEnabled = true;
bool inSwap;
modifier swapping() { inSwap = true; _; inSwap = false; }
/* Token constructor */
constructor () Auth(msg.sender) {
router = IDEXRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E);
pair = IDEXFactory(router.factory()).createPair(WBNB, address(this));
_allowances[address(this)][address(router)] = type(uint256).max;
distributor = new DividendDistributor(address(router));
// Should be the owner wallet/token distributor
address _presaler = msg.sender;
isFeeExempt[_presaler] = true;
isTxLimitExempt[_presaler] = true;
// No timelock for these people
isTimelockExempt[msg.sender] = true;
isTimelockExempt[DEAD] = true;
isTimelockExempt[address(this)] = true;
isTimelockExempt[DEV] = true;
// Exempt from dividend
isDividendExempt[pair] = true;
isDividendExempt[address(this)] = true;
isDividendExempt[DEAD] = true;
// Set the marketing and liq receiver to the owner as default
autoLiquidityReceiver = msg.sender;
marketingFeeReceiver = 0xCEC847CFe13cF00d470D6946D7c7584aD3769642;
_balances[_presaler] = _totalSupply;
emit Transfer(address(0), _presaler, _totalSupply);
}
receive() external payable { }
function totalSupply() external view override returns (uint256) { return _totalSupply; }
function decimals() external pure override returns (uint8) { return _decimals; }
function symbol() external pure override returns (string memory) { return _symbol; }
function name() external pure override returns (string memory) { return _name; }
function getOwner() external view override returns (address) { return owner; }
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
function allowance(address holder, address spender) external view override returns (uint256) { return _allowances[holder][spender]; }
function approve(address spender, uint256 amount) public override returns (bool) {
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function approveMax(address spender) external returns (bool) {
return approve(spender, type(uint256).max);
}
function transfer(address recipient, uint256 amount) external override returns (bool) {
return _transferFrom(msg.sender, recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
if(_allowances[sender][msg.sender] != type(uint256).max){
_allowances[sender][msg.sender] = _allowances[sender][msg.sender].sub(amount, "Insufficient Allowance");
}
return _transferFrom(sender, recipient, amount);
}
// settting the max wallet in percentages
// NOTE: 1% = 100
function setMaxWalletPercent(uint256 maxWallPercent) external onlyOwner() {
_maxWalletToken = _totalSupply.mul(maxWallPercent).div(10000);
}
// Main transfer function
function _transferFrom(address sender, address recipient, uint256 amount) internal returns (bool) {
if(inSwap){ return _basicTransfer(sender, recipient, amount); }
// Check if trading is enabled
if(!authorizations[sender] && !authorizations[recipient]){
require(tradingOpen,"Trading not enabled yet");
}
// Check if address is blacklisted
require(!isBlacklisted[recipient] && !isBlacklisted[sender], 'Address is blacklisted');
// Check if buying or selling
bool isSell = recipient == pair;
// Set buy or sell fees
setCorrectFees(isSell);
// Check max wallet
checkMaxWallet(sender, recipient, amount);
// Buycooldown
checkBuyCooldown(sender, recipient);
// Checks maxTx
checkTxLimit(sender, amount, recipient, isSell);
// Check if we are in GREEDTime
bool GREEDMode = inGREEDTime();
// Check if we should do the swapback
if(shouldSwapBack()){ swapBack(); }
//Exchange tokens
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
uint256 amountReceived = shouldTakeFee(sender) ? takeFee(sender, amount, isSell, GREEDMode) : amount;
_balances[recipient] = _balances[recipient].add(amountReceived);
// Dividend tracker
if(!isDividendExempt[sender]) {
try distributor.setShare(sender, _balances[sender]) {} catch {}
}
if(!isDividendExempt[recipient]) {
try distributor.setShare(recipient, _balances[recipient]) {} catch {}
}
try distributor.process(distributorGas) {} catch {}
emit Transfer(sender, recipient, amountReceived);
return true;
}
// Do a normal transfer
function _basicTransfer(address sender, address recipient, uint256 amount) internal returns (bool) {
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
return true;
}
// Set the correct fees for buying or selling
function setCorrectFees(bool isSell) internal {
if(isSell){
liquidityFee = liquidityFeeSell;
buybackFee = buybackFeeSell;
reflectionFee = reflectionFeeSell;
marketingFee = marketingFeeSell;
devFee = devFeeSell;
totalFee = totalFeeSell;
} else {
liquidityFee = liquidityFeeBuy;
buybackFee = buybackFeeBuy;
reflectionFee = reflectionFeeBuy;
marketingFee = marketingFeeBuy;
devFee = devFeeBuy;
totalFee = totalFeeBuy;
}
}
// Check if we are in GREED time
function inGREEDTime() public view returns (bool){
if(GREEDTriggeredAt.add(GREEDDuration) > block.timestamp){
return true;
} else {
return false;
}
}
// Check for maxTX
function checkTxLimit(address sender, uint256 amount, address recipient, bool isSell) internal view {
if (recipient != owner){
if(isSell){
require(amount <= _maxSellTxAmount || isTxLimitExempt[sender] || isTxLimitExempt[recipient], "TX Limit Exceeded");
} else {
require(amount <= _maxBuyTxAmount || isTxLimitExempt[sender] || isTxLimitExempt[recipient], "TX Limit Exceeded");
}
}
}
// Check buy cooldown
function checkBuyCooldown(address sender, address recipient) internal {
if (sender == pair &&
buyCooldownEnabled &&
!isTimelockExempt[recipient]) {
require(cooldownTimer[recipient] < block.timestamp,"Please wait between two buys");
cooldownTimer[recipient] = block.timestamp cooldownTimerInterval;
}
}
// Check maxWallet
function checkMaxWallet(address sender, address recipient, uint256 amount) internal view {
if (!authorizations[sender] && recipient != owner && recipient != address(this) && recipient != address(DEAD) && recipient != pair && recipient != marketingFeeReceiver && recipient != autoLiquidityReceiver && recipient != DEV){
uint256 heldTokens = balanceOf(recipient);
require((heldTokens amount) <= _maxWalletToken,"Total Holding is currently limited, you can not buy that much.");
}
}
// Check if sender is not feeExempt
function shouldTakeFee(address sender) internal view returns (bool) {
return !isFeeExempt[sender];
}
// Get total fee's or multiplication of fees
function getTotalFee(bool selling) public view returns (uint256) {
if(launchedAt deadBlocks >= block.number){ return feeDenominator.sub(1); }
if(selling && buybackMultiplierTriggeredAt.add(buybackMultiplierLength) > block.timestamp){ return getMultipliedFee(); }
return totalFee;
}
// Get a multiplied fee when buybackMultiplier is active
function getMultipliedFee() public view returns (uint256) {
uint256 remainingTime = buybackMultiplierTriggeredAt.add(buybackMultiplierLength).sub(block.timestamp);
uint256 feeIncrease = totalFee.mul(buybackMultiplierNumerator).div(buybackMultiplierDenominator).sub(totalFee);
return totalFee.add(feeIncrease.mul(remainingTime).div(buybackMultiplierLength));
}
// Take the normal total Fee or the GREED Fee
function takeFee(address sender, uint256 amount, bool isSell, bool GREEDMode) internal returns (uint256) {
uint256 feeAmount;
// Check if we are GREEDd
if (GREEDMode){
if(isSell){
// We are selling so up the selling tax to 1.5x
feeAmount = amount.mul(totalFee).mul(3).div(2).div(feeDenominator);
} else {
// We are buying so cut our taxes in half
feeAmount = amount.mul(totalFee).div(2).div(feeDenominator);
}
} else {
feeAmount = amount.mul(totalFee).div(feeDenominator);
}
_balances[address(this)] = _balances[address(this)].add(feeAmount);
emit Transfer(sender, address(this), feeAmount);
return amount.sub(feeAmount);
}
// Check if we should sell tokens
function shouldSwapBack() internal view returns (bool) {
return msg.sender != pair
&& !inSwap
&& swapEnabled
&& _balances[address(this)] >= swapThreshold;
}
// switch Trading
function tradingStatus(bool _status) public onlyOwner {
tradingOpen = _status;
launch();
}
// Enable GREED
function enableGREED(uint256 _seconds) public authorized {
GREEDTriggeredAt = block.timestamp;
GREEDDuration = _seconds;
}
// Disable the GREED mode
function disableGREED() external authorized {
GREEDTriggeredAt = 0;
}
// Enable/disable cooldown between trades
function cooldownEnabled(bool _status, uint8 _interval) public authorized {
buyCooldownEnabled = _status;
cooldownTimerInterval = _interval;
}
// Blacklist/unblacklist an address
function blacklistAddress(address _address, bool _value) public authorized{
isBlacklisted[_address] = _value;
}
// Main swapback to sell tokens for WBNB
function swapBack() internal swapping {
uint256 dynamicLiquidityFee = isOverLiquified(targetLiquidity, targetLiquidityDenominator) ? 0 : liquidityFee;
uint256 amountToLiquify = swapThreshold.mul(dynamicLiquidityFee).div(totalFee).div(2);
uint256 amountToSwap = swapThreshold.sub(amountToLiquify);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = WBNB;
uint256 balanceBefore = address(this).balance;
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
amountToSwap,
0,
path,
address(this),
block.timestamp
);
uint256 amountBNB = address(this).balance.sub(balanceBefore);
uint256 totalBNBFee = totalFee.sub(dynamicLiquidityFee.div(2));
uint256 amountBNBLiquidity = amountBNB.mul(dynamicLiquidityFee).div(totalBNBFee).div(2);
uint256 amountBNBReflection = amountBNB.mul(reflectionFee).div(totalBNBFee);
uint256 amountBNBMarketing = amountBNB.mul(marketingFee).div(totalBNBFee);
uint256 amountBNBDev = amountBNB.mul(devFee).div(totalBNBFee);
try distributor.deposit{value: amountBNBReflection}() {} catch {}
(bool successMarketing, /* bytes memory data */) = payable(marketingFeeReceiver).call{value: amountBNBMarketing, gas: 30000}("");
(bool successDev, /* bytes memory data */) = payable(DEV).call{value: amountBNBDev, gas: 30000}("");
require(successMarketing, "marketing receiver rejected ETH transfer");
require(successDev, "dev receiver rejected ETH transfer");
if(amountToLiquify > 0){
router.addLiquidityETH{value: amountBNBLiquidity}(
address(this),
amountToLiquify,
0,
0,
autoLiquidityReceiver,
block.timestamp
);
emit AutoLiquify(amountBNBLiquidity, amountToLiquify);
}
}
// Check if autoBuyback is enabled
function shouldAutoBuyback() internal view returns (bool) {
return msg.sender != pair
&& !inSwap
&& autoBuybackEnabled
&& autoBuybackBlockLast autoBuybackBlockPeriod <= block.number
&& address(this).balance >= autoBuybackAmount;
}
// Trigger a manual buyback
function triggerManualBuyback(uint256 amount, bool triggerBuybackMultiplier) external authorized {
uint256 amountWithDecimals = amount * (10 ** 18);
uint256 amountToBuy = amountWithDecimals.div(100);
buyTokens(amountToBuy, DEAD);
if(triggerBuybackMultiplier){
buybackMultiplierTriggeredAt = block.timestamp;
emit BuybackMultiplierActive(buybackMultiplierLength);
}
}
// Stop the buyback Multiplier
function clearBuybackMultiplier() external authorized {
buybackMultiplierTriggeredAt = 0;
}
// Trigger an autobuyback
function triggerAutoBuyback() internal {
buyTokens(autoBuybackAmount, DEAD);
if(autoBuybackMultiplier){
buybackMultiplierTriggeredAt = block.timestamp;
emit BuybackMultiplierActive(buybackMultiplierLength);
}
autoBuybackBlockLast = block.number;
autoBuybackAccumulator = autoBuybackAccumulator.add(autoBuybackAmount);
if(autoBuybackAccumulator > autoBuybackCap){ autoBuybackEnabled = false; }
}
// Buy amount of tokens with bnb from the contract
function buyTokens(uint256 amount, address to) internal swapping {
address[] memory path = new address[](2);
path[0] = WBNB;
path[1] = address(this);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amount}(
0,
path,
to,
block.timestamp
);
}
// Set autobuyback settings
function setAutoBuybackSettings(bool _enabled, uint256 _cap, uint256 _amount, uint256 _period, bool _autoBuybackMultiplier) external authorized {
autoBuybackEnabled = _enabled;
autoBuybackCap = _cap;
autoBuybackAccumulator = 0;
autoBuybackAmount = _amount;
autoBuybackBlockPeriod = _period;
autoBuybackBlockLast = block.number;
autoBuybackMultiplier = _autoBuybackMultiplier;
}
// Set buybackmultiplier settings
function setBuybackMultiplierSettings(uint256 numerator, uint256 denominator, uint256 length) external authorized {
require(numerator / denominator <= 2 && numerator > denominator);
buybackMultiplierNumerator = numerator;
buybackMultiplierDenominator = denominator;
buybackMultiplierLength = length;
}
// Check when the token is launched
function launched() internal view returns (bool) {
return launchedAt != 0;
}
// Set the launchedAt to token launch
function launch() internal {
launchedAt = block.number;
}
// Set max buy TX
function setBuyTxLimitInPercent(uint256 maxBuyTxPercent) external authorized {
_maxBuyTxAmount = _totalSupply.mul(maxBuyTxPercent).div(10000);
}
// Set max sell TX
function setSellTxLimitInPercent(uint256 maxSellTxPercent) external authorized {
_maxSellTxAmount = _totalSupply.mul(maxSellTxPercent).div(10000);
}
// Exempt from dividend
function setIsDividendExempt(address holder, bool exempt) external authorized {
require(holder != address(this) && holder != pair);
isDividendExempt[holder] = exempt;
if(exempt){
distributor.setShare(holder, 0);
}else{
distributor.setShare(holder, _balances[holder]);
}
}
// Exempt from fee
function setIsFeeExempt(address holder, bool exempt) external authorized {
isFeeExempt[holder] = exempt;
}
// Exempt from max TX
function setIsTxLimitExempt(address holder, bool exempt) external authorized {
isTxLimitExempt[holder] = exempt;
}
// Exempt from buy CD
function setIsTimelockExempt(address holder, bool exempt) external authorized {
isTimelockExempt[holder] = exempt;
}
// Set our buy fees
function setBuyFees(uint256 _liquidityFeeBuy, uint256 _buybackFeeBuy, uint256 _reflectionFeeBuy, uint256 _marketingFeeBuy, uint256 _devFeeBuy, uint256 _feeDenominator) external authorized {
liquidityFeeBuy = _liquidityFeeBuy;
buybackFeeBuy = _buybackFeeBuy;
reflectionFeeBuy = _reflectionFeeBuy;
marketingFeeBuy = _marketingFeeBuy;
devFeeBuy = _devFeeBuy;
totalFeeBuy = _liquidityFeeBuy.add(_buybackFeeBuy).add(_reflectionFeeBuy).add(_marketingFeeBuy).add(_devFeeBuy);
feeDenominator = _feeDenominator;
}
// Set our sell fees
function setSellFees(uint256 _liquidityFeeSell, uint256 _buybackFeeSell, uint256 _reflectionFeeSell, uint256 _marketingFeeSell, uint256 _devFeeSell, uint256 _feeDenominator) external authorized {
liquidityFeeSell = _liquidityFeeSell;
buybackFeeSell = _buybackFeeSell;
reflectionFeeSell = _reflectionFeeSell;
marketingFeeSell = _marketingFeeSell;
devFeeSell = _devFeeSell;
totalFeeSell = _liquidityFeeSell.add(_buybackFeeSell).add(_reflectionFeeSell).add(_marketingFeeSell).add(_devFeeSell);
feeDenominator = _feeDenominator;
}
// Set the marketing and liquidity receivers
function setFeeReceivers(address _autoLiquidityReceiver, address _marketingFeeReceiver) external authorized {
autoLiquidityReceiver = _autoLiquidityReceiver;
marketingFeeReceiver = _marketingFeeReceiver;
}
// Set swapBack settings
function setSwapBackSettings(bool _enabled, uint256 _amount) external authorized {
swapEnabled = _enabled;
swapThreshold = _totalSupply * _amount / 10000;
}
// Set target liquidity
function setTargetLiquidity(uint256 _target, uint256 _denominator) external authorized {
targetLiquidity = _target;
targetLiquidityDenominator = _denominator;
}
// Send BNB to marketingwallet
function manualSend() external authorized {
uint256 contractETHBalance = address(this).balance;
payable(marketingFeeReceiver).transfer(contractETHBalance);
}
// Set criteria for auto distribution
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external authorized {
distributor.setDistributionCriteria(_minPeriod, _minDistribution);
}
// Let people claim there dividend
function claimDividend() external {
distributor.claimDividend(msg.sender);
}
// Check how much earnings are unpaid
function getUnpaidEarnings(address shareholder) public view returns (uint256) {
return distributor.getUnpaidEarnings(shareholder);
}
// Set gas for distributor
function setDistributorSettings(uint256 gas) external authorized {
require(gas < 750000);
distributorGas = gas;
}
// Get the circulatingSupply
function getCirculatingSupply() public view returns (uint256) {
return _totalSupply.sub(balanceOf(DEAD)).sub(balanceOf(ZERO));
}
// Get the liquidity backing
function getLiquidityBacking(uint256 accuracy) public view returns (uint256) {
return accuracy.mul(balanceOf(pair).mul(2)).div(getCirculatingSupply());
}
// Get if we are over liquified or not
function isOverLiquified(uint256 target, uint256 accuracy) public view returns (bool) {
return getLiquidityBacking(accuracy) > target;
}
event AutoLiquify(uint256 amountBNB, uint256 amountBOG);
event BuybackMultiplierActive(uint256 duration);
}
pragma solidity ^0.8.7;
/**
* Standard SafeMath, stripped down to just add/sub/mul/div
*/
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c a % b); // There is no case in which this doesn't hold
return c;
}
}
/**
* BEP20 standard interface.
*/
interface IBEP20 {
function totalSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function getOwner() external view returns (address);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address _owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* Allows for contract ownership for multiple adressess
*/
abstract contract Auth {
address internal owner;
mapping (address => bool) internal authorizations;
constructor(address _owner) {
owner = _owner;
authorizations[_owner] = true;
}
/**
* Function modifier to require caller to be contract owner
*/
modifier onlyOwner() {
require(isOwner(msg.sender), "!OWNER"); _;
}
/**
* Function modifier to require caller to be authorized
*/
modifier authorized() {
require(isAuthorized(msg.sender), "!AUTHORIZED"); _;
}
/**
* Authorize address. Owner only
*/
function authorize(address account) public onlyOwner {
authorizations[account] = true;
}
/**
* Remove address authorization. Owner only
*/
function unauthorize(address account) public onlyOwner {
authorizations[account] = false;
}
/**
* Check if address is owner
*/
function isOwner(address account) public view returns (bool) {
return account == owner;
}
/**
* Return address authorization status
*/
function isAuthorized(address account) public view returns (bool) {
return authorizations[account];
}
/**
* Transfer ownership to new address. Caller must be owner. Leaves old owner authorized
*/
function transferOwnership(address payable account) public onlyOwner {
owner = account;
authorizations[account] = true;
emit OwnershipTransferred(account);
}
event OwnershipTransferred(address owner);
}
/* Standard IDEXFactory */
interface IDEXFactory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
/* Standard IDEXRouter */
interface IDEXRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
/* Interface for the DividendDistributor */
interface IDividendDistributor {
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external;
function setShare(address shareholder, uint256 amount) external;
function deposit() external payable;
function process(uint256 gas) external;
}
/* Our DividendDistributor contract responsible for distributing the earn token */
contract DividendDistributor is IDividendDistributor {
using SafeMath for uint256;
address _token;
struct Share {
uint256 amount;
uint256 totalExcluded;
uint256 totalRealised;
}
// EARN
IBEP20 BTCB = IBEP20(0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c);
address WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
IDEXRouter router;
address[] shareholders;
mapping (address => uint256) shareholderIndexes;
mapping (address => uint256) shareholderClaims;
mapping (address => Share) public shares;
uint256 public totalShares;
uint256 public totalDividends;
uint256 public totalDistributed;
uint256 public dividendsPerShare;
uint256 public dividendsPerShareAccuracyFactor = 10 ** 36;
uint256 public minPeriod = 30 * 60;
uint256 public minDistribution = 1 * (10 ** 12);
uint256 currentIndex;
bool initialized;
modifier initialization() {
require(!initialized);
_;
initialized = true;
}
modifier onlyToken() {
require(msg.sender == _token); _;
}
constructor (address _router) {
router = _router != address(0)
? IDEXRouter(_router)
: IDEXRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E);
_token = msg.sender;
}
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external override onlyToken {
minPeriod = _minPeriod;
minDistribution = _minDistribution;
}
function setShare(address shareholder, uint256 amount) external override onlyToken {
if(shares[shareholder].amount > 0){
distributeDividend(shareholder);
}
if(amount > 0 && shares[shareholder].amount == 0){
addShareholder(shareholder);
}else if(amount == 0 && shares[shareholder].amount > 0){
removeShareholder(shareholder);
}
totalShares = totalShares.sub(shares[shareholder].amount).add(amount);
shares[shareholder].amount = amount;
shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
}
function deposit() external payable override onlyToken {
uint256 balanceBefore = BTCB.balanceOf(address(this));
address[] memory path = new address[](2);
path[0] = WBNB;
path[1] = address(BTCB);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(
0,
path,
address(this),
block.timestamp
);
uint256 amount = BTCB.balanceOf(address(this)).sub(balanceBefore);
totalDividends = totalDividends.add(amount);
dividendsPerShare = dividendsPerShare.add(dividendsPerShareAccuracyFactor.mul(amount).div(totalShares));
}
function process(uint256 gas) external override onlyToken {
uint256 shareholderCount = shareholders.length;
if(shareholderCount == 0) { return; }
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
while(gasUsed < gas && iterations < shareholderCount) {
if(currentIndex >= shareholderCount){
currentIndex = 0;
}
if(shouldDistribute(shareholders[currentIndex])){
distributeDividend(shareholders[currentIndex]);
}
gasUsed = gasUsed.add(gasLeft.sub(gasleft()));
gasLeft = gasleft();
currentIndex ;
iterations ;
}
}
function shouldDistribute(address shareholder) internal view returns (bool) {
return shareholderClaims[shareholder] minPeriod < block.timestamp
&& getUnpaidEarnings(shareholder) > minDistribution;
}
function distributeDividend(address shareholder) internal {
if(shares[shareholder].amount == 0){ return; }
uint256 amount = getUnpaidEarnings(shareholder);
if(amount > 0){
totalDistributed = totalDistributed.add(amount);
BTCB.transfer(shareholder, amount);
shareholderClaims[shareholder] = block.timestamp;
shares[shareholder].totalRealised = shares[shareholder].totalRealised.add(amount);
shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
}
}
function claimDividend(address shareholder) external onlyToken{
distributeDividend(shareholder);
}
function getUnpaidEarnings(address shareholder) public view returns (uint256) {
if(shares[shareholder].amount == 0){ return 0; }
uint256 shareholderTotalDividends = getCumulativeDividends(shares[shareholder].amount);
uint256 shareholderTotalExcluded = shares[shareholder].totalExcluded;
if(shareholderTotalDividends <= shareholderTotalExcluded){ return 0; }
return shareholderTotalDividends.sub(shareholderTotalExcluded);
}
function getCumulativeDividends(uint256 share) internal view returns (uint256) {
return share.mul(dividendsPerShare).div(dividendsPerShareAccuracyFactor);
}
function addShareholder(address shareholder) internal {
shareholderIndexes[shareholder] = shareholders.length;
shareholders.push(shareholder);
}
function removeShareholder(address shareholder) internal {
shareholders[shareholderIndexes[shareholder]] = shareholders[shareholders.length-1];
shareholderIndexes[shareholders[shareholders.length-1]] = shareholderIndexes[shareholder];
shareholders.pop();
}
}
/* Token contract */
contract Nirai is IBEP20, Auth {
using SafeMath for uint256;
// Addresses
address BTCB = 0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c;
address WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
address DEAD = 0x000000000000000000000000000000000000dEaD;
address ZERO = 0x0000000000000000000000000000000000000000;
address DEV = 0x5C32718FA88D4c04B83AB46BA0490B003CeD7c00;
// These are owner by default
address private autoLiquidityReceiver;
address private marketingFeeReceiver;
// Name and symbol
string constant _name = "Nirai Inu";
string constant _symbol = "NIRAI";
uint8 constant _decimals = 18;
// Total supply
uint256 _totalSupply = 10000000000 * (10 ** _decimals); // 1m
// Max wallet and TX
uint256 public _maxBuyTxAmount = _totalSupply * 200 / 10000; // 2% (100 mil)
uint256 public _maxSellTxAmount = _totalSupply * 100 / 10000; // 1% (100 mil)
uint256 public _maxWalletToken = ( _totalSupply * 200 ) / 10000; // 2% (100 mil)
// Mappings
mapping (address => uint256) _balances;
mapping (address => mapping (address => uint256)) _allowances;
mapping (address => bool) isFeeExempt;
mapping (address => bool) isTxLimitExempt;
mapping (address => bool) isTimelockExempt;
mapping (address => bool) isDividendExempt;
mapping (address => bool) public isBlacklisted;
// Buy Fees
uint256 public liquidityFeeBuy = 2;
uint256 public buybackFeeBuy = 0;
uint256 public reflectionFeeBuy = 0;
uint256 public marketingFeeBuy = 8;
uint256 public devFeeBuy = 0;
uint256 public totalFeeBuy = 10;
// Sell fees
uint256 public liquidityFeeSell = 0;
uint256 public buybackFeeSell = 0;
uint256 public reflectionFeeSell = 0;
uint256 public marketingFeeSell = 12;
uint256 public devFeeSell = 0;
uint256 public totalFeeSell = 12;
// Fee variables
uint256 liquidityFee;
uint256 buybackFee;
uint256 reflectionFee;
uint256 marketingFee;
uint256 devFee;
uint256 totalFee;
uint256 feeDenominator = 100;
// GREED
uint256 GREEDTriggeredAt;
uint256 GREEDDuration = 3600;
// Dead blocks
uint256 deadBlocks = 1;
// Sell amount of tokens when a sell takes place
uint256 public swapThreshold = _totalSupply * 25 / 10000; // .25% of supply
// Liquidity
uint256 targetLiquidity = 20;
uint256 targetLiquidityDenominator = 100;
// Buyback settings
uint256 buybackMultiplierNumerator = 200;
uint256 buybackMultiplierDenominator = 100;
uint256 buybackMultiplierTriggeredAt;
uint256 buybackMultiplierLength = 30 minutes;
bool public autoBuybackEnabled = false;
bool public autoBuybackMultiplier = false;
uint256 autoBuybackCap;
uint256 autoBuybackAccumulator;
uint256 autoBuybackAmount;
uint256 autoBuybackBlockPeriod;
uint256 autoBuybackBlockLast;
DividendDistributor distributor;
uint256 distributorGas = 500000;
// Cooldown & timer functionality
bool public buyCooldownEnabled = false;
uint8 public cooldownTimerInterval = 30;
mapping (address => uint) private cooldownTimer;
// Other variables
IDEXRouter public router;
address public pair;
uint256 public launchedAt;
bool public tradingOpen = true;
bool public swapEnabled = true;
bool inSwap;
modifier swapping() { inSwap = true; _; inSwap = false; }
/* Token constructor */
constructor () Auth(msg.sender) {
router = IDEXRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E);
pair = IDEXFactory(router.factory()).createPair(WBNB, address(this));
_allowances[address(this)][address(router)] = type(uint256).max;
distributor = new DividendDistributor(address(router));
// Should be the owner wallet/token distributor
address _presaler = msg.sender;
isFeeExempt[_presaler] = true;
isTxLimitExempt[_presaler] = true;
// No timelock for these people
isTimelockExempt[msg.sender] = true;
isTimelockExempt[DEAD] = true;
isTimelockExempt[address(this)] = true;
isTimelockExempt[DEV] = true;
// Exempt from dividend
isDividendExempt[pair] = true;
isDividendExempt[address(this)] = true;
isDividendExempt[DEAD] = true;
// Set the marketing and liq receiver to the owner as default
autoLiquidityReceiver = msg.sender;
marketingFeeReceiver = 0xCEC847CFe13cF00d470D6946D7c7584aD3769642;
_balances[_presaler] = _totalSupply;
emit Transfer(address(0), _presaler, _totalSupply);
}
receive() external payable { }
function totalSupply() external view override returns (uint256) { return _totalSupply; }
function decimals() external pure override returns (uint8) { return _decimals; }
function symbol() external pure override returns (string memory) { return _symbol; }
function name() external pure override returns (string memory) { return _name; }
function getOwner() external view override returns (address) { return owner; }
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
function allowance(address holder, address spender) external view override returns (uint256) { return _allowances[holder][spender]; }
function approve(address spender, uint256 amount) public override returns (bool) {
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function approveMax(address spender) external returns (bool) {
return approve(spender, type(uint256).max);
}
function transfer(address recipient, uint256 amount) external override returns (bool) {
return _transferFrom(msg.sender, recipient, amount);
}
function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
if(_allowances[sender][msg.sender] != type(uint256).max){
_allowances[sender][msg.sender] = _allowances[sender][msg.sender].sub(amount, "Insufficient Allowance");
}
return _transferFrom(sender, recipient, amount);
}
// settting the max wallet in percentages
// NOTE: 1% = 100
function setMaxWalletPercent(uint256 maxWallPercent) external onlyOwner() {
_maxWalletToken = _totalSupply.mul(maxWallPercent).div(10000);
}
// Main transfer function
function _transferFrom(address sender, address recipient, uint256 amount) internal returns (bool) {
if(inSwap){ return _basicTransfer(sender, recipient, amount); }
// Check if trading is enabled
if(!authorizations[sender] && !authorizations[recipient]){
require(tradingOpen,"Trading not enabled yet");
}
// Check if address is blacklisted
require(!isBlacklisted[recipient] && !isBlacklisted[sender], 'Address is blacklisted');
// Check if buying or selling
bool isSell = recipient == pair;
// Set buy or sell fees
setCorrectFees(isSell);
// Check max wallet
checkMaxWallet(sender, recipient, amount);
// Buycooldown
checkBuyCooldown(sender, recipient);
// Checks maxTx
checkTxLimit(sender, amount, recipient, isSell);
// Check if we are in GREEDTime
bool GREEDMode = inGREEDTime();
// Check if we should do the swapback
if(shouldSwapBack()){ swapBack(); }
//Exchange tokens
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
uint256 amountReceived = shouldTakeFee(sender) ? takeFee(sender, amount, isSell, GREEDMode) : amount;
_balances[recipient] = _balances[recipient].add(amountReceived);
// Dividend tracker
if(!isDividendExempt[sender]) {
try distributor.setShare(sender, _balances[sender]) {} catch {}
}
if(!isDividendExempt[recipient]) {
try distributor.setShare(recipient, _balances[recipient]) {} catch {}
}
try distributor.process(distributorGas) {} catch {}
emit Transfer(sender, recipient, amountReceived);
return true;
}
// Do a normal transfer
function _basicTransfer(address sender, address recipient, uint256 amount) internal returns (bool) {
_balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
return true;
}
// Set the correct fees for buying or selling
function setCorrectFees(bool isSell) internal {
if(isSell){
liquidityFee = liquidityFeeSell;
buybackFee = buybackFeeSell;
reflectionFee = reflectionFeeSell;
marketingFee = marketingFeeSell;
devFee = devFeeSell;
totalFee = totalFeeSell;
} else {
liquidityFee = liquidityFeeBuy;
buybackFee = buybackFeeBuy;
reflectionFee = reflectionFeeBuy;
marketingFee = marketingFeeBuy;
devFee = devFeeBuy;
totalFee = totalFeeBuy;
}
}
// Check if we are in GREED time
function inGREEDTime() public view returns (bool){
if(GREEDTriggeredAt.add(GREEDDuration) > block.timestamp){
return true;
} else {
return false;
}
}
// Check for maxTX
function checkTxLimit(address sender, uint256 amount, address recipient, bool isSell) internal view {
if (recipient != owner){
if(isSell){
require(amount <= _maxSellTxAmount || isTxLimitExempt[sender] || isTxLimitExempt[recipient], "TX Limit Exceeded");
} else {
require(amount <= _maxBuyTxAmount || isTxLimitExempt[sender] || isTxLimitExempt[recipient], "TX Limit Exceeded");
}
}
}
// Check buy cooldown
function checkBuyCooldown(address sender, address recipient) internal {
if (sender == pair &&
buyCooldownEnabled &&
!isTimelockExempt[recipient]) {
require(cooldownTimer[recipient] < block.timestamp,"Please wait between two buys");
cooldownTimer[recipient] = block.timestamp cooldownTimerInterval;
}
}
// Check maxWallet
function checkMaxWallet(address sender, address recipient, uint256 amount) internal view {
if (!authorizations[sender] && recipient != owner && recipient != address(this) && recipient != address(DEAD) && recipient != pair && recipient != marketingFeeReceiver && recipient != autoLiquidityReceiver && recipient != DEV){
uint256 heldTokens = balanceOf(recipient);
require((heldTokens amount) <= _maxWalletToken,"Total Holding is currently limited, you can not buy that much.");
}
}
// Check if sender is not feeExempt
function shouldTakeFee(address sender) internal view returns (bool) {
return !isFeeExempt[sender];
}
// Get total fee's or multiplication of fees
function getTotalFee(bool selling) public view returns (uint256) {
if(launchedAt deadBlocks >= block.number){ return feeDenominator.sub(1); }
if(selling && buybackMultiplierTriggeredAt.add(buybackMultiplierLength) > block.timestamp){ return getMultipliedFee(); }
return totalFee;
}
// Get a multiplied fee when buybackMultiplier is active
function getMultipliedFee() public view returns (uint256) {
uint256 remainingTime = buybackMultiplierTriggeredAt.add(buybackMultiplierLength).sub(block.timestamp);
uint256 feeIncrease = totalFee.mul(buybackMultiplierNumerator).div(buybackMultiplierDenominator).sub(totalFee);
return totalFee.add(feeIncrease.mul(remainingTime).div(buybackMultiplierLength));
}
// Take the normal total Fee or the GREED Fee
function takeFee(address sender, uint256 amount, bool isSell, bool GREEDMode) internal returns (uint256) {
uint256 feeAmount;
// Check if we are GREEDd
if (GREEDMode){
if(isSell){
// We are selling so up the selling tax to 1.5x
feeAmount = amount.mul(totalFee).mul(3).div(2).div(feeDenominator);
} else {
// We are buying so cut our taxes in half
feeAmount = amount.mul(totalFee).div(2).div(feeDenominator);
}
} else {
feeAmount = amount.mul(totalFee).div(feeDenominator);
}
_balances[address(this)] = _balances[address(this)].add(feeAmount);
emit Transfer(sender, address(this), feeAmount);
return amount.sub(feeAmount);
}
// Check if we should sell tokens
function shouldSwapBack() internal view returns (bool) {
return msg.sender != pair
&& !inSwap
&& swapEnabled
&& _balances[address(this)] >= swapThreshold;
}
// switch Trading
function tradingStatus(bool _status) public onlyOwner {
tradingOpen = _status;
launch();
}
// Enable GREED
function enableGREED(uint256 _seconds) public authorized {
GREEDTriggeredAt = block.timestamp;
GREEDDuration = _seconds;
}
// Disable the GREED mode
function disableGREED() external authorized {
GREEDTriggeredAt = 0;
}
// Enable/disable cooldown between trades
function cooldownEnabled(bool _status, uint8 _interval) public authorized {
buyCooldownEnabled = _status;
cooldownTimerInterval = _interval;
}
// Blacklist/unblacklist an address
function blacklistAddress(address _address, bool _value) public authorized{
isBlacklisted[_address] = _value;
}
// Main swapback to sell tokens for WBNB
function swapBack() internal swapping {
uint256 dynamicLiquidityFee = isOverLiquified(targetLiquidity, targetLiquidityDenominator) ? 0 : liquidityFee;
uint256 amountToLiquify = swapThreshold.mul(dynamicLiquidityFee).div(totalFee).div(2);
uint256 amountToSwap = swapThreshold.sub(amountToLiquify);
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = WBNB;
uint256 balanceBefore = address(this).balance;
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
amountToSwap,
0,
path,
address(this),
block.timestamp
);
uint256 amountBNB = address(this).balance.sub(balanceBefore);
uint256 totalBNBFee = totalFee.sub(dynamicLiquidityFee.div(2));
uint256 amountBNBLiquidity = amountBNB.mul(dynamicLiquidityFee).div(totalBNBFee).div(2);
uint256 amountBNBReflection = amountBNB.mul(reflectionFee).div(totalBNBFee);
uint256 amountBNBMarketing = amountBNB.mul(marketingFee).div(totalBNBFee);
uint256 amountBNBDev = amountBNB.mul(devFee).div(totalBNBFee);
try distributor.deposit{value: amountBNBReflection}() {} catch {}
(bool successMarketing, /* bytes memory data */) = payable(marketingFeeReceiver).call{value: amountBNBMarketing, gas: 30000}("");
(bool successDev, /* bytes memory data */) = payable(DEV).call{value: amountBNBDev, gas: 30000}("");
require(successMarketing, "marketing receiver rejected ETH transfer");
require(successDev, "dev receiver rejected ETH transfer");
if(amountToLiquify > 0){
router.addLiquidityETH{value: amountBNBLiquidity}(
address(this),
amountToLiquify,
0,
0,
autoLiquidityReceiver,
block.timestamp
);
emit AutoLiquify(amountBNBLiquidity, amountToLiquify);
}
}
// Check if autoBuyback is enabled
function shouldAutoBuyback() internal view returns (bool) {
return msg.sender != pair
&& !inSwap
&& autoBuybackEnabled
&& autoBuybackBlockLast autoBuybackBlockPeriod <= block.number
&& address(this).balance >= autoBuybackAmount;
}
// Trigger a manual buyback
function triggerManualBuyback(uint256 amount, bool triggerBuybackMultiplier) external authorized {
uint256 amountWithDecimals = amount * (10 ** 18);
uint256 amountToBuy = amountWithDecimals.div(100);
buyTokens(amountToBuy, DEAD);
if(triggerBuybackMultiplier){
buybackMultiplierTriggeredAt = block.timestamp;
emit BuybackMultiplierActive(buybackMultiplierLength);
}
}
// Stop the buyback Multiplier
function clearBuybackMultiplier() external authorized {
buybackMultiplierTriggeredAt = 0;
}
// Trigger an autobuyback
function triggerAutoBuyback() internal {
buyTokens(autoBuybackAmount, DEAD);
if(autoBuybackMultiplier){
buybackMultiplierTriggeredAt = block.timestamp;
emit BuybackMultiplierActive(buybackMultiplierLength);
}
autoBuybackBlockLast = block.number;
autoBuybackAccumulator = autoBuybackAccumulator.add(autoBuybackAmount);
if(autoBuybackAccumulator > autoBuybackCap){ autoBuybackEnabled = false; }
}
// Buy amount of tokens with bnb from the contract
function buyTokens(uint256 amount, address to) internal swapping {
address[] memory path = new address[](2);
path[0] = WBNB;
path[1] = address(this);
router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amount}(
0,
path,
to,
block.timestamp
);
}
// Set autobuyback settings
function setAutoBuybackSettings(bool _enabled, uint256 _cap, uint256 _amount, uint256 _period, bool _autoBuybackMultiplier) external authorized {
autoBuybackEnabled = _enabled;
autoBuybackCap = _cap;
autoBuybackAccumulator = 0;
autoBuybackAmount = _amount;
autoBuybackBlockPeriod = _period;
autoBuybackBlockLast = block.number;
autoBuybackMultiplier = _autoBuybackMultiplier;
}
// Set buybackmultiplier settings
function setBuybackMultiplierSettings(uint256 numerator, uint256 denominator, uint256 length) external authorized {
require(numerator / denominator <= 2 && numerator > denominator);
buybackMultiplierNumerator = numerator;
buybackMultiplierDenominator = denominator;
buybackMultiplierLength = length;
}
// Check when the token is launched
function launched() internal view returns (bool) {
return launchedAt != 0;
}
// Set the launchedAt to token launch
function launch() internal {
launchedAt = block.number;
}
// Set max buy TX
function setBuyTxLimitInPercent(uint256 maxBuyTxPercent) external authorized {
_maxBuyTxAmount = _totalSupply.mul(maxBuyTxPercent).div(10000);
}
// Set max sell TX
function setSellTxLimitInPercent(uint256 maxSellTxPercent) external authorized {
_maxSellTxAmount = _totalSupply.mul(maxSellTxPercent).div(10000);
}
// Exempt from dividend
function setIsDividendExempt(address holder, bool exempt) external authorized {
require(holder != address(this) && holder != pair);
isDividendExempt[holder] = exempt;
if(exempt){
distributor.setShare(holder, 0);
}else{
distributor.setShare(holder, _balances[holder]);
}
}
// Exempt from fee
function setIsFeeExempt(address holder, bool exempt) external authorized {
isFeeExempt[holder] = exempt;
}
// Exempt from max TX
function setIsTxLimitExempt(address holder, bool exempt) external authorized {
isTxLimitExempt[holder] = exempt;
}
// Exempt from buy CD
function setIsTimelockExempt(address holder, bool exempt) external authorized {
isTimelockExempt[holder] = exempt;
}
// Set our buy fees
function setBuyFees(uint256 _liquidityFeeBuy, uint256 _buybackFeeBuy, uint256 _reflectionFeeBuy, uint256 _marketingFeeBuy, uint256 _devFeeBuy, uint256 _feeDenominator) external authorized {
liquidityFeeBuy = _liquidityFeeBuy;
buybackFeeBuy = _buybackFeeBuy;
reflectionFeeBuy = _reflectionFeeBuy;
marketingFeeBuy = _marketingFeeBuy;
devFeeBuy = _devFeeBuy;
totalFeeBuy = _liquidityFeeBuy.add(_buybackFeeBuy).add(_reflectionFeeBuy).add(_marketingFeeBuy).add(_devFeeBuy);
feeDenominator = _feeDenominator;
}
// Set our sell fees
function setSellFees(uint256 _liquidityFeeSell, uint256 _buybackFeeSell, uint256 _reflectionFeeSell, uint256 _marketingFeeSell, uint256 _devFeeSell, uint256 _feeDenominator) external authorized {
liquidityFeeSell = _liquidityFeeSell;
buybackFeeSell = _buybackFeeSell;
reflectionFeeSell = _reflectionFeeSell;
marketingFeeSell = _marketingFeeSell;
devFeeSell = _devFeeSell;
totalFeeSell = _liquidityFeeSell.add(_buybackFeeSell).add(_reflectionFeeSell).add(_marketingFeeSell).add(_devFeeSell);
feeDenominator = _feeDenominator;
}
// Set the marketing and liquidity receivers
function setFeeReceivers(address _autoLiquidityReceiver, address _marketingFeeReceiver) external authorized {
autoLiquidityReceiver = _autoLiquidityReceiver;
marketingFeeReceiver = _marketingFeeReceiver;
}
// Set swapBack settings
function setSwapBackSettings(bool _enabled, uint256 _amount) external authorized {
swapEnabled = _enabled;
swapThreshold = _totalSupply * _amount / 10000;
}
// Set target liquidity
function setTargetLiquidity(uint256 _target, uint256 _denominator) external authorized {
targetLiquidity = _target;
targetLiquidityDenominator = _denominator;
}
// Send BNB to marketingwallet
function manualSend() external authorized {
uint256 contractETHBalance = address(this).balance;
payable(marketingFeeReceiver).transfer(contractETHBalance);
}
// Set criteria for auto distribution
function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external authorized {
distributor.setDistributionCriteria(_minPeriod, _minDistribution);
}
// Let people claim there dividend
function claimDividend() external {
distributor.claimDividend(msg.sender);
}
// Check how much earnings are unpaid
function getUnpaidEarnings(address shareholder) public view returns (uint256) {
return distributor.getUnpaidEarnings(shareholder);
}
// Set gas for distributor
function setDistributorSettings(uint256 gas) external authorized {
require(gas < 750000);
distributorGas = gas;
}
// Get the circulatingSupply
function getCirculatingSupply() public view returns (uint256) {
return _totalSupply.sub(balanceOf(DEAD)).sub(balanceOf(ZERO));
}
// Get the liquidity backing
function getLiquidityBacking(uint256 accuracy) public view returns (uint256) {
return accuracy.mul(balanceOf(pair).mul(2)).div(getCirculatingSupply());
}
// Get if we are over liquified or not
function isOverLiquified(uint256 target, uint256 accuracy) public view returns (bool) {
return getLiquidityBacking(accuracy) > target;
}
event AutoLiquify(uint256 amountBNB, uint256 amountBOG);
event BuybackMultiplierActive(uint256 duration);
}