The LevelOne::graduateAndUpgrade
function lacks logic to handle student graduation, which allows the protocol to be upgraded without controlling which students should graduate.
In the LevelOne::graduateAndUpgrade
function, there is no code to manage the graduation of students, which leads to an upgrade of the contract without controlling who should graduate. A student that does not have four reviews or that does not pass the cutOffScore mark is not marked as not graduated, which goes against the protocol intentention. Also, the system does not check that the session has ended to update the system.
This breaks the protocol's invariants and omits a crucial function from the system.
This issue severely breaks the protocol's intended behavior by bypassing a critical function of the system. This will occur every time the system is upgraded.
As will be shown in the Proof of Code, principal
actor is able to call LevelOne::graduateAndUpdate
function in an undesirable scenario in which the student fin
does not outperform LevelOne::cutOffScore
, does not have four reviews in LevelOne::reviewCount
and in which the session has not ended yet.
This test demonstrates a vulnerability that allows the contract upgrade process to proceed even when the necessary conditions for student evaluation are not met. The goal is to bypass validation checks during the session period and confirm that an upgrade can occur undesirably. The steps are as follows:
Increase the cutOffScore
to 100 within the schoolInSession
modifier in the LevelOneGraduateTest.t.sol
contract. This raises the minimum score required for a student to qualify for graduation.
Set the session duration to 1 week, ensuring that the session is still active and has not yet ended (sessionEnd
has not occurred).
Give the student fin
only 1 negative review, resulting in:
Fewer than 4 total reviews (fails the reviewCount
invariant)
A studentScore
lower than the cutOffScore
Trigger the contract upgrade as the principal
, and verify that the upgrade proceeds despite the unmet conditions, thus confirming the vulnerability.
To confirm the vulnerability, apply the following changes in the LevelOneGraduateTest.t.sol
contract:
Update the schoolInSession
modifier by setting the cutOffScore
to 100:
2.Add the following test function to simulate the undesired upgrade:
The issue was discovered through a manual code review.
It is recommended to split the graduation and upgrade functionalities into two distinct functions for better clarity and security of the code.
In the LevelOne.sol
contract, add an array to store all graduated students and a mapping to register whether a student has graduated:
2.Modify the LevelOne::Graduated
event and add an UpgradeToLevelTwo
event:
3.Ensure that LevelOne::reviewCount[_student]
is updated each time a review is submitted within the LevelOne::giveReview
function.
Note: This is an issue which is discussed in detail in a separate submission.
4.Add a LevelOne::graduateStudent
function in the LevelOne.sol
contract that adheres to the protocol's invariants:
5.Update the LevelOne::graduateAndUpgrade
function:
It is recommended to modify the LevelOne::graduateAndUpgrade
function to call the new function graduateStudent
before proceeding with the contract upgrade. This ensures that only students who have completed all the necessary requirements are graduated before the contract upgrade takes place.
By calling graduateStudent
, you can ensure that all necessary graduation conditions are met before allowing any changes or upgrades to the contract, preserving the integrity of the system.
After this, the invariants will be checked, and the LevelOne::graduateAndUpgrade
function should be updated as follows:
Optionally, you can add the new variables to the LevelTwo.sol
contract if they will be used in the updated implementation.
If you do, consider maintaining the same variable declaration order as in the LevelOne.sol
contract, and ensure that variables from the LevelOne.sol
contract are included to avoid storage collisions during the upgrade.
Note: You can check the storage slots by running the following commands in your console:
forge inspect LevelOne storage
to inspect the storage of LevelOne.sol
.
forge inspect LevelTwo storage
to inspect the storage of LevelTwo.sol
.
All students are graduated when the graduation function is called as the cut-off criteria is not applied.
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.