Relevant GitHub Links
Vulnerability Details
When calculating the maximum possible depositable amount for delta neutral vaults,
_maxTokenBLending
is calculated incorrectly.plain textif (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;
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:plain textTotal 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.
diffdiff --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; }