MEDIUM severity: The `QVBaseStrategy::reviewRecipients()` function in the QV strategy contracts is responsible for up. The `QVBaseStrategy::reviewRecipients()` function in the QV strategy contracts is responsible for updating the status of registered recipients based on the reviews from pool managers. The function iterates through the provided arrays of recipient IDs and statuses, incrementing the review counts for...

Vulnerable code:
```\nfunction reviewRecipients(address[] calldata _recipientIds, Status[] calldata _recipientStatuses)\n    external\n    virtual\n    onlyPoolManager(msg.sender)\n    onlyActiveRegistration\n{\n    uint256 recipientLength = _recipientIds.length;\n    if (recipientLength!= _recipientStatuses.length) {\n        revert INVALID();\n    }\n\n    for (uint256 i = 0; i < recipientLength; i++) {\n        Status recipientStatus = _recipientStatuses[i];\n        address recipientId = _recipientIds[i];\n\n        if (recipientStatus == Status.None || recipientStatus == Status.Appealed) {\n            revert RECIPIENT_ERROR(recipientId);\n        }\n\n        reviewsByStatus[recipientId][recipientStatus]++;\n\n        if (reviewsByStatus[recipientId][recipientStatus] >= reviewThreshold) {\n            Recipient storage recipient = recipients[recipientId];\n            recipient.recipientStatus = recipientStatus;\n\n            emit RecipientStatusUpdated(recipientId, recipientStatus, address(0));\n        }\n\n        emit Reviewed(recipientId, recipientStatus, msg.sender);\n    }\n}\n```\n```\nfunction test_reviewRecipient_reviewTreshold_OverwriteTheLastOne() public virtual {\n    address recipientId = __register_recipient();\n\n    // Create rejection status\n    address[] memory recipientIds = new address[](1);\n    recipientIds[0] = recipientId;\n    IStrategy.Status[] memory statuses = new IStrategy.Status[](1);\n    statuses[0] = IStrategy.Status.Rejected;\n\n    // Reject three times with different managers\n    vm.startPrank(pool_manager1());\n    qvStrategy().reviewRecipients(recipientIds, statuses);\n\n    vm.startPrank(pool_manager2());\n    qvStrategy().reviewRecipients(recipientIds, statuses);\n\n    vm.startPrank(pool_manager3());\n    qvStrategy().reviewRecipients(recipientIds, statuses);\n\n    // Three managers rejected. Status will be rejected.\n    assertEq(uint8(qvStrategy().getRecipientStatus(recipientId)), uint8(IStrategy.Status.Rejected));\n    assertEq(qvStrategy().reviewsByStatus(recipientId, IStrategy.Status.Rejected), 3);\n\n    // Accept two times after three rejections\n    statuses[0] = IStrategy.Status.Accepted;\n    vm.startPrank(pool_admin());\n    qvStrategy().reviewRecipients(recipientIds, statuses);\n\n    vm.startPrank(pool_manager4());\n    qvStrategy().reviewRecipients(recipientIds, statuses);\n\n    // 3 Rejected, 2 Accepted, but status is Accepted because it overwrites right after passing threshold.\n    assertEq(uint8(qvStrategy().getRecipientStatus(recipientId)), uint8(IStrategy.Status.Accepted));\n    assertEq(qvStrategy().reviewsByStatus(recipientId, IStrategy.Status.Rejected), 3);\n    assertEq(qvStrategy().reviewsByStatus(recipientId, IStrategy.Status.Accepted), 2);\n}\n```\n```\nRunning 1 test for test/foundry/strategies/QVSimpleStrategy.t.sol:QVSimpleStrategyTest\n[PASS] test_reviewRecipient_reviewTreshold_OverwriteTheLastOne() (gas: 249604)\nTest result: ok. 1 passed; 0 failed; 0 skipped; finished in 10.92ms\n```