Created
October 16, 2021 08:00
-
-
Save markodayan/711fc546cd0c6660129fc46b160f3d1b to your computer and use it in GitHub Desktop.
Dai contract
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity >=0.5.12; | |
// FIXME: This contract was altered compared to the production version. | |
// It doesn't use LibNote anymore. | |
// New deployments of this contract will need to include custom events (TO DO). | |
contract Dai { | |
// --- Auth --- | |
mapping (address => uint) public wards; | |
function rely(address guy) external auth { wards[guy] = 1; } | |
function deny(address guy) external auth { wards[guy] = 0; } | |
modifier auth { | |
require(wards[msg.sender] == 1, "Dai/not-authorized"); | |
_; | |
} | |
// --- ERC20 Data --- | |
string public constant name = "Dai Stablecoin"; | |
string public constant symbol = "DAI"; | |
string public constant version = "1"; | |
uint8 public constant decimals = 18; | |
uint256 public totalSupply; | |
mapping (address => uint) public balanceOf; | |
mapping (address => mapping (address => uint)) public allowance; | |
mapping (address => uint) public nonces; | |
event Approval(address indexed src, address indexed guy, uint wad); | |
event Transfer(address indexed src, address indexed dst, uint wad); | |
// --- Math --- | |
function add(uint x, uint y) internal pure returns (uint z) { | |
require((z = x + y) >= x); | |
} | |
function sub(uint x, uint y) internal pure returns (uint z) { | |
require((z = x - y) <= x); | |
} | |
// --- EIP712 niceties --- | |
bytes32 public DOMAIN_SEPARATOR; | |
// bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)"); | |
bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb; | |
constructor(uint256 chainId_) public { | |
wards[msg.sender] = 1; | |
DOMAIN_SEPARATOR = keccak256(abi.encode( | |
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), | |
keccak256(bytes(name)), | |
keccak256(bytes(version)), | |
chainId_, | |
address(this) | |
)); | |
} | |
// --- Token --- | |
function transfer(address dst, uint wad) external returns (bool) { | |
return transferFrom(msg.sender, dst, wad); | |
} | |
function transferFrom(address src, address dst, uint wad) | |
public returns (bool) | |
{ | |
require(balanceOf[src] >= wad, "Dai/insufficient-balance"); | |
if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { | |
require(allowance[src][msg.sender] >= wad, "Dai/insufficient-allowance"); | |
allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad); | |
} | |
balanceOf[src] = sub(balanceOf[src], wad); | |
balanceOf[dst] = add(balanceOf[dst], wad); | |
emit Transfer(src, dst, wad); | |
return true; | |
} | |
function mint(address usr, uint wad) external auth { | |
balanceOf[usr] = add(balanceOf[usr], wad); | |
totalSupply = add(totalSupply, wad); | |
emit Transfer(address(0), usr, wad); | |
} | |
function burn(address usr, uint wad) external { | |
require(balanceOf[usr] >= wad, "Dai/insufficient-balance"); | |
if (usr != msg.sender && allowance[usr][msg.sender] != uint(-1)) { | |
require(allowance[usr][msg.sender] >= wad, "Dai/insufficient-allowance"); | |
allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad); | |
} | |
balanceOf[usr] = sub(balanceOf[usr], wad); | |
totalSupply = sub(totalSupply, wad); | |
emit Transfer(usr, address(0), wad); | |
} | |
function approve(address usr, uint wad) external returns (bool) { | |
allowance[msg.sender][usr] = wad; | |
emit Approval(msg.sender, usr, wad); | |
return true; | |
} | |
// --- Alias --- | |
function push(address usr, uint wad) external { | |
transferFrom(msg.sender, usr, wad); | |
} | |
function pull(address usr, uint wad) external { | |
transferFrom(usr, msg.sender, wad); | |
} | |
function move(address src, address dst, uint wad) external { | |
transferFrom(src, dst, wad); | |
} | |
// --- Approve by signature --- | |
function permit(address holder, address spender, uint256 nonce, uint256 expiry, | |
bool allowed, uint8 v, bytes32 r, bytes32 s) external | |
{ | |
bytes32 digest = | |
keccak256(abi.encodePacked( | |
"\x19\x01", | |
DOMAIN_SEPARATOR, | |
keccak256(abi.encode(PERMIT_TYPEHASH, | |
holder, | |
spender, | |
nonce, | |
expiry, | |
allowed)) | |
)); | |
require(holder != address(0), "Dai/invalid-address-0"); | |
require(holder == ecrecover(digest, v, r, s), "Dai/invalid-permit"); | |
require(expiry == 0 || now <= expiry, "Dai/permit-expired"); | |
require(nonce == nonces[holder]++, "Dai/invalid-nonce"); | |
uint wad = allowed ? uint(-1) : 0; | |
allowance[holder][spender] = wad; | |
emit Approval(holder, spender, wad); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment