Core Contracts

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

Vampire Attack Risk in RAAC Reward Distribution

Summary

The Stability Pool's calculateRaacRewards() function is vulnerable to a vampire attack, where a whale can front-run reward distribution by executing an atomic deposit and withdrawal to drain the available raacToken rewards. Since the function distributes rewards proportionally based on deposit size at the time of calculation, a large temporary deposit can capture an unfair share of the rewards without maintaining long-term participation.

Vulnerability Details

The function currently calculates RAAC rewards as follows:

StabilityPool.sol#L246-L259

/**
* @notice Calculates the pending RAAC rewards for a user.
* @param user Address of the user.
* @return Amount of RAAC rewards.
*/
function calculateRaacRewards(address user) public view returns (uint256) {
uint256 userDeposit = userDeposits[user];
uint256 totalDeposits = deToken.totalSupply();
uint256 totalRewards = raacToken.balanceOf(address(this));
if (totalDeposits < 1e6) return 0;
return (totalRewards * userDeposit) / totalDeposits;
}

This logic allows for an exploitable scenario:

Step 1. Monitor RAAC reward deposits: An attacker tracks the Stability Pool's balance for newly added rewards, totalRewards = raacToken.balanceOf(address(this)).

Step 2. Front-run deposit: Upon detecting a sizable reward, the attacker deposits a massive amount of rToken, temporarily becoming the dominant depositor, as reflected by userDeposits.

Step 3. Claim rewards: The attacker claims a disproportionate share of raacToken rewards based on their large deposit.

Step 4. Withdraw instantly: The attacker exits the pool right after claiming rewards, leaving long-term depositors with little to no rewards.

StabilityPool.sol#L239-L241

if (raacRewards > 0) {
raacToken.safeTransfer(msg.sender, raacRewards);
}

Since the function does not account for deposit duration or time-weighted staking, this exploit allows RAAC rewards to be drained unfairly, incentivizing short-term participation instead of long-term stability.

Example Attack Scenario

  1. The Stability Pool holds 100,000 RAAC tokens in rewards.

  2. A long-term user has 50,000 rToken deposited, expecting 100% of the rewards (assuming this user is the only depositor where totalDeposits == userDeposit for simplicity).

  3. An attacker deposits 500,000 rToken right before claiming rewards, increasing total deposits to 550,000 rToken.

  4. The attacker's proportional share increases to 90.9%, allowing them to claim 90,900 RAAC tokens.

  5. The attacker immediately withdraws the deposit, leaving the original user with only 9,100 RAAC tokens, instead of the expected 100,000.

Impact

  • Unfair reward distribution: Long-term depositors lose a significant share of RAAC rewards.

  • Discourages stable participation: Encourages speculative deposit behavior rather than sustainable staking.

  • Potential RAAC depletion: Attackers can repeatedly drain RAAC reserves via rapid deposits and withdrawals.

  • Possible reputational damage: The protocol may be perceived as exploitable or unfairly structured.

Tools Used

Manual

Recommendations

To mitigate this vulnerability, the following solutions should be considered to refactor calculateRaacRewards():

Require Minimum Deposit Duration

  • Implement a minimum staking period before rewards can be claimed.

  • Users withdrawing before the required duration forfeit rewards.

Time-Weighted Reward Scaling

  • Scale rewards based on how long a user has been staked.

  • New deposits receive gradually increasing eligibility for rewards over time.

Epoch-Based Reward Distribution

  • Implement an epoch-based system, where rewards are distributed at fixed intervals.

  • Prevents users from claiming rewards in the same block they deposit.

Penalty on Instant Withdrawals

  • Introduce a withdrawal fee for users who exit the pool immediately after depositing.

  • Fees can be redistributed to long-term stakers.

Updates

Lead Judging Commences

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

StabilityPool::calculateRaacRewards is vulnerable to just in time deposits

Support

FAQs

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