function selectPresident() external {
...
for (uint256 i = 0; i < VOTERS.length; i++) {
address[] memory orderedCandidates = s_rankings[VOTERS[i]][
s_voteNumber
];
for (uint256 j = 0; j < orderedCandidates.length; j++) {
if (!_isInArray(s_candidateList, orderedCandidates[j])) {
@> s_candidateList.push(orderedCandidates[j]);
}
}
}
@> address[] memory winnerList = _selectPresidentRecursive(
@> s_candidateList,
0
);
...
}
function _selectPresidentRecursive(
address[] memory candidateList,
uint256 roundNumber
) internal returns (address[] memory) {
if (candidateList.length == 1) {
return candidateList;
}
for (uint256 i = 0; i < VOTERS.length; i++) {
for (
uint256 j = 0;
j < s_rankings[VOTERS[i]][s_voteNumber].length;
j++
) {
address candidate = s_rankings[VOTERS[i]][s_voteNumber][j];
@> if (_isInArray(candidateList, candidate)) {
s_candidateVotesByRound[candidate][s_voteNumber][
roundNumber
] += 1;
break;
} else {
continue;
}
}
}
address fewestVotesCandidate = candidateList[0];
uint256 fewestVotes = s_candidateVotesByRound[fewestVotesCandidate][
s_voteNumber
][roundNumber];
for (uint256 i = 1; i < candidateList.length; i++) {
uint256 votes = s_candidateVotesByRound[candidateList[i]][
s_voteNumber
][roundNumber];
if (votes < fewestVotes) {
fewestVotes = votes;
fewestVotesCandidate = candidateList[i];
}
}
address[] memory newCandidateList = new address[](
candidateList.length - 1
);
bool passedCandidate = false;
for (uint256 i; i < candidateList.length; i++) {
if (passedCandidate) {
newCandidateList[i - 1] = candidateList[i];
} else if (candidateList[i] == fewestVotesCandidate) {
passedCandidate = true;
} else {
newCandidateList[i] = candidateList[i];
}
}
return _selectPresidentRecursive(newCandidateList, roundNumber + 1);
}
function test_BreakVotingSystemByOutOfGas(int numberOfVoters) public {
numberOfVoters = int(bound(uint256(numberOfVoters), 0, MAX_VOTERS));
for (uint256 i = 0; i < uint256(numberOfVoters); i++) {
address voter = address(uint160(i + VOTERS_ADDRESS_MODIFIER));
vm.prank(voter);
orderedCandidates = new address[](0);
for (uint256 j = 0; j < MAX_CANDIDATES; j++) {
orderedCandidates.push(
address(uint160(j + CANDIDATES_ADDRESS_MODIFIER * i))
);
}
rankedChoice.rankCandidates(orderedCandidates);
}
vm.warp(block.timestamp + rankedChoice.getDuration());
uint256 gasStart = gasleft();
rankedChoice.selectPresident();
uint256 gasEnd = gasleft();
uint256 gasUsed = (gasStart - gasEnd) * tx.gasprice;
console.log("Gas cost : ", gasUsed);
console.log(rankedChoice.getCurrentPresident());
}
There are many solutions to solve this problems. However, i suggest an easiest practice that make the list of potential president for voter selecting.