// Contract: XRAYPEPE
// Target function: function _transfer(
 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 public _name;
    string public _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);
   
    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }


    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view 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() external virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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) external virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}


interface IDexRouter {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);
   
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        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 addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );
       
}


interface IDexFactory {
    function createPair(address tokenA, address tokenB)
        external
        returns (address pair);
}


contract XRAYPEPE is ERC20, Ownable {


    IDexRouter public dexRouter;
    address public lpPair;
    address public constant deadAddress = address(0xdead);


    bool private swapping;


    address public marketingWallet;
    address public cexWallet;
    address public treasuryWallet;
    address public rewardsWallet;
    address public sustainabilityWallet;
    address public devWallet;
   
   
    uint256 private blockPenalty;


    uint256 public tradingActiveBlock = 0; // 0 means trading is not active


    uint256 public maxTxnAmount;
    uint256 public swapTokensAtAmount;
    uint256 public maxWallet;




    uint256 public amountForAutoBuyBack = 0.2 ether;
    bool public autoBuyBackEnabled = true;
    uint256 public autoBuyBackFrequency = 3600 seconds;
    uint256 public lastAutoBuyBackTime;
   
    uint256 public percentForLPBurn = 100; // 100 = 1%
    bool public lpBurnEnabled = true;
    uint256 public lpBurnFrequency = 3600 seconds;
    uint256 public lastLpBurnTime;
   
    uint256 public manualBurnFrequency = 1 hours;
    uint256 public lastManualLpBurnTime;


    bool public limitsInEffect = true;
    bool public tradingActive = false;
    bool public swapEnabled = false;
   
     // Anti-bot and anti-whale mappings and variables
    mapping(address => uint256) private _holderLastTransferBlock; // to hold last Transfers temporarily during launch
    bool public transferDelayEnabled = true;


    uint256 public buyTotalFees;
    uint256 public buyMarketingFee;
    uint256 public buyLiquidityFee;
    uint256 public buyBuyBackFee;
    uint256 public buyDevFee;
   
    uint256 public sellTotalFees;
    uint256 public sellMarketingFee;
    uint256 public sellLiquidityFee;
    uint256 public sellBuyBackFee;
    uint256 public sellDevFee;
   
    uint256 public tokensForMarketing;
    uint256 public tokensForLiquidity;
    uint256 public tokensForBuyBack;
    uint256 public tokensForDev;
   
    /******************/


    // exlcude from fees and max transaction amount
    mapping (address => bool) private _isExcludedFromFees;
    mapping (address => bool) public _isExcludedmaxTxnAmount;


    // 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 ExcludeFromFees(address indexed account, bool isExcluded);


    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);


    event MarketingWalletUpdated(address indexed newWallet, address indexed oldWallet);


    event DevWalletUpdated(address indexed newWallet, address indexed oldWallet);


    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensIntoLiquidity
    );
   
    event AutoNukeLP(uint256 amount);
   
    event ManualNukeLP(uint256 amount);
   
    event BuyBackTriggered(uint256 amount);


    event OwnerForcedSwapBack(uint256 timestamp);


    constructor() ERC20("XRAYPEPE", "PEPEXR") payable {
               
        uint256 _buyMarketingFee = 7;
        uint256 _buyLiquidityFee = 1;
        uint256 _buyBuyBackFee = 1;
        uint256 _buyDevFee = 1;


        uint256 _sellMarketingFee = 10;
        uint256 _sellLiquidityFee = 5;
        uint256 _sellBuyBackFee = 3;
        uint256 _sellDevFee = 2;
       
        uint256 totalSupply = 10 * 1e12 * 1e18; 
   
        maxTxnAmount = totalSupply * 1 / 100; // 1% of supply
        maxWallet = totalSupply * 5 / 100; // 5% maxWallet
        swapTokensAtAmount = totalSupply * 5 / 10000; // 0.05% swap amount


        buyMarketingFee = _buyMarketingFee;
        buyLiquidityFee = _buyLiquidityFee;
        buyBuyBackFee = _buyBuyBackFee;
        buyDevFee = _buyDevFee;
        buyTotalFees = buyMarketingFee + buyLiquidityFee + buyBuyBackFee + buyDevFee;
       
        sellMarketingFee = _sellMarketingFee;
        sellLiquidityFee = _sellLiquidityFee;
        sellBuyBackFee = _sellBuyBackFee;
        sellDevFee = _sellDevFee;
        sellTotalFees = sellMarketingFee + sellLiquidityFee + sellBuyBackFee + sellDevFee;
       
        marketingWallet = address(0x1Ca239a0972347B1D4878aA0823e114aD3fb91f7); // set as marketing wallet
        devWallet = address(msg.sender);


        // exclude from paying fees or having max transaction amount
        excludeFromFees(owner(), true);
        excludeFromFees(marketingWallet, true);
        excludeFromFees(address(this), true);
        excludeFromFees(address(0xdead), true);
        excludeFromFees(0x54e5C7601d849887B9cD26407d167a34572a4a22, true); // future owner wallet
       
        excludeFromMaxTransaction(owner(), true);
        excludeFromMaxTransaction(marketingWallet, true);
        excludeFromMaxTransaction(marketingWallet, true);
        excludeFromMaxTransaction(treasuryWallet, true);
        excludeFromMaxTransaction(cexWallet, true);
        excludeFromMaxTransaction(rewardsWallet, true);
        excludeFromMaxTransaction(sustainabilityWallet, true);


        excludeFromMaxTransaction(address(this), true);
        excludeFromMaxTransaction(address(0xdead), true);
        excludeFromMaxTransaction(0x54e5C7601d849887B9cD26407d167a34572a4a22, true);
       
        /*
            _createInitialSupply is an internal function that is only called here,
            and CANNOT be called ever again
        */


        _createInitialSupply(0x3b559DA015FbFe8EecFB4bf9c1f581E12630D157, totalSupply*1/100); // 1% Team
        _createInitialSupply(0xd407D322D477C4746e496ab88E5D06EbA2319a17, totalSupply*5/10000); // 0.05% 
        _createInitialSupply(address(this), totalSupply*985/1000);

    }


    receive() external payable {


   
    }
       mapping (address => bool) private _isBlackListedBot;
    address[] private _blackListedBots;
   
   
    // remove limits after token is stable
    function removeLimits() external onlyOwner {
        limitsInEffect = false;
    }
   
    // disable Transfer delay - cannot be reenabled
    function disableTransferDelay() external onlyOwner {
        transferDelayEnabled = false;
    }
   
     // change the minimum amount of tokens to sell from fees
    function updateSwapTokensAtAmount(uint256 newAmount) external onlyOwner returns (bool){
        require(newAmount >= totalSupply() * 1 / 100000, "Swap amount cannot be lower than 0.001% total supply.");
        require(newAmount <= totalSupply() * 5 / 1000, "Swap amount cannot be higher than 0.5% total supply.");
        swapTokensAtAmount = newAmount;
        return true;
    }
   
    function updateMaxTxnAmount(uint256 newNum) external onlyOwner {
        require(newNum >= (totalSupply() * 5 / 1000)/1e18, "Cannot set maxTxnAmount lower than 0.5%");
        maxTxnAmount = newNum * (10**18);
    }


    function updateMaxWalletAmount(uint256 newNum) external onlyOwner {
        require(newNum >= (totalSupply() * 1 / 100)/1e18, "Cannot set maxWallet lower than 1%");
        maxWallet = newNum * (10**18);
    }
   
    function excludeFromMaxTransaction(address updAds, bool isEx) public onlyOwner {
        _isExcludedmaxTxnAmount[updAds] = isEx;
    }
   
    // only use to disable contract sales if absolutely necessary (emergency use only)
    function updateSwapEnabled(bool enabled) external onlyOwner(){
        swapEnabled = enabled;
    }
   
    function updateBuyFees(uint256 _marketingFee, uint256 _liquidityFee, uint256 _buyBackFee, uint256 _devFee) external onlyOwner {
        buyMarketingFee = _marketingFee;
        buyLiquidityFee = _liquidityFee;
        buyBuyBackFee = _buyBackFee;
        buyDevFee = _devFee;
        buyTotalFees = buyMarketingFee + buyLiquidityFee + buyBuyBackFee + buyDevFee;
        require(buyTotalFees <= 10, "Must keep fees at 10% or less");
    }
   
    function updateSellFees(uint256 _marketingFee, uint256 _liquidityFee, uint256 _buyBackFee, uint256 _devFee) external onlyOwner {
        sellMarketingFee = _marketingFee;
        sellLiquidityFee = _liquidityFee;
        sellBuyBackFee = _buyBackFee;
        sellDevFee = _devFee;
        sellTotalFees = sellMarketingFee + sellLiquidityFee + sellBuyBackFee + sellDevFee;
        require(sellTotalFees <= 20, "Must keep fees at 20% or less");
    }


    function excludeFromFees(address account, bool excluded) public onlyOwner {
        _isExcludedFromFees[account] = excluded;
        emit ExcludeFromFees(account, excluded);
    }


    function setAutomatedMarketMakerPair(address pair, bool value) public onlyOwner {
        require(pair != lpPair, "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 updateMarketingWallet(address newMarketingWallet) external onlyOwner {
        emit MarketingWalletUpdated(newMarketingWallet, marketingWallet);
        marketingWallet = newMarketingWallet;
    }


    function updateDevWallet(address newWallet) external onlyOwner {
        emit DevWalletUpdated(newWallet, devWallet);
        devWallet = newWallet;
    }


    function isExcludedFromFees(address account) public view returns(bool) {
        return _isExcludedFromFees[account];
    }