MyERC20Token

Description:

Decentralized Finance (DeFi) protocol contract providing Mintable, Burnable, Pausable, Swap, Factory functionality.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

/**
 * Advanced ERC-20 Token (single-file)
 *
 * - ERC-20 standard
 * - Ownable (owner can mint/pause/blacklist/etc.)
 * - Mint & Burn functions
 * - Pausable (owner)
 * - Blacklist support
 * - Anti-whale (maxTx, maxWallet) with exclusions
 * - Airdrop batch transfers
 * - Rescue functions for ERC20 & native chain coin (BNB/ETH)
 * - Metadata: version + standard
 * - Trading toggle + DEX router whitelist (block/unblock swaps)
 *
 * Test thoroughly on testnet before mainnet deploy.
 */

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner_, address spender) external view returns (uint256);

    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner_, address indexed spender, uint256 value);
}

/* Minimal ERC20 interface to rescue tokens */
interface IERC20Minimal {
    function transfer(address to, uint256 value) external returns (bool);
}

contract Ownable {
    address public owner;
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor() {
        owner = msg.sender;
        emit OwnershipTransferred(address(0), owner);
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Ownable: caller is not the owner");
        _;
    }

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is zero address");
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }
}

contract Pausable is Ownable {
    bool public paused = false;
    event Paused(address account);
    event Unpaused(address account);

    modifier whenNotPaused() {
        require(!paused, "Pausable: paused");
        _;
    }

    modifier whenPaused() {
        require(paused, "Pausable: not paused");
        _;
    }

    function pause() external onlyOwner whenNotPaused {
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() external onlyOwner whenPaused {
        paused = false;
        emit Unpaused(msg.sender);
    }
}

contract MyERC20Token is IERC20, Pausable {
    // Basic token data
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 private _totalSupply;

    // Mark as ERC20 standard for explorers
    string public constant standard = "ERC20";

    // Advanced metadata
    string public version = "1.0.0";

    // Balances and allowances
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    // Blacklist
    mapping(address => bool) public blacklist;
    event BlacklistUpdated(address indexed account, bool isBlacklisted);

    // Anti-whale limits
    uint256 public maxTxAmount;      // 0 = no limit (in smallest unit)
    uint256 public maxWalletAmount;  // 0 = no limit (in smallest unit)
    mapping(address => bool) public isExcludedFromLimits;
    event MaxTxAmountUpdated(uint256 oldValue, uint256 newValue);
    event MaxWalletAmountUpdated(uint256 oldValue, uint256 newValue);
    event ExcludedFromLimits(address indexed account, bool excluded);

    // Airdrop event
    event Airdrop(address indexed operator, uint256 totalRecipients);

    // Rescue events
    event RecoveredERC20(address indexed token, uint256 amount);
    event RecoveredNative(uint256 amount);

    // Mint & burn events
    event Mint(address indexed to, uint256 amount);
    event Burn(address indexed from, uint256 amount);

    // Trading toggle + dex router whitelist
    bool public tradingEnabled = false; // default off; owner must enable when ready
    mapping(address => bool) public dexRouter;
    event TradingEnabledUpdated(bool enabled);
    event DexRouterUpdated(address indexed router, bool allowed);

    // Constructor
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 initialSupply
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        // exclude owner and contract from limits by default
        isExcludedFromLimits[msg.sender] = true;
        isExcludedFromLimits[address(this)] = true;

        if (initialSupply > 0) {
            // initialSupply is expressed in whole tokens
            _mint(msg.sender, initialSupply * (10 ** _decimals));
        }
    }

    // ---------------------------
    // ERC20 read functions
    // ---------------------------
    function totalSupply() external view override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) external view override returns (uint256) {
        return _balances[account];
    }

    function allowance(address owner_, address spender) external view override returns (uint256) {
        return _allowances[owner_][spender];
    }

    // ---------------------------
    // ERC20 write functions
    // ---------------------------
    function transfer(address recipient, uint256 amount) external override whenNotPaused returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    }

    function approve(address spender, uint256 amount) external override whenNotPaused returns (bool) {
        require(spender != address(0), "approve to zero address");
        _allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) external override whenNotPaused returns (bool) {
        require(amount <= _allowances[sender][msg.sender], "transfer amount exceeds allowance");
        _allowances[sender][msg.sender] -= amount;
        _transfer(sender, recipient, amount);
        emit Approval(sender, msg.sender, _allowances[sender][msg.sender]);
        return true;
    }

    // Increase / decrease allowance helpers
    function increaseAllowance(address spender, uint256 addedValue) external whenNotPaused returns (bool) {
        require(spender != address(0), "increaseAllowance to zero");
        _allowances[msg.sender][spender] += addedValue;
        emit Approval(msg.sender, spender, _allowances[msg.sender][spender]);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) external whenNotPaused returns (bool) {
        require(spender != address(0), "decreaseAllowance to zero");
        uint256 currentAllowance = _allowances[msg.sender][spender];
        if (subtractedValue >= currentAllowance) {
            _allowances[msg.sender][spender] = 0;
        } else {
            _allowances[msg.sender][spender] = currentAllowance - subtractedValue;
        }
        emit Approval(msg.sender, spender, _allowances[msg.sender][spender]);
        return true;
    }

    // ---------------------------
    // Internal transfer (with blacklist + anti-whale + trading toggle)
    // ---------------------------
    modifier notBlacklisted(address account) {
        require(!blacklist[account], "Address blacklisted");
        _;
    }

    function _transfer(address from, address to, uint256 amount) internal notBlacklisted(from) notBlacklisted(to) {
        require(to != address(0), "transfer to zero address");
        require(amount <= _balances[from], "transfer exceeds balance");

        // If trading is disabled, block transfers that interact with registered DEX routers
        // (i.e., swaps). This blocks swaps but allows normal wallet-to-wallet transfers.
        if (!tradingEnabled) {
            if (dexRouter[from] || dexRouter[to]) {
                revert("Trading disabled: swaps currently blocked");
            }
        }

        // enforce anti-whale limits unless excluded
        if (!isExcludedFromLimits[from] && !isExcludedFromLimits[to]) {
            if (maxTxAmount > 0) {
                require(amount <= maxTxAmount, "MyERC20Token: transfer exceeds maxTxAmount");
            }
            if (maxWalletAmount > 0) {
                require(_balances[to] + amount <= maxWalletAmount, "MyERC20Token: recipient balance exceeds maxWalletAmount");
            }
        }

        _balances[from] -= amount;
        _balances[to] += amount;

        emit Transfer(from, to, amount);
    }

    // ---------------------------
    // Mint & Burn (only owner can mint)
    // ---------------------------
    function mint(address account, uint256 amount) external onlyOwner returns (bool) {
        _mint(account, amount);
        return true;
    }

    function _mint(address account, uint256 amount) internal {
        require(account != address(0), "mint to zero address");

        _totalSupply += amount;
        _balances[account] += amount;

        emit Mint(account, amount);
        emit Transfer(address(0), account, amount);
    }

    function burn(uint256 amount) external returns (bool) {
        _burn(msg.sender, amount);
        return true;
    }

    function burnFrom(address account, uint256 amount) external returns (bool) {
        require(amount <= _allowances[account][msg.sender], "burn amount exceeds allowance");
        _allowances[account][msg.sender] -= amount;
        _burn(account, amount);
        return true;
    }

    function _burn(address account, uint256 amount) internal {
        require(account != address(0), "burn from zero address");
        require(amount <= _balances[account], "burn exceeds balance");

        _balances[account] -= amount;
        _totalSupply -= amount;

        emit Burn(account, amount);
        emit Transfer(account, address(0), amount);
    }

    // ---------------------------
    // Admin / Owner functions
    // ---------------------------

    // Blacklist controls
    function setBlacklist(address account, bool value) external onlyOwner {
        blacklist[account] = value;
        emit BlacklistUpdated(account, value);
    }

    // Anti-whale controls (values in smallest unit)
    function setMaxTxAmount(uint256 newAmount) external onlyOwner {
        emit MaxTxAmountUpdated(maxTxAmount, newAmount);
        maxTxAmount = newAmount;
    }

    function setMaxWalletAmount(uint256 newAmount) external onlyOwner {
        emit MaxWalletAmountUpdated(maxWalletAmount, newAmount);
        maxWalletAmount = newAmount;
    }

    // Exclude / include an address from limits (owner, contract, router, etc.)
    function setExcludedFromLimits(address account, bool excluded) external onlyOwner {
        isExcludedFromLimits[account] = excluded;
        emit ExcludedFromLimits(account, excluded);
    }

    function setVersion(string calldata _version) external onlyOwner {
        version = _version;
    }

    // Airdrop helper: owner pays tokens from own balance and distributes
    function airdrop(address[] calldata recipients, uint256[] calldata amounts) external onlyOwner whenNotPaused {
        uint256 len = recipients.length;
        require(len == amounts.length, "Length mismatch");
        for (uint256 i = 0; i < len; i++) {
            address to = recipients[i];
            uint256 amt = amounts[i];
            // use internal transfer (blacklist/limits enforced)
            _transfer(msg.sender, to, amt);
        }
        emit Airdrop(msg.sender, len);
    }

    // Rescue accidentally sent ERC20 tokens to this contract
    function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {
        require(tokenAddress != address(this), "Cannot recover this token");
        IERC20Minimal(tokenAddress).transfer(owner, tokenAmount);
        emit RecoveredERC20(tokenAddress, tokenAmount);
    }

    // Rescue stuck native currency (BNB/ETH)
    function recoverNative(uint256 amount) external onlyOwner {
        (bool sent, ) = payable(owner).call{value: amount}("");
        require(sent, "Native transfer failed");
        emit RecoveredNative(amount);
    }

    // Fallback to receive native currency
    receive() external payable {}

    // ---------------------------
    // Trading toggle & DEX whitelist
    // ---------------------------

    /// @notice Enable or disable trading (swaps). When disabled, transfers involving `dexRouter` addresses are blocked.
    function setTradingEnabled(bool enabled) external onlyOwner {
        tradingEnabled = enabled;
        emit TradingEnabledUpdated(enabled);
    }

    /// @notice Add or remove an address to the DEX router whitelist.
    /// @dev Typical use: add PancakeSwap / Uniswap router address so swaps are recognized and blocked when trading disabled.
    function setDexRouter(address router, bool allowed) external onlyOwner {
        dexRouter[router] = allowed;
        emit DexRouterUpdated(router, allowed);
    }

    // ---------------------------
    // Helpers / view functions
    // ---------------------------
    function isBlacklisted(address account) external view returns (bool) {
        return blacklist[account];
    }

    function isExcluded(address account) external view returns (bool) {
        return isExcludedFromLimits[account];
    }

    function isDexRouter(address account) external view returns (bool) {
        return dexRouter[account];
    }
}

Tags:
ERC20, DeFi, Mintable, Burnable, Pausable, Swap, Factory|addr:0x0a5e22ffdf0bab43df8af4562fcce159545029c6|verified:true|block:23718234|tx:0x7643a054bb43f48d40e638cbaa6fc48534f3067203b7ed56cd34dba79d3e6947|first_check:1762170294

Submitted on: 2025-11-03 12:44:54

Comments

Log in to comment.

No comments yet.