diff --git a/contracts/GovernanceData.sol b/contracts/GovernanceData.sol index e796eda..9346bd3 100644 --- a/contracts/GovernanceData.sol +++ b/contracts/GovernanceData.sol @@ -655,7 +655,7 @@ contract GovernanceData is Upgradeable { //solhint-disable-line ); } - /// @dev fetches details for simplevoting and also verifies that the voter has not casted a vote already + /// @dev fetches details for simplevoting and also verifies that proposal is open for voting function getProposalDetailsForSV(uint _proposalId) public view diff --git a/contracts/ProposalCategoryAdder.sol b/contracts/ProposalCategoryAdder.sol index c1cbbe1..216598e 100644 --- a/contracts/ProposalCategoryAdder.sol +++ b/contracts/ProposalCategoryAdder.sol @@ -97,7 +97,7 @@ contract ProposalCategoryAdder { ); proposalCategory.addInitialSubC( "Pause Proposal", - "QmS5SrwX6J8Cfhp3LAb6N54KYDc55hpnLdFgG6eCPkGvQx", + "QmPh5j3aAPhC6VZ8snjwLWPtR7Ps3os8zdYERTtp5W6RAp", 6, address(0), "GD", @@ -106,7 +106,7 @@ contract ProposalCategoryAdder { ); proposalCategory.addInitialSubC( "Resume Proposal", - "QmS5SrwX6J8Cfhp3LAb6N54KYDc55hpnLdFgG6eCPkGvQx", + "QmSDojLprBLDrPqF7HAaDCdi2Hy129LBwzfRMKhkt2begC", 6, address(0), "GD", diff --git a/contracts/SimpleVoting.sol b/contracts/SimpleVoting.sol index 70bc13f..ab72682 100644 --- a/contracts/SimpleVoting.sol +++ b/contracts/SimpleVoting.sol @@ -213,7 +213,8 @@ contract SimpleVoting is Upgradeable { calculateVoteReward(_memberAddress, i, proposalId, lastIndex); pendingGBTReward += tempGBTReward; pendingDAppReward += tempDAppReward; - rewardClaimed[voteId] = true; + if (lastIndex != i) + rewardClaimed[voteId] = true; } } if (lastIndex == 0) @@ -261,10 +262,6 @@ contract SimpleVoting is Upgradeable { return allVotesByMember[_memberAddress]; } - function getVoteIdOfNthVoteOfMember(address _memberAddress, uint _vote) public view returns(uint) { - return allVotesByMember[_memberAddress][_vote]; - } - function getTotalNumberOfVotesByAddress(address _memberAddress) public view returns(uint) { return allVotesByMember[_memberAddress].length; } @@ -581,7 +578,7 @@ contract SimpleVoting is Upgradeable { (solutionChosen, proposalStatus, finalVredict, voteValue, totalReward, subCategory) = getVoteDetailsToCalculateReward(_memberAddress, _voteNo); - if (proposalStatus < 2 && lastIndex == 0) + if (proposalStatus <= 2 && lastIndex == 0) lastIndex = _voteNo; if (finalVredict > 0 && solutionChosen == finalVredict) { calcReward = (proposalCategory.getRewardPercVote(subCategory) * voteValue * totalReward) diff --git a/contracts/TokenProxy.sol b/contracts/TokenProxy.sol index e4d1275..386a26d 100644 --- a/contracts/TokenProxy.sol +++ b/contracts/TokenProxy.sol @@ -16,6 +16,9 @@ contract TokenProxy is ERC1132 { GBTStandardToken public originalToken; constructor(address _originalToken) public { + + require(_originalToken != address(0)); + originalToken = GBTStandardToken(_originalToken); } @@ -59,7 +62,7 @@ contract TokenProxy is ERC1132 { if (locked[msg.sender][_reason].amount == 0) lockReason[msg.sender].push(_reason); - + originalToken.transferFrom(msg.sender, address(this), _amount); locked[msg.sender][_reason] = lockToken(_amount, validUntil, false); @@ -84,6 +87,7 @@ contract TokenProxy is ERC1132 { require(tokensLocked(_to, _reason) == 0, ALREADY_LOCKED); require(_amount != 0, AMOUNT_ZERO); + require(_to != address(0)); if (locked[_to][_reason].amount == 0) lockReason[_to].push(_reason); diff --git a/test/07_Governance.js b/test/07_Governance.js index ef4dcd9..87ec93c 100644 --- a/test/07_Governance.js +++ b/test/07_Governance.js @@ -6,6 +6,7 @@ const Pool = artifacts.require('Pool'); const SimpleVoting = artifacts.require('SimpleVoting'); const Master = artifacts.require('Master'); const GBTStandardToken = artifacts.require('GBTStandardToken'); +const ProposalCategory = artifacts.require('ProposalCategory'); const MemberRoles = artifacts.require('MemberRoles'); const amount = 500000000000000; @@ -16,13 +17,15 @@ let gd; let gv; let ms; let mr; +let pc; +let propId; const BigNumber = web3.BigNumber; require('chai') .use(require('chai-bignumber')(BigNumber)) .should(); -contract('Governance', ([owner, notOwner]) => { +contract('Governance', ([owner, notOwner, noStake]) => { before(() => { Governance.deployed() .then(instance => { @@ -51,6 +54,10 @@ contract('Governance', ([owner, notOwner]) => { }) .then(instance => { mr = instance; + return ProposalCategory.deployed(); + }) + .then(instance => { + pc = instance; }); }); @@ -159,6 +166,7 @@ contract('Governance', ([owner, notOwner]) => { 0, 9 ); + propId = (await gd.getProposalLength()).toNumber() - 1; await gd.setDAppTokenSupportsLocking(true); await gv.createProposal( 'Add new member', @@ -190,6 +198,50 @@ contract('Governance', ([owner, notOwner]) => { ); }); + it('Should not allow unauthorized people to submit solutions', async () => { + const initSol = await gd.getTotalSolutions(propId); + await catchRevert( + sv.addSolution(propId, noStake, '0x0', '0x0', { from: noStake }) + ); + await catchRevert( + sv.addSolution(propId, noStake, '0x0', '0x0', { from: notOwner }) + ); + const finalSol = await gd.getTotalSolutions(propId); + assert.equal(initSol.toNumber(), finalSol.toNumber()); + }); + + it('Should allow authorized people to submit solution', async () => { + const initSol = await gd.getTotalSolutions(propId); + await sv.addSolution(propId, owner, '0x0', '0x0'); + const finalSol = await gd.getTotalSolutions(propId); + assert.equal(finalSol.toNumber(), initSol.toNumber() + 1); + }); + + it('Should not allow voting before proposal is open for voting', async () => { + await catchRevert(sv.proposalVoting(propId, [1])); + }); + + it('Should open proposal for voting', async () => { + await gv.openProposalForVoting(propId); + const pStatus = await gd.getProposalStatus(propId); + assert.equal(pStatus.toNumber(), 2); + }); + + it('Should not allow unauthorized people to vote', async () => { + await catchRevert(sv.proposalVoting(propId, [1], { from: noStake })); + await mr.updateMemberRole(noStake, 1, true, 356800000054); + await catchRevert(sv.proposalVoting(propId, [1], { from: noStake })); + await mr.updateMemberRole(noStake, 1, false, 356800000054); + }); + + it('Should not allow voting for non existent solution', async () => { + await catchRevert(sv.proposalVoting(propId, [5])); + }); + + it('Should allow voting', async () => { + await sv.proposalVoting(propId, [1]); + }); + it('Should not allow unauthorized people to create proposals', async () => { await catchRevert( gv.createProposal( @@ -236,10 +288,10 @@ contract('Governance', ([owner, notOwner]) => { const g1 = await gv.getMemberDetails(owner); let pr = await pl.getPendingReward(owner); assert.equal(pr[0].toNumber(), 0); - assert.isAtLeast(pr[1].toNumber(), 100000); + assert.equal(pr[1].toNumber(), 100000); pr = await pl.getPendingReward(notOwner); assert.equal(pr[0].toNumber(), 0); - assert.isAtLeast(pr[1].toNumber(), 0); + assert.equal(pr[1].toNumber(), 0); await pl.claimReward(owner); await pl.claimReward(notOwner); const b2 = await gbt.balanceOf(owner); @@ -250,4 +302,20 @@ contract('Governance', ([owner, notOwner]) => { pr2[0].should.be.bignumber.eq(0); pr2[1].should.be.bignumber.eq(0); }); + + it('Should close proposal', async () => { + await mr.updateMemberRole(notOwner, 1, false, 356800000054); + await sv.closeProposalVote(propId); + await catchRevert(sv.closeProposalVote(propId)); + }); + + it('Should allow claiming reward for preious proposals', async () => { + const b1 = await gbt.balanceOf(owner); + const pr = await pl.getPendingReward(owner); + assert.equal(pr[0].toNumber(), 0); + assert.equal(pr[1].toNumber(), 100000); + await pl.claimReward(owner); + const b2 = await gbt.balanceOf(owner); + b2.should.be.bignumber.above(b1); + }); }); diff --git a/test/10_SimpleVoting.js b/test/10_SimpleVoting.js index f3ba362..df853d7 100644 --- a/test/10_SimpleVoting.js +++ b/test/10_SimpleVoting.js @@ -17,6 +17,10 @@ contract('Simple Voting', function([owner]) { }); }); + it('Should be initialized', async function() { + await catchRevert(sv.simpleVotingInitiate()); + }); + it('Should check getters', async function() { this.timeout(100000); let g1 = await sv.votingTypeName(); @@ -31,6 +35,7 @@ contract('Simple Voting', function([owner]) { let g10 = await sv.allVotesTotal(); let g11 = await sv.getSolutionByVoteIdAndIndex(0, 0); let g12 = await sv.getVoteDetailById(0); + await catchRevert(sv.getSolutionByVoteIdAndIndex(0, 1)); assert.equal(g2, true, 'Not initialized'); // TODO verify the data returned });