Summary
The graduateAndUpgrade() function performs a critical role by distributing funds to teachers and the principal and authorizing an upgrade to a new contract (LevelTwo). However, this function does not emit any event indicating that the graduation or upgrade has occurred. This omission leads to reduced transparency and hinders off-chain monitoring and audits of important state transitions.
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);
}
Vulnerability Details
There is no event emitted when:
Impact
It's difficult for auditors or stakeholders to determine when and where funds were disbursed.
Tools Used
Manual Review
Recommendations
Add event for better visibility
event GraduatedAndUpgraded(address indexed newImplementation, uint256 timestamp);
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);
emit GraduatedAndUpgraded(_levelTwo, block.timestamp);
}