You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
10 KiB
341 lines
10 KiB
4 years ago
|
// SPDX-License-Identifier: MIT
|
||
|
|
||
|
pragma solidity >=0.6.0 <0.8.0;
|
||
|
|
||
|
// This is modified from "@openzeppelin/contracts/token/ERC20/IERC20.sol"
|
||
3 years ago
|
// Modifications were made to make the tokenName, tokenSymbol, and
|
||
|
// tokenDecimals fields internal instead of private. Getters for them were
|
||
|
// removed to silence solidity inheritance issues
|
||
4 years ago
|
|
||
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||
|
import "@openzeppelin/contracts/math/SafeMath.sol";
|
||
|
|
||
|
/**
|
||
|
* @dev Implementation of the {IERC20} interface.
|
||
|
*
|
||
|
* This implementation is agnostic to the way tokens are created. This means
|
||
|
* that a supply mechanism has to be added in a derived contract using {_mint}.
|
||
|
* For a generic mechanism see {ERC20PresetMinterPauser}.
|
||
|
*
|
||
|
* TIP: For a detailed writeup see our guide
|
||
|
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
|
||
|
* to implement supply mechanisms].
|
||
|
*
|
||
|
* We have followed general OpenZeppelin guidelines: functions revert instead
|
||
|
* of returning `false` on failure. This behavior is nonetheless conventional
|
||
|
* and does not conflict with the expectations of ERC20 applications.
|
||
|
*
|
||
|
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
|
||
|
* This allows applications to reconstruct the allowance for all accounts just
|
||
|
* by listening to said events. Other implementations of the EIP may not emit
|
||
|
* these events, as it isn't required by the specification.
|
||
|
*
|
||
|
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
|
||
|
* functions have been added to mitigate the well-known issues around setting
|
||
|
* allowances. See {IERC20-approve}.
|
||
|
*/
|
||
3 years ago
|
contract ERC20 is IERC20 {
|
||
4 years ago
|
using SafeMath for uint256;
|
||
|
|
||
4 years ago
|
mapping(address => uint256) private balances;
|
||
4 years ago
|
|
||
4 years ago
|
mapping(address => mapping(address => uint256)) private allowances;
|
||
4 years ago
|
|
||
4 years ago
|
uint256 private supply;
|
||
4 years ago
|
|
||
4 years ago
|
struct Token {
|
||
|
string name;
|
||
|
string symbol;
|
||
|
uint8 decimals;
|
||
|
}
|
||
|
|
||
|
Token internal token;
|
||
4 years ago
|
|
||
|
/**
|
||
|
* @dev See {IERC20-transfer}.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
4 years ago
|
* - `_recipient` cannot be the zero address.
|
||
|
* - the caller must have a balance of at least `_amount`.
|
||
4 years ago
|
*/
|
||
4 years ago
|
function transfer(address _recipient, uint256 _amount)
|
||
4 years ago
|
public
|
||
|
virtual
|
||
|
override
|
||
|
returns (bool)
|
||
|
{
|
||
3 years ago
|
_transfer(msg.sender, _recipient, _amount);
|
||
4 years ago
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev See {IERC20-approve}.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
4 years ago
|
* - `_spender` cannot be the zero address.
|
||
4 years ago
|
*/
|
||
4 years ago
|
function approve(address _spender, uint256 _amount)
|
||
4 years ago
|
public
|
||
|
virtual
|
||
|
override
|
||
|
returns (bool)
|
||
|
{
|
||
3 years ago
|
_approve(msg.sender, _spender, _amount);
|
||
4 years ago
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev See {IERC20-transferFrom}.
|
||
|
*
|
||
|
* Emits an {Approval} event indicating the updated allowance. This is not
|
||
|
* required by the EIP. See the note at the beginning of {ERC20}.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
4 years ago
|
* - `_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
|
||
4 years ago
|
* `amount`.
|
||
|
*/
|
||
|
function transferFrom(
|
||
4 years ago
|
address _sender,
|
||
|
address _recipient,
|
||
|
uint256 _amount
|
||
4 years ago
|
) public virtual override returns (bool) {
|
||
4 years ago
|
_transfer(_sender, _recipient, _amount);
|
||
4 years ago
|
_approve(
|
||
4 years ago
|
_sender,
|
||
3 years ago
|
msg.sender,
|
||
|
allowances[_sender][msg.sender].sub(
|
||
4 years ago
|
_amount,
|
||
4 years ago
|
"ERC20: transfer amount exceeds allowance"
|
||
|
)
|
||
|
);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev Atomically increases the allowance granted to `spender` by the caller.
|
||
|
*
|
||
|
* This is an alternative to {approve} that can be used as a mitigation for
|
||
|
* problems described in {IERC20-approve}.
|
||
|
*
|
||
|
* Emits an {Approval} event indicating the updated allowance.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
4 years ago
|
* - `_spender` cannot be the zero address.
|
||
4 years ago
|
*/
|
||
4 years ago
|
function increaseAllowance(address _spender, uint256 _addedValue)
|
||
4 years ago
|
public
|
||
|
virtual
|
||
|
returns (bool)
|
||
|
{
|
||
|
_approve(
|
||
3 years ago
|
msg.sender,
|
||
4 years ago
|
_spender,
|
||
3 years ago
|
allowances[msg.sender][_spender].add(_addedValue)
|
||
4 years ago
|
);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev Atomically decreases the allowance granted to `spender` by the caller.
|
||
|
*
|
||
|
* This is an alternative to {approve} that can be used as a mitigation for
|
||
|
* problems described in {IERC20-approve}.
|
||
|
*
|
||
|
* Emits an {Approval} event indicating the updated allowance.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
4 years ago
|
* - `_spender` cannot be the zero address.
|
||
|
* - `_spender` must have allowance for the caller of at least
|
||
|
* `_subtractedValue`.
|
||
4 years ago
|
*/
|
||
4 years ago
|
function decreaseAllowance(address _spender, uint256 _subtractedValue)
|
||
4 years ago
|
public
|
||
|
virtual
|
||
|
returns (bool)
|
||
|
{
|
||
|
_approve(
|
||
3 years ago
|
msg.sender,
|
||
4 years ago
|
_spender,
|
||
3 years ago
|
allowances[msg.sender][_spender].sub(
|
||
4 years ago
|
_subtractedValue,
|
||
4 years ago
|
"ERC20: decreased allowance below zero"
|
||
|
)
|
||
|
);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
4 years ago
|
/**
|
||
|
* @dev See {IERC20-totalSupply}.
|
||
|
*/
|
||
|
function totalSupply() public view override returns (uint256) {
|
||
4 years ago
|
return supply;
|
||
4 years ago
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev See {IERC20-balanceOf}.
|
||
|
*/
|
||
4 years ago
|
function balanceOf(address _account)
|
||
|
public
|
||
|
view
|
||
3 years ago
|
virtual
|
||
4 years ago
|
override
|
||
|
returns (uint256)
|
||
|
{
|
||
|
return balances[_account];
|
||
4 years ago
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev See {IERC20-allowance}.
|
||
|
*/
|
||
4 years ago
|
function allowance(address _owner, address _spender)
|
||
4 years ago
|
public
|
||
|
view
|
||
|
virtual
|
||
|
override
|
||
|
returns (uint256)
|
||
|
{
|
||
4 years ago
|
return allowances[_owner][_spender];
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
/**
|
||
4 years ago
|
* @dev Moves tokens `amount` from `_sender` to `_recipient`.
|
||
4 years ago
|
*
|
||
|
* This is internal function is equivalent to {transfer}, and can be used to
|
||
|
* e.g. implement automatic token fees, slashing mechanisms, etc.
|
||
|
*
|
||
|
* Emits a {Transfer} event.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
4 years ago
|
* - `_sender` cannot be the zero address.
|
||
|
* - `_recipient` cannot be the zero address.
|
||
|
* - `_sender` must have a balance of at least `amount`.
|
||
4 years ago
|
*/
|
||
|
function _transfer(
|
||
4 years ago
|
address _sender,
|
||
|
address _recipient,
|
||
4 years ago
|
uint256 amount
|
||
|
) internal virtual {
|
||
4 years ago
|
require(_sender != address(0), "ERC20: transfer from the zero address");
|
||
|
require(
|
||
|
_recipient != address(0),
|
||
|
"ERC20: transfer to the zero address"
|
||
|
);
|
||
4 years ago
|
|
||
4 years ago
|
_beforeTokenTransfer(_sender, _recipient, amount);
|
||
4 years ago
|
|
||
4 years ago
|
balances[_sender] = balances[_sender].sub(
|
||
4 years ago
|
amount,
|
||
|
"ERC20: transfer amount exceeds balance"
|
||
|
);
|
||
4 years ago
|
balances[_recipient] = balances[_recipient].add(amount);
|
||
|
emit Transfer(_sender, _recipient, amount);
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
/** @dev Creates `_amount` tokens and assigns them to `_account`, increasing
|
||
4 years ago
|
* the total supply.
|
||
|
*
|
||
|
* Emits a {Transfer} event with `from` set to the zero address.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
|
* - `to` cannot be the zero address.
|
||
|
*/
|
||
4 years ago
|
function _mint(address _account, uint256 _amount) internal virtual {
|
||
|
require(_account != address(0), "ERC20: mint to the zero address");
|
||
4 years ago
|
|
||
4 years ago
|
_beforeTokenTransfer(address(0), _account, _amount);
|
||
4 years ago
|
|
||
4 years ago
|
supply = supply.add(_amount);
|
||
|
balances[_account] = balances[_account].add(_amount);
|
||
|
emit Transfer(address(0), _account, _amount);
|
||
4 years ago
|
}
|
||
|
|
||
|
/**
|
||
4 years ago
|
* @dev Destroys `_amount` tokens from `_account`, reducing the
|
||
4 years ago
|
* total supply.
|
||
|
*
|
||
|
* Emits a {Transfer} event with `to` set to the zero address.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
4 years ago
|
* - `_account` cannot be the zero address.
|
||
|
* - `_account` must have at least `_amount` tokens.
|
||
4 years ago
|
*/
|
||
4 years ago
|
function _burn(address _account, uint256 _amount) internal virtual {
|
||
|
require(_account != address(0), "ERC20: burn from the zero address");
|
||
4 years ago
|
|
||
4 years ago
|
_beforeTokenTransfer(_account, address(0), _amount);
|
||
4 years ago
|
|
||
4 years ago
|
balances[_account] = balances[_account].sub(
|
||
|
_amount,
|
||
4 years ago
|
"ERC20: burn amount exceeds balance"
|
||
|
);
|
||
4 years ago
|
supply = supply.sub(_amount);
|
||
|
emit Transfer(_account, address(0), _amount);
|
||
4 years ago
|
}
|
||
|
|
||
|
/**
|
||
4 years ago
|
* @dev Sets `_amount` as the allowance of `_spender` over the `_owner` s tokens.
|
||
4 years ago
|
*
|
||
|
* This internal function is equivalent to `approve`, and can be used to
|
||
|
* e.g. set automatic allowances for certain subsystems, etc.
|
||
|
*
|
||
|
* Emits an {Approval} event.
|
||
|
*
|
||
|
* Requirements:
|
||
|
*
|
||
4 years ago
|
* - `_owner` cannot be the zero address.
|
||
|
* - `_spender` cannot be the zero address.
|
||
4 years ago
|
*/
|
||
|
function _approve(
|
||
4 years ago
|
address _owner,
|
||
|
address _spender,
|
||
|
uint256 _amount
|
||
4 years ago
|
) internal virtual {
|
||
4 years ago
|
require(_owner != address(0), "ERC20: approve from the zero address");
|
||
|
require(_spender != address(0), "ERC20: approve to the zero address");
|
||
4 years ago
|
|
||
4 years ago
|
allowances[_owner][_spender] = _amount;
|
||
|
emit Approval(_owner, _spender, _amount);
|
||
4 years ago
|
}
|
||
|
|
||
|
/**
|
||
4 years ago
|
* @dev Sets {decimals_} to a value other than the default one of 18.
|
||
4 years ago
|
*
|
||
|
* WARNING: This function should only be called from the constructor. Most
|
||
|
* applications that interact with token contracts will not expect
|
||
4 years ago
|
* {decimals_} to ever change, and may work incorrectly if it does.
|
||
4 years ago
|
*/
|
||
|
function _setupDecimals(uint8 decimals_) internal {
|
||
4 years ago
|
token.decimals = decimals_;
|
||
4 years ago
|
}
|
||
|
|
||
|
/**
|
||
|
* @dev Hook that is called before any transfer of tokens. This includes
|
||
|
* minting and burning.
|
||
|
*
|
||
|
* Calling conditions:
|
||
|
*
|
||
4 years ago
|
* - when `_from` and `_to` are both non-zero, `_amount` of ``_from``'s tokens
|
||
|
* will be to transferred to `_to`.
|
||
|
* - when `_from` is zero, `_amount` tokens will be minted for `_to`.
|
||
|
* - when `_to` is zero, `_amount` of ``_from``'s tokens will be burned.
|
||
|
* - `_from` and `_to` are never both zero.
|
||
4 years ago
|
*
|
||
|
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
|
||
|
*/
|
||
|
function _beforeTokenTransfer(
|
||
4 years ago
|
address _from,
|
||
|
address _to,
|
||
|
uint256 _amount
|
||
4 years ago
|
) internal virtual {}
|
||
|
}
|