medium

Incorrect depositable shortToken amount calculation in Delta neutral vaults

Contest
Reward

Total

370.32 USDC

Selected
152.48 USDC
108.92 USDC
108.92 USDC
Selected Submission

Incorrect depositable shortToken amount calculation in Delta neutral vaults

Severity

Medium Risk

Relevant GitHub Links

https://github.com/Cyfrin/2023-10-SteadeFi/blob/0f909e2f0917cb9ad02986f631d622376510abec/contracts/strategy/gmx/GMXReader.sol#L264-L270

Vulnerability Details

When calculating the maximum possible depositable amount for delta neutral vaults, _maxTokenBLending is calculated incorrectly.

    if (self.delta == GMXTypes.Delta.Neutral) {
      (uint256 _tokenAWeight, ) = tokenWeights(self);


      uint256 _maxTokenALending = convertToUsdValue(
        self,
        address(self.tokenA),
        self.tokenALendingVault.totalAvailableAsset()
      ) * SAFE_MULTIPLIER
        / (self.leverage * _tokenAWeight / SAFE_MULTIPLIER);


      uint256 _maxTokenBLending = convertToUsdValue(
        self,
        address(self.tokenB),
        self.tokenBLendingVault.totalAvailableAsset()
      ) * SAFE_MULTIPLIER
        / (self.leverage * _tokenAWeight / SAFE_MULTIPLIER)
        - 1e18;

https://github.com/Cyfrin/2023-10-SteadeFi/blob/0f909e2f0917cb9ad02986f631d622376510abec/contracts/strategy/gmx/GMXReader.sol#L254-L270

If a user wants to deposit v value to a l leveraged delta neutral vault with token weights a and b, the calculation of required lending amount would be as follows:

Total value to deposit to GMX = lv
Value of tokens to short = lva
Hence this value will be borrowed from the tokenA lending vault
Remaining value to borrow (from tokenB lending vault) = lv - lva - v (deposit value provided by user)
Hence if there is Tb value of tokens in tokenB lending vault, v <= Tb / (l - la - 1)

Impact

Deposit attempts can revert even when there is enough tokens to lend causing inefficiency, loss of gas for depositors and deviation from the protocol specification.

Recommendations

Change the formula to the correct one.

diff --git a/contracts/strategy/gmx/GMXReader.sol b/contracts/strategy/gmx/GMXReader.sol
index 73bb111..ae819c4 100644
--- a/contracts/strategy/gmx/GMXReader.sol
+++ b/contracts/strategy/gmx/GMXReader.sol
@@ -266,8 +266,7 @@ library GMXReader {
         address(self.tokenB),
         self.tokenBLendingVault.totalAvailableAsset()
       ) * SAFE_MULTIPLIER
-        / (self.leverage * _tokenAWeight / SAFE_MULTIPLIER)
-        - 1e18;
+        / (self.leverage - (self.leverage *_tokenAWeight / SAFE_MULTIPLIER) - 1e18);
 
       _additionalCapacity = _maxTokenALending > _maxTokenBLending ? _maxTokenBLending : _maxTokenALending;
     }