medium

depositors face immediate loss in case `equity = 0`

Contest
Reward

Total

564.75 USDC

Selected
564.75 USDC
Selected Submission

depositors face immediate loss in case equity = 0

Severity

High Risk

Relevant GitHub Links

https://github.com/Cyfrin/2023-10-SteadeFi/blob/main/contracts/strategy/gmx/GMXReader.sol#L48

Summary

The vulnerability in the valueToShares function exposes users to significant losses in case the equity (currentAllAssetValue - debtBorrowed) becomes zero due to strategy losses, users receive disproportionately low shares, and take a loss Immediately.

Vulnerability Details

  • When a user deposits to the contract, the calculation of the shares to be minted depends on the value of equity added to the contract after a successful deposit. In other words:
    • value = equityAfter - equityBefore, while:
    • equity = totalAssetValue - totalDebtValue. and we can see that here :
   function processDeposit(GMXTypes.Store storage self) external {
        self.depositCache.healthParams.equityAfter = GMXReader.equityValue(self);
>>        self.depositCache.sharesToUser = GMXReader.valueToShares(
            self,
            self.depositCache.healthParams.equityAfter - self.depositCache.healthParams.equityBefore,
            self.depositCache.healthParams.equityBefore
        );

        GMXChecks.afterDepositChecks(self);
    }
    // value to shares function :

     function valueToShares(GMXTypes.Store storage self, uint256 value, uint256 currentEquity)
        public
        view
        returns (uint256)
    {

        uint256 _sharesSupply = IERC20(address(self.vault)).totalSupply() + pendingFee(self); // shares is added
>>        if (_sharesSupply == 0 || currentEquity == 0) return value;
>>        return value * _sharesSupply / currentEquity;
    }
  • NOTICE: When the equity value is 0, the shares minted to the user equal the deposited value itself. The equity value can become zero due to various factors such as strategy losses or accumulated lending interests... ect
  • In this scenario, the user immediately incurs a loss, depending on the total supply of svToken (shares).
  • Consider the following simplified example:
    • The total supply of svToken is (1,000,000 * 1e18) (indicating users holding these shares).
    • the equity value drops to zero due to strategy losses and a user deposits 100 USD worth of value,
    • Due to the zero equity value, the user is minted 100 shares (100 * 1e18).
    • Consequently, the value the user owns with these shares immediately reduces to 0.001 USD. 100 * 100 * 1e18 / 1,000,000 = 0.001 USD (value * equity / totalSupply).
  • In this case, the user immediately shares their entire deposited value with these old minted shares and loses their deposit, whereas those old shares should be liquidated some how.

    Notice: If the total supply is higher, the user loses more value, and vice versa.

Impact

  • users face immediate loss of funds in case equity drops to zero

Tools Used

manual review

Recommendations

  • use a liquidation mechanism that burns the shares of all users when equity drops to zero.