LLMOracleManager:getFee calculates totalFee, generatorFee and validatorFee. An incorrect bitwise operation scales generationFee and validationFee by $2^{\text{difficulty + 1}}$ leading to excessive fee escalation, even when the task difficulty is 0.
As the documentation states, the LLM Oracle nodes listen to LLMOracleCoordinator to wait for generation and validation requests.
Once a request is received, they do a proof-of-work via a cryptographic hash function that results in a sufficiently small digest. How small this target value is expected to be is determined by the difficulty value of the task. The target value for the proof-of-work is computed by:
given a taskId and a nonce, LLMOracleCoordinator:assertValidNonce function checks that proof-of-work is valid:
https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/llm/LLMOracleManager.sol#L110-L120
The following table shows how the target diminishes exponentially with the difficulty
| Difficulty | Target | Target Reduction Factor |
|---|---|---|
| 0 | 115792089237316195423570985008687907853269984665640564039457584007913129639935 | 1 |
| 1 | 57896044618658097711785492504343953926634992332820282019728792003956564819967 | 2 |
| 2 | 28948022309329048855892746252171976963317496166410141009864396001978282409983 | 4 |
| 3 | 14474011154664524427946373126085988481658748083205070504932198000989141204991 | 8 |
| 4 | 7237005577332262213973186563042994240829374041602535252466099000494570602495 | 16 |
| 5 | 3618502788666131106986593281521497120414687020801267626233049500247285301247 | 32 |
| 6 | 1809251394333065553493296640760748560207343510400633813116524750123642650623 | 64 |
| 7 | 904625697166532776746648320380374280103671755200316906558262375061821325311 | 128 |
| 8 | 452312848583266388373324160190187140051835877600158453279131187530910662655 | 256 |
| 9 | 226156424291633194186662080095093570025917938800079226639565593765455331327 | 512 |
| 10 | 113078212145816597093331040047546785012958969400039613319782796882727665663 | 1024 |
The following table shows how the fee scales with the difficulty using the LLMOracleManager:getFee function. To demonstrate the fee scaling,
generationFee and validationFee are set to 1 in the LLMOracleCoordinator contract.
| Difficulty | Generator Fee | Validator Fee |
|---|---|---|
| 0 | 2 | 2 |
| 1 | 4 | 4 |
| 2 | 8 | 8 |
| 3 | 16 | 16 |
| 4 | 32 | 32 |
| 5 | 64 | 64 |
| 6 | 128 | 128 |
| 7 | 256 | 256 |
| 8 | 512 | 512 |
| 9 | 1024 | 1024 |
| 10 | 2048 | 2048 |
Comparing the two tables, it is observed that the fees are scaling by $2^{\text{difficulty + 1}}$ instead of $2^{\text{difficulty}}$. This escalates the fees when the difficulty is 0.
This escalation is a result of the bitwise operation in the getFee function:
https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/llm/LLMOracleManager.sol#L110-L120
Steps to reproduce:
Inside the protocol directory:
Run npm i --save-dev @nomicfoundation/hardhat-foundry to install the hardhat-foundry plugin.
Add require("@nomicfoundation/hardhat-foundry"); to the top of the hardhat.config.js file.
Run npx hardhat init-foundry in the terminal. This will generate a foundry.toml file based on the Hardhat project’s existing configuration, and will install the forge-std library.
Create a file ("LLMOracleCoordinatorTest.t.sol") in ./test/ directory.
Copy the provided test case into the file.
Excessive fees are charged for generation and validation tasks
Manual review
Change the getFee function to scale the fees by $2^{\text{difficulty}}$ instead of $2^{\text{difficulty + 1}}$
With this change, fees are scaled according to the target reduction factor, and the fees are not scaled when the difficulty is 0.
After the change, the fees will scale as follows:
generationFee and validationFee are set to 1 in the LLMOracleCoordinator contract to demonstrate the fee scaling.
| Difficulty | Generator Fee | Validator Fee |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 2 | 2 |
| 2 | 4 | 4 |
| 3 | 8 | 8 |
| 4 | 16 | 16 |
| 5 | 32 | 32 |
| 6 | 64 | 64 |
| 7 | 128 | 128 |
| 8 | 256 | 256 |
| 9 | 512 | 512 |
| 10 | 1024 | 1024 |
note that there is no scaling when the difficulty is 0.
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.