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
In the depositCollateral
function:
bool success = IERC20(tokenCollateralAddress).transferFrom(msg.sender, address(this), amountCollateral);
if (!success) {
revert DSCEngine__TransferFailed();
}
_balances[msg.sender].collateral = _balances[msg.sender].collateral.add(amountCollateral);
In the _redeemCollateral
function:
bool success = IERC20(tokenCollateralAddress).transfer(to, amountCollateral);
if (!success) {
revert DSCEngine__TransferFailed();
}
_balances[msg.sender].collateral = _balances[msg.sender].collateral.sub(amountCollateral);
In the _burnDsc
function:
bool success = i_dsc.transferFrom(dscFrom, address(this), amountDscToBurn);
if (!success) {
revert DSCEngine__TransferFailed();
}
_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:
_balances[msg.sender].collateral = _balances[msg.sender].collateral.add(amountCollateral);
bool success = IERC20(tokenCollateralAddress).transferFrom(msg.sender, address(this), amountCollateral);
if (!success) {
revert DSCEngine__TransferFailed();
}