Steadefi

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

Depositor receives protocol's refund in case processDepositFailure call

Summary

When processDepositFailure function is called by keeper, then when request is executed, protocol sends keeper refund to the depositor.

Vulnerability Details

In order to execute any request on GMX user should provide execution fee. This fee should be enough to cover execution of request and calling of callback. After callback is called and request is executed(or canceled), then amount of fee that was not used is sent to the caller. Steadefi protocol set callback gas limit as 2 millions, which is very big amount.

In order to handle this GMXVault has receive function.
https://github.com/Cyfrin/2023-10-SteadeFi/blob/main/contracts/strategy/gmx/GMXVault.sol#L697-L702

receive() external payable {
if (msg.sender == _store.depositVault || msg.sender == _store.withdrawalVault) {
(bool success, ) = _store.refundee.call{value: address(this).balance}("");
require(success, "Transfer failed.");
}
}

So in case if funds are coming from GMX vaults, then protocol sends them to the _store.refundee address.

When user initiates deposit request, then he is set as refundee. So when deposit request is executed on GMX or canceled, then user receives refund.

In case if deposit was successful, then processDeposit is called. This function can fail, which means that user's deposit is accepted by Steadefi. In such situation, Steadefi keeper will call processDepositFailure in order to withdraw deposit funds and return them back to user. This operation is fully paid by Steadefi keeper, so it provides execution fee for the GMX keeper. The problem is that processDepositFailure doesn't change _store.refundee, so when request is processed by GMX keeper, then refund is sent to the current _store.refundee, which is previous depositor. As result depositor receives refund of keeper, which can be really big, because of 2 million gas limit for callback.

Same thing is done for witdrawals.

Tools Used

VsCode

Recommendations

In case if keeper should process failed deposit or withdrawal, make sure it will be set to _store.refundee to receive refund back.

Updates

Lead Judging Commences

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

Keepers do not get refund for execution fee

Impact: High (loss of funds for keepers) Likelihood: High - processDepositFailure - processWithdrawFailure

Support

FAQs

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