/***
    So, top of the smart contract, put this:

    ABOUT ACHMED

    My fans would argue that I don’t need an introduction, but the truth is, after kicking the bucket, you tend to be forgotten and I’ve been dead for quite some time now, so let’s set up the stage:

    Who says your career needs to end once you die? Well, usually, it's the suicide bombers, isn't it? Enter yours truly – Achmed, the dead terrorist; the fear-inducing, worldwide-known, former suicide bomber with a killer sense of humor. My failed attempt at being a suicide bomber (Or was it a success? Can't remember) made me rethink priorities a bit, and while waiting for my promised 72 virgins, I had an epiphany: why not try stand-up comedy instead?

    My debut was in "Spark of Insanity," and ever since, Jeff Dunham and I have been inseparable. Jeff takes me pretty much anywhere and everywhere we show up it’s pretty lit (no pun intended). My fellow suicide bombers might think life after death is only about fun and claiming your 72 virgins, but I’m having such a blast still sticking around and throwing my highly explosive punchlines everywhere I go. Kind to think of it, I really put the "dead" in dead-funny and make audiences blow up into laughter every time I repeat my killer catchphrase "I Keel You!"

    I’d shake your hand, but then I’d be afraid to puzzle my bones back together.

    So, Silence, I Keel You and let’s get things done!

    ---

    ACHMED'S MISSION

    If I couldn’t blow up the whole world, I’m now focused on melting everybody’s hearts instead. Cheesy, I know. While burning tokens up like fireworks is fun, I am also pretty focused on settling the score and doing some good. Therefore, 1% of my earnings will go to a charity fund. Yes, even suicide bombers can have a change of heart, it is usually after they blow up and don’t get their promised rewards, but the order is not that important.

    Together, we can ignite bombs, get virgins and so much more!

    Join me or … Silence, I Keell You!

    Telegram: https://t.me/iKeelYouERC20
    X: https://twitter.com/ikeelyouerc20
    Instagram: https://www.instagram.com/ikeelyouerc20
    YouTube: https://www.youtube.com/@ikeelyouerc20
    TikTok: https://www.tiktok.com/@ikeelyouerc20
    Pinterest: https://www.pinterest.com/ikeelyouerc20/
    Email: ikeelyouerc20@gmail.com

***/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

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);
    }
}

