Browse Source

Merge branch 'voting' into 'develop'

Voting

See merge request ecentrics/concordia!9
develop
Apostolos Fanakis 4 years ago
parent
commit
fd4e39f06d
  1. 12
      packages/concordia-app/src/views/Home/index.jsx
  2. 4
      packages/concordia-contracts/.eslintrc.js
  3. 8
      packages/concordia-contracts/.solhint.json
  4. 68
      packages/concordia-contracts/contracts/Forum.sol
  5. 12
      packages/concordia-contracts/contracts/Migrations.sol
  6. 109
      packages/concordia-contracts/contracts/PostVoting.sol
  7. 155
      packages/concordia-contracts/contracts/Voting.sol
  8. 8
      packages/concordia-contracts/index.js
  9. 8
      packages/concordia-contracts/migrations/2_deploy_contracts.js
  10. 2
      packages/concordia-contracts/package.json
  11. 112
      packages/concordia-contracts/test/TestVoting.sol
  12. 2
      packages/concordia-contracts/truffle-config.js

12
packages/concordia-app/src/views/Home/index.jsx

@ -8,20 +8,20 @@ import './styles.css';
import { drizzle } from '../../redux/store'; import { drizzle } from '../../redux/store';
import { FORUM_CONTRACT } from '../../constants/contracts/ContractNames'; import { FORUM_CONTRACT } from '../../constants/contracts/ContractNames';
const { contracts: { [FORUM_CONTRACT]: { methods: { getNumberOfTopics } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { numTopics } } } } = drizzle;
const Home = () => { const Home = () => {
const [numberOfTopicsCallHash, setNumberOfTopicsCallHash] = useState(''); const [numberOfTopicsCallHash, setNumberOfTopicsCallHash] = useState('');
const getNumberOfTopicsResults = useSelector((state) => state.contracts[FORUM_CONTRACT].getNumberOfTopics); const numTopicsResults = useSelector((state) => state.contracts[FORUM_CONTRACT].numTopics);
useEffect(() => { useEffect(() => {
setNumberOfTopicsCallHash(getNumberOfTopics.cacheCall()); setNumberOfTopicsCallHash(numTopics.cacheCall());
}, []); }, []);
const numberOfTopics = useMemo(() => (getNumberOfTopicsResults[numberOfTopicsCallHash] !== undefined const numberOfTopics = useMemo(() => (numTopicsResults[numberOfTopicsCallHash] !== undefined
? parseInt(getNumberOfTopicsResults[numberOfTopicsCallHash].value, 10) ? parseInt(numTopicsResults[numberOfTopicsCallHash].value, 10)
: null), : null),
[getNumberOfTopicsResults, numberOfTopicsCallHash]); [numTopicsResults, numberOfTopicsCallHash]);
return useMemo(() => ( return useMemo(() => (
<Container id="home-container" textAlign="center"> <Container id="home-container" textAlign="center">

4
packages/concordia-contracts/.eslintrc.js

@ -31,7 +31,9 @@ module.exports = {
'no-unused-vars': 'warn', 'no-unused-vars': 'warn',
'no-console': 'warn', 'no-console': 'warn',
'no-shadow': 'warn', 'no-shadow': 'warn',
"no-multi-str": "warn" 'no-multi-str': 'warn',
'one-var': ["error", { "uninitialized": "always" }],
'one-var-declaration-per-line': ['error', 'initializations']
}, },
'settings': { 'settings': {
'import/resolver': { 'import/resolver': {

8
packages/concordia-contracts/.solhint.json

@ -1,3 +1,9 @@
{ {
"extends": "solhint:default" "extends": "solhint:recommended",
"rules": {
"compiler-version": ["error","~0.8.0"],
"func-visibility": ["warn",{"ignoreConstructors" : true}],
"not-rely-on-time": "off",
"state-visibility": "off"
}
} }

68
packages/concordia-contracts/contracts/Forum.sol

@ -1,8 +1,12 @@
//SPDX-License-Identifier: MIT //SPDX-License-Identifier: MIT
pragma solidity 0.7.1; pragma solidity 0.8.0;
pragma experimental ABIEncoderV2;
contract Forum { contract Forum {
// Error messages for require()
string public constant USER_HAS_NOT_SIGNED_UP = "User hasn't signed up yet.";
string public constant USERNAME_TAKEN = "Username is already taken.";
string public constant TOPIC_DOES_NOT_EXIST = "Topic doesn't exist.";
string public constant POST_DOES_NOT_EXIST = "Post doesn't exist.";
//----------------------------------------USER---------------------------------------- //----------------------------------------USER----------------------------------------
struct User { struct User {
@ -13,25 +17,24 @@ contract Forum {
bool signedUp; // Helper variable for hasUserSignedUp() bool signedUp; // Helper variable for hasUserSignedUp()
} }
mapping (address => User) users; mapping(address => User) users;
mapping (string => address) userAddresses; mapping(string => address) userAddresses;
event UserSignedUp(string username, address userAddress); event UserSignedUp(string username, address userAddress);
event UsernameUpdated(string newName, string oldName, address userAddress); event UsernameUpdated(string newName, string oldName, address userAddress);
function signUp(string memory username) public returns (bool) { function signUp(string memory username) public returns (bool) {
require (!hasUserSignedUp(msg.sender), "User has already signed up."); require(!hasUserSignedUp(msg.sender), USER_HAS_NOT_SIGNED_UP);
require(!isUserNameTaken(username), "Username is already taken."); require(!isUserNameTaken(username), USERNAME_TAKEN);
users[msg.sender] = User(username, users[msg.sender] = User(username, new uint[](0), new uint[](0), block.timestamp, true);
new uint[](0), new uint[](0), block.timestamp, true);
userAddresses[username] = msg.sender; userAddresses[username] = msg.sender;
emit UserSignedUp(username, msg.sender); emit UserSignedUp(username, msg.sender);
return true; return true;
} }
function updateUsername(string memory newUsername) public returns (bool) { function updateUsername(string memory newUsername) public returns (bool) {
require (hasUserSignedUp(msg.sender), "User hasn't signed up yet."); require(hasUserSignedUp(msg.sender), USER_HAS_NOT_SIGNED_UP);
require(!isUserNameTaken(newUsername), "Username is already taken."); require(!isUserNameTaken(newUsername), USERNAME_TAKEN);
string memory oldUsername = getUsername(msg.sender); string memory oldUsername = getUsername(msg.sender);
delete userAddresses[users[msg.sender].username]; delete userAddresses[users[msg.sender].username];
users[msg.sender].username = newUsername; users[msg.sender].username = newUsername;
@ -41,7 +44,7 @@ contract Forum {
} }
function getUsername(address userAddress) public view returns (string memory) { function getUsername(address userAddress) public view returns (string memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up yet."); require(hasUserSignedUp(userAddress), USER_HAS_NOT_SIGNED_UP);
return users[userAddress].username; return users[userAddress].username;
} }
@ -54,28 +57,28 @@ contract Forum {
} }
function isUserNameTaken(string memory username) public view returns (bool) { function isUserNameTaken(string memory username) public view returns (bool) {
if (getUserAddress(username)!=address(0)) if (getUserAddress(username) != address(0))
return true; return true;
return false; return false;
} }
function getUserTopics(address userAddress) public view returns (uint[] memory) { function getUserTopics(address userAddress) public view returns (uint[] memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up yet."); require(hasUserSignedUp(userAddress), USER_HAS_NOT_SIGNED_UP);
return users[userAddress].topicIDs; return users[userAddress].topicIDs;
} }
function getUserPosts(address userAddress) public view returns (uint[] memory) { function getUserPosts(address userAddress) public view returns (uint[] memory) {
require (hasUserSignedUp(userAddress), "User hasn't signed up yet."); require(hasUserSignedUp(userAddress), USER_HAS_NOT_SIGNED_UP);
return users[userAddress].postIDs; return users[userAddress].postIDs;
} }
function getUserDateOfRegister(address userAddress) public view returns (uint) { function getUserDateOfRegister(address userAddress) public view returns (uint) {
require (hasUserSignedUp(userAddress), "User hasn't signed up yet."); require(hasUserSignedUp(userAddress), USER_HAS_NOT_SIGNED_UP);
return users[userAddress].timestamp; return users[userAddress].timestamp;
} }
function getUser(address userAddress) public view returns (User memory) { function getUser(address userAddress) public view returns (User memory) {
require(hasUserSignedUp(userAddress), "User hasn't signed up yet."); require(hasUserSignedUp(userAddress), USER_HAS_NOT_SIGNED_UP);
return users[userAddress]; return users[userAddress];
} }
@ -94,17 +97,17 @@ contract Forum {
uint topicID; uint topicID;
} }
uint numTopics; // Total number of topics uint public numTopics; // Total number of topics
uint numPosts; // Total number of posts uint public numPosts; // Total number of posts
mapping (uint => Topic) topics; mapping(uint => Topic) topics;
mapping (uint => Post) posts; mapping(uint => Post) posts;
event TopicCreated(uint topicID, uint postID); event TopicCreated(uint topicID, uint postID);
event PostCreated(uint postID, uint topicID); event PostCreated(uint postID, uint topicID);
function createTopic() public returns (uint, uint) { function createTopic() public returns (uint, uint) {
require(hasUserSignedUp(msg.sender)); // Only registered users can create topics require(hasUserSignedUp(msg.sender), USER_HAS_NOT_SIGNED_UP);
//Creates topic //Creates topic
uint topicID = numTopics++; uint topicID = numTopics++;
topics[topicID] = Topic(topicID, msg.sender, block.timestamp, new uint[](0)); topics[topicID] = Topic(topicID, msg.sender, block.timestamp, new uint[](0));
@ -121,8 +124,8 @@ contract Forum {
} }
function createPost(uint topicID) public returns (uint) { function createPost(uint topicID) public returns (uint) {
require(hasUserSignedUp(msg.sender)); // Only registered users can create posts require(hasUserSignedUp(msg.sender), USER_HAS_NOT_SIGNED_UP);
require(topicID<numTopics); // Only allow posting to a topic that exists require(topicExists(topicID), TOPIC_DOES_NOT_EXIST);
uint postID = numPosts++; uint postID = numPosts++;
posts[postID] = Post(postID, msg.sender, block.timestamp, topicID); posts[postID] = Post(postID, msg.sender, block.timestamp, topicID);
topics[topicID].postIDs.push(postID); topics[topicID].postIDs.push(postID);
@ -131,12 +134,16 @@ contract Forum {
return postID; return postID;
} }
function getNumberOfTopics() public view returns (uint) { function topicExists(uint topicID) public view returns (bool) {
return numTopics; return topicID < numTopics;
}
function postExists(uint postID) public view returns (bool) {
return postID < numPosts;
} }
function getTopic(uint topicID) public view returns (address, string memory, uint, uint[] memory) { function getTopic(uint topicID) public view returns (address, string memory, uint, uint[] memory) {
require(topicID<numTopics); require(topicExists(topicID), TOPIC_DOES_NOT_EXIST);
return ( return (
topics[topicID].author, topics[topicID].author,
users[topics[topicID].author].username, users[topics[topicID].author].username,
@ -146,12 +153,17 @@ contract Forum {
} }
function getTopicPosts(uint topicID) public view returns (uint[] memory) { function getTopicPosts(uint topicID) public view returns (uint[] memory) {
require(topicID<numTopics); // Topic should exist require(topicExists(topicID), TOPIC_DOES_NOT_EXIST);
return topics[topicID].postIDs; return topics[topicID].postIDs;
} }
function getTopicAuthor(uint topicID) public view returns (address) {
require(topicExists(topicID), TOPIC_DOES_NOT_EXIST);
return topics[topicID].author;
}
function getPost(uint postID) public view returns (address, string memory, uint, uint) { function getPost(uint postID) public view returns (address, string memory, uint, uint) {
require(postID<numPosts); require(postExists(postID), POST_DOES_NOT_EXIST);
return ( return (
posts[postID].author, posts[postID].author,
users[posts[postID].author].username, users[posts[postID].author].username,

12
packages/concordia-contracts/contracts/Migrations.sol

@ -1,9 +1,9 @@
//SPDX-License-Identifier: MIT //SPDX-License-Identifier: MIT
pragma solidity 0.7.1; pragma solidity 0.8.0;
contract Migrations { contract Migrations {
address public owner; address public owner;
uint public last_completed_migration; uint public lastCompletedMigration;
constructor() { constructor() {
owner = msg.sender; owner = msg.sender;
@ -14,11 +14,11 @@ contract Migrations {
} }
function setCompleted(uint completed) public restricted { function setCompleted(uint completed) public restricted {
last_completed_migration = completed; lastCompletedMigration = completed;
} }
function upgrade(address new_address) public restricted { function upgrade(address newAddress) public restricted {
Migrations upgraded = Migrations(new_address); Migrations upgraded = Migrations(newAddress);
upgraded.setCompleted(last_completed_migration); upgraded.setCompleted(lastCompletedMigration);
} }
} }

109
packages/concordia-contracts/contracts/PostVoting.sol

@ -0,0 +1,109 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
import "./Forum.sol";
contract PostVoting {
Forum public forum;
constructor(Forum addr) {
forum = Forum(addr);
}
enum Option { DEFAULT, UP, DOWN } // DEFAULT -> 0, UP -> 1, DOWN -> 2
struct PostBallot {
mapping(address => Option) votes;
mapping(Option => address[]) voters;
}
mapping(uint => PostBallot) postBallots;
event UserVotedPost(address userAddress, uint postID, Option option);
function getVote(uint postID, address voter) public view returns (Option) {
require(forum.postExists(postID), forum.POST_DOES_NOT_EXIST());
return postBallots[postID].votes[voter];
}
// Gets vote count for a specific option (Option.UP/ Option.DOWN only!)
function getVoteCount(uint postID, Option option) private view returns (uint) {
require(forum.postExists(postID), forum.POST_DOES_NOT_EXIST());
return (postBallots[postID].voters[option].length);
}
function getUpvoteCount(uint postID) public view returns (uint) {
return (getVoteCount(postID, Option.UP));
}
function getDownvoteCount(uint postID) public view returns (uint) {
return (getVoteCount(postID, Option.DOWN));
}
// Gets voters for a specific option (Option.UP/ Option.DOWN)
function getVoters(uint postID, Option option) private view returns (address[] memory) {
require(forum.postExists(postID), forum.POST_DOES_NOT_EXIST());
return (postBallots[postID].voters[option]);
}
function getUpvoters(uint postID) public view returns (address[] memory) {
return (getVoters(postID, Option.UP));
}
function getDownvoters(uint postID) public view returns (address[] memory) {
return (getVoters(postID, Option.DOWN));
}
function getVoterIndex(uint postID, address voter) private view returns (uint) {
require(forum.hasUserSignedUp(voter), forum.USER_HAS_NOT_SIGNED_UP());
require(forum.postExists(postID), forum.POST_DOES_NOT_EXIST());
PostBallot storage postBallot = postBallots[postID];
Option votedOption = getVote(postID, voter);
address[] storage optionVoters = postBallot.voters[votedOption];
for (uint voterIndex = 0; voterIndex < optionVoters.length; voterIndex++)
if (optionVoters[voterIndex] == voter)
return voterIndex;
revert("Couldn't find voter's index!");
}
function vote(uint postID, Option option) private {
require(forum.hasUserSignedUp(msg.sender), forum.USER_HAS_NOT_SIGNED_UP());
require(forum.postExists(postID), forum.POST_DOES_NOT_EXIST());
PostBallot storage postBallot = postBallots[postID];
address voter = msg.sender;
Option prevOption = postBallot.votes[voter];
if (prevOption == option)
return;
// Remove previous vote if exists
if (prevOption != Option.DEFAULT) {
uint voterIndex = getVoterIndex(postID, voter);
// Swap with last voter address and delete vote
postBallot.voters[prevOption][voterIndex] = postBallot.voters[prevOption][postBallot.voters[prevOption].length - 1];
postBallot.voters[prevOption].pop();
}
// Add new vote
if (option != Option.DEFAULT)
postBallot.voters[option].push(voter);
postBallot.votes[voter] = option;
emit UserVotedPost(voter, postID, option);
}
function upvote(uint postID) public {
vote(postID, Option.UP);
}
function downvote(uint postID) public {
vote(postID, Option.DOWN);
}
function unvote(uint postID) public {
vote(postID, Option.DEFAULT);
}
}

155
packages/concordia-contracts/contracts/Voting.sol

@ -0,0 +1,155 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
import "./Forum.sol";
contract Voting {
// Error messages for require()
string constant TOPIC_POLL_DIFFERENT_CREATOR = "Only topic's author can create a poll.";
string constant POLL_EXISTS = "Poll already exists.";
string constant POLL_DOES_NOT_EXIST = "Poll does not exist.";
string constant INVALID_OPTION = "Invalid option.";
string constant USER_HAS_NOT_VOTED = "User hasn't voted.";
Forum public forum;
constructor(Forum addr) {
forum = Forum(addr);
}
struct Poll {
uint topicID;
uint numOptions;
string dataHash;
mapping(address => uint) votes;
mapping(uint => address[]) voters;
bool enableVoteChanges;
uint timestamp;
}
mapping(uint => Poll) polls;
event PollCreated(uint topicID);
event UserVotedPoll(address userAddress, uint topicID, uint vote);
function pollExists(uint topicID) public view returns (bool) {
if (polls[topicID].timestamp != 0)
return true;
return false;
}
function createPoll(uint topicID, uint numOptions, string memory dataHash, bool enableVoteChanges) public returns (uint) {
require(forum.hasUserSignedUp(msg.sender), forum.USER_HAS_NOT_SIGNED_UP());
require(forum.topicExists(topicID), forum.TOPIC_DOES_NOT_EXIST());
require(forum.getTopicAuthor(topicID) == msg.sender, TOPIC_POLL_DIFFERENT_CREATOR);
require(!pollExists(topicID), POLL_EXISTS);
Poll storage poll = polls[topicID];
poll.topicID = topicID;
poll.numOptions = numOptions;
poll.dataHash = dataHash;
poll.enableVoteChanges = enableVoteChanges;
poll.timestamp = block.timestamp;
emit PollCreated(topicID);
return topicID;
}
function getPollInfo(uint topicID) public view returns (uint, string memory, uint, uint) {
require(pollExists(topicID), POLL_DOES_NOT_EXIST);
uint totalVotes = getTotalVotes(topicID);
return (
polls[topicID].numOptions,
polls[topicID].dataHash,
polls[topicID].timestamp,
totalVotes
);
}
function isOptionValid(uint topicID, uint option) public view returns (bool) {
require(pollExists(topicID), POLL_DOES_NOT_EXIST);
if (option <= polls[topicID].numOptions) // Option 0 is valid as well (no option chosen)
return true;
return false;
}
function hasVoted(uint topicID, address voter) public view returns (bool) {
require(pollExists(topicID), POLL_DOES_NOT_EXIST);
if (polls[topicID].votes[voter] != 0)
return true;
return false;
}
function getVote(uint topicID, address voter) public view returns (uint) {
require(hasVoted(topicID, voter), USER_HAS_NOT_VOTED);
return polls[topicID].votes[voter];
}
function getVoteCount(uint topicID, uint option) public view returns (uint) {
require(pollExists(topicID), POLL_DOES_NOT_EXIST);
require(isOptionValid(topicID, option), INVALID_OPTION);
return (polls[topicID].voters[option].length);
}
function getTotalVotes(uint topicID) public view returns (uint) {
require(pollExists(topicID), POLL_DOES_NOT_EXIST);
Poll storage poll = polls[topicID];
uint totalVotes = 0;
for (uint pollOption = 1; pollOption <= poll.numOptions; pollOption++)
totalVotes += poll.voters[pollOption].length;
return totalVotes;
}
// Gets voters for a specific option
function getVoters(uint topicID, uint option) public view returns (address[] memory) {
require(pollExists(topicID), POLL_DOES_NOT_EXIST);
return (polls[topicID].voters[option]);
}
function getVoterIndex(uint topicID, address voter) public view returns (uint) {
require(pollExists(topicID), POLL_DOES_NOT_EXIST);
require(hasVoted(topicID, voter), USER_HAS_NOT_VOTED);
Poll storage poll = polls[topicID];
uint votedOption = getVote(topicID, voter);
address[] storage optionVoters = poll.voters[votedOption];
for (uint voterIndex = 0; voterIndex < optionVoters.length; voterIndex++)
if (optionVoters[voterIndex] == voter)
return voterIndex;
revert("Couldn't find voter's index!");
}
function vote(uint topicID, uint option) public {
require(forum.hasUserSignedUp(msg.sender), forum.USER_HAS_NOT_SIGNED_UP());
require(pollExists(topicID), POLL_DOES_NOT_EXIST);
require(isOptionValid(topicID, option), INVALID_OPTION);
Poll storage poll = polls[topicID];
address voter = msg.sender;
uint prevOption = poll.votes[voter];
if (prevOption == option)
return;
// Voter hasn't voted before
if (prevOption == 0) {
poll.voters[option].push(voter);
poll.votes[voter] = option;
emit UserVotedPoll(voter, topicID, option);
}
else if (poll.enableVoteChanges) {
uint voterIndex = getVoterIndex(topicID, voter);
// Swap with last voter address and delete vote
poll.voters[prevOption][voterIndex] = poll.voters[prevOption][poll.voters[prevOption].length - 1];
poll.voters[prevOption].pop();
if (option != 0)
poll.voters[option].push(voter);
poll.votes[voter] = option;
emit UserVotedPoll(voter, topicID, option);
}
}
}

8
packages/concordia-contracts/index.js

@ -1,14 +1,16 @@
let Forum; let Forum, Voting, PostVoting;
/* eslint-disable global-require */
try { try {
// eslint-disable-next-line global-require
Forum = require('./build/Forum.json'); Forum = require('./build/Forum.json');
Voting = require('./build/Voting.json');
PostVoting = require('./build/PostVoting.json');
} catch (e) { } catch (e) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error("Could not require contract artifacts. Haven't you run compile yet?"); console.error("Could not require contract artifacts. Haven't you run compile yet?");
} }
module.exports = { module.exports = {
contracts: [Forum], contracts: [Forum, Voting, PostVoting],
forumContract: Forum, forumContract: Forum,
}; };

8
packages/concordia-contracts/migrations/2_deploy_contracts.js

@ -1,6 +1,12 @@
const Forum = artifacts.require('Forum'); const Forum = artifacts.require('Forum');
const Voting = artifacts.require('Voting');
const PostVoting = artifacts.require('PostVoting');
// eslint-disable-next-line func-names // eslint-disable-next-line func-names
module.exports = function (deployer) { module.exports = function (deployer) {
deployer.deploy(Forum); return deployer.deploy(Forum)
.then(async (forum) => Promise.all([
deployer.deploy(Voting, forum.address),
deployer.deploy(PostVoting, forum.address),
]));
}; };

2
packages/concordia-contracts/package.json

@ -16,7 +16,7 @@
}, },
"dependencies": { "dependencies": {
"@openzeppelin/contracts": "~3.2.0", "@openzeppelin/contracts": "~3.2.0",
"truffle": "~5.1.45" "truffle": "~5.1.55"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^6.8.0", "eslint": "^6.8.0",

112
packages/concordia-contracts/test/TestVoting.sol

@ -0,0 +1,112 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Forum.sol";
import "../contracts/Voting.sol";
contract TestVoting {
Forum forum;
uint firstTopicId;
function beforeAll() public {
forum = Forum(DeployedAddresses.Forum());
forum.signUp("testAccount");
(firstTopicId,) = forum.createTopic();
}
function testIfPollExists() public {
Voting voting = Voting(DeployedAddresses.Voting());
bool actual = voting.pollExists(firstTopicId);
Assert.equal(actual, false, "Poll should not exist");
}
function testCreatePoll() public {
Voting voting = Voting(DeployedAddresses.Voting());
uint actual = voting.createPoll(firstTopicId, 3, "asdf", false);
Assert.equal(actual, firstTopicId, "Topic Id should be 1");
}
function testGetTotalVotes() public {
Voting voting = Voting(DeployedAddresses.Voting());
uint actual = voting.getTotalVotes(firstTopicId);
Assert.equal(actual, 0, "Topic Id should be 0");
}
function testGetPollInfo() public {
Voting voting = Voting(DeployedAddresses.Voting());
(uint actualNumberOfOptions, string memory actualDataHash, , uint actualNumberOfVotes) = voting.getPollInfo(firstTopicId);
Assert.equal(actualNumberOfOptions, 3, "Number of votes should be 0");
Assert.equal(actualDataHash, "asdf", "Number of votes should be 0");
Assert.equal(actualNumberOfVotes, 0, "Number of votes should be 0");
}
function testVote() public {
Voting voting = Voting(DeployedAddresses.Voting());
voting.vote(firstTopicId, 1);
uint votesActual = voting.getTotalVotes(firstTopicId);
Assert.equal(votesActual, 1, "Number of votes should be 1");
}
function testGetVoteCount() public {
Voting voting = Voting(DeployedAddresses.Voting());
uint actualVotesOption0 = voting.getVoteCount(firstTopicId, 1);
uint actualVotesOption1 = voting.getVoteCount(firstTopicId, 2);
uint actualVotesOption2 = voting.getVoteCount(firstTopicId, 3);
Assert.equal(actualVotesOption0, 1, "Vote count is not correct");
Assert.equal(actualVotesOption1, 0, "Vote count is not correct");
Assert.equal(actualVotesOption2, 0, "Vote count is not correct");
}
function testChangeVoteWhenDisabled() public {
Voting voting = Voting(DeployedAddresses.Voting());
(uint topicId,) = forum.createTopic();
voting.createPoll(topicId, 3, "asdf", false);
voting.vote(topicId, 1);
uint actualVotesOption0 = voting.getVoteCount(topicId, 1);
uint actualVotesOption1 = voting.getVoteCount(topicId, 2);
voting.vote(topicId, 2);
uint actualVotesOption2 = voting.getVoteCount(topicId, 1);
uint actualVotesOption3 = voting.getVoteCount(topicId, 2);
Assert.equal(actualVotesOption0, 1, "Number of votes should be 1");
Assert.equal(actualVotesOption1, 0, "Number of votes should be 0");
Assert.equal(actualVotesOption2, 1, "Number of votes should be 1");
Assert.equal(actualVotesOption3, 0, "Number of votes should be 0");
}
function testChangeVoteWhenEnabled() public {
Voting voting = Voting(DeployedAddresses.Voting());
(uint topicId,) = forum.createTopic();
voting.createPoll(topicId, 3, "asdf", true);
voting.vote(topicId, 1);
uint actualVotesOption0 = voting.getVoteCount(topicId, 1);
uint actualVotesOption1 = voting.getVoteCount(topicId, 2);
voting.vote(topicId, 2);
uint actualVotesOption2 = voting.getVoteCount(topicId, 1);
uint actualVotesOption3 = voting.getVoteCount(topicId, 2);
Assert.equal(actualVotesOption0, 1, "Number of votes should be 1");
Assert.equal(actualVotesOption1, 0, "Number of votes should be 0");
Assert.equal(actualVotesOption2, 0, "Number of votes should be 0");
Assert.equal(actualVotesOption3, 1, "Number of votes should be 1");
}
}

2
packages/concordia-contracts/truffle-config.js

@ -10,7 +10,7 @@ module.exports = {
// to customize your Truffle configuration! // to customize your Truffle configuration!
compilers: { compilers: {
solc: { solc: {
version: '0.7.1', version: '0.8.0',
}, },
}, },
contracts_build_directory: path.join(__dirname, 'build/'), contracts_build_directory: path.join(__dirname, 'build/'),

Loading…
Cancel
Save