// Contract: LetsGoBrandon
// Target function: function setIsExcludedFromFees(address account, bool value) external onlyOwner
F54Ac38384C9618449);
		developmentAddress = payable(0x143CE9C93e5F03e860FFEeDEf9D97F621104ad70);

		isExcludedFromFees[owner()] = true;
		isExcludedFromFees[marketingAddress] = true;
		isExcludedFromFees[developmentAddress] = true;
		isExcludedFromFees[self] = true;
		isExcludedFromFees[DEAD_ADDRESS] = true;

		isExcludedFromMaxWallet[owner()] = true;
		isExcludedFromMaxWallet[marketingAddress] = true;
		isExcludedFromMaxWallet[developmentAddress] = true;
		isExcludedFromMaxWallet[self] = true;
		isExcludedFromMaxWallet[DEAD_ADDRESS] = true;

		//new - exclude owner from rewards for fair distribution
		tOwned[owner()] = tokenFromReflection(rOwned[owner()]);
		isExcludedFromRewards[owner()] = true;
		excluded.push(owner());

		emit Transfer(ZERO_ADDRESS, owner(), tTotal);
	}

	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 view override returns (uint256) {
		return tTotal;
	}

	function balanceOf(address account) public view override returns (uint256) {
		if (isExcludedFromRewards[account]) return tOwned[account];
		return tokenFromReflection(rOwned[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);

		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 tokenFromReflection(uint256 rAmount) public view returns (uint256) {
		require(rAmount <= rTotal, "Amount must be less than total reflections");
		uint256 currentRate = _getRate();
		return rAmount / currentRate;
	}

	function excludeFromRewards(address account) external onlyOwner {
		require(!isExcludedFromRewards[account], "Account is already excluded");

		if (rOwned[account] > 0) {
			tOwned[account] = tokenFromReflection(rOwned[account]);
		}

		isExcludedFromRewards[account] = true;
		excluded.push(account);
	}

	function includeInRewards(address account) external onlyOwner {
		require(isExcludedFromRewards[account], "Account is not excluded");

		for (uint256 i = 0; i < excluded.length; i++) {
			if (excluded[i] == account) {
				excluded[i] = excluded[excluded.length - 1];
				tOwned[account] = 0;
				isExcludedFromRewards[account] = false;
				excluded.pop();
				break;
			}
		}
	}

	function _getValues(uint256 tAmount, bool takeFee, uint256 extraFee) private view returns (ReflectValueSet memory set) {
		set = _getTValues(tAmount, takeFee, extraFee);
		(set.rAmount, set.rTransferAmount, set.rReflectFee, set.rOtherFee, set.rExtraFee) = _getRValues(set, tAmount, takeFee, _getRate());
		return set;
	}

	function _getTValues(uint256 tAmount, bool takeFee, uint256 extraFee) private view returns (ReflectValueSet memory set) {
		if (!takeFee) {
			set.tTransferAmount = tAmount;
			return set;
		}

		set.tReflectFee = tAmount * fees.reflectFee / 100;
		set.tExtraFee = tAmount * extraFee / 100;
		set.tOtherFee = tAmount * (fees.marketingFee + fees.liquidityFee + fees.developmentFee) / 100;
		set.tTransferAmount = tAmount - set.tReflectFee - set.tOtherFee - set.tExtraFee;

		return set;
	}

	function _getRValues(ReflectValueSet memory set, uint256 tAmount, bool takeFee, uint256 currentRate) private pure returns (uint256 rAmount, uint256 rTransferAmount, uint256 rReflectFee, uint256 rOtherFee, uint256 rExtraFee) {
		rAmount = tAmount * currentRate;

		if (!takeFee) {
			return (rAmount, rAmount, 0, 0, 0);
		}

		rReflectFee = set.tReflectFee * currentRate;
		rOtherFee = set.tOtherFee * currentRate;
		rExtraFee = set.tExtraFee * currentRate;
		rTransferAmount = rAmount - rReflectFee - rOtherFee - rExtraFee;
		return (rAmount, rTransferAmount, rReflectFee, rOtherFee, rExtraFee);
	}

	function _getRate() private view returns (uint256) {
		(uint256 rSupply, uint256 tSupply) = _getCurrentSupply();
		return rSupply / tSupply;
	}

	function _getCurrentSupply() private view returns (uint256, uint256) {
		uint256 rSupply = rTotal;
		uint256 tSupply = tTotal;

		for (uint256 i = 0; i < excluded.length; i++) {
			if (rOwned[excluded[i]] > rSupply || tOwned[excluded[i]] > tSupply) return (rTotal, tTotal);
			rSupply -= rOwned[excluded[i]];
			tSupply -= tOwned[excluded[i]];
		}

		if (rSupply < rTotal / tTotal) return (rTotal, tTotal);
		return (rSupply, tSupply);
	}

	function _approve(address owner, address spender, uint256 amount) private {
		require(owner != ZERO_ADDRESS, "ERC20: approve from the zero address");
		require(spender != ZERO_ADDRESS, "ERC20: approve to the zero address");

		allowances[owner][spender] = amount;

		emit Approval(owner, spender, amount);
	}

	function _transfer(address from, address to, uint256 amount) private {
		require(from != ZERO_ADDRESS, "ERC20: transfer from the zero address");
		require(to != ZERO_ADDRESS, "ERC20: transfer to the zero address");
		require(!isBot[from], "ERC20: address blacklisted (bot)");
		require(amount > 0, "Transfer amount must be greater than zero");
		require(amount <= balanceOf(from), "You are trying to transfer more than your balance");

		if (maxWalletAmount > 0 && !automatedMarketMakerPairs[to] && !isExcludedFromMaxWallet[to]) {
			require((balanceOf(to) + amount) <= maxWalletAmount, "You are trying to transfer more than the max wallet amount");
		}

		if (launchedAt == 0 && automatedMarketMakerPairs[to]) {
			launchedAt = block.number;
		}

		bool shouldTakeFees = !isExcludedFromFees[from] && !isExcludedFromFees[to];
		if (shouldTakeFees) {
			require(amount <= (automatedMarketMakerPairs[from] ? maxTxAmountBuy : maxTxAmountSell), "You are trying to transfer too many tokens");

			if (automatedMarketMakerPairs[from] && block.number <= launchedAt) {
				isBot[to] = true;
			}
		}

		uint256 balance = balanceOf(address(this));

		if (balance > maxTxAmountSell) {
			balance = maxTxAmountSell;
		}
		uint256 extraFees = 0;
		if(!automatedMarketMakerPairs[from]) 
		{
			if (isFeeProcessingEnabled && !areFeesBeingProcessed 
        		&& balance >= feeProcessingThreshold 
			) {
				areFeesBeingProcessed = true;
				_processFees(balance);
				areFeesBeingProcessed = false;
			}
			if(automatedMarketMakerPairs[to]){ //user is selling//
				uint256 firstTransTime = firstTransactionTimestamp[from];
				uint256 blockTime = block.timestamp;
				//first 5 minutes from launch ONLY - bot protection = 15% burn fee
				if(blockTime < launchedAtTime + 5 minutes){
					extraFees = 15;
				}
				//first week early sale = 10% burn fee
				else if(blockTime < firstTransTime + 7 days){
					extraFees = extraBurnFee;
				}
				//else don't apply extra tax//
			}
		}

		_tokenTransfer(from, to, amount, shouldTakeFees, extraFees);
	}

	function _takeReflectFees(uint256 rReflectFee) private {
		rTotal -= rReflectFee;
	}

	function _takeOtherFees(uint256 rOtherFee, uint256 tOtherFee) private {
		address self = address(this);

		rOwned[self] += rOtherFee;

		if (isExcludedFromRewards[self]) {
			tOwned[self] += tOtherFee;
		}
	}

	function _takeExtraFees(uint256 rExtraFee, uint256 tExtraFee) private {
		rOwned[DEAD_ADDRESS] += rExtraFee;
		if (isExcludedFromRewards[DEAD_ADDRESS]) {
			tOwned[DEAD_ADDRESS] += tExtraFee;
		}
	}

	function _tokenTransfer(address sender, address recipient, uint256 tAmount, bool shouldTakeFees, uint256 extraFee) private {
		ReflectValueSet memory set = _getValues(tAmount, shouldTakeFees, extraFee);

		if (isExcludedFromRewards[sender]) {
			tOwned[sender] -= tAmount;
		}

		if (isExcludedFromRewards[recipient]) {
			tOwned[recipient] += set.tTransferAmount;
		}

		rOwned[sender] -= set.rAmount;
		rOwned[recipient] += set.rTransferAmount;

		if(firstTransactionTimestamp[recipient] == 0){ 
			firstTransactionTimestamp[recipient] = block.timestamp;
		}

		if (shouldTakeFees) {
			_takeReflectFees(set.rReflectFee);
			_takeOtherFees(set.rOtherFee, set.tOtherFee);
			emit Transfer(sender, address(this), set.tOtherFee);
			if(set.tExtraFee > 0){
				_takeExtraFees(set.rExtraFee, set.tExtraFee);
				emit Transfer(sender, DEAD_ADDRESS, set.tExtraFee);
			}
		}

		emit Transfer(sender, recipient, set.tTransferAmount);
	}

	function _processFees(uint256 amount) private lockTheSwap {
		uint256 _marketingFee = fees.marketingFee + fees.developmentFee;
		uint256 feeSum = _marketingFee + fees.liquidityFee;
		
		if (feeSum == 0) return;

		//Calculate amounts
		uint256 amountForMarketing = amount * _marketingFee / feeSum;
		uint256 amountForLiquidity = amount - amountForMarketing;

		//Do processing
		_swapExactTokensForETH(amountForMarketing);
		_addLiquidity(amountForLiquidity);

		//Send marketing funds
		uint256 balanceEth = address(this).balance;
		uint256 marketingInEth = balanceEth * fees.marketingFee / _marketingFee;
		marketingAddress.transfer(marketingInEth);
		developmentAddress.transfer(address(this).balance);
	}

	function _addLiquidity(uint256 amount) private {
		address self = address(this);

		uint256 tokensToSell = amount / 2;
		uint256 tokensForLiquidity = amount - tokensToSell;

		uint256 ethForLiquidity = _swapExactTokensForETH(tokensToSell);

		_approve(self, address(router), MAX_UINT);
		router.addLiquidityETH{value: ethForLiquidity}(self, tokensForLiquidity, 0, 0, DEAD_ADDRESS, block.timestamp);
	}

	function _swapExactTokensForETH(uint256 amountIn) private returns (uint256) {
		address self = address(this);

		address[] memory path = new address[](2);
		path[0] = self;
		path[1] = router.WETH();

		_approve(self, address(router), MAX_UINT);

		uint256 previousBalance = self.balance;
		router.swapExactTokensForETHSupportingFeeOnTransferTokens(amountIn, 0, path, self, block.timestamp);
		return self.balance - previousBalance;
	}
	
	//OWNER ONLY WRITE//
	function burn(uint256 value) external onlyOwner {
		require(balanceOf(_msgSender()) >= value, "Insufficient token balance for burn");
		_tokenTransfer(_msgSender(), DEAD_ADDRESS, value, false, 0);
    }

	function openTrading(uint256 tokensForLiquidity) external payable onlyOwner {
		address self = address(this);
		require(!isTradingOpen, "Trading is already open");
		require(balanceOf(_msgSender()) >= tokensForLiquidity, "Insufficient token balance for initial liquidity");
		require(msg.value > 0, "Insufficient ETH for initial liquidity");

		//Transfer tokens from sender/owner to contract
		_tokenTransfer(_msgSender(), self, tokensForLiquidity, false, 0);

		//Create pair
		address pairAddress = IDEXFactory(router.factory()).createPair(self, router.WETH());
		automatedMarketMakerPairs[pairAddress] = true;
		isExcludedFromMaxWallet[pairAddress] = true;

		//Add liquidity
		_approve(self, address(router), MAX_UINT);
		router.addLiquidityETH{value: msg.value}(self, tokensForLiquidity, 0, 0, owner(), block.timestamp);

		isFeeProcessingEnabled = true;
		isTradingOpen = true;
		launchedAtTime = block.timestamp;
	}

	function setAutomatedMarketMakerPair(address pair, bool value) external onlyOwner {
		require(automatedMarketMakerPairs[pair] != value, "Automated market maker pair is already set to that value");
		automatedMarketMakerPairs[pair] = value;

		if (value) {
			isExcludedFromMaxWallet[pair] = true;
		}
	}

	function setBurnFees(uint256 burnFee) external onlyOwner {
		require(burnFee <= 10, "Cannot set burn fee to above 10%");
		extraBurnFee = burnFee;
	}

	function setIsFeeProcessingEnabled(bool value) public onlyOwner {
		isFeeProcessingEnabled = value;
	}

	function setFeeProcessingThreshold(uint256 value) external onlyOwner {
		feeProcessingThreshold = value;
	}

	function setMarketingAddress(address payable value) external onlyOwner {
		require(marketingAddress != value, "Marketing address is already set to this value");
		marketingAddress = value;
	}
	
	function setDevelopmentAddress(address payable value) external onlyOwner {
		require(developmentAddress != value, "Development address is already set to this value");
		developmentAddress = value;
	}

	function setIsBot(address[] memory accounts, bool value) external onlyOwner {
		for (uint256 i = 0; i < accounts.length; i++){
			isBot[accounts[i]] = value;
		}
	}

	function transferMany(address[] memory accounts, uint256 amount) external onlyOwner {
		require(balanceOf(_msgSender()) >= amount * accounts.length, "Insufficient token balance");
		for (uint256 i = 0; i < accounts.length; i++){
			_tokenTransfer(_msgSender(), accounts[i], amount, false, 0);
		}
	}

	function setMaxTransactionAmounts(uint256 maxBuy, uint256 maxSell) external onlyOwner {
		require(maxBuy >= (tTotal / 400), "Must set max buy to at least 0.25% of total supply");
		require(maxSell >= (tTotal / 400), "Must set max sell to at least 0.25% of total supply");

		maxTxAmountBuy = maxBuy;
		maxTxAmountSell = maxSell;
	}

	function setMaxWalletAmount(uint256 value) external onlyOwner {
		require(value >= (tTotal / 200), "Must set max wallet to at least 0.5% of total supply");
		maxWalletAmount = value;
	}

	function manuallyProcessFees() external onlyOwner{
		uint256 balance = balanceOf(address(this));
		_tokenTransfer(address(this), _msgSender(), balance, false, 0);
	}

	// function setIsExcludedFromMaxWallet(address account, bool value) external onlyOwner {
	// 	require(isExcludedFromMaxWallet[account] != value, "Account is already set to this value");
	// 	isExcludedFromMaxWallet[account] = value;
	// }