In this ICE, you’ll deploy a tiny, dollar-style ERC-20 (6 decimals) to the Sepolia Ethereum testnet using Remix + MetaMask, then mint tokens to teammates and import the token in wallets.
ClubStablecoin.sol
.// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* Club Stablecoin (simple ERC-20 demo)
* - Owner (deployer) can mint and change owner.
* - Anyone can transfer.
* - Anyone can burn their own tokens.
* - Decimals = 6 (dollar-like: 1.000000)
* NOTE: Testnet demo only. Not audited. No fees/pausing/blacklists.
*/
contract ClubStablecoin {
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public totalSupply;
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
address public owner;
modifier onlyOwner(){ require(msg.sender == owner, "not owner"); _; }
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
constructor(string memory _name, string memory _symbol, uint8 _decimals){
owner = msg.sender;
emit OwnershipTransferred(address(0), msg.sender);
name = _name;
symbol = _symbol;
decimals = _decimals; // e.g., 6 for $-style 1.000000
}
function balanceOf(address a) public view returns (uint256) { return _balances[a]; }
function allowance(address a, address s) public view returns (uint256) { return _allowances[a][s]; }
function transfer(address to, uint256 amount) public returns (bool) {
_transfer(msg.sender, to, amount); return true;
}
function approve(address spender, uint256 amount) public returns (bool) {
_approve(msg.sender, spender, amount); return true;
}
function transferFrom(address from, address to, uint256 amount) public returns (bool) {
uint256 allowed = _allowances[from][msg.sender];
require(allowed >= amount, "insufficient allowance");
if (allowed != type(uint256).max) {
_allowances[from][msg.sender] = allowed - amount;
emit Approval(from, msg.sender, _allowances[from][msg.sender]);
}
_transfer(from, to, amount); return true;
}
function mint(address to, uint256 amount) public onlyOwner {
require(to != address(0), "mint to zero");
totalSupply += amount; _balances[to] += amount;
emit Transfer(address(0), to, amount);
}
function burn(uint256 amount) public {
uint256 bal = _balances[msg.sender]; require(bal >= amount, "insufficient");
_balances[msg.sender] = bal - amount; totalSupply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "zero owner");
emit OwnershipTransferred(owner, newOwner); owner = newOwner;
}
function _transfer(address from, address to, uint256 amount) internal {
require(to != address(0), "transfer to zero");
uint256 bal = _balances[from]; require(bal >= amount, "insufficient balance");
_balances[from] = bal - amount; _balances[to] += amount;
emit Transfer(from, to, amount);
}
function _approve(address a, address s, uint256 amount) internal {
require(s != address(0), "approve to zero");
_allowances[a][s] = amount; emit Approval(a, s, amount);
}
}
name: Campus Dollar
symbol: cUSD
decimals: 6
["Campus Dollar","cUSD",6]
As owner (the deployer), call mint(<memberAddress>, 1000000)
to send 1.000000 cUSD (6 decimals). Repeat for 2–3 classmates.
cUSD
, 6
).transferOwnership()
to hand admin to the next treasurer (or move to a Safe multisig).cUSD
, 6
.