Core Contracts

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

Unchecked Refund Math Enables Token Extraction in RAAC Real Estate NFTs

Summary

The RAACNFT contract's refund mechanism contains a potential issue where users minting NFTs could receive incorrect refund amounts.

Vulnerability Details

When users mint real estate NFTs, they can overpay and receive incorrect refund amounts, potentially draining protocol funds through precision manipulation. Notice how the RAAC protocol handles real estate tokenization, users mint NFTs by paying RAAC tokens based on house prices from the oracle. The mistake is in the refund mechanism. When Alice wants to mint an NFT worth 100 RAAC tokens but sends 150 tokens, she should receive exactly 50 tokens back. However, the current implementation fails to properly validate this mathematical relationship.

The issue manifests in the interaction between RAACNFT.sol and RAACHousePrices.sol. Here's what happens: RAACNFT.sol#mint

function mint(uint256 _tokenId, uint256 _amount) public override {
// INTERACTION POINT 1: Price Oracle Check
// Calls external RAACHousePrices contract to get the house price
// Critical assumption: Price is valid and non-zero
uint256 price = raac_hp.tokenToHousePrice(_tokenId);
// VALIDATION POINT 1: Price Existence
// Ensures house price exists in oracle
if(price == 0) { revert RAACNFT__HousePrice(); }
// VALIDATION POINT 2: Payment Sufficiency
// Checks if user sent enough tokens
if(price > _amount) { revert RAACNFT__InsufficientFundsMint(); }
// INTERACTION POINT 2: Token Transfer
// Takes payment from user
// Risk: Full amount transferred before NFT mint
token.safeTransferFrom(msg.sender, address(this), _amount);
// INTERACTION POINT 3: NFT Minting
// Creates the real estate NFT
_safeMint(msg.sender, _tokenId);
// VULNERABLE POINT: Refund Calculation
// No maximum overpayment check
// No validation of refund amount correctness
if (_amount > price) {
uint256 refundAmount = _amount - price;
token.safeTransfer(msg.sender, refundAmount);
}
// EVENT: Transaction Record
emit NFTMinted(msg.sender, _tokenId, price);
}

We can see the vulnerability lies in the refund calculation section where the contract:

  1. Accepts any overpayment amount without upper bounds

  2. Performs unchecked subtraction for refund calculation

  3. Sends refund without validating the mathematical relationship between price, payment, and refund

This creates a direct path for potential token extraction through carefully crafted input values.

This means that refund calculation relies entirely on the difference between sent amount and house price, without additional safeguards. An attacker could manipulate these values to extract more tokens than they should receive.

Impact

When users mint NFTs representing real estate, they interact with two key components, the RAACNFT contract and the RAACHousePrices oracle. This means that every minting operation involves a complex dance of price verification, token transfers, and refund calculations. The current implementation creates a gap between these steps that could lead to incorrect refund amounts.

The RAACHousePrices oracle provides the fundamental price feed that determines NFT values. When Alice overpays for an NFT, the protocol should return exactly the difference between her payment and the house price. However, the unchecked refund calculation in the mint function creates a vulnerability in this core economic mechanism.

This vulnerability directly affects the protocol's ability to maintain accurate real estate value representation on-chain. Think of it as a real estate transaction where the escrow system occasionally returns more money than the overpayment amount, yyou see this breaks the fundamental trust in the tokenization process.

Recommendations

Implement proper validation while maintaining the protocol's elegant simplicity. By adding maximum overpayment limits and strict refund validation, we can preserve the core functionality while preventing potential economic exploits.

// RAACNFT.sol interacts with RAACHousePrices.sol for price feeds
function mint(uint256 _tokenId, uint256 _amount) public override {
// Flow 1: Price Retrieval
// RAACNFT -> IRAACHousePrices -> RAACHousePrices
// Gets real estate price from oracle
uint256 price = raac_hp.tokenToHousePrice(_tokenId);
// Flow 2: Price Validation
// Basic checks but missing maximum bounds
if(price == 0) { revert RAACNFT__HousePrice(); }
if(price > _amount) { revert RAACNFT__InsufficientFundsMint(); }
// Flow 3: Payment Processing
// Transfers full amount before validation
token.safeTransferFrom(msg.sender, address(this), _amount);
_safeMint(msg.sender, _tokenId);
// Flow 4: Refund Processing - Vulnerability Point
// Key Issues:
// 1. No maximum _amount limit
// 2. Direct subtraction without bounds check
// 3. Immediate refund without additional validation
if (_amount > price) {
uint256 refundAmount = _amount - price;
token.safeTransfer(msg.sender, refundAmount);
}
emit NFTMinted(msg.sender, _tokenId, price);
}

The vulnerability exists in the interaction between these contracts:

  • RAACNFT.sol relies on RAACHousePrices.sol for pricing

  • IRAACHousePrices.sol defines the interface for price lookups

  • The refund calculation happens entirely in RAACNFT.sol without additional validation from RAACHousePrices.sol

Secure implementation would add:

// Add maximum overpayment protection
require(_amount <= price * 2, "Excessive payment");
// Validate refund calculation
require(refundAmount == _amount - price, "Invalid refund");
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!