Skip to content

Commit

Permalink
added all tests for daico
Browse files Browse the repository at this point in the history
  • Loading branch information
ryzhak committed Dec 11, 2018
1 parent 66d0161 commit 2227dd6
Show file tree
Hide file tree
Showing 4 changed files with 389 additions and 33 deletions.
2 changes: 1 addition & 1 deletion contracts/Daico/Daico.sol
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ contract Daico is Ownable {
function withdrawTapPayment(uint _tapIndex) external validTapIndex(_tapIndex) {
// validation
require(msg.sender == projectOwner);
require(!tapPayments[_tapIndex].isWithdrawn);
require(isTapWithdrawAcceptedByInvestors(_tapIndex));
require(!tapPayments[_tapIndex].isWithdrawn);
// create tap payment
TapPayment memory tapPayment;
tapPayment.amount = tapAmounts[_tapIndex];
Expand Down
40 changes: 36 additions & 4 deletions contracts/Daico/IDaico.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import "zeppelin-solidity/contracts/token/ERC20/ERC20.sol";
* 2. Contract creates initial votings of type ReleaseTap for each tap.
* 3. Evercity member transfers DAI tokens to DAICO contract address.
*
* Scenarios:
* ==================
* Common scenarios:
* ==================
* # Successful voting for tap release
* 1. Token holders votes via 'vote()'.
* 2. Quorum reached with positive decision.
Expand All @@ -36,6 +38,27 @@ import "zeppelin-solidity/contracts/token/ERC20/ERC20.sol";
* 3. One of the investors creates a new voting of type 'TerminateProject' via 'createVotingByInvestor()'.
* 4. Quorum reached with positive decision.
* 5. Evercity member withdraws left DAI tokens via 'withdrawFunding()'.
*
* ===================
* All scenario steps:
* ===================
* # ReleaseTap/ReleaseTapDecreasedQuorum
* - voting of type ReleaseTap or ReleaseTapDecreasedQuorum finishes with Accept result => project owner withdraws DAI tokens via 'withdrawTapPayment()'
* - voting of type ReleaseTap or ReleaseTapDecreasedQuorum finishes with Decline result => one of the investors creates a voting of type TerminateProject via 'createVotingByInvestor()'
* - voting of type ReleaseTap or ReleaseTapDecreasedQuorum finishes with QuorumNotReached result => evercity member creates a voting of type ReleaseTapDecreasedQuorum via 'createVotingByOwner()'
* - voting of type ReleaseTap or ReleaseTapDecreasedQuorum finishes with NoDecision result => one of the investors creates a voting of type ChangeRoadmap via 'createVotingByInvestor()'
*
* # ChangeRoadmap/ChangeRoadmapDecreasedQuorum
* - voting of type ChangeRoadmap or ChangeRoadmapDecreasedQuorum finishes with Accept result => project owner withdraws DAI tokens via 'withdrawTapPayment()'
* - voting of type ChangeRoadmap or ChangeRoadmapDecreasedQuorum finishes with Decline result => one of the investors creates a voting of type TerminateProject via 'createVotingByInvestor()'
* - voting of type ChangeRoadmap or ChangeRoadmapDecreasedQuorum finishes with QuorumNotReached result => one of the investors creates a voting of type ChangeRoadmapDecreasedQuorum via 'createVotingByInvestor()'
* - voting of type ChangeRoadmap or ChangeRoadmapDecreasedQuorum finishes with NoDecision result => one of the investors creates a voting of type ChangeRoadmapDecreasedQuorum via 'createVotingByInvestor()'
*
* # TerminateProject/TerminateProjectDecreasedQuorum
* - voting of type TerminateProject or TerminateProjectDecreasedQuorum finishes with Accept result => evervity member withdraws DAI tokens via 'withdrawFunding()'
* - voting of type TerminateProject or TerminateProjectDecreasedQuorum finishes with Decline result => one of the investors creates a voting of type ChangeRoadmap via 'createVotingByInvestor()'
* - voting of type TerminateProject or TerminateProjectDecreasedQuorum finishes with QuorumNotReached result => one of the investors creates a voting of type TerminateProjectDecreasedQuorum via 'createVotingByInvestor()'
* - voting of type TerminateProject or TerminateProjectDecreasedQuorum finishes with NoDecision result => one of the investors creates a voting of type TerminateProjectDecreasedQuorum via 'createVotingByInvestor()'
*/
contract IDaico is Ownable {

Expand Down Expand Up @@ -120,9 +143,17 @@ contract IDaico is Ownable {
*/
function getVotingResult(uint _votingIndex) public view returns(VotingResult);

/**
* @dev Checks whether investor already voted in particular voting
* @param _votingIndex voting index
* @param _investorAddress investor address
* @return whether investor has already voted in particular voting
*/
function isInvestorVoted(uint _votingIndex, address _investorAddress) external view returns(bool);

/**
* @dev Checks whether project is terminated.
* Project is terminated when the last voting is of type TerminateProject with Accept result.
* Project is terminated when the last voting is of type TerminateProject/TerminateProjectDecreasedQuorum with Accept result.
* When project is terminated contract owner(evercity member) can withdraw DAI tokens via 'withdrawFunding()'.
* @return is project terminated
*/
Expand All @@ -140,7 +171,7 @@ contract IDaico is Ownable {
*/

/**
* @dev Creates a new voting by investor. Investor can create 2 types of votings: change roadmap and terminate project
* @dev Creates a new voting by investor. Investors can create votings of 4 types: ChangeRoadmap, ChangeRoadmapDecreasedQuorum, TerminateProject, TerminateProjectDecreasedQuorum.
* @param _tapIndex tap index
* @param _votingType voting type
*/
Expand All @@ -153,6 +184,7 @@ contract IDaico is Ownable {
* - Valid voting index
* - Is valid voting period
* - Investor hasn't voted earlier for this proposal
* - Project is not terminated
* @param _votingIndex voting index
* @param _isYes decision, yes or no
*/
Expand All @@ -163,7 +195,7 @@ contract IDaico is Ownable {
*/

/**
* @dev Creates a new voting by owner. Owner can create 1 type of votings: tap release with decreased quorum rate
* @dev Creates a new voting by owner. Owner can create votings only of type ReleaseTapDecreasedQuorum
* @param _tapIndex tap index
* @param _votingType voting type
*/
Expand Down
63 changes: 63 additions & 0 deletions test/Daico.functional.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const moment = require("moment");

const Daico = artifacts.require("DaicoTestable");
const MintableToken = artifacts.require("MintableToken");

contract("Daico", (accounts) => {

const evercityMemberAddress = accounts[0];
const projectOwnerAddress = accounts[1];
const inverstorAddress = accounts[2];
const otherAddress = accounts[3];

const minQuorumRate = 70;
const minVoteRate = 70;
const tokenHoldersCount = 5;

let daico;
let daiToken;
let projectToken;

beforeEach(async() => {
daiToken = await MintableToken.new();
projectToken = await MintableToken.new();
await projectToken.mint(inverstorAddress, 1);

timestampsFinishAt = [
moment.unix(web3.eth.getBlock("latest").timestamp).add(1, 'week').unix(),
moment.unix(web3.eth.getBlock("latest").timestamp).add(5, 'weeks').unix()
];
daico = await Daico.new(daiToken.address, projectToken.address, projectOwnerAddress, 2, [1, 2], timestampsFinishAt, minVoteRate, minQuorumRate, tokenHoldersCount);
});

describe("onlyInvestor()", () => {
it("should revert if method is called not by investor", async() => {
await daico.vote(0, true, {from: otherAddress}).should.be.rejectedWith("revert");
});

it("should call method that can be executed only by investor", async() => {
await daico.vote(0, true, {from: inverstorAddress}).should.be.fulfilled;
});
});

describe("validTapIndex()", () => {
it("should revert if tap index does not exist", async() => {
await daico.isTapWithdrawAcceptedByInvestors(2).should.be.rejectedWith("revert");
});

it("should call method with valid tap index", async() => {
await daico.isTapWithdrawAcceptedByInvestors(1).should.be.fulfilled;
});
});

describe("validVotingIndex()", () => {
it("should revert if voting index does not exist", async() => {
await daico.vote(2, true, {from: inverstorAddress}).should.be.rejectedWith("revert");
});

it("should call method with valid tap index", async() => {
await daico.vote(0, true, {from: inverstorAddress}).should.be.fulfilled;
});
});

});
Loading

0 comments on commit 2227dd6

Please sign in to comment.