Description:
ERC20 token contract with Factory capabilities. Standard implementation for fungible tokens on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;
/**
* @title ClimaVeritas Token Contract ( https://clima-veritas.de/ )
* @dev A complete ERC20 token implementation with ownership capabilities
* @notice This contract implements a standard ERC20 token named "ClimaVeritas" with symbol "CVT"
*/
/**
* @dev Context contract provides access to the transaction sender
* @notice This is a base contract that provides access to msg.sender in a way that's compatible with meta-transactions
*/
abstract contract Context {
/**
* @dev Returns the address of the account that initiated the transaction
* @return The address of the transaction sender
*/
function _msgSender() internal view returns (address) {
return msg.sender;
}
}
/**
* @dev Ownable contract provides basic authorization control functions
* @notice This contract implements ownership functionality with transfer and renounce capabilities
* @dev Inherits from Context to access transaction sender information
*/
abstract contract Ownable is Context {
address private _owner; // Storage for the contract owner address
// Custom error for unauthorized access attempts
error OwnableUnauthorizedAccount(address account);
// Custom error for invalid owner address (zero address)
error OwnableInvalidOwner(address owner);
/**
* @dev Emitted when ownership is transferred
* @param previousOwner The address of the previous owner
* @param newOwner The address of the new owner
*/
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Constructor sets the initial owner
* @param initialOwner The address to be set as the initial owner
* @notice Reverts if initialOwner is the zero address
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Modifier to restrict function access to owner only
* @notice Functions with this modifier can only be called by the contract owner
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner
* @return The owner's address
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Internal function to check if caller is the owner
* @notice Reverts with OwnableUnauthorizedAccount if caller is not the owner
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Allows the owner to renounce ownership
* @notice Sets the owner to the zero address, effectively removing ownership
* @dev Can only be called by the current owner
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership to a new address
* @param newOwner The address to transfer ownership to
* @notice Reverts if newOwner is the zero address
* @dev Can only be called by the current owner
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Internal function to handle ownership transfer
* @param newOwner The address of the new owner
* @notice Emits OwnershipTransferred event
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
/**
* @dev Interface for the ERC20 standard as defined in the EIP
* @notice This interface defines the basic functions and events of an ERC20 token
*/
interface IERC20 {
/**
* @dev Emitted when tokens are transferred from one address to another
* @param from The address tokens are transferred from
* @param to The address tokens are transferred to
* @param value The amount of tokens transferred
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when an approval is made
* @param owner The address that owns the tokens
* @param spender The address that is approved to spend the tokens
* @param value The amount of tokens approved for spending
*/
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
/**
* @dev Returns the total token supply
* @return The total amount of tokens in existence
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the token balance of a specific address
* @param account The address to query the balance of
* @return The number of tokens owned by the account
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Transfers tokens to a specified address
* @param to The address to transfer tokens to
* @param value The amount of tokens to transfer
* @return True if the transfer was successful
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that spender is allowed to spend on behalf of owner
* @param owner The address that owns the tokens
* @param spender The address that is approved to spend the tokens
* @return The remaining allowance amount
*/
function allowance(
address owner,
address spender
) external view returns (uint256);
/**
* @dev Approves another address to spend tokens on behalf of the caller
* @param spender The address to approve for spending
* @param value The amount of tokens to approve
* @return True if the approval was successful
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Transfers tokens from one address to another using allowance mechanism
* @param from The address to transfer tokens from
* @param to The address to transfer tokens to
* @param value The amount of tokens to transfer
* @return True if the transfer was successful
*/
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
}
/**
* @dev Interface for the optional metadata functions from the ERC20 standard
* @notice Extends IERC20 with functions to get token name, symbol, and decimals
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token
* @return The token name as a string
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token
* @return The token symbol as a string
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the number of decimals used for token amounts
* @return The number of decimals (typically 18 for ERC20 tokens)
*/
function decimals() external view returns (uint8);
}
/**
* @dev Interface for ERC20 error handling
* @notice Defines custom errors for better error reporting in ERC20 operations
*/
interface IERC20Errors {
/**
* @dev Error thrown when insufficient balance for a transfer
* @param sender The address attempting the transfer
* @param balance The current balance of the sender
* @param needed The amount needed for the transfer
*/
error ERC20InsufficientBalance(
address sender,
uint256 balance,
uint256 needed
);
/**
* @dev Error thrown when transfer sender is invalid (zero address)
* @param sender The invalid sender address
*/
error ERC20InvalidSender(address sender);
/**
* @dev Error thrown when transfer receiver is invalid (zero address)
* @param receiver The invalid receiver address
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Error thrown when insufficient allowance for transferFrom
* @param spender The address attempting to spend
* @param allowance The current allowance
* @param needed The amount needed for the transfer
*/
error ERC20InsufficientAllowance(
address spender,
uint256 allowance,
uint256 needed
);
/**
* @dev Error thrown when approver is invalid (zero address)
* @param approver The invalid approver address
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Error thrown when spender is invalid (zero address)
* @param spender The invalid spender address
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Implementation of the ERC20 standard
* @notice This contract provides a complete implementation of the ERC20 token standard
* @dev Inherits from Context, IERC20, IERC20Metadata, and IERC20Errors
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
// Mapping from address to token balance
mapping(address account => uint256) private _balances;
// Mapping from owner to spender allowances
// _allowances[owner][spender] = amount
mapping(address account => mapping(address spender => uint256))
private _allowances;
uint256 private _totalSupply; // Total number of tokens in existence
string private _name; // Token name
string private _symbol; // Token symbol
/**
* @dev Constructor to initialize the token name and symbol
* @param name_ The name of the token
* @param symbol_ The symbol of the token
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token
* @return The token name
*/
function name() external view returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token
* @return The token symbol
*/
function symbol() external view returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used for token amounts
* @return Always returns 18 (standard for ERC20 tokens)
*/
function decimals() public pure returns (uint8) {
return 18;
}
/**
* @dev Returns the total token supply
* @return The total amount of tokens in existence
*/
function totalSupply() external view returns (uint256) {
return _totalSupply;
}
/**
* @dev Returns the token balance of a specific address
* @param account The address to query the balance of
* @return The number of tokens owned by the account
*/
function balanceOf(address account) external view returns (uint256) {
return _balances[account];
}
/**
* @dev Transfers tokens from caller to specified address
* @param to The address to transfer tokens to
* @param value The amount of tokens to transfer
* @return Always returns true (reverts on failure)
*/
function transfer(address to, uint256 value) external returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev Returns the remaining allowance for a spender
* @param owner The address that owns the tokens
* @param spender The address that is approved to spend
* @return The remaining allowance amount
*/
function allowance(
address owner,
address spender
) public view returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev Approves another address to spend tokens on behalf of the caller
* @param spender The address to approve for spending
* @param value The amount of tokens to approve
* @return Always returns true (reverts on failure)
*/
function approve(address spender, uint256 value) external returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev Transfers tokens from one address to another using allowance
* @param from The address to transfer tokens from
* @param to The address to transfer tokens to
* @param value The amount of tokens to transfer
* @return Always returns true (reverts on failure)
*/
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Internal function to handle token transfers
* @param from The address to transfer tokens from
* @param to The address to transfer tokens to
* @param value The amount of tokens to transfer
* @notice Performs balance checks and updates balances
*/
function _transfer(address from, address to, uint256 value) private {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
uint256 fromBalance = _balances[from];
require(fromBalance >= value, "ERC20: transfer value exceeds balance");
unchecked {
// Safe to use unchecked since we verified fromBalance >= value
_balances[from] = fromBalance - value;
}
_balances[to] += value;
emit Transfer(from, to, value);
}
/**
* @dev Internal function to create new tokens
* @param account The address to mint tokens to
* @param value The amount of tokens to mint
* @notice Increases total supply and adds tokens to the specified account
*/
function _mint(address account, uint256 value) internal {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply += value;
_balances[account] += value;
emit Transfer(address(0), account, value);
}
/**
* @dev Internal approval function (with event emission)
* @param owner The address that owns the tokens
* @param spender The address to approve for spending
* @param value The amount to approve
*/
function _approve(address owner, address spender, uint256 value) private {
_approve(owner, spender, value, true);
}
/**
* @dev Internal approval function with optional event emission
* @param owner The address that owns the tokens
* @param spender The address to approve for spending
* @param value The amount to approve
* @param emitEvent Whether to emit the Approval event
* @notice Validates addresses and sets allowance
*/
function _approve(
address owner,
address spender,
uint256 value,
bool emitEvent
) private {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Internal function to handle allowance spending
* @param owner The address that owns the tokens
* @param spender The address spending the tokens
* @param value The amount being spent
* @notice Reduces allowance if not set to max uint256 (infinite approval)
*/
function _spendAllowance(
address owner,
address spender,
uint256 value
) private {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(
spender,
currentAllowance,
value
);
}
unchecked {
// Safe to use unchecked since we verified currentAllowance >= value
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
/**
* @title ClimaVeritas Token
* @dev The main token contract that inherits ERC20 and Ownable functionality
* @notice ClimaVeritas (CVT) is an ERC20 token with a fixed supply of 100 million tokens
* @dev This contract creates the token, mints the entire supply to the deployer, and then renounces ownership
*/
contract ClimaVeritas is ERC20, Ownable {
/**
* @dev Constructor initializes the token and mints the entire supply
* @notice Creates 100,000,000 CVT tokens (with 18 decimals) and assigns them to the deployer
* @dev After minting, ownership is immediately renounced to make the contract immutable
*/
constructor(address _receiver) ERC20("ClimaVeritas", "CVT") Ownable(msg.sender) {
// Mint 100 million tokens (100,000,000 * 10^18) to the contract deployer
_mint(_receiver, 100_000_000 * 10 ** decimals());
// Renounce ownership to make the contract truly decentralized
// This prevents any future changes to the contract
renounceOwnership();
}
}
Submitted on: 2025-10-26 12:31:34
Comments
Log in to comment.
No comments yet.