MorpheusAI

MorpheusAI
Foundry
22,500 USDC
View results
Submission Details
Severity: medium
Invalid

Reentrancy attack in Stake and Withdraw

Summary

The _stake and _withdraw functions in the Distribution contract transfer tokens before updating user balances, potentially exposing the contract to reentrancy attacks.

Vulnerability Details

POC

function _stake(address user_, uint256 poolId_, uint256 amount_, uint256 currentPoolRate_) private {
// No user balance update before transferring tokens
IERC20(depositToken).safeTransferFrom(_msgSender(), address(this), amount_);
// ...
}
function _withdraw(address user_, uint256 poolId_, uint256 amount_, uint256 currentPoolRate_) private {
// No user balance update before transferring tokens
IERC20(depositToken).safeTransfer(user_, amount_);
// ...
}

Description

The _stake and _withdraw functions perform token transfers before updating user balances. This design can expose the contract to reentrancy attacks, where a malicious external contract may call back into the Distribution contract during the token transfer process.

Impact

The lack of updating user balances before transferring tokens may allow an attacker to exploit reentrancy, potentially leading to unexpected behavior or financial loss.

Tools Used

No specific tools were used to identify this issue; it was identified through manual code review.

Recommendations

  1. Update User Balances Before Transferring Tokens:
    Ensure that user balances are updated before any token transfers within the _stake and _withdraw functions. This helps prevent potential reentrancy attacks.

Modification

function _stake(address user_, uint256 poolId_, uint256 amount_, uint256 currentPoolRate_) private {
// Update user balance before transferring tokens
_updateUserBalance(user_, poolId_);
IERC20(depositToken).safeTransferFrom(_msgSender(), address(this), amount_);
// ...
}
function _withdraw(address user_, uint256 poolId_, uint256 amount_, uint256 currentPoolRate_) private {
// Update user balance before transferring tokens
_updateUserBalance(user_, poolId_);
IERC20(depositToken).safeTransfer(user_, amount_);
// ...
}
function _updateUserBalance(address user_, uint256 poolId_) private {
// Implement logic to update user balances
// ...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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