Inaccurate handling of identical scores in findModelerUpperBound
Description
The findModelerUpperBound
function in the CompetitionLibrary contract is intended to find the upper bound index for a given element
in a sorted array using binary search. However, the current implementation does not correctly handle scenarios where multiple identical scores exist in the topNModelers
. Specifically, the check modelerToMedian[topNModelers[low - 1]] == element
only considers the immediate preceding score and does not account for multiple identical scores.
function findModelerUpperBound(address[] storage topNModelers, mapping(address => uint256) storage modelerToMedian, uint256 element) external view returns (uint256) {
if (topNModelers.length == 0) {
return 0;
}
uint256 low = 0;
uint256 high = topNModelers.length;
while (low < high) {
uint256 mid = (low + high) / 2;
uint256 midValue = modelerToMedian[topNModelers[mid]];
if (element > midValue) {
high = mid;
} else {
low = mid + 1;
}
}
if (low > 0 && modelerToMedian[topNModelers[low - 1]] == element) {
return low - 1;
} else {
return low;
}
}
Impact
This issue can result in inaccurate positioning of modelers within the topNModelers
list, especially in scenarios with tied scores. It could lead to unfair ranking and potentially affect the outcome of competitions or distributions based on these rankings.
Recommendations
A more robust implementation should be developed to handle identical scores appropriately. The binary search logic should be modified to find the first index that is strictly less than the element
and correctly position modelers with identical scores.
Remediation
This issue has been acknowledged by Spectral Finance, and a fix was implemented in commit fbe68d35↗.