Hawk High

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

No way to track expelled students across school years in LevelOne contract meaning they can re-enroll

Summary

The LevelOne contract lacks a persistent mechanism to track expelled students across school years/deployments. When a student is expelled, their status is only removed for the current contract instance, allowing them to re-enroll in subsequent school years when a new contract is deployed.

Vulnerability Details

The LevelOne contract fails to maintain any record of past expulsions, treating expelled students as if they were never part of the system. This allows a student who has been expelled for disciplinary reasons to simply re-enroll in a subsequent session.

Root Cause

When a student is expelled via the expel() function, the contract only:

  • Removes them from the listOfStudents array

  • Sets their isStudent[address] mapping to false

The contract maintains no persistent record that this student was expelled rather than simply unenrolled or graduated.

Proof of Concept

function testExpel() public schoolInSession {
vm.startPrank(principal);
levelOneProxy.expel(harriet);
vm.stopPrank();
assert(levelOneProxy.isStudent(harriet) == false);
}
function testExpelledStudentcanReEnroll() public{
vm.startPrank(harriet);
usdc.approve(address(levelOneProxy), schoolFees);
levelOneProxy.enroll();
vm.stopPrank();
assert(levelOneProxy.isStudent(harriet) == true);
}

A student expelled in one contract/school session can freely enroll in a new school session as their expulsion is not tracked after the act.

Impact

  1. Circumvention of Disciplinary Actions: Expulsion loses its effectiveness as a permanent disciplinary measure.

  2. Authority Undermining: The principal's authority to permanently remove problematic students is compromised.

  3. Reputational Risk: Schools cannot maintain consistent disciplinary standards across academic years.

Tools Used

  • Foundry

  • Manual code review

  • Test functions demonstrating enrollment capabilities (testExpel and testExpelledStudentcanReEnroll)

Recommendations

Implementing a permanent record of expelled students using the below approach:

// Add permanent record
mapping(address => bool) public hasBeenExpelled;
// Update expel function
function expel(address _student) public onlyPrincipal {
// Existing code...
hasBeenExpelled[_student] = true;
// Existing code...
}
// Update enroll function
function enroll() external notYetInSession {
// Existing checks...
if (hasBeenExpelled[msg.sender]) {
revert HH__PreviouslyExpelled();
}
// Rest of enrollment logic...
}
Updates

Lead Judging Commences

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

Support

FAQs

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