CloneableTestToken

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

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

/*
 * Minimal initializable ERC20-like token for clones.
 * - initialize(...) must be called exactly once per clone.
 * - publicMintAllowed: if true, anyone can call mint(); otherwise only owner.
 * - no pre-mint in implementation; initial supply is minted during initialize() onto `owner`.
 */

contract CloneableTestToken {
    // ERC20 basics
    string public name;
    string public symbol;
    uint8 public constant decimals = 18;
    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    // init/owner/state
    address public owner;
    /// @notice address of the logic implementation (set at deploy time). Used to prevent initializing the implementation itself.
    address public immutable implementation;
    bool public initialized;
    bool public paused;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed ownerAddr, address indexed spender, uint256 value);
    event Paused(address indexed by);
    event Unpaused(address indexed by);

    modifier onlyOwner() {
        require(msg.sender == owner, "owner");
        _;
    }
    modifier whenNotPaused() {
        require(!paused, "paused");
        _;
    }

    /// @notice initialize must be called exactly once on each clone
    // add a constructor and change initialize guard to block initializing the implementation
    constructor() {
        // record the implementation contract address at deployment time
        implementation = address(this);
    }
    function initialize(
        string memory _name,
        string memory _symbol,
        address _owner,
        uint256 _initialSupply
    ) external {
        // Prevent callers from initializing the implementation contract itself.
        // When called on the implementation address: address(this) == implementation -> revert.
        // When called on a clone: address(this) != implementation -> allowed.
        require(address(this) != implementation, "cannot initialize implementation");
        require(!initialized, "already init");
        initialized = true;

        name = _name;
        symbol = _symbol;
        owner = _owner == address(0) ? msg.sender : _owner;

        if (_initialSupply > 0) {
            _mint(owner, _initialSupply);
        }
    }

    /* ========== ERC20 minimal functions ========== */

    function transfer(address to, uint256 amount) external whenNotPaused returns (bool) {
        _transfer(msg.sender, to, amount);
        return true;
    }

    function approve(address spender, uint256 amount) external whenNotPaused returns (bool) {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) external whenNotPaused returns (bool) {
        uint256 allowed = allowance[from][msg.sender];
        require(allowed >= amount, "allowance");
        allowance[from][msg.sender] = allowed - amount;
        _transfer(from, to, amount);
        return true;
    }

    function _transfer(address from, address to, uint256 amount) internal {
        require(to != address(0), "zero");
        uint256 bal = balanceOf[from];
        require(bal >= amount, "balance");
        balanceOf[from] = bal - amount;
        balanceOf[to] += amount;
        emit Transfer(from, to, amount);
    }

    /* ========== Minting ========== */

    /// public mint if allowed (minter pays gas)
    function mint(uint256 amount) external whenNotPaused {
        _mint(msg.sender, amount);
    }

    /// owner mint to arbitrary address
    function ownerMint(address to, uint256 amount) external onlyOwner whenNotPaused {
        _mint(to, amount);
    }

    function _mint(address to, uint256 amount) internal {
        require(to != address(0), "zero");
        totalSupply += amount;
        balanceOf[to] += amount;
        emit Transfer(address(0), to, amount);
    }

    /* ========== Owner controls ========== */

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

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

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "zero");
        owner = newOwner;
    }
}

Tags:
Factory|addr:0x9be231eae1548de427a131988a9c272eb37bb868|verified:true|block:23386313|tx:0x2ccacf360a3d607a2c4c594d986710b3d771621cd7c46a481fa8e591ba533089|first_check:1758187745

Submitted on: 2025-09-18 11:29:07

Comments

Log in to comment.

No comments yet.