## Summary
After distributing salaries and performing the upgrade, the bursary is not updated.
## Vulnerability Details
```diff
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);
+ bursary = bursary - principalPay - totalTeachers * payPerTeacher;
+ _authorizeUpgrade(_levelTwo);
}
```
## Impact
```
function attack() public {
// initial State add teachers and students
_teachersAdded();
_studentsEnrolled();
// principal start session
vm.prank(principal);
levelOneProxy.startSession(70);
assert(levelOneProxy.bursary() == schoolFees * 6);
// prepare for upgrade
levelTwoImplementation = new LevelTwo();
levelTwoImplementationAddress = address(levelTwoImplementation);
bytes memory data = abi.encodeCall(LevelTwo.graduate, ());
// upgrade
vm.prank(principal);
levelOneProxy.graduateAndUpgrade(levelTwoImplementationAddress, data);
assert(levelOneProxy.getSessionStatus() == true);
LevelTwo levelTwoProxy = LevelTwo(proxyAddress);
// check bursary
assert(levelTwoProxy.bursary() != usdc.balanceOf(address(levelTwoProxy)));
// Outcome: After distributing salaries and performing the upgrade, the bursary is not updated.
// Implications: Causing a discrepancy between the actual tuition balance and the value recorded in the contract.
}
```
## Recommendations
Update bursary before upgrade