Core Contracts

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

Incorrect Token Decimal Handling in RAACNFT Minting

Summary

The RAACNFT.mint() function assumes that the house price and the payment token amount are in the same decimal format, which could lead to incorrect payment processing when using tokens with different decimal places (e.g., USDC with 6 decimals vs. price oracle reporting in 18 decimals).

Vulnerability Details

The vulnerability stems from the direct comparison between the oracle-provided house price and the user's token payment amount without accounting for potential decimal differences:

function mint(uint256 _tokenId, uint256 _amount) public override {
uint256 price = raac_hp.tokenToHousePrice(_tokenId);
if (price == 0) revert RAACNFT__HousePrice();
@> if (price > _amount) revert RAACNFT__InsufficientFundsMint();
@> token.safeTransferFrom(msg.sender, address(this), _amount);
// ... rest of the function
}

The oracle reports house prices in 18 decimals, but the payment token could be USDC (6 decimals) or another token with different decimal places.

The code directly compares price and _amount without any decimal normalization:

if (price > _amount) revert RAACNFT__InsufficientFundsMint();

The refund calculation is also affected:

if (_amount > price) {
uint256 refundAmount = _amount - price;
token.safeTransfer(msg.sender, refundAmount);
}

For example, if the house price is 100,000 USD (reported as 100_000 * 10^18 by the oracle), and the user pays with USDC (100_000 * 10^6), the transaction would revert due to insufficient funds, even though the correct amount was provided.

PoC

  1. Oracle sets house price for tokenId 1 as 100,000 USD (100_000 * 10^18)

  2. Alice attempts to mint tokenId 1 using USDC (6 decimals)

  3. Alice approves and sends 100,000 USDC (100_000 * 10^6)

  4. Transaction reverts with RAACNFT__InsufficientFundsMint() because 100_000 * 10^6 < 100_000 * 10^18

Impact

  • Users cannot mint NFTs when using tokens with fewer decimals than the oracle's price format

  • Potential overcharging or undercharging when using tokens with different decimal places

  • Incorrect refund calculations leading to lost funds

Tools Used

Manual code review

Recommendations

Add a decimal scaling factor in the contract to normalize between oracle prices and token decimals:

uint256 private constant PRICE_DECIMALS = 18;
function mint(uint256 _tokenId, uint256 _amount) public {
uint256 price = raac_hp.tokenToHousePrice(_tokenId);
uint256 tokenDecimals = IERC20Metadata(address(token)).decimals();
uint256 scaledPrice = price * (10 ** tokenDecimals) / (10 ** PRICE_DECIMALS);
if (scaledPrice > _amount) revert RAACNFT__InsufficientFundsMint();
// ... rest of the function
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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