Transaction Hash:
Block:
9909147 at Apr-20-2020 11:51:32 AM +UTC
Transaction Fee:
0.000613772 ETH
$1.27
Gas Used:
153,443 Gas / 4 Gwei
Emitted Events:
| 160 |
0x0b5c54905a021b2c3c6dad0e8270a7dd0207cbab.0x1cff79cd00000000000000000000000000000000000000000000000000000000( 0x1cff79cd00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000a1ed93bf44ba35f1e8ebfb4d104a0e109337a5aa, 0x00000000000000000000000007ee93aeea0a36fff2a9b95dd22bd6049ee54f26, 0x0000000000000000000000000000000000000000000000000000000000000040, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 000000000000000000000000000000000000000000000000000000c41cff79cd, 00000000000000000000000007ee93aeea0a36fff2a9b95dd22bd6049ee54f26, 0000000000000000000000000000000000000000000000000000000000000040, 0000000000000000000000000000000000000000000000000000000000000044, c77843b30000000000000000000000009759a6ac90977b93b58547b4a71c7831, 7f391a28000000000000000000000000197e90f9fad81970ba7976f33cbd7708, 8e5d7cf700000000000000000000000000000000000000000000000000000000 )
|
| 161 |
Vat.0xf24e23eb00000000000000000000000000000000000000000000000000000000( 0xf24e23eb00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000a950524441892a31ebddf91d3ceefa04bf454466, 0x000000000000000000000000197e90f9fad81970ba7976f33cbd77088e5d7cf7, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, f24e23eb000000000000000000000000a950524441892a31ebddf91d3ceefa04, bf454466000000000000000000000000197e90f9fad81970ba7976f33cbd7708, 8e5d7cf700000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
|
| 162 |
Pot.0x9f678cca00000000000000000000000000000000000000000000000000000000( 0x9f678cca00000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000b5c54905a021b2c3c6dad0e8270a7dd0207cbab, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 9f678cca00000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
|
| 163 |
Vat.0xbb35783b00000000000000000000000000000000000000000000000000000000( 0xbb35783b00000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000197e90f9fad81970ba7976f33cbd77088e5d7cf7, 0x0000000000000000000000000b5c54905a021b2c3c6dad0e8270a7dd0207cbab, 0x0000000000000000000000033907dd34d26d24a6b08b5a86ff24e4355f63d902, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, bb35783b000000000000000000000000197e90f9fad81970ba7976f33cbd7708, 8e5d7cf70000000000000000000000000b5c54905a021b2c3c6dad0e8270a7dd, 0207cbab0000000000000000000000033907dd34d26d24a6b08b5a86ff24e435, 5f63d90200000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
|
| 164 |
Pot.0x7f8661a100000000000000000000000000000000000000000000000000000000( 0x7f8661a100000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000b5c54905a021b2c3c6dad0e8270a7dd0207cbab, 0x0000000000000000000000000000000000000000000000fad15b604f64b23fe6, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, 7f8661a10000000000000000000000000000000000000000000000fad15b604f, 64b23fe600000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
|
| 165 |
Vat.0xbb35783b00000000000000000000000000000000000000000000000000000000( 0xbb35783b00000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000b5c54905a021b2c3c6dad0e8270a7dd0207cbab, 0x0000000000000000000000009759a6ac90977b93b58547b4a71c78317f391a28, 0x0000000000000000000000033907dd34d26d24a6af871ad78d9285fc38000000, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, bb35783b0000000000000000000000000b5c54905a021b2c3c6dad0e8270a7dd, 0207cbab0000000000000000000000009759a6ac90977b93b58547b4a71c7831, 7f391a280000000000000000000000033907dd34d26d24a6af871ad78d9285fc, 3800000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
|
| 166 |
Dai.Transfer( src=0x0000000000000000000000000000000000000000, dst=[Sender] 0xa1ed93bf44ba35f1e8ebfb4d104a0e109337a5aa, wad=4710092760935635903603 )
|
| 167 |
DaiJoin.0xef693bed00000000000000000000000000000000000000000000000000000000( 0xef693bed00000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000b5c54905a021b2c3c6dad0e8270a7dd0207cbab, 0x000000000000000000000000a1ed93bf44ba35f1e8ebfb4d104a0e109337a5aa, 0x0000000000000000000000000000000000000000000000ff55aafaee13746473, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000000000000000000e0, ef693bed000000000000000000000000a1ed93bf44ba35f1e8ebfb4d104a0e10, 9337a5aa0000000000000000000000000000000000000000000000ff55aafaee, 1374647300000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x197E90f9...88E5D7cf7 | (Sky: MCD Pot) | ||||
| 0x35D1b3F3...259A0492B | (Sky: MCD Vat) | ||||
| 0x6B175474...495271d0F | |||||
| 0xA1eD93Bf...09337A5aa |
81.342202476994933353 Eth
Nonce: 221
|
81.341588704994933353 Eth
Nonce: 222
| 0.000613772 | ||
|
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 884.945665755541194788 Eth | 884.946279527541194788 Eth | 0.000613772 |
Execution Trace
DSProxy #142,561.1cff79cd( )
DssProxyActionsDsr.exitAll( daiJoin=0x9759A6Ac90977b93B58547b4A71c78317f391A28, pot=0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7 )-
DaiJoin.CALL( ) Pot.CALL( )-
Vat.suck( u=0xA950524441892A31ebddF91d3cEEFa04Bf454466, v=0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7, rad=0 )
-
-
Pot.pie( 0x0b5C54905A021b2C3c6DaD0E8270A7Dd0207CBAB ) => ( 4626771775698303598566 ) -
Vat.can( 0x0b5C54905A021b2C3c6DaD0E8270A7Dd0207CBAB, 0x9759A6Ac90977b93B58547b4A71c78317f391A28 ) => ( 1 ) DaiJoin.exit( usr=0xA1eD93Bf44Ba35f1e8EBfB4d104A0e109337A5aa, wad=4710092760935635903603 )
-
File 1 of 5: Vat
File 2 of 5: Pot
File 3 of 5: Dai
File 4 of 5: DaiJoin
File 5 of 5: DssProxyActionsDsr
// hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/vat.sol
pragma solidity =0.5.12;
////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/vat.sol
/// vat.sol -- Dai CDP database
// Copyright (C) 2018 Rain <rainbreak@riseup.net>
//
// 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 <https://www.gnu.org/licenses/>.
/* pragma solidity 0.5.12; */
contract Vat {
// --- Auth ---
mapping (address => uint) public wards;
function rely(address usr) external note auth { require(live == 1, "Vat/not-live"); wards[usr] = 1; }
function deny(address usr) external note auth { require(live == 1, "Vat/not-live"); wards[usr] = 0; }
modifier auth {
require(wards[msg.sender] == 1, "Vat/not-authorized");
_;
}
mapping(address => mapping (address => uint)) public can;
function hope(address usr) external note { can[msg.sender][usr] = 1; }
function nope(address usr) external note { can[msg.sender][usr] = 0; }
function wish(address bit, address usr) internal view returns (bool) {
return either(bit == usr, can[bit][usr] == 1);
}
// --- Data ---
struct Ilk {
uint256 Art; // Total Normalised Debt [wad]
uint256 rate; // Accumulated Rates [ray]
uint256 spot; // Price with Safety Margin [ray]
uint256 line; // Debt Ceiling [rad]
uint256 dust; // Urn Debt Floor [rad]
}
struct Urn {
uint256 ink; // Locked Collateral [wad]
uint256 art; // Normalised Debt [wad]
}
mapping (bytes32 => Ilk) public ilks;
mapping (bytes32 => mapping (address => Urn )) public urns;
mapping (bytes32 => mapping (address => uint)) public gem; // [wad]
mapping (address => uint256) public dai; // [rad]
mapping (address => uint256) public sin; // [rad]
uint256 public debt; // Total Dai Issued [rad]
uint256 public vice; // Total Unbacked Dai [rad]
uint256 public Line; // Total Debt Ceiling [rad]
uint256 public live; // Access Flag
// --- Logs ---
event LogNote(
bytes4 indexed sig,
bytes32 indexed arg1,
bytes32 indexed arg2,
bytes32 indexed arg3,
bytes data
) anonymous;
modifier note {
_;
assembly {
// log an 'anonymous' event with a constant 6 words of calldata
// and four indexed topics: the selector and the first three args
let mark := msize // end of memory ensures zero
mstore(0x40, add(mark, 288)) // update free memory pointer
mstore(mark, 0x20) // bytes type data offset
mstore(add(mark, 0x20), 224) // bytes size (padded)
calldatacopy(add(mark, 0x40), 0, 224) // bytes payload
log4(mark, 288, // calldata
shl(224, shr(224, calldataload(0))), // msg.sig
calldataload(4), // arg1
calldataload(36), // arg2
calldataload(68) // arg3
)
}
}
// --- Init ---
constructor() public {
wards[msg.sender] = 1;
live = 1;
}
// --- Math ---
function add(uint x, int y) internal pure returns (uint z) {
z = x + uint(y);
require(y >= 0 || z <= x);
require(y <= 0 || z >= x);
}
function sub(uint x, int y) internal pure returns (uint z) {
z = x - uint(y);
require(y <= 0 || z <= x);
require(y >= 0 || z >= x);
}
function mul(uint x, int y) internal pure returns (int z) {
z = int(x) * y;
require(int(x) >= 0);
require(y == 0 || z / y == int(x));
}
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);
}
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x);
}
// --- Administration ---
function init(bytes32 ilk) external note auth {
require(ilks[ilk].rate == 0, "Vat/ilk-already-init");
ilks[ilk].rate = 10 ** 27;
}
function file(bytes32 what, uint data) external note auth {
require(live == 1, "Vat/not-live");
if (what == "Line") Line = data;
else revert("Vat/file-unrecognized-param");
}
function file(bytes32 ilk, bytes32 what, uint data) external note auth {
require(live == 1, "Vat/not-live");
if (what == "spot") ilks[ilk].spot = data;
else if (what == "line") ilks[ilk].line = data;
else if (what == "dust") ilks[ilk].dust = data;
else revert("Vat/file-unrecognized-param");
}
function cage() external note auth {
live = 0;
}
// --- Fungibility ---
function slip(bytes32 ilk, address usr, int256 wad) external note auth {
gem[ilk][usr] = add(gem[ilk][usr], wad);
}
function flux(bytes32 ilk, address src, address dst, uint256 wad) external note {
require(wish(src, msg.sender), "Vat/not-allowed");
gem[ilk][src] = sub(gem[ilk][src], wad);
gem[ilk][dst] = add(gem[ilk][dst], wad);
}
function move(address src, address dst, uint256 rad) external note {
require(wish(src, msg.sender), "Vat/not-allowed");
dai[src] = sub(dai[src], rad);
dai[dst] = add(dai[dst], rad);
}
function either(bool x, bool y) internal pure returns (bool z) {
assembly{ z := or(x, y)}
}
function both(bool x, bool y) internal pure returns (bool z) {
assembly{ z := and(x, y)}
}
// --- CDP Manipulation ---
function frob(bytes32 i, address u, address v, address w, int dink, int dart) external note {
// system is live
require(live == 1, "Vat/not-live");
Urn memory urn = urns[i][u];
Ilk memory ilk = ilks[i];
// ilk has been initialised
require(ilk.rate != 0, "Vat/ilk-not-init");
urn.ink = add(urn.ink, dink);
urn.art = add(urn.art, dart);
ilk.Art = add(ilk.Art, dart);
int dtab = mul(ilk.rate, dart);
uint tab = mul(ilk.rate, urn.art);
debt = add(debt, dtab);
// either debt has decreased, or debt ceilings are not exceeded
require(either(dart <= 0, both(mul(ilk.Art, ilk.rate) <= ilk.line, debt <= Line)), "Vat/ceiling-exceeded");
// urn is either less risky than before, or it is safe
require(either(both(dart <= 0, dink >= 0), tab <= mul(urn.ink, ilk.spot)), "Vat/not-safe");
// urn is either more safe, or the owner consents
require(either(both(dart <= 0, dink >= 0), wish(u, msg.sender)), "Vat/not-allowed-u");
// collateral src consents
require(either(dink <= 0, wish(v, msg.sender)), "Vat/not-allowed-v");
// debt dst consents
require(either(dart >= 0, wish(w, msg.sender)), "Vat/not-allowed-w");
// urn has no debt, or a non-dusty amount
require(either(urn.art == 0, tab >= ilk.dust), "Vat/dust");
gem[i][v] = sub(gem[i][v], dink);
dai[w] = add(dai[w], dtab);
urns[i][u] = urn;
ilks[i] = ilk;
}
// --- CDP Fungibility ---
function fork(bytes32 ilk, address src, address dst, int dink, int dart) external note {
Urn storage u = urns[ilk][src];
Urn storage v = urns[ilk][dst];
Ilk storage i = ilks[ilk];
u.ink = sub(u.ink, dink);
u.art = sub(u.art, dart);
v.ink = add(v.ink, dink);
v.art = add(v.art, dart);
uint utab = mul(u.art, i.rate);
uint vtab = mul(v.art, i.rate);
// both sides consent
require(both(wish(src, msg.sender), wish(dst, msg.sender)), "Vat/not-allowed");
// both sides safe
require(utab <= mul(u.ink, i.spot), "Vat/not-safe-src");
require(vtab <= mul(v.ink, i.spot), "Vat/not-safe-dst");
// both sides non-dusty
require(either(utab >= i.dust, u.art == 0), "Vat/dust-src");
require(either(vtab >= i.dust, v.art == 0), "Vat/dust-dst");
}
// --- CDP Confiscation ---
function grab(bytes32 i, address u, address v, address w, int dink, int dart) external note auth {
Urn storage urn = urns[i][u];
Ilk storage ilk = ilks[i];
urn.ink = add(urn.ink, dink);
urn.art = add(urn.art, dart);
ilk.Art = add(ilk.Art, dart);
int dtab = mul(ilk.rate, dart);
gem[i][v] = sub(gem[i][v], dink);
sin[w] = sub(sin[w], dtab);
vice = sub(vice, dtab);
}
// --- Settlement ---
function heal(uint rad) external note {
address u = msg.sender;
sin[u] = sub(sin[u], rad);
dai[u] = sub(dai[u], rad);
vice = sub(vice, rad);
debt = sub(debt, rad);
}
function suck(address u, address v, uint rad) external note auth {
sin[u] = add(sin[u], rad);
dai[v] = add(dai[v], rad);
vice = add(vice, rad);
debt = add(debt, rad);
}
// --- Rates ---
function fold(bytes32 i, address u, int rate) external note auth {
require(live == 1, "Vat/not-live");
Ilk storage ilk = ilks[i];
ilk.rate = add(ilk.rate, rate);
int rad = mul(ilk.Art, rate);
dai[u] = add(dai[u], rad);
debt = add(debt, rad);
}
}File 2 of 5: Pot
// hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/pot.sol
pragma solidity =0.5.12;
////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/lib.sol
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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 General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
/* pragma solidity 0.5.12; */
contract LibNote {
event LogNote(
bytes4 indexed sig,
address indexed usr,
bytes32 indexed arg1,
bytes32 indexed arg2,
bytes data
) anonymous;
modifier note {
_;
assembly {
// log an 'anonymous' event with a constant 6 words of calldata
// and four indexed topics: selector, caller, arg1 and arg2
let mark := msize // end of memory ensures zero
mstore(0x40, add(mark, 288)) // update free memory pointer
mstore(mark, 0x20) // bytes type data offset
mstore(add(mark, 0x20), 224) // bytes size (padded)
calldatacopy(add(mark, 0x40), 0, 224) // bytes payload
log4(mark, 288, // calldata
shl(224, shr(224, calldataload(0))), // msg.sig
caller, // msg.sender
calldataload(4), // arg1
calldataload(36) // arg2
)
}
}
}
////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/pot.sol
/// pot.sol -- Dai Savings Rate
// Copyright (C) 2018 Rain <rainbreak@riseup.net>
//
// 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 <https://www.gnu.org/licenses/>.
/* pragma solidity 0.5.12; */
/* import "./lib.sol"; */
/*
"Savings Dai" is obtained when Dai is deposited into
this contract. Each "Savings Dai" accrues Dai interest
at the "Dai Savings Rate".
This contract does not implement a user tradeable token
and is intended to be used with adapters.
--- `save` your `dai` in the `pot` ---
- `dsr`: the Dai Savings Rate
- `pie`: user balance of Savings Dai
- `join`: start saving some dai
- `exit`: remove some dai
- `drip`: perform rate collection
*/
contract VatLike {
function move(address,address,uint256) external;
function suck(address,address,uint256) external;
}
contract Pot is LibNote {
// --- Auth ---
mapping (address => uint) public wards;
function rely(address guy) external note auth { wards[guy] = 1; }
function deny(address guy) external note auth { wards[guy] = 0; }
modifier auth {
require(wards[msg.sender] == 1, "Pot/not-authorized");
_;
}
// --- Data ---
mapping (address => uint256) public pie; // user Savings Dai
uint256 public Pie; // total Savings Dai
uint256 public dsr; // the Dai Savings Rate
uint256 public chi; // the Rate Accumulator
VatLike public vat; // CDP engine
address public vow; // debt engine
uint256 public rho; // time of last drip
uint256 public live; // Access Flag
// --- Init ---
constructor(address vat_) public {
wards[msg.sender] = 1;
vat = VatLike(vat_);
dsr = ONE;
chi = ONE;
rho = now;
live = 1;
}
// --- Math ---
uint256 constant ONE = 10 ** 27;
function rpow(uint x, uint n, uint base) internal pure returns (uint z) {
assembly {
switch x case 0 {switch n case 0 {z := base} default {z := 0}}
default {
switch mod(n, 2) case 0 { z := base } default { z := x }
let half := div(base, 2) // for rounding.
for { n := div(n, 2) } n { n := div(n,2) } {
let xx := mul(x, x)
if iszero(eq(div(xx, x), x)) { revert(0,0) }
let xxRound := add(xx, half)
if lt(xxRound, xx) { revert(0,0) }
x := div(xxRound, base)
if mod(n,2) {
let zx := mul(z, x)
if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) { revert(0,0) }
let zxRound := add(zx, half)
if lt(zxRound, zx) { revert(0,0) }
z := div(zxRound, base)
}
}
}
}
}
function rmul(uint x, uint y) internal pure returns (uint z) {
z = mul(x, y) / ONE;
}
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);
}
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x);
}
// --- Administration ---
function file(bytes32 what, uint256 data) external note auth {
require(live == 1, "Pot/not-live");
require(now == rho, "Pot/rho-not-updated");
if (what == "dsr") dsr = data;
else revert("Pot/file-unrecognized-param");
}
function file(bytes32 what, address addr) external note auth {
if (what == "vow") vow = addr;
else revert("Pot/file-unrecognized-param");
}
function cage() external note auth {
live = 0;
dsr = ONE;
}
// --- Savings Rate Accumulation ---
function drip() external note returns (uint tmp) {
require(now >= rho, "Pot/invalid-now");
tmp = rmul(rpow(dsr, now - rho, ONE), chi);
uint chi_ = sub(tmp, chi);
chi = tmp;
rho = now;
vat.suck(address(vow), address(this), mul(Pie, chi_));
}
// --- Savings Dai Management ---
function join(uint wad) external note {
require(now == rho, "Pot/rho-not-updated");
pie[msg.sender] = add(pie[msg.sender], wad);
Pie = add(Pie, wad);
vat.move(msg.sender, address(this), mul(chi, wad));
}
function exit(uint wad) external note {
pie[msg.sender] = sub(pie[msg.sender], wad);
Pie = sub(Pie, wad);
vat.move(address(this), msg.sender, mul(chi, wad));
}
}File 3 of 5: Dai
// hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/dai.sol
pragma solidity =0.5.12;
////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/lib.sol
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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 General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
/* pragma solidity 0.5.12; */
contract LibNote {
event LogNote(
bytes4 indexed sig,
address indexed usr,
bytes32 indexed arg1,
bytes32 indexed arg2,
bytes data
) anonymous;
modifier note {
_;
assembly {
// log an 'anonymous' event with a constant 6 words of calldata
// and four indexed topics: selector, caller, arg1 and arg2
let mark := msize // end of memory ensures zero
mstore(0x40, add(mark, 288)) // update free memory pointer
mstore(mark, 0x20) // bytes type data offset
mstore(add(mark, 0x20), 224) // bytes size (padded)
calldatacopy(add(mark, 0x40), 0, 224) // bytes payload
log4(mark, 288, // calldata
shl(224, shr(224, calldataload(0))), // msg.sig
caller, // msg.sender
calldataload(4), // arg1
calldataload(36) // arg2
)
}
}
}
////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/dai.sol
// Copyright (C) 2017, 2018, 2019 dbrock, rain, mrchico
// 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 <https://www.gnu.org/licenses/>.
/* pragma solidity 0.5.12; */
/* import "./lib.sol"; */
contract Dai is LibNote {
// --- Auth ---
mapping (address => uint) public wards;
function rely(address guy) external note auth { wards[guy] = 1; }
function deny(address guy) external note 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);
}
}File 4 of 5: DaiJoin
// hevm: flattened sources of /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/join.sol
pragma solidity =0.5.12;
////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/lib.sol
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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 General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
/* pragma solidity 0.5.12; */
contract LibNote {
event LogNote(
bytes4 indexed sig,
address indexed usr,
bytes32 indexed arg1,
bytes32 indexed arg2,
bytes data
) anonymous;
modifier note {
_;
assembly {
// log an 'anonymous' event with a constant 6 words of calldata
// and four indexed topics: selector, caller, arg1 and arg2
let mark := msize // end of memory ensures zero
mstore(0x40, add(mark, 288)) // update free memory pointer
mstore(mark, 0x20) // bytes type data offset
mstore(add(mark, 0x20), 224) // bytes size (padded)
calldatacopy(add(mark, 0x40), 0, 224) // bytes payload
log4(mark, 288, // calldata
shl(224, shr(224, calldataload(0))), // msg.sig
caller, // msg.sender
calldataload(4), // arg1
calldataload(36) // arg2
)
}
}
}
////// /nix/store/8xb41r4qd0cjb63wcrxf1qmfg88p0961-dss-6fd7de0/src/join.sol
/// join.sol -- Basic token adapters
// Copyright (C) 2018 Rain <rainbreak@riseup.net>
//
// 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 <https://www.gnu.org/licenses/>.
/* pragma solidity 0.5.12; */
/* import "./lib.sol"; */
contract GemLike {
function decimals() public view returns (uint);
function transfer(address,uint) external returns (bool);
function transferFrom(address,address,uint) external returns (bool);
}
contract DSTokenLike {
function mint(address,uint) external;
function burn(address,uint) external;
}
contract VatLike {
function slip(bytes32,address,int) external;
function move(address,address,uint) external;
}
/*
Here we provide *adapters* to connect the Vat to arbitrary external
token implementations, creating a bounded context for the Vat. The
adapters here are provided as working examples:
- `GemJoin`: For well behaved ERC20 tokens, with simple transfer
semantics.
- `ETHJoin`: For native Ether.
- `DaiJoin`: For connecting internal Dai balances to an external
`DSToken` implementation.
In practice, adapter implementations will be varied and specific to
individual collateral types, accounting for different transfer
semantics and token standards.
Adapters need to implement two basic methods:
- `join`: enter collateral into the system
- `exit`: remove collateral from the system
*/
contract GemJoin is LibNote {
// --- Auth ---
mapping (address => uint) public wards;
function rely(address usr) external note auth { wards[usr] = 1; }
function deny(address usr) external note auth { wards[usr] = 0; }
modifier auth {
require(wards[msg.sender] == 1, "GemJoin/not-authorized");
_;
}
VatLike public vat;
bytes32 public ilk;
GemLike public gem;
uint public dec;
uint public live; // Access Flag
constructor(address vat_, bytes32 ilk_, address gem_) public {
wards[msg.sender] = 1;
live = 1;
vat = VatLike(vat_);
ilk = ilk_;
gem = GemLike(gem_);
dec = gem.decimals();
}
function cage() external note auth {
live = 0;
}
function join(address usr, uint wad) external note {
require(live == 1, "GemJoin/not-live");
require(int(wad) >= 0, "GemJoin/overflow");
vat.slip(ilk, usr, int(wad));
require(gem.transferFrom(msg.sender, address(this), wad), "GemJoin/failed-transfer");
}
function exit(address usr, uint wad) external note {
require(wad <= 2 ** 255, "GemJoin/overflow");
vat.slip(ilk, msg.sender, -int(wad));
require(gem.transfer(usr, wad), "GemJoin/failed-transfer");
}
}
contract ETHJoin is LibNote {
// --- Auth ---
mapping (address => uint) public wards;
function rely(address usr) external note auth { wards[usr] = 1; }
function deny(address usr) external note auth { wards[usr] = 0; }
modifier auth {
require(wards[msg.sender] == 1, "ETHJoin/not-authorized");
_;
}
VatLike public vat;
bytes32 public ilk;
uint public live; // Access Flag
constructor(address vat_, bytes32 ilk_) public {
wards[msg.sender] = 1;
live = 1;
vat = VatLike(vat_);
ilk = ilk_;
}
function cage() external note auth {
live = 0;
}
function join(address usr) external payable note {
require(live == 1, "ETHJoin/not-live");
require(int(msg.value) >= 0, "ETHJoin/overflow");
vat.slip(ilk, usr, int(msg.value));
}
function exit(address payable usr, uint wad) external note {
require(int(wad) >= 0, "ETHJoin/overflow");
vat.slip(ilk, msg.sender, -int(wad));
usr.transfer(wad);
}
}
contract DaiJoin is LibNote {
// --- Auth ---
mapping (address => uint) public wards;
function rely(address usr) external note auth { wards[usr] = 1; }
function deny(address usr) external note auth { wards[usr] = 0; }
modifier auth {
require(wards[msg.sender] == 1, "DaiJoin/not-authorized");
_;
}
VatLike public vat;
DSTokenLike public dai;
uint public live; // Access Flag
constructor(address vat_, address dai_) public {
wards[msg.sender] = 1;
live = 1;
vat = VatLike(vat_);
dai = DSTokenLike(dai_);
}
function cage() external note auth {
live = 0;
}
uint constant ONE = 10 ** 27;
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x);
}
function join(address usr, uint wad) external note {
vat.move(address(this), usr, mul(ONE, wad));
dai.burn(msg.sender, wad);
}
function exit(address usr, uint wad) external note {
require(live == 1, "DaiJoin/not-live");
vat.move(msg.sender, address(this), mul(ONE, wad));
dai.mint(usr, wad);
}
}File 5 of 5: DssProxyActionsDsr
// hevm: flattened sources of /nix/store/sxr9nv6bdacjzw8vhns72bxjga458x34-dss-proxy-actions-53f1d75/src/DssProxyActions.sol
pragma solidity =0.5.12;
////// /nix/store/sxr9nv6bdacjzw8vhns72bxjga458x34-dss-proxy-actions-53f1d75/src/DssProxyActions.sol
/* pragma solidity 0.5.12; */
contract GemLike {
function approve(address, uint) public;
function transfer(address, uint) public;
function transferFrom(address, address, uint) public;
function deposit() public payable;
function withdraw(uint) public;
}
contract ManagerLike {
function cdpCan(address, uint, address) public view returns (uint);
function ilks(uint) public view returns (bytes32);
function owns(uint) public view returns (address);
function urns(uint) public view returns (address);
function vat() public view returns (address);
function open(bytes32, address) public returns (uint);
function give(uint, address) public;
function cdpAllow(uint, address, uint) public;
function urnAllow(address, uint) public;
function frob(uint, int, int) public;
function flux(uint, address, uint) public;
function move(uint, address, uint) public;
function exit(address, uint, address, uint) public;
function quit(uint, address) public;
function enter(address, uint) public;
function shift(uint, uint) public;
}
contract VatLike {
function can(address, address) public view returns (uint);
function ilks(bytes32) public view returns (uint, uint, uint, uint, uint);
function dai(address) public view returns (uint);
function urns(bytes32, address) public view returns (uint, uint);
function frob(bytes32, address, address, address, int, int) public;
function hope(address) public;
function move(address, address, uint) public;
}
contract GemJoinLike {
function dec() public returns (uint);
function gem() public returns (GemLike);
function join(address, uint) public payable;
function exit(address, uint) public;
}
contract GNTJoinLike {
function bags(address) public view returns (address);
function make(address) public returns (address);
}
contract DaiJoinLike {
function vat() public returns (VatLike);
function dai() public returns (GemLike);
function join(address, uint) public payable;
function exit(address, uint) public;
}
contract HopeLike {
function hope(address) public;
function nope(address) public;
}
contract EndLike {
function fix(bytes32) public view returns (uint);
function cash(bytes32, uint) public;
function free(bytes32) public;
function pack(uint) public;
function skim(bytes32, address) public;
}
contract JugLike {
function drip(bytes32) public returns (uint);
}
contract PotLike {
function pie(address) public view returns (uint);
function drip() public returns (uint);
function join(uint) public;
function exit(uint) public;
}
contract ProxyRegistryLike {
function proxies(address) public view returns (address);
function build(address) public returns (address);
}
contract ProxyLike {
function owner() public view returns (address);
}
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// WARNING: These functions meant to be used as a a library for a DSProxy. Some are unsafe if you call them directly.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
contract Common {
uint256 constant RAY = 10 ** 27;
// Internal functions
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, "mul-overflow");
}
// Public functions
function daiJoin_join(address apt, address urn, uint wad) public {
// Gets DAI from the user's wallet
DaiJoinLike(apt).dai().transferFrom(msg.sender, address(this), wad);
// Approves adapter to take the DAI amount
DaiJoinLike(apt).dai().approve(apt, wad);
// Joins DAI into the vat
DaiJoinLike(apt).join(urn, wad);
}
}
contract DssProxyActions is Common {
// Internal functions
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x, "sub-overflow");
}
function toInt(uint x) internal pure returns (int y) {
y = int(x);
require(y >= 0, "int-overflow");
}
function toRad(uint wad) internal pure returns (uint rad) {
rad = mul(wad, 10 ** 27);
}
function convertTo18(address gemJoin, uint256 amt) internal returns (uint256 wad) {
// For those collaterals that have less than 18 decimals precision we need to do the conversion before passing to frob function
// Adapters will automatically handle the difference of precision
wad = mul(
amt,
10 ** (18 - GemJoinLike(gemJoin).dec())
);
}
function _getDrawDart(
address vat,
address jug,
address urn,
bytes32 ilk,
uint wad
) internal returns (int dart) {
// Updates stability fee rate
uint rate = JugLike(jug).drip(ilk);
// Gets DAI balance of the urn in the vat
uint dai = VatLike(vat).dai(urn);
// If there was already enough DAI in the vat balance, just exits it without adding more debt
if (dai < mul(wad, RAY)) {
// Calculates the needed dart so together with the existing dai in the vat is enough to exit wad amount of DAI tokens
dart = toInt(sub(mul(wad, RAY), dai) / rate);
// This is neeeded due lack of precision. It might need to sum an extra dart wei (for the given DAI wad amount)
dart = mul(uint(dart), rate) < mul(wad, RAY) ? dart + 1 : dart;
}
}
function _getWipeDart(
address vat,
uint dai,
address urn,
bytes32 ilk
) internal view returns (int dart) {
// Gets actual rate from the vat
(, uint rate,,,) = VatLike(vat).ilks(ilk);
// Gets actual art value of the urn
(, uint art) = VatLike(vat).urns(ilk, urn);
// Uses the whole dai balance in the vat to reduce the debt
dart = toInt(dai / rate);
// Checks the calculated dart is not higher than urn.art (total debt), otherwise uses its value
dart = uint(dart) <= art ? - dart : - toInt(art);
}
function _getWipeAllWad(
address vat,
address usr,
address urn,
bytes32 ilk
) internal view returns (uint wad) {
// Gets actual rate from the vat
(, uint rate,,,) = VatLike(vat).ilks(ilk);
// Gets actual art value of the urn
(, uint art) = VatLike(vat).urns(ilk, urn);
// Gets actual dai amount in the urn
uint dai = VatLike(vat).dai(usr);
uint rad = sub(mul(art, rate), dai);
wad = rad / RAY;
// If the rad precision has some dust, it will need to request for 1 extra wad wei
wad = mul(wad, RAY) < rad ? wad + 1 : wad;
}
// Public functions
function transfer(address gem, address dst, uint wad) public {
GemLike(gem).transfer(dst, wad);
}
function ethJoin_join(address apt, address urn) public payable {
// Wraps ETH in WETH
GemJoinLike(apt).gem().deposit.value(msg.value)();
// Approves adapter to take the WETH amount
GemJoinLike(apt).gem().approve(address(apt), msg.value);
// Joins WETH collateral into the vat
GemJoinLike(apt).join(urn, msg.value);
}
function gemJoin_join(address apt, address urn, uint wad, bool transferFrom) public {
// Only executes for tokens that have approval/transferFrom implementation
if (transferFrom) {
// Gets token from the user's wallet
GemJoinLike(apt).gem().transferFrom(msg.sender, address(this), wad);
// Approves adapter to take the token amount
GemJoinLike(apt).gem().approve(apt, wad);
}
// Joins token collateral into the vat
GemJoinLike(apt).join(urn, wad);
}
function hope(
address obj,
address usr
) public {
HopeLike(obj).hope(usr);
}
function nope(
address obj,
address usr
) public {
HopeLike(obj).nope(usr);
}
function open(
address manager,
bytes32 ilk,
address usr
) public returns (uint cdp) {
cdp = ManagerLike(manager).open(ilk, usr);
}
function give(
address manager,
uint cdp,
address usr
) public {
ManagerLike(manager).give(cdp, usr);
}
function giveToProxy(
address proxyRegistry,
address manager,
uint cdp,
address dst
) public {
// Gets actual proxy address
address proxy = ProxyRegistryLike(proxyRegistry).proxies(dst);
// Checks if the proxy address already existed and dst address is still the owner
if (proxy == address(0) || ProxyLike(proxy).owner() != dst) {
uint csize;
assembly {
csize := extcodesize(dst)
}
// We want to avoid creating a proxy for a contract address that might not be able to handle proxies, then losing the CDP
require(csize == 0, "Dst-is-a-contract");
// Creates the proxy for the dst address
proxy = ProxyRegistryLike(proxyRegistry).build(dst);
}
// Transfers CDP to the dst proxy
give(manager, cdp, proxy);
}
function cdpAllow(
address manager,
uint cdp,
address usr,
uint ok
) public {
ManagerLike(manager).cdpAllow(cdp, usr, ok);
}
function urnAllow(
address manager,
address usr,
uint ok
) public {
ManagerLike(manager).urnAllow(usr, ok);
}
function flux(
address manager,
uint cdp,
address dst,
uint wad
) public {
ManagerLike(manager).flux(cdp, dst, wad);
}
function move(
address manager,
uint cdp,
address dst,
uint rad
) public {
ManagerLike(manager).move(cdp, dst, rad);
}
function frob(
address manager,
uint cdp,
int dink,
int dart
) public {
ManagerLike(manager).frob(cdp, dink, dart);
}
function quit(
address manager,
uint cdp,
address dst
) public {
ManagerLike(manager).quit(cdp, dst);
}
function enter(
address manager,
address src,
uint cdp
) public {
ManagerLike(manager).enter(src, cdp);
}
function shift(
address manager,
uint cdpSrc,
uint cdpOrg
) public {
ManagerLike(manager).shift(cdpSrc, cdpOrg);
}
function makeGemBag(
address gemJoin
) public returns (address bag) {
bag = GNTJoinLike(gemJoin).make(address(this));
}
function lockETH(
address manager,
address ethJoin,
uint cdp
) public payable {
// Receives ETH amount, converts it to WETH and joins it into the vat
ethJoin_join(ethJoin, address(this));
// Locks WETH amount into the CDP
VatLike(ManagerLike(manager).vat()).frob(
ManagerLike(manager).ilks(cdp),
ManagerLike(manager).urns(cdp),
address(this),
address(this),
toInt(msg.value),
0
);
}
function safeLockETH(
address manager,
address ethJoin,
uint cdp,
address owner
) public payable {
require(ManagerLike(manager).owns(cdp) == owner, "owner-missmatch");
lockETH(manager, ethJoin, cdp);
}
function lockGem(
address manager,
address gemJoin,
uint cdp,
uint wad,
bool transferFrom
) public {
// Takes token amount from user's wallet and joins into the vat
gemJoin_join(gemJoin, address(this), wad, transferFrom);
// Locks token amount into the CDP
VatLike(ManagerLike(manager).vat()).frob(
ManagerLike(manager).ilks(cdp),
ManagerLike(manager).urns(cdp),
address(this),
address(this),
toInt(convertTo18(gemJoin, wad)),
0
);
}
function safeLockGem(
address manager,
address gemJoin,
uint cdp,
uint wad,
bool transferFrom,
address owner
) public {
require(ManagerLike(manager).owns(cdp) == owner, "owner-missmatch");
lockGem(manager, gemJoin, cdp, wad, transferFrom);
}
function freeETH(
address manager,
address ethJoin,
uint cdp,
uint wad
) public {
// Unlocks WETH amount from the CDP
frob(manager, cdp, -toInt(wad), 0);
// Moves the amount from the CDP urn to proxy's address
flux(manager, cdp, address(this), wad);
// Exits WETH amount to proxy address as a token
GemJoinLike(ethJoin).exit(address(this), wad);
// Converts WETH to ETH
GemJoinLike(ethJoin).gem().withdraw(wad);
// Sends ETH back to the user's wallet
msg.sender.transfer(wad);
}
function freeGem(
address manager,
address gemJoin,
uint cdp,
uint wad
) public {
uint wad18 = convertTo18(gemJoin, wad);
// Unlocks token amount from the CDP
frob(manager, cdp, -toInt(wad18), 0);
// Moves the amount from the CDP urn to proxy's address
flux(manager, cdp, address(this), wad18);
// Exits token amount to the user's wallet as a token
GemJoinLike(gemJoin).exit(msg.sender, wad);
}
function exitETH(
address manager,
address ethJoin,
uint cdp,
uint wad
) public {
// Moves the amount from the CDP urn to proxy's address
flux(manager, cdp, address(this), wad);
// Exits WETH amount to proxy address as a token
GemJoinLike(ethJoin).exit(address(this), wad);
// Converts WETH to ETH
GemJoinLike(ethJoin).gem().withdraw(wad);
// Sends ETH back to the user's wallet
msg.sender.transfer(wad);
}
function exitGem(
address manager,
address gemJoin,
uint cdp,
uint wad
) public {
// Moves the amount from the CDP urn to proxy's address
flux(manager, cdp, address(this), convertTo18(gemJoin, wad));
// Exits token amount to the user's wallet as a token
GemJoinLike(gemJoin).exit(msg.sender, wad);
}
function draw(
address manager,
address jug,
address daiJoin,
uint cdp,
uint wad
) public {
address urn = ManagerLike(manager).urns(cdp);
address vat = ManagerLike(manager).vat();
bytes32 ilk = ManagerLike(manager).ilks(cdp);
// Generates debt in the CDP
frob(manager, cdp, 0, _getDrawDart(vat, jug, urn, ilk, wad));
// Moves the DAI amount (balance in the vat in rad) to proxy's address
move(manager, cdp, address(this), toRad(wad));
// Allows adapter to access to proxy's DAI balance in the vat
if (VatLike(vat).can(address(this), address(daiJoin)) == 0) {
VatLike(vat).hope(daiJoin);
}
// Exits DAI to the user's wallet as a token
DaiJoinLike(daiJoin).exit(msg.sender, wad);
}
function wipe(
address manager,
address daiJoin,
uint cdp,
uint wad
) public {
address vat = ManagerLike(manager).vat();
address urn = ManagerLike(manager).urns(cdp);
bytes32 ilk = ManagerLike(manager).ilks(cdp);
address own = ManagerLike(manager).owns(cdp);
if (own == address(this) || ManagerLike(manager).cdpCan(own, cdp, address(this)) == 1) {
// Joins DAI amount into the vat
daiJoin_join(daiJoin, urn, wad);
// Paybacks debt to the CDP
frob(manager, cdp, 0, _getWipeDart(vat, VatLike(vat).dai(urn), urn, ilk));
} else {
// Joins DAI amount into the vat
daiJoin_join(daiJoin, address(this), wad);
// Paybacks debt to the CDP
VatLike(vat).frob(
ilk,
urn,
address(this),
address(this),
0,
_getWipeDart(vat, wad * RAY, urn, ilk)
);
}
}
function safeWipe(
address manager,
address daiJoin,
uint cdp,
uint wad,
address owner
) public {
require(ManagerLike(manager).owns(cdp) == owner, "owner-missmatch");
wipe(manager, daiJoin, cdp, wad);
}
function wipeAll(
address manager,
address daiJoin,
uint cdp
) public {
address vat = ManagerLike(manager).vat();
address urn = ManagerLike(manager).urns(cdp);
bytes32 ilk = ManagerLike(manager).ilks(cdp);
(, uint art) = VatLike(vat).urns(ilk, urn);
address own = ManagerLike(manager).owns(cdp);
if (own == address(this) || ManagerLike(manager).cdpCan(own, cdp, address(this)) == 1) {
// Joins DAI amount into the vat
daiJoin_join(daiJoin, urn, _getWipeAllWad(vat, urn, urn, ilk));
// Paybacks debt to the CDP
frob(manager, cdp, 0, -int(art));
} else {
// Joins DAI amount into the vat
daiJoin_join(daiJoin, address(this), _getWipeAllWad(vat, address(this), urn, ilk));
// Paybacks debt to the CDP
VatLike(vat).frob(
ilk,
urn,
address(this),
address(this),
0,
-int(art)
);
}
}
function safeWipeAll(
address manager,
address daiJoin,
uint cdp,
address owner
) public {
require(ManagerLike(manager).owns(cdp) == owner, "owner-missmatch");
wipeAll(manager, daiJoin, cdp);
}
function lockETHAndDraw(
address manager,
address jug,
address ethJoin,
address daiJoin,
uint cdp,
uint wadD
) public payable {
address urn = ManagerLike(manager).urns(cdp);
address vat = ManagerLike(manager).vat();
bytes32 ilk = ManagerLike(manager).ilks(cdp);
// Receives ETH amount, converts it to WETH and joins it into the vat
ethJoin_join(ethJoin, urn);
// Locks WETH amount into the CDP and generates debt
frob(manager, cdp, toInt(msg.value), _getDrawDart(vat, jug, urn, ilk, wadD));
// Moves the DAI amount (balance in the vat in rad) to proxy's address
move(manager, cdp, address(this), toRad(wadD));
// Allows adapter to access to proxy's DAI balance in the vat
if (VatLike(vat).can(address(this), address(daiJoin)) == 0) {
VatLike(vat).hope(daiJoin);
}
// Exits DAI to the user's wallet as a token
DaiJoinLike(daiJoin).exit(msg.sender, wadD);
}
function openLockETHAndDraw(
address manager,
address jug,
address ethJoin,
address daiJoin,
bytes32 ilk,
uint wadD
) public payable returns (uint cdp) {
cdp = open(manager, ilk, address(this));
lockETHAndDraw(manager, jug, ethJoin, daiJoin, cdp, wadD);
}
function lockGemAndDraw(
address manager,
address jug,
address gemJoin,
address daiJoin,
uint cdp,
uint wadC,
uint wadD,
bool transferFrom
) public {
address urn = ManagerLike(manager).urns(cdp);
address vat = ManagerLike(manager).vat();
bytes32 ilk = ManagerLike(manager).ilks(cdp);
// Takes token amount from user's wallet and joins into the vat
gemJoin_join(gemJoin, urn, wadC, transferFrom);
// Locks token amount into the CDP and generates debt
frob(manager, cdp, toInt(convertTo18(gemJoin, wadC)), _getDrawDart(vat, jug, urn, ilk, wadD));
// Moves the DAI amount (balance in the vat in rad) to proxy's address
move(manager, cdp, address(this), toRad(wadD));
// Allows adapter to access to proxy's DAI balance in the vat
if (VatLike(vat).can(address(this), address(daiJoin)) == 0) {
VatLike(vat).hope(daiJoin);
}
// Exits DAI to the user's wallet as a token
DaiJoinLike(daiJoin).exit(msg.sender, wadD);
}
function openLockGemAndDraw(
address manager,
address jug,
address gemJoin,
address daiJoin,
bytes32 ilk,
uint wadC,
uint wadD,
bool transferFrom
) public returns (uint cdp) {
cdp = open(manager, ilk, address(this));
lockGemAndDraw(manager, jug, gemJoin, daiJoin, cdp, wadC, wadD, transferFrom);
}
function openLockGNTAndDraw(
address manager,
address jug,
address gntJoin,
address daiJoin,
bytes32 ilk,
uint wadC,
uint wadD
) public returns (address bag, uint cdp) {
// Creates bag (if doesn't exist) to hold GNT
bag = GNTJoinLike(gntJoin).bags(address(this));
if (bag == address(0)) {
bag = makeGemBag(gntJoin);
}
// Transfer funds to the funds which previously were sent to the proxy
GemLike(GemJoinLike(gntJoin).gem()).transfer(bag, wadC);
cdp = openLockGemAndDraw(manager, jug, gntJoin, daiJoin, ilk, wadC, wadD, false);
}
function wipeAndFreeETH(
address manager,
address ethJoin,
address daiJoin,
uint cdp,
uint wadC,
uint wadD
) public {
address urn = ManagerLike(manager).urns(cdp);
// Joins DAI amount into the vat
daiJoin_join(daiJoin, urn, wadD);
// Paybacks debt to the CDP and unlocks WETH amount from it
frob(
manager,
cdp,
-toInt(wadC),
_getWipeDart(ManagerLike(manager).vat(), VatLike(ManagerLike(manager).vat()).dai(urn), urn, ManagerLike(manager).ilks(cdp))
);
// Moves the amount from the CDP urn to proxy's address
flux(manager, cdp, address(this), wadC);
// Exits WETH amount to proxy address as a token
GemJoinLike(ethJoin).exit(address(this), wadC);
// Converts WETH to ETH
GemJoinLike(ethJoin).gem().withdraw(wadC);
// Sends ETH back to the user's wallet
msg.sender.transfer(wadC);
}
function wipeAllAndFreeETH(
address manager,
address ethJoin,
address daiJoin,
uint cdp,
uint wadC
) public {
address vat = ManagerLike(manager).vat();
address urn = ManagerLike(manager).urns(cdp);
bytes32 ilk = ManagerLike(manager).ilks(cdp);
(, uint art) = VatLike(vat).urns(ilk, urn);
// Joins DAI amount into the vat
daiJoin_join(daiJoin, urn, _getWipeAllWad(vat, urn, urn, ilk));
// Paybacks debt to the CDP and unlocks WETH amount from it
frob(
manager,
cdp,
-toInt(wadC),
-int(art)
);
// Moves the amount from the CDP urn to proxy's address
flux(manager, cdp, address(this), wadC);
// Exits WETH amount to proxy address as a token
GemJoinLike(ethJoin).exit(address(this), wadC);
// Converts WETH to ETH
GemJoinLike(ethJoin).gem().withdraw(wadC);
// Sends ETH back to the user's wallet
msg.sender.transfer(wadC);
}
function wipeAndFreeGem(
address manager,
address gemJoin,
address daiJoin,
uint cdp,
uint wadC,
uint wadD
) public {
address urn = ManagerLike(manager).urns(cdp);
// Joins DAI amount into the vat
daiJoin_join(daiJoin, urn, wadD);
uint wad18 = convertTo18(gemJoin, wadC);
// Paybacks debt to the CDP and unlocks token amount from it
frob(
manager,
cdp,
-toInt(wad18),
_getWipeDart(ManagerLike(manager).vat(), VatLike(ManagerLike(manager).vat()).dai(urn), urn, ManagerLike(manager).ilks(cdp))
);
// Moves the amount from the CDP urn to proxy's address
flux(manager, cdp, address(this), wad18);
// Exits token amount to the user's wallet as a token
GemJoinLike(gemJoin).exit(msg.sender, wadC);
}
function wipeAllAndFreeGem(
address manager,
address gemJoin,
address daiJoin,
uint cdp,
uint wadC
) public {
address vat = ManagerLike(manager).vat();
address urn = ManagerLike(manager).urns(cdp);
bytes32 ilk = ManagerLike(manager).ilks(cdp);
(, uint art) = VatLike(vat).urns(ilk, urn);
// Joins DAI amount into the vat
daiJoin_join(daiJoin, urn, _getWipeAllWad(vat, urn, urn, ilk));
uint wad18 = convertTo18(gemJoin, wadC);
// Paybacks debt to the CDP and unlocks token amount from it
frob(
manager,
cdp,
-toInt(wad18),
-int(art)
);
// Moves the amount from the CDP urn to proxy's address
flux(manager, cdp, address(this), wad18);
// Exits token amount to the user's wallet as a token
GemJoinLike(gemJoin).exit(msg.sender, wadC);
}
}
contract DssProxyActionsEnd is Common {
// Internal functions
function _free(
address manager,
address end,
uint cdp
) internal returns (uint ink) {
bytes32 ilk = ManagerLike(manager).ilks(cdp);
address urn = ManagerLike(manager).urns(cdp);
VatLike vat = VatLike(ManagerLike(manager).vat());
uint art;
(ink, art) = vat.urns(ilk, urn);
// If CDP still has debt, it needs to be paid
if (art > 0) {
EndLike(end).skim(ilk, urn);
(ink,) = vat.urns(ilk, urn);
}
// Approves the manager to transfer the position to proxy's address in the vat
if (vat.can(address(this), address(manager)) == 0) {
vat.hope(manager);
}
// Transfers position from CDP to the proxy address
ManagerLike(manager).quit(cdp, address(this));
// Frees the position and recovers the collateral in the vat registry
EndLike(end).free(ilk);
}
// Public functions
function freeETH(
address manager,
address ethJoin,
address end,
uint cdp
) public {
uint wad = _free(manager, end, cdp);
// Exits WETH amount to proxy address as a token
GemJoinLike(ethJoin).exit(address(this), wad);
// Converts WETH to ETH
GemJoinLike(ethJoin).gem().withdraw(wad);
// Sends ETH back to the user's wallet
msg.sender.transfer(wad);
}
function freeGem(
address manager,
address gemJoin,
address end,
uint cdp
) public {
uint wad = _free(manager, end, cdp);
// Exits token amount to the user's wallet as a token
GemJoinLike(gemJoin).exit(msg.sender, wad);
}
function pack(
address daiJoin,
address end,
uint wad
) public {
daiJoin_join(daiJoin, address(this), wad);
VatLike vat = DaiJoinLike(daiJoin).vat();
// Approves the end to take out DAI from the proxy's balance in the vat
if (vat.can(address(this), address(end)) == 0) {
vat.hope(end);
}
EndLike(end).pack(wad);
}
function cashETH(
address ethJoin,
address end,
bytes32 ilk,
uint wad
) public {
EndLike(end).cash(ilk, wad);
uint wadC = mul(wad, EndLike(end).fix(ilk)) / RAY;
// Exits WETH amount to proxy address as a token
GemJoinLike(ethJoin).exit(address(this), wadC);
// Converts WETH to ETH
GemJoinLike(ethJoin).gem().withdraw(wadC);
// Sends ETH back to the user's wallet
msg.sender.transfer(wadC);
}
function cashGem(
address gemJoin,
address end,
bytes32 ilk,
uint wad
) public {
EndLike(end).cash(ilk, wad);
// Exits token amount to the user's wallet as a token
GemJoinLike(gemJoin).exit(msg.sender, mul(wad, EndLike(end).fix(ilk)) / RAY);
}
}
contract DssProxyActionsDsr is Common {
function join(
address daiJoin,
address pot,
uint wad
) public {
VatLike vat = DaiJoinLike(daiJoin).vat();
// Executes drip to get the chi rate updated to rho == now, otherwise join will fail
uint chi = PotLike(pot).drip();
// Joins wad amount to the vat balance
daiJoin_join(daiJoin, address(this), wad);
// Approves the pot to take out DAI from the proxy's balance in the vat
if (vat.can(address(this), address(pot)) == 0) {
vat.hope(pot);
}
// Joins the pie value (equivalent to the DAI wad amount) in the pot
PotLike(pot).join(mul(wad, RAY) / chi);
}
function exit(
address daiJoin,
address pot,
uint wad
) public {
VatLike vat = DaiJoinLike(daiJoin).vat();
// Executes drip to count the savings accumulated until this moment
uint chi = PotLike(pot).drip();
// Calculates the pie value in the pot equivalent to the DAI wad amount
uint pie = mul(wad, RAY) / chi;
// Exits DAI from the pot
PotLike(pot).exit(pie);
// Checks the actual balance of DAI in the vat after the pot exit
uint bal = DaiJoinLike(daiJoin).vat().dai(address(this));
// Allows adapter to access to proxy's DAI balance in the vat
if (vat.can(address(this), address(daiJoin)) == 0) {
vat.hope(daiJoin);
}
// It is necessary to check if due rounding the exact wad amount can be exited by the adapter.
// Otherwise it will do the maximum DAI balance in the vat
DaiJoinLike(daiJoin).exit(
msg.sender,
bal >= mul(wad, RAY) ? wad : bal / RAY
);
}
function exitAll(
address daiJoin,
address pot
) public {
VatLike vat = DaiJoinLike(daiJoin).vat();
// Executes drip to count the savings accumulated until this moment
uint chi = PotLike(pot).drip();
// Gets the total pie belonging to the proxy address
uint pie = PotLike(pot).pie(address(this));
// Exits DAI from the pot
PotLike(pot).exit(pie);
// Allows adapter to access to proxy's DAI balance in the vat
if (vat.can(address(this), address(daiJoin)) == 0) {
vat.hope(daiJoin);
}
// Exits the DAI amount corresponding to the value of pie
DaiJoinLike(daiJoin).exit(msg.sender, mul(chi, pie) / RAY);
}
}