Hawk High

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

[L-1] Session Flag Never Resets After Four Weeks

Summary

The LevelOne contract sets sessionEnd = block.timestamp + 4 weeks and flips inSession to true when startSession is invoked, but never resets inSession back to false once the four-week term expires. As a result, any on-chain workflow or external caller querying getSessionStatus() will always see the session as active, even long after the intended cutoff. This flaw breaks the invariant that “a school session lasts four weeks,” leading to misleading state and potential downstream logic errors.

Vulnerability Details

When startSession(uint256 _cutOffScore) is called, the contract executes:

sessionEnd = block.timestamp + 4 weeks;
inSession = true;

However, there is no code path—modifier, view helper, or external function—that ever flips inSession back to false when block.timestamp exceeds sessionEnd. Consequently, calls to:

function getSessionStatus() external view returns (bool) {
return inSession;
}

will perpetually return true, regardless of the actual time elapsed. Any business logic relying on session closure—such as forbidding new enrollments or gating graduation—will operate under the false assumption that the session is still ongoing

Impact

The inSession flag remains true indefinitely once startSession is called, even after sessionEnd has passed, causing the reported session status to be misleading and invalidating any logic that depends on the session having actually ended.

Tools Used

  • Foundry

  • Manual Review

Proof of Concept

The following Forge test appended to your existing suite demonstrates that even after warping the blockchain time beyond five weeks, getSessionStatus() remains true:

function test_sessionNeverEndsAfterFourWeeks() public {
_teachersAdded();
_studentsEnrolled();
// Start 4-week session now
vm.prank(principal);
levelOneProxy.startSession(80);
// Immediately confirm session is live
assertEq(levelOneProxy.getSessionStatus(), true);
// Warp forward by 5 weeks (beyond sessionEnd)
vm.warp(block.timestamp + 5 weeks);
// Confirm session is STILL active even after the 4-week period
assertEq(
levelOneProxy.getSessionStatus(),true);
}

Recommendations

Consider adding a state update in a modifier or dedicated function that resets inSession to false once block.timestamp >= sessionEnd. This approach ensures that after four weeks, the session truly ends, restoring the correct contract invariant and preventing downstream logic errors

Updates

Lead Judging Commences

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

session state not updated

`inSession` not updated after during upgrade

Support

FAQs

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