Skip to content

Commit

Permalink
Merge pull request #60 from Ronnieraj37/ccip-funding
Browse files Browse the repository at this point in the history
Changes Week 10 & 11
  • Loading branch information
rajranjan0608 authored Aug 23, 2024
2 parents 6668ef4 + 60ca041 commit 0a3ff79
Show file tree
Hide file tree
Showing 34 changed files with 80,980 additions and 152,190 deletions.
35 changes: 29 additions & 6 deletions blockchain/contracts/cross-chain/CCIPSender.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interface
contract CCIPSender is OwnerIsCreator {
// Used to make sure contract has enough balance
error NotEnoughBalance(uint256 currentBalance, uint256 calculatedFees);

error CCIPNotSupported();
error InsufficientAllowance();
struct CCIPVote {
address election;
address user;
Expand All @@ -27,29 +28,51 @@ contract CCIPSender is OwnerIsCreator {
);

IRouterClient private s_router;

address private electionFactory;
LinkTokenInterface private s_linkToken;
uint public constant minTokens = 25000000000000000000;
mapping(address election => bool status) public electionApproved;

/// @notice Constructor initializes the contract with the router address.
constructor(address _router, address _link) {
constructor(address _router, address _link, address _electionFactory) {
s_router = IRouterClient(_router);
s_linkToken = LinkTokenInterface(_link);
electionFactory = _electionFactory;
}

function getLinkBalance() external view returns (uint) {
return s_linkToken.balanceOf(address(this));
}

function updateElectionFactory(
address _newElectionFactory
) external onlyOwner {
electionFactory = _newElectionFactory;
}

function addElection(address _election) external {
uint256 allowance = s_linkToken.allowance(msg.sender, address(this));
if (allowance < minTokens) revert InsufficientAllowance();
s_linkToken.transferFrom(msg.sender, address(this), minTokens);
electionApproved[_election] = true;
}

function sendMessage(
uint64 destinationChainSelector,
address receiver,
address _election,
uint[] calldata _voteArr
) external returns (bytes32 messageId) {
if (!electionApproved[_election]) {
revert CCIPNotSupported();
}
// Create an EVM2AnyMessage struct in memory with necessary information for sending a cross-chain message
CCIPVote memory _voteDetails = CCIPVote(
_election,
msg.sender,
_voteArr
);
Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({
receiver: abi.encode(receiver),
receiver: abi.encode(electionFactory),
data: abi.encode(_voteDetails), // ABI-encoded vote
tokenAmounts: new Client.EVMTokenAmount[](0), // Empty array indicating no tokens are being sent
extraArgs: Client._argsToBytes(
Expand All @@ -73,7 +96,7 @@ contract CCIPSender is OwnerIsCreator {
emit MessageSent(
messageId,
destinationChainSelector,
receiver,
electionFactory,
"Voted",
address(s_linkToken),
fees
Expand Down
44 changes: 14 additions & 30 deletions blockchain/contracts/resultCalculators/GeneralResult.sol
Original file line number Diff line number Diff line change
@@ -1,52 +1,36 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Errors} from "./interface/Errors.sol";

contract GeneralResult is Errors {
import {Candidatecheck} from "./abstract/CandidateCheck.sol";
import {VoteWinnerCount} from "./abstract/VoteWinnerCount.sol";
import {WinnersArray} from "./abstract/WinnersArray.sol";

contract GeneralResult is
Errors,
Candidatecheck,
VoteWinnerCount,
WinnersArray
{
function calculateGeneralResult(
bytes calldata returnData
) public pure returns (uint[] memory) {
uint[] memory candidateList = abi.decode(returnData, (uint[]));
uint candidatesLength = candidateList.length;

if (candidatesLength == 0) {
revert NoWinner();
}
if (candidatesLength == 1) {
uint[] memory singleWinner = new uint[](1);
singleWinner[0] = 0;
return singleWinner;
if (candidatesLength < 2) {
return checkEdgeCases(candidatesLength);
}

uint maxVotes = 0;
uint winnerCount = 0;

// First pass: find the maximum number of votes and the count of candidates with that maximum
for (uint i = 0; i < candidatesLength; i++) {
uint votes = candidateList[i];
if (votes > maxVotes) {
maxVotes = votes;
winnerCount = 1;
} else if (votes == maxVotes) {
winnerCount++;
}
}
(maxVotes, winnerCount) = getVoteWinnerCount(candidateList);

if (maxVotes == 0) {
revert NoWinner();
}

// Second pass: collect all candidates with the maximum number of votes
uint[] memory winners = new uint[](winnerCount);
uint numWinners = 0;

for (uint i = 0; i < candidatesLength; i++) {
if (candidateList[i] == maxVotes) {
winners[numWinners] = i;
numWinners++;
}
}

return winners;
return getWinnersArray(winnerCount, maxVotes, candidateList);
}
}
103 changes: 4 additions & 99 deletions blockchain/contracts/resultCalculators/IRVResult.sol
Original file line number Diff line number Diff line change
@@ -1,99 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {Errors} from "./interface/Errors.sol";
import {Candidatecheck} from "./abstract/CandidateCheck.sol";

// contract IRVResult is Errors {
// function calculateIRVResult(
// bytes memory returnData
// ) public pure returns (uint256[] memory winners) {
// uint256[][] memory votes = abi.decode(returnData, (uint256[][]));

// // Calculate winners
// winners = performIRV(votes);
// }

// function performIRV(
// uint256[][] memory votes
// ) internal pure returns (uint256[] memory winners) {
// uint256 numCandidates = votes[0].length;
// uint totalCandidates = numCandidates;
// while (true) {
// uint[] memory preference = countFirstPreferences(
// votes,
// numCandidates
// );
// uint leastVotes = checkForLeastID(preference);
// }
// }

// function checkForLeastID(
// uint[] memory preference
// ) internal pure returns (uint) {
// uint arrLength = preference.length;
// preference = sort(preference);
// uint leastId = arrLength;
// uint g_leastVotes = arrLength;
// uint l_leastVotes = 0;
// for(uint i =0 ; i < arrLength -1 ;i++){
// if(preference[i] == preference[i+1]){
// i++;
// }
// }

// }

// function countFirstPreferences(
// uint256[][] memory votes,
// uint256 numCandidates
// ) internal pure returns (uint256[] memory) {
// // Count the first preferences for each candidate
// uint256[] memory firstPreferences = new uint256[](numCandidates);
// for (uint256 i = 0; i < votes.length; i++) {
// if (votes[i].length > 0) {
// firstPreferences[votes[i][0]]++;
// }
// }
// return firstPreferences;
// }

// function modifyArray(
// uint256[][] memory array,
// uint256 id
// ) public pure returns (uint256[][] memory) {
// uint256 rows = array.length;
// uint256 cols = array[0].length;

// for (uint256 i = 0; i < rows; i++) {
// for (uint256 j = 0; j < cols; j++) {
// if (array[i][j] == id) {
// // Found the ID, now shift elements to the left
// for (uint256 k = j; k < cols - 1; k++) {
// array[i][k] = array[i][k + 1];
// }
// break; // Since there's only one element with the same ID, we can break the loop
// }
// }
// }

// return array;
// }

// function sort(uint256[] memory array) public pure returns (uint256[] memory) {
// uint256 length = array.length;
// for (uint256 i = 0; i < length; i++) {
// for (uint256 j = 0; j < length - 1; j++) {
// if (array[j] > array[j + 1]) {
// uint256 temp = array[j];
// array[j] = array[j + 1];
// array[j + 1] = temp;
// }
// }
// }
// return array;
// }
// }

contract IRVResult is Errors {
contract IRVResult is Errors, Candidatecheck {
function calculateIRVResult(
bytes memory returnData
) public pure returns (uint256[] memory winners) {
Expand All @@ -110,13 +20,8 @@ contract IRVResult is Errors {
uint256 numCandidates = votes[0].length;

// Check for no candidates
if (numCandidates == 0) {
revert NoCandidates();
}
if (numCandidates == 1) {
winners = new uint256[](1);
winners[0] = 0;
return winners;
if (numCandidates < 2) {
return checkEdgeCases(numCandidates);
}

uint256[] memory remainingCandidates = new uint256[](numCandidates);
Expand Down
45 changes: 15 additions & 30 deletions blockchain/contracts/resultCalculators/KemenyYoungResult.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
pragma solidity ^0.8.24;

import {Errors} from "./interface/Errors.sol";
import {Candidatecheck} from "./abstract/CandidateCheck.sol";
import {VoteWinnerCount} from "./abstract/VoteWinnerCount.sol";
import {WinnersArray} from "./abstract/WinnersArray.sol";

contract KemenyYoungResult is Errors {
contract KemenyYoungResult is
Errors,
Candidatecheck,
VoteWinnerCount,
WinnersArray
{
function calculateKemenyYoungResult(
bytes memory returnData
) public pure returns (uint256[] memory) {
Expand All @@ -19,14 +27,8 @@ contract KemenyYoungResult is Errors {
) internal pure returns (uint256[] memory) {
uint256 numCandidates = votes.length;

// Check for no candidates
if (numCandidates == 0) {
revert NoCandidates();
}
if (numCandidates == 1) {
uint[] memory singleWinner = new uint[](1);
singleWinner[0] = 0;
return singleWinner;
if (numCandidates < 2) {
return checkEdgeCases(numCandidates);
}

// Compute pairwise scores
Expand Down Expand Up @@ -65,29 +67,12 @@ contract KemenyYoungResult is Errors {
}
}

uint256 highestRankingScore = 0;
uint256 winnerCount = 0;
uint256 highestRankingScore;
uint256 winnerCount;

for (uint i = 0; i < numCandidates; i++) {
if (bestRanking[i] > highestRankingScore) {
highestRankingScore = bestRanking[i];
winnerCount = 1;
} else if (bestRanking[i] == highestRankingScore) {
winnerCount++;
}
}
(highestRankingScore, winnerCount) = getVoteWinnerCount(bestRanking);

// Collect all candidates with the highest ranking score
uint256[] memory winners = new uint256[](winnerCount);
uint256 numWinners = 0;

for (uint256 i = 0; i < numCandidates; i++) {
if (bestRanking[i] == highestRankingScore) {
winners[numWinners] = i;
numWinners++;
}
}

return winners;
return getWinnersArray(winnerCount, highestRankingScore, bestRanking);
}
}
25 changes: 6 additions & 19 deletions blockchain/contracts/resultCalculators/MooreResult.sol
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Errors} from "./interface/Errors.sol";
import {Candidatecheck} from "./abstract/CandidateCheck.sol";
import {WinnersArray} from "./abstract/WinnersArray.sol";

contract MooreResult is Errors {
contract MooreResult is Errors, Candidatecheck, WinnersArray {
function calculateMooreResult(
bytes calldata returnData
) public pure returns (uint[] memory) {
uint[] memory candidateList = abi.decode(returnData, (uint[]));
uint candidatesLength = candidateList.length;

if (candidatesLength == 0) {
revert NoWinner();
}
if (candidatesLength == 1) {
uint[] memory singleWinner = new uint[](1);
singleWinner[0] = 0;
return singleWinner;
if (candidatesLength < 2) {
return checkEdgeCases(candidatesLength);
}

uint maxVotes = 0;
Expand All @@ -35,16 +32,6 @@ contract MooreResult is Errors {
}
}

winners = new uint[](winnerCount);
uint numWinners = 0;

for (uint i = 0; i < candidatesLength; i++) {
if (candidateList[i] == maxVotes) {
winners[numWinners] = i;
numWinners++;
}
}

return winners;
return getWinnersArray(winnerCount, maxVotes, candidateList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {IResultCalculator} from "./interface/IResultCalculator.sol";
import {KemenyYoungResult} from "./KemenyYoungResult.sol";
import {SchulzeResult} from "./SchulzeResult.sol";
import {MooreResult} from "./MooreResult.sol";

contract ResultCalculator is
GeneralResult,
IRVResult,
Expand Down
Loading

0 comments on commit 0a3ff79

Please sign in to comment.