Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: high
Valid

Extraneous `GMXManager#borrow` in `GMXWithdraw#processWithdrawFailure`

Summary

Processing a withdraw failure performs a borrow even though no repayment has happened. This can cause the leverage to increase over time (or through intentionally causing failed withdraws).

Vulnerability Details

When a withdrawal is processed the following happens in GMXWithdraw#processWithdraw:

function processWithdraw(
...
try GMXProcessWithdraw.processWithdraw(self) {
...
} catch (bytes memory reason) {
self.status = GMXTypes.Status.Withdraw_Failed;
emit WithdrawFailed(reason);
}

GMXProcessWithdraw.processWithdraw swaps tokens and performs a repayment:

GMXManager.swapTokensForExactTokens(self, _sp);
...
GMXManager.repay(
self,
self.withdrawCache.repayParams.repayTokenAAmt,
self.withdrawCache.repayParams.repayTokenBAmt
);

If GMXProcessWithdraw.processWithdraw fails (e.g. slippage too low) then the repayment will not be executed and state changes to Withdraw_Failed.

In GMXWithdraw#processWithdrawFailure there is a borrow that is meant to reborrow the repaid amount (which again wasn't repaid) and add back the liquidity that was removed from GMX. This will cause more borrowed tokens to be added as liquidity before the withdrawal happened.

Impact

Vault's leverage is increased above the intended 3x and the vault takes on more risk than desired

Tools Used

Manual Review

Recommendations

Don't perform the borrow in GMXWithdraw#processWithdrawFailure

Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

Wrong logic in processWithdrawFailure

Impact: High Likelihood: High Overlending is caused due to unnecessary re-borrow on processWithdrawFailure. Assumption that the repayment had gone because it was in try-catch is incorrect.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.