Core Contracts

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

In StabilityPool, all rewards can be stolen by flashloan attack

Summary

The StabilityPool contract allows users to deposit rToken and receive deToken in return, while also distributing RAAC rewards based on the proportion of a user's stake relative to the total stake. However, the current implementation of the reward calculation (calculateRaacRewards) is vulnerable to Flash Loan attacks, where a user can temporarily stake a large amount of tokens and immediately withdraw them to claim a disproportionate share of the rewards. This issue arises because rewards are distributed solely based on the staking proportion, without considering the staking duration.

Vulnerability Details

The calculateRaacRewards function computes a user's RAAC rewards using the formula:

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 means that simply having a large temporary deposit allows the attacker to claim rewards in the proportional manner calculated.

By utilizing a Flash Loan, an attacker can borrow a significant amount of crvUSD and deposit to LendingPool to receive rToken, immediately stake them in the StabilityPool, and when the rewards are calculated, they would receive rewards corresponding to their temporarily inflated stake. Following this, the attacker can withdraw their rToken in StabilityPool and then burn rToken to receive crvUSD in LendingPool , at last, he can pay back the Flash Loan, pocketing a significant portion of the rewards that were accrued based on their short-time stakes.

Attack Scenario

  1. A user borrows a large amount of crvUSD via a Flash Loan.

  2. The user calls the deposit function in LendingPool to receive rToken.

  3. The user calls the deposit function in StabilityPool to stake the rToken.

  4. The user calls the withdraw function in StabilityPool to unstake the rToken and claim rewards.

  5. the user calls the withdraw function in LendingPool to burn rToken and get back the crvUSD.

  6. The user repays the crvUSD Flash Loan within the same transaction.

Since the reward calculation does not consider the staking duration, the user can claim a significant portion of the rewards despite staking the tokens for only a brief moment.

Impact

All rewards can be stolen. The impact is High, the likelihood is High, so the severity is High.

Tools Used

Manual Review

Recommendations

To address this issue, rewards should be calculated based on both the amount and duration of the stake. Consider adopting a reward distribution mechanism inspired by SushiSwap's MasterChef.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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.