@@ -101,7 +101,12 @@ contract AngleRouterMainnetTest is BaseTest {
101
101
assertEq (token.balanceOf (address (to)), 0 );
102
102
}
103
103
104
- function testMint4626ForgotFunds (uint256 initShares , uint256 shares , uint256 maxAmount , uint256 gainOrLoss ) public {
104
+ function testMint4626ForgotFunds (
105
+ uint256 initShares ,
106
+ uint256 shares ,
107
+ uint256 maxAmount ,
108
+ uint256 gainOrLoss
109
+ ) public {
105
110
address to = address (router);
106
111
uint256 balanceUsers = BASE_TOKENS * 1 ether ;
107
112
deal (address (token), address (_alice), balanceUsers);
@@ -189,6 +194,52 @@ contract AngleRouterMainnetTest is BaseTest {
189
194
assertEq (token.balanceOf (address (to)), 0 );
190
195
}
191
196
197
+ function testDeposit4626MaxBalance (
198
+ uint256 initShares ,
199
+ uint256 amount ,
200
+ uint256 minSharesOut ,
201
+ uint256 gainOrLoss
202
+ ) public {
203
+ address to = address (router);
204
+
205
+ uint256 balanceUsers = BASE_TOKENS * 1 ether ;
206
+ deal (address (token), address (_alice), balanceUsers);
207
+
208
+ _randomizeSavingsRate (gainOrLoss, initShares);
209
+
210
+ amount = bound (amount, 0 , balanceUsers);
211
+ uint256 previewDeposit = savingsRate.previewDeposit (amount);
212
+
213
+ PermitType[] memory paramsPermit = new PermitType [](0 );
214
+ ActionType[] memory actionType = new ActionType [](2 );
215
+ bytes [] memory data = new bytes [](2 );
216
+
217
+ actionType[0 ] = ActionType.transfer;
218
+ data[0 ] = abi.encode (token, router, amount);
219
+ actionType[1 ] = ActionType.deposit4626;
220
+ data[1 ] = abi.encode (token, savingsRate, type (uint256 ).max, to, minSharesOut);
221
+
222
+ uint256 mintedShares = savingsRate.convertToShares (amount);
223
+
224
+ vm.startPrank (_alice);
225
+ token.approve (address (router), type (uint256 ).max);
226
+ // as this is a mock vault, previewMint is exactly what is needed to mint
227
+ if (previewDeposit < minSharesOut) {
228
+ vm.expectRevert (BaseRouter.TooSmallAmountOut.selector );
229
+ router.mixer (paramsPermit, actionType, data);
230
+ return ;
231
+ } else {
232
+ router.mixer (paramsPermit, actionType, data);
233
+ }
234
+ vm.stopPrank ();
235
+
236
+ assertEq (savingsRate.balanceOf (address (to)), previewDeposit);
237
+ assertEq (savingsRate.balanceOf (address (to)), mintedShares);
238
+
239
+ assertEq (token.balanceOf (address (router)), 0 );
240
+ assertEq (token.balanceOf (address (_alice)), balanceUsers - amount);
241
+ }
242
+
192
243
function testDeposit4626ForgotFunds (
193
244
uint256 initShares ,
194
245
uint256 amount ,
@@ -232,6 +283,53 @@ contract AngleRouterMainnetTest is BaseTest {
232
283
assertEq (token.balanceOf (address (_alice)), balanceUsers - amount);
233
284
}
234
285
286
+ function testDepositReferral4626MaxBalance (
287
+ uint256 initShares ,
288
+ uint256 amount ,
289
+ uint256 minSharesOut ,
290
+ uint256 gainOrLoss ,
291
+ address referrer
292
+ ) public {
293
+ address to = address (router);
294
+
295
+ uint256 balanceUsers = BASE_TOKENS * 1 ether ;
296
+ deal (address (token), address (_alice), balanceUsers);
297
+
298
+ _randomizeSavingsRate (gainOrLoss, initShares);
299
+
300
+ amount = bound (amount, 0 , balanceUsers);
301
+ uint256 previewDeposit = savingsRate.previewDeposit (amount);
302
+
303
+ PermitType[] memory paramsPermit = new PermitType [](0 );
304
+ ActionType[] memory actionType = new ActionType [](2 );
305
+ bytes [] memory data = new bytes [](2 );
306
+
307
+ actionType[0 ] = ActionType.transfer;
308
+ data[0 ] = abi.encode (token, router, amount);
309
+ actionType[1 ] = ActionType.deposit4626Referral;
310
+ data[1 ] = abi.encode (token, savingsRate, type (uint256 ).max, to, minSharesOut, referrer);
311
+
312
+ uint256 mintedShares = savingsRate.convertToShares (amount);
313
+
314
+ vm.startPrank (_alice);
315
+ token.approve (address (router), type (uint256 ).max);
316
+ // as this is a mock vault, previewMint is exactly what is needed to mint
317
+ if (previewDeposit < minSharesOut) {
318
+ vm.expectRevert (BaseRouter.TooSmallAmountOut.selector );
319
+ router.mixer (paramsPermit, actionType, data);
320
+ return ;
321
+ } else {
322
+ router.mixer (paramsPermit, actionType, data);
323
+ }
324
+ vm.stopPrank ();
325
+
326
+ assertEq (savingsRate.balanceOf (address (to)), previewDeposit);
327
+ assertEq (savingsRate.balanceOf (address (to)), mintedShares);
328
+
329
+ assertEq (token.balanceOf (address (router)), 0 );
330
+ assertEq (token.balanceOf (address (_alice)), balanceUsers - amount);
331
+ }
332
+
235
333
function testRedeem4626GoodPractice (
236
334
uint256 initShares ,
237
335
uint256 aliceAmount ,
@@ -387,6 +485,78 @@ contract AngleRouterMainnetTest is BaseTest {
387
485
assertEq (token.balanceOf (address (_alice)), balanceUsers - aliceAmount);
388
486
}
389
487
488
+ function testRedeem4626MaxBalance (
489
+ uint256 initShares ,
490
+ uint256 aliceAmount ,
491
+ uint256 minAmount ,
492
+ uint256 gainOrLoss ,
493
+ uint256 gainOrLoss2
494
+ ) public {
495
+ uint256 balanceUsers = BASE_TOKENS * 1 ether ;
496
+ deal (address (token), address (_alice), balanceUsers);
497
+
498
+ _randomizeSavingsRate (gainOrLoss, initShares);
499
+
500
+ aliceAmount = bound (aliceAmount, 0 , balanceUsers);
501
+ uint256 previewDeposit = savingsRate.previewDeposit (aliceAmount);
502
+ // otherwise there could be overflows
503
+ vm.assume (previewDeposit < type (uint256 ).max / BASE_PARAMS);
504
+
505
+ uint256 previewRedeem;
506
+ {
507
+ // do a first deposit
508
+ PermitType[] memory paramsPermit = new PermitType [](0 );
509
+ ActionType[] memory actionType = new ActionType [](2 );
510
+ bytes [] memory data = new bytes [](2 );
511
+
512
+ actionType[0 ] = ActionType.transfer;
513
+ data[0 ] = abi.encode (token, router, aliceAmount);
514
+ actionType[1 ] = ActionType.deposit4626;
515
+ data[1 ] = abi.encode (token, savingsRate, aliceAmount, _alice, previewDeposit);
516
+
517
+ vm.startPrank (_alice);
518
+ token.approve (address (router), type (uint256 ).max);
519
+ router.mixer (paramsPermit, actionType, data);
520
+ vm.stopPrank ();
521
+
522
+ assertEq (savingsRate.balanceOf (address (router)), 0 );
523
+ assertEq (savingsRate.balanceOf (address (_alice)), previewDeposit);
524
+ assertEq (token.balanceOf (address (router)), 0 );
525
+ assertEq (token.balanceOf (address (_alice)), balanceUsers - aliceAmount);
526
+
527
+ // make the savings rate have a loss / gain
528
+ gainOrLoss2 = bound (gainOrLoss2, 1 , 1 ether * 1 ether);
529
+ deal (address (token), address (savingsRate), gainOrLoss2);
530
+
531
+ // then redeem
532
+ uint256 sharesToBurn = savingsRate.balanceOf (_alice);
533
+
534
+ actionType = new ActionType [](1 );
535
+ data = new bytes [](1 );
536
+
537
+ actionType[0 ] = ActionType.redeem4626;
538
+ data[0 ] = abi.encode (savingsRate, type (uint256 ).max, address (router), minAmount);
539
+
540
+ previewRedeem = savingsRate.previewRedeem (sharesToBurn);
541
+ vm.startPrank (_alice);
542
+ savingsRate.approve (address (router), type (uint256 ).max);
543
+ // as this is a mock vault, previewRedeem is exactly what should be received
544
+ if (previewRedeem < minAmount) {
545
+ vm.expectRevert (BaseRouter.TooSmallAmountOut.selector );
546
+ router.mixer (paramsPermit, actionType, data);
547
+ return ;
548
+ } else {
549
+ router.mixer (paramsPermit, actionType, data);
550
+ }
551
+ vm.stopPrank ();
552
+ assertEq (savingsRate.balanceOf (address (_alice)), previewDeposit - sharesToBurn);
553
+ }
554
+
555
+ assertEq (savingsRate.balanceOf (address (router)), 0 );
556
+ assertEq (token.balanceOf (address (router)), previewRedeem);
557
+ assertEq (token.balanceOf (address (_alice)), balanceUsers - aliceAmount);
558
+ }
559
+
390
560
function testWithdraw4626GoodPractice (
391
561
uint256 initShares ,
392
562
uint256 aliceAmount ,
0 commit comments