From a812f8957e4563b0bcaa01ed8c2ac767b2f3e996 Mon Sep 17 00:00:00 2001 From: Trevor Richard Date: Fri, 21 Jun 2024 01:03:19 +0000 Subject: [PATCH] handle div by zero edge case in maxRedeem --- src/PrizeVault.sol | 3 ++- test/unit/PrizeVault/PrizeVault.t.sol | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/PrizeVault.sol b/src/PrizeVault.sol index 0f2c18c..5090c6e 100644 --- a/src/PrizeVault.sol +++ b/src/PrizeVault.sol @@ -856,6 +856,7 @@ contract PrizeVault is TwabERC20, Claimable, IERC4626, ILiquidationSource, Ownab } /// @notice Converts assets to shares with the given vault state and rounding direction. + /// @dev Returns zero if the vault is in a lossy state AND there are no more assets. /// @param _assets The assets to convert /// @param _totalAssets The total assets that the vault controls /// @param _totalDebt The total debt the vault owes @@ -873,7 +874,7 @@ contract PrizeVault is TwabERC20, Claimable, IERC4626, ILiquidationSource, Ownab // If the vault controls less assets than what has been deposited a share will be worth a // proportional amount of the total assets. This can happen due to fees, slippage, or loss // of funds in the underlying yield vault. - return _assets.mulDiv(_totalDebt, _totalAssets, _rounding); + return _totalAssets == 0 ? 0 : _assets.mulDiv(_totalDebt, _totalAssets, _rounding); } } diff --git a/test/unit/PrizeVault/PrizeVault.t.sol b/test/unit/PrizeVault/PrizeVault.t.sol index 7006f44..f9b08f1 100644 --- a/test/unit/PrizeVault/PrizeVault.t.sol +++ b/test/unit/PrizeVault/PrizeVault.t.sol @@ -405,6 +405,25 @@ contract PrizeVaultTest is UnitBaseSetup { assertEq(vault.maxRedeem(alice), 0); } + function testMaxRedeem_ReturnsZeroIfLossyAndNoTotalAssets() public { + // deposit some assets + underlyingAsset.mint(alice, 1e18); + vm.startPrank(alice); + underlyingAsset.approve(address(vault), 1e18); + vault.deposit(1e18, alice); + vm.stopPrank(); + + assertGt(vault.maxRedeem(alice), 0); + + // yield vault loses all funds + underlyingAsset.burn(address(yieldVault), underlyingAsset.balanceOf(address(yieldVault))); + assertEq(underlyingAsset.balanceOf(address(yieldVault)), 0); + assertEq(underlyingAsset.balanceOf(address(vault)), 0); + assertEq(vault.totalPreciseAssets(), 0); + + assertEq(vault.maxRedeem(alice), 0); + } + /* ============ previewWithdraw ============ */ function testPreviewWithdraw() public {