ERC20.sol 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. pragma solidity ^0.6.0;
  2. import "../../GSN/Context.sol";
  3. import "./IERC20.sol";
  4. import "../../math/SafeMath.sol";
  5. /**
  6. * @dev Implementation of the {IERC20} interface.
  7. *
  8. * This implementation is agnostic to the way tokens are created. This means
  9. * that a supply mechanism has to be added in a derived contract using {_mint}.
  10. * For a generic mechanism see {ERC20Mintable}.
  11. *
  12. * TIP: For a detailed writeup see our guide
  13. * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
  14. * to implement supply mechanisms].
  15. *
  16. * We have followed general OpenZeppelin guidelines: functions revert instead
  17. * of returning `false` on failure. This behavior is nonetheless conventional
  18. * and does not conflict with the expectations of ERC20 applications.
  19. *
  20. * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
  21. * This allows applications to reconstruct the allowance for all accounts just
  22. * by listening to said events. Other implementations of the EIP may not emit
  23. * these events, as it isn't required by the specification.
  24. *
  25. * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
  26. * functions have been added to mitigate the well-known issues around setting
  27. * allowances. See {IERC20-approve}.
  28. */
  29. contract ERC20 is Context, IERC20 {
  30. using SafeMath for uint256;
  31. mapping (address => uint256) private _balances;
  32. mapping (address => mapping (address => uint256)) private _allowances;
  33. uint256 private _totalSupply;
  34. /**
  35. * @dev See {IERC20-totalSupply}.
  36. */
  37. function totalSupply() public view override returns (uint256) {
  38. return _totalSupply;
  39. }
  40. /**
  41. * @dev See {IERC20-balanceOf}.
  42. */
  43. function balanceOf(address account) public view override returns (uint256) {
  44. return _balances[account];
  45. }
  46. /**
  47. * @dev See {IERC20-transfer}.
  48. *
  49. * Requirements:
  50. *
  51. * - `recipient` cannot be the zero address.
  52. * - the caller must have a balance of at least `amount`.
  53. */
  54. function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
  55. _transfer(_msgSender(), recipient, amount);
  56. return true;
  57. }
  58. /**
  59. * @dev See {IERC20-allowance}.
  60. */
  61. function allowance(address owner, address spender) public view virtual override returns (uint256) {
  62. return _allowances[owner][spender];
  63. }
  64. /**
  65. * @dev See {IERC20-approve}.
  66. *
  67. * Requirements:
  68. *
  69. * - `spender` cannot be the zero address.
  70. */
  71. function approve(address spender, uint256 amount) public virtual override returns (bool) {
  72. _approve(_msgSender(), spender, amount);
  73. return true;
  74. }
  75. /**
  76. * @dev See {IERC20-transferFrom}.
  77. *
  78. * Emits an {Approval} event indicating the updated allowance. This is not
  79. * required by the EIP. See the note at the beginning of {ERC20};
  80. *
  81. * Requirements:
  82. * - `sender` and `recipient` cannot be the zero address.
  83. * - `sender` must have a balance of at least `amount`.
  84. * - the caller must have allowance for `sender`'s tokens of at least
  85. * `amount`.
  86. */
  87. function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
  88. _transfer(sender, recipient, amount);
  89. _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
  90. return true;
  91. }
  92. /**
  93. * @dev Atomically increases the allowance granted to `spender` by the caller.
  94. *
  95. * This is an alternative to {approve} that can be used as a mitigation for
  96. * problems described in {IERC20-approve}.
  97. *
  98. * Emits an {Approval} event indicating the updated allowance.
  99. *
  100. * Requirements:
  101. *
  102. * - `spender` cannot be the zero address.
  103. */
  104. function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
  105. _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
  106. return true;
  107. }
  108. /**
  109. * @dev Atomically decreases the allowance granted to `spender` by the caller.
  110. *
  111. * This is an alternative to {approve} that can be used as a mitigation for
  112. * problems described in {IERC20-approve}.
  113. *
  114. * Emits an {Approval} event indicating the updated allowance.
  115. *
  116. * Requirements:
  117. *
  118. * - `spender` cannot be the zero address.
  119. * - `spender` must have allowance for the caller of at least
  120. * `subtractedValue`.
  121. */
  122. function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
  123. _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
  124. return true;
  125. }
  126. /**
  127. * @dev Moves tokens `amount` from `sender` to `recipient`.
  128. *
  129. * This is internal function is equivalent to {transfer}, and can be used to
  130. * e.g. implement automatic token fees, slashing mechanisms, etc.
  131. *
  132. * Emits a {Transfer} event.
  133. *
  134. * Requirements:
  135. *
  136. * - `sender` cannot be the zero address.
  137. * - `recipient` cannot be the zero address.
  138. * - `sender` must have a balance of at least `amount`.
  139. */
  140. function _transfer(address sender, address recipient, uint256 amount) internal virtual {
  141. require(sender != address(0), "ERC20: transfer from the zero address");
  142. require(recipient != address(0), "ERC20: transfer to the zero address");
  143. _beforeTokenTransfer(sender, recipient, amount);
  144. _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
  145. _balances[recipient] = _balances[recipient].add(amount);
  146. emit Transfer(sender, recipient, amount);
  147. }
  148. /** @dev Creates `amount` tokens and assigns them to `account`, increasing
  149. * the total supply.
  150. *
  151. * Emits a {Transfer} event with `from` set to the zero address.
  152. *
  153. * Requirements
  154. *
  155. * - `to` cannot be the zero address.
  156. */
  157. function _mint(address account, uint256 amount) internal virtual {
  158. require(account != address(0), "ERC20: mint to the zero address");
  159. _beforeTokenTransfer(address(0), account, amount);
  160. _totalSupply = _totalSupply.add(amount);
  161. _balances[account] = _balances[account].add(amount);
  162. emit Transfer(address(0), account, amount);
  163. }
  164. /**
  165. * @dev Destroys `amount` tokens from `account`, reducing the
  166. * total supply.
  167. *
  168. * Emits a {Transfer} event with `to` set to the zero address.
  169. *
  170. * Requirements
  171. *
  172. * - `account` cannot be the zero address.
  173. * - `account` must have at least `amount` tokens.
  174. */
  175. function _burn(address account, uint256 amount) internal virtual {
  176. require(account != address(0), "ERC20: burn from the zero address");
  177. _beforeTokenTransfer(account, address(0), amount);
  178. _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
  179. _totalSupply = _totalSupply.sub(amount);
  180. emit Transfer(account, address(0), amount);
  181. }
  182. /**
  183. * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
  184. *
  185. * This is internal function is equivalent to `approve`, and can be used to
  186. * e.g. set automatic allowances for certain subsystems, etc.
  187. *
  188. * Emits an {Approval} event.
  189. *
  190. * Requirements:
  191. *
  192. * - `owner` cannot be the zero address.
  193. * - `spender` cannot be the zero address.
  194. */
  195. function _approve(address owner, address spender, uint256 amount) internal virtual {
  196. require(owner != address(0), "ERC20: approve from the zero address");
  197. require(spender != address(0), "ERC20: approve to the zero address");
  198. _allowances[owner][spender] = amount;
  199. emit Approval(owner, spender, amount);
  200. }
  201. /**
  202. * @dev Hook that is called before any transfer of tokens. This includes
  203. * minting and burning.
  204. *
  205. * Calling conditions:
  206. *
  207. * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens
  208. * will be to transferred to `to`.
  209. * - when `from` is zero, `amount` tokens will be minted for `to`.
  210. * - when `to` is zero, `amount` of `from`'s tokens will be burned.
  211. * - `from` and `to` are never both zero.
  212. *
  213. * To learn more about hooks, head to xref:ROOT:using-hooks.adoc[Using Hooks].
  214. */
  215. function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
  216. }