Core Contracts

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

FeeCollector: Unauthorized Reward Claim Exploitation via Missing Access Control in claimRewards()

Summary

The FeeCollector::claimRewards() function lacks sender validation, allowing any address to trigger reward claims for arbitrary users. This violates core security assumptions about reward ownership, enabling direct loss of user rewards and contract state manipulation.

Vulnerability Details

Affected Code:

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();
userRewards[user] = totalDistributed; // State reset
raacToken.safeTransfer(user, pendingReward);
emit RewardClaimed(user, pendingReward);
return pendingReward;
}

Attack Vectors:

  1. Premature Reward Reset
    Any actor can call FeeCollector::claimRewards(alice) when Alice has unclaimed rewards, forcibly resetting her userRewards state to totalDistributed before she chooses to claim. Subsequent legitimate claims by Alice would return 0 until new rewards accumulate.

  2. Front-Running Griefing
    Malicious actors can front-run Alice's legitimate claim transactions, making her transaction revert due to the InsufficientBalance check after state reset.

  3. Tax/Regulatory Manipulation
    Third parties can trigger taxable events for users by forcing reward claims at inopportune times, violating financial privacy assumptions.

Mathematical Proof of Loss
Let:

  • T0 = Initial totalDistributed = 1000 RAAC

  • A_share = 10% of rewards → 100 RAAC earned

  • Attacker triggers early claim at T0

After new distribution:

  • T1 = T0 + 500 = 1500 RAAC

  • A_true_entitlement = 10% of 500 = 50 RAAC

  • A_can_claim = T1 - userRewards[A] = 1500 - 1000 = 500 RAAC

  • Protocol Overpayment = 500 - 50 = 450 RAAC

Result: Protocol's RAAC reserves drained through false entitlements.

Impact

  • Direct Fund Loss: Users may permanently lose access to accrued rewards through state reset attacks

  • System Manipulation: Attackers can artificially suppress reward payouts by resetting user states

  • Protocol Bankruptcy: Mass false claims could drain the contract's RAAC balance if rewards are improperly funded

  • Legal Liability: Unauthorized creation of taxable events violates financial privacy regulations

Tools Used

  1. Manual Code Review identified missing access control

Recommendations

Critical Fixes:

  1. Access Control:

    function claimRewards() external nonReentrant whenNotPaused {
    address user = msg.sender; // Enforce sender ownership
    // ... rest of logic ...
    }
  2. State Management:

    // Track cumulative claimed instead of resetting
    userRewards[user] += pendingAmount;

Supplemental Protections:

  • Implement claim expiration timelines

  • Add multi-sig approval for large withdrawals

  • Introduce claim history tracking

Updates

Lead Judging Commences

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

FeeCollector::claimRewards sets `userRewards[user]` to `totalDistributed` seriously grieving users from rewards

Support

FAQs

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

Give us feedback!