Summary
LLMOracleCoordinator::getBestResponse() will always revert, since it is view function and tries to modify the state of the blockchain
Vulnerability Details
As seen in the block of code bellow, taskRequestis storage pointer the public responsesmapping. Then after a check, the resultstorage pointer is set to point to the first element of the taskResponsesarray. After that, there is a for loop where the resultstorage pointer is modified. This modification of the storage pointer changes the taskResponcearray, which on its own is a storage pointer the the responsesmapping, which is a modification of the blockchain state.
function getBestResponse(uint256 taskId) external view returns (TaskResponse memory) {
TaskResponse[] storage taskResponses = responses[taskId];
if (requests[taskId].status != LLMOracleTask.TaskStatus.Completed) {
revert InvalidTaskStatus(taskId, requests[taskId].status, LLMOracleTask.TaskStatus.Completed);
}
TaskResponse storage result = taskResponses[0];
uint256 highestScore = result.score;
for (uint256 i = 1; i < taskResponses.length; i++) {
if (taskResponses[i].score > highestScore) {
highestScore = taskResponses[i].score;
@> result = taskResponses[i];
}
}
return result;
}
Impact
This will cause a DoS to both BuyerAgent::updateStateand BuyerAgent::purchasefunctions, because the the call the oracleResultfunction, which on its own calls getBestResponse.
Tools Used
Manual Review
Recommendations
Change the result pointer from storage to memory like this:
function getBestResponse(uint256 taskId) external view returns (TaskResponse memory) {
TaskResponse[] storage taskResponses = responses[taskId];
// ensure that task is completed
if (requests[taskId].status != LLMOracleTask.TaskStatus.Completed) {
revert InvalidTaskStatus(taskId, requests[taskId].status, LLMOracleTask.TaskStatus.Completed);
}
// pick the result with the highest validation score
- TaskResponse storage result = taskResponses[0];
+ TaskResponse memory result = taskResponses[0];
uint256 highestScore = result.score;
for (uint256 i = 1; i < taskResponses.length; i++) {
if (taskResponses[i].score > highestScore) {
highestScore = taskResponses[i].score;
...