Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: low
Valid

Missing Increment for reviewCount Allows Unlimited Negative Reviews

Summary

The reviewCount variable is used to limit the number of reviews a student can receive, but it is never incremented when a review is given. This completely breaks the review limitation mechanism, allowing unlimited reviews for each student.

Vulnerability Details

function giveReview(address _student, bool review) public onlyTeacher {
require(reviewCount[_student] < 5, "Student review count exceeded!!!");
require(
block.timestamp >= lastReviewTime[_student] + reviewTime,
"Reviews can only be given once per week"
);
// where `false` is a bad review and true is a good review
if (!review) {
studentScore[_student] -= 10;
}
// Update last review time
lastReviewTime[_student] = block.timestamp;
// reviewCount is never incremented!
emit ReviewGiven(_student, review, studentScore[_student]);
}

The issue is that while the function checks if reviewCount[_student] < 5, it never increments reviewCount[_student] after giving a review. Since the counter is never incremented, the check will continue to pass indefinitely, making the 5-review limit ineffective.

Impact

Teachers can give unlimited negative reviews to a student, potentially reducing their score to 0 or a very low value. This undermines the intended limitation of 5 reviews per student and could allow malicious teachers to unfairly penalize students.

Tools Used

Recommendations

function giveReview(address _student, bool review) public onlyTeacher {
// ... existing code ...
// where `false` is a bad review and true is a good review
if (!review) {
studentScore[_student] -= 10;
}
// Update last review time
lastReviewTime[_student] = block.timestamp;
reviewCount[_student]++; // Add missing increment
emit ReviewGiven(_student, review, studentScore[_student]);
}

This change will ensure that the review count limit works as intended, preventing teachers from giving more than 5 reviews to any student.

POC

function test_ReviewCountNotIncremented() public {
// Setup teachers and enroll students
_teachersAdded();
_studentsEnrolled();
// Start a session
vm.prank(principal);
levelOneProxy.startSession(70);
// Get a student to give reviews to
address student = levelOneProxy.getListOfStudents()[0];
// Initial score of the student
uint256 initialScore = levelOneProxy.studentScore(student);
console.log("Initial student score:", initialScore);
// Have a teacher give 6 bad reviews - should be limited to 5 max
vm.startPrank(alice); // Alice is a teacher
// Give 6 reviews with appropriate time intervals (1 week + 1 day between each)
for (uint256 i = 0; i < 6; i++) {
vm.warp(block.timestamp + 1 weeks + 1 days);
levelOneProxy.giveReview(student, false); // false = bad review
console.log(
"Review #",
i + 1,
"given. Student score:",
levelOneProxy.studentScore(student)
);
}
vm.stopPrank();
// If reviewCount worked correctly, the student's score should be reduced by 10 points for 5 reviews
// So the expected final score would be initialScore - (5 * 10) = initialScore - 50
uint256 expectedScoreIfLimited = initialScore - 50;
uint256 actualFinalScore = levelOneProxy.studentScore(student);
console.log(
"Expected score if limited to 5 reviews:",
expectedScoreIfLimited
);
console.log("Actual final score after 6 reviews:", actualFinalScore);
// This assertion will fail because reviewCount is never incremented,
// so all 6 reviews went through (reducing score by 60, not 50)
assertTrue(
actualFinalScore < expectedScoreIfLimited,
"Expected student to receive more than 5 reviews, but limit seems to be working"
);
}

Output

-> % forge test --mt test_ReviewCountNotIncremented -vvv
[⠊] Compiling...
[⠑] Compiling 1 files with Solc 0.8.26
[⠘] Solc 0.8.26 finished in 598.94ms
Compiler run successful!
Ran 1 test for test/LeveOnelAndGraduateTest.t.sol:LevelOneAndGraduateTest
[PASS] test_ReviewCountNotIncremented() (gas: 1013520)
Logs:
Initial student score: 100
Review # 1 given. Student score: 90
Review # 2 given. Student score: 80
Review # 3 given. Student score: 70
Review # 4 given. Student score: 60
Review # 5 given. Student score: 50
Review # 6 given. Student score: 40
Expected score if limited to 5 reviews: 50
Actual final score after 6 reviews: 40
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 17.16ms (3.76ms CPU time)
Ran 1 test suite in 103.79ms (17.16ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)


Updates

Lead Judging Commences

yeahchibyke Lead Judge
about 1 month ago
yeahchibyke Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

reviewCount not updated

`reviewCount` for students is not updated after each review session

Support

FAQs

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