Vulnerability
The refund function is vulnerable to reentrancy attacks due to incorrect usage of the nonReentrant modifier. Specifically, the modifier does not set the locked flag to true before executing the function body, which allows malicious contracts to re-enter the function and potentially drain funds or cause inconsistent state
Root Cause
modifier nonReentrant() {
require(!locked, "No re-entrancy");
_;
locked = false;
}
Mitigation
modifier nonReentrant() {
require(!locked, "No re-entrancy");
+ locked = true;
_;
locked = false;
}
Use CEI (check effect interaction pattern)
function _refundERC20(address _to) internal {
+ balances[_to][address(i_USDC)] = 0;
+ balances[_to][address(i_WBTC)] = 0;
+ balances[_to][address(i_WETH)] = 0;
i_WETH.safeTransfer(_to, balances[_to][address(i_WETH)]);
i_WBTC.safeTransfer(_to, balances[_to][address(i_WBTC)]);
i_USDC.safeTransfer(_to, balances[_to][address(i_USDC)]);
- balances[_to][address(i_USDC)] = 0;
- balances[_to][address(i_WBTC)] = 0;
- balances[_to][address(i_WETH)] = 0;
}
function _refundETH(address payable _to) internal {
uint256 refundValue = etherBalance[_to];
+ etherBalance[_to] = 0;
_to.transfer(refundValue);
- etherBalance[_to] = 0;
}
Tool Used
Manual Review , VS code , foundry