Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: low
Invalid

High gas usage due to storage access in `LLMOracleCoordinator::getBestResponse`, causing unnecessary high gas usage when call `BuyerAgent::updateState` and `BuyerAgent::purchase`

Summary

LLMOracleCoordinator::getBestResponse using storage access instead memory

Vulnerability Details

LLMOracleCoordinator.sol#L404-L420

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];
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;
}

this function are intended to be called as part of the core function of Swan Dria protocol.
using storage would impact the gas usage (because of frequent SLOAD and SSTORE) and the gas cost is increased with taskResponses.length which should be correspond to number of generated response by generator.

Impact

The cost of core functions like BuyerAgent::updateState and BuyerAgent::purchase would be high because of BuyerAgent::oracleResult is called which then call the LLMOracleCoordinator::getBestResponse.
This might discourage users from using them as it could offset the profits made from using the protocol.
This also would impact the user experience, because of the unnecessary increase in operational cost.

If the issue is not corrected, beside the user experience, there would be a cap of how many max generator it can have before the gas is incredibly high.

Tools Used

foundry

Recommendations

Change the storage to memory

function getBestResponse(uint256 taskId) external view returns (TaskResponse memory) {
- TaskResponse[] storage taskResponses = responses[taskId];
+ TaskResponse[] memory 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;
result = taskResponses[i];
}
}
return result;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 8 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.