Skip to content

Commit 98c8905

Browse files
committed
fix: PR Reviews
1 parent a211dfb commit 98c8905

22 files changed

+248
-89
lines changed

src/ForeignController.sol

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ contract ForeignController is ReentrancyGuard, AccessControlEnumerable {
349349
rateLimitedAddress(LIMIT_4626_DEPOSIT, token, amount)
350350
returns (uint256 shares)
351351
{
352+
uint256 maxExchangeRate = maxExchangeRates[token];
353+
354+
require(maxExchangeRate != 0, "ForeignController/max-exchange-rate-not-set");
355+
352356
// Approve asset to token from the proxy (assumes the proxy has enough of the asset).
353357
_approve(IERC4626(token).asset(), token, amount);
354358

@@ -362,7 +366,7 @@ contract ForeignController is ReentrancyGuard, AccessControlEnumerable {
362366
);
363367

364368
require(
365-
_getExchangeRate(shares, amount) <= maxExchangeRates[token],
369+
_getExchangeRate(shares, amount) <= maxExchangeRate,
366370
"ForeignController/exchange-rate-too-high"
367371
);
368372
}
@@ -606,7 +610,13 @@ contract ForeignController is ReentrancyGuard, AccessControlEnumerable {
606610
/**********************************************************************************************/
607611

608612
function _getExchangeRate(uint256 shares, uint256 assets) internal pure returns (uint256) {
609-
return assets == 0 ? 0 : (EXCHANGE_RATE_PRECISION * assets) / shares;
613+
// Return 0 for zero assets first, to handle the valid case of 0 shares and 0 assets.
614+
if (assets == 0) return 0;
615+
616+
// Zero shares with non-zero assets is invalid (infinite exchange rate).
617+
if (shares == 0) revert("ForeignController/zero-shares");
618+
619+
return (EXCHANGE_RATE_PRECISION * assets) / shares;
610620
}
611621

612622
}

src/MainnetController.sol

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,10 @@ contract MainnetController is ReentrancyGuard, AccessControlEnumerable {
458458
_checkRole(RELAYER);
459459
_rateLimitedAddress(LIMIT_4626_DEPOSIT, token, amount);
460460

461+
uint256 maxExchangeRate = maxExchangeRates[token];
462+
463+
require(maxExchangeRate != 0, "MainnetController/max-exchange-rate-not-set");
464+
461465
// Approve asset to token from the proxy (assumes the proxy has enough of the asset).
462466
_approve(IERC4626(token).asset(), token, amount);
463467

@@ -471,7 +475,7 @@ contract MainnetController is ReentrancyGuard, AccessControlEnumerable {
471475
);
472476

473477
require(
474-
_getExchangeRate(shares, amount) <= maxExchangeRates[token],
478+
_getExchangeRate(shares, amount) <= maxExchangeRate,
475479
"MainnetController/exchange-rate-too-high"
476480
);
477481
}
@@ -1121,6 +1125,12 @@ contract MainnetController is ReentrancyGuard, AccessControlEnumerable {
11211125
/**********************************************************************************************/
11221126

11231127
function _getExchangeRate(uint256 shares, uint256 assets) internal pure returns (uint256) {
1128+
// Return 0 for zero assets first, to handle the valid case of 0 shares and 0 assets.
1129+
if (assets == 0) return 0;
1130+
1131+
// Zero shares with non-zero assets is invalid (infinite exchange rate).
1132+
if (shares == 0) revert("MainnetController/zero-shares");
1133+
11241134
return (EXCHANGE_RATE_PRECISION * assets) / shares;
11251135
}
11261136

test/base-fork/Aave.t.sol

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,10 @@ contract AaveV3BaseMarketDepositFailureTests is AaveV3BaseMarketTestBase {
9090
deal(Base.USDC, address(almProxy), 1_000_000e6 + 1);
9191

9292
vm.expectRevert("RateLimits/rate-limit-exceeded");
93-
vm.startPrank(relayer);
93+
vm.prank(relayer);
9494
foreignController.depositAave(ATOKEN_USDC, 1_000_000e6 + 1);
9595

96+
vm.prank(relayer);
9697
foreignController.depositAave(ATOKEN_USDC, 1_000_000e6);
9798
}
9899

@@ -183,21 +184,27 @@ contract AaveV3BaseMarketWithdrawFailureTests is AaveV3BaseMarketTestBase {
183184

184185
vm.expectRevert("RateLimits/zero-maxAmount");
185186
foreignController.withdrawAave(ATOKEN_USDC, 1_000_000e6);
187+
vm.stopPrank();
186188
}
187189

188190
function test_withdrawAave_usdcRateLimitedBoundary() external {
189191
deal(Base.USDC, address(almProxy), 2_000_000e6);
190192

191193
// Warp to get past rate limit
192194
vm.startPrank(relayer);
195+
193196
foreignController.depositAave(ATOKEN_USDC, 1_000_000e6);
197+
194198
skip(1 days);
199+
195200
foreignController.depositAave(ATOKEN_USDC, 100_000e6);
196201

197202
vm.expectRevert("RateLimits/rate-limit-exceeded");
198203
foreignController.withdrawAave(ATOKEN_USDC, 1_000_000e6 + 1);
199204

200205
foreignController.withdrawAave(ATOKEN_USDC, 1_000_000e6);
206+
207+
vm.stopPrank();
201208
}
202209

203210
}

test/base-fork/Morpho.t.sol

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ contract MorphoBaseTest is ForkTestBase {
102102
uint256(5_000_000e6) / 1 days
103103
);
104104

105-
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDS, 1e18, IERC4626(MORPHO_VAULT_USDS).convertToAssets(1e18));
106-
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDC, 1e18, IERC4626(MORPHO_VAULT_USDC).convertToAssets(1e18));
105+
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDS, 1e18, usdsVault.convertToAssets(1e18));
106+
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDC, 1e18, usdcVault.convertToAssets(1e18));
107107

