Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: medium
Valid

LLMOracleCoordinator::validate() is missing check for maximum score

Summary

Vulnerability Details

The documentation stipulates that LLMOracleCoordinator::validate function should revert if any score is greater than the maximum score, but there is no such check in the function implementation.

File: contracts/llm/LLMOracleCoordinator.sol#L252-L306
/// @notice Validate requests for a given taskId.
/// @dev Reverts if the task is not pending validation.
/// @dev Reverts if the number of scores is not equal to the number of generations.
/// @dev Reverts if any score is greater than the maximum score. /// <--@
/// @param taskId The ID of the task to validate.
/// @param nonce The proof-of-work nonce.
/// @param scores The validation scores for each generation.
/// @param metadata Optional metadata for this validation.
function validate(uint256 taskId, uint256 nonce, uint256[] calldata scores, bytes calldata metadata)
public
onlyRegistered(LLMOracleKind.Validator)
onlyAtStatus(taskId, TaskStatus.PendingValidation)
{
TaskRequest storage task = requests[taskId];
// ensure there is a score for each generation
if (scores.length != task.parameters.numGenerations) {
revert InvalidValidation(taskId, msg.sender);
}
// ensure validator did not participate in generation
for (uint256 i = 0; i < task.parameters.numGenerations; i++) {
if (responses[taskId][i].responder == msg.sender) {
revert AlreadyResponded(taskId, msg.sender);
}
}
// ensure validator to be unique for this task
for (uint256 i = 0; i < validations[taskId].length; i++) {
if (validations[taskId][i].validator == msg.sender) {
revert AlreadyResponded(taskId, msg.sender);
}
}
// check nonce (proof-of-work)
assertValidNonce(taskId, task, nonce);
// update validation scores
validations[taskId].push(
TaskValidation({scores: scores, nonce: nonce, metadata: metadata, validator: msg.sender})
);
// emit validation event
emit Validation(taskId, msg.sender);
// update completion status
bool isCompleted = validations[taskId].length == task.parameters.numValidations;
if (isCompleted) {
task.status = TaskStatus.Completed;
emit StatusUpdate(taskId, task.protocol, TaskStatus.PendingValidation, TaskStatus.Completed);
// finalize validation scores
finalizeValidation(taskId);
}
}

Impact

Invalid scores may process and compromise the integrity of the validation process.

Tools Used

Manual review.

Recommendations

Add the following snippet to the function implementation

for (uint256 i = 0; i < scores.length; i++) {
require(scores[i] <= MAX_SCORE, "Invalid score");
}
Updates

Lead Judging Commences

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

Unbounded score values in `validate` function

Support

FAQs

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