Core Contracts

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

Incorrect Reward Distribution in Market Redemption Process

Relevant Context

The MarketCreator contract implements a market system where users can deposit quote assets and receive RAAC token rewards after a lock period. The reward distribution is proportional to the user's deposit amount relative to the total deposits in the market.

Finding Description

The redeemFromMarket() function contains a critical flaw in its reward distribution mechanism. When users redeem their positions, the function calculates rewards based on the current total deposits but fails to decrease the market's reward pool. This means that subsequent redemptions will calculate rewards using the original reward amount against a decreased total deposit amount, leading to inflated rewards for later redeemers.

The root cause lies in the calculateReward() function, which uses the full market.reward amount for each redemption calculation without accounting for previously distributed rewards. This creates a scenario where the last user to redeem could receive disproportionately large rewards.

Impact Explanation

High. This vulnerability can lead to significant economic implications:

  1. Unfair distribution of rewards, where later redeemers receive more tokens than they should

  2. Potential depletion of the contract's RAAC token balance beyond intended amounts

  3. Possible denial of service for later redeemers if the contract runs out of RAAC tokens

Likelihood Explanation

High. This issue will manifest every time multiple users redeem from the same market with non-zero rewards, making it a frequently occurring problem under normal operation conditions.

Proof of Concept

Consider a market with the following parameters:

  1. Total RAAC reward: 100 tokens

  2. Alice and Bob each deposit 50 quote tokens

  3. Total deposits: 100 quote tokens

Sequence of events:

  1. Alice redeems first:

    • calculateReward() returns: (50 * 100) / 100 = 50 RAAC tokens

    • totalDeposits reduces to 50

  2. Bob redeems second:

    • calculateReward() returns: (50 * 100) / 50 = 100 RAAC tokens

    • Total rewards distributed: 150 RAAC tokens (50 + 100)

The intended distribution should have been 50 RAAC tokens each, totaling 100 RAAC tokens.

Recommendation

Update the redeemFromMarket() function to decrease the market's reward pool after each redemption:

function redeemFromMarket(uint256 marketId) external nonReentrant {
Market storage market = markets[marketId];
UserPosition storage position = userPositions[marketId][msg.sender];
require(position.exists, "No position found");
require(block.timestamp >= position.lockEndTime, "Lock duration has not passed");
uint256 amount = position.amount;
uint256 reward = calculateReward(marketId, amount);
market.totalDeposits -= amount;
market.reward -= reward; // Decrease the reward pool
delete userPositions[marketId][msg.sender];
market.quoteAsset.safeTransfer(msg.sender, amount);
raacToken.safeTransfer(msg.sender, reward);
emit Redeemed(marketId, msg.sender, amount, reward);
}

This solution ensures that rewards are calculated based on the remaining reward amount, maintaining fair distribution among all participants.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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

Give us feedback!