@@ -26,7 +26,7 @@ interface GemLike {
26
26
function approve (address , uint256 ) external returns (bool );
27
27
}
28
28
29
- interface DaiLike is GemLike {
29
+ interface ERC20Like is GemLike {
30
30
function balanceOf (address ) external returns (uint256 );
31
31
}
32
32
@@ -92,15 +92,17 @@ contract DssVestTest is DSTest {
92
92
93
93
DssVestMintable mVest;
94
94
DssVestSuckable sVest;
95
+ DssVestSuckable sVestUsds;
95
96
DssVestTransferrable tVest;
96
97
Manager boss;
97
98
98
99
ChainlogLike chainlog;
99
100
DSTokenLike gem;
100
101
MkrAuthorityLike authority;
101
102
VatLike vat;
102
- DaiLike dai;
103
+ ERC20Like dai;
103
104
JoinLike daiJoin;
105
+ ERC20Like usds;
104
106
JoinLike usdsJoin;
105
107
EndLike end;
106
108
@@ -113,16 +115,19 @@ contract DssVestTest is DSTest {
113
115
gem = DSTokenLike ( chainlog.getAddress ("MCD_GOV " ));
114
116
authority = MkrAuthorityLike ( chainlog.getAddress ("GOV_GUARD " ));
115
117
vat = VatLike ( chainlog.getAddress ("MCD_VAT " ));
116
- dai = DaiLike ( chainlog.getAddress ("MCD_DAI " ));
118
+ dai = ERC20Like ( chainlog.getAddress ("MCD_DAI " ));
117
119
daiJoin = JoinLike ( chainlog.getAddress ("MCD_JOIN_DAI " ));
120
+ usds = ERC20Like ( chainlog.getAddress ("USDS " ));
118
121
usdsJoin = JoinLike ( chainlog.getAddress ("USDS_JOIN " ));
119
122
end = EndLike ( chainlog.getAddress ("MCD_END " ));
120
123
VOW = chainlog.getAddress ("MCD_VOW " );
121
124
122
125
mVest = new DssVestMintable (address (gem));
123
126
mVest.file ("cap " , (2000 * WAD) / (4 * 365 days));
124
- sVest = new DssVestSuckable (address (chainlog), address (usdsJoin ));
127
+ sVest = new DssVestSuckable (address (chainlog), address (daiJoin ));
125
128
sVest.file ("cap " , (2000 * WAD) / (4 * 365 days));
129
+ sVestUsds = new DssVestSuckable (address (chainlog), address (usdsJoin));
130
+ sVestUsds.file ("cap " , (2000 * WAD) / (4 * 365 days));
126
131
boss = new Manager ();
127
132
tVest = new DssVestTransferrable (address (boss), address (dai));
128
133
tVest.file ("cap " , (2000 * WAD) / (4 * 365 days));
@@ -145,13 +150,28 @@ contract DssVestTest is DSTest {
145
150
);
146
151
assertEq (vat.wards (address (sVest)), 1 );
147
152
153
+ hevm.store (
154
+ address (vat),
155
+ keccak256 (abi.encode (address (sVestUsds), uint256 (0 ))),
156
+ bytes32 (uint256 (1 ))
157
+ );
158
+ assertEq (vat.wards (address (sVestUsds)), 1 );
159
+
148
160
// Give boss 10000 DAI
149
161
hevm.store (
150
162
address (dai),
151
163
keccak256 (abi.encode (address (boss), uint (2 ))),
152
164
bytes32 (uint256 (10000 * WAD))
153
165
);
154
166
assertEq (dai.balanceOf (address (boss)), 10000 * WAD);
167
+
168
+ // Give boss 10000 USDS
169
+ hevm.store (
170
+ address (usds),
171
+ keccak256 (abi.encode (address (boss), uint (2 ))),
172
+ bytes32 (uint256 (10000 * WAD))
173
+ );
174
+ assertEq (usds.balanceOf (address (boss)), 10000 * WAD, "Failed to check usds balance " );
155
175
}
156
176
157
177
function testCost () public {
@@ -290,34 +310,34 @@ contract DssVestTest is DSTest {
290
310
291
311
function testAccrued () public {
292
312
uint256 id = mVest.create (address (this ), 100 * days_vest, block .timestamp + 10 days, 100 days, 0 , address (0 ));
293
- assertTrue (mVest.valid (id));
313
+ assertTrue (mVest.valid (id), " 0 " );
294
314
295
- assertEq (mVest.accrued (id), 0 );
315
+ assertEq (mVest.accrued (id), 0 , " 1 " );
296
316
hevm.warp (block .timestamp + 43200 );
297
- assertEq (mVest.unpaid (id), 0 ); // inside cliff
298
- assertEq (mVest.accrued (id), 0 );
317
+ assertEq (mVest.unpaid (id), 0 , " 2 " ); // inside cliff
318
+ assertEq (mVest.accrued (id), 0 , " 3 " );
299
319
hevm.warp (block .timestamp + 12 hours + 11 days);
300
- assertEq (mVest.unpaid (id), days_vest * 2 ); // past cliff
301
- assertEq (mVest.accrued (id), days_vest * 2 );
320
+ assertEq (mVest.unpaid (id), days_vest * 2 , " 3.1 " ); // past cliff
321
+ assertEq (mVest.accrued (id), days_vest * 2 , " 4 " );
302
322
hevm.warp (block .timestamp + 2 days);
303
- assertEq (mVest.unpaid (id), days_vest * 4 ); // past cliff
304
- assertEq (mVest.accrued (id), days_vest * 4 );
323
+ assertEq (mVest.unpaid (id), days_vest * 4 , " 5 " ); // past cliff
324
+ assertEq (mVest.accrued (id), days_vest * 4 , " 6 " );
305
325
mVest.vest (id);
306
- assertEq (mVest.unpaid (id), 0 );
307
- assertEq (mVest.accrued (id), days_vest * 4 );
308
- assertEq (gem.balanceOf (address (this )), days_vest * 4 );
326
+ assertEq (mVest.unpaid (id), 0 , " 7 " );
327
+ assertEq (mVest.accrued (id), days_vest * 4 , " 8 " );
328
+ assertEq (gem.balanceOf (address (this )), days_vest * 4 , " 9 " );
309
329
hevm.warp (block .timestamp + 10 days);
310
- assertEq (mVest.unpaid (id), days_vest * 10 );
311
- assertEq (mVest.accrued (id), days_vest * 14 );
330
+ assertEq (mVest.unpaid (id), days_vest * 10 , " 10 " );
331
+ assertEq (mVest.accrued (id), days_vest * 14 , " 11 " );
312
332
mVest.vest (id);
313
- assertEq (mVest.unpaid (id), 0 );
314
- assertEq (mVest.accrued (id), days_vest * 14 );
315
- assertEq (gem.balanceOf (address (this )), days_vest * 14 );
333
+ assertEq (mVest.unpaid (id), 0 , " 12 " );
334
+ assertEq (mVest.accrued (id), days_vest * 14 , " 13 " );
335
+ assertEq (gem.balanceOf (address (this )), days_vest * 14 , " 14 " );
316
336
hevm.warp (block .timestamp + 120 days); // vesting complete
317
- assertEq (mVest.unpaid (id), days_vest * 86 );
318
- assertEq (mVest.accrued (id), days_vest * 100 );
337
+ assertEq (mVest.unpaid (id), days_vest * 86 , " 15 " );
338
+ assertEq (mVest.accrued (id), days_vest * 100 , " 16 " );
319
339
mVest.vest (id);
320
- assertEq (gem.balanceOf (address (this )), 100 * days_vest);
340
+ assertEq (gem.balanceOf (address (this )), 100 * days_vest, " 17 " );
321
341
}
322
342
323
343
function testFutureAccrual () public {
@@ -676,6 +696,24 @@ contract DssVestTest is DSTest {
676
696
assertEq (vat.sin (VOW), originalSin + 100 * days_vest * RAY);
677
697
}
678
698
699
+ function testSuckableVestUsds () public {
700
+ uint256 originalSin = vat.sin (VOW);
701
+ uint256 id = sVestUsds.create (address (this ), 100 * days_vest, block .timestamp , 100 days, 0 , address (0 ));
702
+ assertTrue (sVestUsds.valid (id));
703
+ hevm.warp (block .timestamp + 1 days);
704
+ sVestUsds.vest (id);
705
+ assertEq (usds.balanceOf (address (this )), 1 * days_vest);
706
+ assertEq (vat.sin (VOW), originalSin + 1 * days_vest * RAY);
707
+ hevm.warp (block .timestamp + 9 days);
708
+ sVestUsds.vest (id);
709
+ assertEq (usds.balanceOf (address (this )), 10 * days_vest);
710
+ assertEq (vat.sin (VOW), originalSin + 10 * days_vest * RAY);
711
+ hevm.warp (block .timestamp + 365 days);
712
+ sVestUsds.vest (id);
713
+ assertEq (usds.balanceOf (address (this )), 100 * days_vest);
714
+ assertEq (vat.sin (VOW), originalSin + 100 * days_vest * RAY);
715
+ }
716
+
679
717
function testSuckableVestCaged () public {
680
718
uint256 originalSin = vat.sin (VOW);
681
719
uint256 id = sVest.create (address (this ), 100 * days_vest, block .timestamp , 100 days, 0 , address (0 ));
0 commit comments