{"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":"UsddJoin","fullyQualifiedName":"src/dss/join.sol:UsddJoin"},"sources":{"src/dss/join.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-or-later\n\n/// join.sol -- Basic token adapters\n\n// Copyright (C) 2018 Rain <rainbreak@riseup.net>\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\ninterface GemLike {\n    function decimals() external view returns (uint);\n    function transfer(address,uint) external returns (bool);\n    function transferFrom(address,address,uint) external returns (bool);\n}\n\ninterface DSTokenLike {\n    function mint(address,uint) external;\n    function burn(address,uint) external;\n}\n\ninterface VatLike {\n    function slip(bytes32,address,int) external;\n    function move(address,address,uint) external;\n}\n\n/*\n    Here we provide *adapters* to connect the Vat to arbitrary external\n    token implementations, creating a bounded context for the Vat. The\n    adapters here are provided as working examples:\n\n      - `GemJoin`: For well behaved ERC20 tokens, with simple transfer\n                   semantics.\n\n      - `ETHJoin`: For native ETH.\n\n      - `UsddJoin`: For connecting internal Usdd balances to an external\n                   `DSToken` implementation.\n\n    In practice, adapter implementations will be varied and specific to\n    individual collateral types, accounting for different transfer\n    semantics and token standards.\n\n    Adapters need to implement two basic methods:\n\n      - `join`: enter collateral into the system\n      - `exit`: remove collateral from the system\n\n*/\n\ncontract GemJoin {\n    // --- Auth ---\n    mapping (address => uint) public wards;\n    function rely(address usr) external auth {\n        wards[usr] = 1;\n        emit Rely(usr);\n    }\n    function deny(address usr) external auth {\n        wards[usr] = 0;\n        emit Deny(usr);\n    }\n    modifier auth {\n        require(wards[msg.sender] == 1, \"GemJoin/not-authorized\");\n        _;\n    }\n\n    VatLike public vat;   // CDP Engine\n    bytes32 public ilk;   // Collateral Type\n    GemLike public gem;\n    uint    public dec;\n    uint    public live;  // Active Flag\n\n    // Events\n    event Rely(address indexed usr);\n    event Deny(address indexed usr);\n    event Join(address indexed usr, uint256 wad);\n    event Exit(address indexed usr, uint256 wad);\n    event Cage();\n\n    constructor(address vat_, bytes32 ilk_, address gem_) public {\n        wards[msg.sender] = 1;\n        live = 1;\n        vat = VatLike(vat_);\n        ilk = ilk_;\n        gem = GemLike(gem_);\n        dec = gem.decimals();\n        emit Rely(msg.sender);\n    }\n    function cage() external auth {\n        live = 0;\n        emit Cage();\n    }\n    function join(address usr, uint wad) external {\n        require(live == 1, \"GemJoin/not-live\");\n        require(int(wad) >= 0, \"GemJoin/overflow\");\n        vat.slip(ilk, usr, int(wad));\n        require(gem.transferFrom(msg.sender, address(this), wad), \"GemJoin/failed-transfer\");\n        emit Join(usr, wad);\n    }\n    function exit(address usr, uint wad) external {\n        require(wad <= 2 ** 255, \"GemJoin/overflow\");\n        vat.slip(ilk, msg.sender, -int(wad));\n        require(gem.transfer(usr, wad), \"GemJoin/failed-transfer\");\n        emit Exit(usr, wad);\n    }\n}\n\ncontract ETHJoin {\n    // --- Auth ---\n    mapping (address => uint) public wards;\n    function rely(address usr) external auth {\n        wards[usr] = 1;\n        emit Rely(usr);\n    }\n    function deny(address usr) external auth {\n        wards[usr] = 0;\n        emit Deny(usr);\n    }\n    modifier auth {\n        require(wards[msg.sender] == 1, \"ETHJoin/not-authorized\");\n        _;\n    }\n\n    // Events\n    event Rely(address indexed usr);\n    event Deny(address indexed usr);\n    event Join(address indexed usr, uint256 wad);\n    event Exit(address indexed usr, uint256 wad);\n    event Cage();\n\n    VatLike public vat;\n    bytes32 public ilk;\n    uint    public live;  // Access Flag\n\n    constructor(address vat_, bytes32 ilk_) public {\n        wards[msg.sender] = 1;\n        live = 1;\n        vat = VatLike(vat_);\n        ilk = ilk_;\n    }\n    function cage() external auth {\n        live = 0;\n        emit Cage();\n    }\n    function join(address usr) external payable {\n        require(live == 1, \"ETHJoin/not-live\");\n        require(int(msg.value) >= 0, \"ETHJoin/overflow\");\n        vat.slip(ilk, usr, int(msg.value));\n        emit Join(usr, msg.value);\n    }\n    function exit(address payable usr, uint wad) external {\n        require(int(wad) >= 0, \"ETHJoin/overflow\");\n        vat.slip(ilk, msg.sender, -int(wad));\n        usr.transfer(wad);\n        emit Exit(usr, wad);\n    }\n}\n\ncontract UsddJoin {\n    // --- Auth ---\n    mapping (address => uint) public wards;\n    function rely(address usr) external auth {\n        wards[usr] = 1;\n        emit Rely(usr);\n    }\n    function deny(address usr) external auth {\n        wards[usr] = 0;\n        emit Deny(usr);\n    }\n    modifier auth {\n        require(wards[msg.sender] == 1, \"UsddJoin/not-authorized\");\n        _;\n    }\n\n    VatLike public vat;      // CDP Engine\n    DSTokenLike public usdd;  // Stablecoin Token\n    uint    public live;     // Active Flag\n\n    // Events\n    event Rely(address indexed usr);\n    event Deny(address indexed usr);\n    event Join(address indexed usr, uint256 wad);\n    event Exit(address indexed usr, uint256 wad);\n    event Cage();\n\n    constructor(address vat_, address usdd_) public {\n        wards[msg.sender] = 1;\n        live = 1;\n        vat = VatLike(vat_);\n        usdd = DSTokenLike(usdd_);\n    }\n    function cage() external auth {\n        live = 0;\n        emit Cage();\n    }\n    uint constant ONE = 10 ** 27;\n    function mul(uint x, uint y) internal pure returns (uint z) {\n        require(y == 0 || (z = x * y) / y == x);\n    }\n    function join(address usr, uint wad) external {\n        vat.move(address(this), usr, mul(ONE, wad));\n        usdd.burn(msg.sender, wad);\n        emit Join(usr, wad);\n    }\n    function exit(address usr, uint wad) external {\n        require(live == 1, \"UsddJoin/not-live\");\n        vat.move(msg.sender, address(this), mul(ONE, wad));\n        usdd.mint(usr, wad);\n        emit Exit(usr, wad);\n    }\n}\n"}},"proxyResolution":{"isProxy":false,"proxyType":null,"implementations":[]},"matchId":"28270617","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-04-24T22:02:30Z","match":"exact_match","chainId":"1","address":"0x983DFef6d71862d809e239845Da5A959492f63b8"}