Core Contracts

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

Request ID Mismatch when fulfilling request of RAACHousePriceOracle could lead to setting wrong house prices

Summary

When response is processed in RAACHousePriceOracle::_processResponse (as the request is fulfilled) there is no validation to ensure that a price corresponds to the house id which may lead to interchanging house prices.

Vulnerability Details

When a price update is requested through BaseChainlinkFunctionsOracle::sendRequest(), it stores the request ID and immediately calls _beforeFulfill(), which in RAACHousePriceOracle saves the target house ID in a single state variable lastHouseId.

When responses arrive through fulfillRequest(), they're processed without verifying if the response matches the last request made s_lastRequestId. The response processing uses the current value of lastHouseId to update house prices in the RAACHousePriceOracle::_processResponse() function. Since lastHouseId gets overwritten with each new request and responses can arrive in any order, prices could be set for the wrong houses.

Due to network conditions or other factors, responses could arrive in a different order than requests were sent, leading to price updates being applied to wrong houses.

PoC

  1. Oracle sends request A for House 1 (price: $100k), stores requestId_A in s_lastRequestId

  2. Oracle sends request B for House 2 (price: $200k), stores requestId_B in s_lastRequestId

  3. Due to network conditions, response for request A arrives after request B

  4. fulfillRequest processes response A ($100k) but associates it with House 2 since lastHouseId was set by request B

  5. House 2 gets incorrectly priced at $100k instead of $200k

Impact

House prices could be set incorrectly, leading to incorrect loan valuations and potential financial losses.

Tools Used

Manual code review

Recommendations

Add request ID validation in fulfillRequest:

function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override {
require(s_lastRequestId == requestId, "Unexpected request ID");
s_lastResponse = response;
s_lastError = err;
if (err.length == 0) {
if (response.length == 0) {
revert FulfillmentFailed();
}
_processResponse(response);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Oracle Race Condition in RAACHousePriceOracle causes price misassignment between NFTs

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Oracle Race Condition in RAACHousePriceOracle causes price misassignment between NFTs

Support

FAQs

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

Give us feedback!