/*
                      ██████╗ ███████╗██████╗ ███████╗    ███╗   ███╗ ██████╗ ██████╗ ██████╗ ███████╗ ██████╗  ██████╗ ██████╗ 
                      ██╔══██╗██╔════╝██╔══██╗██╔════╝    ████╗ ████║██╔════╝██╔════╝ ██╔══██╗██╔════╝██╔════╝ ██╔═══██╗██╔══██╗
                      ██████╔╝█████╗  ██████╔╝█████╗      ██╔████╔██║██║     ██║  ███╗██████╔╝█████╗  ██║  ███╗██║   ██║██████╔╝
                      ██╔═══╝ ██╔══╝  ██╔═══╝ ██╔══╝      ██║╚██╔╝██║██║     ██║   ██║██╔══██╗██╔══╝  ██║   ██║██║   ██║██╔══██╗
                      ██║     ███████╗██║     ███████╗    ██║ ╚═╝ ██║╚██████╗╚██████╔╝██║  ██║███████╗╚██████╔╝╚██████╔╝██║  ██║
                      ╚═╝     ╚══════╝╚═╝     ╚══════╝    ╚═╝     ╚═╝ ╚═════╝ ╚═════╝ ╚═╝  ╚═╝╚══════╝ ╚═════╝  ╚═════╝ ╚═╝  ╚═╝
                                                                                                          
                        https://pepemcgregorerc.com/     https://twitter.com/McGregorePepe     https://t.me/pepemcgregorEntry                                                                                                                                 
                                                                                                                                                      
                                                                                                                                                      
                                                                      .:^~!!!~:.                                                                      
                                                                   .~?Y5PPPGGPPPY!.                                                                   
                                                                 .7YYYJ?7!~~!7?JYYY?:                                                                 
                                       ...:^~^                 ~YJ7~~~^^^^^^^^^~~!?YJ~                                                               
                                  ^::::::^~!77!^.              .JJ77!~~^^^^^^^^^~!!??5Y                   :^::..                                      
                            .:^!!^^^^~!!7??!!~~~~.             .J?77!!!!~~~~~~~!!!!JJYY.                 :~!~^:::::::..                               
                          .^~!!!!?????YPY??!!!!7!.             :J???JYPBBPJ7JGBBG5Y5YY5:               .:^^^~!!~~~^^^~!~^:.                           
                       ::^~~~!JPBGP5555PP5J??YGP:             :~J??YP5PP5Y7^7PPPGGGPYY5~.              ^!~~~~!77??!!!7?7!7JJ^                         
                    .:^~~~!7YPBB?:      ...  .^:              7?J??7!!!~~!~^!?!!????YYYYJ.              !5GYJ?JYB#BBBBGPJ?JY5J~.                      
                 .:^^~~!7JPGBG?.                             .77J???!~~?JJ?7JYY7!7?YY55PY.              ^7?!^^~!777!7?5##PJ???JJ!^.                   
               :^^~~~!7YPGGG5:                                ~7YJJJJJPYYPGBBG5PYJ555PYY~                              ^Y#&B57!JJJ?~:                 
             :^~~~~!!7?Y55GJ.                                  ~PPYYYPP55555PPPPG5PPPGJ~                                 ^P#BB555YYJ?!:.              
           :^~~~~!!7?J5PGBJ                                     !BG5YG#&@@@@@@&#BPPGB?                                     ?#BBGBP55Y?77^:            
         :~~~~~!77?Y5PPPGJ.                                     :GBG5PPBGPB#B#&BBGGBB^                                      Y#BGGGGP5???7!^.          
       .^!~~!!77?JJY55PP?                                        !BGP5Y7????JYYPPGBB5:                                       J#BGGGP555YJJ??!.        
      :!!7777777???JY5PY:.::::::....      ..........             !GGG5J??JJYYYYYPGBPJ!^..           .......                   YBGPPPGGGPYJ555J~       
    :~!!7?JYY55555PPP5YJ7!~^^^^^:::::::::::^^^^^^~~~~~~^:...::^^~75PGP5JJY5YJJYPGBBPY??7!~^^:.::^~~^^^^^^^^^^^^^:.....:::::^:::YGPY?YY5P57???YP?:     
   7?7??JJY5GBB##BBG5YJ?!~~~~~~~~~~^^^^^:::::::::::^~7JJJ77?J7!~!?JYGGGPY5555PBB#BP5Y!!!7?J5Y??!77!~^^^^^^^^^^^^::::::^^^^^~~!!7J55J?77???????JPJ^.   
   ~55JY5PP5YYJJYY5555J??????J????777777!!!!~^^^::::^^~!??7!7~~!?JJYGGBBBBBBB####BBGY??!~!7??77!!~^:::::::^^^^:::^^^^^^^^^^^~~77!7Y5P555555YYYJJ??!:  
    :?55555555555YYJJ???JY5PGPPGGPPPPPPPPPP5?!~~^^^~~7??J777!~~~!7?YPGB#&&&&&&&#BGGG55JJ????JJJ7!!!^^^^^~!?J!~!!!!!!!777???????????YPGBBBBBGPPP55YJY^ 
      .^75PGBBBBBGP55YYYYYYY55PPGGBBBBGGGP55P5Y?7!!~~7JYYJY5YYJ????JY5PB#&@@&&#GPGGPGBGP5?J?YYJ77!!!~~!7JPBBPPPPPPPPPGGBBGGGP5J??????JYPGB###BBGGGG?. 
         .~?5G#&&##BG5YJJ???JJYY5PPGBBGBBGGGGBBGPYJ??J??JYYY55P55YJY55PGGB#&#B#BGGPPGGGPJ?JYYYJJJJ!!?J5PBBBPY55PPPPGPPGGGG55YJJJJJYYYY5PGBBB#BBBGJ:   
             .^7YPB##BBBGGPPPPPGGGGGB############BGPY?7?7JYJJY5YY55YYY5PPGGBBBBBGGGGGP5Y??JYYYJ?7Y5PGBB####BGGBBBBBBBBGPYYYYYYYY5PGGBB####BBGP5?:     
                  .^!?YPGBB######BBBGGPPPGB#####B###BPY??YYJ?J?YYYYYYYJJYJJY5PPGGGGP5555JJYYYJYGPGB####&&###&########BBGGGGGGGBBB####BG5J7!^:.        
                        ..:^~~~~^^:...    :P##GP5?YB##BPYJYYYYYYJJYJJYYYYY5YJYY5555YJYYYYJJ7?55B####B5P#####J~~!!7?J55PGGGGGP55Y?7!~:.                
                                           .Y#5??77J5GGPYJJJYJYYJJJJ7?JJJJ?JYJJYYJJJY5J!Y?J?Y5P###BPYYYPB#&5           ....                           
                                             !PY?777JJ?7???J?7?JYYYYJJJJ??!?J??JJJY555J7??JY5555GGPYYYYPG#5.                                          
                                              :5Y7!7??7!777?YY??J?JYYYYYJYYJYYYY5555YJ?JY5JJJJYJJ5YJJYPBG!                                            
                                               .?J!!77!!!!!!?J?7??J5YJJY555JYYYYYJ?????JYY?7?JJ?JY?7J5BY.                                             
                                                 ?7!!!777??7!!!!!!?PGGGGGPPPPJ?????777777?JJYJJJJ?7?Y5~                                               
                                                 ~J!!!77!!777!!!!!!!?Y555PPPY?7!!7777??JJYYYJJJYJ77J5:                                                
                                                 .J?77???7!!777!!!!~~~~!!77!~^^~~!!7?JYYJJJ?JJY5Y?J5?                                                 
                                                  ~J??????7!~~!!7!!7!~~!7!~!!!!!7777??7!!!7?J5555JY5.                                                 
                                                  .J?JYY??J?7777?!77~!????!77?7?7!????J??JJJY55PYYP!                                                  
                                                   ?J??J7!7?JJ?J?7????JJJJJ?JJ?J?7????YYYY55YY55Y5Y.               
                                                                                      
*/
// SPDX-License-Identifier: Unlicensed

