Since the numGenerations
can be equal to 0, the request will never be completed. And any oracle generator can keep on responding to retrieve the generatorFees (Note that the request sender will give 0 fees as numGenerations == 0
, thus other users money will be stolen in the attack mentioned below).
Assume the following scenario:
1. Bob creates a request with the LLMOracleTastParameters as :
difficulty = 1,
numGenerations = 0,
numValidations = 0
2.Thus the fees Bob has to pay will be calculated will be as follows:
(uint256 totalfee, uint256 generatorFee, uint256 validatorFee) = getFee(parameters);
(https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleManager.sol#L110-L120)
Since the numGenerations == 0
, Bob will only have to pay the platformFee
for this request.
3.Thus Bob has created a task by paying just the platformFee
.
4. Now any oracle can respond
for this task.
5. When such an oracle responds to this, since the numValidations == 0
, their allowance is increased and they can withdraw the amount.
6. But the issue occurs, because during the first response, the response[taskId]
array is pushed with the response the oracle provided. Making the responses[taskId].length = 1
(https://github.com/Cyfrin/2024-10-swan-dria/blob/c8686b199daadcef3161980022e12b66a5304f8e/contracts/llm/LLMOracleCoordinator.sol#L225-L238)
7. Therefore when the code tries to check if the generations are completed using isCompleted
, it will give as false
.
Since the responses[taskId].length = 1
and the numGenerations = 0
. Which makes the isCompleted = false
.
So eventhough only 0 generations were asked, an infinite number of generations can be done on such a request.(since responses[taskId].length
will only keep on increasing with more responses, while numGenerations
remains 0). Each generation will cost the generatorFee
which was not deposited by Bob. So an innocent request maker Alice's funds will be taken by Bob.
Thus Bob has deposited only the platformFee
but can withdraw an infinite amount of tokens from the contract. (Using different Oracle generator each time (which can be created easily by staking and unstaking the amount)). Making the likelihood of such an attack high as it is highly incentivized and pretty easy to perform.
Draining of the protocol coupled with stealing tokens from other users can be done. Which is a very high impact.
Manual Review
Make sure that the numGenerations != 0
. This will stop this attack path.
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.