108108
vm.stopPrank();
109109
}
@@ -140,30 +140,11 @@ contract MorphoDepositFailureTests is MorphoBaseTest {
140140
foreignController.depositERC4626(makeAddr("fake-token"), 1e18);
141141
}
142142

143-
function test_depositERC4626_exchangeRateBoundary() external {
144-
deal(Base.USDS, address(almProxy), 25_000_000e18);
145-
146-
vm.startPrank(Base.SPARK_EXECUTOR);
147-
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDS, 1e18, IERC4626(MORPHO_VAULT_USDS).convertToAssets(1e18) - 1);
148-
vm.stopPrank();
149-
150-
vm.prank(relayer);
151-
vm.expectRevert("ForeignController/exchange-rate-too-high");
152-
foreignController.depositERC4626(MORPHO_VAULT_USDS, 25_000_000e18);
153-
154-
vm.startPrank(Base.SPARK_EXECUTOR);
155-
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDS, 1e18, IERC4626(MORPHO_VAULT_USDS).convertToAssets(1e18));
156-
vm.stopPrank();
157-
158-
vm.prank(relayer);
159-
foreignController.depositERC4626(MORPHO_VAULT_USDS, 25_000_000e18);
160-
}
161-
162143
function test_morpho_usds_deposit_rateLimitedBoundary() external {
163144
deal(Base.USDS, address(almProxy), 25_000_000e18 + 1);
164145

165-
vm.expectRevert("RateLimits/rate-limit-exceeded");
166146
vm.prank(relayer);
147+
vm.expectRevert("RateLimits/rate-limit-exceeded");
167148
foreignController.depositERC4626(MORPHO_VAULT_USDS, 25_000_000e18 + 1);
168149

169150
vm.prank(relayer);
@@ -173,14 +154,42 @@ contract MorphoDepositFailureTests is MorphoBaseTest {
173154
function test_morpho_usdc_deposit_rateLimitedBoundary() external {
174155
deal(Base.USDC, address(almProxy), 25_000_000e6 + 1);
175156

176-
vm.expectRevert("RateLimits/rate-limit-exceeded");
177157
vm.prank(relayer);
158+
vm.expectRevert("RateLimits/rate-limit-exceeded");
178159
foreignController.depositERC4626(MORPHO_VAULT_USDC, 25_000_000e6 + 1);
179160

180161
vm.prank(relayer);
181162
foreignController.depositERC4626(MORPHO_VAULT_USDC, 25_000_000e6);
182163
}
183164

165+
function test_morpho_deposit_maxExchangeRateNotSet() external {
166+
vm.prank(Base.SPARK_EXECUTOR);
167+
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDS, 0, 0);
168+
169+
vm.prank(relayer);
170+
vm.expectRevert("ForeignController/max-exchange-rate-not-set");
171+
foreignController.depositERC4626(MORPHO_VAULT_USDS, 1_000_000e18);
172+
}
173+
174+
function test_depositERC4626_exchangeRateBoundary() external {
175+
deal(Base.USDS, address(almProxy), 25_000_000e18);
176+
177+
vm.startPrank(Base.SPARK_EXECUTOR);
178+
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDS, 1e18, usdsVault.convertToAssets(1e18) - 1);
179+
vm.stopPrank();
180+
181+
vm.prank(relayer);
182+
vm.expectRevert("ForeignController/exchange-rate-too-high");
183+
foreignController.depositERC4626(MORPHO_VAULT_USDS, 25_000_000e18);
184+
185+
vm.startPrank(Base.SPARK_EXECUTOR);
186+
foreignController.setMaxExchangeRate(MORPHO_VAULT_USDS, 1e18, usdsVault.convertToAssets(1e18));
187+
vm.stopPrank();
188+
189+
vm.prank(relayer);
190+
foreignController.depositERC4626(MORPHO_VAULT_USDS, 25_000_000e18);
191+
}
192+
184193
}
185194

