Dai.sol 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/dai.sol
  2. pragma solidity =0.5.12;
  3. ////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/lib.sol
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. // You should have received a copy of the GNU General Public License
  13. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. /* pragma solidity 0.5.12; */
  15. contract LibNote {
  16. event LogNote(
  17. bytes4 indexed sig,
  18. address indexed usr,
  19. bytes32 indexed arg1,
  20. bytes32 indexed arg2,
  21. bytes data
  22. ) anonymous;
  23. modifier note {
  24. _;
  25. assembly {
  26. // log an 'anonymous' event with a constant 6 words of calldata
  27. // and four indexed topics: selector, caller, arg1 and arg2
  28. let mark := msize // end of memory ensures zero
  29. mstore(0x40, add(mark, 288)) // update free memory pointer
  30. mstore(mark, 0x20) // bytes type data offset
  31. mstore(add(mark, 0x20), 224) // bytes size (padded)
  32. calldatacopy(add(mark, 0x40), 0, 224) // bytes payload
  33. log4(mark, 288, // calldata
  34. shl(224, shr(224, calldataload(0))), // msg.sig
  35. caller, // msg.sender
  36. calldataload(4), // arg1
  37. calldataload(36) // arg2
  38. )
  39. }
  40. }
  41. }
  42. ////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/dai.sol
  43. // Copyright (C) 2017, 2018, 2019 dbrock, rain, mrchico
  44. // This program is free software: you can redistribute it and/or modify
  45. // it under the terms of the GNU Affero General Public License as published by
  46. // the Free Software Foundation, either version 3 of the License, or
  47. // (at your option) any later version.
  48. //
  49. // This program is distributed in the hope that it will be useful,
  50. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  51. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  52. // GNU Affero General Public License for more details.
  53. //
  54. // You should have received a copy of the GNU Affero General Public License
  55. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  56. /* pragma solidity 0.5.12; */
  57. /* import "./lib.sol"; */
  58. contract Dai is LibNote {
  59. // --- Auth ---
  60. mapping (address => uint) public wards;
  61. function rely(address guy) external note auth { wards[guy] = 1; }
  62. function deny(address guy) external note auth { wards[guy] = 0; }
  63. modifier auth {
  64. require(wards[msg.sender] == 1, "Dai/not-authorized");
  65. _;
  66. }
  67. // --- ERC20 Data ---
  68. string public constant name = "Dai Stablecoin";
  69. string public constant symbol = "DAI";
  70. string public constant version = "1";
  71. uint8 public constant decimals = 18;
  72. uint256 public totalSupply;
  73. mapping (address => uint) public balanceOf;
  74. mapping (address => mapping (address => uint)) public allowance;
  75. mapping (address => uint) public nonces;
  76. event Approval(address indexed src, address indexed guy, uint wad);
  77. event Transfer(address indexed src, address indexed dst, uint wad);
  78. // --- Math ---
  79. function add(uint x, uint y) internal pure returns (uint z) {
  80. require((z = x + y) >= x);
  81. }
  82. function sub(uint x, uint y) internal pure returns (uint z) {
  83. require((z = x - y) <= x);
  84. }
  85. // --- EIP712 niceties ---
  86. bytes32 public DOMAIN_SEPARATOR;
  87. // bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)");
  88. bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;
  89. constructor(uint256 chainId_) public {
  90. wards[msg.sender] = 1;
  91. DOMAIN_SEPARATOR = keccak256(abi.encode(
  92. keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
  93. keccak256(bytes(name)),
  94. keccak256(bytes(version)),
  95. chainId_,
  96. address(this)
  97. ));
  98. }
  99. // --- Token ---
  100. function transfer(address dst, uint wad) external returns (bool) {
  101. return transferFrom(msg.sender, dst, wad);
  102. }
  103. function transferFrom(address src, address dst, uint wad)
  104. public returns (bool)
  105. {
  106. require(balanceOf[src] >= wad, "Dai/insufficient-balance");
  107. if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
  108. require(allowance[src][msg.sender] >= wad, "Dai/insufficient-allowance");
  109. allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);
  110. }
  111. balanceOf[src] = sub(balanceOf[src], wad);
  112. balanceOf[dst] = add(balanceOf[dst], wad);
  113. emit Transfer(src, dst, wad);
  114. return true;
  115. }
  116. function mint(address usr, uint wad) external auth {
  117. balanceOf[usr] = add(balanceOf[usr], wad);
  118. totalSupply = add(totalSupply, wad);
  119. emit Transfer(address(0), usr, wad);
  120. }
  121. function burn(address usr, uint wad) external {
  122. require(balanceOf[usr] >= wad, "Dai/insufficient-balance");
  123. if (usr != msg.sender && allowance[usr][msg.sender] != uint(-1)) {
  124. require(allowance[usr][msg.sender] >= wad, "Dai/insufficient-allowance");
  125. allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad);
  126. }
  127. balanceOf[usr] = sub(balanceOf[usr], wad);
  128. totalSupply = sub(totalSupply, wad);
  129. emit Transfer(usr, address(0), wad);
  130. }
  131. function approve(address usr, uint wad) external returns (bool) {
  132. allowance[msg.sender][usr] = wad;
  133. emit Approval(msg.sender, usr, wad);
  134. return true;
  135. }
  136. // --- Alias ---
  137. function push(address usr, uint wad) external {
  138. transferFrom(msg.sender, usr, wad);
  139. }
  140. function pull(address usr, uint wad) external {
  141. transferFrom(usr, msg.sender, wad);
  142. }
  143. function move(address src, address dst, uint wad) external {
  144. transferFrom(src, dst, wad);
  145. }
  146. // --- Approve by signature ---
  147. function permit(address holder, address spender, uint256 nonce, uint256 expiry,
  148. bool allowed, uint8 v, bytes32 r, bytes32 s) external
  149. {
  150. bytes32 digest =
  151. keccak256(abi.encodePacked(
  152. "\x19\x01",
  153. DOMAIN_SEPARATOR,
  154. keccak256(abi.encode(PERMIT_TYPEHASH,
  155. holder,
  156. spender,
  157. nonce,
  158. expiry,
  159. allowed))
  160. ));
  161. require(holder != address(0), "Dai/invalid-address-0");
  162. require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit");
  163. require(expiry == 0 || now <= expiry, "Dai/permit-expired");
  164. require(nonce == nonces[holder]++, "Dai/invalid-nonce");
  165. uint wad = allowed ? uint(-1) : 0;
  166. allowance[holder][spender] = wad;
  167. emit Approval(holder, spender, wad);
  168. }
  169. }