// File: /contracts/NTWO.sol



pragma solidity ^0.8.9;
pragma experimental ABIEncoderV2;

// SPDX-License-Identifier:MIT
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
interface IBEP20 {

    function totalSupply() external view returns (uint256);

    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);
}

abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return payable(msg.sender);
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

contract Ownable is Context {
    address payable private _owner;
    address payable private _previousOwner;
    uint256 private _lockTime;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor () {
        _owner = _msgSender();
        emit OwnershipTransferred(address(0), _owner);
    }

    function owner() public view returns (address) {
        return _owner;
    }

    modifier onlyOwner() {
        require(_owner == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = payable(address(0));
    }

    function transferOwnership(address payable newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }

    function geUnlockTime() public view returns (uint256) {
        return _lockTime;
    }

    //Locks the contract for owner for the amount of time provided
    function lock(uint256 time) public virtual onlyOwner {
        _previousOwner = _owner;
        _owner = payable(address(0));
        _lockTime = block.timestamp + time;
        emit OwnershipTransferred(_owner, address(0));
    }

    //Unlocks the contract for owner when _lockTime is exceeds
    function unlock() public virtual {
        require(_previousOwner == msg.sender, "You don't have permission to unlock");
        require(block.timestamp > _lockTime , "Contract is locked until defined days");
        emit OwnershipTransferred(_owner, _previousOwner);
        _owner = _previousOwner;
        _previousOwner = payable(address(0));
    }
}

interface IUniswapFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

interface IUniswapPair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

interface IUniswapRouter01 {
    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 removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountETH);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
    external
    payable
    returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
    external
    returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
    external
    returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
    external
    payable
    returns (uint[] memory amounts);

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

interface IUniswapRouter02 is IUniswapRouter01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);

    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;
}