186195
contract MorphoDepositSuccessTests is MorphoBaseTest {
@@ -246,24 +255,32 @@ contract MorphoWithdrawFailureTests is MorphoBaseTest {
246255

247256
function test_morpho_usds_withdraw_rateLimitBoundary() external {
248257
deal(Base.USDS, address(almProxy), 10_000_000e18 + 1);
258+
249259
vm.startPrank(relayer);
260+
250261
foreignController.depositERC4626(MORPHO_VAULT_USDS, 10_000_000e18 + 1);
251262

252263
vm.expectRevert("RateLimits/rate-limit-exceeded");
253264
foreignController.withdrawERC4626(MORPHO_VAULT_USDS, 10_000_000e18 + 1);
254265

255266
foreignController.withdrawERC4626(MORPHO_VAULT_USDS, 10_000_000e18);
267+
268+
vm.stopPrank();
256269
}
257270

258271
function test_morpho_usdc_withdraw_rateLimitBoundary() external {
259272
deal(Base.USDC, address(almProxy), 10_000_000e18 + 1);
273+
260274
vm.startPrank(relayer);
275+
261276
foreignController.depositERC4626(MORPHO_VAULT_USDC, 10_000_000e6 + 1);
262277

263278
vm.expectRevert("RateLimits/rate-limit-exceeded");
264279
foreignController.withdrawERC4626(MORPHO_VAULT_USDC, 10_000_000e6 + 1);
265280

266281
foreignController.withdrawERC4626(MORPHO_VAULT_USDC, 10_000_000e6);
282+
283+
vm.stopPrank();
267284
}
268285

269286
}
@@ -373,49 +390,57 @@ contract MorphoRedeemFailureTests is MorphoBaseTest {
373390
vm.stopPrank();
374391

375392
deal(Base.USDS, address(almProxy), 1_000_000e18);
393+
376394
vm.startPrank(relayer);
395+
377396
foreignController.depositERC4626(MORPHO_VAULT_USDS, 1_000_000e18);
378397

379398
vm.expectRevert("RateLimits/zero-maxAmount");
380399
foreignController.redeemERC4626(MORPHO_VAULT_USDS, 1_000_000e18);
400+
401+
vm.stopPrank();
381402
}
382403

383404
function test_morpho_usds_redeem_rateLimitBoundary() external {
384405
deal(Base.USDS, address(almProxy), 20_000_000e18);
406+
385407
vm.startPrank(relayer);
386-
foreignController.depositERC4626(MORPHO_VAULT_USDS, 20_000_000e18);
387408

388-
IERC4626 vault = IERC4626(MORPHO_VAULT_USDS);
409+
foreignController.depositERC4626(MORPHO_VAULT_USDS, 20_000_000e18);
389410

390-
uint256 overBoundaryShares = vault.convertToShares(10_000_000e18 + 1);
391-
uint256 atBoundaryShares = vault.convertToShares(10_000_000e18);
411+
uint256 overBoundaryShares = usdsVault.convertToShares(10_000_000e18 + 1);
412+
uint256 atBoundaryShares = usdsVault.convertToShares(10_000_000e18);
392413

393-
assertEq(vault.previewRedeem(overBoundaryShares), 10_000_000e18 + 1);
394-
assertEq(vault.previewRedeem(atBoundaryShares), 10_000_000e18);
414+
assertEq(usdsVault.previewRedeem(overBoundaryShares), 10_000_000e18 + 1);
415+
assertEq(usdsVault.previewRedeem(atBoundaryShares), 10_000_000e18);
395416

396417
vm.expectRevert("RateLimits/rate-limit-exceeded");
397418
foreignController.redeemERC4626(MORPHO_VAULT_USDS, overBoundaryShares);
398419

399420
foreignController.redeemERC4626(MORPHO_VAULT_USDS, atBoundaryShares);
421+
422+
vm.stopPrank();
400423
}
401424

402425
function test_morpho_usdc_redeem_rateLimitBoundary() external {
403426
deal(Base.USDC, address(almProxy), 20_000_000e18);
427+
404428
vm.startPrank(relayer);
405-
foreignController.depositERC4626(MORPHO_VAULT_USDC, 20_000_000e6);
406429

407-
IERC4626 vault = IERC4626(MORPHO_VAULT_USDC);
430+
foreignController.depositERC4626(MORPHO_VAULT_USDC, 20_000_000e6);
408431

409-
uint256 overBoundaryShares = vault.convertToShares(10_000_000e6 + 1);
410-
uint256 atBoundaryShares = vault.convertToShares(10_000_000e6);
432+
uint256 overBoundaryShares = usdcVault.convertToShares(10_000_000e6 + 1);
433+
uint256 atBoundaryShares = usdcVault.convertToShares(10_000_000e6);
411434

412-
assertEq(vault.previewRedeem(overBoundaryShares), 10_000_000e6 + 1);
413-
assertEq(vault.previewRedeem(atBoundaryShares), 10_000_000e6);
435+
assertEq(usdcVault.previewRedeem(overBoundaryShares), 10_000_000e6 + 1);
436+
assertEq(usdcVault.previewRedeem(atBoundaryShares), 10_000_000e6);
414437

415438
vm.expectRevert("RateLimits/rate-limit-exceeded");
416439
foreignController.redeemERC4626(MORPHO_VAULT_USDC, overBoundaryShares);
417440

418441
foreignController.redeemERC4626(MORPHO_VAULT_USDC, atBoundaryShares);
442+
443+
vm.stopPrank();
419444
}
420445

421446
}

