Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mip fix #4

Open
wants to merge 7 commits into
base: mip
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 125 additions & 33 deletions src/blip.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@

pragma solidity >=0.6.12;

import "./org/clip.sol";
interface VatLike {
function move(address,address,uint256) external;
function flux(bytes32,address,address,uint256) external;
function ilks(bytes32) external returns (uint256, uint256, uint256, uint256, uint256);
function suck(address,address,uint256) external;
}

interface DogLike {
function chop(bytes32) external returns (uint256);
function digs(bytes32, uint256) external;
}

interface OracleLike {
function read() external returns (bytes32);
Expand All @@ -12,46 +22,117 @@ interface BProtocolLike {
function prep(bytes32 ilk, uint256 amt, uint256 owe, uint256 mid) external;
}

interface ClipperLike {
function dog() external view returns(DogLike);
function vow() external view returns(address);
function chip() external view returns(uint64);
function tip() external view returns(uint192);
function stopped() external view returns(uint256);

function kick(
uint256 tab,
uint256 lot,
address usr,
address kpr
) external returns (uint256 id);
}


contract Blipper {
// --- Auth ---
mapping (address => uint256) public wards;
function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
modifier auth {
require(wards[msg.sender] == 1, "Blipper/not-authorized");
_;
}

// --- Clipper Data ---
bytes32 immutable public ilk; // Collateral type of this Clipper
VatLike immutable public vat; // Core CDP Engine
DogLike public dog; // Liquidation module
address public vow; // Recipient of dai raised in auctions
uint64 public chip; // Percentage of tab to suck from vow to incentivize keepers [wad]
uint192 public tip; // Flat fee to suck from vow to incentivize keepers [rad]

contract Blipper is Clipper {
// --- B.Protocol Data ---
address public clipper;
address public bprotocol;
uint256 public bee; // b.protocol discount
address public oracle;

// --- Events ---
event Rely(address indexed usr);
event Deny(address indexed usr);

event File(bytes32 indexed what, uint256 data);
event File(bytes32 indexed what, address data);

event Blip(
uint256 tab,
uint256 lot,
address usr,
address kpr,
uint256 amt,
uint256 owe
);

// --- Init ---
constructor(address vat_, address spotter_, address dog_, bytes32 ilk_, address oracle_) public
Clipper(vat_, spotter_, dog_, ilk_)
{
constructor(address vat_, bytes32 ilk_, address oracle_) public
{
vat = VatLike(vat_);
ilk = ilk_;
oracle = oracle_;

wards[msg.sender] = 1;
emit Rely(msg.sender);
}

// --- Administration ---
function file(bytes32 what, uint256 data) public override auth lock {
if (what == "bee") {
bee = data;
File(what, data);
}
else {
locked = 0;
super.file(what, data);
}
function file(bytes32 what, uint256 data) external auth {
if (what == "bee") bee = data;
else revert("Blipper/file-unrecognized-param");

emit File(what, data);
}

function file(bytes32 what, address data) public override auth lock {
if (what == "bprotocol") {
bprotocol = data;
File(what, data);
}
else if(what == "oracle") {
oracle = data;
File(what, data);
}
else {
locked = 0;
super.file(what, data);
}
function file(bytes32 what, address data) external auth {
if (what == "bprotocol") bprotocol = data;
else if(what == "oracle") oracle = data;
else if(what == "clipper") clipper = data;

else revert("Blipper/file-unrecognized-param");

emit File(what, data);
}

// --- Math ---
uint256 constant BLN = 10 ** 9;
uint256 constant WAD = 10 ** 18;
uint256 constant RAY = 10 ** 27;

function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x <= y ? x : y;
}
function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x + y) >= x);
}
function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
require((z = x - y) <= x);
}
function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(y == 0 || (z = x * y) / y == x);
}
function wmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, y) / WAD;
}
function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, y) / RAY;
}
function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = mul(x, RAY) / y;
}

