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;
}
}
Submitted on: 2025-09-18 11:29:07
Comments
Log in to comment.
No comments yet.