{"compilation":{"language":"Solidity","compiler":"solc","compilerVersion":"0.6.12+commit.27d51765","compilerSettings":{"metadata":{"bytecodeHash":"ipfs","useLiteralContent":false},"optimizer":{"runs":200,"enabled":true},"evmVersion":"istanbul","remappings":["ds-test/=lib/ds-auth/lib/ds-test/src/","ds-thing/=lib/ds-value/lib/ds-thing/src/","ds-value/=lib/ds-value/src/","forge-std/=lib/forge-std/src/","psm/=lib/psm/src/","ds-token/=lib/ds-token/src/","ds-auth/=lib/ds-auth/src/","erc4626-tests/=lib/erc4626-tests/","ds-math/=lib/ds-token/lib/ds-math/src/","ds-note/=lib/ds-value/lib/ds-thing/lib/ds-note/src/","usddv2/=lib/psm/lib/usddv2/src/"]},"name":"Usdd","fullyQualifiedName":"src/dss/usdd.sol:Usdd"},"sources":{"src/dss/usdd.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-or-later\n\n/// usdd.sol -- Usdd Stablecoin ERC-20 Token\n\n// Copyright (C) 2017, 2018, 2019 dbrock, rain, mrchico\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\npragma solidity ^0.6.12;\n\ncontract Usdd {\n    // --- Auth ---\n    mapping (address => uint) public wards;\n    function rely(address guy) external auth { wards[guy] = 1; }\n    function deny(address guy) external auth { wards[guy] = 0; }\n    modifier auth {\n        require(wards[msg.sender] == 1, \"Usdd/not-authorized\");\n        _;\n    }\n\n    // --- ERC20 Data ---\n    string  public constant name     = \"Usdd Stablecoin\";\n    string  public constant symbol   = \"USDD\";\n    string  public constant version  = \"1\";\n    uint8   public constant decimals = 18;\n    uint256 public totalSupply;\n\n    mapping (address => uint)                      public balanceOf;\n    mapping (address => mapping (address => uint)) public allowance;\n    mapping (address => uint)                      public nonces;\n\n    event Approval(address indexed src, address indexed guy, uint wad);\n    event Transfer(address indexed src, address indexed dst, uint wad);\n\n    // --- Math ---\n    function add(uint x, uint y) internal pure returns (uint z) {\n        require((z = x + y) >= x);\n    }\n    function sub(uint x, uint y) internal pure returns (uint z) {\n        require((z = x - y) <= x);\n    }\n\n    // --- EIP712 niceties ---\n    bytes32 public DOMAIN_SEPARATOR;\n    // bytes32 public constant PERMIT_TYPEHASH = keccak256(\"Permit(address holder,address spender,uint256 nonce,uint256 expiry,bool allowed)\");\n    bytes32 public constant PERMIT_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb;\n\n    constructor(uint256 chainId_) public {\n        wards[msg.sender] = 1;\n        DOMAIN_SEPARATOR = keccak256(abi.encode(\n            keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n            keccak256(bytes(name)),\n            keccak256(bytes(version)),\n            chainId_,\n            address(this)\n        ));\n    }\n\n    // --- Token ---\n    function transfer(address dst, uint wad) external returns (bool) {\n        return transferFrom(msg.sender, dst, wad);\n    }\n    function transferFrom(address src, address dst, uint wad)\n        public returns (bool)\n    {\n        require(balanceOf[src] >= wad, \"Usdd/insufficient-balance\");\n        if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {\n            require(allowance[src][msg.sender] >= wad, \"Usdd/insufficient-allowance\");\n            allowance[src][msg.sender] = sub(allowance[src][msg.sender], wad);\n        }\n        balanceOf[src] = sub(balanceOf[src], wad);\n        balanceOf[dst] = add(balanceOf[dst], wad);\n        emit Transfer(src, dst, wad);\n        return true;\n    }\n    function mint(address usr, uint wad) external auth {\n        balanceOf[usr] = add(balanceOf[usr], wad);\n        totalSupply    = add(totalSupply, wad);\n        emit Transfer(address(0), usr, wad);\n    }\n    function burn(address usr, uint wad) external {\n        require(balanceOf[usr] >= wad, \"Usdd/insufficient-balance\");\n        if (usr != msg.sender && allowance[usr][msg.sender] != uint(-1)) {\n            require(allowance[usr][msg.sender] >= wad, \"Usdd/insufficient-allowance\");\n            allowance[usr][msg.sender] = sub(allowance[usr][msg.sender], wad);\n        }\n        balanceOf[usr] = sub(balanceOf[usr], wad);\n        totalSupply    = sub(totalSupply, wad);\n        emit Transfer(usr, address(0), wad);\n    }\n    function approve(address usr, uint wad) external returns (bool) {\n        allowance[msg.sender][usr] = wad;\n        emit Approval(msg.sender, usr, wad);\n        return true;\n    }\n\n    // --- Alias ---\n    function push(address usr, uint wad) external {\n        transferFrom(msg.sender, usr, wad);\n    }\n    function pull(address usr, uint wad) external {\n        transferFrom(usr, msg.sender, wad);\n    }\n    function move(address src, address dst, uint wad) external {\n        transferFrom(src, dst, wad);\n    }\n\n    // --- Approve by signature ---\n    function permit(address holder, address spender, uint256 nonce, uint256 expiry,\n                    bool allowed, uint8 v, bytes32 r, bytes32 s) external\n    {\n        bytes32 digest =\n            keccak256(abi.encodePacked(\n                \"\\x19\\x01\",\n                DOMAIN_SEPARATOR,\n                keccak256(abi.encode(PERMIT_TYPEHASH,\n                                     holder,\n                                     spender,\n                                     nonce,\n                                     expiry,\n                                     allowed))\n        ));\n\n        require(holder != address(0), \"Usdd/invalid-address-0\");\n        require(holder == ecrecover(digest, v, r, s), \"Usdd/invalid-permit\");\n        require(expiry == 0 || now <= expiry, \"Usdd/permit-expired\");\n        require(nonce == nonces[holder]++, \"Usdd/invalid-nonce\");\n        uint wad = allowed ? uint(-1) : 0;\n        allowance[holder][spender] = wad;\n        emit Approval(holder, spender, wad);\n    }\n}\n"}},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"matchId":"9447663","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2025-10-12T12:55:36Z","match":"exact_match","chainId":"1","address":"0x4f8e5DE400DE08B164E7421B3EE387f461beCD1A"}