Dria

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

Misssing Gap To Avoid Storage Collisions

Summary

The LLMOracleCoordinator and Swan contracts are upgradable smart contracts that inherit from LLMOracleManager and SwanManager contracts, respectively. If storage variables are added to either LLMOracleManager or SwanManager, they will cause a storage collision with the corresponding inherited contracts, potentially resulting in overwritten storage and data corruption.

Vulnerability Details

Taking LLMOracleCoordinator as an example:

Since LLMOracleCoordinator inherits from the LLMOracleManager contract, we can inspect the storage slots as follows using a Foundry command:

forge inspect LLMOracleCoordinator storage --pretty

The log output:

| Name | Type | Slot | Offset | Bytes | Contract |
|---------------------------|-----------------------------------------------------------|------|--------|-------|-------------------------------------------------------------|
| platformFee | uint256 | 0 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| generationFee | uint256 | 1 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| validationFee | uint256 | 2 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| validationDeviationFactor | uint64 | 3 | 0 | 8 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| generationDeviationFactor | uint64 | 3 | 8 | 8 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| minimumParameters | struct LLMOracleTaskParameters | 4 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| maximumParameters | struct LLMOracleTaskParameters | 5 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| registry | contract LLMOracleRegistry | 6 | 0 | 20 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| feeToken | contract ERC20 | 7 | 0 | 20 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| nextTaskId | uint256 | 8 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| requests | mapping(uint256 => struct LLMOracleTask.TaskRequest) | 9 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| responses | mapping(uint256 => struct LLMOracleTask.TaskResponse[]) | 10 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |
| validations | mapping(uint256 => struct LLMOracleTask.TaskValidation[]) | 11 | 0 | 32 | contracts/llm/LLMOracleCoordinator.sol:LLMOracleCoordinator |

As shown, the storage slots from 0 to 5 are inherited from LLMOracleManager. The issue arises if any new state variables are added to LLMOracleManager, which could lead to a collision with the existing storage layout of the LLMOracleCoordinator contract.

The same vulnerability occurs in the Swan contract, which is inherited from SwanManager.

Impact

Adding new state variables to LLMOracleManager or SwanManager will overwrite existing storage slots in LLMOracleCoordinator and Swan, causing data corruption and disrupting contract functionality.

Tools Used

Foundry, documentation.

Recommendations

Add a storage gap at the end of both LLMOracleManager and SwanManager contracts to reserve slots for future state variables. This will prevent any new variables from colliding with inherited slots in LLMOracleCoordinator and Swan. Example code for adding a storage gap:

+ uint256[50] private __gap;

This code reserves 50 storage slots, ensuring that future additions to LLMOracleManager or SwanManager do not interfere with inherited storage.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Appeal created

yaioxy Submitter
7 months ago
inallhonesty Lead Judge
7 months ago
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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