Hawk High

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

DoS Vulnerability in Teacher Removal Mechanism

Description: The LevelOne contract implements an inefficient mechanism for removing teachers that can lead to denial of service. The removeTeacher() function requires linear time complexity O(n) to find and remove a teacher from the listOfTeachers array, where n is the total number of teachers. As this list grows, the gas cost increases proportionally, creating a condition where the function may become unusable due to exceeding block gas limits.

Code Snippet:

function removeTeacher(address _teacher) public onlyPrincipal {
if (_teacher == address(0)) {
revert HH__ZeroAddress();
}
if (!isTeacher[_teacher]) {
revert HH__TeacherDoesNotExist();
}
uint256 teacherLength = listOfTeachers.length;
for (uint256 n = 0; n < teacherLength; n++) {
if (listOfTeachers[n] == _teacher) {
listOfTeachers[n] = listOfTeachers[teacherLength - 1];
listOfTeachers.pop();
break;
}
}
isTeacher[_teacher] = false;
emit TeacherRemoved(_teacher);
}

Impact: The current implementation creates a critical vulnerability where the contract could reach a state in which teacher management operations become impossible. If the principal cannot remove teachers, this limits the contract's administrative flexibility and potentially blocks necessary organization changes. This issue could be exploited by a malicious principal who adds many teachers to make the system unmanageable.

Detailed Analysis: Each iteration of the loop requires:

  • Reading an address from storage (~2,100 gas per read)

  • Comparison operation (~3 gas)

  • If a match is found, write operations (~5,000 gas)

With Ethereum's current block gas limit of approximately 30 million gas, this function would fail with roughly 10,000+ teachers in the worst case. However, practical limitations would be lower due to other operations in the function.

Recommended Mitigation:

  1. Implement a mapping-based index tracking system to achieve O(1) removal operations.

  2. Consider implementing batch operations for managing multiple teachers.

  3. Add administrative functions to handle system recovery if the list becomes too large.

// Track index in array for O(1) removal
mapping(address => uint256) private teacherToIndex;
function addTeacher(address _teacher) public onlyPrincipal notYetInSession {
// Existing validation...
teacherToIndex[_teacher] = listOfTeachers.length;
listOfTeachers.push(_teacher);
isTeacher[_teacher] = true;
emit TeacherAdded(_teacher);
}
function removeTeacher(address _teacher) public onlyPrincipal {
// Existing validation...
uint256 indexToRemove = teacherToIndex[_teacher];
uint256 lastIndex = listOfTeachers.length - 1;
if (indexToRemove != lastIndex) {
address lastTeacher = listOfTeachers[lastIndex];
listOfTeachers[indexToRemove] = lastTeacher;
teacherToIndex[lastTeacher] = indexToRemove;
}
listOfTeachers.pop();
delete teacherToIndex[_teacher];
isTeacher[_teacher] = false;
emit TeacherRemoved(_teacher);
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge
6 months ago
yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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