15,000 USDC
View results
Submission Details
Severity: low

Function Should Follow CEI(Check Effects Interactions)

Summary

Although the contract uses OpenZeppelin's ReentrancyGuard to guard against reentrant attacks, it still has certain external contract calls which could potentially lead to reentrancy if those external contracts are not designed correctly or maliciously designed.

Vulnerability Details

  1. In the depositCollateral function:

// An external interaction with the ERC20 token contract
bool success = IERC20(tokenCollateralAddress).transferFrom(msg.sender, address(this), amountCollateral);
// Checks here, but state changes have already been made
if (!success) {
revert DSCEngine__TransferFailed();
}
// State changes are made after the external interaction
_balances[msg.sender].collateral = _balances[msg.sender].collateral.add(amountCollateral);
  1. In the _redeemCollateral function:

// An external interaction with the ERC20 token contract
bool success = IERC20(tokenCollateralAddress).transfer(to, amountCollateral);
// Checks here, but state changes have already been made
if (!success) {
revert DSCEngine__TransferFailed();
}
// State changes are made after the external interaction
_balances[msg.sender].collateral = _balances[msg.sender].collateral.sub(amountCollateral);
  1. In the _burnDsc function:

// An external interaction with the ERC20 token contract
bool success = i_dsc.transferFrom(dscFrom, address(this), amountDscToBurn);
// Checks here, but state changes have already been made
if (!success) {
revert DSCEngine__TransferFailed();
}
// State changes are made after the external interaction
_balances[dscFrom].dsc = _balances[dscFrom].dsc.sub(amountDscToBurn);

Impact

potentially lead to reentrancy

Tools Used

manually reviewed

Recommendations

The recommended way is to rearrange the sequence and make sure all state changes (effects) happen before any external interactions:

// First, update the state
_balances[msg.sender].collateral = _balances[msg.sender].collateral.add(amountCollateral);
// Then, interact with the external contract
bool success = IERC20(tokenCollateralAddress).transferFrom(msg.sender, address(this), amountCollateral);
if (!success) {
revert DSCEngine__TransferFailed();
}

Support

FAQs

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