Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

[L-1] No Principal Rotation Mechanism

Severity

Low

Impact

The contract permanently assigns the principal role during initialization with no mechanism to transfer this role or replace the principal if they become unavailable, compromised, or need to be replaced.

Description

The LevelOne contract sets the principal address in the initialize function but doesn't provide any function to update this critical role:

function initialize(address _principal, uint256 _schoolFees, address _usdcAddress) public initializer {
principal = _principal;
// ...
}

This creates a single point of failure, as only the principal can perform critical functions such as adding/removing teachers, starting sessions, and upgrading the contract. If the principal's private key is compromised or the principal becomes unavailable, these administrative functions become inaccessible, potentially causing the entire school system to become non-functional.

Recommended Mitigation

Implement a function that allows the current principal to transfer ownership to a new address, similar to OpenZeppelin's Ownable pattern:

function transferPrincipalRole(address newPrincipal) external onlyPrincipal {
if (newPrincipal == address(0)) {
revert HH__ZeroAddress();
}
principal = newPrincipal;
emit PrincipalTransferred(msg.sender, newPrincipal);
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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