Commit my random junk
[sandbox] / solidity / token.sol
1 pragma solidity ^0.8.4;
2
3 pragma solidity ^0.8.0;
4
5 /**
6  * @dev Interface of the ERC20 standard as defined in the EIP.
7  */
8 interface IERC20 {
9     /**
10      * @dev Returns the amount of tokens in existence.
11      */
12     function totalSupply() external view returns (uint256);
13
14     /**
15      * @dev Returns the amount of tokens owned by `account`.
16      */
17     function balanceOf(address account) external view returns (uint256);
18
19     /**
20      * @dev Moves `amount` tokens from the caller's account to `recipient`.
21      *
22      * Returns a boolean value indicating whether the operation succeeded.
23      *
24      * Emits a {Transfer} event.
25      */
26     function transfer(address recipient, uint256 amount) external returns (bool);
27
28     /**
29      * @dev Returns the remaining number of tokens that `spender` will be
30      * allowed to spend on behalf of `owner` through {transferFrom}. This is
31      * zero by default.
32      *
33      * This value changes when {approve} or {transferFrom} are called.
34      */
35     function allowance(address owner, address spender) external view returns (uint256);
36
37     /**
38      * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
39      *
40      * Returns a boolean value indicating whether the operation succeeded.
41      *
42      * IMPORTANT: Beware that changing an allowance with this method brings the risk
43      * that someone may use both the old and the new allowance by unfortunate
44      * transaction ordering. One possible solution to mitigate this race
45      * condition is to first reduce the spender's allowance to 0 and set the
46      * desired value afterwards:
47      * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
48      *
49      * Emits an {Approval} event.
50      */
51     function approve(address spender, uint256 amount) external returns (bool);
52
53     /**
54      * @dev Moves `amount` tokens from `sender` to `recipient` using the
55      * allowance mechanism. `amount` is then deducted from the caller's
56      * allowance.
57      *
58      * Returns a boolean value indicating whether the operation succeeded.
59      *
60      * Emits a {Transfer} event.
61      */
62     function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
63
64     /**
65      * @dev Emitted when `value` tokens are moved from one account (`from`) to
66      * another (`to`).
67      *
68      * Note that `value` may be zero.
69      */
70     event Transfer(address indexed from, address indexed to, uint256 value);
71
72     /**
73      * @dev Emitted when the allowance of a `spender` for an `owner` is set by
74      * a call to {approve}. `value` is the new allowance.
75      */
76     event Approval(address indexed owner, address indexed spender, uint256 value);
77 }
78
79 contract Token is IERC20 {
80     mapping (address => uint256) private _balances;
81
82     mapping (address => mapping (address => uint256)) private _allowances;
83
84     uint256 private _totalSupply;
85
86     string private _name;
87     string private _symbol;
88
89     /**
90      * @dev Sets the values for {name} and {symbol}.
91      *
92      * The defaut value of {decimals} is 18. To select a different value for
93      * {decimals} you should overload it.
94      *
95      * All two of these values are immutable: they can only be set once during
96      * construction.
97      */
98     constructor (string memory name_, string memory symbol_) {
99         _name = name_;
100         _symbol = symbol_;
101     }
102
103     /**
104      * @dev Returns the name of the token.
105      */
106     function name() public view virtual override returns (string memory) {
107         return _name;
108     }
109
110     /**
111      * @dev Returns the symbol of the token, usually a shorter version of the
112      * name.
113      */
114     function symbol() public view virtual override returns (string memory) {
115         return _symbol;
116     }
117
118     /**
119      * @dev Returns the number of decimals used to get its user representation.
120      * For example, if `decimals` equals `2`, a balance of `505` tokens should
121      * be displayed to a user as `5,05` (`505 / 10 ** 2`).
122      *
123      * Tokens usually opt for a value of 18, imitating the relationship between
124      * Ether and Wei. This is the value {ERC20} uses, unless this function is
125      * overridden;
126      *
127      * NOTE: This information is only used for _display_ purposes: it in
128      * no way affects any of the arithmetic of the contract, including
129      * {IERC20-balanceOf} and {IERC20-transfer}.
130      */
131     function decimals() public view virtual override returns (uint8) {
132         return 18;
133     }
134
135     /**
136      * @dev See {IERC20-totalSupply}.
137      */
138     function totalSupply() public view virtual override returns (uint256) {
139         return _totalSupply;
140     }
141
142     /**
143      * @dev See {IERC20-balanceOf}.
144      */
145     function balanceOf(address account) public view virtual override returns (uint256) {
146         return _balances[account];
147     }
148
149     /**
150      * @dev See {IERC20-transfer}.
151      *
152      * Requirements:
153      *
154      * - `recipient` cannot be the zero address.
155      * - the caller must have a balance of at least `amount`.
156      */
157     function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
158         _transfer(_msgSender(), recipient, amount);
159         return true;
160     }
161
162     /**
163      * @dev See {IERC20-allowance}.
164      */
165     function allowance(address owner, address spender) public view virtual override returns (uint256) {
166         return _allowances[owner][spender];
167     }
168
169     /**
170      * @dev See {IERC20-approve}.
171      *
172      * Requirements:
173      *
174      * - `spender` cannot be the zero address.
175      */
176     function approve(address spender, uint256 amount) public virtual override returns (bool) {
177         _approve(_msgSender(), spender, amount);
178         return true;
179     }
180
181     /**
182      * @dev See {IERC20-transferFrom}.
183      *
184      * Emits an {Approval} event indicating the updated allowance. This is not
185      * required by the EIP. See the note at the beginning of {ERC20}.
186      *
187      * Requirements:
188      *
189      * - `sender` and `recipient` cannot be the zero address.
190      * - `sender` must have a balance of at least `amount`.
191      * - the caller must have allowance for ``sender``'s tokens of at least
192      * `amount`.
193      */
194     function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
195         _transfer(sender, recipient, amount);
196
197         uint256 currentAllowance = _allowances[sender][_msgSender()];
198         require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
199         _approve(sender, _msgSender(), currentAllowance - amount);
200
201         return true;
202     }
203
204     /**
205      * @dev Atomically increases the allowance granted to `spender` by the caller.
206      *
207      * This is an alternative to {approve} that can be used as a mitigation for
208      * problems described in {IERC20-approve}.
209      *
210      * Emits an {Approval} event indicating the updated allowance.
211      *
212      * Requirements:
213      *
214      * - `spender` cannot be the zero address.
215      */
216     function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
217         _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
218         return true;
219     }
220
221     /**
222      * @dev Atomically decreases the allowance granted to `spender` by the caller.
223      *
224      * This is an alternative to {approve} that can be used as a mitigation for
225      * problems described in {IERC20-approve}.
226      *
227      * Emits an {Approval} event indicating the updated allowance.
228      *
229      * Requirements:
230      *
231      * - `spender` cannot be the zero address.
232      * - `spender` must have allowance for the caller of at least
233      * `subtractedValue`.
234      */
235     function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
236         uint256 currentAllowance = _allowances[_msgSender()][spender];
237         require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
238         _approve(_msgSender(), spender, currentAllowance - subtractedValue);
239
240         return true;
241     }
242
243     /**
244      * @dev Moves tokens `amount` from `sender` to `recipient`.
245      *
246      * This is internal function is equivalent to {transfer}, and can be used to
247      * e.g. implement automatic token fees, slashing mechanisms, etc.
248      *
249      * Emits a {Transfer} event.
250      *
251      * Requirements:
252      *
253      * - `sender` cannot be the zero address.
254      * - `recipient` cannot be the zero address.
255      * - `sender` must have a balance of at least `amount`.
256      */
257     function _transfer(address sender, address recipient, uint256 amount) internal virtual {
258         require(sender != address(0), "ERC20: transfer from the zero address");
259         require(recipient != address(0), "ERC20: transfer to the zero address");
260
261         _beforeTokenTransfer(sender, recipient, amount);
262
263         uint256 senderBalance = _balances[sender];
264         require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
265         _balances[sender] = senderBalance - amount;
266         _balances[recipient] += amount;
267
268         emit Transfer(sender, recipient, amount);
269     }
270
271     /** @dev Creates `amount` tokens and assigns them to `account`, increasing
272      * the total supply.
273      *
274      * Emits a {Transfer} event with `from` set to the zero address.
275      *
276      * Requirements:
277      *
278      * - `to` cannot be the zero address.
279      */
280     function _mint(address account, uint256 amount) internal virtual {
281         require(account != address(0), "ERC20: mint to the zero address");
282
283         _beforeTokenTransfer(address(0), account, amount);
284
285         _totalSupply += amount;
286         _balances[account] += amount;
287         emit Transfer(address(0), account, amount);
288     }
289
290     /**
291      * @dev Destroys `amount` tokens from `account`, reducing the
292      * total supply.
293      *
294      * Emits a {Transfer} event with `to` set to the zero address.
295      *
296      * Requirements:
297      *
298      * - `account` cannot be the zero address.
299      * - `account` must have at least `amount` tokens.
300      */
301     function _burn(address account, uint256 amount) internal virtual {
302         require(account != address(0), "ERC20: burn from the zero address");
303
304         _beforeTokenTransfer(account, address(0), amount);
305
306         uint256 accountBalance = _balances[account];
307         require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
308         _balances[account] = accountBalance - amount;
309         _totalSupply -= amount;
310
311         emit Transfer(account, address(0), amount);
312     }
313
314     /**
315      * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
316      *
317      * This internal function is equivalent to `approve`, and can be used to
318      * e.g. set automatic allowances for certain subsystems, etc.
319      *
320      * Emits an {Approval} event.
321      *
322      * Requirements:
323      *
324      * - `owner` cannot be the zero address.
325      * - `spender` cannot be the zero address.
326      */
327     function _approve(address owner, address spender, uint256 amount) internal virtual {
328         require(owner != address(0), "ERC20: approve from the zero address");
329         require(spender != address(0), "ERC20: approve to the zero address");
330
331         _allowances[owner][spender] = amount;
332         emit Approval(owner, spender, amount);
333     }
334
335     /**
336      * @dev Hook that is called before any transfer of tokens. This includes
337      * minting and burning.
338      *
339      * Calling conditions:
340      *
341      * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
342      * will be to transferred to `to`.
343      * - when `from` is zero, `amount` tokens will be minted for `to`.
344      * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
345      * - `from` and `to` are never both zero.
346      *
347      * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
348      */
349     function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
350 }