## Summary
The contract can be upgraded before the school session has ended.
## Vulnerability Details
```diff
function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
+ if(getSessionEnd() > block.timestamp || getSessionEnd() == 0) {
+ revert HH__SessionNotEnded();
+ }
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);
}
```
## Impact
```
function attack() public {
// initial State add teachers and students
_teachersAdded();
_studentsEnrolled();
// principal start session
vm.prank(principal);
levelOneProxy.startSession(70);
// prepare for upgrade
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
// principal upgrade before session end
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
assert(levelOneProxy.getSessionStatus() == true);
// Implications: Before the school session ends, the principal and teachers can withdraw their salaries in advance and, through multiple upgrades, deplete all tuition funds, which could harm students' rights. A mechanism similar to a time lock should be implemented to ensure that the contract can only be upgraded after the session has ended and all students have received their reviews.
}
```
## Recommendations
Add session end check before upgrade