The BaseChainlinkFunctionsOracle::fulfillRequest
function in the smart contract does not validate the requestId parameter before processing the response. This allows outdated responses to override the latest one, leading to unintended behavior and inaccurate price updates.
The BaseChainlinkFunctionsOracle::fulfillRequest
function is responsible for processing the responses from Chainlink. However, it does not verify whether the requestId
matches the expected s_lastRequestId
before storing the response and error values:
Code Reference: https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/oracles/BaseChainlinkFunctionsOracle.sol#L99
According to Chainlink’s official documentation, a proper implementation should include request ID verification:
Documentation Reference: https://docs.chain.link/chainlink-functions/tutorials/abi-decoding#examine-the-code
The issue occurs in the following sequence:
The owner calls sendRequest
, receiving s_lastRequestId
= 3.
The owner calls sendRequest
again, updating s_lastRequestId
to 4.
Due to execution delays, Chainlink fulfills request ID 4 first and updates the response.
Chainlink then fulfills request ID 3, which is outdated but still processed because there is no validation.
The outdated response overwrites the correct response, leading to incorrect price updates and potential financial loss.
Incorrect Data Updates: The contract may store an outdated response, leading to incorrect decision-making in dependent logic.
Financial Risks: If price updates are used for financial transactions, an outdated response could result in mispriced trades or inaccurate settlements.
Manual Review
To mitigate this issue, implement a request ID validation check in BaseChainlinkFunctionsOracle::fulfillRequest
as follows:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.