Merge branch '000-snt-voting-dapp' of https://github.com/status-im/contracts into 000-snt-voting-dapp
This commit is contained in:
commit
00957320b1
|
@ -48,10 +48,6 @@
|
|||
"TestToken": {
|
||||
"deploy": true
|
||||
},
|
||||
"MultiOptionPollManager": {
|
||||
"deploy": false
|
||||
},
|
||||
|
||||
"SNT": {
|
||||
"instanceOf": "MiniMeToken",
|
||||
"deploy": true,
|
||||
|
@ -83,6 +79,9 @@
|
|||
],
|
||||
"gasLimit": 5000000
|
||||
},
|
||||
"SingleChoiceFactory": {
|
||||
"deploy": false
|
||||
},
|
||||
"PollManager": {
|
||||
"deploy": true,
|
||||
"args": ["$MiniMeTokenFactory", "$SNT"]
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
pragma solidity ^0.4.21;
|
||||
|
||||
import "../common/Controlled.sol";
|
||||
import "../token/MiniMeTokenInterface.sol";
|
||||
import "../token/MiniMeTokenFactory.sol";
|
||||
|
||||
/**
|
||||
* @title PollManager
|
||||
* @author Richard Ramos (Status Research & Development GmbH)
|
||||
*/
|
||||
contract MultiOptionPollManager is Controlled {
|
||||
event PollCreated(uint256 pollId, uint8 numOptions);
|
||||
event PollCanceled(uint256 pollId);
|
||||
event Voted(address voter, uint8[] votes);
|
||||
|
||||
MiniMeTokenFactory public tokenFactory;
|
||||
MiniMeTokenInterface public token;
|
||||
|
||||
Poll[] public polls;
|
||||
|
||||
struct Vote {
|
||||
mapping(uint8 => uint8) distribution;
|
||||
bool voted;
|
||||
}
|
||||
|
||||
struct Poll {
|
||||
uint start;
|
||||
uint end;
|
||||
uint8 numOptions;
|
||||
address[] voters;
|
||||
mapping(address => Vote) voteMap;
|
||||
uint256[] results;
|
||||
address token;
|
||||
bool cancelled;
|
||||
}
|
||||
|
||||
constructor(address _tokenFactory, address _token)
|
||||
public
|
||||
{
|
||||
tokenFactory = MiniMeTokenFactory(_tokenFactory);
|
||||
token = MiniMeTokenInterface(_token);
|
||||
}
|
||||
|
||||
function createPoll(
|
||||
uint _blocksUntilVotingStart,
|
||||
uint _voteDuration,
|
||||
uint8 _numOptions
|
||||
)
|
||||
public
|
||||
onlyController
|
||||
returns (uint pollId)
|
||||
{
|
||||
pollId = polls.length++;
|
||||
|
||||
Poll storage p = polls[pollId];
|
||||
|
||||
p.cancelled = false;
|
||||
p.start = block.number + _blocksUntilVotingStart;
|
||||
p.end = p.start + _voteDuration;
|
||||
p.numOptions = _numOptions;
|
||||
p.token = tokenFactory.createCloneToken(
|
||||
token,
|
||||
p.start - 1,
|
||||
"VotingToken",
|
||||
MiniMeToken(token).decimals(),
|
||||
"VTN",
|
||||
true);
|
||||
|
||||
|
||||
emit PollCreated(pollId, _numOptions);
|
||||
}
|
||||
|
||||
function vote(uint _pollId, uint8[] _vote)
|
||||
public
|
||||
{
|
||||
Poll storage poll = polls[_pollId];
|
||||
|
||||
require(block.number >= poll.start);
|
||||
require(block.number <= poll.end);
|
||||
require(_vote.length == poll.numOptions);
|
||||
require(!poll.voteMap[msg.sender].voted);
|
||||
require(!poll.cancelled);
|
||||
|
||||
uint8 percentage = 0;
|
||||
|
||||
for(uint8 i = 0; i < poll.numOptions; i++){
|
||||
poll.results[i] = (MiniMeTokenInterface(poll.token).balanceOf(msg.sender) * _vote[i]) / 100;
|
||||
percentage += _vote[i];
|
||||
poll.voteMap[msg.sender].distribution[i] = _vote[i];
|
||||
}
|
||||
|
||||
require(percentage == 100);
|
||||
|
||||
poll.voteMap[msg.sender].voted = true;
|
||||
poll.voters.push(msg.sender);
|
||||
|
||||
emit Voted(msg.sender, _vote);
|
||||
}
|
||||
|
||||
function getPollCount()
|
||||
public
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return polls.length;
|
||||
}
|
||||
|
||||
function exists(uint _pollId)
|
||||
public
|
||||
view
|
||||
returns (bool) {
|
||||
return polls.length != 0 && polls[_pollId].start != 0;
|
||||
}
|
||||
|
||||
function getPollResults(uint _pollId)
|
||||
external
|
||||
view
|
||||
returns (uint256[]){
|
||||
return polls[_pollId].results;
|
||||
}
|
||||
|
||||
function hasVotesRecorded(uint256 _pollId)
|
||||
external
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return polls[_pollId].voters.length > 0;
|
||||
}
|
||||
|
||||
function isVotingAvailable(uint _pollId) public view returns (bool){
|
||||
Poll memory p = polls[_pollId];
|
||||
return p.end > block.number;
|
||||
}
|
||||
|
||||
function cancel(uint _pollId) onlyController {
|
||||
require(polls[_pollId].start > 0);
|
||||
require(polls[_pollId].end < block.number);
|
||||
|
||||
Poll storage p = polls[_pollId];
|
||||
p.cancelled = true;
|
||||
|
||||
emit PollCanceled(_pollId);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
pragma solidity ^0.4.23;
|
||||
|
||||
contract IPollFactory {
|
||||
function create(bytes _description) public returns(address);
|
||||
}
|
|
@ -65,7 +65,7 @@ contract LowLevelStringManipulator {
|
|||
}
|
||||
|
||||
function getTokenNameSymbol(address tokenAddr) internal returns (string name, string symbol) {
|
||||
return (getString(tokenAddr, bytes4(sha3("name()"))),getString(tokenAddr, bytes4(sha3("symbol()"))));
|
||||
return (getString(tokenAddr, bytes4(keccak256("name()"))),getString(tokenAddr, bytes4(keccak256("symbol()"))));
|
||||
}
|
||||
|
||||
function getString(address _dst, bytes4 sig) internal returns(string) {
|
||||
|
|
|
@ -3,16 +3,17 @@ pragma solidity ^0.4.23;
|
|||
import "../common/Controlled.sol";
|
||||
import "./LowLevelStringManipulator.sol";
|
||||
import "../token/MiniMeToken.sol";
|
||||
import "./IPollFactory.sol";
|
||||
import "./SingleChoiceFactory.sol";
|
||||
|
||||
|
||||
|
||||
contract IPollContract {
|
||||
function deltaVote(int _amount, bytes32 _ballot) returns (bool _succes);
|
||||
function pollType() constant returns (bytes32);
|
||||
function question() constant returns (string);
|
||||
function deltaVote(int _amount, bytes32 _ballot) public returns (bool _succes);
|
||||
function pollType() public constant returns (bytes32);
|
||||
function question() public constant returns (string);
|
||||
}
|
||||
|
||||
contract IPollFactory {
|
||||
function create(bytes _description) returns(address);
|
||||
}
|
||||
|
||||
contract PollManager is LowLevelStringManipulator, Controlled {
|
||||
|
||||
|
@ -33,14 +34,16 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
|||
}
|
||||
|
||||
Poll[] _polls;
|
||||
IPollFactory pollFactory;
|
||||
|
||||
MiniMeTokenFactory public tokenFactory;
|
||||
MiniMeToken public token;
|
||||
|
||||
function PollManager(address _tokenFactory, address _token)
|
||||
constructor(address _tokenFactory, address _token)
|
||||
public {
|
||||
tokenFactory = MiniMeTokenFactory(_tokenFactory);
|
||||
token = MiniMeToken(_token);
|
||||
pollFactory = IPollFactory(new SingleChoiceFactory());
|
||||
}
|
||||
|
||||
modifier onlySNTHolder {
|
||||
|
@ -52,21 +55,24 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
|||
function addPoll(
|
||||
uint _startBlock,
|
||||
uint _endBlock,
|
||||
address _pollFactory,
|
||||
bytes _description)
|
||||
public
|
||||
onlySNTHolder
|
||||
returns (uint _idPoll)
|
||||
{
|
||||
if (_endBlock <= _startBlock) throw;
|
||||
if (_endBlock <= getBlockNumber()) throw;
|
||||
require(_endBlock > _startBlock && _endBlock > block.number);
|
||||
|
||||
_idPoll = _polls.length;
|
||||
_polls.length ++;
|
||||
Poll p = _polls[ _idPoll ];
|
||||
Poll storage p = _polls[ _idPoll ];
|
||||
p.startBlock = _startBlock;
|
||||
p.endBlock = _endBlock;
|
||||
p.voters = 0;
|
||||
|
||||
var (name, symbol) = getTokenNameSymbol(address(token));
|
||||
string memory name;
|
||||
string memory symbol;
|
||||
(name, symbol) = getTokenNameSymbol(address(token));
|
||||
|
||||
string memory proposalName = strConcat(name, "_", uint2str(_idPoll));
|
||||
string memory proposalSymbol = strConcat(symbol, "_", uint2str(_idPoll));
|
||||
|
||||
|
@ -78,23 +84,32 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
|||
proposalSymbol,
|
||||
true);
|
||||
|
||||
p.pollContract = pollFactory.create(_description);
|
||||
|
||||
p.pollContract = IPollFactory(_pollFactory).create(_description);
|
||||
|
||||
if (p.pollContract == 0) throw;
|
||||
require(p.pollContract != 0);
|
||||
|
||||
emit PollCreated(_idPoll);
|
||||
}
|
||||
|
||||
function cancelPoll(uint _idPoll) onlyController {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
Poll p = _polls[_idPoll];
|
||||
if (getBlockNumber() >= p.endBlock) throw;
|
||||
function cancelPoll(uint _idPoll)
|
||||
onlyController
|
||||
public
|
||||
{
|
||||
require(_idPoll < _polls.length);
|
||||
|
||||
Poll storage p = _polls[_idPoll];
|
||||
|
||||
require(p.endBlock < block.number);
|
||||
|
||||
p.canceled = true;
|
||||
PollCanceled(_idPoll);
|
||||
emit PollCanceled(_idPoll);
|
||||
}
|
||||
|
||||
function canVote(uint _idPoll) public view returns(bool) {
|
||||
function canVote(uint _idPoll)
|
||||
public
|
||||
view
|
||||
returns(bool)
|
||||
{
|
||||
if(_idPoll >= _polls.length) return false;
|
||||
|
||||
Poll storage p = _polls[_idPoll];
|
||||
|
@ -106,23 +121,19 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
|||
balance != 0;
|
||||
}
|
||||
|
||||
function vote(uint _idPoll, bytes32 _ballot) {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
Poll p = _polls[_idPoll];
|
||||
if (getBlockNumber() < p.startBlock) throw;
|
||||
if (getBlockNumber() >= p.endBlock) throw;
|
||||
if (p.canceled) throw;
|
||||
function vote(uint _idPoll, bytes32 _ballot) public {
|
||||
require(_idPoll < _polls.length);
|
||||
|
||||
Poll storage p = _polls[_idPoll];
|
||||
|
||||
require(block.number >= p.startBlock && block.number < p.endBlock && !p.canceled);
|
||||
|
||||
unvote(_idPoll);
|
||||
|
||||
uint amount = MiniMeToken(p.token).balanceOf(msg.sender);
|
||||
|
||||
if (amount == 0) throw;
|
||||
|
||||
|
||||
// enableTransfers = true;
|
||||
if (!MiniMeToken(p.token).transferFrom(msg.sender, address(this), amount)) throw;
|
||||
// enableTransfers = false;
|
||||
require(amount != 0);
|
||||
require(MiniMeToken(p.token).transferFrom(msg.sender, address(this), amount));
|
||||
|
||||
p.votes[msg.sender].ballot = _ballot;
|
||||
p.votes[msg.sender].amount = amount;
|
||||
|
@ -131,44 +142,48 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
|||
|
||||
p.votersPerBallot[_ballot]++;
|
||||
|
||||
if (!IPollContract(p.pollContract).deltaVote(int(amount), _ballot)) throw;
|
||||
require(IPollContract(p.pollContract).deltaVote(int(amount), _ballot));
|
||||
|
||||
Vote(_idPoll, msg.sender, _ballot, amount);
|
||||
emit Vote(_idPoll, msg.sender, _ballot, amount);
|
||||
}
|
||||
|
||||
function unvote(uint _idPoll) {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
Poll p = _polls[_idPoll];
|
||||
if (getBlockNumber() < p.startBlock) throw;
|
||||
if (getBlockNumber() >= p.endBlock) throw;
|
||||
if (p.canceled) throw;
|
||||
function unvote(uint _idPoll) public {
|
||||
require(_idPoll < _polls.length);
|
||||
Poll storage p = _polls[_idPoll];
|
||||
|
||||
require(block.number >= p.startBlock && block.number < p.endBlock && !p.canceled);
|
||||
|
||||
uint amount = p.votes[msg.sender].amount;
|
||||
bytes32 ballot = p.votes[msg.sender].ballot;
|
||||
if (amount == 0) return;
|
||||
|
||||
if (!IPollContract(p.pollContract).deltaVote(-int(amount), ballot)) throw;
|
||||
require(IPollContract(p.pollContract).deltaVote(-int(amount), ballot));
|
||||
|
||||
p.votes[msg.sender].ballot = 0;
|
||||
p.votes[msg.sender].ballot = 0x00;
|
||||
p.votes[msg.sender].amount = 0;
|
||||
p.votersPerBallot[ballot]--;
|
||||
|
||||
p.voters--;
|
||||
|
||||
// enableTransfers = true;
|
||||
if (!MiniMeToken(p.token).transferFrom(address(this), msg.sender, amount)) throw;
|
||||
// enableTransfers = false;
|
||||
require(MiniMeToken(p.token).transferFrom(address(this), msg.sender, amount));
|
||||
|
||||
Unvote(_idPoll, msg.sender, ballot, amount);
|
||||
emit Unvote(_idPoll, msg.sender, ballot, amount);
|
||||
}
|
||||
|
||||
// Constant Helper Function
|
||||
|
||||
function nPolls() constant returns(uint) {
|
||||
function nPolls()
|
||||
public
|
||||
view
|
||||
returns(uint)
|
||||
{
|
||||
return _polls.length;
|
||||
}
|
||||
|
||||
function poll(uint _idPoll) constant returns(
|
||||
function poll(uint _idPoll)
|
||||
public
|
||||
view
|
||||
returns(
|
||||
uint _startBlock,
|
||||
uint _endBlock,
|
||||
address _token,
|
||||
|
@ -179,32 +194,44 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
|||
bool _finalized,
|
||||
uint _totalCensus,
|
||||
uint _voters
|
||||
) {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
Poll p = _polls[_idPoll];
|
||||
)
|
||||
{
|
||||
require(_idPoll < _polls.length);
|
||||
|
||||
Poll storage p = _polls[_idPoll];
|
||||
|
||||
_startBlock = p.startBlock;
|
||||
_endBlock = p.endBlock;
|
||||
_token = p.token;
|
||||
_pollContract = p.pollContract;
|
||||
_canceled = p.canceled;
|
||||
_pollType = IPollContract(p.pollContract).pollType();
|
||||
_question = getString(p.pollContract, bytes4(sha3("question()")));
|
||||
_finalized = (!p.canceled) && (getBlockNumber() >= _endBlock);
|
||||
_question = getString(p.pollContract, bytes4(keccak256("question()")));
|
||||
_finalized = (!p.canceled) && (block.number >= _endBlock);
|
||||
_totalCensus = MiniMeToken(p.token).totalSupply();
|
||||
_voters = p.voters;
|
||||
}
|
||||
|
||||
function getVote(uint _idPoll, address _voter) constant returns (bytes32 _ballot, uint _amount) {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
Poll p = _polls[_idPoll];
|
||||
function getVote(uint _idPoll, address _voter)
|
||||
public
|
||||
view
|
||||
returns (bytes32 _ballot, uint _amount)
|
||||
{
|
||||
require(_idPoll < _polls.length);
|
||||
|
||||
Poll storage p = _polls[_idPoll];
|
||||
|
||||
_ballot = p.votes[_voter].ballot;
|
||||
_amount = p.votes[_voter].amount;
|
||||
}
|
||||
|
||||
function getVotesByBallot(uint _idPoll, bytes32 _ballot)
|
||||
public view returns(uint voters, uint votes) {
|
||||
if (_idPoll >= _polls.length) throw;
|
||||
public
|
||||
view
|
||||
returns(uint voters, uint votes)
|
||||
{
|
||||
require(_idPoll < _polls.length);
|
||||
|
||||
Poll storage p = _polls[_idPoll];
|
||||
|
||||
voters = p.votersPerBallot[_ballot];
|
||||
|
@ -212,29 +239,30 @@ contract PollManager is LowLevelStringManipulator, Controlled {
|
|||
|
||||
}
|
||||
|
||||
function proxyPayment(address ) payable returns(bool) {
|
||||
function proxyPayment(address )
|
||||
payable
|
||||
returns(bool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function onTransfer(address , address , uint ) returns(bool) {
|
||||
function onTransfer(address , address , uint )
|
||||
public
|
||||
pure
|
||||
returns(bool)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function onApprove(address , address , uint ) returns(bool) {
|
||||
function onApprove(address , address , uint )
|
||||
public
|
||||
pure
|
||||
returns(bool) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function getBlockNumber() internal constant returns (uint) {
|
||||
return block.number;
|
||||
}
|
||||
|
||||
event Vote(uint indexed idPoll, address indexed _voter, bytes32 ballot, uint amount);
|
||||
event Unvote(uint indexed idPoll, address indexed _voter, bytes32 ballot, uint amount);
|
||||
event PollCanceled(uint indexed idPoll);
|
||||
event PollCreated(uint indexed idPoll);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -27,12 +27,15 @@ contract SingleChoice is Controlled {
|
|||
|
||||
string public question;
|
||||
string[] public choices;
|
||||
|
||||
int[] public result;
|
||||
int[] public qvResult;
|
||||
|
||||
bytes32 uid;
|
||||
|
||||
function SingleChoice(address _controller, bytes _rlpDefinition, uint salt) {
|
||||
|
||||
uid = sha3(block.blockhash(block.number-1), salt);
|
||||
uid = keccak256(block.blockhash(block.number-1), salt);
|
||||
controller = _controller;
|
||||
|
||||
var itmPoll = _rlpDefinition.toRLPItem(true);
|
||||
|
@ -55,9 +58,10 @@ contract SingleChoice is Controlled {
|
|||
}
|
||||
|
||||
result.length = choices.length;
|
||||
qvResult.length = choices.length;
|
||||
}
|
||||
|
||||
function pollType() constant returns (bytes32) {
|
||||
function pollType() public constant returns (bytes32) {
|
||||
return bytes32("SINGLE_CHOICE");
|
||||
}
|
||||
|
||||
|
@ -71,7 +75,18 @@ contract SingleChoice is Controlled {
|
|||
function deltaVote(int _amount, bytes32 _ballot) onlyController returns (bool _succes) {
|
||||
if (!isValid(_ballot)) return false;
|
||||
uint v = uint(_ballot) / (2**248);
|
||||
|
||||
result[v] += _amount;
|
||||
|
||||
int qv;
|
||||
if (_amount < 0) {
|
||||
qv = -sqrt(-_amount);
|
||||
} else {
|
||||
qv = sqrt(_amount);
|
||||
}
|
||||
|
||||
qvResult[v] += qv;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -80,7 +95,16 @@ contract SingleChoice is Controlled {
|
|||
}
|
||||
|
||||
function getBallot(uint _option) constant returns(bytes32) {
|
||||
return bytes32((_option * (2**248)) + (uint(sha3(uid, _option)) & (2**248 -1)));
|
||||
return bytes32((_option * (2**248)) + (uint(keccak256(uid, _option)) & (2**248 -1)));
|
||||
}
|
||||
|
||||
function sqrt(int256 x) public pure returns (int256 y) {
|
||||
int256 z = (x + 1) / 2;
|
||||
y = x;
|
||||
while (z < y) {
|
||||
y = z;
|
||||
z = (x / z + z) / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
pragma solidity ^0.4.6;
|
||||
|
||||
import "./SingleChoice.sol";
|
||||
import "./PollManager.sol";
|
||||
import "./IPollFactory.sol";
|
||||
|
||||
|
||||
contract SingleChoiceFactory is IPollFactory {
|
||||
uint salt;
|
||||
function create(bytes _description) returns(address) {
|
||||
function create(bytes _description) public returns(address) {
|
||||
salt++;
|
||||
SingleChoice sc = new SingleChoice(msg.sender, _description, salt);
|
||||
SingleChoiceCreated(address(sc));
|
||||
emit SingleChoiceCreated(address(sc));
|
||||
return address(sc);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,12 +26,12 @@ config({
|
|||
],
|
||||
"gasLimit": 4000000
|
||||
},
|
||||
"SingleChoiceFactory": {
|
||||
"deploy": false
|
||||
},
|
||||
"PollManager": {
|
||||
"deploy": true,
|
||||
"args": ["$MiniMeTokenFactory", "$SNT"]
|
||||
},
|
||||
"SingleChoiceFactory": {
|
||||
"deploy": true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -59,13 +59,13 @@ describe("VotingDapp", function () {
|
|||
|
||||
web3.eth.getAccounts().then((acc) => {
|
||||
accounts = acc;
|
||||
return SNT.methods.generateTokens(accounts[0], 123456).send()
|
||||
return SNT.methods.generateTokens(accounts[0], 6).send()
|
||||
}).then((receipt) => {
|
||||
return SNT.methods.generateTokens(accounts[1], 789012).send()
|
||||
return SNT.methods.generateTokens(accounts[1], 12).send()
|
||||
}).then((receipt) => {
|
||||
return SNT.methods.generateTokens(accounts[2], 345678).send()
|
||||
return SNT.methods.generateTokens(accounts[2], 10).send()
|
||||
}).then((receipt) => {
|
||||
return SNT.methods.generateTokens(accounts[3], 901234).send()
|
||||
return SNT.methods.generateTokens(accounts[3], 7).send()
|
||||
}).then((receipt) => {
|
||||
done();
|
||||
});
|
||||
|
@ -84,7 +84,6 @@ describe("VotingDapp", function () {
|
|||
receipt = await PollManager.methods.addPoll(
|
||||
blockNumber,
|
||||
blockNumber + 10,
|
||||
SingleChoiceFactory.options.address,
|
||||
question)
|
||||
.send({from: accounts[8]});
|
||||
assert.fail('should have reverted before');
|
||||
|
@ -99,7 +98,6 @@ describe("VotingDapp", function () {
|
|||
receipt = await PollManager.methods.addPoll(
|
||||
blockNumber,
|
||||
blockNumber + 10,
|
||||
SingleChoiceFactory.options.address,
|
||||
question)
|
||||
.send({from: accounts[0]});
|
||||
|
||||
|
@ -150,18 +148,25 @@ describe("VotingDapp", function () {
|
|||
poll = await PollManager.methods.poll(pollId).call();
|
||||
let votersByBallotYES = await PollManager.methods.getVotesByBallot(pollId, Yes).call();
|
||||
let tokenVotesByBallotYES = await pollContract.methods.result(0).call(); // 0 == Yes (because it is the initial option )
|
||||
let quadraticVotesByBallotYES = await pollContract.methods.qvResult(0).call(); // 0 == Yes (because it is the initial option )
|
||||
|
||||
// console.dir(poll); // Will contain state of the poll
|
||||
// console.log(tokenVotesByBallotYES); // Contains how many votes has a ballot
|
||||
// console.log(votersByBallotYES); // Contains how many voters voted for that option
|
||||
// Will contain state of the poll
|
||||
// console.dir(poll);
|
||||
|
||||
// Contains how many votes has a ballot
|
||||
// console.log(tokenVotesByBallotYES);
|
||||
|
||||
// Contains how many votes has a ballot using quadratic voting
|
||||
//console.log(quadraticVotesByBallotYES);
|
||||
|
||||
// Contains how many voters voted for that option
|
||||
// console.log(votersByBallotYES);
|
||||
|
||||
// ===================================================
|
||||
// Unvote
|
||||
receipt = await PollManager.methods.unvote(pollId).send({from: accounts[0]});
|
||||
assert.equal(!!receipt.events.Unvote, true, "Unvote not triggered");
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue