Hawk High

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

Lack of Session Duration Enforcement in System Upgrade Mechanism


Severity: High

Likelihood: High

Summary

The graduateAndUpgrade function in the LevelOne contract fails to validate that the educational session has reached its intended conclusion before allowing graduation and contract upgrade. This critical oversight enables the principal to prematurely terminate academic sessions, upgrade the system, and distribute funds before students have received their full educational term.

Vulnerability Details

The contract establishes a time-bound educational session through the startSession function:

function startSession(uint256 _cutOffScore) public onlyPrincipal notYetInSession {
sessionEnd = block.timestamp + 4 weeks;
inSession = true;
cutOffScore = _cutOffScore;
emit SchoolInSession(block.timestamp, sessionEnd);
}

However, the graduateAndUpgrade function contains no temporal validation whatsoever:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
uint256 totalTeachers = listOfTeachers.length;
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
_authorizeUpgrade(_levelTwo);
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
}

This function should include a check that verifies block.timestamp >= sessionEnd to ensure the session has properly concluded.

Impact

This vulnerability introduces several critical issues to the educational system:

  1. Economic Impact:

    • Students pay school fees (stored in bursary) with the expectation of a 4-week educational term

    • Premature graduation denies students the full value of their investment

    • Teachers receive compensation without delivering the complete educational service

  2. Educational Integrity Violation:

    • The academic process is compromised when sessions can end arbitrarily

    • Student evaluation may be incomplete if the graduation occurs before sufficient reviews

    • The cutOffScore mechanism becomes ineffective if students are graduated before final assessments

  3. System State Corruption:

    • After graduation, the system remains in an inconsistent state where inSession = true

    • This state inconsistency could affect future operations or integrations

  4. Trust and Fairness:

    • The arbitrary nature of session termination undermines trust in the educational platform

    • Students are subject to unequal treatment if some sessions run full-term while others are cut short

Code Reference

The critical vulnerability is in the graduateAndUpgrade function:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
uint256 totalTeachers = listOfTeachers.length;
uint256 payPerTeacher = (bursary * TEACHER_WAGE) / PRECISION;
uint256 principalPay = (bursary * PRINCIPAL_WAGE) / PRECISION;
_authorizeUpgrade(_levelTwo);
for (uint256 n = 0; n < totalTeachers; n++) {
usdc.safeTransfer(listOfTeachers[n], payPerTeacher);
}
usdc.safeTransfer(principal, principalPay);
}

Proof of Concept

Scenario: Immediate Graduation After Session Start

  1. The principal calls startSession(70) to start a session with a cutoff score of 70

    • This sets sessionEnd = block.timestamp + 4 weeks

    • Sets inSession = true

  2. Immediately after (in the same block or next block), the principal calls graduateAndUpgrade(newImplementationAddress, "0x")

  3. The function executes successfully:

    • The contract is upgraded to the new implementation

    • Teachers receive their share of the school fees (35%)

    • Principal receives their share (5%)

    • The session effectively lasted only minutes instead of the intended 4 weeks

  4. Students have been denied the educational services they paid for, with no recourse

Recommendations

  1. Add mandatory session duration enforcement:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
require(block.timestamp >= sessionEnd, "Session duration not complete");
require(inSession == true, "Not in active session");
// Reset session state before proceeding
inSession = false;
// Rest of the function remains the same
...
}
  1. Implement proper state management:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
require(block.timestamp >= sessionEnd, "Session duration not complete");
require(inSession == true, "Not in active session");
// Reset session state
inSession = false;
// Optional: Verify students meet graduation criteria
for (uint256 i = 0; i < listOfStudents.length; i++) {
if (studentScore[listOfStudents[i]] < cutOffScore) {
// Handle students below cutoff score (e.g., expel or mark as failed)
}
}
// Rest of the function remains the same
...
}
  1. Add an event to track graduation:

event SessionGraduated(uint256 indexed endTime, uint256 indexed actualEndTime, uint256 studentCount);
function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
// Add checks...
// Emit graduation event
emit SessionGraduated(sessionEnd, block.timestamp, listOfStudents.length);
// Rest of the function remains the same
...
}
Updates

Lead Judging Commences

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

can graduate without session end

`graduateAndUpgrade()` can be called successfully even when the school session has not ended

Support

FAQs

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