Skip to content

Commit

Permalink
Merge pull request #218 from Thetta/dev
Browse files Browse the repository at this point in the history
dev -> master
  • Loading branch information
AnthonyAkentiev authored Jul 24, 2018
2 parents 8f1f965 + b10809f commit 79ea6b2
Show file tree
Hide file tree
Showing 50 changed files with 7,711 additions and 3,315 deletions.
85 changes: 36 additions & 49 deletions contracts/DaoBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import "zeppelin-solidity/contracts/ownership/Ownable.sol";
* It will transfer ownership only during upgrade
*
* 2. Currently DaoBase works only with StdDaoToken. It does not support working with
* plain ERC20 tokens because we need some extra features like mint(), burn() and transferOwnership()
* plain ERC20 tokens because we need some extra features like mintFor(), burnFor() and transferOwnership()
*/
contract DaoBase is IDaoBase, Ownable {
DaoStorage public store;
Expand All @@ -32,11 +32,11 @@ contract DaoBase is IDaoBase, Ownable {
event DaoBase_IssueTokens(address _tokenAddress, address _to, uint _amount);
event DaoBase_BurnTokens(address _tokenAddress, address _who, uint _amount);

bytes32 constant public ISSUE_TOKENS = keccak256("issueTokens");
bytes32 constant public MANAGE_GROUPS = keccak256("manageGroups");
bytes32 constant public ADD_NEW_PROPOSAL = keccak256("addNewProposal");
bytes32 constant public BURN_TOKENS = keccak256("burnTokens");
bytes32 constant public UPGRADE_DAO_CONTRACT = keccak256("upgradeDaoContract");
bytes32 public ISSUE_TOKENS = keccak256(abi.encodePacked("issueTokens"));
bytes32 public MANAGE_GROUPS = keccak256(abi.encodePacked("manageGroups"));
bytes32 public ADD_NEW_PROPOSAL = keccak256(abi.encodePacked("addNewProposal"));
bytes32 public BURN_TOKENS = keccak256(abi.encodePacked("burnTokens"));
bytes32 public UPGRADE_DAO_CONTRACT = keccak256(abi.encodePacked("upgradeDaoContract"));

constructor(DaoStorage _store) public {
store = _store;
Expand All @@ -55,20 +55,16 @@ contract DaoBase is IDaoBase, Ownable {
}

modifier isCanDo(bytes32 _what){
require(_isCanDoAction(msg.sender,_what));
require(isCanDoAction(msg.sender,_what));
_;
}

// IDaoBase:
function addObserver(IDaoObserver _observer) external {
function addObserver(IDaoObserver _observer) public {
store.addObserver(_observer);
}

function upgradeDaoContract(IDaoBase _new) external isCanDo(UPGRADE_DAO_CONTRACT) {
_upgradeDaoContract(_new);
}

function _upgradeDaoContract(IDaoBase _new) internal{
function upgradeDaoContract(IDaoBase _new) public isCanDo(UPGRADE_DAO_CONTRACT) {
emit DaoBase_UpgradeDaoContract(_new);
// call observers.onUpgrade() for all observers
for(uint i=0; i<store.getObserverCount(); ++i){
Expand All @@ -85,43 +81,43 @@ contract DaoBase is IDaoBase, Ownable {
}

// Groups:
function getMembersCount(string _groupName) external constant returns(uint){
return store.getMembersCount(keccak256(_groupName));
function getMembersCount(string _groupName) public constant returns(uint){
return store.getMembersCount(keccak256(abi.encodePacked(_groupName)));
}
function addGroupMember(string _groupName, address _a) external isCanDo(MANAGE_GROUPS) {
function addGroupMember(string _groupName, address _a) public isCanDo(MANAGE_GROUPS) {
emit DaoBase_AddGroupMember(_groupName, _a);
store.addGroupMember(keccak256(_groupName), _a);
store.addGroupMember(keccak256(abi.encodePacked(_groupName)), _a);
}
function getGroupMembers(string _groupName) external constant returns(address[]){
return store.getGroupMembers(keccak256(_groupName));
function getGroupMembers(string _groupName) public constant returns(address[]){
return store.getGroupMembers(keccak256(abi.encodePacked(_groupName)));
}
function removeGroupMember(string _groupName, address _a) external isCanDo(MANAGE_GROUPS){
function removeGroupMember(string _groupName, address _a) public isCanDo(MANAGE_GROUPS){
emit DaoBase_RemoveGroupMember(_a);
store.removeGroupMember(keccak256(_groupName), _a);
store.removeGroupMember(keccak256(abi.encodePacked(_groupName)), _a);
}
function isGroupMember(string _groupName,address _a)external constant returns(bool) {
return store.isGroupMember(keccak256(_groupName), _a);
function isGroupMember(string _groupName,address _a)public constant returns(bool) {
return store.isGroupMember(keccak256(abi.encodePacked(_groupName)), _a);
}
function getMemberByIndex(string _groupName, uint _index) external view returns (address) {
return store.getMemberByIndex(keccak256(_groupName), _index);
function getMemberByIndex(string _groupName, uint _index) public view returns (address) {
return store.getMemberByIndex(keccak256(abi.encodePacked(_groupName)), _index);
}

// Actions:
function allowActionByShareholder(bytes32 _what, address _tokenAddress) external isCanDo(MANAGE_GROUPS){
function allowActionByShareholder(bytes32 _what, address _tokenAddress) public isCanDo(MANAGE_GROUPS){
emit DaoBase_AllowActionByShareholder(_what, _tokenAddress);
store.allowActionByShareholder(_what, _tokenAddress);
}
function allowActionByVoting(bytes32 _what, address _tokenAddress) external isCanDo(MANAGE_GROUPS){
function allowActionByVoting(bytes32 _what, address _tokenAddress) public isCanDo(MANAGE_GROUPS){
emit DaoBase_AllowActionByVoting(_what, _tokenAddress);
store.allowActionByVoting(_what,_tokenAddress);
}
function allowActionByAddress(bytes32 _what, address _a) external isCanDo(MANAGE_GROUPS) {
function allowActionByAddress(bytes32 _what, address _a) public isCanDo(MANAGE_GROUPS) {
emit DaoBase_AllowActionByAddress(_what, _a);
store.allowActionByAddress(_what,_a);
}
function allowActionByAnyMemberOfGroup(bytes32 _what, string _groupName) external isCanDo(MANAGE_GROUPS){
function allowActionByAnyMemberOfGroup(bytes32 _what, string _groupName) public isCanDo(MANAGE_GROUPS){
emit DaoBase_AllowActionByAnyMemberOfGroup(_what, _groupName);
store.allowActionByAnyMemberOfGroup(_what, keccak256(_groupName));
store.allowActionByAnyMemberOfGroup(_what, keccak256(abi.encodePacked(_groupName)));
}

/**
Expand All @@ -135,12 +131,7 @@ contract DaoBase is IDaoBase, Ownable {
* b. caller is voting and it is succeeded -> allow
* 4. deny
*/

function isCanDoAction(address _a, bytes32 _permissionNameHash) external constant returns(bool){
return _isCanDoAction(_a, _permissionNameHash);
}

function _isCanDoAction(address _a, bytes32 _permissionNameHash) internal constant returns(bool){
function isCanDoAction(address _a, bytes32 _permissionNameHash) public constant returns(bool){
// 0 - is can do by address?
if(store.isCanDoByAddress(_permissionNameHash, _a)){
return true;
Expand Down Expand Up @@ -189,31 +180,27 @@ contract DaoBase is IDaoBase, Ownable {
}

// Proposals:
function addNewProposal(IProposal _proposal) external isCanDo(ADD_NEW_PROPOSAL) {
function addNewProposal(IProposal _proposal) public isCanDo(ADD_NEW_PROPOSAL) {
emit DaoBase_AddNewProposal(address(_proposal));
store.addNewProposal(_proposal);
}

function getProposalAtIndex(uint _i)external constant returns(IProposal){
function getProposalAtIndex(uint _i)public constant returns(IProposal){
return store.getProposalAtIndex(_i);
}

function getProposalsCount()external constant returns(uint){
function getProposalsCount()public constant returns(uint){
return store.getProposalsCount();
}

// Tokens:
function issueTokens(address _tokenAddress, address _to, uint _amount)external isCanDo(ISSUE_TOKENS) {
_issueTokens(_tokenAddress,_to,_amount);
}

function _issueTokens(address _tokenAddress, address _to, uint _amount)internal{
function issueTokens(address _tokenAddress, address _to, uint _amount)public isCanDo(ISSUE_TOKENS) {
emit DaoBase_IssueTokens(_tokenAddress, _to, _amount);
for(uint i=0; i<store.getAllTokenAddresses().length; ++i){
if(store.getAllTokenAddresses()[i]==_tokenAddress){
// WARNING:
// token ownership should be transferred to the current DaoBase to do that!!!
store.getAllTokenAddresses()[i].mint(_to, _amount);
store.getAllTokenAddresses()[i].mintFor(_to, _amount);
return;
}
}
Expand All @@ -222,14 +209,14 @@ contract DaoBase is IDaoBase, Ownable {
revert();
}

function burnTokens(address _tokenAddress, address _who, uint _amount)external isCanDo(BURN_TOKENS){
function burnTokens(address _tokenAddress, address _who, uint _amount)public isCanDo(BURN_TOKENS){
emit DaoBase_BurnTokens(_tokenAddress, _who, _amount);

for(uint i=0; i<store.getAllTokenAddresses().length; ++i){
if(store.getAllTokenAddresses()[i]==_tokenAddress){
// WARNING:
// token ownership should be transferred to the current DaoBase to do that!!!
store.getAllTokenAddresses()[i].burn(_who, _amount);
store.getAllTokenAddresses()[i].burnFor(_who, _amount);
return;
}
}
Expand All @@ -255,7 +242,7 @@ contract DaoBaseWithUnpackers is DaoBase {

function upgradeDaoContractGeneric(bytes32[] _params) external {
IDaoBase _b = IDaoBase(address(_params[0]));
_upgradeDaoContract(_b);
upgradeDaoContract(_b);
}

function addGroupMemberGeneric(bytes32[] _params) external {
Expand All @@ -271,7 +258,7 @@ contract DaoBaseWithUnpackers is DaoBase {
address _to = address(_params[1]);
uint _amount = uint(_params[2]);

_issueTokens(_tokenAddress, _to, _amount);
issueTokens(_tokenAddress, _to, _amount);
}

// TODO: add other methods:
Expand Down
11 changes: 5 additions & 6 deletions contracts/DaoBaseAuto.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import "./utils/GenericCaller.sol";
*/
contract DaoBaseAuto is GenericCaller {

bytes32 constant public MANAGE_GROUPS = keccak256("manageGroups");
bytes32 constant public ISSUE_TOKENS = keccak256("issueTokens");
bytes32 constant public UPGRADE_DAO_CONTRACT = keccak256("upgradeDaoContract");
bytes32 public MANAGE_GROUPS = keccak256(abi.encodePacked("manageGroups"));
bytes32 public ISSUE_TOKENS = keccak256(abi.encodePacked("issueTokens"));
bytes32 public UPGRADE_DAO_CONTRACT = keccak256(abi.encodePacked("upgradeDaoContract"));

constructor(IDaoBase _dao)public
GenericCaller(_dao)
Expand All @@ -26,7 +26,7 @@ contract DaoBaseAuto is GenericCaller {

function addGroupMemberAuto(string _group, address _a) public returns(address proposalOut){
bytes32[] memory params = new bytes32[](2);
params[0] = bytes32(keccak256(_group));
params[0] = bytes32(keccak256(abi.encodePacked(_group)));
params[1] = bytes32(_a);

return doAction(MANAGE_GROUPS, dao, msg.sender,"addGroupMemberGeneric(bytes32[])",params);
Expand Down Expand Up @@ -57,5 +57,4 @@ contract DaoBaseAuto is GenericCaller {
function allowActionByAddress(string _what, address _a) public isCanDo("manageGroups"){
function allowActionByAnyMemberOfGroup(string _what, string _groupName) public isCanDo("manageGroups"){
*/
}

}
4 changes: 2 additions & 2 deletions contracts/DaoBaseImpersonated.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import "zeppelin-solidity/contracts/ECRecovery.sol";
*/
contract ImpersonationCaller is DaoClient {

bytes32 constant public ISSUE_TOKENS = keccak256("issueTokens");
bytes32 public ISSUE_TOKENS = keccak256(abi.encodePacked("issueTokens"));

constructor(IDaoBase _dao) public DaoClient(_dao) {

Expand All @@ -34,7 +34,7 @@ contract ImpersonationCaller is DaoClient {

// 3 - call
if(!address(dao).call(
bytes4(keccak256(_methodSig)),
bytes4(keccak256(abi.encodePacked(_methodSig))),
uint256(32), // pointer to the length of the array
uint256(_params.length), // length of the array
_params)){
Expand Down
42 changes: 21 additions & 21 deletions contracts/IDaoBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,44 @@ import './governance/IProposal.sol';
* @title IDaoObserver, can be called IDaoClient really.
* @dev Also, see DaoClient contract below.
*/
interface IDaoObserver {
function onUpgrade(address _newAddress) external;
contract IDaoObserver {
function onUpgrade(address _newAddress) public;
}

/**
* @title This is the base interface that you should use.
* @dev Derive your DAO from it and provide the method implementation or
* see DaoBase contract that implements it.
*/
interface IDaoBase {
function addObserver(IDaoObserver _observer)external;
function upgradeDaoContract(IDaoBase _new)external;
contract IDaoBase {
function addObserver(IDaoObserver _observer)public;
function upgradeDaoContract(IDaoBase _new)public;

// Groups
function addGroupMember(string _groupName, address _a) external;
function removeGroupMember(string _groupName, address _a) external;
function getMembersCount(string _groupName) external constant returns(uint);
function isGroupMember(string _groupName,address _a)external constant returns(bool);
function getMemberByIndex(string _groupName, uint _index) external view returns (address);
function addGroupMember(string _groupName, address _a) public;
function removeGroupMember(string _groupName, address _a) public;
function getMembersCount(string _groupName) public constant returns(uint);
function isGroupMember(string _groupName,address _a)public constant returns(bool);
function getMemberByIndex(string _groupName, uint _index) public view returns (address);

// Permissions
function allowActionByShareholder(bytes32 _what, address _tokenAddress) external;
function allowActionByVoting(bytes32 _what, address _tokenAddress) external;
function allowActionByAddress(bytes32 _what, address _a) external;
function allowActionByAnyMemberOfGroup(bytes32 _what, string _groupName) external;
function allowActionByShareholder(bytes32 _what, address _tokenAddress) public;
function allowActionByVoting(bytes32 _what, address _tokenAddress) public;
function allowActionByAddress(bytes32 _what, address _a) public;
function allowActionByAnyMemberOfGroup(bytes32 _what, string _groupName) public;

function isCanDoAction(address _a, bytes32 _permissionName)external constant returns(bool);
function isCanDoAction(address _a, bytes32 _permissionName)public constant returns(bool);

// Tokens
// ???? TODO: needed
//function addTokenAddressToList();
function issueTokens(address _tokenAddress, address _to, uint amount)external;
function burnTokens(address _tokenAddress, address _who, uint amount)external;
function issueTokens(address _tokenAddress, address _to, uint amount)public;
function burnTokens(address _tokenAddress, address _who, uint amount)public;

// Governance/Proposals
function addNewProposal(IProposal _proposal) external;
function getProposalAtIndex(uint _i)external constant returns(IProposal);
function getProposalsCount()external constant returns(uint);
function addNewProposal(IProposal _proposal) public;
function getProposalAtIndex(uint _i)public constant returns(IProposal);
function getProposalsCount()public constant returns(uint);
}

/**
Expand Down Expand Up @@ -72,7 +72,7 @@ contract DaoClient is IDaoObserver {
* dao will point at NEW contract!
* @param _newAddress New controller.
*/
function onUpgrade(address _newAddress) external {
function onUpgrade(address _newAddress) public {
require(msg.sender==address(dao));

dao = IDaoBase(_newAddress);
Expand Down
6 changes: 3 additions & 3 deletions contracts/governance/IProposal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import '../IDaoBase.sol';
* @dev This is the basic DAO Proposal interface. Each Proposal should have voting attached.
* Proposal can do some action if voting is finished with 'yes' result. Or action can be empty.
*/
interface IProposal {
function action()external;
function getVoting()external view returns(IVoting voting);
contract IProposal {
function action()public;
function getVoting()public view returns(IVoting voting);

// ???
// function isOpen() public constant returns(bool);
Expand Down
Loading

0 comments on commit 79ea6b2

Please sign in to comment.