contract NTWO is Context, IBEP20, Ownable,ReentrancyGuard {
    using SafeMath for uint256;

    mapping(address => uint256) private _rOwned;
    mapping(address => uint256) private _tOwned;
    mapping(address => mapping(address => uint256)) private _allowances;

    mapping(address => bool) private _isExcludedFromFee;
    mapping(address => bool) private _isExcluded;

    address[] private _excluded;

    uint256 private constant MAX = ~uint256(0);
    uint256 private _tTotal = 3_000_000* 10**18;
    uint256 private maxSupply = 3_000_000 * 10**18;
    uint256 private _rTotal = (MAX - (MAX % _tTotal));
    uint256 private _tFeeTotal;

    string private _name = "NUME2";
    string private _symbol = "NTWO";
    uint8 private _decimals = 18;

    IUniswapRouter02 public uniswapRouter;
    address public uniswapPair;
    address payable public marketWallet;
    address public burnAddress = 0x000000000000000000000000000000000000dEaD;

    uint256 public minimumTokensBeforeSwap ;
    uint256 public tokenUnlockTime;

    bool public swapAndLiquifyEnabled = false; // should be true to turn on to liquidate the pool
    bool public reflectionFeesdiabled = false; // should be false to charge fee
    bool inSwapAndLiquify;
    
    uint256 public _taxFee ; 
    uint256 public _taxBuyFee = 0; // 0% will be distributed among holder as token divideneds
    uint256 public _taxSellFee = 0; // 0% will be distributed among holder as token divideneds

    uint256 public _liquidityFee ;
    uint256 public _liquidityBuyFee = 0; // 0% will be added to the liquidity pool
    uint256 public _liquiditySellFee = 20; // 1% will be added to the liquidity pool

    
    uint256 public _marketFee;  
    uint256 public _marketBuyFee = 0;  // 0% will go to the market address 
    uint256 public _marketSellFee = 20;  // 1% will go to the market address 
    
    uint256 public _burnFee;  
    uint256 public _burnBuyFee = 0;  // 0% will go to the Dead address to deflate token
    uint256 public _burnSellFee = 0;  // 0% will go to the Dead address to deflate token

    address payable public treasury;
    uint256 public treasuryMintTime;
    uint256 public unlockAmount;
    uint256 private initalMint; 
    uint256 public mintedAmount; 
    bool public _takeFee ;
    uint256 public feeUpdationLimit;


    uint256 public totalLiqudityFeeCollected;
    uint256 public totalMarketFeeCollected;
    uint256 public totalDevFeeCollected;

    event SwapAndLiquifyEnabledUpdated(bool enabled);
    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensIntoLiqudity
    );
     event TransferForeignToken(address token, uint256 amount);
    
    
    modifier lockTheSwap {
        inSwapAndLiquify = true;
        _;
        inSwapAndLiquify = false;
    }

    constructor (address _marketAddress,address _treasury)     {
        marketWallet = payable(_marketAddress);
        treasury = payable(_treasury);
         _takeFee = true;
         feeUpdationLimit=40;
         IUniswapRouter02 _uniswapRouter = IUniswapRouter02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); //uniswap mainnet & testnet Router
        // Create a uniswap pair for this new token
        uniswapPair = IUniswapFactory(_uniswapRouter.factory())
        .createPair(address(this), _uniswapRouter.WETH());

        // set the rest of the contract variables
        uniswapRouter = _uniswapRouter;

        //exclude owner and this contract from fee
        _isExcludedFromFee[owner()] = true;
        _isExcludedFromFee[address(this)] = true;
        initalMint = 1_000_000*1e18;
        unlockAmount = 100_000*1e18;
        tokenUnlockTime= 262800 minutes;
        minimumTokensBeforeSwap = 1; // 0.0001% of totalSupply swap tokens amount 
        _tOwned[treasury] += initalMint - unlockAmount;
        _tOwned[uniswapPair] += unlockAmount;
        mintedAmount  = initalMint;
        treasuryMintTime=block.timestamp;
   
        emit Transfer(address(0), treasury, initalMint-unlockAmount);
        emit Transfer(address(0), uniswapPair, unlockAmount);
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function symbol() public view returns (string memory) {
        return _symbol;
    }

    function decimals() public view returns (uint8) {
        return _decimals;
    }

    function totalSupply() public view override returns (uint256) {
        return _tTotal;
    }

    function balanceOf(address account) public view override returns (uint256) {
         return _tOwned[account];
       
    }

    function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance"));
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "BEP20: decreased allowance below zero"));
        return true;
    }

    function isExcludedFromReward(address account) public view returns (bool) {
        return _isExcluded[account];
    }

    function totalFees() public view returns (uint256) {
        return _tFeeTotal;
    }

  

    function excludeFromReward(address account) public onlyOwner {
        require(!_isExcluded[account], "Account is already excluded");
        _isExcluded[account] = true;
        _excluded.push(account);
    }

    

       function unlockToken() external onlyOwner {
        require(block.timestamp >= treasuryMintTime + tokenUnlockTime  ,"You cannot unlock before time ");
        uint256 time= (block.timestamp - treasuryMintTime) / tokenUnlockTime ;
        uint256 amount = time * unlockAmount ;
        require(amount > 0, "no more to unlock");
        require( mintedAmount <= maxSupply , "max supply reached");
        if(amount + mintedAmount > maxSupply){
            uint256 _amount = maxSupply-mintedAmount;
          _tOwned[treasury] += _amount;
          mintedAmount +=_amount;

        }
        else{
            _tOwned[treasury] += amount;
             mintedAmount +=amount;
        }
        treasuryMintTime +=  time * tokenUnlockTime;
        emit Transfer(address(this), treasury, amount);
    }

    function excludeFromFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = true;
    }

    function includeInFee(address account) public onlyOwner {
        _isExcludedFromFee[account] = false;
    }

    function setTaxBuyFeePercent(uint256 taxFee, uint256 liquidityFee, uint256 marketFee, uint256 burnFee) external onlyOwner {
        _taxBuyFee = taxFee;
        _liquidityBuyFee = liquidityFee;
        _marketBuyFee = marketFee;
        _burnBuyFee = burnFee;
    }
    function setTaxSellFeePercent(uint256 liquidityFee, uint256 marketFee) external onlyOwner {
        require((liquidityFee + marketFee) <= feeUpdationLimit,"Taxfee must less than 4%");
        _liquiditySellFee = liquidityFee;
        _marketSellFee = marketFee;
    }
    function changefeeUpdationLimit(uint256 _limit) external onlyOwner{
        feeUpdationLimit=_limit;
    }
    function setFeeEnableOrDisable(bool _status) external{
        _takeFee=_status;
    } 

    function setSwapAndLiquifyEnabled(bool _state) public onlyOwner {
        swapAndLiquifyEnabled = _state;
        emit SwapAndLiquifyEnabledUpdated(_state);
    }

    function setReflectionFees(bool _state) external onlyOwner {
        reflectionFeesdiabled = _state;
    }

    function setTreasuryAddress(address _treasury) external onlyOwner{
        treasury=payable(_treasury);
    }

    function setTokenUnlockAmount(uint256 amount) external onlyOwner{
        unlockAmount=amount;
    }
    
    
    function setMarketAddress(address payable _marketAddress) external onlyOwner {
        marketWallet = _marketAddress;
    }
    

    function setRoute(IUniswapRouter02 _router, address _pair) external onlyOwner {
        uniswapRouter = _router;
        uniswapPair = _pair;
    }

    //to receive Eth from uniswapRouter when swapping
    receive() external payable {}
    
    function totalFeePerTx(uint256 tAmount) internal view returns(uint256) {
        uint256 percentage = tAmount.mul(_taxFee.add(_liquidityFee).add(_marketFee).add(_burnFee)).div(1e3);
        return percentage;
    }


  

    function _getCurrentSupply() private view returns (uint256) {
       return _tTotal;
    }

    function _takeLiquidityPoolFee(uint256 tAmount) internal {
        uint256 tPoolFee = tAmount.mul(_liquidityFee).div(1e3);
        _tOwned[address(this)] = _tOwned[address(this)].add(tPoolFee);
        totalLiqudityFeeCollected += tPoolFee;
        emit Transfer(_msgSender(), address(this), tPoolFee);
    }
    

    function _takeMarketFee(uint256 tAmount) internal {
        uint256 tMarketFee = tAmount.mul(_marketFee).div(1e3);
        _tOwned[address(this)] = _tOwned[address(this)].add(tMarketFee);
        totalMarketFeeCollected +=tMarketFee;
        emit Transfer(_msgSender(), address(this), tMarketFee);
    }


    function removeAllFee() private {

        _liquidityFee = 0;
        _marketFee = 0;
    }

    
    function isExcludedFromFee(address account) public view returns (bool) {
        return _isExcludedFromFee[account];
    }

    function _approve(address owner, address spender, uint256 amount) private {
        require(owner != address(0), "BEP20: approve from the zero address");
        require(spender != address(0), "BEP20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) private {
        require(from != address(0), "BEP20: transfer from the zero address");
        require(to != address(0), "BEP20: transfer to the zero address");
        require(amount > 0, "BEP20: Transfer amount must be greater than zero");

        // swap and liquify
        if (
            !inSwapAndLiquify &&
            from != uniswapPair &&
            swapAndLiquifyEnabled &&
            !(from == address(this) && to == address(uniswapPair)) // swap 1 time
        ) {
            swapAndLiquify();
        }

        //indicates if fee should be deducted from transfer
        bool takeFee = _takeFee;

        //if any account belongs to _isExcludedFromFee account then remove the fee
        if (_isExcludedFromFee[from] || _isExcludedFromFee[to] || reflectionFeesdiabled || (from!=uniswapPair && to!=uniswapPair )) {
            takeFee = false;
        }

        //transfer amount, it will take tax, burn, liquidity fee

         if(to==uniswapPair){
            _liquidityFee=_liquiditySellFee;
            _marketFee=_marketSellFee;
        _tokenTransfer(from, to, amount, takeFee);
             
        }
        else{
            _liquidityFee=0;
            _marketFee=0;
        _tokenTransfer(from, to, amount, takeFee);
        }
    }

    //this method is responsible for taking all fee, if takeFee is true
    function _tokenTransfer(address sender, address recipient, uint256 amount, bool takeFee) private {
        if (!takeFee){
            removeAllFee();
        }

        if (_isExcluded[sender] && !_isExcluded[recipient]) {
            _transferFromExcluded(sender, recipient, amount , takeFee);
        } else if (!_isExcluded[sender] && _isExcluded[recipient]) {
            _transferToExcluded(sender, recipient, amount , takeFee);
        } else if (_isExcluded[sender] && _isExcluded[recipient] ) {
            _transferBothExcluded(sender, recipient, amount , takeFee);
        } else {
            _transferStandard(sender, recipient, amount, takeFee);
        }
    }

    function _transferStandard(address sender, address recipient, uint256 tAmount, bool takeFee) private {
        uint256 tTransferAmount = tAmount.sub(totalFeePerTx(tAmount));
        _tOwned[sender] = _tOwned[sender].sub(tAmount);
        _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
        if(takeFee){
        _takeLiquidityPoolFee(tAmount);
        _takeMarketFee(tAmount);
        }
       
        emit Transfer(sender, recipient, tTransferAmount);
    }

    function _transferToExcluded(address sender, address recipient, uint256 tAmount, bool takeFee) private {
        uint256 tTransferAmount = tAmount.sub(totalFeePerTx(tAmount));
        _tOwned[sender] = _tOwned[sender].add(tAmount);
        _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
        if(takeFee){
        _takeLiquidityPoolFee(tAmount);
        _takeMarketFee(tAmount);
        }
        emit Transfer(sender, recipient, tTransferAmount);
    }

    function _transferFromExcluded(address sender, address recipient, uint256 tAmount, bool takeFee) private {
        uint256 tTransferAmount = tAmount.sub(totalFeePerTx(tAmount));
        _tOwned[sender] = _tOwned[sender].sub(tAmount);
        _tOwned[recipient] = _tOwned[recipient].sub(tTransferAmount);
        if(takeFee){
        _takeLiquidityPoolFee(tAmount);
        _takeMarketFee(tAmount);
        }
        emit Transfer(sender, recipient, tTransferAmount);
    }
    
    function _transferBothExcluded(address sender, address recipient, uint256 tAmount, bool takeFee) private {
        uint256 tTransferAmount = tAmount.sub(totalFeePerTx(tAmount));
        _tOwned[sender] = _tOwned[sender].sub(tAmount);
        _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount);
        if(takeFee){
        _takeLiquidityPoolFee(tAmount);
        _takeMarketFee(tAmount);
        }
        emit Transfer(sender, recipient, tTransferAmount);
    }

    function swapAndLiquify() private  lockTheSwap {
        uint256 contractBalance = balanceOf(address(this));
        uint256 totalTokensToSwap = totalLiqudityFeeCollected + totalMarketFeeCollected ;
        bool success;
       
       if(contractBalance >= minimumTokensBeforeSwap ){
            contractBalance = minimumTokensBeforeSwap;
        }
        if(contractBalance == 0 || totalTokensToSwap == 0) {return;}
        // Halve the amount of liquidity tokens
        uint256 tokensForLiquidity = ((contractBalance * totalLiqudityFeeCollected )/ totalTokensToSwap) / 2;
        uint256 amountToSwapForETH = contractBalance.sub(tokensForLiquidity);
        
        uint256 initialETHBalance = address(this).balance;

         _approve(address(this), address(uniswapRouter), amountToSwapForETH);
         Utils.swapTokensForEth(address(uniswapRouter),amountToSwapForETH);

        
        uint256 ethBalance = address(this).balance.sub(initialETHBalance);
        
        uint256 ethForMarketing = ethBalance.mul(totalMarketFeeCollected).div(totalTokensToSwap - (totalMarketFeeCollected/2));        
        uint256 ethForLiquidity = ethBalance - ethForMarketing ;
        
        totalLiqudityFeeCollected = 0;
        totalMarketFeeCollected = 0;
                
        if(tokensForLiquidity > 0 && ethForLiquidity > 0){
            _approve(address(this), address(uniswapRouter), tokensForLiquidity);
            Utils.addLiquidity(address(uniswapRouter) ,address(0xdead),tokensForLiquidity, ethForLiquidity);
            emit SwapAndLiquify(amountToSwapForETH, ethForLiquidity, tokensForLiquidity);
        }
        // send remainder to marketing
        (success,) = address(marketWallet).call{value: address(this).balance}("");
    } 

       function withdrawStuckToken(address _token, address _to)
        external
        onlyOwner
        returns (bool _sent)
    {
        require(_token != address(0), "_token address cannot be 0");
        require(_token != address(uniswapPair), "Can't withdraw Native LP tokens with this method");
        uint256 _contractBalance = IBEP20(_token).balanceOf(address(this));
        _sent = IBEP20(_token).transfer(_to, _contractBalance);
        emit TransferForeignToken(_token, _contractBalance);
    }
    
    // withdraw ETH if stuck before launch
    function withdrawStuckETH(address payable _to) external onlyOwner {
        bool success;
        (success,) = address(_to).call{value: address(this).balance}("");
    }  

    
      // change the minimum amount of tokens to sell from fees
    function updateMinimumTokensBeforeSwap(uint256 newAmount) external onlyOwner{
  	    require(newAmount >= _tTotal * 1 / 100000, "Swap amount cannot be lower than 0.001% total supply.");
  	    require(newAmount <= _tTotal * 5 / 1000, "Swap amount cannot be higher than 0.5% total supply.");
  	    minimumTokensBeforeSwap = newAmount;
  	}

    function totalPercentFeesOnSelling() external view returns (uint256) {
        return (_liquiditySellFee + _marketSellFee)/100;
    }
    function setTokenUnlockTime(uint256 _time) public onlyOwner{
        tokenUnlockTime=_time;
    }


    
}

