ERC20.sol 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. pragma solidity ^0.5.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 returns (uint256) {
  38. return _totalSupply;
  39. }
  40. /**
  41. * @dev See {IERC20-balanceOf}.
  42. */
  43. function balanceOf(address account) public view 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 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 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 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 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 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 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 {
  141. require(sender != address(0), "ERC20: transfer from the zero address");
  142. require(recipient != address(0), "ERC20: transfer to the zero address");
  143. _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
  144. _balances[recipient] = _balances[recipient].add(amount);
  145. emit Transfer(sender, recipient, amount);
  146. }
  147. /** @dev Creates `amount` tokens and assigns them to `account`, increasing
  148. * the total supply.
  149. *
  150. * Emits a {Transfer} event with `from` set to the zero address.
  151. *
  152. * Requirements
  153. *
  154. * - `to` cannot be the zero address.
  155. */
  156. function _mint(address account, uint256 amount) internal {
  157. require(account != address(0), "ERC20: mint to the zero address");
  158. _totalSupply = _totalSupply.add(amount);
  159. _balances[account] = _balances[account].add(amount);
  160. emit Transfer(address(0), account, amount);
  161. }
  162. /**
  163. * @dev Destroys `amount` tokens from `account`, reducing the
  164. * total supply.
  165. *
  166. * Emits a {Transfer} event with `to` set to the zero address.
  167. *
  168. * Requirements
  169. *
  170. * - `account` cannot be the zero address.
  171. * - `account` must have at least `amount` tokens.
  172. */
  173. function _burn(address account, uint256 amount) internal {
  174. require(account != address(0), "ERC20: burn from the zero address");
  175. _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
  176. _totalSupply = _totalSupply.sub(amount);
  177. emit Transfer(account, address(0), amount);
  178. }
  179. /**
  180. * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
  181. *
  182. * This is internal function is equivalent to `approve`, and can be used to
  183. * e.g. set automatic allowances for certain subsystems, etc.
  184. *
  185. * Emits an {Approval} event.
  186. *
  187. * Requirements:
  188. *
  189. * - `owner` cannot be the zero address.
  190. * - `spender` cannot be the zero address.
  191. */
  192. function _approve(address owner, address spender, uint256 amount) internal {
  193. require(owner != address(0), "ERC20: approve from the zero address");
  194. require(spender != address(0), "ERC20: approve to the zero address");
  195. _allowances[owner][spender] = amount;
  196. emit Approval(owner, spender, amount);
  197. }
  198. /**
  199. * @dev Destroys `amount` tokens from `account`.`amount` is then deducted
  200. * from the caller's allowance.
  201. *
  202. * See {_burn} and {_approve}.
  203. */
  204. function _burnFrom(address account, uint256 amount) internal {
  205. _burn(account, amount);
  206. _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
  207. }
  208. }