0% found this document useful (0 votes)
67 views4 pages

ERC20 Sol

The document is a Solidity smart contract for an ERC20 token implementation, which includes functionalities for token transfers, approvals, and minting/burning of tokens. It defines essential properties such as name, symbol, decimals, total supply, and maximum supply, along with functions to manage balances and allowances. The contract uses OpenZeppelin's library for security and initialization features.

Uploaded by

Karol Karpiński
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
67 views4 pages

ERC20 Sol

The document is a Solidity smart contract for an ERC20 token implementation, which includes functionalities for token transfers, approvals, and minting/burning of tokens. It defines essential properties such as name, symbol, decimals, total supply, and maximum supply, along with functions to manage balances and allowances. The contract uses OpenZeppelin's library for security and initialization features.

Uploaded by

Karol Karpiński
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

// SPDX-License-Identifier: MIT

// Factory: CreateMyToken
// Library: OpenZeppelin Contracts
pragma solidity ^0.8.24;

import "./interfaces/IERC20Metadata.sol";
import "./Initializable.sol";

contract ERC20 is Initializable, IERC20Metadata {


mapping(address => uint256) private _balances;

mapping(address => mapping(address => uint256)) private _allowances;

uint256 private _totalSupply;


uint256 private _maxSupply;

string private _name;


string private _symbol;
uint8 private _decimals;

function init(
string memory name_,
string memory symbol_,
uint8 decimals_,
uint256 maxSupply_
) internal onlyInitializing {
_name = name_;
_symbol = symbol_;
_decimals = decimals_;

_maxSupply = maxSupply_;
}

function name() public view virtual override returns (string memory) {


return _name;
}

function symbol() public view virtual override returns (string memory) {


return _symbol;
}

function decimals() public view virtual override returns (uint8) {


return _decimals;
}

function totalSupply() public view virtual override returns (uint256) {


return _totalSupply;
}

function maxSupply() public view virtual returns (uint256) {


return _maxSupply;
}

function balanceOf(address account) public view virtual override returns


(uint256) {
return _balances[account];
}

function transfer(address to, uint256 amount) public virtual override returns


(bool) {
_transfer(msg.sender, to, amount);
return true;
}

function allowance(address owner, address spender) public view virtual override


returns (uint256) {
return _allowances[owner][spender];
}

function approve(address spender, uint256 amount) public virtual override


returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}

function transferFrom(address from, address to, uint256 amount) public virtual


override returns (bool) {
_spendAllowance(from, msg.sender, amount);
_transfer(from, to, amount);
return true;
}

function increaseAllowance(address spender, uint256 addedValue) public virtual


returns (bool) {
address owner = msg.sender;
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}

function decreaseAllowance(address spender, uint256 subtractedValue) public


virtual returns (bool) {
address owner = msg.sender;
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance
below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}

return true;
}

function burn(uint256 amount) public virtual {


_burn(msg.sender, amount);
}

function burnFrom(address account, uint256 amount) public virtual {


_spendAllowance(account, msg.sender, amount);
_burn(account, amount);
}

function _transfer(address from, address to, uint256 amount) internal virtual {


require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");

_beforeTokenTransfer(from, to, amount);

uint256 fromBalance = _balances[from];


require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by
totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}

emit Transfer(from, to, amount);

_afterTokenTransfer(from, to, amount);


}

function _mint(address account, uint256 amount) internal virtual {


require(_totalSupply + amount <= _maxSupply, "ERC20: cap exceeded");
require(account != address(0), "ERC20: mint to the zero address");

_beforeTokenTransfer(address(0), account, amount);

_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply +
amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);

_afterTokenTransfer(address(0), account, amount);


}

function _burn(address account, uint256 amount) internal virtual {


require(account != address(0), "ERC20: burn from the zero address");

_beforeTokenTransfer(account, address(0), amount);

uint256 accountBalance = _balances[account];


require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}

emit Transfer(account, address(0), amount);

_afterTokenTransfer(account, address(0), amount);


}

function _approve(address owner, address spender, uint256 amount) internal


virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");

_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}

function _spendAllowance(address owner, address spender, uint256 amount)


internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}

function _beforeTokenTransfer(address from, address to, uint256 amount)


internal virtual {}

function _afterTokenTransfer(address from, address to, uint256 amount) internal


virtual {}
}

You might also like