pragma solidity 0.8.20;

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
}

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
    );
}

contract Ownable is Context {
    address private _owner;
    address private _previousOwner;
    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 transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    function _transferOwnership(address newOwner) internal {
        require(
            newOwner != address(0),
            "Ownable: new owner is the zero address"
        );
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }

    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }
}

interface IUniswapV2Factory {
    function createPair(address tokenA, address tokenB)
        external
        returns (address pair);
}

interface IUniswapV2Router02 {
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function factory() external pure returns (address);

    function WETH() external pure returns (address);
}

contract MCGREGOR is Context, IERC20, Ownable {
    uint256 private constant _totalSupply = 100_000_000e18;
    uint256 private constant onePercent = 1_000_000e18;
    uint256 private constant minSwap = 10_000e18;
    uint8 private constant _decimals = 18;

    IUniswapV2Router02 immutable uniswapV2Router;
    address immutable uniswapV2Pair;
    address immutable WETH;
    address payable immutable marketingWallet;

    uint256 public buyTax;
    uint256 public sellTax;

    uint8 private launch;
    uint8 private inSwapAndLiquify;

    uint256 private launchBlock;
    uint256 public maxTxAmount = onePercent; //max Tx for first mins after launch

    string private constant _name = "Pepe McGregor";
    string private constant _symbol = "MCGREGOR";


    mapping(address => uint256) private _balance;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => bool) private _isExcludedFromFeeWallet;

    constructor() {
        uniswapV2Router = IUniswapV2Router02(
            0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
        );
        WETH = uniswapV2Router.WETH();
        buyTax = 15;
        sellTax = 25;

        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(
            address(this),
            WETH
        );

        marketingWallet = payable(0x51EA6585D4A612454118D6230E59A07d5350b147);
        _balance[msg.sender] = _totalSupply;
        _isExcludedFromFeeWallet[marketingWallet] = true;
        _isExcludedFromFeeWallet[msg.sender] = true;
        _isExcludedFromFeeWallet[address(this)] = true;
        _allowances[address(this)][address(uniswapV2Router)] = type(uint256)
            .max;
        _allowances[msg.sender][address(uniswapV2Router)] = type(uint256).max;
        _allowances[marketingWallet][address(uniswapV2Router)] = type(uint256)
            .max;

        emit Transfer(address(0), _msgSender(), _totalSupply);
    }

    function name() public pure returns (string memory) {
        return _name;
    }

    function symbol() public pure returns (string memory) {
        return _symbol;
    }

    function decimals() public pure returns (uint8) {
        return _decimals;
    }

    function totalSupply() public pure override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) public view override returns (uint256) {
        return _balance[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()] - amount
        );
        return true;
    }

    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) private {
        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);
    }

    function openTrading() external onlyOwner {
        launch = 1;
        launchBlock = block.number;
    }

    function addExcludedWallet(address wallet) external onlyOwner {
        _isExcludedFromFeeWallet[wallet] = true;
    }

    function removeLimits() external onlyOwner {
        maxTxAmount = _totalSupply;
    }

    function changeTax(uint256 newBuyTax, uint256 newSellTax) external onlyOwner {
        buyTax = newBuyTax;
        sellTax = newSellTax;
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(amount > 1e9, "Min transfer amt");

        uint256 _tax;
        if (_isExcludedFromFeeWallet[from] || _isExcludedFromFeeWallet[to]) {
            _tax = 0;
        } else {
            require(
                launch != 0 && amount <= maxTxAmount,
                "Launch / Max TxAmount 1% at launch"
            );

            if (inSwapAndLiquify == 1) {
                //No tax transfer
                _balance[from] -= amount;
                _balance[to] += amount;

                emit Transfer(from, to, amount);
                return;
            }

            if (from == uniswapV2Pair) {
                _tax = buyTax;
            } else if (to == uniswapV2Pair) {
                uint256 tokensToSwap = _balance[address(this)];
                if (tokensToSwap > minSwap && inSwapAndLiquify == 0) {
                    if (tokensToSwap > onePercent) {
                        tokensToSwap = onePercent;
                    }
                    inSwapAndLiquify = 1;
                    address[] memory path = new address[](2);
                    path[0] = address(this);
                    path[1] = WETH;
                    uniswapV2Router
                        .swapExactTokensForETHSupportingFeeOnTransferTokens(
                            tokensToSwap,
                            0,
                            path,
                            marketingWallet,
                            block.timestamp
                        );
                    inSwapAndLiquify = 0;
                }
                _tax = sellTax;
            } else {
                _tax = 0;
            }
        }

        //Is there tax for sender|receiver?
        if (_tax != 0) {
            //Tax transfer
            uint256 taxTokens = (amount * _tax) / 100;
            uint256 transferAmount = amount - taxTokens;

            _balance[from] -= amount;
            _balance[to] += transferAmount;
            _balance[address(this)] += taxTokens;
            emit Transfer(from, address(this), taxTokens);
            emit Transfer(from, to, transferAmount);
        } else {
            //No tax transfer
            _balance[from] -= amount;
            _balance[to] += amount;

            emit Transfer(from, to, amount);
        }
    }

    receive() external payable {}
}