ClimaVeritas

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();
    }
}

Tags:
ERC20, Token, Factory|addr:0x2aca4a6ec7cf7ac328b5bae76aab89ab4c8752e1|verified:true|block:23660513|tx:0xa3915fb34c90847e482006cc13d242031163230dece9e632f47568af0f5b13a6|first_check:1761478294

Submitted on: 2025-10-26 12:31:34

Comments

Log in to comment.

No comments yet.