Skip to content

Commit

Permalink
Exit dai to flapper
Browse files Browse the repository at this point in the history
  • Loading branch information
telome committed Jan 17, 2024
1 parent 839fbb6 commit 11bcd6e
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 52 deletions.
14 changes: 4 additions & 10 deletions src/FlapperUniV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ contract FlapperUniV2 {
// (2) (lot - sell) / bought = (reserveDai + sell) / (reserveGem - bought)
//
// The solution for the these equations for variables `sell` and `bought` is used below.
function _getDaiToSell(uint256 wlot, uint256 reserveDai) internal pure returns (uint256 sell) {
sell = (Babylonian.sqrt(reserveDai * (wlot * 3988000 + reserveDai * 3988009)) - reserveDai * 1997) / 1994;
function _getDaiToSell(uint256 lot, uint256 reserveDai) internal pure returns (uint256 sell) {
sell = (Babylonian.sqrt(reserveDai * (lot * 3988000 + reserveDai * 3988009)) - reserveDai * 1997) / 1994;
}

// Based on: https://github.com/Uniswap/v2-periphery/blob/0335e8f7e1bd1e8d8329fd300aea2ef2f36dd19f/contracts/libraries/UniswapV2Library.sol#L43
Expand All @@ -165,26 +165,20 @@ contract FlapperUniV2 {
// Check Amounts
(uint256 _reserveDai, uint256 _reserveGem) = _getReserves();

uint256 _wlot = lot / RAY;
uint256 _sell = _getDaiToSell(_wlot, _reserveDai);
uint256 _sell = _getDaiToSell(lot, _reserveDai);

uint256 _buy = _getAmountOut(_sell, _reserveDai, _reserveGem);
require(_buy >= _sell * want / (uint256(pip.read()) * RAY / spotter.par()), "FlapperUniV2/insufficient-buy-amount");
//

// Get Dai
vat.move(msg.sender, address(this), _wlot * RAY);
daiJoin.exit(address(this), _wlot);
//

// Swap
GemLike(dai).transfer(address(pair), _sell);
(uint256 _amt0Out, uint256 _amt1Out) = daiFirst ? (uint256(0), _buy) : (_buy, uint256(0));
pair.swap(_amt0Out, _amt1Out, address(this), new bytes(0));
//

// Deposit
GemLike(dai).transfer(address(pair), _wlot - _sell);
GemLike(dai).transfer(address(pair), lot - _sell);
GemLike(gem).transfer(address(pair), _buy);
uint256 _liquidity = pair.mint(receiver);
//
Expand Down
12 changes: 5 additions & 7 deletions src/FlapperUniV2SwapOnly.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface SpotterLike {

interface GemLike {
function decimals() external view returns (uint8);
function transfer(address, uint256) external;
}

interface PipLike {
Expand Down Expand Up @@ -141,15 +142,12 @@ contract FlapperUniV2SwapOnly {
// Check Amount to buy
(uint256 _reserveDai, uint256 _reserveGem) = _getReserves();

uint256 _wlot = lot / RAY;

uint256 _buy = _getAmountOut(_wlot, _reserveDai, _reserveGem);
require(_buy >= _wlot * want / (uint256(pip.read()) * RAY / spotter.par()), "FlapperUniV2SwapOnly/insufficient-buy-amount");
uint256 _buy = _getAmountOut(lot, _reserveDai, _reserveGem);
require(_buy >= lot * want / (uint256(pip.read()) * RAY / spotter.par()), "FlapperUniV2SwapOnly/insufficient-buy-amount");
//

// Get Dai and swap
vat.move(msg.sender, address(this), _wlot * RAY);
daiJoin.exit(address(pair), _wlot);
// Swap
GemLike(dai).transfer(address(pair), lot);
(uint256 _amt0Out, uint256 _amt1Out) = daiFirst ? (uint256(0), _buy) : (_buy, uint256(0));
pair.swap(_amt0Out, _amt1Out, receiver, new bytes(0));
//
Expand Down
13 changes: 5 additions & 8 deletions src/Splitter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ contract Splitter {
_;
}

uint256 internal constant WAD = 10 ** 18;
uint256 internal constant RAY = 10 ** 27;
uint256 internal constant RAD = 10 ** 45;

function rely(address usr) external auth { wards[usr] = 1; emit Rely(usr); }
function deny(address usr) external auth { wards[usr] = 0; emit Deny(usr); }
Expand All @@ -88,11 +88,7 @@ contract Splitter {
}

function file(bytes32 what, address data) external auth {
if (what == "flapper") {
vat.nope(address(flapper));
flapper = FlapLike(data);
vat.hope(data);
}
if (what == "flapper") flapper = FlapLike(data);
else revert("Splitter/file-unrecognized-param");
emit File(what, data);
}
Expand All @@ -103,12 +99,13 @@ contract Splitter {

vat.move(msg.sender, address(this), tot);

uint256 lot = tot * burn / WAD;
uint256 lot = tot * burn / RAD;
if (lot > 0) {
DaiJoinLike(daiJoin).exit(address(flapper), lot);
flapper.exec(lot);
}

uint256 pay = (tot - lot) / RAY;
uint256 pay = (tot / RAY - lot);
if (pay > 0) {
DaiJoinLike(daiJoin).exit(address(farm), pay);
farm.notifyRewardAmount(pay);
Expand Down
2 changes: 1 addition & 1 deletion test/FlapperUniV2.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ contract FlapperUniV2Test is DssTest {
end = EndLike(ChainlogLike(LOG).getAddress("MCD_END"));
spotter = SpotterLike(ChainlogLike(LOG).getAddress("MCD_SPOT"));

splitter = new SplitterMock(address(vat));
splitter = new SplitterMock(DAI_JOIN);
vm.startPrank(PAUSE_PROXY);
vow.file("hump", 50_000_000 * RAD);
vow.file("bump", 5707 * RAD);
Expand Down
2 changes: 1 addition & 1 deletion test/FlapperUniV2SwapOnly.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ contract FlapperUniV2SwapOnlyTest is DssTest {
end = EndLike(ChainlogLike(LOG).getAddress("MCD_END"));
spotter = SpotterLike(ChainlogLike(LOG).getAddress("MCD_SPOT"));

splitter = new SplitterMock(address(vat));
splitter = new SplitterMock(DAI_JOIN);
vm.startPrank(PAUSE_PROXY);
vow.file("hump", 50_000_000 * RAD);
vow.file("bump", 5707 * RAD);
Expand Down
16 changes: 1 addition & 15 deletions test/Splitter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ contract SplitterTest is DssTest {
uint256 prevLastUpdateTime = farm.lastUpdateTime();

vm.expectEmit(false, false, false, true);
emit Kick(vow.bump(), vow.bump() * splitter.burn() / WAD, farmReward);
emit Kick(vow.bump(), vow.bump() * splitter.burn() / RAD, farmReward);
vow.flap();

assertEq(vat.dai(address(vow)), initialVowVatDai - vow.bump());
Expand Down Expand Up @@ -319,20 +319,6 @@ contract SplitterTest is DssTest {
checkFileAddress(address(splitter), "Splitter", ["flapper"]);
}

function testVatCanAfterFile() public {
assertEq(vat.can(address(splitter), address(0xf1)), 0);

vm.prank(PAUSE_PROXY); splitter.file("flapper", address(0xf1));

assertEq(vat.can(address(splitter), address(0xf1)), 1);
assertEq(vat.can(address(splitter), address(0xf2)), 0);

vm.prank(PAUSE_PROXY); splitter.file("flapper", address(0xf2));

assertEq(vat.can(address(splitter), address(0xf1)), 0);
assertEq(vat.can(address(splitter), address(0xf2)), 1);
}

function testKick() public {
doKick();
}
Expand Down
30 changes: 20 additions & 10 deletions test/mocks/SplitterMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,43 @@ interface VatLike {
function nope(address) external;
}

interface DaiJoinLike {
function vat() external view returns (address);
function exit(address, uint256) external;
}

interface FlapLike {
function exec(uint256) external;
function cage() external;
}

contract SplitterMock {
FlapLike public flapper;

VatLike public immutable vat;
DaiJoinLike public immutable daiJoin;

constructor(
address _vat
address _daiJoin
) {
vat = VatLike(_vat);
daiJoin = DaiJoinLike(_daiJoin);
vat = VatLike(daiJoin.vat());

vat.hope(_daiJoin);
}

FlapLike public flapper;
VatLike public immutable vat;
uint256 internal constant RAY = 10 ** 27;

function file(bytes32 what, address data) external {
if (what == "flapper") {
vat.nope(address(flapper));
flapper = FlapLike(data);
vat.hope(data);
}
if (what == "flapper") flapper = FlapLike(data);
else revert("SplitterMock/file-unrecognized-param");
}

function kick(uint256 tot, uint256) external returns (uint256) {
vat.move(msg.sender, address(this), tot);
flapper.exec(tot);
uint256 lot = tot / RAY;
DaiJoinLike(daiJoin).exit(address(flapper), lot);
flapper.exec(lot);
return 0;
}

Expand Down

0 comments on commit 11bcd6e

Please sign in to comment.