Core Contracts

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

`MarketCreator` distribute the rewards unfairly and lead to corruption of service

Summary

The issue arises because the MarketCreator contract fails to decrement the market.reward value when users redeem their rewards. This leads to an inconsistency where the stored market.reward value remains artificially high, even after redemptions, causing the contract to incorrectly report available rewards. Over time, this discrepancy can result in redemption attempts that exceed the contract's actual balance, causing transactions to revert and potentially leading to a DOS for users.

Vulnerability Details

The MarketCreator contract allows users to redeem their assets and rewards after the lock duration expires. However, the market.reward value is not properly decremented when rewards are claimed. This results in:

  • Stale Reward Value: The market.reward remains unchanged even after redemptions, causing subsequent users to calculate their rewards based on an inflated, incorrect value.

  • Failed Transactions: When users attempt to redeem rewards, raacToken.safeTransfer(msg.sender, reward) may revert due to insufficient contract balance, as the actual available rewards are lower than the reported market.reward.

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;
delete userPositions[marketId][msg.sender];
market.quoteAsset.safeTransfer(msg.sender, amount);
raacToken.safeTransfer(msg.sender, reward); <@
emit Redeemed(marketId, msg.sender, amount, reward);
}
function calculateReward(uint256 marketId, uint256 amount) internal view returns (uint256) {
Market storage market = markets[marketId];
return (amount * market.reward) / market.totalDeposits; <@
}

Impact

  • User funds may become stuck in the contract

  • Rewards are distributed unfairly.

Tools Used

Manual audit

Recommendations

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.reward -= amount; // Fix: Update the total reward
market.totalDeposits -= amount;
delete userPositions[marketId][msg.sender];
market.quoteAsset.safeTransfer(msg.sender, amount);
raacToken.safeTransfer(msg.sender, reward);
emit Redeemed(marketId, msg.sender, amount, reward);
}
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!