Summary
The FeeCollector::emergencyWithdraw function fails to ensure reliable emergency withdrawals when handling non-standard tokens (e.g., tokens with blacklist mechanisms). If the predefined treasury address is blacklisted by the token contract, emergency withdrawals will irreversibly fail, potentially resulting in fund loss.
Vulnerability Details
function emergencyWithdraw(address token) external override whenPaused {
if (!hasRole(EMERGENCY_ROLE, msg.sender)) revert UnauthorizedCaller();
if (token == address(0)) revert InvalidAddress();
uint256 balance;
if (token == address(raacToken)) {
balance = raacToken.balanceOf(address(this));
raacToken.safeTransfer(treasury, balance);
} else {
balance = IERC20(token).balanceOf(address(this));
SafeERC20.safeTransfer(IERC20(token), treasury, balance); <==@found
}
emit EmergencyWithdrawal(token, balance);
}
Impact
Tools Used
Recommendations
Implement Flexible Recipient Parameter:
- function emergencyWithdraw(address token) external override whenPaused {
+ function emergencyWithdraw(address token,address recipient) external override whenPaused {
if (!hasRole(EMERGENCY_ROLE, msg.sender)) revert UnauthorizedCaller();
if (token == address(0)) revert InvalidAddress();
+ if (recipient == address(0)) revert InvalidAddress();
uint256 balance;
if (token == address(raacToken)) {
balance = raacToken.balanceOf(address(this));
- raacToken.safeTransfer(treasury, balance);
+ raacToken.safeTransfer(recipient, balance);
} else {
balance = IERC20(token).balanceOf(address(this));
- SafeERC20.safeTransfer(IERC20(token), treasury, balance);
+ SafeERC20.safeTransfer(IERC20(token), recipient, balance);
}
emit EmergencyWithdrawal(token, balance);
}