daostack / arc Goto Github PK
View Code? Open in Web Editor NEWArc is an operating system for DAOs.
License: GNU General Public License v3.0
Arc is an operating system for DAOs.
License: GNU General Public License v3.0
Create version.sol that would include only
pragma solidity ^0.X.X;
All our files (e.g., not zeplin's) should import it.
I became aware of this project yesterday at a meetup where Matan presented it.
I am not sure what is the security model you have (i.e., who is malicious and who is trusted), but I thought I can give some small comments nevertheless.
When setting reputation, there is a danger of an overflow when totalReputation - reputation[_account] + _amount > 2**256
(note that user is free to set _amount
to whatever value he wishes).
The winning proposal function winningProposal
is attackable. A malicious user might propose many proposals by calling NamedProposalBallot
, which will cause winningProposal
to run out of gas, even if the possible maximum gas is allocated for running it.
A possible fix is to update the winning proposal on the fly, whenever calling vote
function.
I can arrange a pull request to fix these two issues if you want.
But I am still not sure I get the full picture.
General rule is that only those things that need to be persistent and trustless go to the blockchain/solidity. The reason is that the blockchain is expensive/difficult to work with, in comparison to javascript.
This seems to me a wrong pattern to use:
// deploy a helper contract that creates my controller
helpercontract = new GenesisSchema(configurationoptions)
// do some explicit stuff that the helpercontract is not doing automatically
helpercontract.collectFoundershare()..
// now get the controller
controller = x.controller()
// if we need to do more config, we can do it by voting
controller.proposeToAddSomeSchema(0x1234, 400)
controller.voteonthis()
This is wrong because (1) configuration logic is spread over javascript and solidity, which is messy and hard to code and understand and (2) is wastes resources by deploying contracts that are just temporary helpers.
Instead, this pattern seems more straightforward to me:
// create a new Controller
controller = new Controller(somebasicsettings)
// the controller is owned by its cerateor, who can now do some more configutaation here in javascript
controller.setReputation(0x123, 100)
controller.addSchema(0x125)
// when configuration is done, the owner can renounce ownership
// (e.g. by setting the owner "to itself")
controller.transferOwnershipt(controller.address)
The current workflow is to register the schem is:
Question: should 4. be included in 3?
pro: easier to use, one transacion less
contra: possibily need tokens to register the controller
Lets say we have a Reputation system with total supply 100 and I (account[0]
) have a reputation of 5.
I can do:
const simpleVote = await SimpleVote.new();
const executable = await ExecutableTest.new();
const paramsHash = await simpleVote.setParameters(reputation.address, 4);
const tx = await simpleVote.propose(paramsHash, helpers.NULL_ADDRESS, executable.address);
const proposalId = await getValueFromLogs(tx, '_proposalId');
await simpleVote.vote(proposalId, true, accounts[0]);
Won't this win every time?
At this point we have a generic upgradeable DAO with reputation, majority voting, and the possibility to mint and sell tokens, distribute reputation.
See #15 for details.
@yaronvel mentioned some problem with deployment (I guess GenesisScheme needs to be higher in the tree than the Controller?)
This is the currently implemented API, https://github.com/daostack/daostack/blob/dev/docs/library/organization.md
Here are some questions/suggestions for improvement:
Perhaps it is better to pass the founders like this:
await Organization.new({
orgName: 'Name of organization', // string, required, name of organization
tokenName: 'xx', // string, required, name of organization's token
tokenSymbol: 'xxx', // string, required, symbol of organization's token
founders: [
address: '0x1234',
reputatoin: 30,
tokens: 12.3333,
] })
should we offer the optino to set the schemes used. Or do we just offer our ones, or the possibility to "roll your own"?
Even though ethereum blockchain is public and technically any data is extractable by anyone, it is still technically cumbersome to reason on operations that are not explicitly logged.
Logging important operations, such as votes, token minting, reputation creation etc, as solidity events generates public trace and thus both increase the credability of the contract (e.g., one can witness that the contract is running as expected) and give the user an interface to programmingly react to important operations (e.g., if person X votes Y, then I will also vote Y).
So the schema should allow for creating proposals to give N tokens to 0x1234.
There is already code and tests for that in a previous version (prev to 09c78ff)
right now need to deploy and approve a new contract each update
I.e. rewrite this line in registerScheme
:
/* require(bytes4(15)&(_permissions^scheme.permissions)&(~schemes[msg.sender].permissions) == bytes4(0)); */
As it is now, one a ProposalMintTokens is accepted, it can be executed many times. We'll need to add an "executed" flag.
Same holds for ProposalMintReputation.
Here's the thing:
In the library, I'd expect this kind of interaction (one of these, I'm not sure about the syntax yet):
organization.proposeNewScheme(...)
organization.schemeRegistrar.proposeScheme(...)
organization.schemes.schemeRegisterar.proposeScheme(...)
The first problem with this is that at the moment there is no way (as far as I can see) to get the 'schemeRegistrar' from the controller.
There is an extra complication that in theory there is no the schemeRegistrar, there could be many registered.
(Just be clear, what we can do is:
Possible solutions:
schemeRegistrar
, updateScheme
and globalConstraintRegistrar
(with specific registration functions).I vote tentatively for the second solution, which seems the least traumatic and does not need any changes in the code.
you agree, @fmatan?
propose(...)
does not automatically vote, which is different from the proposeScheme
, where proposing -does- imply voting.
vote(proposalId, yes, voter)
: the owner can cast a vote in the name of voter
. This renders the contract inherently less "trustless" - trust is transferred to the owner. In our case, the owners is the controller: this means that the organization could accepts a proposal to vote in some minorityes name. It all seems messy and wrong.
UX issue with SimpleProposal.vote(...) We now have the situation where, if the decisive vote is cast, the proposal is executed This has the following problem: if for some reason, the executions fails (and it could fail for many reasons), this means the vote will not be counted at all.
We need a set of tests (in test/simplevote.js
) that test registering a prposal, voting with different parameters, testing permissions.
Hi all,
After an architecture session with @fmatan.
Tried to draw the main changes towards architecture for alpha and beta versions.
Main alpha changes are:
We can open an issue for each one. But I think we can start here, and the issues that will raise debate we will separate.
Adam.
Here's a lucid description of the (two) alternatives:
https://github.com/ConsenSys/smart-contract-best-practices#upgrading-broken-contracts
No, each global contstraints on the controller are kept in an array of address of the global constraints. This makes it possible to only register each GC contract only once on the controller. But it is easy to think of scenarios in which we use the same GC contract for different constraints, using different params (e.ge. the tokenCap constraint can also be used for external tokens).
Propsal: instead, have an array of (gccontractaddres, params) structs (or some other kind of scheme)
In the suggested scheme making a new ballot to vote on amounts to deploying a new contract. However, it can also be implemented (as in TheDAO) as a function inside a DAO contract. Should understand what's the main differences and what's better. Moreover, right now we have no DAO contract, but only a Token and Reputation contract, and Ballots to modify them. We do need to tie each Reputation contract to a Token contract 1-1, but do we need a central DAO contract? More generally it'd be useful to define the general architecture for the entire DAO and then implement its elements. A WIP on this can be found here.
Steps to reproduce:
git clone <daostack URL>
cd daostack
truffle test
Error
Error: Could not find zeppelin/contracts/ownership/Ownable.sol from any sources; imported from /mnt/d/work/eth/daostack/contracts/SimpleVote.sol
at /mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/index.js:76:23
at /mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/node_modules/async/internal/onlyOnce.js:12:16
at next (/mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/node_modules/async/whilst.js:68:18)
at /mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/index.js:64:7
at /mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/fs.js:65:5
at /mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/node_modules/async/internal/once.js:12:16
at replenish (/mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/node_modules/async/internal/eachOfLimit.js:59:25)
at iterateeCallback (/mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/node_modules/async/internal/eachOfLimit.js:49:17)
at /mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/node_modules/async/internal/onlyOnce.js:12:16
at ReadFileContext.callback (/mnt/c/Users/User/AppData/Roaming/nvm/v7.5.0/node_modules/truffle/node_modules/truffle-resolver/fs.js:61:14)
Environment:
See also issue #12
While a vote is opened, the totalSupply
of Reputation
can change. The owner of the Reputation is the only one that can mint and set reputation, but what happens when this owner cannot be trusted? He can manipulate totalSupply
and affect voting results.
I think reputation should be given via contract and not by the Reputation owner
.
E.g. make a reputation registry - like the gov registry - with "plug-able" reputation implementations and allow DOAs to create/choose their own reputation system.
Also I like that you did take into account that reputations change while a proposal is opened (by using proposal.voted[_voter]
):
https://github.com/daostack/daostack/blob/6a2a928cc130e78638d4f440112e11c147f4b0b3/contracts/VotingMachines/SimpleVote.sol#L111-L120
One of the main points of the genesisscheme is to simplify the deployment into as few transactions as possible. This is working out not so good.
At the moment of writing (commit 64c1554) the deployment procedure of a new organization that uses only already existing schemes takes 8 different transactions, plus you need to have tokens to pay for registering your organization with the schemes (at the moment 3, possibly different from each other).
The relevant code is here: https://github.com/daostack/daostack/blob/64c1554a003512c1cfc436040acc0bb114a13c8b/lib/organization.js#L24
Proposed upgrades for the beta version:
@fmatan @jellegerbrandy, your thoughts and ideas will be appreciated :)
UniversalGCRegister ==> GlobalConstraintsRegistrar
(not register but registrar, because it is not a register but a contract that is registering global constraints at te controller)
UniversalGenesisScheme ==> GenesisScheme
UniversalOrgRegistry ==> OrganizationRegister
UniversalScheme ==> Scheme
UniversalSchemeRegister ==>> SchemeRegistrar
(a scheme that registers other schems)
UniversalSimpleContribution ==> SimpleContributionScheme
UniversalUpgradeScheme ==> UpgradeScheme
UniversalSimpleVote ==> BooleanVotingMachine
BoolVoteInterface is not used: remove?
UniversalSimpleVoteInterface ==> VotingMachineInterface
nativeToken ==> token (anywhere where it does not lead to ambiguity)
nativeReputation ==> reputation (anywhere where it does not elad to ambiguity)
Contract initiated with fixed amount of non-transferable reputation score to deployer
Assign new reputation score works like this:
Assigning new tokens works in a way very similar to assigning reputation, just that it is another type of Ballot (#13)
like #27, but for reputation
This seems only fair.
if not, remove employee.js and employee.sol
The UI should make interacting with a DCO simple and intuitive. In the spirit of the DAO stack, we implement functionality in an incremental way.
for example, the eecute function in SimpleContributionScheme.sol
starts with:
function execute(bytes32 _proposalId, address _avatar, int _param) returns(bool) {
// Check if vote was successful:
// TODO: this seems a security problem
if (_param != 1) {
delete proposals[_proposalId];
return true;
}
which seems to allow anyone to delete a proposal from the propals list. The same pattern occurs in other places
all other schemes: "registerOrganization" add the avatar to the list of registered organization. SimpleICO also creates a donatino contract and checks for settings on the organization.
Proposal is to have a uniform semantics for registerOrganization
in the schemes, and add a 'startICO' or similar for actually starting hte ICO.
This is a standard Token contract that is Ownable and Killable.
[matanf wrote:] We need to decide about the actual voting-collection method: we have a default one for now but should consider others. There's a few posts on this topic (including of people from Colony), reviewing different methods and problems. Basically you can compute votes all together, or one by one, etc.
We'd like to run tests and perhaps also some formatting checks automatically on each commit
The genesischeme at the moment does two different, basically unrelated, things:
I propose to separate this in two different contracts (or, if we do what i propse in #25, just forget about the 1), and just have it do 2).
Reputation distribution changes in time; the decision process takes time. This raises a number of decisions we need to make on how to count votes (i.e. relative to which distribution): Here is a typical case:
Question: did the proposal pass? And specifically: how much rep is staked on "yes" and how much on "no"?
The idea is that the frontend-devs would be much helped with a consistent sane interface.
A JS sessino interacting with an Organization could look like this (simplified by pretending these are all synchronous functions; in reality the code would be full of 'awaits')
import { Organization } from 'lib/Organization.js';
// a new organization is called with an options object that has lots of sane defaults.
// These are the the only obligatory options:
let organisation = Organisation.new({
orgName: 'A descriptive name',
tokenName: 'OrgToken',
tokenSymbol: 'OTO'
});
// while the full list of options (with its default) looks like this (there will be moer options):
organisation = Organisation.new({
orgName: null, // no default provided, must be defined in the function call
tokenName: null, // no default provided
tokenSymbol: null, // no default provided
founders: [],
tokensForFounders: [],
repForFounders: [],
genesisSchemeAddress: 0x123, // default is the most recnet DAOStack genesis scheme
schemeRegistrar: {
address: 0x12344, // default is the daostack registrar
votingMachineAddress: 0x1234, // a SimpleVote contract
reputationAddress, // default is the reputation of the present organisation,
votePrec: 50, // percentage of votes needed for decision
},
GCRegister: {
// ... config here
},
UpgradeScheme: {
},
})
// alternative, a deployed organization can be instantiated using "at"
organisation = Organization.at('0x12345..');
// the Organisation object corresponds roughly to the controller and its "spiderweb" of registered schemes, tokens, etc
organisation.token();
organisation.reputation();
organisation.avatar();
// next call returns the registered schemes
let schemes = organization.listSchemes()
// scheme will be an in isntance of Scheme
let scheme = schemes[0];
// the scheme has all the methods of the corresponding contract on the blockchain
// (and perhaps others)
// for example, if scheme is a SimpleICO, we can do:
scheme.haltICO(controller);
// we can also see which proposals have been proposed (in the different schemes)
let proposalsList = organisation.listProposals();
// proposalsList is an array of Proposal instances
let proposal = proposalsList[0];
// we can getinfo from the proposal like how many have voted, what scheme they are
// registered in, what votingmachine is being used, etc
assert.equal(proposal.yes(), 12);
assert.equal(assert.scheme.address, '0x124...');
proposal.votingMachine;
proposal.votingMachineParams;
// voting looks like this
organisation.vote(proposal, true);
// or we can even do:
proposal.vote(true);
// etc. etc. (still to be defined)
What is preventing a malicious proposal.owner
rapidly voting for its proposal "on behalf" of other voters (just call vote
with other voters' addresses) and triggering a successful executeProposal(_proposalId)
in https://github.com/daostack/daostack/blob/6a2a928cc130e78638d4f440112e11c147f4b0b3/contracts/VotingMachines/SimpleVote.sol#L133 after enough votes?
I think that _voter
should always be msg.sender
.
Am I missing someting? When and why would a voter need to vote on behalf of someone else?
Hi,
Solidity 0.4.11 was introduced. There were several important changes since 0.4.8 (most of the current code was last written using 0.4.8).
Important changes:
They added
I have opened a new branch to implement these new features and will soon merge it to master.
Adam.
The next pattern is not really testing anything (the value of fail is always 200).
try {
web3.eth.sendTransaction({'from':founders[1], 'to':tokenSaleAddress, 'value': web3.toWei(1, "ether")});
throw 'an error' // make sure that an error is thrown
} catch(error) {
fail = 200;
}
assert.equal(fail,200,"buying tokens should fail"); // todo make less ugly
Instead it should be:
try {
web3.eth.sendTransaction({'from':founders[1], 'to':tokenSaleAddress, 'value': web3.toWei(1, "ether")});
throw 'an error' // make sure that an error is thrown
} catch(error) {
// assert something specific about the kind fo error - for example that it is not the error thrown in the previous line
assertJump(error)
}
In the current setup, the Token contract can mint unlimited new tokens.
This may be unideal, because it makes all tokens infinitely dilutable, in principle. There is no garantee for a token holder that his tokens will continue to represent a certain guaranteed fraction of the total amount. Anyone who controls the mint function can dilute your tokens as much as he wants (assigning them to himself, for example).
Question: should we put a maximum limit on the amount of tokens that can be created, making them more similar to stocks in the real world?
Our code needs to be usable in the browser - we need to set up a build system that bundles and browserifies our library
npm run solium
should exit without errors or warnings.
once all errors are resolved, we should add solium to the travic tests
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.