// get the price directly from the OSM
// Could get this from rmul(Vat.ilks(ilk).spot, Spotter.mat()) instead, but
Expand All @@ -72,7 +153,7 @@ contract Blipper is Clipper {
uint256 ask = rmul(tab, WAD) / rdiv(mid, bee);

// how much dai to get for the entire collateral
uint256 bid = mul(wmul(lot, rmul(mid, bee)), RAY);
uint256 bid = mul(mul(lot, BLN), rdiv(mid, bee));

if(ask <= lot) {
amt = ask;
Expand Down Expand Up @@ -110,12 +191,23 @@ contract Blipper is Clipper {
uint256 lot, // Collateral [wad]
address usr, // Address that will receive any leftover collateral
address kpr // Address that will receive incentives
) public auth lock isStopped(1) override returns (uint256 id) {
try this.blink(lot, tab, usr, kpr) returns(uint256 /*amt*/, uint256 /*owe*/) {
// TODO - emit events
) public auth returns (uint256 id) {
require(ClipperLike(clipper).stopped() < 1, "Blipper/stopped-incorrect");

try this.blink(lot, tab, usr, kpr) returns(uint256 amt, uint256 owe) {
emit Blip(tab, lot, usr, kpr, amt, owe);
return 0;
} catch {
locked = 0;
return super.kick(tab, lot, usr, kpr);
vat.flux(ilk, address(this), clipper, lot);
return ClipperLike(clipper).kick(tab, lot, usr, kpr);
}
}

// Public function to update the cached clipper params.
function upparams() public {
dog = ClipperLike(clipper).dog();
vow = ClipperLike(clipper).vow();
chip = ClipperLike(clipper).chip();
tip = ClipperLike(clipper).tip();
}
}
33 changes: 24 additions & 9 deletions src/blip.t.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma solidity >=0.6.12;

import { DssDeployTestBase, Vat } from "dss-deploy/DssDeploy.t.base.sol";
import { DssDeployTestBase, Vat, Clipper } from "dss-deploy/DssDeploy.t.base.sol";
import { Blipper } from "./blip.sol";
import { BAMMJoin } from "./bammJoin.sol";
import { CToken } from "./mock/ctoken.sol";
Expand All @@ -9,6 +9,7 @@ import { DSToken } from "ds-token/token.sol";
contract BammJoinTest is DssDeployTestBase {
BAMMJoin bamm;
Blipper blipper;
Clipper clipper;

function setUp() override public {
super.setUp();
Expand All @@ -19,19 +20,25 @@ contract BammJoinTest is DssDeployTestBase {

assertEq(uint(1), dog.wards(address(this)));

blipper = new Blipper(address(vat), address(spotter), address(dog), "ETH", address(pipETH));
clipper = new Clipper(address(vat), address(spotter), address(dog), "ETH");

blipper = new Blipper(address(vat), "ETH", address(pipETH));
dog.file("ETH", "clip", address(blipper));
dog.file("Hole", 10000000e45);
dog.file("ETH", "hole", 10000000e45);
dog.file("ETH", "chop", 113e16);

blipper.file("vow", address(vow));
blipper.file("buf", 2e27);
blipper.file("tip", 1e27);
clipper.file("vow", address(vow));
clipper.file("buf", 2e27);
clipper.file("tip", 1e27);
clipper.upchost();

this.rely(address(vat), address(blipper));
this.rely(address(vat), address(clipper));
this.rely(address(dog), address(blipper));
blipper.rely(address(dog));
clipper.rely(address(blipper));
assertEq(uint(1), clipper.wards(address(blipper)));

weth.mint(1e30);
weth.approve(address(ethJoin), uint(-1));
Expand All @@ -57,7 +64,12 @@ contract BammJoinTest is DssDeployTestBase {
address(0xc),
address(new DSToken("comp")));
blipper.file("bprotocol", address(bamm));
blipper.file("bee", 105e25); // 5% premium

blipper.file("bee", 105e25); /* 5% premium */
blipper.file("clipper", address(clipper));
blipper.upparams();

assertEq(blipper.clipper(), address(clipper));

vat.suck(address(0x5), address(this), 1000000 ether * 1e27);
assertEq(vat.dai(address(this)), 1010000 ether * 1e27);
Expand Down Expand Up @@ -111,7 +123,8 @@ contract BammJoinTest is DssDeployTestBase {
assertEq(vat.gem("ETH", address(bamm)), expectedEth, "gem balance low ink");
assertEq(vat.dai(address(0x123)), 1e27);

uint daiDebt = uint(100 ether * 110 * 105) / 100;
// 100 ether to dai with 5% premium
uint daiDebt = 100 * (uint(100 ether * 110) / 105);
assertEq(vat.dai(address(vow)), daiDebt * 1e27);
assertEq(dog.Dirt(), 0);
(,,,uint dirt) = dog.ilks("ETH");
Expand All @@ -124,9 +137,9 @@ contract BammJoinTest is DssDeployTestBase {
spotter.poke("ETH");
pipETH.poke(bytes32(uint(9 * 1e18)));

uint kickBefore = blipper.kicks();
uint kickBefore = clipper.kicks();
dog.bark("ETH", address(this), address(0x123));
uint kickAfter = blipper.kicks();
uint kickAfter = clipper.kicks();

assertEq(kickBefore + 1, kickAfter, "testBarkWithClipper: expected auction to start");
assertEq(vat.dai(address(0x123)), 1e27);
Expand All @@ -136,6 +149,8 @@ contract BammJoinTest is DssDeployTestBase {
assertEq(dog.Dirt(), daiDebt * 1e27);
(,,,uint dirt) = dog.ilks("ETH");
assertEq(dirt, daiDebt * 1e27);

assertEq(vat.gem("ETH", address(clipper)), 100 ether);
}
}

Expand Down
Loading