Hawk High

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

`LevelOne::giveReview` function does not update `LevelOne::reviewCount`, breaking the function requirements and making the contract vulnerable.

Summary

The LevelOne::giveReview function incorrectly handles the update of the LevelOne::reviewCount for students, which can break the intended checks within the function.

Specifically, the function includes a requirement that LevelOne::reviewCount must be less than five. However, this counter is never updated when a review is submitted, rendering the check ineffective.

Vulnerability Details

LevelOne::giveReview function is supposed to allow the teachers to submit only one review per student per week. However, it does not update LevelOne::reviewCount mapping as expected. Although other variables in the contact such as LevelOne::lastReviewTime or LevelOne::sessionEnd provide protection to it indirectly, the function should still update LevelOne::reviewCount every time it is called. This omission creates an inconsistency in the contract's state.

Impact

Although the current implementation restricts teachers from calling LevelOne::giveReview more than once per week, which decreases the likelihood of this issue being exploited by a malicious actor, the logic of the contract becomes fragile. If variables like LevelOne::sessionEnd or LevelOne::lastReviewTime are modified, the protection breaks down.

The intended restriction (reviewCount < 5) is entirely bypassed, rendering the reviewCount mapping functionally useless.

This issue can be confirmed by adding the following test to the LevelOneAndGraduateTest.t.sol contract. The console will show that "reviewCount:", "reviewCount2:", and "reviewCount3:" all return 0.

Proof of Concept:

  1. Teacher alice submits three reviews for student fin.

  2. After the third review, the console shows reviewCount(fin) is still 0, despite three reviews being recorded.

Proof of Code

function test_reviewCount_does_not_increase() public schoolInSession {
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(fin, false);
console2.log("reviewCount: ", levelOneProxy.reviewCount(fin));
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(fin, false);
console2.log("reviewCount2: ", levelOneProxy.reviewCount(fin));
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
levelOneProxy.giveReview(fin, false);
console2.log("reviewCount3: ", levelOneProxy.reviewCount(fin));
}

Tools Used

This issue was found by manual review.

Recommendations

Consider to modify LevelOne::giveReview function to properly update LevelOne::reviewCount value every time the function is called:

function giveReview(address _student, bool review) public onlyTeacher {
if (!isStudent[_student]) {
revert HH__StudentDoesNotExist();
}
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;
+ // Update
+ reviewCount[_student]++;
emit ReviewGiven(_student, review, studentScore[_student]);
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 months 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.