Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: medium
Invalid

The contract in the `processDeposit` function invokes external contracts, such as the GMXManager functions, without using the "Checks-Effects-Interactions" pattern, posing reentrancy risks

Summary

Contract invokes external contracts, such as the GMXManager functions, without using the "Checks-Effects-Interactions" pattern. This could create reentrancy risks if the called contracts have reentrancy vulnerabilities.

Vulnerability Details

Where the "Checks-Effects-Interactions" pattern is not followed is mainly in the processDeposit function:

function processDeposit(
GMXTypes.Store storage self
) external {
// The function performs interactions with external contracts without following "Checks-Effects-Interactions" pattern.
try GMXProcessDeposit.processDeposit(self) {
// Mint shares to depositor
self.vault.mint(self.depositCache.user, self.depositCache.sharesToUser);
self.status = GMXTypes.Status.Open;
emit DepositCompleted(
self.depositCache.user,
self.depositCache.sharesToUser,
self.depositCache.healthParams.equityBefore,
self.depositCache.healthParams.equityAfter
);
} catch (bytes memory reason) {
self.status = GMXTypes.Status.Deposit_Failed;
emit DepositFailed(reason);
}
}

Impact

The absence of the "Checks-Effects-Interactions" pattern can lead to reentrancy risks. Reentrancy attacks can result in unexpected behavior and potential loss of funds, making the system vulnerable to exploit.

Tools Used

Manual

Recommendations

Addressing this reentrancy risk, it is recommended to follow the "Checks-Effects-Interactions" pattern when interacting with external contracts. Here's an example of how the code can be modified to mitigate the risk:

function processDeposit(
GMXTypes.Store storage self
) external {
GMXChecks.beforeProcessDepositChecks(self);
// Perform checks
// Update effects
// Interact with external contracts
try GMXProcessDeposit.processDeposit(self) {
// Mint shares to depositor
self.vault.mint(self.depositCache.user, self.depositCache.sharesToUser);
self.status = GMXTypes.Status.Open;
emit DepositCompleted(
self.depositCache.user,
self.depositCache.sharesToUser,
self.depositCache.healthParams.equityBefore,
self.depositCache.healthParams.equityAfter
);
} catch (bytes memory reason) {
self.status = GMXTypes.Status.Deposit_Failed;
emit DepositFailed(reason);
}
}
Updates

Lead Judging Commences

hans Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality
0xVinylDavyl Submitter
over 1 year ago
hans Auditor
over 1 year ago
0xVinylDavyl Submitter
over 1 year ago
hans Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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