Skip to content

Commit 556ba2a

Browse files
committed
Migrate tests to use USDS and SKY
1 parent 6a5813a commit 556ba2a

File tree

4 files changed

+262
-241
lines changed

4 files changed

+262
-241
lines changed

test/FlapperUniV2.t.sol

Lines changed: 98 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ interface GemLike {
6262
function transfer(address, uint256) external;
6363
}
6464

65+
interface Univ2FactoryLike {
66+
function createPair(address, address) external returns (address);
67+
}
68+
6569
contract MockMedianizer {
6670
uint256 public price;
6771
mapping (address => uint256) public bud;
@@ -85,55 +89,62 @@ contract FlapperUniV2Test is DssTest {
8589

8690
SplitterMock public splitter;
8791
FlapperUniV2 public flapper;
88-
FlapperUniV2 public linkFlapper;
92+
FlapperUniV2 public imxFlapper;
8993
MockMedianizer public medianizer;
90-
MockMedianizer public linkMedianizer;
94+
MockMedianizer public imxMedianizer;
9195

92-
address DAI_JOIN;
96+
address USDS_JOIN;
9397
address SPOT;
94-
address DAI;
95-
address MKR;
98+
address USDS;
99+
address SKY;
96100
address USDC;
97-
address LINK;
98101
address PAUSE_PROXY;
99102
VatLike vat;
100103
VowLike vow;
104+
address UNIV2_USDS_IMX_PAIR;
101105

102106
address constant LOG = 0xdA0Ab1e0017DEbCd72Be8599041a2aa3bA7e740F;
103107

108+
address constant IMX = 0xF57e7e7C23978C3cAEC3C3548E3D615c346e79fF; // Random token that orders after USDS
104109
address constant UNIV2_FACTORY = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
105-
address constant UNIV2_DAI_MKR_PAIR = 0x517F9dD285e75b599234F7221227339478d0FcC8;
106-
address constant UNIV2_LINK_DAI_PAIR = 0x6D4fd456eDecA58Cf53A8b586cd50754547DBDB2;
110+
address constant UNIV2_SKY_USDS_PAIR = 0x2621CC0B3F3c079c1Db0E80794AA24976F0b9e3c;
107111

108112
event Exec(uint256 lot, uint256 sell, uint256 buy, uint256 liquidity);
109113

110114
function setUp() public {
111115
vm.createSelectFork(vm.envString("ETH_RPC_URL"));
112116

113-
DAI_JOIN = ChainlogLike(LOG).getAddress("MCD_JOIN_DAI");
117+
USDS_JOIN = ChainlogLike(LOG).getAddress("USDS_JOIN");
114118
SPOT = ChainlogLike(LOG).getAddress("MCD_SPOT");
115-
DAI = ChainlogLike(LOG).getAddress("MCD_DAI");
116-
MKR = ChainlogLike(LOG).getAddress("MCD_GOV");
119+
USDS = ChainlogLike(LOG).getAddress("USDS");
120+
SKY = ChainlogLike(LOG).getAddress("SKY");
117121
USDC = ChainlogLike(LOG).getAddress("USDC");
118-
LINK = ChainlogLike(LOG).getAddress("LINK");
119122
PAUSE_PROXY = ChainlogLike(LOG).getAddress("MCD_PAUSE_PROXY");
120123
vat = VatLike(ChainlogLike(LOG).getAddress("MCD_VAT"));
121124
vow = VowLike(ChainlogLike(LOG).getAddress("MCD_VOW"));
125+
126+
UNIV2_USDS_IMX_PAIR = Univ2FactoryLike(UNIV2_FACTORY).createPair(USDS, IMX);
122127

123-
splitter = new SplitterMock(DAI_JOIN);
128+
splitter = new SplitterMock(USDS_JOIN);
124129
vm.startPrank(PAUSE_PROXY);
125130
vow.file("hump", 50_000_000 * RAD);
126131
vow.file("bump", 5707 * RAD);
127132
vow.file("flapper", address(splitter));
128133
vm.stopPrank();
129134

130-
(flapper, medianizer) = setUpFlapper(MKR, UNIV2_DAI_MKR_PAIR, 727 * WAD, "MCD_FLAP") ;
131-
assertEq(flapper.usdsFirst(), true);
135+
{
136+
deal(IMX, UNIV2_USDS_IMX_PAIR, 200_000_0000 * WAD, true);
137+
deal(USDS, UNIV2_USDS_IMX_PAIR, 10_000_0000 * WAD, true);
138+
PairLike(UNIV2_USDS_IMX_PAIR).sync();
139+
}
140+
141+
(flapper, medianizer) = setUpFlapper(SKY, UNIV2_SKY_USDS_PAIR, 727 * WAD, "MCD_FLAP") ;
142+
assertEq(flapper.usdsFirst(), false);
132143

133-
(linkFlapper, linkMedianizer) = setUpFlapper(LINK, UNIV2_LINK_DAI_PAIR, 654 * WAD / 100, bytes32(0));
134-
assertEq(linkFlapper.usdsFirst(), false);
144+
(imxFlapper, imxMedianizer) = setUpFlapper(IMX, UNIV2_USDS_IMX_PAIR, 654 * WAD / 100, bytes32(0));
145+
assertEq(imxFlapper.usdsFirst(), true);
135146

136-
changeFlapper(address(flapper)); // Use MKR flapper by default
147+
changeFlapper(address(flapper)); // Use SKY flapper by default
137148

138149
// Create additional surplus if needed
139150
uint256 bumps = 2 * vow.bump(); // two kicks
@@ -160,7 +171,7 @@ contract FlapperUniV2Test is DssTest {
160171
deployer: address(this),
161172
owner: PAUSE_PROXY,
162173
spotter: SPOT,
163-
usds: DAI,
174+
usds: USDS,
164175
gem: gem,
165176
pair: pair,
166177
receiver: PAUSE_PROXY,
@@ -173,7 +184,7 @@ contract FlapperUniV2Test is DssTest {
173184
want: WAD * 97 / 100,
174185
pip: address(_medianizer),
175186
pair: pair,
176-
usds: DAI,
187+
usds: USDS,
177188
splitter: address(splitter),
178189
prevChainlogKey: prevChainlogKey,
179190
chainlogKey: "MCD_FLAP_LP"
@@ -190,18 +201,18 @@ contract FlapperUniV2Test is DssTest {
190201
}
191202

192203
// Add initial liquidity if needed
193-
(uint256 reserveDai, ) = UniswapV2Library.getReserves(UNIV2_FACTORY, DAI, gem);
194-
uint256 minimalDaiReserve = 280_000 * WAD;
195-
if (reserveDai < minimalDaiReserve) {
204+
(uint256 reserveUsds, ) = UniswapV2Library.getReserves(UNIV2_FACTORY, USDS, gem);
205+
uint256 minimalUsdsReserve = 280_000 * WAD;
206+
if (reserveUsds < minimalUsdsReserve) {
196207
_medianizer.setPrice(price);
197208
changeUniV2Price(price, gem, pair);
198-
(reserveDai, ) = UniswapV2Library.getReserves(UNIV2_FACTORY, DAI, gem);
199-
if(reserveDai < minimalDaiReserve) {
200-
topUpLiquidity(minimalDaiReserve - reserveDai, gem, pair);
209+
(reserveUsds, ) = UniswapV2Library.getReserves(UNIV2_FACTORY, USDS, gem);
210+
if(reserveUsds < minimalUsdsReserve) {
211+
topUpLiquidity(minimalUsdsReserve - reserveUsds, gem, pair);
201212
}
202213
} else {
203214
// If there is initial liquidity, then the oracle price should be set to the current price
204-
_medianizer.setPrice(uniV2DaiForGem(WAD, gem));
215+
_medianizer.setPrice(uniV2UsdsForGem(WAD, gem));
205216
}
206217
}
207218

@@ -213,37 +224,37 @@ contract FlapperUniV2Test is DssTest {
213224
return amountIn * WAD / (uint256(MockMedianizer(pip).read()) * RAY / SpotterLike(SPOT).par());
214225
}
215226

216-
function uniV2GemForDai(uint256 amountIn, address gem) internal view returns (uint256 amountOut) {
217-
(uint256 reserveDai, uint256 reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, DAI, gem);
218-
amountOut = UniswapV2Library.getAmountOut(amountIn, reserveDai, reserveGem);
227+
function uniV2GemForUsds(uint256 amountIn, address gem) internal view returns (uint256 amountOut) {
228+
(uint256 reserveUsds, uint256 reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, USDS, gem);
229+
amountOut = UniswapV2Library.getAmountOut(amountIn, reserveUsds, reserveGem);
219230
}
220231

221-
function uniV2DaiForGem(uint256 amountIn, address gem) internal view returns (uint256 amountOut) {
222-
(uint256 reserveDai, uint256 reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, DAI, gem);
223-
return UniswapV2Library.getAmountOut(amountIn, reserveGem, reserveDai);
232+
function uniV2UsdsForGem(uint256 amountIn, address gem) internal view returns (uint256 amountOut) {
233+
(uint256 reserveUsds, uint256 reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, USDS, gem);
234+
return UniswapV2Library.getAmountOut(amountIn, reserveGem, reserveUsds);
224235
}
225236

226-
function changeUniV2Price(uint256 daiForGem, address gem, address pair) internal {
227-
(uint256 reserveDai, uint256 reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, DAI, gem);
228-
uint256 currentDaiForGem = reserveDai * WAD / reserveGem;
237+
function changeUniV2Price(uint256 usdsForGem, address gem, address pair) internal {
238+
(uint256 reserveUsds, uint256 reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, USDS, gem);
239+
uint256 currentUsdsForGem = reserveUsds * WAD / reserveGem;
229240

230-
// neededReserveDai * WAD / neededReserveMkr = daiForGem;
231-
if (currentDaiForGem > daiForGem) {
232-
deal(gem, pair, reserveDai * WAD / daiForGem);
241+
// neededReserveUsds * WAD / neededReserveSky = usdsForGem;
242+
if (currentUsdsForGem > usdsForGem) {
243+
deal(gem, pair, reserveUsds * WAD / usdsForGem);
233244
} else {
234-
deal(DAI, pair, reserveGem * daiForGem / WAD);
245+
deal(USDS, pair, reserveGem * usdsForGem / WAD);
235246
}
236247
PairLike(pair).sync();
237248
}
238249

239-
function topUpLiquidity(uint256 daiAmt, address gem, address pair) internal {
240-
(uint256 reserveDai, uint256 reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, DAI, gem);
241-
uint256 gemAmt = UniswapV2Library.quote(daiAmt, reserveDai, reserveGem);
250+
function topUpLiquidity(uint256 usdsAmt, address gem, address pair) internal {
251+
(uint256 reserveUsds, uint256 reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, USDS, gem);
252+
uint256 gemAmt = UniswapV2Library.quote(usdsAmt, reserveUsds, reserveGem);
242253

243-
deal(DAI, address(this), GemLike(DAI).balanceOf(address(this)) + daiAmt);
254+
deal(USDS, address(this), GemLike(USDS).balanceOf(address(this)) + usdsAmt);
244255
deal(gem, address(this), GemLike(gem).balanceOf(address(this)) + gemAmt);
245256

246-
GemLike(DAI).transfer(pair, daiAmt);
257+
GemLike(USDS).transfer(pair, usdsAmt);
247258
GemLike(gem).transfer(pair, gemAmt);
248259
uint256 liquidity = PairLike(pair).mint(address(this));
249260
assertGt(liquidity, 0);
@@ -252,41 +263,41 @@ contract FlapperUniV2Test is DssTest {
252263

253264
function marginalWant(address gem, address pip) internal view returns (uint256) {
254265
uint256 wbump = vow.bump() / RAY;
255-
(uint256 reserveDai, ) = UniswapV2Library.getReserves(UNIV2_FACTORY, DAI, gem);
256-
uint256 sell = (Babylonian.sqrt(reserveDai * (wbump * 3_988_000 + reserveDai * 3_988_009)) - reserveDai * 1997) / 1994;
266+
(uint256 reserveUsds, ) = UniswapV2Library.getReserves(UNIV2_FACTORY, USDS, gem);
267+
uint256 sell = (Babylonian.sqrt(reserveUsds * (wbump * 3_988_000 + reserveUsds * 3_988_009)) - reserveUsds * 1997) / 1994;
257268

258-
uint256 actual = uniV2GemForDai(sell, gem);
269+
uint256 actual = uniV2GemForUsds(sell, gem);
259270
uint256 ref = refAmountOut(sell, pip);
260271
return actual * WAD / ref;
261272
}
262273

263274
function doExec(address _flapper, address gem, address pair) internal {
264275
uint256 initialLp = GemLike(pair).balanceOf(address(PAUSE_PROXY));
265276
uint256 initialDaiVow = vat.dai(address(vow));
266-
uint256 initialReserveDai = GemLike(DAI).balanceOf(pair);
267-
uint256 initialReserveMkr = GemLike(gem).balanceOf(pair);
277+
uint256 initialReserveUsds = GemLike(USDS).balanceOf(pair);
278+
uint256 initialReserveSky = GemLike(gem).balanceOf(pair);
268279

269280
vm.expectEmit(false, false, false, false); // only check event signature (topic 0)
270281
emit Exec(0, 0, 0, 0);
271282
vow.flap();
272283

273284
assertGt(GemLike(pair).balanceOf(address(PAUSE_PROXY)), initialLp);
274-
assertEq(GemLike(DAI).balanceOf(pair), initialReserveDai + vow.bump() / RAY);
275-
assertEq(GemLike(gem).balanceOf(pair), initialReserveMkr);
285+
assertEq(GemLike(USDS).balanceOf(pair), initialReserveUsds + vow.bump() / RAY);
286+
assertEq(GemLike(gem).balanceOf(pair), initialReserveSky);
276287
assertEq(initialDaiVow - vat.dai(address(vow)), vow.bump());
277-
assertEq(GemLike(DAI).balanceOf(address(_flapper)), 0);
288+
assertEq(GemLike(USDS).balanceOf(address(_flapper)), 0);
278289
assertEq(GemLike(gem).balanceOf(address(_flapper)), 0);
279290
}
280291

281292
function testDefaultValues() public {
282-
FlapperUniV2 f = new FlapperUniV2(DAI_JOIN, SPOT, MKR, UNIV2_DAI_MKR_PAIR, PAUSE_PROXY);
293+
FlapperUniV2 f = new FlapperUniV2(USDS_JOIN, SPOT, SKY, UNIV2_SKY_USDS_PAIR, PAUSE_PROXY);
283294
assertEq(f.want(), WAD);
284295
assertEq(f.wards(address(this)), 1);
285296
}
286297

287298
function testIllegalGemDecimals() public {
288299
vm.expectRevert("FlapperUniV2/gem-decimals-not-18");
289-
flapper = new FlapperUniV2(DAI_JOIN, SPOT, USDC, UNIV2_DAI_MKR_PAIR, PAUSE_PROXY);
300+
flapper = new FlapperUniV2(USDS_JOIN, SPOT, USDC, UNIV2_SKY_USDS_PAIR, PAUSE_PROXY);
290301
}
291302

292303
function testAuth() public {
@@ -310,89 +321,89 @@ contract FlapperUniV2Test is DssTest {
310321
}
311322

312323
function testExec() public {
313-
doExec(address(flapper), MKR, UNIV2_DAI_MKR_PAIR);
324+
doExec(address(flapper), SKY, UNIV2_SKY_USDS_PAIR);
314325
}
315326

316-
function testExecDaiSecond() public {
317-
changeFlapper(address(linkFlapper));
318-
doExec(address(linkFlapper), LINK, UNIV2_LINK_DAI_PAIR);
327+
function testExecUsdsFirst() public {
328+
changeFlapper(address(imxFlapper));
329+
doExec(address(imxFlapper), IMX, UNIV2_USDS_IMX_PAIR);
319330
}
320331

321332
function testExecWantAllows() public {
322-
uint256 _marginalWant = marginalWant(MKR, address(medianizer));
333+
uint256 _marginalWant = marginalWant(SKY, address(medianizer));
323334
vm.prank(PAUSE_PROXY); flapper.file("want", _marginalWant * 99 / 100);
324-
doExec(address(flapper), MKR, UNIV2_DAI_MKR_PAIR);
335+
doExec(address(flapper), SKY, UNIV2_SKY_USDS_PAIR);
325336
}
326337

327338
function testExecWantBlocks() public {
328-
uint256 _marginalWant = marginalWant(MKR, address(medianizer));
339+
uint256 _marginalWant = marginalWant(SKY, address(medianizer));
329340
vm.prank(PAUSE_PROXY); flapper.file("want", _marginalWant * 101 / 100);
330341
vm.expectRevert("FlapperUniV2/insufficient-buy-amount");
331342
vow.flap();
332343
}
333344

334-
function testExecDaiSecondWantBlocks() public {
335-
changeFlapper(address(linkFlapper));
336-
uint256 _marginalWant = marginalWant(LINK, address(linkMedianizer));
337-
vm.prank(PAUSE_PROXY); linkFlapper.file("want", _marginalWant * 101 / 100);
345+
function testExecUsdsFirstWantBlocks() public {
346+
changeFlapper(address(imxFlapper));
347+
uint256 _marginalWant = marginalWant(IMX, address(imxMedianizer));
348+
vm.prank(PAUSE_PROXY); imxFlapper.file("want", _marginalWant * 101 / 100);
338349
vm.expectRevert("FlapperUniV2/insufficient-buy-amount");
339350
vow.flap();
340351
}
341352

342-
function testExecDonationDai() public {
343-
deal(DAI, UNIV2_DAI_MKR_PAIR, GemLike(DAI).balanceOf(UNIV2_DAI_MKR_PAIR) * 1005 / 1000);
353+
function testExecDonationUsds() public {
354+
deal(USDS, UNIV2_SKY_USDS_PAIR, GemLike(USDS).balanceOf(UNIV2_SKY_USDS_PAIR) * 1005 / 1000);
344355
// This will now sync the reserves before the swap
345-
doExec(address(flapper), MKR, UNIV2_DAI_MKR_PAIR);
356+
doExec(address(flapper), SKY, UNIV2_SKY_USDS_PAIR);
346357
}
347358

348359
function testExecDonationGem() public {
349-
deal(MKR, UNIV2_DAI_MKR_PAIR, GemLike(MKR).balanceOf(UNIV2_DAI_MKR_PAIR) * 1005 / 1000);
360+
deal(SKY, UNIV2_SKY_USDS_PAIR, GemLike(SKY).balanceOf(UNIV2_SKY_USDS_PAIR) * 1005 / 1000);
350361
// This will now sync the reserves before the swap
351-
doExec(address(flapper), MKR, UNIV2_DAI_MKR_PAIR);
362+
doExec(address(flapper), SKY, UNIV2_SKY_USDS_PAIR);
352363
}
353364

354365
// A shortened version of the sell and deposit flapper that sells `lot`.
355366
// Based on: https://github.com/makerdao/dss-flappers/blob/da7b6b70e7cfe3631f8af695bbe0c79db90e2a20/src/FlapperUniV2.sol
356367
function sellLotAndDeposit(PairLike pair, address gem, bool usdsFirst, address receiver, uint256 lot) internal {
357368
// Get Amounts
358-
(uint256 _reserveDai, uint256 _reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, DAI, gem);
369+
(uint256 _reserveUsds, uint256 _reserveGem) = UniswapV2Library.getReserves(UNIV2_FACTORY, USDS, gem);
359370
uint256 _wlot = lot / RAY;
360-
uint256 _total = _wlot * (997 * _wlot + 1997 * _reserveDai) / (1000 * _reserveDai);
361-
uint256 _buy = _wlot * 997 * _reserveGem / (_reserveDai * 1000 + _wlot * 997);
371+
uint256 _total = _wlot * (997 * _wlot + 1997 * _reserveUsds) / (1000 * _reserveUsds);
372+
uint256 _buy = _wlot * 997 * _reserveGem / (_reserveUsds * 1000 + _wlot * 997);
362373

363374
// Swap
364-
GemLike(DAI).transfer(address(pair), _wlot);
375+
GemLike(USDS).transfer(address(pair), _wlot);
365376
(uint256 _amt0Out, uint256 _amt1Out) = usdsFirst ? (uint256(0), _buy) : (_buy, uint256(0));
366377
pair.swap(_amt0Out, _amt1Out, address(this), new bytes(0));
367378

368379
// Deposit
369-
GemLike(DAI).transfer(address(pair), _total - _wlot);
380+
GemLike(USDS).transfer(address(pair), _total - _wlot);
370381
GemLike(gem).transfer(address(pair), _buy);
371382
pair.mint(receiver);
372383
}
373384

374385
function testEquivalenceToSellLotAndDeposit() public {
375-
deal(DAI, address(this), vow.bump() * 3); // certainly enough for the sell and deposit
376-
GemLike(DAI).approve(UNIV2_DAI_MKR_PAIR, vow.bump() * 3);
386+
deal(USDS, address(this), vow.bump() * 3); // certainly enough for the sell and deposit
387+
GemLike(USDS).approve(UNIV2_SKY_USDS_PAIR, vow.bump() * 3);
377388

378-
uint256 initialDai = GemLike(DAI).balanceOf(address(this));
379-
uint256 initialLp = GemLike(UNIV2_DAI_MKR_PAIR).balanceOf(PAUSE_PROXY);
389+
uint256 initialUsds = GemLike(USDS).balanceOf(address(this));
390+
uint256 initialLp = GemLike(UNIV2_SKY_USDS_PAIR).balanceOf(PAUSE_PROXY);
380391

381392
uint256 initialState = vm.snapshot();
382393

383394
// Old version
384-
sellLotAndDeposit(PairLike(UNIV2_DAI_MKR_PAIR), MKR, true, PAUSE_PROXY, vow.bump());
385-
uint256 totalDaiConsumed = initialDai - GemLike(DAI).balanceOf(address(this));
386-
uint256 boughtLpOldVersion = GemLike(UNIV2_DAI_MKR_PAIR).balanceOf(PAUSE_PROXY) - initialLp;
395+
sellLotAndDeposit(PairLike(UNIV2_SKY_USDS_PAIR), SKY, false, PAUSE_PROXY, vow.bump());
396+
uint256 totalUsdsConsumed = initialUsds - GemLike(USDS).balanceOf(address(this));
397+
uint256 boughtLpOldVersion = GemLike(UNIV2_SKY_USDS_PAIR).balanceOf(PAUSE_PROXY) - initialLp;
387398

388399
vm.revertTo(initialState);
389400

390401
// New version
391-
vm.prank(PAUSE_PROXY); vow.file("bump", totalDaiConsumed * RAY); // The current flapper gets the total vat.dai to consume.
392-
doExec(address(flapper), MKR, UNIV2_DAI_MKR_PAIR);
393-
uint256 boughtLpNewVersion = GemLike(UNIV2_DAI_MKR_PAIR).balanceOf(PAUSE_PROXY) - initialLp;
402+
vm.prank(PAUSE_PROXY); vow.file("bump", totalUsdsConsumed * RAY); // The current flapper gets the total vat.Usds to consume.
403+
doExec(address(flapper), SKY, UNIV2_SKY_USDS_PAIR);
404+
uint256 boughtLpNewVersion = GemLike(UNIV2_SKY_USDS_PAIR).balanceOf(PAUSE_PROXY) - initialLp;
394405

395406
// Compare results for both versions
396-
assertEq(boughtLpNewVersion, boughtLpOldVersion);
407+
assertApproxEqAbs(boughtLpNewVersion, boughtLpOldVersion, 10);
397408
}
398409
}

0 commit comments

Comments
 (0)