Comments (3)
I notice in your example that you've commented out this requires check: // require(now == rho, "Pot/rho-not-updated");
Any reason why? That check stops you from joining the pot unless it has been recently dripped, which keeps you from earning interest on time from before you joined the pot.
from dss.
I'd suggest you use the real code as also the drip
function was changed. The require
you commented actually avoids taking advantage of an old rate accumulated.
You can test the real dsr
using dapptools
which allows you to handle the time easily.
from dss.
@ehildenb @gbalabasquer Thanks for your answers.
I retry to keep all require
and don't modify drip
, but still get the same result as before: I received more interest in the second join than the first join.
/// pot.sol -- Dai Savings Rate
// Copyright (C) 2018 Rain <[email protected]>
//
// 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;
/*
"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
*/
interface VatLike {
function move(address,address,uint256) external;
function suck(address,address,uint256) external;
}
contract Pot {
// --- 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, "Pot/not-authorized");
_;
}
// --- Data ---
mapping (address => uint256) public pie; // Normalised Savings Dai [wad]
uint256 public Pie; // Total Normalised Savings Dai [wad]
uint256 public dsr; // The Dai Savings Rate [ray]
uint256 public chi; // The Rate Accumulator [ray]
VatLike public vat; // CDP Engine
address public vow; // Debt Engine
uint256 public rho; // Time of last drip [unix epoch time]
uint256 public live; // Active Flag
mapping(address=>int256) public gains;
// --- 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 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 auth {
// if (what == "vow") vow = addr;
// else revert("Pot/file-unrecognized-param");
// }
function cage() external auth {
live = 0;
dsr = ONE;
}
// --- Savings Rate Accumulation ---
function drip() external 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 {
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));
gains[msg.sender] -= int(mul(chi, wad));
}
function exit(uint wad) external {
pie[msg.sender] = sub(pie[msg.sender], wad);
Pie = sub(Pie, wad);
// vat.move(address(this), msg.sender, mul(chi, wad));
gains[msg.sender] += int(mul(chi, wad));
}
function resetgain() external {
gains[msg.sender] = 0;
}
}
Test in truffle
var Pot = artifacts.require("Pot");
var time = require("./utils/time.js");
contract("pot test", async function (accounts) {
it("", async function () {
var pot = await Pot.deployed();
//feed dsr = 2%
await pot.drip();
await pot.file("0x6473720000000000000000000000000000000000000000000000000000000000", "1000000000627937192491029810");
await pot.drip();
await pot.join("100000000000000000000"); //100
await time.advanceTimeAndBlock(86400 * 365); // After 1 year
await pot.drip();
await pot.exit("100000000000000000000");
var gain = await pot.gains.call(accounts[0]);
console.log("gain: ", gain.toString()); //1999999999999999997283187900000000000000000000
await pot.resetgain();
//Note: My Dai has been exited all and gains is reset to 0;
//After some time....
//Note: If uncomment, the gain will be bigger.
// await time.advanceTimeAndBlock(86400 * 365);
await pot.drip();
await pot.join("100000000000000000000");
await time.advanceTimeAndBlock(86400 * 365); // After 1 year again
await pot.drip();
await pot.exit("100000000000000000000");
var gain = await pot.gains.call(accounts[0]);
console.log("gain: ", gain.toString()); //2039999999999999997174515400000000000000000000
});
});
from dss.
Related Issues (20)
- Debt Auctions Can Be Blocked HOT 8
- Jug.base does not conform to standard rate calculation HOT 13
- Clearer naming convention HOT 3
- Expose liquidation penalty as a public function HOT 1
- Wiki glossary: ambiguous usage of `collateral` notion in `flux` and `slip` HOT 3
- lack of tests for `rpow` (?) HOT 3
- Add ERC20-compatible Escape Hatch to Gem Join Contracts HOT 1
- add automated toolings to rename methods/variables, for instructional aids HOT 2
- liquidation 2.0: add bark's tip to tab (user debt)
- DAI seem to be stuck in contract HOT 1
- Oasis does not work when using MetaMask with local full node HOT 1
- Missing dai in dai stable coin adress
- Missing Dai in DAI stable coin
- Maximum acceptable price HOT 1
- HOW TO CREATE DAI WALLET HOT 1
- Bug in dai.sol?
- Hey old investor and holder with smart contracts helping and old project with security HOT 16
- lodash pollution
- elliticp (high) cryptographfic HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dss.