-
Notifications
You must be signed in to change notification settings - Fork 0
/
ERC20.sol
110 lines (102 loc) · 4.44 KB
/
ERC20.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract ERC20 {
event Transfer(address indexed from, address indexed to, uint amount);
event Approval(address indexed from, address indexed to, uint amount);
address owner = msg.sender;
address spender = msg.sender;
mapping(address => uint) public _balances;
mapping(address => mapping(address => uint)) public _allowances;
uint public _totalSupply;
string public _name;
string public _symbol;
constructor(string memory name_, string memory symbol_){
_name = name_;
_symbol = symbol_;
}
function name() public view virtual returns(string memory){
return _name;
}
function symbol() public view virtual returns(string memory){
return _symbol;
}
function decimals() public view virtual returns(uint8){
return 18;
}
function totalSupply() public view virtual returns(uint){
return _totalSupply;
}
function balanceOf(address account) public view virtual returns(uint){
return _balances[account];
}
function transfer(address to, uint amount) public virtual returns(bool){
_transfer(owner, to, amount);
return true;
}
function allowance(address owner, address spender) public view virtual returns(uint){
return _allowances[owner][spender];
}
function approve(address spender, uint amount) public virtual returns(bool){
_approve(owner, spender, amount);
return true;
}
function transferFrom(address from, address to, uint amount) public virtual returns(bool){
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAlowance(address spender, uint addedValue) public virtual returns(bool){
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(address spender, uint subtractedValue) public virtual returns(bool){
uint currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(address from, address to, uint 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);
uint fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _burn(address account, uint amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint 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 from, address to, uint amount) internal virtual {
uint currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint).max){
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function _beforeTokenTransfer(address from, address to, uint amount) internal virtual {}
function _afterTokenTransfer(address from, address to, uint amount) internal virtual {}
}