library SafeMath {

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }
}

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 ACHMED is Context, IERC20, Ownable {
    using SafeMath for uint256;
    
    string private constant _name = "ACHMED - The Dead Terrorist";
    string private constant _symbol = "ACHMED";
    uint256 private constant _totalSupply = 6969 * 10**18;
    uint256 public MinTaxSwapLimit = 7 * 10**18; // 0.1% of the total Supply
    uint256 public maxTxAmount = 69 * 10**18; // 1% maxTxAmount
    uint256 public maxWalletlimit = 69 * 10**18; // 1% Maxwalletlimit
    uint8 private constant _decimals = 18;

    IUniswapV2Router02 immutable uniswapV2Router;
    address public  uniswapV2Pair;
    address immutable WETH;
    address payable public marketingWallet;
    address payable public devWallet;

    uint256 private marketingBuyTax = 3;
    uint256 private marketingSellTax = 3;
    uint256 private devBuyTax = 2;
    uint256 private devSellTax = 2;

    uint256 public buyTax = marketingBuyTax.add(devBuyTax);
    uint256 public sellTax = marketingSellTax.add(devSellTax);
    uint8 private inSwapAndLiquify;

    uint256 countMarketingTax;
    uint256 countDevTax;

    mapping(address => uint256) private _balance;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => bool) private _isExcludedFromFees;
    
    bool public isOpen = false;
    bool private inSwap;
    mapping(address => bool) private _whiteList;

    modifier inSwapFlag {
        inSwap = true;
        _;
        inSwap = false;
    }
    modifier open(address from, address to) {
        require(isOpen || _whiteList[from] || _whiteList[to], "Not Open");
        _;
    }

    constructor() {
        uniswapV2Router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
        WETH = uniswapV2Router.WETH();

        _whiteList[msg.sender] = true;
        _whiteList[address(this)] = true;

        marketingWallet = payable(0x37Dce6E73EF0bd098d93797FaAcEE9Ef3bB1132b);
        devWallet = payable(0x272CB609522d54099e8F6aBB50073E8C98006Fc4);
        _balance[0x3f6F125665441b83c272599a5F0B1248deAA8BEF] = _totalSupply;
        _isExcludedFromFees[marketingWallet] = true;
        _isExcludedFromFees[devWallet] = true;
        _isExcludedFromFees[msg.sender] = true;
        _isExcludedFromFees[address(this)] = true;
        _isExcludedFromFees[address(uniswapV2Router)] = true;
        _allowances[address(this)][address(uniswapV2Router)] = type(uint256).max;
        _allowances[0x3f6F125665441b83c272599a5F0B1248deAA8BEF][address(uniswapV2Router)] = type(uint256).max;
        _allowances[marketingWallet][address(uniswapV2Router)] = type(uint256).max;
        _allowances[devWallet][address(uniswapV2Router)] = type(uint256).max;

        emit Transfer(address(0), _msgSender(), _totalSupply);
    }

    function createPair() external  onlyOwner {

        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(
            address(this),
            WETH
        );

    }

    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 updateBuyTaxes(uint256 marketing, uint256 dev) external onlyOwner {
        require(marketing.add(dev) <= 25);
        marketingBuyTax = marketing;
        devBuyTax = dev;
        buyTax = marketingBuyTax.add(devBuyTax);
    }    

    function updateSellTaxes(uint256 marketing, uint256 dev) external onlyOwner {
        require(marketing.add(dev) <= 25);
        marketingSellTax = marketing;
        devSellTax = dev;
        sellTax = marketingSellTax.add(devSellTax);
    }    

    function ExcludeFromFees(address holder, bool exempt) external onlyOwner {
        _isExcludedFromFees[holder] = exempt;
    }
    
    function ChangeMinTaxSwapLimit(uint256 NewMinTaxSwapLimitAmount) external onlyOwner {
        MinTaxSwapLimit = NewMinTaxSwapLimitAmount;
    }

    function ChangeMaxTxAmountLimit(uint256 NewMaxTxAmountLimit) external onlyOwner {
        maxTxAmount = NewMaxTxAmountLimit;
    }

    function DisableWalletLimit() external onlyOwner {
        maxWalletlimit = _totalSupply;
    }
    
    function ChangeMarketingWalletAddress(address newAddress) external onlyOwner() {
        marketingWallet = payable(newAddress);
    }

    function ChangeDevWalletAddress(address newAddress) external onlyOwner() {
        devWallet = payable(newAddress);
    }

    function EnableTrade() external onlyOwner {
        isOpen = true;
    }

    function includeToWhiteList(address[] memory _users) external onlyOwner {
        for(uint8 i = 0; i < _users.length; i++) {
            _whiteList[_users[i]] = true;
        }
    }

    // Contract Coded by @butiyam on Fiverr and Telegram

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");
        require(isOpen || _whiteList[from] || _whiteList[to], "Not Open");

        uint256 _tax;
        bool isBuying = false;
        if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
            _tax = 0;
        } else {

            if (inSwapAndLiquify == 1) {
                //No tax transfer
                _balance[from] -= amount;
                _balance[to] += amount;

                emit Transfer(from, to, amount);
                return;
            }

            if (from == uniswapV2Pair) {
                isBuying = true;
                _tax = buyTax;
                require(amount <= maxTxAmount);
                require(balanceOf(to).add(amount) <= maxWalletlimit);
            } else if (to == uniswapV2Pair) {
                require(from != address(this) && amount <= maxTxAmount);
                uint256 tokensToSwap = _balance[address(this)];
                if (tokensToSwap > MinTaxSwapLimit && inSwapAndLiquify == 0) {
                    inSwapAndLiquify = 1;
                    internalSwap(countDevTax, devWallet, true);
                    internalSwap(countMarketingTax, marketingWallet, false);

                    inSwapAndLiquify = 0;
                }
                isBuying = false;
                _tax = sellTax;
            } else {
                _tax = 0;
            }
        }
        
    // Contract Coded by @butiyam on Fiverr and Telegram

        //Is there tax for sender|receiver?
        if (_tax != 0) {
            if(isBuying){
                countMarketingTax += (amount * marketingBuyTax) / 100;
                countDevTax += (amount * devBuyTax) / 100; 
            }else {
                countMarketingTax += (amount * marketingSellTax) / 100;
                countDevTax += (amount * devSellTax) / 100; 
            }
            //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);
        }
    }

     function internalSwap(uint256 tokenAmount, address walletAddress, bool isDev) internal inSwapFlag {
        
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = WETH;

        if (_allowances[address(this)][address(uniswapV2Router)] != type(uint256).max) {
            _allowances[address(this)][address(uniswapV2Router)] = type(uint256).max;
        }

        try uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0,
            path,
           walletAddress,
            block.timestamp
        ) {} catch {
            return;
        }

        (isDev)? countDevTax = 0: countMarketingTax = 0;

    }

    receive() external payable {}
}