Dria

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

Validator Can Manipulate Scores by Using Multiple Addresses

Relevant Context

The LLMOracleCoordinator contract implements a validation system where validators score the outputs from generators. To prevent collusion, the contract attempts to prevent generators from validating their own outputs by checking if the validator's address matches any generator's address for the task.

Finding Description

The validation system in validate() attempts to prevent generators from validating their own outputs through a simple address check:

for (uint256 i = 0; i < task.parameters.numGenerations; i++) {
if (responses[taskId][i].responder == msg.sender) {
revert AlreadyResponded(taskId, msg.sender);
}
}

However, this check is insufficient as it only compares the validator's address (msg.sender) with the generator addresses. A malicious actor can easily bypass this by using different addresses for generation and validation. This allows them to:

  1. Generate output using Address A

  2. Validate their own output using Address B

  3. Manipulate scores to favor their own generation

This undermines the core security assumption of the protocol that generators cannot influence the validation of their own outputs.

Impact Explanation

High. This vulnerability allows malicious actors to bypass a critical security mechanism designed to prevent collusion between generators and validators. By manipulating validation scores, they can:

  • Ensure their generations receive high scores

  • Potentially earn both generation and validation fees

  • Manipulate which response becomes the "best" response

  • Undermine the integrity of the entire oracle system

Likelihood Explanation

High. The attack is:

  • Easy to execute (only requires controlling multiple addresses)

  • Requires no special conditions

  • Has low cost (just normal transaction fees)

  • Provides clear financial incentives

Proof of Concept

  1. Attacker creates two addresses: A (generator) and B (validator)

  2. Address A submits a generation response via respond()

  3. Address B participates as a validator via validate()

  4. Address B can now assign favorable scores to Address A's generation

Recommendation

Implement a more robust validation system that tracks relationships between addresses. Some possible approaches:

  1. Require validators to stake tokens and have a reputation system that can be slashed if manipulation is detected

  2. Implement a random selection system for validators that makes it difficult to predict or influence who will validate a specific task

  3. Track historical relationships between addresses and prevent addresses that frequently interact from participating in the same tasks

Example implementation for tracking historical relationships:

mapping(address => mapping(address => uint256)) public lastInteraction;
uint256 public constant COOLDOWN_PERIOD = 7 days;
function validate(uint256 taskId, uint256 nonce, uint256[] calldata scores) public {
TaskRequest storage task = requests[taskId];
// Check historical interactions with all generators
for (uint256 i = 0; i < responses[taskId].length; i++) {
address generator = responses[taskId][i].responder;
if (block.timestamp - lastInteraction[msg.sender][generator] < COOLDOWN_PERIOD) {
revert RecentInteraction(msg.sender, generator);
}
}
// Rest of the validation logic...
}
Updates

Lead Judging Commences

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

There is no oracle whitelisting

Support

FAQs

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