Skip to content

Commit 92e58c5

Browse files
committed
address pr comments
1 parent a5118d8 commit 92e58c5

2 files changed

Lines changed: 15 additions & 22 deletions

File tree

solidity/src/FCMVault.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ contract FCMVault is IFCMVault, ERC20, Ownable2Step, IMorphoFlashLoanCallback {
420420

421421
/// @inheritdoc IFCMVault
422422
function maxRedeem(address owner) external view returns (uint256) {
423-
if (_market().healthFactor() > HEALTH_FACTOR_MAX) return 0;
423+
if (_market().healthFactor() < HEALTH_FACTOR_MIN) return 0;
424424
return balanceOf(owner);
425425
}
426426

solidity/test/FCMMaxRedeem.t.sol

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,26 @@ contract FCMMaxRedeemTest is Test, Deployers {
3333
assertEq(vault.maxRedeem(alice), shares);
3434
}
3535

36-
function test_maxRedeem_zeroWhenHealthFactorAboveMax() public {
36+
function test_maxRedeem_zeroWhenUnhealthy() public {
3737
vm.prank(alice);
3838
uint256 shares = vault.deposit(1 ether, alice);
3939
assertGt(shares, 0);
4040

41-
setCollateralPrice(COLLATERAL_PRICE * 3); // HF well above MAX
42-
assertGt(vault.healthFactor(), HEALTH_FACTOR_MAX);
41+
setCollateralPrice(COLLATERAL_PRICE / 2);
42+
assertLt(vault.healthFactor(), HEALTH_FACTOR_MIN);
4343

4444
assertEq(vault.maxRedeem(alice), 0);
45-
assertGt(vault.balanceOf(alice), 0);
45+
}
46+
47+
function test_maxRedeem_veryHealthy() public {
48+
vm.prank(alice);
49+
uint256 shares = vault.deposit(1 ether, alice);
50+
assertGt(shares, 0);
51+
52+
setCollateralPrice(COLLATERAL_PRICE * 10);
53+
assertGt(vault.healthFactor(), HEALTH_FACTOR_MIN);
54+
55+
assertEq(vault.maxRedeem(alice), shares);
4656
}
4757

4858
function test_maxRedeem_perOwnerIndependence() public {
@@ -56,21 +66,4 @@ contract FCMMaxRedeemTest is Test, Deployers {
5666
assertEq(vault.maxRedeem(bob), bobShares);
5767
assertEq(vault.maxRedeem(stranger), 0);
5868
}
59-
60-
// ERC4626 consistency gap: `redeem()` does NOT enforce `maxRedeem` /
61-
// `ERC4626ExceededMaxRedeem` — its only HF gate is `>= HEALTH_FACTOR_MIN`. So when
62-
// `hf > HEALTH_FACTOR_MAX` but `hf >= HEALTH_FACTOR_MIN`, `maxRedeem` reports 0
63-
// yet `redeem()` still succeeds. This pins that divergence.
64-
function test_maxRedeem_reportsZeroButRedeemStillSucceeds() public {
65-
vm.prank(alice);
66-
uint256 shares = vault.deposit(1 ether, alice);
67-
68-
setCollateralPrice(COLLATERAL_PRICE * 3); // HF above MAX (> MIN too)
69-
assertGt(vault.healthFactor(), HEALTH_FACTOR_MAX);
70-
assertEq(vault.maxRedeem(alice), 0);
71-
72-
vm.prank(alice);
73-
uint256 assetsOut = vault.redeem(shares, alice, alice);
74-
assertGt(assetsOut, 0);
75-
}
7669
}

0 commit comments

Comments
 (0)