Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

High Severity - Unlimited Student Enrollment in `LevelOne::enroll` (Unbounded Array Growth + DoS Risk)

Summary

The enroll function allows an unlimited number of students to enroll, causing the listOfStudents array to grow indefinitely. This can lead to a denial-of-service (DoS) attack by making the graduateAndUpgrade function unusable due to gas limit constraints.

Vulnerability Details

Root Cause: The enroll function appends to listOfStudents without a cap on the array length.

Attack Path: An attacker enrolls thousands of students, bloating listOfStudents. When graduateAndUpgrade iterates over listOfStudents to distribute wages, it exceeds the gas limit and reverts.

Affected Component: The listOfStudents array and its iteration in graduateAndUpgrade.

Proof of Concept

The following steps outline how an attacker can exploit this vulnerability to cause a DoS attack:

Step 1: The attacker creates or controls a large number of addresses (e.g., 10,000 unique addresses).

Step 2: For each address, the attacker ensures they have sufficient USDC to cover schoolFees (e.g., by minting or acquiring tokens in a test environment).

Step 3: The attacker calls usdc.approve(address(levelOneProxy), schoolFees)` for each address to allow the contract to transfer funds.

Step 4: The attacker iterates over each address and calls levelOneProxy.enroll() to enroll each as a student, adding them to listOfStudents. After 10,000 enrollments, listOfStudents.length becomes 10,000.

Step 5: The Principal starts the session by calling levelOneProxy.startSession(70).

Step 6: After 5 weeks, the Principal attempts to upgrade by calling levelOneProxy.graduateAndUpgrade(address(new LevelTwo()), "").

Expected Result: The graduateAndUpgrade function should complete successfully, distributing wages and upgrading the contract.

Actual Result: The function reverts due to exceeding the block gas limit while iterating over the 10,000 students in listOfStudents to distribute wages, preventing the upgrade.

Impact

Denial-of-Service: Prevents the upgrade to LevelTwo, stalling the system.
Operational Disruption: The school cannot progress to the next level, affecting all users.

Recommendations

Add a maximum student limit to enroll.

+ uint256 public constant MAX_STUDENTS = 1000; // Adjust as needed
function enroll() external notYetInSession {
if (isTeacher[msg.sender] || msg.sender == principal) {
revert HH__NotAllowed();
}
if (isStudent[msg.sender]) {
revert HH__StudentExists();
}
+ require(listOfStudents.length < MAX_STUDENTS, "Max student limit reached");
usdc.safeTransferFrom(msg.sender, address(this), schoolFees);
listOfStudents.push(msg.sender);
isStudent[msg.sender] = true;
studentScore[msg.sender] = 100;
bursary += schoolFees;
emit Enrolled(msg.sender);
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
yeahchibyke Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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