Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: medium
Valid

`Storage Collisions` due to reordered state variables in implementation contracts

Summary

Reordering the state varibales in the upgradeable implementation contracts can lead to storage collisions, modifying the contract state. This happens because of the proxy contract retain the original storage layout but the new implementation contracts introduces the mismatched layout, resulting in unintended overwrites and unpredictable behaviour.

Vulnerability Details

There is a mismatch in the order of state variables declared in LevelOne.sol and LevelTwo.sol. This leads to storage collisions and unpredictable behaviour.

state variables in LevelOne.sol:LevelOne contract

address principal;
bool inSession;
uint256 schoolFees;
uint256 public immutable reviewTime = 1 weeks;
uint256 public sessionEnd;
uint256 public bursary;
uint256 public cutOffScore;
mapping(address => bool) public isTeacher;
mapping(address => bool) public isStudent;
mapping(address => uint256) public studentScore;
mapping(address => uint256) private reviewCount;
mapping(address => uint256) private lastReviewTime;
address[] listOfStudents;
address[] listOfTeachers;

state variables in LevelTwo.sol:LevelTwo contract

address principal;
bool inSession;
//state variables order mismatch
uint256 public sessionEnd;
uint256 public bursary;
uint256 public cutOffScore;
mapping(address => bool) public isTeacher;
mapping(address => bool) public isStudent;
mapping(address => uint256) public studentScore;
address[] listOfStudents;
address[] listOfTeachers;

let's see how storage is modified

LevelOne
slot - value
0 principal
0 inSession
- 1 schoolFees
- 2 sessionEnd
- 3 bursary
- 4 cutOffScore
- 5 ...........
LevelTwo
slot - value
0 principal
0 inSession
- 1 sessionEnd
- 2 bursary
- 3 cutOffScore
- 4 ............

We can clearly see that the values in

  • slot 1 (schoolFees) is overwritten with sessionEnd

  • slot2 (sessionEnd) with bursary

  • slot3 (bursary) with cutOffScore

Impact

This causes the contract to read incorrect values from storage, leading to unintended and unpredictable behavior.

Tools Used

  • Manual Analysis

  • Foundry

Recommendations

Maintain the same variable order in all implementation versions.

Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Validated
Assigned finding tags:

storage collision

Support

FAQs

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