Core Contracts

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

Lack of Price Validation

Summary

The setHousePrice function lacks price validation mechanisms, allowing arbitrary price values to be set without any bounds checking or rate limiting.

Proof of Concept

const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("RAACHousePrices Price Validation", function () {
let prices;
let owner;
let oracle;
beforeEach(async function () {
[owner, oracle] = await ethers.getSigners();
const RAACHousePrices = await ethers.getContractFactory("RAACHousePrices");
prices = await RAACHousePrices.deploy(owner.address);
await prices.deployed();
// Set oracle
await prices.connect(owner).setOracle(oracle.address);
});
it("allows setting extreme prices", async function () {
// Set unreasonably high price
const extremePrice = ethers.utils.parseEther("999999999999999999");
await prices.connect(oracle).setHousePrice(1, extremePrice);
// Set zero price
await prices.connect(oracle).setHousePrice(2, 0);
// Verify prices were set
const [price1] = await prices.getLatestPrice(1);
const [price2] = await prices.getLatestPrice(2);
expect(price1).to.equal(extremePrice);
expect(price2).to.equal(0);
});
it("allows extreme price changes", async function () {
// Set initial price
await prices.connect(oracle).setHousePrice(1, ethers.utils.parseEther("100000"));
// Change price by 1000x in next update
await prices.connect(oracle).setHousePrice(1, ethers.utils.parseEther("100000000"));
});
});

Impact

Severity: Medium

  • Malicious or compromised oracle can set arbitrary prices

  • No protection against flash crashes or price spikes

  • Zero prices can break calculations in dependent contracts

  • No rate limiting between updates

Recommended Fix

contract RAACHousePrices is Ownable {
uint256 public constant MAX_PRICE = 1_000_000_000 * 1e18; // $1B
uint256 public constant MIN_PRICE = 1000 * 1e18; // $1000
uint256 public constant MAX_PRICE_CHANGE_PERCENTAGE = 20; // 20%
uint256 public constant MIN_UPDATE_INTERVAL = 1 hours;
mapping(uint256 => uint256) public lastTokenUpdateTime;
function setHousePrice(uint256 _tokenId, uint256 _amount) external onlyOracle {
require(_amount >= MIN_PRICE, "Price too low");
require(_amount <= MAX_PRICE, "Price too high");
require(
block.timestamp >= lastTokenUpdateTime[_tokenId] + MIN_UPDATE_INTERVAL,
"Update too frequent"
);
uint256 oldPrice = tokenToHousePrice[_tokenId];
if (oldPrice > 0) {
uint256 changePercentage = _amount > oldPrice
? ((_amount - oldPrice) * 100) / oldPrice
: ((oldPrice - _amount) * 100) / oldPrice;
require(
changePercentage <= MAX_PRICE_CHANGE_PERCENTAGE,
"Price change too large"
);
}
tokenToHousePrice[_tokenId] = _amount;
lastTokenUpdateTime[_tokenId] = block.timestamp;
lastUpdateTimestamp = block.timestamp;
emit PriceUpdated(_tokenId, _amount);
}
}

Tools Used

  • Manual code review

  • Hardhat test suite

  • Protocol documentation analysis

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 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!