test/base-fork/MorphoAllocations.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ contract MorphoReallocateMorphoFailureTests is MorphoTestBase {
209209

210210
contract MorphoReallocateMorphoSuccessTests is MorphoTestBase {
211211

212-
function test_reallocateMorpho_xxx() external {
212+
function test_reallocateMorpho() external {
213213
vm.startPrank(Base.SPARK_EXECUTOR);
214214
rateLimits.setRateLimitData(
215215
RateLimitHelpers.makeAddressKey(

test/base-fork/PsmCalls.t.sol

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,31 +68,40 @@ contract ForeignControllerDepositPSMFailureTests is ForkTestBase {
6868
function test_depositPSM_usdcRateLimitedBoundary() external {
6969
deal(address(usdcBase), address(almProxy), 5_000_000e6 + 1);
7070

71-
vm.expectRevert("RateLimits/rate-limit-exceeded");
7271
vm.startPrank(relayer);
72+
73+
vm.expectRevert("RateLimits/rate-limit-exceeded");
7374
foreignController.depositPSM(address(usdcBase), 5_000_000e6 + 1);
7475

7576
foreignController.depositPSM(address(usdcBase), 5_000_000e6);
77+
78+
vm.stopPrank();
7679
}
7780

7881
function test_depositPSM_usdsRateLimitedBoundary() external {
7982
deal(address(usdsBase), address(almProxy), 5_000_000e18 + 1);
8083

81-
vm.expectRevert("RateLimits/rate-limit-exceeded");
8284
vm.startPrank(relayer);
85+
86+
vm.expectRevert("RateLimits/rate-limit-exceeded");
8387
foreignController.depositPSM(address(usdsBase), 5_000_000e18 + 1);
8488

8589
foreignController.depositPSM(address(usdsBase), 5_000_000e18);
90+
91+
vm.stopPrank();
8692
}
8793

8894
function test_depositPSM_susdsRateLimitedBoundary() external {
8995
deal(address(susdsBase), address(almProxy), 5_000_000e18 + 1);
9096

91-
vm.expectRevert("RateLimits/rate-limit-exceeded");
9297
vm.startPrank(relayer);
98+
99+
vm.expectRevert("RateLimits/rate-limit-exceeded");
93100
foreignController.depositPSM(address(susdsBase), 5_000_000e18 + 1);
94101

95102
foreignController.depositPSM(address(susdsBase), 5_000_000e18);
103+
104+
vm.stopPrank();
96105
}
97106

98107
}
@@ -275,12 +284,15 @@ contract ForeignControllerWithdrawPSMFailureTests is ForkTestBase {
275284
deal(address(usdcBase), address(almProxy), 1_000_000e6 + 1);
276285

277286
vm.startPrank(relayer);
287+
278288
foreignController.depositPSM(address(usdcBase), 1_000_000e6 + 1);
279289

280290
vm.expectRevert("RateLimits/rate-limit-exceeded");
281291
foreignController.withdrawPSM(address(usdcBase), 1_000_000e6 + 1);
282292

283293
foreignController.withdrawPSM(address(usdcBase), 1_000_000e6);
294+
295+
vm.stopPrank();
284296
}
285297

286298
function test_withdrawPSM_usdsRateLimitedBoundary() external {
@@ -293,12 +305,15 @@ contract ForeignControllerWithdrawPSMFailureTests is ForkTestBase {
293305
deal(address(usdsBase), address(almProxy), 1_000_000e18 + 1);
294306

295307
vm.startPrank(relayer);
308+
296309
foreignController.depositPSM(address(usdsBase), 1_000_000e18 + 1);
297310

298311
vm.expectRevert("RateLimits/rate-limit-exceeded");
299312
foreignController.withdrawPSM(address(usdsBase), 1_000_000e18 + 1);
300313

301314
foreignController.withdrawPSM(address(usdsBase), 1_000_000e18);
315+
316+
vm.stopPrank();
302317
}
303318

304319
function test_withdrawPSM_susdsRateLimitedBoundary() external {
@@ -312,6 +327,7 @@ contract ForeignControllerWithdrawPSMFailureTests is ForkTestBase {
312327
deal(address(susdsBase), address(almProxy), 1_000_000e18 + 2);
313328

314329
vm.startPrank(relayer);
330+
315331
foreignController.depositPSM(address(susdsBase), 1_000_000e18 + 2);
316332

317333
vm.expectRevert("RateLimits/rate-limit-exceeded");
@@ -320,6 +336,8 @@ contract ForeignControllerWithdrawPSMFailureTests is ForkTestBase {
320336
uint256 withdrawn = foreignController.withdrawPSM(address(susdsBase), 1_000_000e18);
321337

322338
assertEq(withdrawn, 1_000_000e18);
339+
340+
vm.stopPrank();
323341
}
324342

325343
}

0 commit comments

Comments
 (0)