// Copyright (C) 2022 Dai Foundation // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.6.12; import "dss-interfaces/dss/DaiJoinAbstract.sol"; import "dss-interfaces/dss/DaiAbstract.sol"; import "dss-interfaces/dss/ChainlogAbstract.sol"; /** * @author Henrique Barcelos * @title RwaJar: Facility to allow stability fee payments into the Surplus Buffer. * @dev Users can either send Dai directly to this conract or approve it to pull Dai from their wallet. */ contract RwaJar { /// @notice The DaiJoin adapter from MCD. DaiJoinAbstract public immutable daiJoin; /// @notice The Dai token. DaiAbstract public immutable dai; /// @notice The Chainlog from MCD. ChainlogAbstract public immutable chainlog; /** * @notice Emitted whenever Dai is sent to the `vow`. * @param usr The origin of the funds. * @param wad The amount of Dai sent. */ event Toss(address indexed usr, uint256 wad); /** * @dev The Dai address is obtained from the DaiJoin contract. * @param chainlog_ The chainlog from MCD. */ constructor(address chainlog_) public { address daiJoin_ = ChainlogAbstract(chainlog_).getAddress("MCD_JOIN_DAI"); // DaiJoin and Dai are meant to be immutable, so we can store them. daiJoin = DaiJoinAbstract(daiJoin_); dai = DaiAbstract(DaiJoinAbstract(daiJoin_).dai()); // We also store the chainlog to get the Vow address on-demand. chainlog = ChainlogAbstract(chainlog_); DaiAbstract(DaiJoinAbstract(daiJoin_).dai()).approve(daiJoin_, type(uint256).max); } /** * @notice Transfers any outstanding Dai balance in this contract to the `vow`. * @dev Reverts if there Dai balance of this contract is zero. * @dev This effectively burns ERC-20 Dai and credits it to the internal Dai balance of the `vow` in the Vat. */ function void() external { uint256 balance = dai.balanceOf(address(this)); require(balance > 0, "RwaJar/already-empty"); daiJoin.join(chainlog.getAddress("MCD_VOW"), balance); emit Toss(address(this), balance); } /** * @notice Pulls `wad` amount of Dai from the sender's wallet into the `vow`. * @dev Requires `msg.sender` to have previously `approve`d this contract to spend at least `wad` Dai. * @dev This effectively burns ERC-20 Dai and credits it to the internal Dai balance of the `vow` in the Vat. * @param wad The amount of Dai. */ function toss(uint256 wad) external { dai.transferFrom(msg.sender, address(this), wad); daiJoin.join(chainlog.getAddress("MCD_VOW"), wad); emit Toss(msg.sender, wad); } }