// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";

/// @title YYDS: Yong Yuan De Shen Token
/// @notice Embrace the spirit of eternal greatness with YYDS, the token of legends.
contract YYDSToken is ERC20, Ownable {
    bool public tradingLive;
    uint256 private startOfTrade;

    address public marketingWallet;
    address public operationsWallet;
    address public futureAirdropWallet;
    address public devWallet;

    address public wethTokenAddress;

    IUniswapV2Router02 public uniswapV2Router;
    address public uniswapV2Pair;
    uint256 public constant MAX_TOKENS = 8_880_000_000 * 10 ** 18; // 8.88 billion tokens

    mapping(address => bool) private approvedAddresses;
    mapping(address => bool) public bannedUsers;

    constructor(
        address routerAddress,
        address wethAddr,
        address marketingAddr,
        address operationsAddr,
        address futureAirdropAddr,
        address devAddr
    ) ERC20("Yong Yuan De Shen", "YYDS") {
        wethTokenAddress = wethAddr;

        marketingWallet = marketingAddr;
        operationsWallet = operationsAddr;
        futureAirdropWallet = futureAirdropAddr;
        devWallet = devAddr;

        // Minting tokens based on the allocation strategy
        _mint(msg.sender, (MAX_TOKENS * 70) / 100); // 70% for Liquidity
        _mint(marketingWallet, (MAX_TOKENS * 10) / 100); // 10% for Marketing
        _mint(operationsWallet, (MAX_TOKENS * 10) / 100); // 10% for Operations
        _mint(futureAirdropWallet, (MAX_TOKENS * 5) / 100); // 5% for Future Airdrops
        _mint(devWallet, (MAX_TOKENS * 5) / 100); // 5% for the Dev Wallet

        // Setup Uniswap with the YYDS token
        uniswapV2Router = IUniswapV2Router02(routerAddress);
        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(
            address(this),
            wethAddr
        );

        // Whitelist essential addresses
        approvedAddresses[owner()] = true;
        approvedAddresses[address(this)] = true;
        approvedAddresses[routerAddress] = true;
        approvedAddresses[marketingWallet] = true;
        approvedAddresses[operationsWallet] = true;
        approvedAddresses[futureAirdropWallet] = true;
        approvedAddresses[devWallet] = true;
    }

    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal override {
        require(sender != address(0), "Sender cannot be the zero address");
        require(!bannedUsers[sender], "Sender is in the hall of shame");
        require(!bannedUsers[recipient], "Recipient is in the hall of shame");

        if (approvedAddresses[sender] || approvedAddresses[recipient]) {
            super._transfer(sender, recipient, amount);
            return;
        }

        // Ensure trading is live before proceeding
        require(tradingLive, "The gates of trade are not yet open");

        // Special conditions for trading pairs
        if (recipient == uniswapV2Pair || sender == uniswapV2Pair) {
            // Apply a high tax to early trades to discourage sniper bots
            if (block.timestamp < startOfTrade + 5 minutes) {
                uint256 taxAmount = (amount * 99) / 100; // 99% tax
                uint256 taxedAmount = amount - taxAmount;

                // Redirect the tax to the reserve treasury
                super._transfer(sender, devWallet, taxAmount);

                // Complete the transaction for the remaining amount
                super._transfer(sender, recipient, taxedAmount);
            } else {
                // Proceed normally for transactions after the initial period
                super._transfer(sender, recipient, amount);
            }
        } else {
            // Standard transfer for non-trading pair transactions
            super._transfer(sender, recipient, amount);
        }
    }

    /// @notice Activates the gates of trading, allowing the flow of YYDS tokens
    function commenceTrading() external onlyOwner {
        tradingLive = true;
        startOfTrade = block.timestamp;
    }

    /// @notice Adds a list of unworthy addresses to the hall of shame
    /// @param accounts Array of addresses to be dishonored
    function addShame(address[] memory accounts) external onlyOwner {
        for (uint i = 0; i < accounts.length; i++) {
            bannedUsers[accounts[i]] = true;
        }
    }

    /// @notice Redeems the honor of addresses, removing them from the hall of shame
    /// @param accounts Array of addresses to be reinstated in honor
    function removeShame(address[] memory accounts) external onlyOwner {
        for (uint i = 0; i < accounts.length; i++) {
            bannedUsers[accounts[i]] = false;
        }
    }
}
[{"inputs":[{"internalType":"address","name":"routerAddress","type":"address"},{"internalType":"address","name":"wethAddr","type":"address"},{"internalType":"address","name":"marketingAddr","type":"address"},{"internalType":"address","name":"operationsAddr","type":"address"},{"internalType":"address","name":"futureAirdropAddr","type":"address"},{"internalType":"address","name":"devAddr","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":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"addShame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bannedUsers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"commenceTrading","outputs":[],"stateMutability":"nonpayable","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":[],"name":"devWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"futureAirdropWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"marketingWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operationsWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"removeShame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","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":[],"name":"tradingLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","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":"amount","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"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wethTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]