Hawk High

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

Circumvention of Expulsion Mechanism

Executive Summary

The Hawk High School smart contract (LevelOne) contains a critical educational governance vulnerability that allows expelled students to immediately re-enroll in the school. This undermines the disciplinary framework of the institution and creates several vectors for academic integrity violations and economic exploitation of the system.

Detailed Analysis

Contract Logic Flaw

The vulnerability exists in the relationship between the expel() and enroll() functions. When a student is expelled, the contract properly removes them from the current student roster but fails to implement any mechanism to track expelled students or prevent their re-enrollment.

Expulsion Implementation:

function expel(address _student) public onlyPrincipal {
if (inSession == false) {
revert();
}
if (_student == address(0)) {
revert HH__ZeroAddress();
}
if (!isStudent[_student]) {
revert HH__StudentDoesNotExist();
}
uint256 studentLength = listOfStudents.length;
for (uint256 n = 0; n < studentLength; n++) {
if (listOfStudents[n] == _student) {
listOfStudents[n] = listOfStudents[studentLength - 1];
listOfStudents.pop();
break;
}
}
isStudent[_student] = false;
emit Expelled(_student);
}

The function performs these operations:

  1. Removes the student from the listOfStudents array

  2. Sets isStudent[_student] to false

  3. Emits an Expelled event

Enrollment Implementation:

function enroll() external notYetInSession {
if (isTeacher[msg.sender] || msg.sender == principal) {
revert HH__NotAllowed();
}
if (isStudent[msg.sender]) {
revert HH__StudentExists();
}
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);
}

The enrollment function only checks:

  1. That the enrollment occurs when school is not in session

  2. That the address is not a teacher or principal

  3. That the address is not currently a student

Notably absent is any check for previous expulsion status.

Business Impact Analysis

1. Academic Integrity Compromise: The vulnerability enables a cycle where students can:

  • Perform poorly or receive negative reviews

  • Get expelled (resetting their academic record)

  • Re-enroll with a fresh score of 100

  • Repeat as needed to maintain artificially high scores

2. Economic Exploitation: Each re-enrollment requires payment of school fees, which:

  • Creates a potential revenue stream from repeated re-enrollments

  • Distorts the financial model of the school

  • May create perverse incentives where problematic students become profitable

3. Score Manipulation Mechanics: The contract assigns a perfect score to all new enrollees:

studentScore[msg.sender] = 100;

This creates a direct pathway for score manipulation:

  • A student with a score of 60 after negative reviews

  • Gets expelled and re-enrolls

  • Instantly receives a score of 100

  • Effectively gains +40 points through this manipulation

4. Review System Subversion: The contract implements a review system with time limitations:

require(reviewCount[_student] < 5, "Student review count exceeded!!!");
require(block.timestamp >= lastReviewTime[_student] + reviewTime, "Reviews can only be given once per week");

But when a student re-enrolls:

  • Their reviewCount is effectively reset (not explicitly, but the mapping no longer tracks them as having reviews)

  • Their lastReviewTime record is lost

  • This permits bypassing review frequency limitations

Proof of Concept: Expulsion Bypass Attack

Attack Steps:

  1. Attacker enrolls as a student during enrollment period

  2. During the school session, they receive multiple negative reviews

  3. Their score drops significantly, potentially below the cutOffScore

  4. They are expelled by the principal

  5. After the session ends, they re-enroll during the next enrollment period

  6. They receive a fresh score of 100 and clean academic record

Code Execution Path:

enroll() → [school session] → receive negative reviewsscore drops
expel() → [session ends] → enroll() → score resets to 100

Recommended Remediation Strategies

Approach 1: Expulsion Registry with Permanent Ban

// Add state variable
mapping(address => bool) public blacklistedStudents;
// Modify expel function
function expel(address _student) public onlyPrincipal {
// Existing validation...
// Add to blacklist
blacklistedStudents[_student] = true;
// Existing removal code...
}
// Modify enroll function
function enroll() external notYetInSession {
// Existing checks...
// Check if blacklisted
require(!blacklistedStudents[msg.sender], "HH: Previously expelled students cannot re-enroll");
// Existing enrollment code...
}

Approach 2: Time-Based Suspension System

// Add state variables
mapping(address => uint256) public expulsionTimestamp;
uint256 public constant EXPULSION_PENALTY_PERIOD = 365 days;
// Modify expel function
function expel(address _student) public onlyPrincipal {
// Existing validation...
// Record expulsion time
expulsionTimestamp[_student] = block.timestamp;
// Existing removal code...
}
// Modify enroll function
function enroll() external notYetInSession {
// Existing checks...
// Check if still in penalty period
require(
expulsionTimestamp[msg.sender] == 0 ||
block.timestamp > expulsionTimestamp[msg.sender] + EXPULSION_PENALTY_PERIOD,
"HH: Cannot re-enroll during expulsion penalty period"
);
// Existing enrollment code...
}

Approach 3: Graduated Penalty System For a more nuanced approach that escalates penalties for repeat offenders:

// Add state variables
mapping(address => uint256) public expulsionCount;
mapping(address => uint256) public lastExpulsionTimestamp;
// Modify expel function
function expel(address _student) public onlyPrincipal {
// Existing validation...
// Increment expulsion count and record timestamp
expulsionCount[_student]++;
lastExpulsionTimestamp[_student] = block.timestamp;
// Existing removal code...
}
// Modify enroll function
function enroll() external notYetInSession {
// Existing checks...
// Calculate penalty based on number of previous expulsions
uint256 penaltyPeriod = 0;
if (expulsionCount[msg.sender] == 1) {
penaltyPeriod = 180 days; // 6 months for first offense
} else if (expulsionCount[msg.sender] == 2) {
penaltyPeriod = 365 days; // 1 year for second offense
} else if (expulsionCount[msg.sender] >= 3) {
revert("HH: Permanently expelled after three violations");
}
require(
lastExpulsionTimestamp[msg.sender] == 0 ||
block.timestamp > lastExpulsionTimestamp[msg.sender] + penaltyPeriod,
"HH: Cannot re-enroll during expulsion penalty period"
);
// Existing enrollment code...
}

Conclusion

The ability for expelled students to re-enroll represents a fundamental design flaw in the educational governance model implemented by this smart contract. Without addressing this vulnerability, the disciplinary system lacks effectiveness and creates opportunities for manipulation. The implementation of an expulsion tracking system with appropriate re-enrollment restrictions is strongly recommended to maintain the integrity of the Hawk High School system.

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.