library Utils {
    using SafeMath for uint256;
     
    function swapTokensForEth(
        address routerAddress,
        uint256 tokenAmount
    ) internal {
        IUniswapRouter02 uniswapRouter = IUniswapRouter02(routerAddress);

        // generate the pancake pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapRouter.WETH();

        // make the swap
        uniswapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of BNB
            path,
            address(this),
            block.timestamp + 300
        );
    }

    function swapETHForTokens(
        address routerAddress,
        address recipient,
        uint256 ethAmount
    ) internal {
        IUniswapRouter02 uniswapRouter = IUniswapRouter02(routerAddress);

        // generate the uniswap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = uniswapRouter.WETH();
        path[1] = address(this);

        // make the swap
        uniswapRouter.swapExactETHForTokensSupportingFeeOnTransferTokens{value: ethAmount}(
            0, // accept any amount of BNB
            path,
            address(recipient),
            block.timestamp + 300
        );
    }

    function addLiquidity(
        address routerAddress,
        address owner,
        uint256 tokenAmount,
        uint256 ethAmount
    ) internal {
        IUniswapRouter02 uniswapRouter = IUniswapRouter02(routerAddress);

        // add the liquidity
        uniswapRouter.addLiquidityETH{value : ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            owner,
            block.timestamp + 300
        );
    }
}

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) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        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) {
        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;
    }

    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol



// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}