/**
                                                                 ▄╖╓  
                                                              ▄▓╨─,»ƒ≈, 
                                                            ▄██▌⌐,¬Q ░U⌂.
                                                         ▄█▓▓┘^^2,┐VΣ⌐^∩╩»
                                                      ,▄▓▓█▓Q╠"░¬¬╙í╙▐l¿-╚▀╓ 
                                                    ,#▓▓▓▓▓µ╙eµOΓÇ⌠"▄└w¬▐»⌠╩╚] 
                                                 ╓▓▓██▓▓▌╪p"╗╗Åε"∩░ⁿ╩╨╗C╞wN./ÜU⌐ 
                                               ▄▓█▓▓█▓╣▀▒╗╪çj╥╘»^"≡╙»¬⌂"Ç╪\j "¬└⌡╖
                                             ▄▓▓▀▓▓▓▓▓╙╩^~└┘┘h ¬Ö╥⌠└╚ƒ░,⌡Ü╙-╛╤";--╥≈
                                           ▄██▌▓▓███▌b*╥ └J╥ │░╙├╓b┘▌5▄╠╣v░j╙╕╔╬J╔▐┴╝Æ 
                                         ▄███▓╣▓▓██▌ `╜─'╙░Å╕▀⌐µ∩──┘╥╢▒▄▒▀┬▐▄*▒▐╙▄▒▄═╘╬½ 
                                      ▄▓▓█▓▓██▓▓▓▓▌.╙l-j▄½-≤│╙²~▄╡ ┴▄╚╠%┐`▐Ñ╜Θ╘⌠▐╛▌▀╛╜╨Ö»=╥
                                   .▄█▓█▓▓▓▓▓████▌«G,M╙t"ΓJÖN╚tÅ:`ÅM⌂╙ñ╙╗²#╥╖╟║▐7╚/▒d╚p╦▒\▐╩╗ 
                                 ╓▄█▓▓▓██▓█▓█▓█▀ ╦╙h╙Å╡└I"7╚",ΓΣ`╩▄┘ª╓"µ╘,╙"*ƒ└┐╥╠ ▌┤Φµ▐Σ╔╜╪╫▒⌐
                              ▄▓▓▓█▓▓╣╬▓▓▓███▓▀ª▄^.- └J▄ N.≈.╩╘/╩`▐.╠`─▒┘▄╖≈─ÖÿΓ╚╧─╠╥▒╡Æ╙╥╬╦╠╔╫╫▄  
                            ▄▓▓▀█▌╬▓▓▓▓▌▓████ ▄Στ¬ƒ"⌐Ot{⌐ΣD,M,╞#╘─^ÄƒÖ> Ωⁿⁿ-;`¬,Θb╙─`┬╙-\⌡▒⌠"ƒ▄▄⌂╙▒╥
                          ▄█▓▓▓█▌▌▓▓█▓█▓███▓▀▄╙,╗τ║▒O,║ ¥▄░Cⁿ√,│╓╛.░≈╚▌└$∩^^ [¡%╘╓\]>Y⌐≤Γ╝╚≥╨╠╘Å╦ΦmÜ⌠w 
                        ▄▓▓▓▓╫▓▓╬▓▓▓▓▓▓▓█▓▓.MÑδçD,╡æε▐≤. ⌐▌L≥"C]j╔∞,]"3▒^L"╓,═╙U╓╛▐╙╛╨ε├╡╝ÖΦQ▄═╙▀▌╔╪╟╩▌╥ 
                     ▄█▓▓▓▓▌╫▓▓▓▓▌█▓▌██▓╩¿╧ⁿJ╙⌂╧,Σ&Γ▄.ïΓⁿ,Σ└". ╙¼,N⌐∩▄▄⌐»J╥≥*└└═Θ?%▒▒╛¬▀Γ╪╘,╦╨⌐Q╛┤Qæ╛▐▐▒╗⌠"
                  ╓▓▓▓▓╬▓▓▓╣▓▓▓▓▓▓█╣█▓▌▀¬≈▌▄{,▒"Θ╥½,%*"┘"~²Y\Hê⌂»╙?.T└┴╫p\╞╙▄└ ▄┐p²▐╨╬╨*┘╥╙µ╫╩dæ⌡▐,▐Ö╓É"▐▄Γª⌠" 
                ▄▓▓▓▓▓▓╣▓▓▓█▓▓██▓█▓█▌▓╝─▐▒▌▒▀@▀µ▒╣╚7╚▒▌▒²╬ç▀▄╙╨▄╜╚▒╟=╙╝╨╬▀ΓÇÑ╖åΓ╜ΓÇ.,╚ ├"Σ▒▒╠≡▒▐╓╓╙╥╝╙5╫╬▐╚╬▄╝╦⌠"
              ▄▓                                                                                              ▒▄▐▒╗⌐
            ▄▓▓▓          ><         ><< <<   ><<<><<<<<<><<<<<<<          ><       ><<<<<<<<      ><         ╬▐▒╗╟▄▄╓  
         ▄▓▓▓▓╫▓         >< <<     ><<    ><<     ><<    ><<    ><<       >< <<     ><<           >< <<       ⌠"▐▒╗▄▄╝╦╜
      ▄▓▓▓▓╫▓▓╬▓        ><  ><<     ><<           ><<    ><<    ><<      ><  ><<    ><<          ><  ><<      æ⌠"╛▐▒╗▐▐▄▄▄
        ▀▓▐▐╛æb┤       ><<   ><<      ><<         ><<    >< ><<         ><<   ><<   ><<<<<<     ><<   ><<     ⌠"æ▐▄▄▒╗╩▄ 
          ▀▓╬▓▓▓      ><<<<<< ><<        ><<      ><<    ><<  ><<      ><<<<<< ><<  ><<        ><<<<<< ><<    Ü⌠▐▄▄▒╗"w
            ▀▓╬▓     ><<       ><< ><<    ><<     ><<    ><<    ><<   ><<       ><< ><<       ><<       ><<   ╩▌▄▄▄▄╥
              ▀▓    ><<         ><<  ><< <<       ><<    ><<      ><<><<         ><<><<<<<<<<><<         ><<  ▒▄▄▄▄╥
               ▀                                                                                              ╗▄▄▄
                 ▀▓▓╬▓▓▓╣▓▓▓▓▓▓█╣█▓▌▓╝─▐▒▌▒▀@▀µ▒╣╚7╚▒▌▒²╬ç▀▄╙╨▄╜╚▒╟=╙╝╨╬▀ΓÇÑ╖åΓ╜ΓÇ.,╚ ├"Σ▒▒╠≡▒▐╓╓╙╥╝╙5╫╬▐╚╬╝╦▄▄▄
                   ▀▓▀█▌╬▓▓▓▓▓▓▓▓                                                                    æ⌠"ƒ▄▄─╠╥▒╡
                     ▀▓ ▀█▌╬▓▓▓▓▓           𓂀         ASTRAEA - E PLURIBUS UNUM          𓂀         ╥╬ ─╠▒╡╙╥
                       ▀▓ ▓▓▓▓▓▓▓                                                                    ╪─╠╥╡╦▀⌐
                         ▀▓▓▓▓▓▓▓       Vision is teh art of seeing what is invisible to others.     ╗╠╥▒▀
                           ▀▓█▓▓▓    Teh people shall make teh community and they shall see light.   =╠╥▒
                             ▀▓▓▓                               5% Tax                               ╠╦½
                              ▀▓▓           ALL TAXES WILL GO TO THE LIQUIDITY POOLS                 ⁿⁿ
                                 ▀                                                                   b
                                   ▀▓▓▓█▓▓██▓  ¬D,╡æε▐≤. ⌐▌L≥"C]j╔∞,]"3▒ⁿⁿ-;`¬,Θb╙─`┬╙^L"╓,═╙U╓╛▐╙╛╨
                                     ▀▓▓▓█▓▓██▓ ÜD,╡æε▐≤. ⌐▌L≥"ⁿⁿ-;`¬,Θb╙─`╙C]j╔∞,ⁿⁿ-;`¬,Θb╙─╙─`┬
                                       ▀▓▓▓█▓▓██▓ ΓÇ⌠"▄└w¬Oⁿⁿ-;`¬,Θb╙─`┬╙,║¥▄░Cⁿ√,│╓╛.░≈╚▌b╙─$∩^
                                         ▀▓▓▓█▓▓██▓ │╙²~▄╡ ┴▄╚╠%┐`b╙─▐Ñ╜Θ╘⌠╛░Å╕▀⌐┐`▐Ñ╜Θ┐`▐Ñ╜Θ
                                          ,#█▓▓█▓▓▓▓▓╠"░¬¬╙ⁿⁿ-;`b╙─¬,Θb╙─`┬í╙ l¿-╚▀╓`╜─'╙░Å
                                              ▓▀▓▓▓▓▓▓▓╙╩^~└┘┘h ¬Ö╥⌠└ⁿⁿ-;`¬╙─Θb╙─`┬╙╚ƒ░,
                                               ,#▓▓▓▓▓▓▓µ╙eµOΓÇ⌠"▄└ⁿⁿb╙─-;`,Θb╙─`┬╙w¬▐»
                                                   ▄█▓▓▓▓▓┘^^2,┐Vⁿⁿ-;`¬,Θbb╙─╙b╙─`┬╙Σ
                                                      ▀▓▓▓ ▓▄┘^^ⁿⁿ-;`¬,Θbb╙─╙─┬╙2b╙
                                                         ▄▓▓▓ └J╥ │░╙├╓b┘▌5▄╠╣v░╖  
                                                          ▀▓▓▓▒O,║ ¥▄░Cⁿ√,│╓╛.
                                                             ▄▓▄╖▄╖╓▒O,║ ¥╚ 
                                                                ▓▄╖╓▒O,OΓ
                                                                  ▄╖╓▒
                                                                    ╖
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


interface IERC20 {
    
    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);
}

library Address {

    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }


    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, errorMessage);
    }

    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else {
            
            if (returndata.length > 0) {
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}




contract ASTRAEA is Context,IERC20, Ownable{
    using Address for address;

    string private _name = "E Pluribus Unum";
    string private _symbol = "ASTRAEA";
    uint8 private _decimals = 18;
    uint256 totalFeeFortx = 0;
    uint256 maxWalletTreshold = 3;
    uint256 maxTxTreshold = 2;
    uint256 private swapTreshold =2;

    uint256 private currentThreshold = 20; //Once the token value goes up this number can be decreased (To reduce price impact on asset)
    uint256 private _totalSupply = 23333333231 * 10**_decimals; 
    uint256 public requiredTokensToSwap = _totalSupply * swapTreshold /1000;
    mapping (address => uint256) private _balances;
    mapping (address => bool) private _excludedFromFees;
    mapping (address => mapping (address => uint256)) private _allowances;
    mapping (address => bool) public automatedMarketMakerPairs;
    address _owner;
    address payable public marketingAddress = payable(0x31A5512D3b640C9235cDF57b351A6e0d586ce279);
    address public NOS =  (0x234736F78a6F18d20d3d2eD0544c55d38F26b1CD);
    address public POO = (0x2B52cC9051991B42A77CA1Dc703f6d15E0981241);
    uint256 maxWalletAmount = _totalSupply*maxWalletTreshold/100; 
    uint256 maxTxAmount = _totalSupply*maxTxTreshold/100;
    mapping (address => bool) botWallets;
    bool botTradeEnabled = false;
    bool checkWalletSize = true;
    mapping (address => bool) private _liquidityHolders;
    mapping (address => bool) private presaleAddresses;
    uint256 private buyliqFee = 1; 
    uint256 private buyprevLiqFee = 1;
    uint256 private buymktFee = 2;
    uint256 private buyPrevmktFee = 2;
    uint256 private buyNOS = 1;
    uint256 private buyprevNOS = 1;
    uint256 private buyPOO = 1;
    uint256 private buyPrevPOO = 1;
    
    bool private tradeEnabled = false;

    
    uint256 private sellliqFee = 1;
    uint256 private sellprevLiqFee = 1;
    uint256 private sellmktFee = 2;
    uint256 private sellPrevmktFee = 2;
    uint256 private sellNOS = 1;
    uint256 private sellprevNOS = 1;
    uint256 private sellPOO = 1;
    uint256 private sellPrevPOO =1;


    bool public inSwapAndLiquify;
    bool public swapAndLiquifyEnabled = true;
    address public immutable deadAddress = 0x000000000000000000000000000000000000dEaD;
    uint256 private mktTokens = 0;
    uint256 private NOSTokens = 0;
    uint256 private liqTokens = 0;
    uint256 private POOtokens =0;

    
    event SwapAndLiquify(uint256 tokensSwapped,
		uint256 ethReceived,
		uint256 tokensIntoLiquidity
	);
    event tokensSwappedDuringTokenomics(uint256 amount);
    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);
    
    // 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
    IUniswapV2Router02 _router;
    address public uniswapV2Pair;

    //Balances tracker

    modifier lockTheSwap{
		inSwapAndLiquify = true;
		_;
		inSwapAndLiquify = false;
	}
    

    constructor(){
        _balances[_msgSender()] = _totalSupply;
        //0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D mainnet and all networks
        IUniswapV2Router02 _uniRouter = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
        
        uniswapV2Pair = IUniswapV2Factory(_uniRouter.factory())
            .createPair(address(this), _uniRouter.WETH());
        
        _excludedFromFees[owner()] = true;         
        _excludedFromFees[address(this)] = true;// exclude owner and contract instance from fees
        _router = _uniRouter;
        _liquidityHolders[address(_router)] = true;
        _liquidityHolders[owner()] = true;
        _liquidityHolders[address(this)] = true;
        _setAutomatedMarketMakerPair(address(uniswapV2Pair), true);
        emit Transfer(address(0),_msgSender(),_totalSupply);




    }
    receive() external payable{}


    //general token data and tracking of balances to be swapped.
    function getOwner()external view returns(address){
            return owner();
    }
    function currentmktTokens() external view returns (uint256){
            return mktTokens;
     }
     function currentPZTokens() external view returns (uint256){
            return NOSTokens;
     }
      function currentPOOokens() external view returns (uint256){
            return POOtokens;
     }
     function currentLiqTokens() external view returns (uint256){
            return liqTokens;
     }

     function totalSupply() external view override returns (uint256){
            return _totalSupply;
     }
   
    function balanceOf(address account) public view override returns (uint256){
        return _balances[account];
    }
   
    function transfer(address recipient, uint256 amount) external override returns (bool){
            _transfer(_msgSender(),recipient,amount);
            return true;

    }
   
    function allowance(address owner, address spender) external view override returns (uint256){
            return _allowances[owner][spender];
    }
 
    function approve(address spender, uint256 amount) external override returns (bool){
            _approve(_msgSender(),spender,amount);
            return true;
    }

    function decimals()external view returns(uint256){
        return _decimals;
    }
    function name() external view returns (string memory) {
		return _name;
	}
    function symbol() external view returns (string memory){
        return _symbol;
    }
        function updateMaxTxTreshold(uint256 newVal) public onlyOwner{
        maxTxTreshold = newVal;
        maxTxAmount = _totalSupply*maxTxTreshold/100;// 1%

    }
     function updateMaxWalletTreshold(uint256 newVal) public onlyOwner{
        maxWalletTreshold = newVal;
        maxWalletAmount = _totalSupply*maxWalletTreshold/100;

    }
    

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public override returns (bool){
        require(amount <= _allowances[sender][_msgSender()], "ERC20: transfer amount exceeds allowance");
		_transfer(sender, recipient, amount);
		_approve(sender, _msgSender(), _allowances[sender][_msgSender()] - amount);
		return true;
    }

    function addBotWallet (address payable detectedBot, bool isBot) public onlyOwner{
        botWallets[detectedBot] = isBot;
    }
    function currentbuyliqFee() public view returns (uint256){
            return buyliqFee;
    }
    function currentbuymktfee() public view returns (uint256){
            return buymktFee;
    }
    function currentbuyNOSfee() public view returns (uint256){
            return buyNOS;
    }
     function currentbuyPOOfee() public view returns (uint256){
            return buyPOO;
    }

      function currentsellLiqFee() public view returns (uint256){
            return sellliqFee;
    }
    function currentsellmktfee() public view returns (uint256){
            return sellmktFee;
    }
    function currentsellyNOSfee() public view returns (uint256){
            return sellNOS;
    }
     function currentsellyPOOfee() public view returns (uint256){
            return sellPOO;
    }
    function currentThresholdInt()public view returns (uint256){
        return currentThreshold;
    }
    function isExcluded(address toCheck)public view returns (bool){
            return _excludedFromFees[toCheck];
    }

    function _transfer(address from, address to, uint256 amount) internal{
        
        require(from != address(0), "ERC20: transfer from the zero address");
		require(to != address(0), "ERC20: transfer to the zero address");
        require(amount > 0,"ERC20: transfered amount must be greater than zero");
        uint256 senderBalance = _balances[from];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        if(tradeEnabled == false){
            require(_liquidityHolders[to] || _liquidityHolders[from],"Cant trade, trade is disabled");
        }
        if(_liquidityHolders[to]==false && _liquidityHolders[from]==false){
        require(amount <= maxTxAmount, "Transfer amount exceeds the maxTxAmount.");
        }
        uint256 inContractBalance = balanceOf(address(this));
        if(inContractBalance >=requiredTokensToSwap && 
			!inSwapAndLiquify && 
			from != uniswapV2Pair && 
			swapAndLiquifyEnabled){
                if(inContractBalance >= requiredTokensToSwap ){
                    inContractBalance = requiredTokensToSwap;
                    swapForTokenomics(inContractBalance);
                }
            }

            bool takeFees = true;
            
            
            if(_excludedFromFees[from] || _excludedFromFees[to]) {
                totalFeeFortx = 0;
                takeFees = false;
               

            }
            uint256 mktAmount = 0;
            uint256 NOSAmount = 0; // Amount to be added to prize pool.
		    uint256 liqAmount = 0;  // Amount to be added to liquidity.
            uint256 POOamount = 0;
            if(takeFees){
                
                //bot fees
                if(botWallets[from] == true||botWallets[to]==true){
                    revert("No bots allowed to trade");
                }
                //Selling fees
                if (automatedMarketMakerPairs[to] && to != address(_router) ){
                        totalFeeFortx = 0;
                        mktAmount = amount * sellmktFee/100;
                        liqAmount = amount * sellliqFee/100;
                        NOSAmount = amount * sellNOS/100;
                        POOamount = amount * sellPOO/100;
                        totalFeeFortx = mktAmount + liqAmount + NOSAmount;
                }
                //Buy Fees
                else if(automatedMarketMakerPairs[from] && from != address(_router)) {
                
                    totalFeeFortx = 0;
                    mktAmount = amount * buymktFee/100;
                    liqAmount = amount * buyliqFee/100;
                    NOSAmount = amount * buyNOS/100;
                    POOamount = amount * buyPOO/100;
                    totalFeeFortx = mktAmount + liqAmount + NOSAmount;
                }

                
            }

            _balances[from] = senderBalance - amount;
            _balances[to] += amount - mktAmount - NOSAmount - liqAmount-POOamount;

          if(liqAmount != 0) {
			_balances[address(this)] += totalFeeFortx;
			//tLiqTotal += liqAmount;
            liqTokens += liqAmount;
            NOSTokens += NOSAmount;
            mktTokens += mktAmount;
            POOtokens += POOamount;
			emit Transfer(from, address(this), totalFeeFortx);
            
		    }
            emit Transfer(from, to,amount-totalFeeFortx);
            
        
    }
    function swapForTokenomics(uint256 balanceToswap) private lockTheSwap{
        swapAndLiquify(liqTokens);
        swapTokensForETHmkt(mktTokens);
        SwapForNOS(NOSTokens);
        uint256 halfETHBalance = address(this).balance;
        processNOS(halfETHBalance,NOS);
        SwapForNOS(POOtokens);
        uint256 remainingETHBalance = address(this).balance;
        processNOS(remainingETHBalance,POO);
  
        emit tokensSwappedDuringTokenomics(balanceToswap);
        mktTokens = 0;
        NOSTokens = 0;
        liqTokens = 0;
        POOtokens = 0;
    }
     function addLimitExempt(address newAddress)external onlyOwner{
        _liquidityHolders[newAddress] = true;
     
    }
    function swapTokensForETHmkt(uint256 amount)private {
        address[] memory path = new address[](2);
		path[0] = address(this);
		path[1] = _router.WETH();
		_approve(address(this), address(_router), amount);

		
		_router.swapExactTokensForETHSupportingFeeOnTransferTokens(
			amount,
			0, // Accept any amount of ETH.
			path,
			marketingAddress,
			block.timestamp
		);

    }
      function SwapForNOS(uint256 amount)private {
        address[] memory path = new address[](2);
		path[0] = address(this);
		path[1] = _router.WETH();
		_approve(address(this), address(_router), amount);

		
		_router.swapExactTokensForETHSupportingFeeOnTransferTokens(
			amount,
			0, // Accept any amount of ETH.
			path,
			address(this),
			block.timestamp
		);
        

    }
    function updateNOS(address newToken) external{
        NOS = newToken;
    }
     function updatePOO(address newToken) external{
        POO = newToken;
    }
    function processNOS(uint256 ethAmount, address rewardToken) internal {
        // generate the uniswap pair path of weth -> eth
        address[] memory path = new address[](2);
        path[0] = _router.WETH();
        path[1] = rewardToken;

        // make the swap
        _router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: ethAmount}(
            0, // accept any amount of Ethereum
            path,
            address(this),
            block.timestamp
        );
    }

    function unstuckTokens (IERC20 tokenToClear, address payable destination, uint256 amount) public onlyOwner{
        //uint256 contractBalance = tokenToClear.balanceOf(address(this));
        tokenToClear.transfer(destination, amount);
    }

    function unstuckETH(address payable destination) public onlyOwner{
        uint256 ethBalance = address(this).balance;
        payable(destination).transfer(ethBalance);
    }

    function tradeStatus(bool status) public onlyOwner{
        tradeEnabled = status;
    }

    function swapAndLiquify(uint256 liqTokensPassed) private {
		uint256 half = liqTokensPassed / 2;
		uint256 otherHalf = liqTokensPassed - half;
		uint256 initialBalance = address(this).balance;

		swapTokensForETH(half);
		uint256 newBalance = address(this).balance - (initialBalance); 

		addLiquidity(otherHalf, newBalance);
		emit SwapAndLiquify(half,newBalance,otherHalf);
	}

    function swapTokensForETH(uint256 tokenAmount) private{
		address[] memory path = new address[](2);
		path[0] = address(this);
		path[1] = _router.WETH();
		_approve(address(this), address(_router), tokenAmount);

		
		_router.swapExactTokensForETHSupportingFeeOnTransferTokens(
			tokenAmount,
			0, // Accept any amount of ETH.
			path,
			address(this),
			block.timestamp
		);
	}
    
    function addLiquidity(uint256 tokenAmount,uint256 ethAmount) private{
		_approve(address(this), address(_router), tokenAmount);

		_router.addLiquidityETH{value:ethAmount}(
			address(this),
			tokenAmount,
			0,
			0,
			deadAddress,// tr
			block.timestamp
		);
	}

    function _approve(address owner,address spender, uint256 amount) internal{
        require(owner != address(0), "ERC20: approve from the zero address");
		require(spender != address(0), "ERC20: approve to the zero address");

		_allowances[owner][spender] = amount;
		emit Approval(owner, spender, amount);


    }




    //Fees related functions

    function addToExcluded(address toExclude) public onlyOwner{  
        _excludedFromFees[toExclude] = true;
    }

    function removeFromExcluded(address toRemove) public onlyOwner{
        _excludedFromFees[toRemove] = false;
    }
      function excludePresaleAddresses(address router, address presale) external onlyOwner {
        
        _liquidityHolders[address(router)] = true;
        _liquidityHolders[presale] = true;
        presaleAddresses[address(router)] = true;
        presaleAddresses[presale] = true;
       
    }

    function startPresaleStatus()public onlyOwner{
        
        buymktFee = 0;
        sellmktFee =0;
        buyliqFee =0;
        sellliqFee =0;
        buyNOS =0;
        sellNOS = 0;
        buyPOO =0;
        sellPOO = 0;
        setSwapAndLiquify(false);

    }
    function endPresaleStatus() public onlyOwner{
        buymktFee = 1;
        buyliqFee = 1;
        buyNOS = 1;
        buyPOO =1;

        sellmktFee = 1;
        sellliqFee = 1;
        sellNOS = 1;
        sellPOO =1;
        setSwapAndLiquify(true);
    }

    function updateThreshold(uint newThreshold) public onlyOwner{
        currentThreshold = newThreshold;

    }

    function setSwapAndLiquify(bool _enabled) public onlyOwner{
            swapAndLiquifyEnabled = _enabled;
    }


    //Marketing related 

    function setMktAddress(address newAddress) external onlyOwner{
        marketingAddress = payable(newAddress);
    }
   
    function transferAssetsETH(address payable to, uint256 amount) internal{
            to.transfer(amount);
    }
   
    function setAutomatedMarketMakerPair(address pair, bool value) public onlyOwner {
        require(pair != uniswapV2Pair, "The pair cannot be removed from automatedMarketMakerPairs");
        _setAutomatedMarketMakerPair(pair, value);
    }
    function _setAutomatedMarketMakerPair(address pair, bool value) private {
        automatedMarketMakerPairs[pair] = value;

        emit SetAutomatedMarketMakerPair(pair, value);
    }

    function updatecurrentbuyliqFee(uint256 newAmount) public onlyOwner{
            buyliqFee = newAmount;
    }
    function updatecurrentbuymktfee(uint256 newAmount) public onlyOwner{
             buymktFee= newAmount;
    }
    function updatecurrentbuyNOSfee(uint256 newAmount) public onlyOwner{
             buyNOS= newAmount;
    }
     function updatecurrentbuyPOOfee(uint256 newAmount) public onlyOwner{
             buyPOO= newAmount;
    }

      function updatecurrentsellLiqFee(uint256 newAmount) public onlyOwner{
             sellliqFee= newAmount;
    }
    function updatecurrentsellmktfee(uint256 newAmount)public onlyOwner{
             sellmktFee= newAmount;
    }
    
    function updatecurrentsellyNOSfee(uint256 newAmount) public onlyOwner{
             sellNOS= newAmount;
    }
     function updatecurrentsellyPOOfee(uint256 newAmount) public onlyOwner{
             sellPOO= newAmount;
    }
    function currentMaxWallet() public view returns(uint256){
        return maxWalletAmount;
    }
    function currentMaxTx() public view returns(uint256){
        return maxTxAmount;
    }
    function updateSwapTreshold(uint256 newVal) public onlyOwner{
        swapTreshold = newVal;
        requiredTokensToSwap = _totalSupply*swapTreshold/1000;
        
    }
    function currentTradeStatus() public view returns (bool){
        return tradeEnabled;   
    }
    function currentSwapTreshold() public view returns(uint256){
        return swapTreshold;
    }
    function currentTokensToSwap() public view returns(uint256){
        return requiredTokensToSwap;
    }
    function AHD666LaunchPad() public pure returns(uint256) {
        return 1;
    }
}


interface IUniswapV2Factory {
    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 IUniswapV2Pair {
    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 IUniswapV2Router01 {
    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 IUniswapV2Router02 is IUniswapV2Router01 {
    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;
}