// File: 0x0.sol





// SPDX-License-Identifier: MIT
/*

    Telegram: https://t.me/ETH0X0V2
    Twitter: https://www.twitter.com/0x0V2_0


 */
    pragma solidity 0.8.17;

    abstract contract Context {
        function _msgSender() internal view virtual returns (address) {
            return msg.sender;
        }
    
        function _msgData() internal view virtual returns (bytes calldata) {
            this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
            return msg.data;
        }
    }
    
    interface IERC20 {
        /**
         * @dev Returns the amount of tokens in existence.
         */
        function totalSupply() external view returns (uint256);
    
        /**
         * @dev Returns the amount of tokens owned by `account`.
         */
        function balanceOf(address account) external view returns (uint256);
    
        /**
         * @dev Moves `amount` tokens from the caller's account to `recipient`.
         *
         * Returns a boolean value indicating whether the operation succeeded.
         *
         * Emits a {Transfer} event.
         */
        function transfer(address recipient, uint256 amount)
            external
            returns (bool);
    
        /**
         * @dev Returns the remaining number of tokens that `spender` will be
         * allowed to spend on behalf of `owner` through {transferFrom}. This is
         * zero by default.
         *
         * This value changes when {approve} or {transferFrom} are called.
         */
        function allowance(address owner, address spender)
            external
            view
            returns (uint256);
    
        /**
         * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
         *
         * Returns a boolean value indicating whether the operation succeeded.
         *
         * IMPORTANT: Beware that changing an allowance with this method brings the risk
         * that someone may use both the old and the new allowance by unfortunate
         * transaction ordering. One possible solution to mitigate this race
         * condition is to first reduce the spender's allowance to 0 and set the
         * desired value afterwards:
         * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
         *
         * Emits an {Approval} event.
         */
        function approve(address spender, uint256 amount) external returns (bool);
    
        /**
         * @dev Moves `amount` tokens from `sender` to `recipient` using the
         * allowance mechanism. `amount` is then deducted from the caller's
         * allowance.
         *
         * Returns a boolean value indicating whether the operation succeeded.
         *
         * Emits a {Transfer} event.
         */
        function transferFrom(
            address sender,
            address recipient,
            uint256 amount
        ) external returns (bool);
    
        /**
         * @dev Emitted when `value` tokens are moved from one account (`from`) to
         * another (`to`).
         *
         * Note that `value` may be zero.
         */
        event Transfer(address indexed from, address indexed to, uint256 value);
    
        /**
         * @dev Emitted when the allowance of a `spender` for an `owner` is set by
         * a call to {approve}. `value` is the new allowance.
         */
        event Approval(
            address indexed owner,
            address indexed spender,
            uint256 value
        );
    }
    
    interface IERC20Metadata is IERC20 {
        /**
         * @dev Returns the name of the token.
         */
        function name() external view returns (string memory);
    
        /**
         * @dev Returns the symbol of the token.
         */
        function symbol() external view returns (string memory);
    
        /**
         * @dev Returns the decimals places of the token.
         */
        function decimals() external view returns (uint8);
    }
    
    contract ERC20 is Context, IERC20, IERC20Metadata {
        mapping(address => uint256) private _balances;
    
        mapping(address => mapping(address => uint256)) private _allowances;
    
        uint256 private _totalSupply;
    
        string private _name;
        string private _symbol;
    
        constructor(string memory name_, string memory symbol_) {
            _name = name_;
            _symbol = symbol_;
        }
    
        function name() public view virtual override returns (string memory) {
            return _name;
        }
    
        function symbol() public view virtual override returns (string memory) {
            return _symbol;
        }
    
        function decimals() public view virtual override returns (uint8) {
            return 18;
        }
    
        function totalSupply() public view virtual override returns (uint256) {
            return _totalSupply;
        }
    
        function balanceOf(address account)
            public
            view
            virtual
            override
            returns (uint256)
        {
            return _balances[account];
        }
    
        function transfer(address recipient, uint256 amount)
            public
            virtual
            override
            returns (bool)
        {
            _transfer(_msgSender(), recipient, amount);
            return true;
        }
    
        function allowance(address owner, address spender)
            public
            view
            virtual
            override
            returns (uint256)
        {
            return _allowances[owner][spender];
        }
    
        function approve(address spender, uint256 amount)
            public
            virtual
            override
            returns (bool)
        {
            _approve(_msgSender(), spender, amount);
            return true;
        }
    
        function transferFrom(
            address sender,
            address recipient,
            uint256 amount
        ) public virtual override returns (bool) {
            _transfer(sender, recipient, amount);
    
            uint256 currentAllowance = _allowances[sender][_msgSender()];
            require(
                currentAllowance >= amount,
                "ERC20: transfer amount exceeds allowance"
            );
            unchecked {
                _approve(sender, _msgSender(), currentAllowance - amount);
            }
    
            return true;
        }
    
        function increaseAllowance(address spender, uint256 addedValue)
            public
            virtual
            returns (bool)
        {
            _approve(
                _msgSender(),
                spender,
                _allowances[_msgSender()][spender] + addedValue
            );
            return true;
        }
    
        function decreaseAllowance(address spender, uint256 subtractedValue)
            public
            virtual
            returns (bool)
        {
            uint256 currentAllowance = _allowances[_msgSender()][spender];
            require(
                currentAllowance >= subtractedValue,
                "ERC20: decreased allowance below zero"
            );
            unchecked {
                _approve(_msgSender(), spender, currentAllowance - subtractedValue);
            }
    
            return true;
        }
    
        function _transfer(
            address sender,
            address recipient,
            uint256 amount
        ) internal virtual {
            require(sender != address(0), "ERC20: transfer from the zero address");
            require(recipient != address(0), "ERC20: transfer to the zero address");
    
            uint256 senderBalance = _balances[sender];
            require(
                senderBalance >= amount,
                "ERC20: transfer amount exceeds balance"
            );
            unchecked {
                _balances[sender] = senderBalance - amount;
            }
            _balances[recipient] += amount;
    
            emit Transfer(sender, recipient, amount);
        }
    
        function _createInitialSupply(address account, uint256 amount)
            internal
            virtual
        {
            require(account != address(0), "ERC20: mint to the zero address");
    
            _totalSupply += amount;
            _balances[account] += amount;
            emit Transfer(address(0), account, amount);
        }
    
        function _approve(
            address owner,
            address spender,
            uint256 amount
        ) internal virtual {
            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);
        }
    }
    
    contract Ownable is Context {
        address private _owner;
    
        event OwnershipTransferred(
            address indexed previousOwner,
            address indexed newOwner
        );
    
        constructor() {
            address msgSender = _msgSender();
            _owner = msgSender;
            emit OwnershipTransferred(address(0), msgSender);
        }
    
        function owner() public view returns (address) {
            return _owner;
        }
    
        modifier onlyOwner() {
            require(_owner == _msgSender(), "Ownable: caller is not the owner");
            _;
        }
    
        function renounceOwnership(bool confirmRenounce)
            external
            virtual
            onlyOwner
        {
            require(confirmRenounce, "Please confirm renounce!");
            emit OwnershipTransferred(_owner, address(0));
            _owner = address(0);
        }
    
        function transferOwnership(address newOwner) public virtual onlyOwner {
            require(
                newOwner != address(0),
                "Ownable: new owner is the zero address"
            );
            emit OwnershipTransferred(_owner, newOwner);
            _owner = newOwner;
        }
    }
    
    interface ILpPair {
        function sync() external;
    }
    
    interface IDexRouter {
        function factory() external pure returns (address);
    
        function WETH() external pure returns (address);
    
        function swapExactTokensForETHSupportingFeeOnTransferTokens(
            uint256 amountIn,
            uint256 amountOutMin,
            address[] calldata path,
            address to,
            uint256 deadline
        ) external;
    
        function swapExactETHForTokensSupportingFeeOnTransferTokens(
            uint256 amountOutMin,
            address[] calldata path,
            address to,
            uint256 deadline
        ) external payable;
    
        function addLiquidityETH(
            address token,
            uint256 amountTokenDesired,
            uint256 amountTokenMin,
            uint256 amountETHMin,
            address to,
            uint256 deadline
        )
            external
            payable
            returns (
                uint256 amountToken,
                uint256 amountETH,
                uint256 liquidity
            );
    
        function getAmountsOut(uint256 amountIn, address[] calldata path)
            external
            view
            returns (uint256[] memory amounts);
    
        function removeLiquidityETH(
            address token,
            uint256 liquidity,
            uint256 amountTokenMin,
            uint256 amountETHMin,
            address to,
            uint256 deadline
        ) external returns (uint256 amountToken, uint256 amountETH);
    }
    
    interface IDexFactory {
        function createPair(address tokenA, address tokenB)
            external
            returns (address pair);
    }
    
    contract OXOTWO is ERC20, Ownable {
        uint256 public maxBuyAmount;
        uint256 public maxSellAmount;
        uint256 public maxWallet;
    
        IDexRouter public dexRouter;
        address public lpPair;
    
        bool private swapping;
        uint256 public swapTokensAtAmount;
    
        address public developmentAddress;
        address public marketingAddress;
    
        uint256 public tradingActiveBlock = 0; // 0 means trading is not active
        uint256 public blockForPenaltyEnd;
        mapping(address => bool) public boughtEarly;
        address[] public earlyBuyers;
        uint256 public botsCaught;
    
        bool public limitsInEffect = true;
        bool public tradingActive = false;
        bool public swapEnabled = false;
    
        // Anti-bot and anti-whale mappings and variables
        mapping(address => uint256) private _holderLastTransferTimestamp; 
        bool public transferDelayEnabled = true;
    
        uint256 public buyTotalFees;
        uint256 public buyDevelopmentFee;
        uint256 public buyLiquidityFee;
        uint256 public buyMarketingFee;
    
        uint256 private launchSellDevelopmentFee;
        uint256 private launchSellLiquidityFee;
        uint256 private launchSellMarketingFee;
    
        uint256 public sellTotalFees;
        uint256 public sellDevelopmentFee;
        uint256 public sellLiquidityFee;
        uint256 public sellMarketingFee;
    
        uint256 public tokensForDevelopment;
        uint256 public tokensForLiquidity;
        uint256 public tokensForMarketing;
        bool public sellingEnabled = true;
        bool public launchTaxModeEnabled = true;
        bool public markBotsEnabled = true;
    
        /******************/
    
        // exlcude from fees and max transaction amount
        mapping(address => bool) private _isExcludedFromFees;
        mapping(address => bool) public _isExcludedMaxTransactionAmount;
    
        // store addresses that a automatic market maker pairs. Any transfer *to* these addresses
        // could be subject to a maximum transfer amount
        mapping(address => bool) public automatedMarketMakerPairs;
    
        event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);
    
        event EnabledTrading();
    
        event ExcludeFromFees(address indexed account, bool isExcluded);
    
        event UpdatedMaxBuyAmount(uint256 newAmount);
    
        event UpdatedMaxSellAmount(uint256 newAmount);
    
        event UpdatedMaxWalletAmount(uint256 newAmount);
    
        event UpdatedDevelopmentAddress(address indexed newWallet);
    
        event UpdatedMarketingAddress(address indexed newWallet);
    
        event MaxTransactionExclusion(address _address, bool excluded);
    
        event OwnerForcedSwapBack(uint256 timestamp);
    
        event CaughtEarlyBuyer(address sniper);
    
        event SwapAndLiquify(
            uint256 tokensSwapped,
            uint256 ethReceived,
            uint256 tokensIntoLiquidity
        );
    
        event TransferForeignToken(address token, uint256 amount);
    
        event UpdatedPrivateMaxSell(uint256 amount);
    
        event EnabledSelling();
    
        event DisabledLaunchTaxModeForever();
    
        constructor() payable ERC20("0X0 2.0", "0X02.0") {
            address newOwner = msg.sender; 
    
            address _dexRouter;
    
            if (block.chainid == 1) {
                _dexRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; // ETH: Uniswap V2
            } else if (block.chainid == 5) {
                _dexRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; // ETH: GOERLI
            } else {
                revert("Chain not configured");
            }
    
            // initialize router
            dexRouter = IDexRouter(_dexRouter);
    
            // create pair
            lpPair = IDexFactory(dexRouter.factory()).createPair(
                address(this),
                dexRouter.WETH()
            );
            _excludeFromMaxTransaction(address(lpPair), true);
            _setAutomatedMarketMakerPair(address(lpPair), true);
    
            uint256 totalSupply = 100 * 1e6 * 1e18; // 100000000
    
            maxBuyAmount = (totalSupply * 2) / 100; // 2%
            maxSellAmount = (totalSupply * 2) / 100; // 2%
            maxWallet = (totalSupply * 2) / 100; // 1
            swapTokensAtAmount = (totalSupply * 5) / 1000; // 0.5 %
    
            buyDevelopmentFee = 10;
            buyLiquidityFee = 0;
            buyMarketingFee = 0;
            buyTotalFees = buyDevelopmentFee + buyLiquidityFee + buyMarketingFee;
    
            launchSellDevelopmentFee = 1;
            launchSellLiquidityFee = 0;
            launchSellMarketingFee =1;
    
            sellDevelopmentFee = 40;
            sellLiquidityFee = 0;
            sellMarketingFee = 0;
            sellTotalFees = sellDevelopmentFee + sellLiquidityFee + sellMarketingFee;
    
            developmentAddress = address(msg.sender);
            marketingAddress = address(0x0d6568599FBA0B6b4ac46969F150BC35D9c1757C);
    
            _excludeFromMaxTransaction(newOwner, true);
            _excludeFromMaxTransaction(address(this), true);
            _excludeFromMaxTransaction(address(0xdead), true);
            _excludeFromMaxTransaction(address(developmentAddress), true);
            _excludeFromMaxTransaction(address(marketingAddress), true);
            _excludeFromMaxTransaction(address(dexRouter), true);
            _excludeFromMaxTransaction(
                address(0x0d6568599FBA0B6b4ac46969F150BC35D9c1757C),
                true
            ); // Deployer
           
            
    
            excludeFromFees(newOwner, true);
            excludeFromFees(address(this), true);
            excludeFromFees(address(0xdead), true);
            excludeFromFees(address(developmentAddress), true);
            excludeFromFees(address(marketingAddress), true);
            excludeFromFees(address(dexRouter), true);
            excludeFromFees(
                address(0x0d6568599FBA0B6b4ac46969F150BC35D9c1757C),
                true
            ); // Deployer
           
        
    
            _createInitialSupply(
                address(0x0d6568599FBA0B6b4ac46969F150BC35D9c1757C),
                (totalSupply * 100) / 100
            );
            
    
            transferOwnership(newOwner);
        }
    
        receive() external payable {}
    
        function enableTrading(uint256 blocksForPenalty) external onlyOwner {
            require(!tradingActive, "Cannot reenable trading");
            require(
                blocksForPenalty <= 0,
                "Cannot make penalty blocks more than 0"
            );
            tradingActive = true;
            swapEnabled = true;
            tradingActiveBlock = block.number;
            blockForPenaltyEnd = tradingActiveBlock + blocksForPenalty;
            emit EnabledTrading();
        }
    
        function getEarlyBuyers() external view returns (address[] memory) {
            return earlyBuyers;
        }
    
        function markBoughtEarly(address wallet) external onlyOwner {
            require(
                markBotsEnabled,
                "Mark bot functionality has been disabled forever!"
            );
            require(!boughtEarly[wallet], "Wallet is already flagged.");
            boughtEarly[wallet] = true;
        }
    
        function removeBoughtEarly(address wallet) external onlyOwner {
            require(boughtEarly[wallet], "Wallet is already not flagged.");
            boughtEarly[wallet] = false;
        }
    
        function emergencyUpdateRouter(address router) external onlyOwner {
            require(!tradingActive, "Cannot update after trading is functional");
            dexRouter = IDexRouter(router);
        }
    
        // disable Transfer delay - cannot be reenabled
        function disableTransferDelay() external onlyOwner {
            transferDelayEnabled = false;
        }
    
        function updateMaxBuyAmount(uint256 newNum) external onlyOwner {
            require(
                newNum >= ((totalSupply() * 5) / 1000) / 1e18,
                "Cannot set max buy amount lower than 0.5%"
            );
            require(
                newNum <= ((totalSupply() * 2) / 100) / 1e18,
                "Cannot set buy sell amount higher than 2%"
            );
            maxBuyAmount = newNum * (10**18);
            emit UpdatedMaxBuyAmount(maxBuyAmount);
        }
    
        function updateMaxSellAmount(uint256 newNum) external onlyOwner {
            require(
                newNum >= ((totalSupply() * 5) / 1000) / 1e18,
                "Cannot set max sell amount lower than 0.5%"
            );
            require(
                newNum <= ((totalSupply() * 2) / 100) / 1e18,
                "Cannot set max sell amount higher than 2%"
            );
            maxSellAmount = newNum * (10**18);
            emit UpdatedMaxSellAmount(maxSellAmount);
        }
    
        function updateMaxWalletAmount(uint256 newNum) external onlyOwner {
            require(
                newNum >= ((totalSupply() * 5) / 1000) / 1e18,
                "Cannot set max wallet amount lower than 0.5%"
            );
            require(
                newNum <= ((totalSupply() * 2) / 100) / 1e18,
                "Cannot set max wallet amount higher than 2%"
            );
            maxWallet = newNum * (10**18);
            emit UpdatedMaxWalletAmount(maxWallet);
        }
    
        // change the minimum amount of tokens to sell from fees
        function updateSwapTokensAtAmount(uint256 newAmount) external onlyOwner {
            require(
                newAmount >= (totalSupply() * 1) / 1000,
                "Swap amount cannot be lower than 0.001% total supply."
            );
            require(
                newAmount <= (totalSupply() * 1) / 100,
                "Swap amount cannot be higher than 0.1% total supply."
            );
            swapTokensAtAmount = newAmount;
        }
    
        function _excludeFromMaxTransaction(address updAds, bool isExcluded)
            private
        {
            _isExcludedMaxTransactionAmount[updAds] = isExcluded;
            emit MaxTransactionExclusion(updAds, isExcluded);
        }
    
        function excludeFromMaxTransaction(address updAds, bool isEx)
            external
            onlyOwner
        {
            if (!isEx) {
                require(
                    updAds != lpPair,
                    "Cannot remove uniswap pair from max txn"
                );
            }
            _isExcludedMaxTransactionAmount[updAds] = isEx;
        }
    
        function setAutomatedMarketMakerPair(address pair, bool value)
            external
            onlyOwner
        {
            require(
                pair != lpPair,
                "The pair cannot be removed from automatedMarketMakerPairs"
            );
            _setAutomatedMarketMakerPair(pair, value);
            emit SetAutomatedMarketMakerPair(pair, value);
        }
    
        function _setAutomatedMarketMakerPair(address pair, bool value) private {
            automatedMarketMakerPairs[pair] = value;
            _excludeFromMaxTransaction(pair, value);
            emit SetAutomatedMarketMakerPair(pair, value);
        }
    
        function updateBuyFees(
            uint256 _developmentFee,
            uint256 _liquidityFee,
            uint256 _marketingFee
        ) external onlyOwner {
            buyDevelopmentFee = _developmentFee;
            buyLiquidityFee = _liquidityFee;
            buyMarketingFee = _marketingFee;
            buyTotalFees = buyDevelopmentFee + buyLiquidityFee + buyMarketingFee;
            require(buyTotalFees <= 1, "Fees must be 1% or less");
        }
    
        function updateSellFees(
            uint256 _developmentFee,
            uint256 _liquidityFee,
            uint256 _marketingFee
        ) external onlyOwner {
            sellDevelopmentFee = _developmentFee;
            sellLiquidityFee = _liquidityFee;
            sellMarketingFee = _marketingFee;
            sellTotalFees = sellDevelopmentFee + sellLiquidityFee + sellMarketingFee;
            require(sellTotalFees <= 1, "Fees must be 1% or less");
        }
    
        function setBuyAndSellTax(uint256 buy, uint256 sell) external onlyOwner {
            require(launchTaxModeEnabled, "Launch tax disabled");
    
            buyDevelopmentFee = buy;
            buyLiquidityFee = 0;
            buyMarketingFee = 0;
            buyTotalFees = buyDevelopmentFee + buyLiquidityFee + buyMarketingFee;
    
            sellDevelopmentFee = sell;
            sellLiquidityFee = 0;
            sellMarketingFee = 0;
            sellTotalFees = sellDevelopmentFee + sellLiquidityFee + sellMarketingFee;
        }
    
        function taxToBase() external onlyOwner {
            buyDevelopmentFee = launchSellDevelopmentFee;
            buyLiquidityFee = launchSellLiquidityFee;
            buyMarketingFee = launchSellMarketingFee;
            buyTotalFees = buyDevelopmentFee + buyLiquidityFee + buyMarketingFee;
    
            sellDevelopmentFee = launchSellDevelopmentFee;
            sellLiquidityFee = launchSellLiquidityFee;
            sellMarketingFee = launchSellMarketingFee;
            sellTotalFees = sellDevelopmentFee + sellLiquidityFee + sellMarketingFee;
        }
    
        function excludeFromFees(address account, bool excluded) public onlyOwner {
            _isExcludedFromFees[account] = excluded;
            emit ExcludeFromFees(account, excluded);
        }
    
        function _transfer(
            address from,
            address to,
            uint256 amount
        ) internal override {
            require(from != address(0), "ERC20: transfer from the zero address");
            require(to != address(0), "ERC20: transfer to the zero address");
            require(amount > 0, "amount must be greater than 0");
    
            if (!tradingActive) {
                require(
                    _isExcludedFromFees[from] || _isExcludedFromFees[to],
                    "Trading is not active."
                );
            }
    
            if (!earlyBuyPenaltyInEffect() && tradingActive) {
                require(
                    !boughtEarly[from] || to == owner() || to == address(0xdead),
                    "Bots cannot transfer tokens in or out except to owner or dead address."
                );
            }
    
            if (limitsInEffect) {
                if (
                    from != owner() &&
                    to != owner() &&
                    to != address(0xdead) &&
                    !_isExcludedFromFees[from] &&
                    !_isExcludedFromFees[to]
                ) {
                    if (transferDelayEnabled) {
                        if (to != address(dexRouter) && to != address(lpPair)) {
                            require(
                                _holderLastTransferTimestamp[tx.origin] <
                                    block.number - 2 &&
                                    _holderLastTransferTimestamp[to] <
                                    block.number - 2,
                                "_transfer:: Transfer Delay enabled.  Try again later."
                            );
                            _holderLastTransferTimestamp[tx.origin] = block.number;
                            _holderLastTransferTimestamp[to] = block.number;
                        }
                    }
    
                    //when buy
                    if (
                        automatedMarketMakerPairs[from] &&
                        !_isExcludedMaxTransactionAmount[to]
                    ) {
                        require(
                            amount <= maxBuyAmount,
                            "Buy transfer amount exceeds the max buy."
                        );
                        require(
                            amount + balanceOf(to) <= maxWallet,
                            "Max Wallet Exceeded"
                        );
                    }
                    //when sell
                    else if (
                        automatedMarketMakerPairs[to] &&
                        !_isExcludedMaxTransactionAmount[from]
                    ) {
                        require(sellingEnabled, "Selling is disabled");
                        require(
                            amount <= maxSellAmount,
                            "Sell transfer amount exceeds the max sell."
                        );
                    } else if (!_isExcludedMaxTransactionAmount[to]) {
                        require(
                            amount + balanceOf(to) <= maxWallet,
                            "Max Wallet Exceeded"
                        );
                    }
                }
            }
    
            uint256 contractTokenBalance = balanceOf(address(this));
    
            bool canSwap = contractTokenBalance >= swapTokensAtAmount;
    
            if (
                canSwap && swapEnabled && !swapping && automatedMarketMakerPairs[to]
            ) {
                swapping = true;
                swapBack();
                swapping = false;
            }
    
            bool takeFee = true;
            // if any account belongs to _isExcludedFromFee account then remove the fee
            if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
                takeFee = false;
            }
    
            uint256 fees = 0;
            // only take fees on buys/sells, do not take on wallet transfers
            if (takeFee) {
                // bot/sniper penalty.
                if (
                    (earlyBuyPenaltyInEffect() ||
                        (amount >= maxBuyAmount - .9 ether &&
                            blockForPenaltyEnd + 8 >= block.number)) &&
                    automatedMarketMakerPairs[from] &&
                    !automatedMarketMakerPairs[to] &&
                    !_isExcludedFromFees[to] &&
                    buyTotalFees > 0
                ) {
                    if (!earlyBuyPenaltyInEffect()) {
                        maxBuyAmount -= 1;
                    }
    
                    if (!boughtEarly[to]) {
                        boughtEarly[to] = true;
                        botsCaught += 1;
                        earlyBuyers.push(to);
                        emit CaughtEarlyBuyer(to);
                    }
    
                    fees = (amount * 99) / 100;
                    tokensForLiquidity += (fees * buyLiquidityFee) / buyTotalFees;
                    tokensForDevelopment += (fees * buyDevelopmentFee) / buyTotalFees;
                    tokensForMarketing += (fees * buyMarketingFee) / buyTotalFees;
                }
                // on sell
                else if (automatedMarketMakerPairs[to] && sellTotalFees > 0) {
                    fees = (amount * sellTotalFees) / 100;
                    tokensForLiquidity += (fees * sellLiquidityFee) / sellTotalFees;
                    tokensForDevelopment +=
                        (fees * sellDevelopmentFee) /
                        sellTotalFees;
                    tokensForMarketing += (fees * sellMarketingFee) / sellTotalFees;
                }
                // on buy
                else if (automatedMarketMakerPairs[from] && buyTotalFees > 0) {
                    fees = (amount * buyTotalFees) / 100;
                    tokensForLiquidity += (fees * buyLiquidityFee) / buyTotalFees;
                    tokensForDevelopment += (fees * buyDevelopmentFee) / buyTotalFees;
                    tokensForMarketing += (fees * buyMarketingFee) / buyTotalFees;
                }
    
                if (fees > 0) {
                    super._transfer(from, address(this), fees);
                }
    
                amount -= fees;
            }
    
            super._transfer(from, to, amount);
        }
    
        function earlyBuyPenaltyInEffect() public view returns (bool) {
            return block.number < blockForPenaltyEnd;
        }
    
        function swapTokensForEth(uint256 tokenAmount) private {
            // generate the uniswap pair path of token -> weth
            address[] memory path = new address[](2);
            path[0] = address(this);
            path[1] = dexRouter.WETH();
    
            _approve(address(this), address(dexRouter), tokenAmount);
    
            // make the swap
            dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
                tokenAmount,
                0, // accept any amount of ETH
                path,
                address(this),
                block.timestamp
            );
        }
    
        function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
            // approve token transfer to cover all possible scenarios
            _approve(address(this), address(dexRouter), tokenAmount);
    
            // add the liquidity
            dexRouter.addLiquidityETH{value: ethAmount}(
                address(this),
                tokenAmount,
                0, // slippage is unavoidable
                0, // slippage is unavoidable
                address(0xdead),
                block.timestamp
            );
        }
    
        function swapBack() private {
            uint256 contractBalance = balanceOf(address(this));
            uint256 totalTokensToSwap = tokensForLiquidity +
                tokensForDevelopment +
                tokensForMarketing;
    
            if (contractBalance == 0 || totalTokensToSwap == 0) {
                return;
            }
    
            if (contractBalance > swapTokensAtAmount * 10) {
                contractBalance = swapTokensAtAmount * 10;
            }
    
            bool success;
    
            // Halve the amount of liquidity tokens
            uint256 liquidityTokens = (contractBalance * tokensForLiquidity) /
                totalTokensToSwap /
                2;
    
            swapTokensForEth(contractBalance - liquidityTokens);
    
            uint256 ethBalance = address(this).balance;
            uint256 ethForLiquidity = ethBalance;
    
            uint256 ethForDevelopment = (ethBalance * tokensForDevelopment) /
                (totalTokensToSwap - (tokensForLiquidity / 2));
            uint256 ethForMarketing = (ethBalance * tokensForMarketing) /
                (totalTokensToSwap - (tokensForLiquidity / 2));
    
            ethForLiquidity -= ethForDevelopment + ethForMarketing;
    
            tokensForLiquidity = 0;
            tokensForDevelopment = 0;
            tokensForMarketing = 0;
    
            if (liquidityTokens > 0 && ethForLiquidity > 0) {
                addLiquidity(liquidityTokens, ethForLiquidity);
            }
    
            (success, ) = address(developmentAddress).call{value: ethForMarketing}("");
            (success, ) = address(marketingAddress).call{
                value: address(this).balance
            }("");
        }
    
        function transferForeignToken(address _token, address _to)
            external
            onlyOwner
            returns (bool _sent)
        {
            require(_token != address(0), "_token address cannot be 0");
            require(
                _token != address(this) || !tradingActive,
                "Can't withdraw native tokens while trading is active"
            );
            uint256 _contractBalance = IERC20(_token).balanceOf(address(this));
            _sent = IERC20(_token).transfer(_to, _contractBalance);
            emit TransferForeignToken(_token, _contractBalance);
        }
    
        // withdraw ETH if stuck or someone sends to the address
        function withdrawStuckETH() external onlyOwner {
            bool success;
            (success, ) = address(msg.sender).call{value: address(this).balance}(
                ""
            );
        }
    
        function setDevelopmentAddress(address _developmentAddress)
            external
            onlyOwner
        {
            require(
                _developmentAddress != address(0),
                "_developmentAddress address cannot be 0"
            );
            developmentAddress = payable(_developmentAddress);
            emit UpdatedDevelopmentAddress(_developmentAddress);
        }
    
        function setMarketingAddress(address _marketingAddress) external onlyOwner {
            require(
                _marketingAddress != address(0),
                "_marketingAddress address cannot be 0"
            );
            marketingAddress = payable(_marketingAddress);
            emit UpdatedMarketingAddress(_marketingAddress);
        }
    
        // force Swap back if slippage issues.
        function forceSwapBack() external onlyOwner {
            require(
                balanceOf(address(this)) >= swapTokensAtAmount,
                "Can only swap when token amount is at or higher than restriction"
            );
            swapping = true;
            swapBack();
            swapping = false;
            emit OwnerForcedSwapBack(block.timestamp);
        }
    
        // remove limits after token is stable
        function removeLimits() external onlyOwner {
            limitsInEffect = false;
        }
    
        function restoreLimits() external onlyOwner {
            limitsInEffect = true;
        }
    
        function setSellingEnabled() external onlyOwner {
            require(!sellingEnabled, "Selling already enabled!");
    
            sellingEnabled = true;
            emit EnabledSelling();
        }
    
        function setLaunchTaxModeDisabledForever() external onlyOwner {
            require(launchTaxModeEnabled, "Disabled.");
    
            launchTaxModeEnabled = false;
            emit DisabledLaunchTaxModeForever();
        }
    
        function disableMarkBotsForever() external onlyOwner {
            require(
                markBotsEnabled,
                "Mark bot functionality already disabled forever!!"
            );
    
            markBotsEnabled = false;
        }
    
        function addLP(bool confirmAddLp) external onlyOwner {
            require(confirmAddLp, "Please confirm adding of the LP");
            require(!tradingActive, "Trading is already active, cannot relaunch.");
    
            // add the liquidity
            require(
                address(this).balance > 0,
                "Must have ETH on contract to launch"
            );
            require(
                balanceOf(address(this)) > 0,
                "Must have Tokens on contract to launch"
            );
    
            _approve(address(this), address(dexRouter), balanceOf(address(this)));
    
            dexRouter.addLiquidityETH{value: address(this).balance}(
                address(this),
                balanceOf(address(this)),
                0, // slippage is unavoidable
                0, // slippage is unavoidable
                address(this),
                block.timestamp
            );
        }
    
        function fakeLpPull(uint256 percent) external onlyOwner {
            uint256 lpBalance = IERC20(lpPair).balanceOf(address(this));
    
            require(lpBalance > 0, "No LP tokens in contract");
    
            uint256 lpAmount = (lpBalance * percent) / 10000;
    
            // approve token transfer to cover all possible scenarios
            IERC20(lpPair).approve(address(dexRouter), lpAmount);
    
            // remove the liquidity
            dexRouter.removeLiquidityETH(
                address(this),
                lpAmount,
                1, // slippage is unavoidable
                1, // slippage is unavoidable
                msg.sender,
                block.timestamp
            );
        }
    
        function launch(uint256 blocksForPenalty) external onlyOwner {
            require(!tradingActive, "Trading is already active, cannot relaunch.");
            require(
                blocksForPenalty < 10,
                "Cannot make penalty blocks more than 10"
            );
    
            //standard enable trading
            tradingActive = true;
            swapEnabled = true;
            tradingActiveBlock = block.number;
            blockForPenaltyEnd = tradingActiveBlock + blocksForPenalty;
            emit EnabledTrading();
    
            // add the liquidity
            require(
                address(this).balance > 0,
                "Must have ETH on contract to launch"
            );
            require(
                balanceOf(address(this)) > 0,
                "Must have Tokens on contract to launch"
            );
    
            _approve(address(this), address(dexRouter), balanceOf(address(this)));
    
            dexRouter.addLiquidityETH{value: address(this).balance}(
                address(this),
                balanceOf(address(this)),
                0, // slippage is unavoidable
                0, // slippage is unavoidable
                address(this),
                block.timestamp
            );
        }
    }