ERC20.sol 7.6 KB

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