Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Valid

Unclaimed Rewards lost after emergency withdraw

Overview

In the feeCollector contract there is a function that allows the user with emergency role to call the emergencyWithdraw function

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);
}
emit EmergencyWithdrawal(token, balance);
}

However, there are no calls that ensure that users rewards are handled appropriately. below is a function user calls to claim rewards

function claimRewards(address user) external override nonReentrant whenNotPaused returns (uint256) {
if (user == address(0)) revert InvalidAddress();
uint256 pendingReward = _calculatePendingRewards(user);
if (pendingReward == 0) revert InsufficientBalance();
// Reset user rewards before transfer
userRewards[user] = totalDistributed;
// Transfer rewards
raacToken.safeTransfer(user, pendingReward);
emit RewardClaimed(user, pendingReward);
return pendingReward;
}

When emergencyWithdraw is called if users are yet to claim rewards the rewards will be lost in the process

Impact

Loss or rewards

Recommendation

Before calling emergency withdraw add logic to ensure rewards are also collected in the process

Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

FeeCollector::emergencyWithdraw sends all tokens to treasury without resetting collectedFees, breaking rewards and future distributions

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

FeeCollector::emergencyWithdraw sends all tokens to treasury without resetting collectedFees, breaking rewards and future distributions

Support

FAQs

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