From 7aed03381c192e5d66a4619e8415815521121eee Mon Sep 17 00:00:00 2001 From: KIrill Guzenko Date: Tue, 24 Jul 2018 12:12:48 +0300 Subject: [PATCH 1/4] #183: moneyflowTable fixes + code coverage improved --- contracts/moneyflow/MoneflowTable.sol | 9 +- test/moneyflow/moneyflow_table.tests.js | 142 ++++++++++++++++++++++-- 2 files changed, 138 insertions(+), 13 deletions(-) diff --git a/contracts/moneyflow/MoneflowTable.sol b/contracts/moneyflow/MoneflowTable.sol index e665c34..28b94a3 100644 --- a/contracts/moneyflow/MoneflowTable.sol +++ b/contracts/moneyflow/MoneflowTable.sol @@ -86,10 +86,9 @@ contract MoneyflowTable is Ownable{//is IWeiReceiver, function _processFunds(uint _eId, uint _currentFlow, uint _amount) internal { if(Splitters[_eId].isOpen){ return _processFundsSplitter(_eId, _currentFlow, _amount); - }else if(Expenses[_eId].isOpen){ + }else if(Expenses[_eId].isOpen&&_isNeedsMoney(_eId)){ return _processFundsExpense(_eId, _currentFlow, _amount); }else { - revert(); } } @@ -115,6 +114,7 @@ contract MoneyflowTable is Ownable{//is IWeiReceiver, require(_amount==_getTotalWeiNeeded(_eId, _currentFlow)); Expenses[_eId].momentReceived = uint(now); Expenses[_eId].balance += _amount; + Expenses[_eId].isMoneyReceived = true; } function getMinWeiNeededForElement(uint _eId)external view returns(uint) { @@ -128,7 +128,7 @@ contract MoneyflowTable is Ownable{//is IWeiReceiver, }else if((Splitters[_eId].isOpen)&&(ElementTypes.UnsortedSplitter==elementsType[_eId])){ return _getMinWeiNeededUnsortedSplitter(_eId); - }else if(Expenses[_eId].isOpen){ + }else if(Expenses[_eId].isOpen && _isNeedsMoney(_eId)){ return _getMinWeiNeededExpense(_eId); }else { @@ -239,6 +239,7 @@ contract MoneyflowTable is Ownable{//is IWeiReceiver, function processFunds(uint _currentFlow) external payable { require(_currentFlow>=_getMinWeiNeeded(0)); require(msg.value>=_getMinWeiNeeded(0)); + return _processFunds(0, _currentFlow, msg.value); } @@ -365,7 +366,7 @@ contract MoneyflowTable is Ownable{//is IWeiReceiver, } function withdrawFundsFromElement(uint _eId)external onlyOwner{ - require(_isExpense(_eId)); + // require(_isExpense(_eId)); Expenses[_eId].output.processFunds.value(Expenses[_eId].balance)(Expenses[_eId].balance); Expenses[_eId].balance = 0; } diff --git a/test/moneyflow/moneyflow_table.tests.js b/test/moneyflow/moneyflow_table.tests.js index 3291cde..ea1d017 100644 --- a/test/moneyflow/moneyflow_table.tests.js +++ b/test/moneyflow/moneyflow_table.tests.js @@ -261,17 +261,28 @@ contract('MoneyflowTable tests', (accounts) => { // 0->•abs it('should process money with WeiTopDownSplitter + 3 WeiAbsoluteExpense',async() => { let moneyflowTable = await MoneyflowTable.new(); - + var output1 = await WeiAbsoluteExpense.new(neededAmount); + var output2 = await WeiAbsoluteExpense.new(2*neededAmount); + var output3 = await WeiAbsoluteExpense.new(3*neededAmount); let topDownSplitterId = getEId(await moneyflowTable.addTopdownSplitter()); - let AbsoluteExpense1Id = getEId(await moneyflowTable.addAbsoluteExpense(neededAmount, isPeriodic, isAccumulateDebt, periodHours, output)); - let AbsoluteExpense2Id = getEId(await moneyflowTable.addAbsoluteExpense(2*neededAmount, isPeriodic, isAccumulateDebt, periodHours, output)); - let AbsoluteExpense3Id = getEId(await moneyflowTable.addAbsoluteExpense(3*neededAmount, isPeriodic, isAccumulateDebt, periodHours, output)); + let AbsoluteExpense1Id = getEId(await moneyflowTable.addAbsoluteExpense(neededAmount, isPeriodic, isAccumulateDebt, periodHours, output1.address)); + let AbsoluteExpense2Id = getEId(await moneyflowTable.addAbsoluteExpense(2*neededAmount, isPeriodic, isAccumulateDebt, periodHours, output2.address)); + let AbsoluteExpense3Id = getEId(await moneyflowTable.addAbsoluteExpense(3*neededAmount, isPeriodic, isAccumulateDebt, periodHours, output3.address)); // add 3 WeiAbsoluteExpense outputs to the splitter await moneyflowTable.addChild(topDownSplitterId, AbsoluteExpense1Id); await moneyflowTable.addChild(topDownSplitterId, AbsoluteExpense2Id); await moneyflowTable.addChild(topDownSplitterId, AbsoluteExpense3Id); + + var id1 = await moneyflowTable.getChildId(topDownSplitterId, 0); + var id2 = await moneyflowTable.getChildId(topDownSplitterId, 1); + var id3 = await moneyflowTable.getChildId(topDownSplitterId, 2); + + assert.equal(id1, AbsoluteExpense1Id); + assert.equal(id2, AbsoluteExpense2Id); + assert.equal(id3, AbsoluteExpense3Id); + // add WeiTopDownSplitter to the moneyflow await moneyflowInstance.setRootWeiReceiver(moneyflowTable.address); @@ -279,15 +290,14 @@ contract('MoneyflowTable tests', (accounts) => { assert.equal(revenueEndpointAddress, moneyflowTable.address, 'weiTopDownSplitter.address saved in moneyflowInstance as revenueEndpointAddress'); - let totalNeed = await moneyflowTable.getTotalWeiNeeded(6*neededAmount); + var totalNeed = await moneyflowTable.getTotalWeiNeeded(6*neededAmount); assert.equal(totalNeed, 6*neededAmount); - let minNeed = await moneyflowTable.getMinWeiNeeded(); - // console.log('minNeed:', minNeed) + var minNeed = await moneyflowTable.getMinWeiNeeded(); assert.equal(minNeed, 6*neededAmount); - + var need1 = await moneyflowTable.isNeedsMoney(); // now send some money to the revenue endpoint await moneyflowTable.processFunds(6*neededAmount, {value:6*neededAmount, from:creator}); - + assert.equal(need1, true); // money should end up in the outputs var absoluteExpense1Balance = await moneyflowTable.getElementBalance(AbsoluteExpense1Id); assert.equal(absoluteExpense1Balance.toNumber(),1*neededAmount, 'resource point received money from splitter'); @@ -297,6 +307,40 @@ contract('MoneyflowTable tests', (accounts) => { var absoluteExpense3Balance = await moneyflowTable.getElementBalance(AbsoluteExpense3Id); assert.equal(absoluteExpense3Balance.toNumber(),3*neededAmount, 'resource point received money from splitter'); + + var totalNeed = await moneyflowTable.getTotalWeiNeeded(6*neededAmount); + assert.equal(totalNeed.toNumber(), 0*neededAmount); + var minNeed = await moneyflowTable.getMinWeiNeeded(); + assert.equal(minNeed.toNumber(), 0*neededAmount); + + var need2 = await moneyflowTable.isNeedsMoney(); + assert.equal(need2, false); + + var b1 = await web3.eth.getBalance(output1.address); + await moneyflowTable.withdrawFundsFromElement(AbsoluteExpense1Id,{gasPrice:0}); + var b2 = await web3.eth.getBalance(output1.address); + assert.equal(b2.toNumber()-b1.toNumber(), 1*neededAmount); + + var b1 = await web3.eth.getBalance(output2.address); + await moneyflowTable.withdrawFundsFromElement(AbsoluteExpense2Id,{gasPrice:0}); + var b2 = await web3.eth.getBalance(output2.address); + assert.equal(b2.toNumber()-b1.toNumber(), 2*neededAmount); + + var b1 = await web3.eth.getBalance(output3.address); + await moneyflowTable.withdrawFundsFromElement(AbsoluteExpense3Id,{gasPrice:0}); + var b2 = await web3.eth.getBalance(output3.address); + assert.equal(b2.toNumber()-b1.toNumber(), 3*neededAmount); + + var absoluteExpense1Balance = await moneyflowTable.getElementBalance(AbsoluteExpense1Id); + assert.equal(absoluteExpense1Balance.toNumber(),0*neededAmount, 'resource point received money from splitter'); + + var absoluteExpense2Balance = await moneyflowTable.getElementBalance(AbsoluteExpense2Id); + assert.equal(absoluteExpense2Balance.toNumber(),0*neededAmount, 'resource point received money from splitter'); + + var absoluteExpense3Balance = await moneyflowTable.getElementBalance(AbsoluteExpense3Id); + assert.equal(absoluteExpense3Balance.toNumber(),0*neededAmount, 'resource point received money from splitter'); + var need2 = await moneyflowTable.isNeedsMoney(); + }); it('should process money with WeiUnsortedSplitter + 3 WeiAbsoluteExpense',async() => { @@ -353,6 +397,10 @@ contract('MoneyflowTable tests', (accounts) => { // add WeiTopDownSplitter to the moneyflow await moneyflowInstance.setRootWeiReceiver(moneyflowTable.address); + var id1 = await moneyflowTable.getChildId(topDownSplitterId, 0); + var id2 = await moneyflowTable.getChildId(topDownSplitterId, 1); + var id3 = await moneyflowTable.getChildId(topDownSplitterId, 2); + var revenueEndpointAddress = await moneyflowInstance.getRevenueEndpoint(); assert.equal(revenueEndpointAddress, moneyflowTable.address, 'weiTopDownSplitter.address saved in moneyflowInstance as revenueEndpointAddress'); @@ -580,4 +628,80 @@ contract('MoneyflowTable tests', (accounts) => { await struct.moneyflowTable.processFunds(CURRENT_INPUT*money, {value:CURRENT_INPUT*money/100, gasPrice:0}).should.be.rejectedWith('revert'); await struct.moneyflowTable.processFunds(CURRENT_INPUT*money/100, {value:CURRENT_INPUT*money, gasPrice:0}).should.be.rejectedWith('revert'); }); + + it('should process money when opened and not process when closed with WeiTopDownSplitter + 3 WeiAbsoluteExpense',async() => { + let moneyflowTable = await MoneyflowTable.new(); + + let topDownSplitterId = getEId(await moneyflowTable.addTopdownSplitter()); + let AbsoluteExpense1Id = getEId(await moneyflowTable.addAbsoluteExpense(neededAmount, isPeriodic, isAccumulateDebt, periodHours, output)); + let AbsoluteExpense2Id = getEId(await moneyflowTable.addAbsoluteExpense(2*neededAmount, isPeriodic, isAccumulateDebt, periodHours, output)); + let AbsoluteExpense3Id = getEId(await moneyflowTable.addAbsoluteExpense(3*neededAmount, isPeriodic, isAccumulateDebt, periodHours, output)); + + // add 3 WeiAbsoluteExpense outputs to the splitter + await moneyflowTable.addChild(topDownSplitterId, AbsoluteExpense1Id); + await moneyflowTable.addChild(topDownSplitterId, AbsoluteExpense2Id); + await moneyflowTable.addChild(topDownSplitterId, AbsoluteExpense3Id); + + // add WeiTopDownSplitter to the moneyflow + await moneyflowInstance.setRootWeiReceiver(moneyflowTable.address); + + var revenueEndpointAddress = await moneyflowInstance.getRevenueEndpoint(); + + assert.equal(revenueEndpointAddress, moneyflowTable.address, 'weiTopDownSplitter.address saved in moneyflowInstance as revenueEndpointAddress'); + + var totalNeed = await moneyflowTable.getTotalWeiNeeded(6*neededAmount); + assert.equal(totalNeed, 6*neededAmount); + var minNeed = await moneyflowTable.getMinWeiNeeded(); + // console.log('minNeed:', minNeed) + assert.equal(minNeed, 6*neededAmount); + + var isOpen1 = await moneyflowTable.isOpen(AbsoluteExpense1Id); + var isOpen2 = await moneyflowTable.isOpen(AbsoluteExpense2Id); + var isOpen3 = await moneyflowTable.isOpen(AbsoluteExpense3Id); + assert.equal(isOpen1, true); + assert.equal(isOpen2, true); + assert.equal(isOpen3, true); + + await moneyflowTable.closeElement(AbsoluteExpense3Id); + + var totalNeed = await moneyflowTable.getTotalWeiNeeded(6*neededAmount); + assert.equal(totalNeed, 3*neededAmount); + var minNeed = await moneyflowTable.getMinWeiNeeded(); + assert.equal(minNeed, 3*neededAmount); + + await moneyflowTable.closeElement(AbsoluteExpense1Id); + + var totalNeed = await moneyflowTable.getTotalWeiNeeded(6*neededAmount); + assert.equal(totalNeed, 2*neededAmount); + var minNeed = await moneyflowTable.getMinWeiNeeded(); + assert.equal(minNeed, 2*neededAmount); + + var isOpen1 = await moneyflowTable.isOpen(AbsoluteExpense1Id); + var isOpen2 = await moneyflowTable.isOpen(AbsoluteExpense2Id); + var isOpen3 = await moneyflowTable.isOpen(AbsoluteExpense3Id); + assert.equal(isOpen1, false); + assert.equal(isOpen2, true); + assert.equal(isOpen3, false); + + await moneyflowTable.openElement(AbsoluteExpense3Id); + var isOpen1 = await moneyflowTable.isOpen(AbsoluteExpense1Id); + var isOpen2 = await moneyflowTable.isOpen(AbsoluteExpense2Id); + var isOpen3 = await moneyflowTable.isOpen(AbsoluteExpense3Id); + assert.equal(isOpen1, false); + assert.equal(isOpen2, true); + assert.equal(isOpen3, true); + + // now send some money to the revenue endpoint + await moneyflowTable.processFunds(5*neededAmount, {value:5*neededAmount, from:creator}); + + // money should end up in the outputs + var absoluteExpense1Balance = await moneyflowTable.getElementBalance(AbsoluteExpense1Id); + assert.equal(absoluteExpense1Balance.toNumber(),0*neededAmount, 'resource point received money from splitter'); + + var absoluteExpense2Balance = await moneyflowTable.getElementBalance(AbsoluteExpense2Id); + assert.equal(absoluteExpense2Balance.toNumber(),2*neededAmount, 'resource point received money from splitter'); + + var absoluteExpense3Balance = await moneyflowTable.getElementBalance(AbsoluteExpense3Id); + assert.equal(absoluteExpense3Balance.toNumber(),3*neededAmount, 'resource point received money from splitter'); + }); }); From 4e8761738ddaa6c56f21b5aac03d8b3ddeec6294 Mon Sep 17 00:00:00 2001 From: KIrill Guzenko Date: Wed, 25 Jul 2018 11:05:17 +0300 Subject: [PATCH 2/4] genericCaller link removed --- contracts/governance/Voting.sol | 42 ++++----- contracts/utils/GenericCaller.sol | 13 +-- contracts/utils/Manageable.sol | 146 ------------------------------ contracts/utils/Pausable.sol | 54 ----------- 4 files changed, 23 insertions(+), 232 deletions(-) delete mode 100644 contracts/utils/Manageable.sol delete mode 100644 contracts/utils/Pausable.sol diff --git a/contracts/governance/Voting.sol b/contracts/governance/Voting.sol index c004dcf..5e70b36 100644 --- a/contracts/governance/Voting.sol +++ b/contracts/governance/Voting.sol @@ -19,6 +19,14 @@ contract Voting is IVoting, Ownable { event DelegatedTo(address _sender, uint _tokensAmount); event DelegationRemoved(address _from, address _to); + enum VotingType{ + NoVoting, + Voting1p1v, + VotingSimpleToken, + VotingQuadratic, + VotingLiquid + } + /* * @param _dao – DAO where proposal was created. * @param _proposal – proposal, which create vote. @@ -31,7 +39,7 @@ contract Voting is IVoting, Ownable { * @param _tokenAddress – for votings that uses token amount of voter */ constructor(IDaoBase _dao, IProposal _proposal, - address _origin, VotingLib.VotingType _votingType, + address _origin, VotingType _votingType, uint _minutesToVote, string _groupName, uint _quorumPercent, uint _consensusPercent, address _tokenAddress) public @@ -107,14 +115,6 @@ library VotingLib { event DelegatedTo(address _sender, uint _tokensAmount); event DelegationRemoved(address _from, address _to); - enum VotingType{ - NoVoting, - Voting1p1v, - VotingSimpleToken, - VotingQuadratic, - VotingLiquid - } - struct Delegation { address _address; uint amount; @@ -144,11 +144,11 @@ library VotingLib { mapping(address=>Delegation[]) delegations; uint votesCount; - VotingType votingType; + Voting.VotingType votingType; } function generalConstructor(VotingStorage storage store, IDaoBase _dao, IProposal _proposal, - address _origin, VotingType _votingType, + address _origin, Voting.VotingType _votingType, uint _minutesToVote, string _groupName, uint _quorumPercent, uint _consensusPercent, address _tokenAddress) public @@ -165,7 +165,7 @@ library VotingLib { store.votingType = _votingType; store.genesis = now; - if(VotingType.Voting1p1v!=store.votingType){ + if(Voting.VotingType.Voting1p1v!=store.votingType){ store.tokenAddress = _tokenAddress; store.votingID = StdDaoToken(_tokenAddress).startNewVoting(); } @@ -177,13 +177,13 @@ library VotingLib { } function getVotersTotal(VotingStorage storage store)public view returns(uint){ - if(VotingType.Voting1p1v==store.votingType){ + if(Voting.VotingType.Voting1p1v==store.votingType){ return store.dao.getMembersCount(store.groupName); - }else if(VotingType.VotingSimpleToken==store.votingType){ + }else if(Voting.VotingType.VotingSimpleToken==store.votingType){ return StdDaoToken(store.tokenAddress).totalSupply(); - }else if(VotingType.VotingQuadratic==store.votingType){ + }else if(Voting.VotingType.VotingQuadratic==store.votingType){ return StdDaoToken(store.tokenAddress).getVotingTotalForQuadraticVoting(); - }else if(VotingType.VotingLiquid==store.votingType){ + }else if(Voting.VotingType.VotingLiquid==store.votingType){ return StdDaoToken(store.tokenAddress).totalSupply(); }else{ revert(); @@ -191,17 +191,17 @@ library VotingLib { } function getPowerOf(VotingStorage storage store, address _voter)public view returns(uint){ - if(VotingType.Voting1p1v==store.votingType){ + if(Voting.VotingType.Voting1p1v==store.votingType){ if(store.dao.isGroupMember(store.groupName, _voter)){ return 1; }else{ return 0; } - }else if(VotingType.VotingSimpleToken==store.votingType){ + }else if(Voting.VotingType.VotingSimpleToken==store.votingType){ return StdDaoToken(store.tokenAddress).getBalanceAtVoting(store.votingID, _voter); - }else if(VotingType.VotingQuadratic==store.votingType){ + }else if(Voting.VotingType.VotingQuadratic==store.votingType){ return sqrt(StdDaoToken(store.tokenAddress).getBalanceAtVoting(store.votingID, _voter)); - }else if(VotingType.VotingLiquid==store.votingType){ + }else if(Voting.VotingType.VotingLiquid==store.votingType){ uint res = StdDaoToken(store.tokenAddress).getBalanceAtVoting(store.votingID, _voter); for(uint i = 0; i < store.delegations[_voter].length; i++){ if(!store.delegations[_voter][i].isDelegator){ @@ -229,7 +229,7 @@ library VotingLib { require(!isFinished(store)); require(!store.voted[msg.sender]); - if(VotingType.Voting1p1v==store.votingType){ + if(Voting.VotingType.Voting1p1v==store.votingType){ require(store.dao.isGroupMember(store.groupName, _voter)); } diff --git a/contracts/utils/GenericCaller.sol b/contracts/utils/GenericCaller.sol index 690e622..e86bbb1 100644 --- a/contracts/utils/GenericCaller.sol +++ b/contracts/utils/GenericCaller.sol @@ -14,21 +14,12 @@ import "zeppelin-solidity/contracts/ownership/Ownable.sol"; * WARNING: should be permitted to add new proposal by the current DaoBase!!! */ contract GenericCaller is DaoClient, Ownable { - using VotingLib for VotingLib.VotingType; - // enum VotingType { - // NoVoting, - // Voting1p1v, - // VotingSimpleToken, - // VotingQuadratic, - // VotingLiquid - // } - event consoleAddr(string comment, address a); event consoleB32(string comment, bytes32 a); event consoleUint(string comment, uint a); event consoleStr(string comment, string a); struct VotingParams { - VotingLib.VotingType votingType; + Voting.VotingType votingType; bytes32 param1; bytes32 param2; bytes32 param3; @@ -102,7 +93,7 @@ contract GenericCaller is DaoClient, Ownable { bytes32 _param1, bytes32 _param2, bytes32 _param3, bytes32 _param4, bytes32 _param5) public onlyOwner { VotingParams memory params; - params.votingType = VotingLib.VotingType(_votingType); + params.votingType = Voting.VotingType(_votingType); params.param1 = _param1; params.param2 = _param2; params.param3 = _param3; diff --git a/contracts/utils/Manageable.sol b/contracts/utils/Manageable.sol deleted file mode 100644 index e7e2f1d..0000000 --- a/contracts/utils/Manageable.sol +++ /dev/null @@ -1,146 +0,0 @@ -pragma solidity ^0.4.22; - -import "zeppelin-solidity/contracts/ownership/Ownable.sol"; - -/** - * @title Manageable - * @author https://github.com/jibrelnetwork/jibrel-contracts - * @dev Contract that allows to grant permissions to any address - * @dev In real life we are not able to perform all actions with just one Ethereum address - * @dev because risks are too high. - * @dev Instead owner delegates rights to manage an contract to the different addresses and - * @dev stay able to revoke permissions at any time. - */ -contract Manageable is Ownable { -// Fields: - mapping (address => bool) managerEnabled; // hard switch for a manager - on/off - mapping (address => mapping (string => bool)) managerPermissions; // detailed info about manager`s permissions - -//Events: - event Manageable_ManagerEnabled(address indexed _manager); - event Manageable_ManagerDisabled(address indexed _manager); - event Manageable_ManagerPermissionGranted(address indexed _manager, string _permission); - event Manageable_ManagerPermissionRevoked(address indexed _manager, string _permission); - -// Modifiers: - modifier onlyValidAddress(address _manager) { - require(_manager != address(0x0)); - _; - } - - modifier onlyValidPermissionName(string _permissionName) { - require(bytes(_permissionName).length != 0); - _; - } - - modifier onlyAllowedManager(string _permissionName) { - require(isManagerAllowed(msg.sender, _permissionName) == true); - _; - } - -// Methods: - /** - * @dev Function to add new manager - * @param _manager address New manager - */ - function enableManager(address _manager) public onlyOwner onlyValidAddress(_manager) { - require(managerEnabled[_manager] == false); - - managerEnabled[_manager] = true; - emit Manageable_ManagerEnabled(_manager); - } - - /** - * @dev Function to remove existing manager - * @param _manager address Existing manager - */ - function disableManager(address _manager) public onlyOwner onlyValidAddress(_manager) { - require(managerEnabled[_manager] == true); - - managerEnabled[_manager] = false; - emit Manageable_ManagerDisabled(_manager); - } - - /** - * @dev Function to grant new permission to the manager - * @param _manager address Existing manager - * @param _permissionName string Granted permission name - */ - function grantManagerPermission( - address _manager, string _permissionName - ) - public - onlyOwner - onlyValidAddress(_manager) - onlyValidPermissionName(_permissionName) - { - require(managerPermissions[_manager][_permissionName] == false); - - managerPermissions[_manager][_permissionName] = true; - emit Manageable_ManagerPermissionGranted(_manager, _permissionName); - } - - /** - * @dev Function to revoke permission of the manager - * @param _manager address Existing manager - * @param _permissionName string Revoked permission name - */ - function revokeManagerPermission( - address _manager, string _permissionName - ) - public - onlyOwner - onlyValidAddress(_manager) - onlyValidPermissionName(_permissionName) - { - require(managerPermissions[_manager][_permissionName] == true); - - managerPermissions[_manager][_permissionName] = false; - emit Manageable_ManagerPermissionRevoked(_manager, _permissionName); - } - - /** - * @dev Function to check manager status - * @param _manager address Manager`s address - * @return True if manager is enabled - */ - function isManagerEnabled(address _manager) constant public onlyValidAddress(_manager) returns (bool) { - return managerEnabled[_manager]; - } - - /** - * @dev Function to check permissions of a manager - * @param _manager address Manager`s address - * @param _permissionName string Permission name - * @return True if manager has been granted needed permission - */ - function isPermissionGranted( - address _manager, string _permissionName - ) - constant - public - onlyValidAddress(_manager) - onlyValidPermissionName(_permissionName) - returns (bool) - { - return managerPermissions[_manager][_permissionName]; - } - - /** - * @dev Function to check if the manager can perform the action or not - * @param _manager address Manager`s address - * @param _permissionName string Permission name - * @return True if manager is enabled and has been granted needed permission - */ - function isManagerAllowed( - address _manager, string _permissionName - ) - constant - public - onlyValidAddress(_manager) - onlyValidPermissionName(_permissionName) - returns (bool) - { - return (managerEnabled[_manager] && managerPermissions[_manager][_permissionName]); - } -} diff --git a/contracts/utils/Pausable.sol b/contracts/utils/Pausable.sol deleted file mode 100644 index 4269a76..0000000 --- a/contracts/utils/Pausable.sol +++ /dev/null @@ -1,54 +0,0 @@ -pragma solidity ^0.4.22; - -import "./Manageable.sol"; - -/** - * @title Pausable - * @author https://github.com/jibrelnetwork/jibrel-contracts - * @dev Base contract which allows children to implement an emergency stop mechanism. - * @dev Based on zeppelin's Pausable, but integrated with Manageable - * @dev Contract is in paused state by default and should be explicitly unlocked - */ -contract Pausable is Manageable { -// Fields: - bool paused = true; - -// Events: - event Pausable_Pause(); - event Pausable_Unpause(); - -// Modifiers: - modifier whenContractNotPaused() { - require(paused == false); - _; - } - - modifier whenContractPaused { - require(paused == true); - _; - } - -// Methods: - /** - * @dev called by the manager to pause, triggers stopped state - */ - function pauseContract() public onlyAllowedManager('pause_contract') whenContractNotPaused { - paused = true; - emit Pausable_Pause(); - } - - /** - * @dev called by the manager to unpause, returns to normal state - */ - function unpauseContract() public onlyAllowedManager('unpause_contract') whenContractPaused { - paused = false; - emit Pausable_Unpause(); - } - - /** - * @dev The getter for "paused" contract variable - */ - function getPaused() constant public returns (bool) { - return paused; - } -} From ca741064052fa1002083d092d31f81585ce7f5e8 Mon Sep 17 00:00:00 2001 From: KIrill Guzenko Date: Wed, 25 Jul 2018 11:11:13 +0300 Subject: [PATCH 3/4] #220 --- migrations/2_deploy_contracts.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 5d24b74..912d31d 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -1,12 +1,8 @@ var Voting = artifacts.require("./Voting") ; var VotingLib = artifacts.require("./VotingLib") ; -var GenericCaller = artifacts.require("./GenericCaller") ; -var MoneyflowAuto = artifacts.require("./MoneyflowAuto") ; module.exports = function (deployer) { deployer.deploy(VotingLib).then(() => { deployer.link(VotingLib, Voting); - deployer.link(VotingLib, GenericCaller); - deployer.link(VotingLib, MoneyflowAuto); }); }; \ No newline at end of file From 21081ef77436cf49dd21dca6d914d51f2b810b64 Mon Sep 17 00:00:00 2001 From: KIrill Guzenko Date: Wed, 25 Jul 2018 11:45:47 +0300 Subject: [PATCH 4/4] #220 reverted --- contracts/governance/Voting.sol | 42 +++++++++++++++---------------- contracts/utils/GenericCaller.sol | 6 +++-- migrations/2_deploy_contracts.js | 4 +++ 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/contracts/governance/Voting.sol b/contracts/governance/Voting.sol index 5e70b36..c004dcf 100644 --- a/contracts/governance/Voting.sol +++ b/contracts/governance/Voting.sol @@ -19,14 +19,6 @@ contract Voting is IVoting, Ownable { event DelegatedTo(address _sender, uint _tokensAmount); event DelegationRemoved(address _from, address _to); - enum VotingType{ - NoVoting, - Voting1p1v, - VotingSimpleToken, - VotingQuadratic, - VotingLiquid - } - /* * @param _dao – DAO where proposal was created. * @param _proposal – proposal, which create vote. @@ -39,7 +31,7 @@ contract Voting is IVoting, Ownable { * @param _tokenAddress – for votings that uses token amount of voter */ constructor(IDaoBase _dao, IProposal _proposal, - address _origin, VotingType _votingType, + address _origin, VotingLib.VotingType _votingType, uint _minutesToVote, string _groupName, uint _quorumPercent, uint _consensusPercent, address _tokenAddress) public @@ -115,6 +107,14 @@ library VotingLib { event DelegatedTo(address _sender, uint _tokensAmount); event DelegationRemoved(address _from, address _to); + enum VotingType{ + NoVoting, + Voting1p1v, + VotingSimpleToken, + VotingQuadratic, + VotingLiquid + } + struct Delegation { address _address; uint amount; @@ -144,11 +144,11 @@ library VotingLib { mapping(address=>Delegation[]) delegations; uint votesCount; - Voting.VotingType votingType; + VotingType votingType; } function generalConstructor(VotingStorage storage store, IDaoBase _dao, IProposal _proposal, - address _origin, Voting.VotingType _votingType, + address _origin, VotingType _votingType, uint _minutesToVote, string _groupName, uint _quorumPercent, uint _consensusPercent, address _tokenAddress) public @@ -165,7 +165,7 @@ library VotingLib { store.votingType = _votingType; store.genesis = now; - if(Voting.VotingType.Voting1p1v!=store.votingType){ + if(VotingType.Voting1p1v!=store.votingType){ store.tokenAddress = _tokenAddress; store.votingID = StdDaoToken(_tokenAddress).startNewVoting(); } @@ -177,13 +177,13 @@ library VotingLib { } function getVotersTotal(VotingStorage storage store)public view returns(uint){ - if(Voting.VotingType.Voting1p1v==store.votingType){ + if(VotingType.Voting1p1v==store.votingType){ return store.dao.getMembersCount(store.groupName); - }else if(Voting.VotingType.VotingSimpleToken==store.votingType){ + }else if(VotingType.VotingSimpleToken==store.votingType){ return StdDaoToken(store.tokenAddress).totalSupply(); - }else if(Voting.VotingType.VotingQuadratic==store.votingType){ + }else if(VotingType.VotingQuadratic==store.votingType){ return StdDaoToken(store.tokenAddress).getVotingTotalForQuadraticVoting(); - }else if(Voting.VotingType.VotingLiquid==store.votingType){ + }else if(VotingType.VotingLiquid==store.votingType){ return StdDaoToken(store.tokenAddress).totalSupply(); }else{ revert(); @@ -191,17 +191,17 @@ library VotingLib { } function getPowerOf(VotingStorage storage store, address _voter)public view returns(uint){ - if(Voting.VotingType.Voting1p1v==store.votingType){ + if(VotingType.Voting1p1v==store.votingType){ if(store.dao.isGroupMember(store.groupName, _voter)){ return 1; }else{ return 0; } - }else if(Voting.VotingType.VotingSimpleToken==store.votingType){ + }else if(VotingType.VotingSimpleToken==store.votingType){ return StdDaoToken(store.tokenAddress).getBalanceAtVoting(store.votingID, _voter); - }else if(Voting.VotingType.VotingQuadratic==store.votingType){ + }else if(VotingType.VotingQuadratic==store.votingType){ return sqrt(StdDaoToken(store.tokenAddress).getBalanceAtVoting(store.votingID, _voter)); - }else if(Voting.VotingType.VotingLiquid==store.votingType){ + }else if(VotingType.VotingLiquid==store.votingType){ uint res = StdDaoToken(store.tokenAddress).getBalanceAtVoting(store.votingID, _voter); for(uint i = 0; i < store.delegations[_voter].length; i++){ if(!store.delegations[_voter][i].isDelegator){ @@ -229,7 +229,7 @@ library VotingLib { require(!isFinished(store)); require(!store.voted[msg.sender]); - if(Voting.VotingType.Voting1p1v==store.votingType){ + if(VotingType.Voting1p1v==store.votingType){ require(store.dao.isGroupMember(store.groupName, _voter)); } diff --git a/contracts/utils/GenericCaller.sol b/contracts/utils/GenericCaller.sol index e86bbb1..4b395b6 100644 --- a/contracts/utils/GenericCaller.sol +++ b/contracts/utils/GenericCaller.sol @@ -14,12 +14,14 @@ import "zeppelin-solidity/contracts/ownership/Ownable.sol"; * WARNING: should be permitted to add new proposal by the current DaoBase!!! */ contract GenericCaller is DaoClient, Ownable { + using VotingLib for VotingLib.VotingType; + event consoleAddr(string comment, address a); event consoleB32(string comment, bytes32 a); event consoleUint(string comment, uint a); event consoleStr(string comment, string a); struct VotingParams { - Voting.VotingType votingType; + VotingLib.VotingType votingType; bytes32 param1; bytes32 param2; bytes32 param3; @@ -93,7 +95,7 @@ contract GenericCaller is DaoClient, Ownable { bytes32 _param1, bytes32 _param2, bytes32 _param3, bytes32 _param4, bytes32 _param5) public onlyOwner { VotingParams memory params; - params.votingType = Voting.VotingType(_votingType); + params.votingType = VotingLib.VotingType(_votingType); params.param1 = _param1; params.param2 = _param2; params.param3 = _param3; diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 912d31d..5d24b74 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -1,8 +1,12 @@ var Voting = artifacts.require("./Voting") ; var VotingLib = artifacts.require("./VotingLib") ; +var GenericCaller = artifacts.require("./GenericCaller") ; +var MoneyflowAuto = artifacts.require("./MoneyflowAuto") ; module.exports = function (deployer) { deployer.deploy(VotingLib).then(() => { deployer.link(VotingLib, Voting); + deployer.link(VotingLib, GenericCaller); + deployer.link(VotingLib, MoneyflowAuto); }); }; \ No newline at end of file