Hawk High

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

[M-4] Implementation Address Not Verified in graduateAndUpgrade Function

Severity

Medium

Impact

The graduateAndUpgrade function in LevelOne.sol accepts any non-zero address as the upgrade target without verifying it's a legitimate LevelTwo implementation. This allows the principal to mistakenly or maliciously upgrade to an incompatible or malicious contract, potentially leading to fund loss, system failure, or permanent contract lockup.

Description

When upgrading from LevelOne to LevelTwo, the only validation performed on the target implementation address is a zero-address check:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
// ... payment calculations ...
_authorizeUpgrade(_levelTwo);
// ... payments to teachers and principal ...
}

Potential Attack Scenarios

  1. Phishing Attack: An attacker could send the principal a message claiming to be from the development team, providing a malicious implementation address disguised as the legitimate LevelTwo contract. Since there are no verification checks, the principal could unknowingly upgrade to this malicious contract.

  2. Malicious Principal: A compromised or malicious principal could upgrade to a specially crafted contract designed to:

    • Redirect future fee payments to their own address

    • Manipulate the bursary accounting to steal funds

    • Remove legitimate teachers and replace them with collaborators

  3. Operational Error: Even without malicious intent, the principal could accidentally provide an incorrect address (e.g., a user wallet or a different contract), bricking the entire school system since no verification is performed.

Without proper validation, these scenarios represent significant risks to the system's funds and operational integrity.

Tools Used

Manual code review

Recommended Mitigation

Implement proper verification of the upgrade target by:

function graduateAndUpgrade(address _levelTwo, bytes memory) public onlyPrincipal {
if (_levelTwo == address(0)) {
revert HH__ZeroAddress();
}
+
+ // Verify the address is a contract
+ uint256 codeSize;
+ assembly {
+ codeSize := extcodesize(_levelTwo)
+ }
+ require(codeSize > 0, "Target must be a contract");
+
+ // Verify it's a LevelTwo implementation by checking interface
+ try LevelTwo(_levelTwo).getPrincipal() returns (address) {
+ // Function exists and can be called
+ } catch {
+ revert("Invalid LevelTwo implementation");
+ }
// ... rest of the function ...
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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