├── .babelrc ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github └── CODEOWNERS ├── .gitignore ├── .solcover.js ├── .solhint.json ├── .travis.yml ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── contracts ├── controller │ ├── Avatar.sol │ ├── Controller.sol │ └── DAOToken.sol ├── globalConstraints │ ├── GlobalConstraintInterface.sol │ └── TokenCapGC.sol ├── libs │ └── SafeERC20.sol ├── schemes │ ├── Agreement.sol │ ├── Auction4Reputation.sol │ ├── Competition.sol │ ├── ContinuousLocking4Reputation.sol │ ├── ContributionRewardExt.sol │ ├── CurveInterface.sol │ ├── DxDaoSchemeConstraints.sol │ ├── ExternalLocking4Reputation.sol │ ├── FixedReputationAllocation.sol │ ├── Forwarder.sol │ ├── GenericScheme.sol │ ├── GenericSchemeMultiCall.sol │ ├── Locking4Reputation.sol │ ├── LockingEth4Reputation.sol │ ├── LockingToken4Reputation.sol │ ├── PriceOracleInterface.sol │ ├── RageQuitWithToken.sol │ ├── ReputationAdmin.sol │ ├── ReputationFromToken.sol │ ├── SchemeConstraints.sol │ ├── SignalScheme.sol │ ├── SimpleSchemeConstraints.sol │ └── TransitionScheme.sol ├── test │ ├── ARCDebug.sol │ ├── ARCGenesisProtocolCallbacksMock.sol │ ├── ActionMock.sol │ ├── AgreementMock.sol │ ├── BadERC20.sol │ ├── ERC20Mock.sol │ ├── ExternalTokenLockerMock.sol │ ├── GlobalConstraintMock.sol │ ├── NectarRepAllocation.sol │ ├── PolkaCurve.sol │ ├── PriceOracleMock.sol │ ├── SafeERC20Mock.sol │ ├── UniversalSchemeMock.sol │ └── Wallet.sol ├── universalSchemes │ ├── ContributionReward.sol │ ├── DaoCreator.sol │ ├── GlobalConstraintRegistrar.sol │ ├── OrganizationRegister.sol │ ├── SchemeRegistrar.sol │ ├── UniversalScheme.sol │ ├── UniversalSchemeInterface.sol │ ├── UpgradeScheme.sol │ └── VoteInOrganizationScheme.sol ├── utils │ ├── CompetitionFactory.sol │ ├── ContinuousLocking4ReputationFactory.sol │ ├── DAOTracker.sol │ ├── GenericSchemeMultiCallFactory.sol │ ├── Redeemer.sol │ └── RepAllocation.sol └── votingMachines │ └── VotingMachineCallbacks.sol ├── docs ├── README.md ├── contracts │ ├── README.md │ ├── VotingMachines │ │ └── README.md │ ├── controller │ │ ├── Avatar.md │ │ ├── Controller.md │ │ ├── DAOToken.md │ │ ├── README.md │ │ ├── Reputation.md │ │ └── UController.md │ ├── globalConstraints │ │ ├── README.md │ │ └── TokenCapGC.md │ └── universalSchemes │ │ └── README.md ├── generated_docs │ ├── Migrations.md │ ├── README.md │ ├── VotingMachines │ │ ├── AbsoluteVote.md │ │ ├── GenesisProtocol.md │ │ ├── GenesisProtocolFormulasInterface.md │ │ ├── IntVoteInterface.md │ │ └── QuorumVote.md │ ├── controller │ │ ├── ActionInterface.md │ │ ├── Avatar.md │ │ ├── Controller.md │ │ ├── ControllerInterface.md │ │ ├── DAOToken.md │ │ ├── Reputation.md │ │ └── UController.md │ ├── globalConstraints │ │ ├── GlobalConstraintInterface.md │ │ └── TokenCapGC.md │ ├── test │ │ ├── ActionMock.md │ │ ├── Debug.md │ │ ├── ExecutableTest.md │ │ ├── GenesisProtocolFormulasMock.md │ │ ├── GlobalConstraintMock.md │ │ └── UniversalSchemeMock.md │ └── universalSchemes │ │ ├── ContributionReward.md │ │ ├── ControllerCreator.md │ │ ├── DaoCreator.md │ │ ├── ExecutableInterface.md │ │ ├── GlobalConstraintRegistrar.md │ │ ├── MirrorContractICO.md │ │ ├── OrganizationRegister.md │ │ ├── SchemeRegistrar.md │ │ ├── SimpleICO.md │ │ ├── UniversalScheme.md │ │ ├── UniversalSchemeInterface.md │ │ ├── UpgradeScheme.md │ │ ├── VestingScheme.md │ │ └── VoteInOrganizationScheme.md ├── img │ ├── controller.png │ ├── favicon.ico │ └── the_dao_stack.png └── index.html ├── hardhat.config.js ├── mkdocs.yml ├── package-lock.json ├── package.json ├── release.sh ├── scripts └── extract-abis.js ├── test ├── agreement.js ├── auction4reputation.js ├── avatar.js ├── competition.js ├── competitionfactory.js ├── constants.js ├── continuouslocking4reputationfactory.js ├── continuouslockingtoken4reputation.js ├── contributionreward.js ├── contributionrewardext.js ├── controller.js ├── daocreator.js ├── daotoken.js ├── daotracker.js ├── externallocking4reputation.js ├── fixreputationallocation.js ├── forwarder.js ├── genericscheme.js ├── genericschememulticall.js ├── genericschememulticallfactory.js ├── globalconstraintregistrar.js ├── helpers.js ├── lockingeth4reputation.js ├── lockingtoken4reputation.js ├── nectarrepallocation.js ├── organizationregister.js ├── polkacurve.js ├── ragequitwithtoken.js ├── reputationadmin.js ├── reputationfromtoken.js ├── safeerc20.js ├── schemeregistrar.js ├── signalscheme.js ├── tokencapgc.js ├── transitionscheme.js ├── upgradescheme.js ├── voteinorganization.js └── votingmachinecallbacks.js ├── truffle.js └── tsconfig.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": ["syntax-async-functions"] 4 | } 5 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | coverage/ 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "parser": "babel-eslint", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module", 7 | "ecmaFeatures": { 8 | "jsx": true 9 | } 10 | }, 11 | "rules": { 12 | "semi": 2, 13 | "no-undef": "off", 14 | "eol-last": 2, 15 | "eqeqeq": "error" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/about-codeowners/ 2 | # for more info about CODEOWNERS file 3 | 4 | # It uses the same pattern rule for gitignore file 5 | # https://git-scm.com/docs/gitignore#_pattern_format 6 | 7 | * @orenyodfat @leviadam 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *sublime* 2 | *.pyc 3 | build/ 4 | logs/ 5 | node_modules/ 6 | .node-xmlhttprequest-sync* 7 | *.tgz 8 | .vscode/ 9 | site/ 10 | coverage/ 11 | coverage.json 12 | .covera* 13 | cache/ 14 | yarn* 15 | 16 | node_modules 17 | 18 | #Hardhat files 19 | cache 20 | artifacts 21 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mocha: { 3 | enableTimeouts: false, 4 | grep: "@skip-on-coverage", // Find everything with this tag 5 | invert: true, // Run the grep's inverse set. 6 | timeout: 100000, 7 | }, 8 | skipFiles: ['test/'], 9 | providerOptions: { 10 | accounts: [ 11 | { 12 | secretKey: 13 | "0xc5e8f61d1ab959b397eecc0a37a6517b8e67a0e7cf1f4bce5591f3ed80199122", 14 | balance: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 15 | }, 16 | { 17 | secretKey: 18 | "0xd49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb", 19 | balance: "10000000000000000000000" 20 | }, 21 | { 22 | secretKey: 23 | "0x23c601ae397441f3ef6f1075dcb0031ff17fb079837beadaf3c84d96c6f3e569", 24 | balance: "10000000000000000000000" 25 | }, 26 | { 27 | secretKey: 28 | "0xee9d129c1997549ee09c0757af5939b2483d80ad649a0eda68e8b0357ad11131", 29 | balance: "10000000000000000000000" 30 | }, 31 | { 32 | secretKey: 33 | "0x87630b2d1de0fbd5044eb6891b3d9d98c34c8d310c852f98550ba774480e47cc", 34 | balance: "10000000000000000000000" 35 | }, 36 | { 37 | secretKey: 38 | "0x275cc4a2bfd4f612625204a20a2280ab53a6da2d14860c47a9f5affe58ad86d4", 39 | balance: "10000000000000000000000" 40 | }, 41 | { 42 | secretKey: 43 | "0x7f307c41137d1ed409f0a7b028f6c7596f12734b1d289b58099b99d60a96efff", 44 | balance: "10000000000000000000000" 45 | }, 46 | { 47 | secretKey: 48 | "0x2a8aede924268f84156a00761de73998dac7bf703408754b776ff3f873bcec60", 49 | balance: "10000000000000000000000" 50 | }, 51 | { 52 | secretKey: 53 | "0x8b24fd94f1ce869d81a34b95351e7f97b2cd88a891d5c00abc33d0ec9501902e", 54 | balance: "10000000000000000000000" 55 | }, 56 | { 57 | secretKey: 58 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29085", 59 | balance: "10000000000000000000000" 60 | }, 61 | { 62 | secretKey: 63 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29086", 64 | balance: "10000000000000000000000" 65 | }, 66 | { 67 | secretKey: 68 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29087", 69 | balance: "10000000000000000000000" 70 | }, 71 | { 72 | secretKey: 73 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29088", 74 | balance: "10000000000000000000000" 75 | }, 76 | { 77 | secretKey: 78 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29089", 79 | balance: "10000000000000000000000" 80 | }, 81 | { 82 | secretKey: 83 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908a", 84 | balance: "10000000000000000000000" 85 | }, 86 | { 87 | secretKey: 88 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908b", 89 | balance: "10000000000000000000000" 90 | }, 91 | { 92 | secretKey: 93 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908c", 94 | balance: "10000000000000000000000" 95 | }, 96 | { 97 | secretKey: 98 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908d", 99 | balance: "10000000000000000000000" 100 | }, 101 | { 102 | secretKey: 103 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908e", 104 | balance: "10000000000000000000000" 105 | }, 106 | { 107 | secretKey: 108 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908f", 109 | balance: "10000000000000000000000" 110 | } 111 | ] 112 | } 113 | }; 114 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:all", 3 | "rules": { 4 | "indent": ["error", 4], 5 | 6 | "compiler-fixed": "off", 7 | "no-simple-event-func-name": "off", 8 | "two-lines-top-level-separator": "off", 9 | "mark-callable-contracts": "off", 10 | "reason-string": "off" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - "14.5.0" 7 | 8 | before_install: 9 | 10 | install: 11 | - rm -rf node_modules/ # remove any remaining artifacts from a previous build 12 | - npm i 13 | - rm -rf build/ # remove any remaining artifacts from a previous build 14 | - npx hardhat --version 15 | - npx hardhat clean 16 | 17 | jobs: 18 | include: 19 | - stage: tests 20 | name: "Unit tests" 21 | script: npx hardhat test 22 | 23 | - stage: tests 24 | name: "Solidity Lint" 25 | script: npx hardhat check 26 | 27 | - stage: tests 28 | name: "JS Lint" 29 | script: npx eslint . 30 | 31 | - stage: coverage 32 | name: "Solidity Test Coverage" 33 | if: branch = master 34 | script: npm run coveralls 35 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | # Contribution Guide 3 | ___ 4 | 5 | Firstly, thanks for wanting to help with the development of DAOSTACK. All contributions, code or documents, should come from a forked version of the respective repository. Then the proposed changes must be submitted via a pull request to the master branch. All pull requests must be reviewed by the maintainers of the repository in question. Once a pull request has been reviewed & approved; you should merge and rebase, and then delete the branch. 6 | GitHub [keywords](https://help.github.com/articles/closing-issues-using-keywords/) should be used when closing pull requests and issues. 7 | 8 | If you wish to submit more substantial changes or additions, please see the feature contributions section below. 9 | 10 | 11 | ## Git Practice 12 | 13 | Branches should be named with a brief semantic title. 14 | Commit messages should be capitalised and follow these rules: 15 | ``` 16 | Short (50 chars or less) summary of changes 17 | 18 | More detailed explanatory text, if necessary. Wrap it to about 72 19 | characters or so. In some contexts, the first line is treated as the 20 | subject of an email and the rest of the text as the body. The blank 21 | line separating the summary from the body is critical (unless you omit 22 | the body entirely); tools like rebase can get confused if you run the 23 | two together. 24 | 25 | Further paragraphs come after blank lines. 26 | 27 | - Bullet points are okay, too 28 | 29 | - Typically a hyphen or asterisk is used for the bullet, preceded by a 30 | single space, with blank lines in between, but conventions vary here 31 | 32 | Issue: #1, #2 33 | ``` 34 | A properly formed Git commit subject line should always be able to complete the following sentence: 35 | 36 | If applied, this commit will _Your subject line here_ 37 | 38 | **Please refer to [this guide](https://chris.beams.io/posts/git-commit/) for additional information.** 39 | 40 | 41 | ## Feature Contributions 42 | 43 | For the submission of more substantial changes or additions, an issue should be opened outlining what is being proposed for implementation. The title of the issue should be descriptive and brief, follow the same rules as a commit message, as outlined above. The body of the issue should detail the reasoning for the need of the work to be carried out and the desired outcome. 44 | 45 | 46 | ## Code Formatting and Commentary 47 | 48 | ### Javascript 49 | All Javascript must be formatted with [ESLint](http://eslint.org/) using the DAOSTACK [configuration](https://github.com/daostack/daostack/blob/master/.eslintrc.json). 50 | 51 | ### Solidity 52 | All Solidity files must follow the style guide found [here](http://solidity.readthedocs.io/en/develop/style-guide.html). 53 | All Solidity code must pass [solium](https://github.com/duaraghav8/Solium) linter check using DAOSTACK [configuration](https://github.com/daostack/daostack/blob/master/.soliumrc.json). 54 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # This is a Dockerfile that standardizes the project's development environment 2 | # and makes it cross-os/platform. 3 | # 4 | # Built image live at: https://hub.docker.com/r/daostack/arc/ 5 | # 6 | # author: Matan Tsuberi 7 | 8 | FROM node:9.5.0 9 | 10 | LABEL maintainer="Matan Tsuberi " 11 | 12 | VOLUME /home/arc 13 | WORKDIR /home/arc 14 | 15 | # install mkdocs & mkdocs-material 16 | RUN apt-get -y -qq update 17 | RUN apt-get -y -qq install python-pip build-essential libssl-dev libffi-dev python-dev 18 | RUN pip install mkdocs mkdocs-material 19 | 20 | # truffle 21 | RUN npm i -g truffle ganache-cli 22 | 23 | # clone the project if not cloned, else fetch latest. in any case install all `package.json` deps. 24 | CMD (git -C . fetch || git clone https://github.com/daostack/arc.git .) && npm i && /bin/bash 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ***DEVELOPMENT OF THIS PACKAGE HAS MOVED TO: https://github.com/daostack/alchemy-monorepo/tree/dev/packages/arc*** 2 | 3 | [![Build Status](https://travis-ci.org/daostack/arc.svg?branch=master)](https://travis-ci.org/daostack/arc) 4 | [![NPM Package](https://img.shields.io/npm/v/@daostack/arc.svg?style=flat-square)](https://www.npmjs.org/package/@daostack/arc) 5 | [![Join the chat at https://gitter.im/daostack/Lobby](https://badges.gitter.im/daostack/Lobby.svg)](https://gitter.im/daostack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 6 | # Arc 7 | 8 | Arc is the base layer of the DAO stack. It consists of a set of smart contracts deployed on the Ethereum blockchain that define the basic building blocks and standard components that can be used to implement any DAO. 9 | 10 | Arc is a modular, upgradeable platform that allows for a rapid natural selection of governance systems. 11 | 12 | ![Arc Structure Diagram](https://user-images.githubusercontent.com/5414803/51004260-d7252180-1507-11e9-9be7-2018dbc7452d.jpeg) 13 | *

Figure 1: Arc's structure

* 14 | 15 | **Every box in Figure 1 represents a smart contract.** 16 | 17 | The Token contract probably does not require an explanation, being the most popular use-case of the Ethereum network. 18 | 19 | **The Avatar contract is the face of an organization on the blockchain**, e.g. if the organization is to hold ownership of anything, like ownership over a contract or asset, the owner address will be the Avatar. 20 | 21 | **The Reputation contract stores a DAO's reputation data.** In Arc, Reputation represents a user's decision power in a given DAO. It is very similar to a token, with two main differences: one, it is non-transferable, and two, it can be granted or taken away by the DAO. 22 | 23 | On the right side of the figure we have the schemes. **Schemes are simple pieces of logic describing the different actions a DAO can take.** One example is a scheme for funding proposals, in which everyone can suggest and vote on proposals, and if a proposal is approved, it is automatically funded. 24 | 25 | At the bottom are the global constraints. **Global constraints prevent current and future modules from breaking certain overarching rules**, e.g. a cap on an organization’s total possible reputation. 26 | 27 | **The Controller is an access control module** that keeps a record of all the registered schemes in a DAO and the permissions for each scheme. It also records all global constraints and enforces them by reverting transactions that violate them. 28 | 29 | Go [here](https://medium.com/daostack/the-arc-platform-2353229a32fc) for a full primer on Arc. 30 | 31 | ## Security 32 | *DAOstack Arc* is still in its **alpha** version. 33 | Arc is intended to provide secure, tested, and community-audited code, but please use common sense when doing anything that deals with real money! 34 | We take no responsibility for your implementation decisions and any security problem you might experience. 35 | 36 | ## Getting Started 37 | 38 | 1. Please install [Truffle](https://github.com/ConsenSys/truffle) and initialize your project with `truffle init`. 39 | ```sh 40 | npm install -g truffle 41 | mkdir myproject && cd myproject 42 | truffle init 43 | ``` 44 | 2. Install the `@daostack/arc` package: `npm install @daostack/arc`. 45 | - `.sol` Source code is found under `node_modules/@daostack/arc/contracts` 46 | - `.json` Compiled contracts are found under `node_modules/@daostack/arc/build/contracts` 47 | 3. Import in your project: 48 | ```JavaScript 49 | import '@daostack/arc/contracts/universalSchemes/UniversalScheme.sol'; 50 | 51 | contract MyContract is UniversalScheme { 52 | ... 53 | } 54 | ``` 55 | You should be able to find the `@daostack/arc` contracts (.json) already built and ready for deployment in the `node_modules/@daostack/arc/build/contracts/` folder. 56 | 4. Read the [documentation](https://daostack.github.io/arc/) to get a better understanding of how to use Arc. 57 | 58 | ## Contribute 59 | 60 | PRs are welcome, but please first consult with the [Contribution guide](https://github.com/daostack/arc/blob/master/CONTRIBUTING.md). 61 | 62 | Join us on [Discord](https://daostack.io/community)! 63 | 64 | To contribute to Arc development start by cloning the repo and installing the dependencies: 65 | ```sh 66 | git clone https://github.com/daostack/arc 67 | cd arc 68 | npm install 69 | ``` 70 | ### Commands 71 | 72 | Available commands while developing: 73 | 74 | - `npm run build` - Compile all contracts to the `build/` folder. 75 | - `npm run test` - This will run ganache-cli, compile, migrate and run all tests. 76 | - `npm run lint` - Check all JavaScript code for style & good practices. 77 | - `npm run solhint` - Check all Solidity code for style & good practices. 78 | - `npm run docs:` - See [this](docs#contributing-to-arc-docs) for details. 79 | 80 | ### Docker 81 | Arc has a prebuilt Docker image that makes development environments consistent and cross-platform. 82 | To start developing inside this environment: 83 | 84 | 1. Install [Docker](https://www.docker.com/community-edition#/download) in your favorite OS/platform. 85 | 2. Run `docker run --rm -it -v :/home/arc daostack/arc` (*May require Admin/root permissions). 86 | 2. The container will automatically `git clone` or `git fetch` depending on if `` is empty, and will install any dependencies. 87 | 3. Continue development inside the container. 88 | 89 | ## License 90 | 91 | This is an open-source project ([GPL license](https://github.com/daostack/arc/blob/master/LICENSE)). 92 | -------------------------------------------------------------------------------- /contracts/controller/Avatar.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "@daostack/infra/contracts/Reputation.sol"; 4 | import "./DAOToken.sol"; 5 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 6 | import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; 7 | import "../libs/SafeERC20.sol"; 8 | 9 | 10 | /** 11 | * @title An Avatar holds tokens, reputation and ether for a controller 12 | */ 13 | contract Avatar is Ownable { 14 | using SafeERC20 for address; 15 | 16 | string public orgName; 17 | DAOToken public nativeToken; 18 | Reputation public nativeReputation; 19 | 20 | event GenericCall(address indexed _contract, bytes _data, uint _value, bool _success); 21 | event SendEther(uint256 _amountInWei, address indexed _to); 22 | event ExternalTokenTransfer(address indexed _externalToken, address indexed _to, uint256 _value); 23 | event ExternalTokenTransferFrom(address indexed _externalToken, address _from, address _to, uint256 _value); 24 | event ExternalTokenApproval(address indexed _externalToken, address _spender, uint256 _value); 25 | event ReceiveEther(address indexed _sender, uint256 _value); 26 | event MetaData(string _metaData); 27 | 28 | /** 29 | * @dev the constructor takes organization name, native token and reputation system 30 | and creates an avatar for a controller 31 | */ 32 | constructor(string memory _orgName, DAOToken _nativeToken, Reputation _nativeReputation) public { 33 | orgName = _orgName; 34 | nativeToken = _nativeToken; 35 | nativeReputation = _nativeReputation; 36 | } 37 | 38 | /** 39 | * @dev enables an avatar to receive ethers 40 | */ 41 | function() external payable { 42 | emit ReceiveEther(msg.sender, msg.value); 43 | } 44 | 45 | /** 46 | * @dev perform a generic call to an arbitrary contract 47 | * @param _contract the contract's address to call 48 | * @param _data ABI-encoded contract call to call `_contract` address. 49 | * @param _value value (ETH) to transfer with the transaction 50 | * @return bool success or fail 51 | * bytes - the return bytes of the called contract's function. 52 | */ 53 | function genericCall(address _contract, bytes memory _data, uint256 _value) 54 | public 55 | onlyOwner 56 | returns(bool success, bytes memory returnValue) { 57 | // solhint-disable-next-line avoid-call-value 58 | (success, returnValue) = _contract.call.value(_value)(_data); 59 | emit GenericCall(_contract, _data, _value, success); 60 | } 61 | 62 | /** 63 | * @dev send ethers from the avatar's wallet 64 | * @param _amountInWei amount to send in Wei units 65 | * @param _to send the ethers to this address 66 | * @return bool which represents success 67 | */ 68 | function sendEther(uint256 _amountInWei, address payable _to) public onlyOwner returns(bool) { 69 | _to.transfer(_amountInWei); 70 | emit SendEther(_amountInWei, _to); 71 | return true; 72 | } 73 | 74 | /** 75 | * @dev external token transfer 76 | * @param _externalToken the token contract 77 | * @param _to the destination address 78 | * @param _value the amount of tokens to transfer 79 | * @return bool which represents success 80 | */ 81 | function externalTokenTransfer(IERC20 _externalToken, address _to, uint256 _value) 82 | public onlyOwner returns(bool) 83 | { 84 | address(_externalToken).safeTransfer(_to, _value); 85 | emit ExternalTokenTransfer(address(_externalToken), _to, _value); 86 | return true; 87 | } 88 | 89 | /** 90 | * @dev external token transfer from a specific account 91 | * @param _externalToken the token contract 92 | * @param _from the account to spend token from 93 | * @param _to the destination address 94 | * @param _value the amount of tokens to transfer 95 | * @return bool which represents success 96 | */ 97 | function externalTokenTransferFrom( 98 | IERC20 _externalToken, 99 | address _from, 100 | address _to, 101 | uint256 _value 102 | ) 103 | public onlyOwner returns(bool) 104 | { 105 | address(_externalToken).safeTransferFrom(_from, _to, _value); 106 | emit ExternalTokenTransferFrom(address(_externalToken), _from, _to, _value); 107 | return true; 108 | } 109 | 110 | /** 111 | * @dev externalTokenApproval approve the spender address to spend a specified amount of tokens 112 | * on behalf of msg.sender. 113 | * @param _externalToken the address of the Token Contract 114 | * @param _spender address 115 | * @param _value the amount of ether (in Wei) which the approval is referring to. 116 | * @return bool which represents a success 117 | */ 118 | function externalTokenApproval(IERC20 _externalToken, address _spender, uint256 _value) 119 | public onlyOwner returns(bool) 120 | { 121 | address(_externalToken).safeApprove(_spender, _value); 122 | emit ExternalTokenApproval(address(_externalToken), _spender, _value); 123 | return true; 124 | } 125 | 126 | /** 127 | * @dev metaData emits an event with a string, should contain the hash of some meta data. 128 | * @param _metaData a string representing a hash of the meta data 129 | * @return bool which represents a success 130 | */ 131 | function metaData(string memory _metaData) public onlyOwner returns(bool) { 132 | emit MetaData(_metaData); 133 | return true; 134 | } 135 | 136 | 137 | } 138 | -------------------------------------------------------------------------------- /contracts/controller/DAOToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "openzeppelin-solidity/contracts/token/ERC20/ERC20Burnable.sol"; 4 | import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; 5 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 6 | 7 | 8 | /** 9 | * @title DAOToken, base on zeppelin contract. 10 | * @dev ERC20 compatible token. It is a mintable, burnable token. 11 | */ 12 | 13 | contract DAOToken is ERC20, ERC20Burnable, Ownable { 14 | 15 | string public name; 16 | string public symbol; 17 | // solhint-disable-next-line const-name-snakecase 18 | uint8 public constant decimals = 18; 19 | uint256 public cap; 20 | 21 | /** 22 | * @dev Constructor 23 | * @param _name - token name 24 | * @param _symbol - token symbol 25 | * @param _cap - token cap - 0 value means no cap 26 | */ 27 | constructor(string memory _name, string memory _symbol, uint256 _cap) 28 | public { 29 | name = _name; 30 | symbol = _symbol; 31 | cap = _cap; 32 | } 33 | 34 | /** 35 | * @dev Function to mint tokens 36 | * @param _to The address that will receive the minted tokens. 37 | * @param _amount The amount of tokens to mint. 38 | */ 39 | function mint(address _to, uint256 _amount) public onlyOwner returns (bool) { 40 | if (cap > 0) 41 | require(totalSupply().add(_amount) <= cap); 42 | _mint(_to, _amount); 43 | return true; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /contracts/globalConstraints/GlobalConstraintInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | 4 | contract GlobalConstraintInterface { 5 | 6 | enum CallPhase { Pre, Post, PreAndPost } 7 | 8 | function pre( address _scheme, bytes32 _params, bytes32 _method ) public returns(bool); 9 | function post( address _scheme, bytes32 _params, bytes32 _method ) public returns(bool); 10 | /** 11 | * @dev when return if this globalConstraints is pre, post or both. 12 | * @return CallPhase enum indication Pre, Post or PreAndPost. 13 | */ 14 | function when() public returns(CallPhase); 15 | } 16 | -------------------------------------------------------------------------------- /contracts/globalConstraints/TokenCapGC.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; 4 | import "./GlobalConstraintInterface.sol"; 5 | 6 | 7 | /** 8 | * @title Token Cap Global Constraint 9 | * @dev A simple global constraint to cap the number of tokens. 10 | */ 11 | 12 | contract TokenCapGC { 13 | // A set of parameters, on which the cap will be checked: 14 | struct Parameters { 15 | IERC20 token; 16 | uint256 cap; 17 | } 18 | 19 | // Mapping from the hash of the parameters to the parameters themselves: 20 | mapping (bytes32=>Parameters) public parameters; 21 | 22 | /** 23 | * @dev adding a new set of parameters 24 | * @param _token the token to add to the params. 25 | * @param _cap the cap to check the total supply against. 26 | * @return the calculated parameters hash 27 | */ 28 | function setParameters(IERC20 _token, uint256 _cap) public returns(bytes32) { 29 | bytes32 paramsHash = getParametersHash(_token, _cap); 30 | parameters[paramsHash].token = _token; 31 | parameters[paramsHash].cap = _cap; 32 | return paramsHash; 33 | } 34 | 35 | /** 36 | * @dev calculate and returns the hash of the given parameters 37 | * @param _token the token to add to the params. 38 | * @param _cap the cap to check the total supply against. 39 | * @return the calculated parameters hash 40 | */ 41 | function getParametersHash(IERC20 _token, uint256 _cap) public pure returns(bytes32) { 42 | return (keccak256(abi.encodePacked(_token, _cap))); 43 | } 44 | 45 | /** 46 | * @dev check the constraint after the action. 47 | * This global constraint only checks the state after the action, so here we just return true: 48 | * @return true 49 | */ 50 | function pre(address, bytes32, bytes32) public pure returns(bool) { 51 | return true; 52 | } 53 | 54 | /** 55 | * @dev check the total supply cap. 56 | * @param _paramsHash the parameters hash to check the total supply cap against. 57 | * @return bool which represents a success 58 | */ 59 | function post(address, bytes32 _paramsHash, bytes32) public view returns(bool) { 60 | if ((parameters[_paramsHash].token != IERC20(0)) && 61 | (parameters[_paramsHash].token.totalSupply() > parameters[_paramsHash].cap)) { 62 | return false; 63 | } 64 | return true; 65 | } 66 | 67 | /** 68 | * @dev when return if this globalConstraints is pre, post or both. 69 | * @return CallPhase enum indication Pre, Post or PreAndPost. 70 | */ 71 | function when() public pure returns(GlobalConstraintInterface.CallPhase) { 72 | return GlobalConstraintInterface.CallPhase.Post; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /contracts/libs/SafeERC20.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | SafeERC20 by daostack. 4 | The code is based on a fix by SECBIT Team. 5 | 6 | USE WITH CAUTION & NO WARRANTY 7 | 8 | REFERENCE & RELATED READING 9 | - https://github.com/ethereum/solidity/issues/4116 10 | - https://medium.com/@chris_77367/explaining-unexpected-reverts-starting-with-solidity-0-4-22-3ada6e82308c 11 | - https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca 12 | - https://gist.github.com/BrendanChou/88a2eeb80947ff00bcf58ffdafeaeb61 13 | 14 | */ 15 | pragma solidity 0.5.17; 16 | 17 | import "openzeppelin-solidity/contracts/utils/Address.sol"; 18 | import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; 19 | 20 | library SafeERC20 { 21 | using Address for address; 22 | 23 | bytes4 constant private TRANSFER_SELECTOR = bytes4(keccak256(bytes("transfer(address,uint256)"))); 24 | bytes4 constant private TRANSFERFROM_SELECTOR = bytes4(keccak256(bytes("transferFrom(address,address,uint256)"))); 25 | bytes4 constant private APPROVE_SELECTOR = bytes4(keccak256(bytes("approve(address,uint256)"))); 26 | 27 | function safeTransfer(address _erc20Addr, address _to, uint256 _value) internal { 28 | 29 | // Must be a contract addr first! 30 | require(_erc20Addr.isContract()); 31 | 32 | (bool success, bytes memory returnValue) = 33 | // solhint-disable-next-line avoid-low-level-calls 34 | _erc20Addr.call(abi.encodeWithSelector(TRANSFER_SELECTOR, _to, _value)); 35 | // call return false when something wrong 36 | require(success); 37 | //check return value 38 | require(returnValue.length == 0 || (returnValue.length == 32 && (returnValue[31] != 0))); 39 | } 40 | 41 | function safeTransferFrom(address _erc20Addr, address _from, address _to, uint256 _value) internal { 42 | 43 | // Must be a contract addr first! 44 | require(_erc20Addr.isContract()); 45 | 46 | (bool success, bytes memory returnValue) = 47 | // solhint-disable-next-line avoid-low-level-calls 48 | _erc20Addr.call(abi.encodeWithSelector(TRANSFERFROM_SELECTOR, _from, _to, _value)); 49 | // call return false when something wrong 50 | require(success); 51 | //check return value 52 | require(returnValue.length == 0 || (returnValue.length == 32 && (returnValue[31] != 0))); 53 | } 54 | 55 | function safeApprove(address _erc20Addr, address _spender, uint256 _value) internal { 56 | 57 | // Must be a contract addr first! 58 | require(_erc20Addr.isContract()); 59 | 60 | // safeApprove should only be called when setting an initial allowance, 61 | // or when resetting it to zero. 62 | require((_value == 0) || (IERC20(_erc20Addr).allowance(address(this), _spender) == 0)); 63 | 64 | (bool success, bytes memory returnValue) = 65 | // solhint-disable-next-line avoid-low-level-calls 66 | _erc20Addr.call(abi.encodeWithSelector(APPROVE_SELECTOR, _spender, _value)); 67 | // call return false when something wrong 68 | require(success); 69 | //check return value 70 | require(returnValue.length == 0 || (returnValue.length == 32 && (returnValue[31] != 0))); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /contracts/schemes/Agreement.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | /** 4 | * @title A scheme for conduct ERC20 Tokens auction for reputation 5 | */ 6 | 7 | 8 | contract Agreement { 9 | 10 | bytes32 private agreementHash; 11 | 12 | modifier onlyAgree(bytes32 _agreementHash) { 13 | require(_agreementHash == agreementHash, "Sender must send the right agreementHash"); 14 | _; 15 | } 16 | 17 | /** 18 | * @dev getAgreementHash 19 | * @return bytes32 agreementHash 20 | */ 21 | function getAgreementHash() external view returns(bytes32) 22 | { 23 | return agreementHash; 24 | } 25 | 26 | /** 27 | * @dev setAgreementHash 28 | * @param _agreementHash is a hash of agreement required to be added to the TX by participants 29 | */ 30 | function setAgreementHash(bytes32 _agreementHash) internal 31 | { 32 | require(agreementHash == bytes32(0), "Can not set agreement twice"); 33 | agreementHash = _agreementHash; 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /contracts/schemes/CurveInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | interface CurveInterface { 4 | 5 | function calc(uint) external pure returns (uint); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /contracts/schemes/ExternalLocking4Reputation.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "./Locking4Reputation.sol"; 4 | 5 | /** 6 | * @title A scheme for external locking Tokens for reputation 7 | */ 8 | 9 | contract ExternalLocking4Reputation is Locking4Reputation { 10 | 11 | event Register(address indexed _beneficiary); 12 | 13 | address public externalLockingContract; 14 | string public getBalanceFuncSignature; 15 | 16 | // locker -> bool 17 | mapping(address => bool) public externalLockers; 18 | // beneficiary -> bool 19 | mapping(address => bool) public registrar; 20 | 21 | /** 22 | * @dev initialize 23 | * @param _avatar the avatar to mint reputation from 24 | * @param _reputationReward the total reputation this contract will reward 25 | * for the token locking 26 | * @param _claimingStartTime claiming starting period time. 27 | * @param _claimingEndTime the claiming end time. 28 | * claiming is disable after this time. 29 | * @param _redeemEnableTime redeem enable time . 30 | * redeem reputation can be done after this time. 31 | * @param _externalLockingContract the contract which lock the token. 32 | * @param _getBalanceFuncSignature get balance function signature 33 | * e.g "lockedTokenBalances(address)" 34 | */ 35 | function initialize( 36 | Avatar _avatar, 37 | uint256 _reputationReward, 38 | uint256 _claimingStartTime, 39 | uint256 _claimingEndTime, 40 | uint256 _redeemEnableTime, 41 | address _externalLockingContract, 42 | string calldata _getBalanceFuncSignature, 43 | bytes32 _agreementHash) 44 | external 45 | { 46 | require(_claimingEndTime > _claimingStartTime, "_claimingEndTime should be greater than _claimingStartTime"); 47 | externalLockingContract = _externalLockingContract; 48 | getBalanceFuncSignature = _getBalanceFuncSignature; 49 | super._initialize( 50 | _avatar, 51 | _reputationReward, 52 | _claimingStartTime, 53 | _claimingEndTime, 54 | _redeemEnableTime, 55 | 1, 56 | _agreementHash); 57 | } 58 | 59 | /** 60 | * @dev claim function 61 | * @param _beneficiary the beneficiary address to claim for 62 | * if _beneficiary == 0 the claim will be for the msg.sender. 63 | * @return claimId 64 | */ 65 | function claim(address _beneficiary, bytes32 _agreementHash) public returns(bytes32) { 66 | require(avatar != Avatar(0), "should initialize first"); 67 | address beneficiary; 68 | if (_beneficiary == address(0)) { 69 | beneficiary = msg.sender; 70 | } else { 71 | require(registrar[_beneficiary], "beneficiary should be register"); 72 | beneficiary = _beneficiary; 73 | } 74 | require(externalLockers[beneficiary] == false, "claiming twice for the same beneficiary is not allowed"); 75 | externalLockers[beneficiary] = true; 76 | (bool result, bytes memory returnValue) = 77 | // solhint-disable-next-line avoid-call-value,avoid-low-level-calls 78 | externalLockingContract.call(abi.encodeWithSignature(getBalanceFuncSignature, beneficiary)); 79 | require(result, "call to external contract should succeed"); 80 | uint256 lockedAmount; 81 | // solhint-disable-next-line no-inline-assembly 82 | assembly { 83 | lockedAmount := mload(add(returnValue, 0x20)) 84 | } 85 | return super._lock(lockedAmount, 1, beneficiary, 1, 1, _agreementHash); 86 | } 87 | 88 | /** 89 | * @dev register function 90 | * register for external locking claim 91 | */ 92 | function register(bytes32 _agreementHash) public onlyAgree(_agreementHash) { 93 | registrar[msg.sender] = true; 94 | emit Register(msg.sender); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /contracts/schemes/FixedReputationAllocation.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../controller/Controller.sol"; 4 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 5 | 6 | 7 | /** 8 | * @title A fixed reputation allocation contract 9 | * This scheme can be used to allocate a pre define amount of reputation to whitelisted 10 | * beneficiaries. 11 | */ 12 | contract FixedReputationAllocation is Ownable { 13 | using SafeMath for uint256; 14 | 15 | event Redeem(address indexed _beneficiary, uint256 _amount); 16 | event BeneficiaryAddressAdded(address indexed _beneficiary); 17 | 18 | // beneficiary -> exist 19 | mapping(address => bool) public beneficiaries; 20 | 21 | Avatar public avatar; 22 | uint256 public reputationReward; 23 | bool public isEnable; 24 | uint256 public numberOfBeneficiaries; 25 | uint256 public beneficiaryReward; 26 | uint256 public redeemEnableTime; 27 | 28 | /** 29 | * @dev initialize 30 | * @param _avatar the avatar to mint reputation from 31 | * @param _reputationReward the total reputation this contract will reward 32 | * @param _redeemEnableTime time to enable redeem 33 | */ 34 | function initialize(Avatar _avatar, uint256 _reputationReward, uint256 _redeemEnableTime) external onlyOwner { 35 | require(avatar == Avatar(0), "can be called only one time"); 36 | require(_avatar != Avatar(0), "avatar cannot be zero"); 37 | reputationReward = _reputationReward; 38 | redeemEnableTime = _redeemEnableTime; 39 | avatar = _avatar; 40 | } 41 | 42 | /** 43 | * @dev redeem reputation function 44 | * @param _beneficiary the beneficiary for the release 45 | * @return bool 46 | */ 47 | function redeem(address _beneficiary) public returns(bool) { 48 | require(isEnable, "require to be enable"); 49 | require(beneficiaries[_beneficiary], "require _beneficiary to exist in the beneficiaries map"); 50 | beneficiaries[_beneficiary] = false; 51 | // solhint-disable-next-line not-rely-on-time 52 | require(now > redeemEnableTime, "require now > redeemEnableTime"); 53 | require( 54 | Controller( 55 | avatar.owner()) 56 | .mintReputation(beneficiaryReward, _beneficiary, address(avatar)), "mint reputation failed"); 57 | 58 | emit Redeem(_beneficiary, beneficiaryReward); 59 | 60 | return true; 61 | } 62 | 63 | /** 64 | * @dev addBeneficiary function 65 | * @param _beneficiary to be whitelisted 66 | */ 67 | function addBeneficiary(address _beneficiary) public onlyOwner { 68 | require(!isEnable, "can add beneficiary only if not already enable"); 69 | 70 | if (!beneficiaries[_beneficiary]) { 71 | beneficiaries[_beneficiary] = true; 72 | numberOfBeneficiaries++; 73 | 74 | emit BeneficiaryAddressAdded(_beneficiary); 75 | } 76 | } 77 | 78 | /** 79 | * @dev add addBeneficiaries function 80 | * @param _beneficiaries addresses 81 | */ 82 | function addBeneficiaries(address[] memory _beneficiaries) public onlyOwner { 83 | for (uint256 i = 0; i < _beneficiaries.length; i++) { 84 | addBeneficiary(_beneficiaries[i]); 85 | } 86 | } 87 | 88 | /** 89 | * @dev enable function 90 | */ 91 | function enable() public onlyOwner { 92 | isEnable = true; 93 | // Calculate beneficiary reward 94 | beneficiaryReward = reputationReward.div(numberOfBeneficiaries); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /contracts/schemes/Forwarder.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../controller/Controller.sol"; 4 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 5 | 6 | /** 7 | * @title A scheme to forward a call to a dao. 8 | * The scheme can unregister itself when its expirationTime reached. 9 | */ 10 | 11 | 12 | contract Forwarder is Ownable { 13 | 14 | Avatar public avatar; 15 | uint256 public expirationTime; 16 | 17 | /** 18 | * @dev forwardCall forward a call to the dao controller 19 | */ 20 | // solhint-disable-next-line no-complex-fallback,payable-fallback 21 | function () external onlyOwner { 22 | // solhint-disable-next-line not-rely-on-time 23 | require(expirationTime > now, "expirationTime > now"); 24 | // solhint-disable-next-line avoid-low-level-calls 25 | (bool result,) = avatar.owner().call(msg.data); 26 | require(result); 27 | } 28 | 29 | /** 30 | * @dev initialize 31 | * @param _avatar the avatar of the dao to forward the call to 32 | * @param _expirationTime the expirationTime to forwardCall 33 | */ 34 | function initialize(Avatar _avatar, uint256 _expirationTime) external onlyOwner { 35 | require(avatar == Avatar(0), "can be called only one time"); 36 | require(_avatar != Avatar(0), "avatar cannot be zero"); 37 | avatar = _avatar; 38 | expirationTime = _expirationTime; 39 | } 40 | 41 | /** 42 | * @dev unregisterSelf function 43 | * @return bool 44 | */ 45 | function unregisterSelf() public returns(bool) { 46 | // solhint-disable-next-line not-rely-on-time 47 | require(expirationTime <= now, "expirationTime <= now"); 48 | return Controller(avatar.owner()).unregisterSelf(address(avatar)); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /contracts/schemes/LockingEth4Reputation.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "./Locking4Reputation.sol"; 4 | 5 | /** 6 | * @title A scheme for locking ETH for reputation 7 | */ 8 | 9 | contract LockingEth4Reputation is Locking4Reputation { 10 | 11 | /** 12 | * @dev initialize 13 | * @param _avatar the avatar to mint reputation from 14 | * @param _reputationReward the total reputation this contract will reward 15 | * for eth locking 16 | * @param _lockingStartTime locking starting period time. 17 | * @param _lockingEndTime the locking end time. 18 | * locking is disable after this time. 19 | * @param _redeemEnableTime redeem enable time . 20 | * redeem reputation can be done after this time. 21 | * @param _maxLockingPeriod maximum locking period allowed. 22 | */ 23 | function initialize( 24 | Avatar _avatar, 25 | uint256 _reputationReward, 26 | uint256 _lockingStartTime, 27 | uint256 _lockingEndTime, 28 | uint256 _redeemEnableTime, 29 | uint256 _maxLockingPeriod, 30 | bytes32 _agreementHash ) 31 | external 32 | { 33 | super._initialize( 34 | _avatar, 35 | _reputationReward, 36 | _lockingStartTime, 37 | _lockingEndTime, 38 | _redeemEnableTime, 39 | _maxLockingPeriod, 40 | _agreementHash); 41 | } 42 | 43 | /** 44 | * @dev release locked eth 45 | * @param _beneficiary the release _beneficiary 46 | * @param _lockingId the locking id 47 | * @return bool 48 | */ 49 | function release(address payable _beneficiary, bytes32 _lockingId) public returns(bool) { 50 | uint256 amount = super._release(_beneficiary, _lockingId); 51 | _beneficiary.transfer(amount); 52 | 53 | return true; 54 | } 55 | 56 | /** 57 | * @dev lock function 58 | * @param _period the locking period 59 | * @return lockingId the unique Id 60 | */ 61 | function lock(uint256 _period, bytes32 _agreementHash) public payable returns(bytes32 lockingId) { 62 | return super._lock(msg.value, _period, msg.sender, 1, 1, _agreementHash); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /contracts/schemes/LockingToken4Reputation.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "./Locking4Reputation.sol"; 4 | import "./PriceOracleInterface.sol"; 5 | import "../libs/SafeERC20.sol"; 6 | 7 | 8 | /** 9 | * @title A scheme for locking ERC20 Tokens for reputation 10 | */ 11 | 12 | contract LockingToken4Reputation is Locking4Reputation { 13 | using SafeERC20 for address; 14 | 15 | PriceOracleInterface public priceOracleContract; 16 | // lockingId => token 17 | mapping(bytes32 => address) public lockedTokens; 18 | 19 | event LockToken(bytes32 indexed _lockingId, address indexed _token, uint256 _numerator, uint256 _denominator); 20 | 21 | /** 22 | * @dev initialize 23 | * @param _avatar the avatar to mint reputation from 24 | * @param _reputationReward the total reputation this contract will reward 25 | * for the token locking 26 | * @param _lockingStartTime locking starting period time. 27 | * @param _lockingEndTime the locking end time. 28 | * locking is disable after this time. 29 | * @param _redeemEnableTime redeem enable time . 30 | * redeem reputation can be done after this time. 31 | * @param _maxLockingPeriod maximum locking period allowed. 32 | * @param _priceOracleContract the price oracle contract which the locked token will be 33 | * validated against 34 | */ 35 | function initialize( 36 | Avatar _avatar, 37 | uint256 _reputationReward, 38 | uint256 _lockingStartTime, 39 | uint256 _lockingEndTime, 40 | uint256 _redeemEnableTime, 41 | uint256 _maxLockingPeriod, 42 | PriceOracleInterface _priceOracleContract, 43 | bytes32 _agreementHash) 44 | external 45 | { 46 | priceOracleContract = _priceOracleContract; 47 | super._initialize( 48 | _avatar, 49 | _reputationReward, 50 | _lockingStartTime, 51 | _lockingEndTime, 52 | _redeemEnableTime, 53 | _maxLockingPeriod, 54 | _agreementHash); 55 | } 56 | 57 | /** 58 | * @dev release locked tokens 59 | * @param _beneficiary the release _beneficiary 60 | * @param _lockingId the locking id 61 | * @return bool 62 | */ 63 | function release(address _beneficiary, bytes32 _lockingId) public returns(bool) { 64 | uint256 amount = super._release(_beneficiary, _lockingId); 65 | lockedTokens[_lockingId].safeTransfer(_beneficiary, amount); 66 | 67 | return true; 68 | } 69 | 70 | /** 71 | * @dev lock function 72 | * @param _amount the amount to lock 73 | * @param _period the locking period 74 | * @param _token the token to lock - this should be whitelisted at the priceOracleContract 75 | * @return lockingId 76 | */ 77 | function lock(uint256 _amount, 78 | uint256 _period, 79 | address _token, 80 | bytes32 _agreementHash) 81 | public returns(bytes32 lockingId) { 82 | 83 | uint256 numerator; 84 | uint256 denominator; 85 | 86 | (numerator, denominator) = priceOracleContract.getPrice(_token); 87 | 88 | require(numerator > 0, "numerator should be > 0"); 89 | require(denominator > 0, "denominator should be > 0"); 90 | 91 | _token.safeTransferFrom(msg.sender, address(this), _amount); 92 | 93 | lockingId = super._lock(_amount, _period, msg.sender, numerator, denominator, _agreementHash); 94 | 95 | lockedTokens[lockingId] = _token; 96 | 97 | emit LockToken(lockingId, _token, numerator, denominator); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /contracts/schemes/PriceOracleInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | interface PriceOracleInterface { 4 | 5 | function getPrice(address token) external view returns (uint, uint); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /contracts/schemes/RageQuitWithToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "openzeppelin-solidity/contracts/math/SafeMath.sol"; 4 | import "../controller/Controller.sol"; 5 | 6 | 7 | /** 8 | * @title A scheme to rage quit from a dao with token. 9 | * by sending the dao native token to the RageQuit function the sender will get is proportional share of the dao 10 | * rageQuitToken (DAI in most case) 11 | */ 12 | contract RageQuitWithToken { 13 | using SafeMath for uint256; 14 | 15 | event RageQuit( 16 | address indexed _avatar, 17 | address indexed _rageQuitter, 18 | uint256 indexed _refund 19 | ); 20 | 21 | Avatar public avatar; 22 | IERC20 public rageQuitToken; //the token which is given back for rageQuit - DAI in most cases 23 | 24 | /** 25 | * @dev initialize 26 | * @param _avatar the avatar this scheme referring to. 27 | * @param _rageQuitToken the token which is given back for rageQuit - DAI in most 28 | */ 29 | function initialize( 30 | Avatar _avatar, 31 | IERC20 _rageQuitToken 32 | ) 33 | external 34 | { 35 | require(_avatar != Avatar(0), "avatar cannot be zero"); 36 | require(avatar == Avatar(0), "cannot initialize twice"); 37 | avatar = _avatar; 38 | rageQuitToken = _rageQuitToken; 39 | } 40 | 41 | /** 42 | * @dev rageQuit quit from the dao. 43 | * @param _amountToRageQuitWith amount of native token to rageQuit with. 44 | * @return refund the refund amount 45 | */ 46 | function rageQuit(uint256 _amountToRageQuitWith) external returns(uint256 refund) { 47 | uint256 totalTokenSupply = avatar.nativeToken().totalSupply(); 48 | uint256 rageQuitTokenTotalSupply = rageQuitToken.balanceOf(address(avatar)); 49 | refund = _amountToRageQuitWith.mul(rageQuitTokenTotalSupply).div(totalTokenSupply); 50 | //this will revert if the msg.sender token balance is less than _amountToRageQuitWith. 51 | avatar.nativeToken().burnFrom(msg.sender, _amountToRageQuitWith); 52 | require( 53 | Controller( 54 | avatar.owner()).externalTokenTransfer(rageQuitToken, msg.sender, refund, avatar), "send token failed"); 55 | emit RageQuit(address(avatar), msg.sender, refund); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /contracts/schemes/ReputationAdmin.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 4 | import "openzeppelin-solidity/contracts/math/SafeMath.sol"; 5 | import "../controller/Controller.sol"; 6 | 7 | /** 8 | * @title A scheme for reputation minting/burning by an authorized account 9 | */ 10 | 11 | contract ReputationAdmin is Ownable { 12 | using SafeMath for uint256; 13 | 14 | Avatar public avatar; 15 | uint256 public activationStartTime; 16 | uint256 public activationEndTime; 17 | uint256 public repRewardLeft; 18 | uint256 public limitRepReward; 19 | 20 | /** 21 | * @dev initialize 22 | * @param _avatar the avatar to mint reputation from 23 | * @param _activationStartTime start time for allowing minting 24 | * @param _activationEndTime end time for allowing minting 25 | * @param _maxRepReward maximum reputation mintable by this scheme 26 | */ 27 | function initialize( 28 | Avatar _avatar, 29 | uint256 _activationStartTime, 30 | uint256 _activationEndTime, 31 | uint256 _maxRepReward 32 | ) external onlyOwner { 33 | require(avatar == Avatar(0), "can be called only one time"); 34 | require(_avatar != Avatar(0), "avatar cannot be zero"); 35 | require(_activationStartTime < _activationEndTime, "_activationStartTime < _activationEndTime"); 36 | avatar = _avatar; 37 | activationStartTime = _activationStartTime; 38 | activationEndTime = _activationEndTime; 39 | repRewardLeft = _maxRepReward; 40 | limitRepReward = _maxRepReward; 41 | } 42 | 43 | /** 44 | * @dev reputationBurn function 45 | * @param _beneficiaries the beneficiaries address to mint reputation from 46 | * @param _amounts the amounts of reputation to mint for beneficiaries 47 | */ 48 | function reputationMint(address[] calldata _beneficiaries, uint256[] calldata _amounts) external onlyOwner { 49 | require(_beneficiaries.length == _amounts.length, "Arrays length mismatch"); 50 | for (uint256 i=0; i < _beneficiaries.length; i++) { 51 | _reputationMint(_beneficiaries[i], _amounts[i]); 52 | } 53 | } 54 | 55 | /** 56 | * @dev reputationBurn function 57 | * @param _beneficiaries the beneficiaries address to burm reputation from 58 | * @param _amounts the amounts of reputation to burn for beneficiaries 59 | */ 60 | function reputationBurn(address[] calldata _beneficiaries, uint256[] calldata _amounts) external onlyOwner { 61 | require(_beneficiaries.length == _amounts.length, "Arrays length mismatch"); 62 | for (uint256 i=0; i < _beneficiaries.length; i++) { 63 | _reputationBurn(_beneficiaries[i], _amounts[i]); 64 | } 65 | } 66 | 67 | /** 68 | * @dev reputationMint function 69 | * @param _beneficiary the beneficiary address to mint reputation for 70 | * @param _amount the amount of reputation to mint the the beneficirary 71 | */ 72 | function _reputationMint(address _beneficiary, uint256 _amount) private { 73 | // solhint-disable-next-line not-rely-on-time 74 | require(now >= activationStartTime, "Minting period did not start yet"); 75 | // solhint-disable-next-line not-rely-on-time 76 | require(now < activationEndTime, "Minting period ended."); 77 | 78 | if (limitRepReward > 0) { 79 | repRewardLeft = repRewardLeft.sub(_amount); 80 | } 81 | 82 | require( 83 | Controller(avatar.owner()).mintReputation(_amount, _beneficiary, address(avatar)), 84 | "Minting reputation should succeed" 85 | ); 86 | } 87 | 88 | /** 89 | * @dev reputationBurn function 90 | * @param _beneficiary the beneficiary address to burm reputation from 91 | * @param _amount the amount of reputation to burn for a beneficirary 92 | */ 93 | function _reputationBurn(address _beneficiary, uint256 _amount) private { 94 | // solhint-disable-next-line not-rely-on-time 95 | require(now >= activationStartTime, "Burning period did not start yet"); 96 | // solhint-disable-next-line not-rely-on-time 97 | require(now < activationEndTime, "Burning period ended."); 98 | 99 | if (limitRepReward > 0) { 100 | require(_amount <= limitRepReward.sub(repRewardLeft), "Cannot burn more than minted"); 101 | repRewardLeft = repRewardLeft.add(_amount); 102 | } 103 | 104 | require( 105 | Controller(avatar.owner()).burnReputation(_amount, _beneficiary, address(avatar)), 106 | "Burn reputation should succeed" 107 | ); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /contracts/schemes/ReputationFromToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../controller/Controller.sol"; 4 | import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; 5 | import "./CurveInterface.sol"; 6 | import "openzeppelin-solidity/contracts/cryptography/ECDSA.sol"; 7 | import "openzeppelin-solidity/contracts/math/SafeMath.sol"; 8 | import "./Agreement.sol"; 9 | 10 | /** 11 | * @title A scheme for reputation allocation according to token balances 12 | * This contract is assuming that the token contract is paused, and one cannot transfer its tokens. 13 | */ 14 | 15 | contract ReputationFromToken is Agreement { 16 | using ECDSA for bytes32; 17 | using SafeMath for uint256; 18 | 19 | IERC20 public tokenContract; 20 | CurveInterface public curve; 21 | // beneficiary -> bool 22 | mapping(address => bool) public redeems; 23 | Avatar public avatar; 24 | 25 | // Digest describing the data the user signs according EIP 712. 26 | // Needs to match what is passed to Metamask. 27 | bytes32 public constant DELEGATION_HASH_EIP712 = 28 | keccak256(abi.encodePacked( 29 | "address ReputationFromTokenAddress", 30 | "address Beneficiary", 31 | "bytes32 AgreementHash" 32 | )); 33 | 34 | event Redeem(address indexed _beneficiary, address indexed _sender, uint256 _amount); 35 | 36 | /** 37 | * @dev initialize 38 | * @param _avatar the avatar to mint reputation from 39 | * @param _tokenContract the token contract 40 | * @param _agreementHash is a hash of agreement required to be added to the TX by participants 41 | */ 42 | function initialize(Avatar _avatar, IERC20 _tokenContract, CurveInterface _curve, bytes32 _agreementHash) external 43 | { 44 | require(avatar == Avatar(0), "can be called only one time"); 45 | require(_avatar != Avatar(0), "avatar cannot be zero"); 46 | tokenContract = _tokenContract; 47 | avatar = _avatar; 48 | curve = _curve; 49 | super.setAgreementHash(_agreementHash); 50 | } 51 | 52 | /** 53 | * @dev redeem function 54 | * @param _beneficiary the beneficiary address to redeem for 55 | * @param _agreementHash the agreementHash hash 56 | * @return uint256 minted reputation 57 | */ 58 | function redeem(address _beneficiary, bytes32 _agreementHash) external returns(uint256) { 59 | return _redeem(_beneficiary, msg.sender, _agreementHash); 60 | } 61 | 62 | /** 63 | * @dev redeemWithSignature function 64 | * @param _beneficiary the beneficiary address to redeem for 65 | * @param _signatureType signature type 66 | 1 - for web3.eth.sign 67 | 2 - for eth_signTypedData according to EIP #712. 68 | * @param _signature - signed data by the staker 69 | * @return uint256 minted reputation 70 | */ 71 | function redeemWithSignature( 72 | address _beneficiary, 73 | bytes32 _agreementHash, 74 | uint256 _signatureType, 75 | bytes calldata _signature 76 | ) 77 | external 78 | returns(uint256) 79 | { 80 | // Recreate the digest the user signed 81 | bytes32 delegationDigest; 82 | if (_signatureType == 2) { 83 | delegationDigest = keccak256( 84 | abi.encodePacked( 85 | DELEGATION_HASH_EIP712, keccak256( 86 | abi.encodePacked( 87 | address(this), 88 | _beneficiary, 89 | _agreementHash) 90 | ) 91 | ) 92 | ); 93 | } else { 94 | delegationDigest = keccak256( 95 | abi.encodePacked( 96 | address(this), 97 | _beneficiary, 98 | _agreementHash) 99 | ).toEthSignedMessageHash(); 100 | } 101 | address redeemer = delegationDigest.recover(_signature); 102 | require(redeemer != address(0), "redeemer address cannot be 0"); 103 | return _redeem(_beneficiary, redeemer, _agreementHash); 104 | } 105 | 106 | /** 107 | * @dev redeem function 108 | * @param _beneficiary the beneficiary address to redeem for 109 | * @param _redeemer the redeemer address 110 | * @return uint256 minted reputation 111 | */ 112 | function _redeem(address _beneficiary, address _redeemer, bytes32 _agreementHash) 113 | private 114 | onlyAgree(_agreementHash) 115 | returns(uint256) { 116 | require(avatar != Avatar(0), "should initialize first"); 117 | require(redeems[_redeemer] == false, "redeeming twice from the same account is not allowed"); 118 | redeems[_redeemer] = true; 119 | uint256 tokenAmount = tokenContract.balanceOf(_redeemer); 120 | if (curve != CurveInterface(0)) { 121 | tokenAmount = curve.calc(tokenAmount); 122 | } 123 | if (_beneficiary == address(0)) { 124 | _beneficiary = _redeemer; 125 | } 126 | require( 127 | Controller( 128 | avatar.owner()) 129 | .mintReputation(tokenAmount, _beneficiary, address(avatar)), "mint reputation should succeed"); 130 | emit Redeem(_beneficiary, _redeemer, tokenAmount); 131 | return tokenAmount; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /contracts/schemes/SchemeConstraints.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | pragma experimental ABIEncoderV2; 3 | import "../controller/Avatar.sol"; 4 | 5 | 6 | contract SchemeConstraints { 7 | 8 | address[] public contractsWhiteList; 9 | //descriptionHash can be used to add detalis description of the constraints. 10 | //e.g it can be ipfs hash of the contractsWhiteList abis +names. 11 | string public descriptionHash; 12 | 13 | /* 14 | * @dev isAllowedToCall should be called upon a proposal execution. 15 | * @param _contractsToCall the contracts to be called 16 | * @param _callsData - The abi encode data for the calls 17 | * @param _values value(ETH) to transfer with the calls 18 | * @param _avatar avatar 19 | * @return bool value true-allowed false not allowed 20 | */ 21 | function isAllowedToCall( 22 | address[] calldata _contractsToCall, 23 | bytes[] calldata _callsData, 24 | uint256[] calldata _values, 25 | Avatar _avatar) 26 | external returns(bool); 27 | 28 | /* 29 | * @dev isAllowedToPropose should be called upon a proposal submition. 30 | * @param _contractsToCall the contracts to be called 31 | * @param _callsData - The abi encode data for the calls 32 | * @param _values value(ETH) to transfer with the calls 33 | * @param _avatar avatar 34 | * @return bool value true-allowed false not allowed 35 | */ 36 | function isAllowedToPropose( 37 | address[] calldata _contractsToCall, 38 | bytes[] calldata _callsData, 39 | uint256[] calldata _values, 40 | Avatar _avatar) 41 | external returns(bool); 42 | 43 | function getContractsWhiteList() external view returns(address[] memory) { 44 | return contractsWhiteList; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /contracts/schemes/SignalScheme.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "@daostack/infra/contracts/votingMachines/IntVoteInterface.sol"; 4 | import "@daostack/infra/contracts/votingMachines/VotingMachineCallbacksInterface.sol"; 5 | import "../votingMachines/VotingMachineCallbacks.sol"; 6 | import "../controller/Avatar.sol"; 7 | 8 | 9 | /** 10 | * @title A scheme for proposing a signal on behalkf of the daoCreator 11 | */ 12 | 13 | contract SignalScheme is VotingMachineCallbacks, ProposalExecuteInterface { 14 | 15 | event NewSignalProposal( 16 | address indexed _avatar, 17 | bytes32 indexed _proposalId, 18 | uint256 indexed _signalType, 19 | string _descriptionHash 20 | ); 21 | 22 | event Signal( 23 | address indexed _avatar, 24 | bytes32 indexed _proposalId, 25 | uint256 indexed _signalType, 26 | string _descriptionHash 27 | ); 28 | 29 | struct Proposal { 30 | string descriptionHash; 31 | bool executed; 32 | } 33 | 34 | struct Parameters { 35 | bytes32 voteApproveParams; 36 | IntVoteInterface intVote; 37 | uint256 signalType; 38 | Avatar avatar; 39 | } 40 | 41 | mapping(bytes32 => Proposal) public proposals; 42 | 43 | Parameters public params; 44 | 45 | /** 46 | * @dev initialize 47 | * @param _avatar the scheme avatar 48 | * @param _signalType - signal types 49 | * @param _voteApproveParams voting machine params 50 | * @param _intVote voting machine address 51 | */ 52 | function initialize(Avatar _avatar, 53 | uint256 _signalType, 54 | bytes32 _voteApproveParams, 55 | IntVoteInterface _intVote) 56 | external { 57 | require(params.avatar == Avatar(0), "can be called only one time"); 58 | require(_avatar != Avatar(0), "avatar cannot be zero"); 59 | params = Parameters({ 60 | voteApproveParams: _voteApproveParams, 61 | signalType: _signalType, 62 | intVote: _intVote, 63 | avatar: _avatar 64 | }); 65 | } 66 | 67 | /** 68 | * @dev Submit a proposal for a dao signal 69 | * @param _descriptionHash A hash of the proposal's description 70 | */ 71 | function proposeSignal( 72 | string calldata _descriptionHash 73 | ) 74 | external 75 | returns(bytes32) 76 | { 77 | require(Controller(params.avatar.owner()).isSchemeRegistered(address(this), address(params.avatar)), 78 | "scheme is not registered"); 79 | 80 | bytes32 proposalId = params.intVote.propose( 81 | 2, 82 | params.voteApproveParams, 83 | msg.sender, 84 | address(params.avatar) 85 | ); 86 | 87 | proposals[proposalId].descriptionHash = _descriptionHash; 88 | 89 | emit NewSignalProposal( 90 | address(params.avatar), 91 | proposalId, 92 | params.signalType, 93 | _descriptionHash 94 | ); 95 | 96 | proposalsInfo[address(params.intVote)][proposalId] = ProposalInfo({ 97 | blockNumber:block.number, 98 | avatar:params.avatar 99 | }); 100 | return proposalId; 101 | } 102 | 103 | /** 104 | * @dev execution of proposals, can only be called by the voting machine in which the vote is held. 105 | * @param _proposalId the ID of the voting in the voting machine 106 | * @param _param a parameter of the voting result, 1 yes and 2 is no. 107 | */ 108 | function executeProposal(bytes32 _proposalId, int256 _param) external onlyVotingMachine(_proposalId) returns(bool) { 109 | require(!proposals[_proposalId].executed); 110 | proposals[_proposalId].executed = true; 111 | // Check if vote was successful: 112 | if (_param == 1) { 113 | emit Signal(address(params.avatar), 114 | _proposalId, 115 | params.signalType, 116 | proposals[_proposalId].descriptionHash); 117 | } 118 | return true; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /contracts/schemes/SimpleSchemeConstraints.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | pragma experimental ABIEncoderV2; 3 | 4 | import "./SchemeConstraints.sol"; 5 | 6 | //a simple genericSchemeMultiCall constraint which put constraints only on white listed contracts to call. 7 | 8 | contract SimpleSchemeConstraints is SchemeConstraints { 9 | 10 | mapping(address=>bool) public contractsWhiteListMap; 11 | bool public initialized; 12 | bool public enableWhitelisting; 13 | bool public enableSendEth; 14 | 15 | /* @dev initialize 16 | * @param _contractsWhiteList the contracts the scheme is allowed to interact with 17 | * @param _descriptionHash can be used to add detalis description of the constraints. 18 | */ 19 | function initialize( 20 | address[] calldata _contractsWhiteList, 21 | string calldata _descriptionHash, 22 | bool _enableSendEth 23 | ) 24 | external { 25 | require(!initialized, "cannot initialize twice"); 26 | initialized = true; 27 | for (uint i = 0; i < _contractsWhiteList.length; i++) { 28 | contractsWhiteListMap[_contractsWhiteList[i]] = true; 29 | } 30 | contractsWhiteList = _contractsWhiteList; 31 | descriptionHash = _descriptionHash; 32 | enableSendEth = _enableSendEth; 33 | enableWhitelisting = _contractsWhiteList.length > 0; 34 | } 35 | 36 | /* 37 | * @dev isAllowedToCall should be called upon a proposal execution. 38 | * @param _contractsToCall the contracts to be called 39 | * @param _values value(ETH) to transfer with the calls 40 | * @return bool value true-allowed false not allowed 41 | */ 42 | function isAllowedToCall( 43 | address[] calldata _contractsToCall, 44 | bytes[] calldata, 45 | uint256[] calldata _values, 46 | Avatar 47 | ) 48 | external 49 | returns(bool) 50 | { 51 | for (uint i = 0; i < _contractsToCall.length; i++) { 52 | require(!enableWhitelisting || contractsWhiteListMap[_contractsToCall[i]], "contract not whitelisted"); 53 | if (!enableSendEth) { 54 | require(_values[i] == 0, "sending eth is not allowed"); 55 | } 56 | } 57 | return true; 58 | } 59 | 60 | /* 61 | * @dev isAllowedToPropose should be called upon a proposal submition. 62 | * @param _contractsToCall the contracts to be called 63 | * @param _values value(ETH) to transfer with the calls 64 | * @return bool value true-allowed false not allowed 65 | */ 66 | function isAllowedToPropose( 67 | address[] calldata _contractsToCall, 68 | bytes[] calldata, 69 | uint256[] calldata _values, 70 | Avatar) 71 | external 72 | returns(bool) 73 | { 74 | for (uint i = 0; i < _contractsToCall.length; i++) { 75 | require(!enableWhitelisting || contractsWhiteListMap[_contractsToCall[i]], "contract not whitelisted"); 76 | if (!enableSendEth) { 77 | require(_values[i] == 0, "sending eth is not allowed"); 78 | } 79 | } 80 | return true; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /contracts/schemes/TransitionScheme.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../controller/Controller.sol"; 4 | 5 | /** 6 | * @title A scheme for transitioning the DAO's assets to a new one. 7 | */ 8 | 9 | contract TransitionScheme { 10 | 11 | uint256 public constant ASSETS_CAP = 100; 12 | 13 | event OwnershipTransferred(Avatar indexed _avatar, address indexed _newAvatar, address indexed _asset); 14 | 15 | Avatar public avatar; 16 | address payable public newAvatar; 17 | address[] public externalTokens; 18 | address[] public assetAddresses; 19 | bytes4[] public selectors; 20 | 21 | /** 22 | * @dev initialize 23 | * @param _avatar the avatar to migrate from 24 | * @param _newAvatar the avatar to migrate to 25 | * @param _externalTokens external tokens to allow transfer to the new avatar 26 | * @param _assetAddresses the assets to transfer 27 | * @param _selectors the functions to call to to transfer the assets 28 | */ 29 | function initialize( 30 | Avatar _avatar, 31 | address payable _newAvatar, 32 | address[] calldata _externalTokens, 33 | address[] calldata _assetAddresses, 34 | bytes4[] calldata _selectors 35 | ) external { 36 | require(_assetAddresses.length <= ASSETS_CAP, "cannot transfer more than 100 assets"); 37 | require(_assetAddresses.length == _selectors.length, "Arrays length mismatch"); 38 | require(avatar == Avatar(0), "can be called only one time"); 39 | require(_avatar != Avatar(0), "avatar cannot be zero"); 40 | avatar = _avatar; 41 | newAvatar = _newAvatar; 42 | externalTokens = _externalTokens; 43 | assetAddresses = _assetAddresses; 44 | selectors = _selectors; 45 | } 46 | 47 | /** 48 | * @dev transferAssets function 49 | * transfer the DAO assets to a new DAO 50 | */ 51 | function transferAssets() external { 52 | for (uint256 i=0; i < assetAddresses.length; i++) { 53 | bytes memory genericCallReturnValue; 54 | bool success; 55 | Controller controller = Controller(avatar.owner()); 56 | (success, genericCallReturnValue) = 57 | controller.genericCall( 58 | assetAddresses[i], 59 | abi.encodeWithSelector(selectors[i], newAvatar), 60 | avatar, 61 | 0 62 | ); 63 | if (success) { 64 | emit OwnershipTransferred(avatar, newAvatar, assetAddresses[i]); 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * @dev sendEther function 71 | * @param _amount the amount of ether to send to the new avatar 72 | */ 73 | function sendEther(uint256 _amount) external { 74 | require( 75 | Controller(avatar.owner()).sendEther(_amount, newAvatar, avatar), 76 | "Sending ether should succeed" 77 | ); 78 | } 79 | 80 | /** 81 | * @dev sendExternalToken function 82 | * @param _amounts the amounts of tokens to send to the new avatar 83 | */ 84 | function sendExternalToken(uint256[] calldata _amounts) external { 85 | require(externalTokens.length == _amounts.length, "Arrays length mismatch"); 86 | for (uint256 i=0; i < externalTokens.length; i++) { 87 | if (_amounts[i] > 0) { 88 | require( 89 | Controller(avatar.owner()).externalTokenTransfer( 90 | IERC20(externalTokens[i]), 91 | newAvatar, 92 | _amounts[i], 93 | avatar 94 | ), 95 | "Sending external token should succeed" 96 | ); 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /contracts/test/ARCDebug.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "@daostack/infra/contracts/votingMachines/GenesisProtocol.sol"; 4 | import "@daostack/infra/contracts/votingMachines/AbsoluteVote.sol"; 5 | import "@daostack/infra/contracts/votingMachines/QuorumVote.sol"; 6 | import "@daostack/infra/contracts/test/AbsoluteVoteExecuteMock.sol"; 7 | import "@daostack/infra/contracts/test/GenesisProtocolCallbacksMock.sol"; 8 | 9 | /* 10 | A contract you can inherit from that has some useful Events to print statements. 11 | */ 12 | 13 | 14 | contract ARCDebug { 15 | event LogAddress(address _msg); 16 | event LogInt(int256 _msg); 17 | event LogString(string _msg); 18 | event LogUint(uint256 _msg); 19 | event LogBytes(bytes _msg); 20 | event LogBytes32(bytes32 _msg); 21 | event LogBool(bool _msg); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/test/ARCGenesisProtocolCallbacksMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../votingMachines/VotingMachineCallbacks.sol"; 4 | 5 | 6 | contract ARCVotingMachineCallbacksMock is VotingMachineCallbacks { 7 | 8 | function propose(bytes32 _proposalId, Avatar _avatar, address _votingMachine) public { 9 | proposalsInfo[_votingMachine][_proposalId] = ProposalInfo({ 10 | blockNumber:block.number, 11 | avatar:_avatar 12 | }); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /contracts/test/ActionMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../controller/Avatar.sol"; 4 | 5 | 6 | contract ActionMock { 7 | 8 | event WithoutReturnValue(address _addr); 9 | event ReceiveEther(address indexed _sender, uint256 _value); 10 | 11 | uint public activationTime; 12 | 13 | function test(uint256 _a, address _b, bytes32 _c) public payable returns(uint256) { 14 | require(_a == 7); 15 | require(_b == address(this)); 16 | require(_c == 0x1234000000000000000000000000000000000000000000000000000000000000); 17 | emit ReceiveEther(msg.sender, msg.value); 18 | return _a*2; 19 | } 20 | 21 | function test2(address _addr) public payable returns(bool) { 22 | require(msg.sender == _addr, "the caller must be equal to _addr"); 23 | return true; 24 | } 25 | 26 | function withoutReturnValue(address _addr) public { 27 | require(msg.sender == _addr, "the caller must be equal to _addr"); 28 | emit WithoutReturnValue(_addr); 29 | } 30 | 31 | function setActivationTime(uint _activationTime) public { 32 | activationTime = _activationTime; 33 | } 34 | 35 | function test3() public view { 36 | // solhint-disable-next-line not-rely-on-time 37 | require(now > activationTime, "now should be greater than the activation time"); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /contracts/test/AgreementMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../schemes/Agreement.sol"; 4 | 5 | 6 | contract AgreementMock is Agreement { 7 | 8 | function setAgreementHashTest(bytes32 _agreementHash) public 9 | { 10 | super.setAgreementHash(_agreementHash); 11 | } 12 | 13 | function test(bytes32 _agreementHash) public onlyAgree(_agreementHash) view returns(bool) 14 | { 15 | return true; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/test/BadERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | //this is a mock to simulate bad ERC20 token implementation as describe at 4 | //https://github.com/ethereum/solidity/issues/4116 5 | contract BadERC20 { 6 | 7 | mapping(address => uint256) public balances; 8 | mapping (address => mapping (address => uint256)) public allowance; 9 | 10 | function transfer(address _to, uint256 _value) public { 11 | balances[_to] = _value; 12 | } 13 | 14 | function transferFrom(address, address _to, uint256 _value) public { 15 | balances[_to] += _value; 16 | } 17 | 18 | function approve(address _spender, uint256 _value) public { 19 | allowance[msg.sender][_spender] = _value; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /contracts/test/ERC20Mock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol"; 4 | 5 | 6 | // mock class using ERC20 7 | contract ERC20Mock is ERC20 { 8 | 9 | constructor(address initialAccount, uint256 initialBalance) public { 10 | _mint(initialAccount, initialBalance); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/test/ExternalTokenLockerMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 4 | 5 | contract ExternalTokenLockerMock is Ownable { 6 | 7 | // user => amount 8 | mapping (address => uint256) public lockedTokenBalances; 9 | 10 | function lock(uint256 _amount, address _beneficiary) public onlyOwner { 11 | lockedTokenBalances[_beneficiary] = _amount; 12 | } 13 | 14 | function balanceOf(address _beneficiary) public view returns(uint256) { 15 | return lockedTokenBalances[_beneficiary]; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/test/GlobalConstraintMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../globalConstraints/GlobalConstraintInterface.sol"; 4 | 5 | 6 | contract GlobalConstraintMock { 7 | 8 | struct TestParam { 9 | bool pre; 10 | bool post; 11 | } 12 | 13 | mapping (bytes32=>TestParam) public testParams; 14 | 15 | GlobalConstraintInterface.CallPhase public currentCallPhase; 16 | 17 | function setConstraint(bytes32 method, bool pre, bool post) public returns(bool) { 18 | testParams[method].pre = pre; 19 | testParams[method].post = post; 20 | 21 | if (!pre && !post) { 22 | currentCallPhase = GlobalConstraintInterface.CallPhase.PreAndPost; 23 | } else { 24 | if (!pre) { 25 | currentCallPhase = GlobalConstraintInterface.CallPhase.Pre; 26 | } else if (!post) { 27 | currentCallPhase = GlobalConstraintInterface.CallPhase.Post; 28 | } 29 | } 30 | return true; 31 | } 32 | 33 | function pre(address, bytes32, bytes32 method) public view returns(bool) { 34 | return testParams[method].pre; 35 | } 36 | 37 | function post(address, bytes32, bytes32 method) public view returns(bool) { 38 | return testParams[method].post; 39 | } 40 | 41 | function when() public view returns(GlobalConstraintInterface.CallPhase) { 42 | return currentCallPhase; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/test/NectarRepAllocation.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "openzeppelin-solidity/contracts/math/SafeMath.sol"; 4 | 5 | 6 | contract MiniMeToken { 7 | function balanceOfAt(address _owner, uint _blockNumber) public view returns (uint); 8 | function totalSupplyAt(uint _blockNumber) public view returns(uint); 9 | } 10 | 11 | /** 12 | * @title NectarRepAllocation contract 13 | * This contract should be use to calculate reputation allocation for nextar dao bootstrat 14 | * this contract can be used as the rep mapping contract for RepitationFromToken contract. 15 | */ 16 | 17 | contract NectarRepAllocation { 18 | using SafeMath for uint256; 19 | 20 | uint256 public reputationReward; 21 | uint256 public claimingStartTime; 22 | uint256 public claimingEndTime; 23 | uint256 public totalTokenSupplyAt; 24 | uint256 public blockReference; 25 | MiniMeToken public token; 26 | 27 | /** 28 | * @dev initialize 29 | * @param _reputationReward the total reputation which will be used to calc the reward 30 | * for the token locking 31 | * @param _claimingStartTime claiming starting period time. 32 | * @param _claimingEndTime the claiming end time. 33 | * claiming is disable after this time. 34 | * @param _blockReference the block nbumber reference which is used to takle the balance from. 35 | * @param _token nectar token address 36 | */ 37 | function initialize( 38 | uint256 _reputationReward, 39 | uint256 _claimingStartTime, 40 | uint256 _claimingEndTime, 41 | uint256 _blockReference, 42 | MiniMeToken _token) 43 | external 44 | { 45 | require(token == MiniMeToken(0), "can be called only one time"); 46 | require(_token != MiniMeToken(0), "token cannot be zero"); 47 | token = _token; 48 | reputationReward = _reputationReward; 49 | claimingStartTime = _claimingStartTime; 50 | claimingEndTime = _claimingEndTime; 51 | blockReference = _blockReference; 52 | if ((claimingStartTime != 0) || (claimingEndTime != 0)) { 53 | require(claimingEndTime > claimingStartTime, "claimingStartTime > claimingEndTime"); 54 | } 55 | totalTokenSupplyAt = token.totalSupplyAt(_blockReference); 56 | } 57 | 58 | /** 59 | * @dev get balanceOf _beneficiary function 60 | * @param _beneficiary addresses 61 | */ 62 | function balanceOf(address _beneficiary) public view returns(uint256 reputation) { 63 | if (((claimingStartTime != 0) || (claimingEndTime != 0)) && 64 | // solhint-disable-next-line not-rely-on-time 65 | ((now >= claimingEndTime) || (now < claimingStartTime))) { 66 | reputation = 0; 67 | } else { 68 | reputation = token.balanceOfAt(_beneficiary, blockReference).mul(reputationReward).div(totalTokenSupplyAt); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /contracts/test/PolkaCurve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../schemes/CurveInterface.sol"; 4 | 5 | /** 6 | * @title A Curve contract which implement the function of square root. 7 | * the result is normalized for the total reputation allocated. 8 | */ 9 | 10 | contract PolkaCurve is CurveInterface { 11 | 12 | uint256 public constant TOTAL_REPUTATION = 800000; 13 | uint256 public constant SUM_OF_SQRTS = 1718050; 14 | 15 | function calc(uint256 _value) external pure returns (uint256 sqrt) { 16 | uint value = _value * 1 ether; 17 | uint z = (value + 1) / 2; 18 | sqrt = value; 19 | while (z < sqrt) { 20 | sqrt = z; 21 | z = (value / z + z) / 2; 22 | } 23 | sqrt = ((sqrt*TOTAL_REPUTATION)/SUM_OF_SQRTS) * 1000000000; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/test/PriceOracleMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../schemes/PriceOracleInterface.sol"; 4 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 5 | 6 | 7 | contract PriceOracleMock is PriceOracleInterface, Ownable { 8 | 9 | struct Price { 10 | uint256 numerator; 11 | uint256 denominator; 12 | } 13 | 14 | // user => amount 15 | mapping (address => Price) public tokenPrices; 16 | 17 | function setTokenPrice(address token, uint256 numerator, uint256 denominator) public onlyOwner { 18 | tokenPrices[token] = Price(numerator, denominator); 19 | } 20 | 21 | function getPrice(address token) public view returns (uint, uint) { 22 | Price memory price = tokenPrices[token]; 23 | return (price.numerator, price.denominator); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/test/SafeERC20Mock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "./BadERC20.sol"; 4 | import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol"; 5 | import "../libs/SafeERC20.sol"; 6 | 7 | 8 | contract SafeERC20Mock { 9 | using SafeERC20 for address; 10 | 11 | address public token; 12 | 13 | constructor(IERC20 _token) public { 14 | token = address(_token); 15 | } 16 | 17 | function transfer(address _to, uint256 _value) public returns(bool) { 18 | require(IERC20(token).transfer(_to, _value)); 19 | } 20 | 21 | function transferWithFix(address _to, uint256 _value) public returns(bool) { 22 | token.safeTransfer(_to, _value); 23 | return true; 24 | } 25 | 26 | function transferFromWithFix(address _from, address _to, uint256 _value) public returns(bool) { 27 | token.safeTransferFrom(_from, _to, _value); 28 | return true; 29 | } 30 | 31 | function approveWithFix(address _spender, uint256 _value) public returns(bool) { 32 | token.safeApprove(_spender, _value); 33 | return true; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /contracts/test/UniversalSchemeMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../universalSchemes/UniversalScheme.sol"; 4 | import "../controller/Controller.sol"; 5 | 6 | 7 | contract UniversalSchemeMock is UniversalScheme { 8 | 9 | function genericCall(Avatar _avatar, address _contract, uint256 _a, address _b, bytes32 _c, uint256 _value) 10 | public returns(bool, bytes memory) 11 | { 12 | 13 | address controller = _avatar.owner(); 14 | return Controller(controller).genericCall( 15 | _contract, abi.encodeWithSignature("test(uint256,address,bytes32)", _a, _b, _c), _avatar, _value); 16 | } 17 | 18 | function genericCallDirect(Avatar _avatar, address _contract, uint256 _a, address _b, bytes32 _c, uint256 _value) 19 | public returns(bool, bytes memory) 20 | { 21 | return _avatar.genericCall( 22 | _contract, 23 | abi.encodeWithSignature("test(uint256,address,bytes32)", _a, _b, _c), 24 | _value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /contracts/test/Wallet.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 3 | 4 | 5 | contract Wallet is Ownable { 6 | 7 | event ReceiveEther(address indexed _sender, uint256 _value); 8 | event Pay(address indexed _sender, uint256 _value); 9 | 10 | function() external payable { 11 | emit ReceiveEther(msg.sender, msg.value); 12 | } 13 | 14 | function pay(address payable _beneficiary) public onlyOwner { 15 | uint256 amount = address(this).balance; 16 | _beneficiary.transfer(amount); 17 | emit Pay(_beneficiary, amount); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /contracts/universalSchemes/OrganizationRegister.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "./UniversalScheme.sol"; 4 | import "../libs/SafeERC20.sol"; 5 | 6 | /** 7 | * @title A universal organization registry. 8 | * @dev Organizations can use this scheme to open a registry. 9 | * Other organizations can then add and promote themselves on this registry. 10 | */ 11 | 12 | contract OrganizationRegister is UniversalScheme { 13 | using SafeMath for uint; 14 | using SafeERC20 for address; 15 | 16 | struct Parameters { 17 | uint256 fee; 18 | IERC20 token; 19 | address beneficiary; 20 | } 21 | 22 | // A mapping from the organization (Avatar) address to the saved data of the organization: 23 | mapping(address=>mapping(address=>uint)) public organizationsRegistry; 24 | 25 | mapping(bytes32=>Parameters) public parameters; 26 | 27 | event OrgAdded( address indexed _registry, address indexed _org); 28 | event Promotion( address indexed _registry, address indexed _org, uint256 _amount); 29 | 30 | /** 31 | * @dev Hash the parameters, save if needed and return the hash value 32 | * @param _token - the token to pay for register or promotion an address. 33 | * @param _fee - fee needed for register an address. 34 | * @param _beneficiary - the beneficiary payment address 35 | * @return bytes32 -the parameters hash 36 | */ 37 | function setParameters(IERC20 _token, uint256 _fee, address _beneficiary) public returns(bytes32) { 38 | bytes32 paramsHash = getParametersHash(_token, _fee, _beneficiary); 39 | if (parameters[paramsHash].token == ERC20(0)) { 40 | parameters[paramsHash].token = _token; 41 | parameters[paramsHash].fee = _fee; 42 | parameters[paramsHash].beneficiary = _beneficiary; 43 | } 44 | return paramsHash; 45 | } 46 | 47 | /** 48 | * @dev Adding or promoting an address on the registry. 49 | * An address(record) to add or promote can be organization address or any contract address. 50 | * Adding a record is done by paying at least the minimum required by the registry params. 51 | * Promoting a record is done by paying(adding)amount of token to the registry beneficiary. 52 | * @param _avatar The _avatar of the organization which own the registry. 53 | * @param _record The address to add or promote. 54 | * @param _amount amount to pay for adding or promoting 55 | */ 56 | function addOrPromoteAddress(Avatar _avatar, address _record, uint256 _amount) 57 | public 58 | { 59 | Parameters memory params = parameters[getParametersFromController(_avatar)]; 60 | // Pay promotion, if the org was not listed the minimum is the fee: 61 | require((organizationsRegistry[address(_avatar)][_record] > 0) || (_amount >= params.fee)); 62 | 63 | address(params.token).safeTransferFrom(msg.sender, params.beneficiary, _amount); 64 | if (organizationsRegistry[address(_avatar)][_record] == 0) { 65 | emit OrgAdded(address(_avatar), _record); 66 | } 67 | organizationsRegistry[address(_avatar)][_record] = 68 | organizationsRegistry[address(_avatar)][_record].add(_amount); 69 | emit Promotion(address(_avatar), _record, _amount); 70 | } 71 | 72 | /** 73 | * @dev Hash the parameters ,and return the hash value 74 | * @param _token - the token to pay for register or promotion an address. 75 | * @param _fee - fee needed for register an address. 76 | * @param _beneficiary - the beneficiary payment address 77 | * @return bytes32 -the parameters hash 78 | */ 79 | function getParametersHash(IERC20 _token, uint256 _fee, address _beneficiary) 80 | public pure returns(bytes32) 81 | { 82 | return (keccak256(abi.encodePacked(_token, _fee, _beneficiary))); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /contracts/universalSchemes/UniversalScheme.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "./UniversalSchemeInterface.sol"; 4 | import "../controller/Controller.sol"; 5 | import "../controller/Avatar.sol"; 6 | 7 | 8 | contract UniversalScheme is UniversalSchemeInterface { 9 | /** 10 | * @dev get the parameters for the current scheme from the controller 11 | */ 12 | function getParametersFromController(Avatar _avatar) internal view returns(bytes32) { 13 | require(Controller(_avatar.owner()).isSchemeRegistered(address(this), address(_avatar)), 14 | "scheme is not registered"); 15 | return Controller(_avatar.owner()).getSchemeParameters(address(this), address(_avatar)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/universalSchemes/UniversalSchemeInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../controller/Avatar.sol"; 4 | 5 | contract UniversalSchemeInterface { 6 | 7 | function getParametersFromController(Avatar _avatar) internal view returns(bytes32); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /contracts/utils/CompetitionFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "@daostack/infra/contracts/votingMachines/GenesisProtocolInterface.sol"; 4 | import "../schemes/Competition.sol"; 5 | import "../schemes/ContributionRewardExt.sol"; 6 | 7 | /** 8 | * @title CompetitionFactory 9 | */ 10 | contract CompetitionFactory { 11 | uint8 public constant CUSTOM = 0; 12 | uint8 public constant FAST = 1; 13 | uint8 public constant NORMAL = 2; 14 | uint8 public constant SLOW = 3; 15 | 16 | event NewCompetition(address competition, address contributionRewardExt); 17 | 18 | function createCompetition( 19 | Avatar _avatar, 20 | IntVoteInterface _votingMachine, 21 | uint8 _voteParamsType, 22 | uint256[11] memory _votingParams, 23 | address _voteOnBehalf 24 | ) public returns(address, address) { 25 | require(_voteParamsType < 4, "Vote params type specified does not exist"); 26 | ContributionRewardExt contributionRewardExt = new ContributionRewardExt(); 27 | Competition competition = new Competition(); 28 | competition.initialize(address(contributionRewardExt)); 29 | 30 | uint256[11] memory voteParams; 31 | if (_voteParamsType == CUSTOM) { 32 | // Custom params hash 33 | voteParams = _votingParams; 34 | } else { 35 | voteParams = getDefaultVoteParams(_voteParamsType); 36 | } 37 | 38 | bytes32 voteParamsHash = GenesisProtocolInterface(address(_votingMachine)) 39 | .setParameters(voteParams, _voteOnBehalf); 40 | 41 | contributionRewardExt.initialize( 42 | _avatar, _votingMachine, voteParamsHash, address(competition) 43 | ); 44 | 45 | emit NewCompetition(address(competition), address(contributionRewardExt)); 46 | return (address(competition), address(contributionRewardExt)); 47 | } 48 | 49 | function getDefaultVoteParams(uint8 _voteParamsType) private pure returns(uint256[11] memory voteParams) { 50 | if (_voteParamsType == FAST) { 51 | // Fast params hash 52 | voteParams = [ 53 | uint256(50), 54 | uint256(604800), 55 | uint256(129600), 56 | uint256(43200), 57 | uint256(1200), 58 | uint256(86400), 59 | uint256(10000000000000000000), 60 | uint256(1), 61 | uint256(50000000000000000000), 62 | uint256(10), 63 | uint256(0) 64 | ]; 65 | } else if (_voteParamsType == NORMAL) { 66 | // Normal params hash 67 | voteParams = [ 68 | uint256(50), 69 | uint256(2592000), 70 | uint256(345600), 71 | uint256(86400), 72 | uint256(1200), 73 | uint256(172800), 74 | uint256(50000000000000000000), 75 | uint256(4), 76 | uint256(150000000000000000000), 77 | uint256(10), 78 | uint256(0) 79 | ]; 80 | } else if (_voteParamsType == SLOW) { 81 | // Slow params hash 82 | voteParams = [ 83 | uint256(50), 84 | uint256(5184000), 85 | uint256(691200), 86 | uint256(172800), 87 | uint256(1500), 88 | uint256(345600), 89 | uint256(200000000000000000000), 90 | uint256(4), 91 | uint256(500000000000000000000), 92 | uint256(10), 93 | uint256(0) 94 | ]; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /contracts/utils/ContinuousLocking4ReputationFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../schemes/ContinuousLocking4Reputation.sol"; 4 | 5 | /** 6 | * @title ContinuousLocking4ReputationFactory 7 | */ 8 | contract ContinuousLocking4ReputationFactory { 9 | 10 | event NewCL4R(address continuousLocking4Reputation); 11 | 12 | function createCL4R( 13 | Avatar _avatar, 14 | uint256 _reputationReward, 15 | uint256 _startTime, 16 | uint256 _batchTime, 17 | uint256 _redeemEnableTime, 18 | uint256 _maxLockingBatches, 19 | uint256 _repRewardConstA, 20 | uint256 _repRewardConstB, 21 | uint256 _batchesIndexCap, 22 | IERC20 _token, 23 | bytes32 _agreementHash) public returns(address) { 24 | ContinuousLocking4Reputation continuousLocking4Reputation = new ContinuousLocking4Reputation(); 25 | continuousLocking4Reputation.initialize( 26 | _avatar, 27 | _reputationReward, 28 | _startTime, 29 | _batchTime, 30 | _redeemEnableTime, 31 | _maxLockingBatches, 32 | _repRewardConstA, 33 | _repRewardConstB, 34 | _batchesIndexCap, 35 | _token, 36 | _agreementHash 37 | ); 38 | emit NewCL4R(address(continuousLocking4Reputation)); 39 | return address(continuousLocking4Reputation); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /contracts/utils/DAOTracker.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "@daostack/infra/contracts/Reputation.sol"; 4 | import "../controller/DAOToken.sol"; 5 | import "../controller/Avatar.sol"; 6 | import "../controller/Controller.sol"; 7 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 8 | 9 | /** 10 | * @title An on-chain "source of truth" for what DAOs 11 | * should be index into DAOstack's subgraph. 12 | */ 13 | contract DAOTracker is Ownable { 14 | 15 | // `blacklist` the DAO from the subgraph's cache. 16 | // Only able to be set by the owner of the DAOTracker. 17 | mapping(address=>bool) public blacklisted; 18 | 19 | event TrackDAO( 20 | address indexed _avatar, 21 | address _controller, 22 | address _reputation, 23 | address _daoToken, 24 | address _sender, 25 | string _arcVersion 26 | ); 27 | 28 | event BlacklistDAO( 29 | address indexed _avatar, 30 | string _explanationHash 31 | ); 32 | 33 | event ResetDAO( 34 | address indexed _avatar, 35 | string _explanationHash 36 | ); 37 | 38 | modifier onlyAvatarOwner(Avatar avatar) { 39 | require(avatar.owner() == msg.sender, 40 | "The caller must be the owner of the Avatar."); 41 | _; 42 | } 43 | 44 | modifier notBlacklisted(Avatar avatar) { 45 | require(blacklisted[address(avatar)] == false, 46 | "The avatar has been blacklisted."); 47 | _; 48 | } 49 | 50 | /** 51 | * @dev track a new organization. This function will tell the subgraph 52 | * to start ingesting events from the DAO's contracts. 53 | * NOTE: This function should be called as early as possible in the DAO deployment 54 | * process. **Smart Contract Events that are emitted from blocks prior to this function's 55 | * event being emitted WILL NOT be ingested into the subgraph**, leading to an incorrect 56 | * cache. If this happens to you, please contact the subgraph maintainer. Your DAO will 57 | * need to be added to the subgraph's startup config, and the cache will need to be rebuilt. 58 | * @param _avatar the organization avatar 59 | * @param _controller the organization controller 60 | */ 61 | function track(Avatar _avatar, Controller _controller, string memory _arcVersion) 62 | public 63 | onlyAvatarOwner(_avatar) 64 | notBlacklisted(_avatar) { 65 | // Only allow the information to be set once. In the case of a controller upgrades, 66 | // the subgraph will be updated via the UpgradeController event. 67 | require(_avatar != Avatar(0)); 68 | require(_controller != Controller(0)); 69 | 70 | emit TrackDAO( 71 | address(_avatar), 72 | address(_controller), 73 | address(_avatar.nativeReputation()), 74 | address(_avatar.nativeToken()), 75 | msg.sender, 76 | _arcVersion 77 | ); 78 | } 79 | 80 | /** 81 | * @dev blacklist a DAO from the cache. This should be callable by maintainer of the cache. 82 | * Blacklisting can be used to defend against DoS attacks, or to remove spam. In order 83 | * for this blacklisting to take affect within the cache, it would need to be rebuilt. 84 | * @param _avatar the organization avatar 85 | * @param _explanationHash A hash of a document explaining why this DAO was blacklisted 86 | */ 87 | function blacklist(Avatar _avatar, string memory _explanationHash) 88 | public 89 | onlyOwner { 90 | require(_avatar != Avatar(0)); 91 | blacklisted[address(_avatar)] = true; 92 | emit BlacklistDAO(address(_avatar), _explanationHash); 93 | } 94 | 95 | /** 96 | * @dev reset a DAO in the cache. This should be callable by the maintainer of the cache. 97 | * @param _avatar the organization avatar 98 | * @param _explanationHash A hash of a document explaining why this DAO was reset 99 | */ 100 | function reset(Avatar _avatar, string memory _explanationHash) 101 | public 102 | onlyOwner { 103 | require(_avatar != Avatar(0)); 104 | blacklisted[address(_avatar)] = false; 105 | emit ResetDAO(address(_avatar), _explanationHash); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /contracts/utils/GenericSchemeMultiCallFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "@daostack/infra/contracts/votingMachines/GenesisProtocolInterface.sol"; 4 | import "../schemes/GenericSchemeMultiCall.sol"; 5 | import "../schemes/SimpleSchemeConstraints.sol"; 6 | 7 | /** 8 | * @title GenericSchemeMultiCallFactory 9 | */ 10 | contract GenericSchemeMultiCallFactory { 11 | uint8 public constant CUSTOM = 0; 12 | uint8 public constant FAST = 1; 13 | uint8 public constant NORMAL = 2; 14 | uint8 public constant SLOW = 3; 15 | 16 | event NewGenericSchemeMultiCall(address genericSchemeMultiCall); 17 | 18 | function createGenericSchemeMultiCallSimple( 19 | Avatar _avatar, 20 | IntVoteInterface _votingMachine, 21 | uint8 _voteParamsType, 22 | uint256[11] memory _votingParams, 23 | address _voteOnBehalf, 24 | address[] memory _contractsWhiteList, 25 | bool _enableSendEth, 26 | string memory _descriptionHash 27 | ) public returns(address) { 28 | require(_voteParamsType < 4, "Vote params type specified does not exist"); 29 | GenericSchemeMultiCall genericSchemeMultiCall = new GenericSchemeMultiCall(); 30 | address simpleSchemeConstraints; 31 | if (_contractsWhiteList.length > 0 || !_enableSendEth) { 32 | simpleSchemeConstraints = address(new SimpleSchemeConstraints()); 33 | SimpleSchemeConstraints(simpleSchemeConstraints) 34 | .initialize(_contractsWhiteList, _descriptionHash, _enableSendEth); 35 | } 36 | uint256[11] memory voteParams; 37 | if (_voteParamsType == CUSTOM) { 38 | // Custom params hash 39 | voteParams = _votingParams; 40 | } else { 41 | voteParams = getDefaultVoteParams(_voteParamsType); 42 | } 43 | 44 | bytes32 voteParamsHash = GenesisProtocolInterface(address(_votingMachine)) 45 | .setParameters(voteParams, _voteOnBehalf); 46 | 47 | genericSchemeMultiCall.initialize( 48 | _avatar, _votingMachine, voteParamsHash, SchemeConstraints(simpleSchemeConstraints) 49 | ); 50 | 51 | emit NewGenericSchemeMultiCall(address(genericSchemeMultiCall)); 52 | return address(genericSchemeMultiCall); 53 | } 54 | 55 | function getDefaultVoteParams(uint8 _voteParamsType) private pure returns(uint256[11] memory voteParams) { 56 | if (_voteParamsType == FAST) { 57 | // Fast params hash 58 | voteParams = [ 59 | uint256(50), 60 | uint256(604800), 61 | uint256(129600), 62 | uint256(43200), 63 | uint256(1200), 64 | uint256(86400), 65 | uint256(10000000000000000000), 66 | uint256(1), 67 | uint256(50000000000000000000), 68 | uint256(10), 69 | uint256(0) 70 | ]; 71 | } else if (_voteParamsType == NORMAL) { 72 | // Normal params hash 73 | voteParams = [ 74 | uint256(50), 75 | uint256(2592000), 76 | uint256(345600), 77 | uint256(86400), 78 | uint256(1200), 79 | uint256(172800), 80 | uint256(50000000000000000000), 81 | uint256(4), 82 | uint256(150000000000000000000), 83 | uint256(10), 84 | uint256(0) 85 | ]; 86 | } else if (_voteParamsType == SLOW) { 87 | // Slow params hash 88 | voteParams = [ 89 | uint256(50), 90 | uint256(5184000), 91 | uint256(691200), 92 | uint256(172800), 93 | uint256(1500), 94 | uint256(345600), 95 | uint256(200000000000000000000), 96 | uint256(4), 97 | uint256(500000000000000000000), 98 | uint256(10), 99 | uint256(0) 100 | ]; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /contracts/utils/RepAllocation.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; 4 | 5 | 6 | /** 7 | * @title reputation allocation contract 8 | * This scheme can be used to allocate a pre define amount of reputation to whitelisted 9 | * beneficiaries. 10 | * this contract can be used as the rep mapping contract for RepitationFromToken contract. 11 | */ 12 | contract RepAllocation is Ownable { 13 | 14 | 15 | // beneficiary -> amount 16 | mapping(address => uint256) public reputationAllocations; 17 | bool public isFreeze; 18 | 19 | event BeneficiaryAddressAdded(address indexed _beneficiary, uint256 indexed _amount); 20 | 21 | /** 22 | * @dev addBeneficiary function 23 | * @param _beneficiary to be whitelisted 24 | */ 25 | function addBeneficiary(address _beneficiary, uint256 _amount) public onlyOwner { 26 | require(!isFreeze, "can add beneficiary only if not disable"); 27 | 28 | if (reputationAllocations[_beneficiary] == 0) { 29 | reputationAllocations[_beneficiary] = _amount; 30 | emit BeneficiaryAddressAdded(_beneficiary, _amount); 31 | } 32 | } 33 | 34 | /** 35 | * @dev add addBeneficiaries function 36 | * @param _beneficiaries addresses 37 | */ 38 | function addBeneficiaries(address[] memory _beneficiaries, uint256[] memory _amounts) public onlyOwner { 39 | require(_beneficiaries.length == _amounts.length); 40 | for (uint256 i = 0; i < _beneficiaries.length; i++) { 41 | addBeneficiary(_beneficiaries[i], _amounts[i]); 42 | } 43 | } 44 | 45 | /** 46 | * @dev freeze function 47 | * cannot defreeze 48 | */ 49 | function freeze() public onlyOwner { 50 | isFreeze = true; 51 | } 52 | 53 | /** 54 | * @dev get balanceOf _beneficiary function 55 | * @param _beneficiary addresses 56 | */ 57 | function balanceOf(address _beneficiary) public view returns(uint256) { 58 | return reputationAllocations[_beneficiary]; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /contracts/votingMachines/VotingMachineCallbacks.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.17; 2 | 3 | import "../universalSchemes/UniversalScheme.sol"; 4 | import "@daostack/infra/contracts/votingMachines/VotingMachineCallbacksInterface.sol"; 5 | import "@daostack/infra/contracts/votingMachines/ProposalExecuteInterface.sol"; 6 | 7 | 8 | contract VotingMachineCallbacks is VotingMachineCallbacksInterface { 9 | 10 | struct ProposalInfo { 11 | uint256 blockNumber; // the proposal's block number 12 | Avatar avatar; // the proposal's avatar 13 | } 14 | 15 | modifier onlyVotingMachine(bytes32 _proposalId) { 16 | require(proposalsInfo[msg.sender][_proposalId].avatar != Avatar(address(0)), "only VotingMachine"); 17 | _; 18 | } 19 | 20 | modifier onlyRegisteredScheme(bytes32 _proposalId) { 21 | Avatar avatar = proposalsInfo[msg.sender][_proposalId].avatar; 22 | require(Controller(avatar.owner()).isSchemeRegistered(address(this), address(avatar)), 23 | "scheme is not registered" 24 | ); 25 | _; 26 | } 27 | 28 | // VotingMaching -> proposalId -> ProposalInfo 29 | mapping(address => mapping(bytes32 => ProposalInfo)) public proposalsInfo; 30 | 31 | function mintReputation(uint256 _amount, address _beneficiary, bytes32 _proposalId) 32 | external 33 | onlyVotingMachine(_proposalId) 34 | returns(bool) 35 | { 36 | Avatar avatar = proposalsInfo[msg.sender][_proposalId].avatar; 37 | if (avatar == Avatar(0)) { 38 | return false; 39 | } 40 | return Controller(avatar.owner()).mintReputation(_amount, _beneficiary, address(avatar)); 41 | } 42 | 43 | function burnReputation(uint256 _amount, address _beneficiary, bytes32 _proposalId) 44 | external 45 | onlyVotingMachine(_proposalId) 46 | returns(bool) 47 | { 48 | Avatar avatar = proposalsInfo[msg.sender][_proposalId].avatar; 49 | if (avatar == Avatar(0)) { 50 | return false; 51 | } 52 | return Controller(avatar.owner()).burnReputation(_amount, _beneficiary, address(avatar)); 53 | } 54 | 55 | function stakingTokenTransfer( 56 | IERC20 _stakingToken, 57 | address _beneficiary, 58 | uint256 _amount, 59 | bytes32 _proposalId) 60 | external 61 | onlyVotingMachine(_proposalId) 62 | returns(bool) 63 | { 64 | Avatar avatar = proposalsInfo[msg.sender][_proposalId].avatar; 65 | if (avatar == Avatar(0)) { 66 | return false; 67 | } 68 | return Controller(avatar.owner()).externalTokenTransfer(_stakingToken, _beneficiary, _amount, avatar); 69 | } 70 | 71 | function balanceOfStakingToken(IERC20 _stakingToken, bytes32 _proposalId) external view returns(uint256) { 72 | Avatar avatar = proposalsInfo[msg.sender][_proposalId].avatar; 73 | if (proposalsInfo[msg.sender][_proposalId].avatar == Avatar(0)) { 74 | return 0; 75 | } 76 | return _stakingToken.balanceOf(address(avatar)); 77 | } 78 | 79 | function getTotalReputationSupply(bytes32 _proposalId) 80 | external 81 | view 82 | onlyRegisteredScheme(_proposalId) 83 | returns(uint256) { 84 | ProposalInfo memory proposal = proposalsInfo[msg.sender][_proposalId]; 85 | if (proposal.avatar == Avatar(0)) { 86 | return 0; 87 | } 88 | return proposal.avatar.nativeReputation().totalSupplyAt(proposal.blockNumber); 89 | } 90 | 91 | function reputationOf(address _owner, bytes32 _proposalId) 92 | external 93 | view 94 | onlyRegisteredScheme(_proposalId) 95 | returns(uint256) { 96 | ProposalInfo memory proposal = proposalsInfo[msg.sender][_proposalId]; 97 | if (proposal.avatar == Avatar(0)) { 98 | return 0; 99 | } 100 | return proposal.avatar.nativeReputation().balanceOfAt(_owner, proposal.blockNumber); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /docs/contracts/README.md: -------------------------------------------------------------------------------- 1 | Welcome to contracts documentation! 2 | 3 | This directory includes manual markdown documentation for `contracts` directory. 4 | It follows the directory structure of `contracts` (eg. file `foo/bar.md` documents the `bar` contract in `contracts/foo`). 5 | 6 | [see the generated documentation](../generated_docs/README.md). 7 | -------------------------------------------------------------------------------- /docs/contracts/VotingMachines/README.md: -------------------------------------------------------------------------------- 1 | # Voting Machines Home 2 | 3 | A *VotingMachine* is a pluggable component, provided by DAOstack Arc which can be used by a DAO's schemes to manage a voting process on a certain proposal. 4 | 5 | The *VotingMachine* maintains the voting process and the proposals to vote on, collects votes, and determines the winning vote according to the DAO's pre-defined configuration. 6 | 7 | In some cases, such as [GenesisProtocol](../../generated_docs/VotingMachines/GenesisProtocol.md), it also collects stakes, promotes proposals, and maintains a reputation flow for participants according to the DAO's pre-defined configuration. 8 | 9 | Each *VotingMachine* use its own decision method and has its own voting choices range. 10 | 11 | ## Basic decisions methods used by voting machines 12 | 13 | ### Absolute 14 | 15 | A decision is made if more than a certain percentage (`P`) from the total DAO's reputation voted 16 | on a certain voting choice. Normally `P` is 50% though it can be set to any value. 17 | 18 | The "winning" choice is the one that first crosses that bar. 19 | 20 | ### Relative 21 | 22 | A decision is made on a timeout (`T`) according to the higher relative vote among all votes. 23 | 24 | The "winning" choice is the one with the higher relative votes (reputation). 25 | 26 | 27 | ### Quorum 28 | 29 | A decision is made if at least a certain percentage (`P`) from the total DAO's reputation votes on a certain proposal. 30 | 31 | The "winning" choice is the one with the maximum votes (reputation). 32 | 33 | ## List of supported voting machines 34 | 35 | Below is a list of supported `VotingMachines` and their decision methods: 36 | 37 | | *VotingMachine* | absolute | relative | quorum 38 | | --- | --- | --- | --- | 39 | | [AbsoluteVote](#absolutevote) | yes | no | no | 40 | | [QuorumVote](#quorumvote) | no | no | yes | 41 | | [GenesisProtocol](#genesisprotocol) | yes | yes | no | 42 | 43 | ### [AbsoluteVote](../../generated_docs/VotingMachines/AbsoluteVote.md) 44 | 45 | Uses an absolute decision method. 46 | 47 | Allow voting choices range 0-10. 48 | 49 | Vote 0 for abstain. 50 | 51 | ### [QuorumVote](../../generated_docs/VotingMachines/QuorumVote.md) 52 | 53 | Uses a quorum decision method. 54 | 55 | Allow voting choices range 0-10. 56 | 57 | Vote 0 for abstain. 58 | 59 | ### [GenesisProtocol](../../generated_docs/VotingMachines/GenesisProtocol.md) 60 | 61 | Use absolute and relative decision method. 62 | 63 | Currently it allows only `YES`/`NO` voting choices (2 choices). 64 | 65 | Abstaining is not allowed. 66 | 67 | This voting machine is also a `UniversalScheme`. 68 | -------------------------------------------------------------------------------- /docs/contracts/controller/Avatar.md: -------------------------------------------------------------------------------- 1 | # Avatar 2 | [see the generated documentation](../../generated_docs/controller/Avatar.md) 3 | 4 | 5 | The *Avatar* is the public facing entity a DAO exposes to interact with the outside world (vote on other DAOs, pay external actors, etc...). 6 | It holds the organization's name, token and reputation system and can send and receive Ether and any other ERC20 external tokens. 7 | -------------------------------------------------------------------------------- /docs/contracts/controller/Controller.md: -------------------------------------------------------------------------------- 1 | # Controller 2 | [see the generated documentation](../../generated_docs/controller/Controller.md) 3 | 4 | A non-universal implementation of the [ControllerInterface](../../generated_docs/controller/ControllerInterface.md) 5 | which requires each DAO to have it's own instance of `Controller`. 6 | -------------------------------------------------------------------------------- /docs/contracts/controller/DAOToken.md: -------------------------------------------------------------------------------- 1 | # DAOToken 2 | [see the generated documentation](../../generated_docs/controller/DAOToken.md) 3 | 4 | The *DAOToken* is an *ERC20* compatible token that can be used to assign value and reward the DAO's members for their contributions. 5 | Each *DAOToken* is controlled by the DAO it belongs to via the controller. 6 | 7 | The *DAOToken* can be **minted** or **burned** by the DAO and also be **destroyed** in the event of an upgrade to a better token or in other circumstances. 8 | -------------------------------------------------------------------------------- /docs/contracts/controller/README.md: -------------------------------------------------------------------------------- 1 | # Controller Home 2 | [see the generated documentation](../../generated_docs/controller/ControllerInterface.md) 3 | 4 | related: [Controller](Controller.md) | [UController](UController.md) 5 | 6 | The controller is the central entity of a DAO, 7 | which acts as the owner of the DAO's [Avatar](./Avatar.md), [Reputation](Reputation.md) and [DAOToken](DAOToken.md). 8 | 9 | It can perform "sensitive"operations through these entities (e.g token and reputation operations). 10 | 11 | It is subject to a set of *Schemes* and *Constraints* that determine its behavior, where each scheme has it own operations permissions. 12 | 13 | It stores scheme's parameters for the specific DAO. 14 | 15 | ### Interface & Implementations 16 | 17 | There are currently two implementations of the [Controller Interface](../../generated_docs/controller/ControllerInterface.md) 18 | provided by Arc: 19 | 20 | - [Controller](Controller.md) - A controller instance deployed for each DAO. 21 | - [UController](UController.md) - A single, universal controller instance deployed for many DAOs. 22 | 23 | #### Choosing an implementation 24 | 25 | - `UController` will probably will be deployed by the DAOstack team so by using it one saves the gas cost of deploying a controller when creating a DAO. 26 | - On the other hand, `UController` might be a bit expensive in terms of GAS for each operation. 27 | 28 | 29 | ## Schemes 30 | 31 | A single DAO controller might be a subject to multiple schemes, each with it's own logic. 32 | A scheme can only be registered to a controller by a scheme which has registration permission. 33 | 34 | ### Permissions 35 | 36 | The controller holds and enforces the permissions for each scheme. 37 | e.g [registerScheme(...)](../../generated_docs/controller/ControllerInterface/#registerschemeaddressbytes32bytes4address) is allowed to be called only by an authorized (with permission: `CAN_REGISTER`) scheme. 38 | 39 | A scheme can have any combination of the following permissions: 40 | 41 | - `REGISTERED` - All registered schemes has this permission. Only registered schemes can perform controller operations. 42 | - `CAN_REGISTER` - Grant the scheme the permission to register other schemes. 43 | - `ADD_OR_REMOVE_GLOBAL_CONSTRAINT` - Grant the scheme the permission to add or remove a global constraint. 44 | - `CAN_UPGRADE` - Grant the scheme the permission to upgrade the controller. 45 | 46 | ### Parameters 47 | 48 | The controller holds the hash of a parameters set for each scheme. 49 | 50 | This way a scheme can define a set of parameters which are specific for an organization(defined by the controller). 51 | 52 | ## Global constraints 53 | 54 | A controller maintains and enforces global constraints for the organization. 55 | 56 | A constraint define what a "cannot be done" in the DAO. e.g limit the number of minted tokens for the DAO. 57 | 58 | The global constraints is checked before and after each controller operation. 59 | 60 | Only a scheme with the `ADD_OR_REMOVE_GLOBAL_CONSTRAINT` permission can add or remove a global constraint. 61 | -------------------------------------------------------------------------------- /docs/contracts/controller/Reputation.md: -------------------------------------------------------------------------------- 1 | # Reputation 2 | [see the generated documentation](../../generated_docs/controller/Reputation.md) 3 | 4 | A DAO has Reputation System which allows peers to rate other peers in order to build trust . A reputation is use to assign influence measure to a DAO'S peers. 5 | For example : A DAO might choose to use a reputation based voting mechanism in order to take decisions. In this case a peer with relatively higher reputation value will have more influence in the organization. 6 | *Reputation* is similar to regular tokens but with one crucial difference: **It is non-transferable**. 7 | 8 | The Reputation contract maintain a map of address to reputation value. 9 | It provides a function to mint ,negative or positive, reputation for a specific address. 10 | 11 | ### Range 12 | 13 | Max reputation allowed is capped by INT256_MAX = 2**255 - Any value minted over this MAX will cause a revert. 14 | 15 | Min reputation allowed is 0. - Any value minted below this MIN will be trim to 0. 16 | -------------------------------------------------------------------------------- /docs/contracts/controller/UController.md: -------------------------------------------------------------------------------- 1 | # UController 2 | [see the generated documentation](../../generated_docs/controller/UController.md) 3 | 4 | The `UController`(Universal Controller) is a universal implementation of the [ControllerInterface](../../generated_docs/controller/ControllerInterface.md) which behaves like a [Controller](Controller.md), but for multiple DAOs at the same time. 5 | 6 | Any DAO can initiate and register itself via the Universal Controller. 7 | 8 | As a controller it holds the DAO's organs ([Avatar](./Avatar.md), [Reputation](Reputation.md) and [DAOToken](DAOToken.md)), maintain schemes permissions and global constraints for each DAO. 9 | 10 | ## [newOrganization(...)](http://127.0.0.1:8000/generated_docs/controller/UController/#neworganizationaddress) function 11 | 12 | Using the `newOrganization`(...) function , one can create a new organization with a default scheme with full permissions. 13 | -------------------------------------------------------------------------------- /docs/contracts/globalConstraints/README.md: -------------------------------------------------------------------------------- 1 | # Global Constraints Home 2 | 3 | [see the generated documentation](../../generated_docs/globalConstraints/GlobalConstraintInterface.md) 4 | 5 | related: [TokenCapGC](TokenCapGC.md) 6 | 7 | *Global Constraint*s define certain conditions the DAO must hold at all times. More concretely, they define *pre* & *post* conditions that must hold before & after any action the DAO takes. 8 | They are meant to be *Universal* (i.e. only one deployed instance), but do not strictly need to be. 9 | 10 | When an action is about to happen, the [Controller](../controller/Controller.md) consults the *Global Constraint* and runs it's `pre` & `post` methods to see if the conditions hold. 11 | It passes the following parameters to `pre` & `post`: 12 | 13 | 1. `address scheme` - the scheme that performed the action. 14 | 2. `bytes32 hash` - a hash of the parameters to be used. 15 | 3. `bytes32 method` - what kind of event occurred, available `method`s: 16 | - `mintReputation` 17 | - `mintTokens` 18 | - `registerScheme` 19 | - `unregisterScheme` 20 | - `sendEther` 21 | - `externalTokenTransfer` 22 | - `externalTokenTransferFrom` 23 | - `externalTokenIncreaseApproval` 24 | - `externalTokenDecreaseApproval` 25 | - `genericAction` - all other actions. 26 | 27 | ## Examples 28 | 29 | ### A simple time-lock constraint for registering schemes 30 | 31 | #### Defining it 32 | 33 | We are going to define a simple global constraint that disallows registering new *Scheme*s during a certain time period. 34 | 35 | ``` 36 | import '@daostack/arc/contracts/globalConstraints/GlobalConstraintInterface.sol'; 37 | 38 | contract SchemeRegisterTimeLock is GlobalConstraintInterface{ 39 | 40 | /* Define how our parameters look like*/ 41 | struct Params{ 42 | uint start; 43 | uint end; 44 | } 45 | 46 | mapping(bytes32=>Params) public params; 47 | 48 | function setParams(uint start, uint end) returns(bytes32){ 49 | bytes32 hash = keccak256(start,end); 50 | params[hash].start = start; 51 | params[hash].end = end; 52 | return hash; 53 | } 54 | 55 | function pre(address scheme, bytes32 hash, bytes32 method) public returns(bool){ 56 | /* This runs *before* an action is taken */ 57 | 58 | /* make sure no registerations occur between `start` and `end`*/ 59 | if(method == "registerScheme" 60 | && params[hash].start <= now 61 | && now <= params[hash].end) 62 | return false; 63 | 64 | return true; 65 | } 66 | 67 | function post(address scheme, bytes32 hash, bytes32 method) public returns(bool){ 68 | /* This runs *after* an action is taken */ 69 | return true; 70 | } 71 | } 72 | ``` 73 | 74 | #### Registering it with the controller 75 | 76 | Registering a global constraint is done inside a method of a *Scheme* which is permitted to add/remove global constraints. 77 | ``` 78 | SchemeRegisterTimeLock gc = new SchemeRegisterTimeLock(); 79 | 80 | /* Somewhere inside a scheme with `ADD_OR_REMOVE_GLOBAL_CONSTRAINT` permission */ 81 | bytes32 hash = gc.setParameters(now,now + 2 days) 82 | contoller.addGlobalConstraint(address(myGlobalConstraint),hash) 83 | ``` 84 | -------------------------------------------------------------------------------- /docs/contracts/globalConstraints/TokenCapGC.md: -------------------------------------------------------------------------------- 1 | # TokenCapGC 2 | [see the generated documentation](../../generated_docs/globalConstraints/TokenCapGC.md) 3 | 4 | *TokenCapGC* is a simple global constraint that limits the number of tokens that can be issued. 5 | 6 | ## Usage 7 | 8 | ``` 9 | TokenCapGC gc = new TokenCapGC(); 10 | 11 | /* some where inside a scheme with relevent permissions */ 12 | bytes32 hash = gc.setParameters(contoller.nativeToken,100) /*limit DAO token issuance to 100*/ 13 | controller.addGlobalConstraint(gc,hash) 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/contracts/universalSchemes/README.md: -------------------------------------------------------------------------------- 1 | # Universal Schemes Home 2 | 3 | [see the generated documentation](../../generated_docs/universalSchemes/UniversalSchemeInterface.md) 4 | 5 | A Scheme defines rules the DAO follows. 6 | 7 | ## Universal Scheme 8 | 9 | *Universal Schemes* are schemes that inherit from *UniversalSchemeInterface* and are supposed to be deployed once. 10 | 11 | ## Non-universal Scheme 12 | 13 | *Non-Universal Schemes* are schemes that do not follow any standard and do not inherit from *UniversalSchemeInterface* 14 | -------------------------------------------------------------------------------- /docs/generated_docs/Migrations.md: -------------------------------------------------------------------------------- 1 | # Migrations 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/Migrations.sol) 3 | 4 | 5 | **Execution cost**: less than 20527 gas 6 | 7 | **Deployment cost**: less than 112200 gas 8 | 9 | **Combined cost**: less than 132727 gas 10 | 11 | ## Constructor 12 | 13 | 14 | 15 | 16 | 17 | 18 | ## Methods 19 | ### last_completed_migration() 20 | 21 | 22 | **Execution cost**: less than 395 gas 23 | 24 | **Attributes**: constant 25 | 26 | 27 | 28 | Returns: 29 | 30 | 31 | 1. **output_0** *of type `uint256`* 32 | 33 | --- 34 | ### owner() 35 | 36 | 37 | **Execution cost**: less than 432 gas 38 | 39 | **Attributes**: constant 40 | 41 | 42 | 43 | Returns: 44 | 45 | 46 | 1. **output_0** *of type `address`* 47 | 48 | --- 49 | ### setCompleted(uint256) 50 | 51 | 52 | **Execution cost**: less than 20451 gas 53 | 54 | 55 | Params: 56 | 57 | 1. **completed** *of type `uint256`* 58 | 59 | 60 | --- 61 | ### upgrade(address) 62 | 63 | 64 | **Execution cost**: No bound available 65 | 66 | 67 | Params: 68 | 69 | 1. **newAddress** *of type `address`* 70 | 71 | 72 | [Back to the top ↑](#migrations) 73 | -------------------------------------------------------------------------------- /docs/generated_docs/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the generated documentation! 2 | 3 | This directory contains automated documentation generated directly from `.sol` source files. 4 | They include the following info: 5 | 6 | - Gas estimates on constructors & functions. 7 | - Technical information about the exposed public interface of each contract. 8 | -------------------------------------------------------------------------------- /docs/generated_docs/VotingMachines/GenesisProtocolFormulasInterface.md: -------------------------------------------------------------------------------- 1 | # GenesisProtocolFormulasInterface 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/VotingMachines/GenesisProtocolFormulasInterface.sol) 3 | 4 | 5 | **Execution cost**: No bound available 6 | 7 | **Deployment cost**: No bound available 8 | 9 | **Combined cost**: No bound available 10 | 11 | 12 | 13 | 14 | ## Methods 15 | ### getRedeemableReputationProposer(bytes32) 16 | 17 | 18 | **Execution cost**: No bound available 19 | 20 | **Attributes**: constant 21 | 22 | 23 | Params: 24 | 25 | 1. **_proposalId** *of type `bytes32`* 26 | 27 | Returns: 28 | 29 | 30 | 1. **output_0** *of type `int256`* 31 | 32 | --- 33 | ### getRedeemableTokensStaker(bytes32,address) 34 | 35 | 36 | **Execution cost**: No bound available 37 | 38 | **Attributes**: constant 39 | 40 | 41 | Params: 42 | 43 | 1. **_proposalId** *of type `bytes32`* 44 | 2. **_staker** *of type `address`* 45 | 46 | Returns: 47 | 48 | 49 | 1. **output_0** *of type `uint256`* 50 | 51 | --- 52 | ### getRedeemableTokensVoter(bytes32,address) 53 | 54 | 55 | **Execution cost**: No bound available 56 | 57 | **Attributes**: constant 58 | 59 | 60 | Params: 61 | 62 | 1. **_proposalId** *of type `bytes32`* 63 | 2. **_beneficiary** *of type `address`* 64 | 65 | Returns: 66 | 67 | 68 | 1. **output_0** *of type `uint256`* 69 | 70 | --- 71 | ### score(bytes32) 72 | 73 | 74 | **Execution cost**: No bound available 75 | 76 | **Attributes**: constant 77 | 78 | 79 | Params: 80 | 81 | 1. **_proposalId** *of type `bytes32`* 82 | 83 | Returns: 84 | 85 | 86 | 1. **output_0** *of type `int256`* 87 | 88 | --- 89 | ### shouldBoost(bytes32) 90 | 91 | 92 | **Execution cost**: No bound available 93 | 94 | **Attributes**: constant 95 | 96 | 97 | Params: 98 | 99 | 1. **_proposalId** *of type `bytes32`* 100 | 101 | Returns: 102 | 103 | 104 | 1. **output_0** *of type `bool`* 105 | 106 | --- 107 | ### threshold(address) 108 | 109 | 110 | **Execution cost**: No bound available 111 | 112 | **Attributes**: constant 113 | 114 | 115 | Params: 116 | 117 | 1. **_avatar** *of type `address`* 118 | 119 | Returns: 120 | 121 | 122 | 1. **output_0** *of type `int256`* 123 | 124 | [Back to the top ↑](#genesisprotocolformulasinterface) 125 | -------------------------------------------------------------------------------- /docs/generated_docs/VotingMachines/IntVoteInterface.md: -------------------------------------------------------------------------------- 1 | # IntVoteInterface 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/VotingMachines/IntVoteInterface.sol) 3 | 4 | 5 | **Execution cost**: No bound available 6 | 7 | **Deployment cost**: No bound available 8 | 9 | **Combined cost**: No bound available 10 | 11 | 12 | 13 | 14 | ## Methods 15 | ### vote(bytes32,uint256) 16 | 17 | 18 | **Execution cost**: No bound available 19 | 20 | 21 | Params: 22 | 23 | 1. **_proposalId** *of type `bytes32`* 24 | 2. **_vote** *of type `uint256`* 25 | 26 | Returns: 27 | 28 | 29 | 1. **output_0** *of type `bool`* 30 | 31 | --- 32 | ### execute(bytes32) 33 | 34 | 35 | **Execution cost**: No bound available 36 | 37 | 38 | Params: 39 | 40 | 1. **_proposalId** *of type `bytes32`* 41 | 42 | Returns: 43 | 44 | 45 | 1. **output_0** *of type `bool`* 46 | 47 | --- 48 | ### cancelProposal(bytes32) 49 | 50 | 51 | **Execution cost**: No bound available 52 | 53 | 54 | Params: 55 | 56 | 1. **_proposalId** *of type `bytes32`* 57 | 58 | Returns: 59 | 60 | 61 | 1. **output_0** *of type `bool`* 62 | 63 | --- 64 | ### cancelVote(bytes32) 65 | 66 | 67 | **Execution cost**: No bound available 68 | 69 | 70 | Params: 71 | 72 | 1. **_proposalId** *of type `bytes32`* 73 | 74 | 75 | --- 76 | ### getNumberOfChoices(bytes32) 77 | 78 | 79 | **Execution cost**: No bound available 80 | 81 | **Attributes**: constant 82 | 83 | 84 | Params: 85 | 86 | 1. **_proposalId** *of type `bytes32`* 87 | 88 | Returns: 89 | 90 | 91 | 1. **output_0** *of type `uint256`* 92 | 93 | --- 94 | ### isAbstainAllow() 95 | 96 | 97 | **Execution cost**: No bound available 98 | 99 | **Attributes**: constant 100 | 101 | 102 | 103 | Returns: 104 | 105 | 106 | 1. **output_0** *of type `bool`* 107 | 108 | --- 109 | ### isVotable(bytes32) 110 | 111 | 112 | **Execution cost**: No bound available 113 | 114 | **Attributes**: constant 115 | 116 | 117 | Params: 118 | 119 | 1. **_proposalId** *of type `bytes32`* 120 | 121 | Returns: 122 | 123 | 124 | 1. **output_0** *of type `bool`* 125 | 126 | --- 127 | ### ownerVote(bytes32,uint256,address) 128 | 129 | 130 | **Execution cost**: No bound available 131 | 132 | 133 | Params: 134 | 135 | 1. **_proposalId** *of type `bytes32`* 136 | 2. **_vote** *of type `uint256`* 137 | 3. **_voter** *of type `address`* 138 | 139 | Returns: 140 | 141 | 142 | 1. **output_0** *of type `bool`* 143 | 144 | --- 145 | ### propose(uint256,bytes32,address,address,address) 146 | 147 | 148 | **Execution cost**: No bound available 149 | 150 | 151 | Params: 152 | 153 | 1. **_numOfChoices** *of type `uint256`* 154 | 2. **_proposalParameters** *of type `bytes32`* 155 | 3. **_avatar** *of type `address`* 156 | 4. **_executable** *of type `address`* 157 | 5. **_proposer** *of type `address`* 158 | 159 | Returns: 160 | 161 | 162 | 1. **output_0** *of type `bytes32`* 163 | 164 | --- 165 | ### voteStatus(bytes32,uint256) 166 | 167 | 168 | **Execution cost**: No bound available 169 | 170 | **Attributes**: constant 171 | 172 | 173 | Params: 174 | 175 | 1. **_proposalId** *of type `bytes32`* 176 | 2. **_choice** *of type `uint256`* 177 | 178 | Returns: 179 | 180 | 181 | 1. **output_0** *of type `uint256`* 182 | 183 | --- 184 | ### voteWithSpecifiedAmounts(bytes32,uint256,uint256,uint256) 185 | 186 | 187 | **Execution cost**: No bound available 188 | 189 | 190 | Params: 191 | 192 | 1. **_proposalId** *of type `bytes32`* 193 | 2. **_vote** *of type `uint256`* 194 | 3. **_rep** *of type `uint256`* 195 | 4. **_token** *of type `uint256`* 196 | 197 | Returns: 198 | 199 | 200 | 1. **output_0** *of type `bool`* 201 | 202 | [Back to the top ↑](#intvoteinterface) 203 | -------------------------------------------------------------------------------- /docs/generated_docs/controller/ActionInterface.md: -------------------------------------------------------------------------------- 1 | # ActionInterface 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/controller/Avatar.sol) 3 | 4 | 5 | **Execution cost**: No bound available 6 | 7 | **Deployment cost**: No bound available 8 | 9 | **Combined cost**: No bound available 10 | 11 | 12 | 13 | 14 | ## Methods 15 | ### action(bytes32[]) 16 | 17 | 18 | **Execution cost**: No bound available 19 | 20 | 21 | Params: 22 | 23 | 1. **_params** *of type `bytes32[]`* 24 | 25 | Returns: 26 | 27 | 28 | 1. **output_0** *of type `bool`* 29 | 30 | [Back to the top ↑](#actioninterface) 31 | -------------------------------------------------------------------------------- /docs/generated_docs/controller/Reputation.md: -------------------------------------------------------------------------------- 1 | # Reputation 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/controller/Reputation.sol) 3 | > Reputation system 4 | 5 | 6 | **Execution cost**: less than 40630 gas 7 | 8 | **Deployment cost**: less than 234600 gas 9 | 10 | **Combined cost**: less than 275230 gas 11 | 12 | 13 | ## Events 14 | ### Burn(address,uint256) 15 | 16 | 17 | **Execution cost**: No bound available 18 | 19 | 20 | Params: 21 | 22 | 1. **_from** *of type `address`* 23 | 2. **_amount** *of type `uint256`* 24 | 25 | --- 26 | ### Mint(address,uint256) 27 | 28 | 29 | **Execution cost**: No bound available 30 | 31 | 32 | Params: 33 | 34 | 1. **_to** *of type `address`* 35 | 2. **_amount** *of type `uint256`* 36 | 37 | --- 38 | ### OwnershipTransferred(address,address) 39 | 40 | 41 | **Execution cost**: No bound available 42 | 43 | 44 | Params: 45 | 46 | 1. **previousOwner** *of type `address`* 47 | 2. **newOwner** *of type `address`* 48 | 49 | 50 | ## Methods 51 | ### balances(address) 52 | 53 | 54 | **Execution cost**: less than 542 gas 55 | 56 | **Attributes**: constant 57 | 58 | 59 | Params: 60 | 61 | 1. **param_0** *of type `address`* 62 | 63 | Returns: 64 | 65 | 66 | 1. **output_0** *of type `uint256`* 67 | 68 | --- 69 | ### burn(address,uint256) 70 | > 71 | > Burns `_amount` of reputation from `_from` if _amount tokens to burn > balances[_from] the balance of _from will turn to zero. 72 | 73 | 74 | **Execution cost**: No bound available 75 | 76 | 77 | Params: 78 | 79 | 1. **_from** *of type `address`* 80 | 81 | > The address that will lose the reputation 82 | 83 | 2. **_amount** *of type `uint256`* 84 | 85 | > The quantity of reputation to burn 86 | 87 | 88 | Returns: 89 | 90 | > True if the reputation are burned correctly 91 | 92 | 1. **output_0** *of type `bool`* 93 | 94 | --- 95 | ### decimals() 96 | 97 | 98 | **Execution cost**: less than 417 gas 99 | 100 | **Attributes**: constant 101 | 102 | 103 | 104 | Returns: 105 | 106 | 107 | 1. **output_0** *of type `uint256`* 108 | 109 | --- 110 | ### mint(address,uint256) 111 | > 112 | > Generates `_amount` of reputation that are assigned to `_to` 113 | 114 | 115 | **Execution cost**: No bound available 116 | 117 | 118 | Params: 119 | 120 | 1. **_to** *of type `address`* 121 | 122 | > The address that will be assigned the new reputation 123 | 124 | 2. **_amount** *of type `uint256`* 125 | 126 | > The quantity of reputation to be generated 127 | 128 | 129 | Returns: 130 | 131 | > True if the reputation are generated correctly 132 | 133 | 1. **output_0** *of type `bool`* 134 | 135 | --- 136 | ### owner() 137 | 138 | 139 | **Execution cost**: less than 617 gas 140 | 141 | **Attributes**: constant 142 | 143 | 144 | 145 | Returns: 146 | 147 | 148 | 1. **output_0** *of type `address`* 149 | 150 | --- 151 | ### reputationOf(address) 152 | > 153 | > return the reputation amount of a given owner 154 | 155 | 156 | **Execution cost**: less than 727 gas 157 | 158 | **Attributes**: constant 159 | 160 | 161 | Params: 162 | 163 | 1. **_owner** *of type `address`* 164 | 165 | > an address of the owner which we want to get his reputation 166 | 167 | 168 | Returns: 169 | 170 | 171 | 1. **balance** *of type `uint256`* 172 | 173 | --- 174 | ### totalSupply() 175 | 176 | 177 | **Execution cost**: less than 373 gas 178 | 179 | **Attributes**: constant 180 | 181 | 182 | 183 | Returns: 184 | 185 | 186 | 1. **output_0** *of type `uint256`* 187 | 188 | --- 189 | ### transferOwnership(address) 190 | > 191 | > Allows the current owner to transfer control of the contract to a newOwner. 192 | 193 | 194 | **Execution cost**: less than 22898 gas 195 | 196 | 197 | Params: 198 | 199 | 1. **newOwner** *of type `address`* 200 | 201 | > The address to transfer ownership to. 202 | 203 | 204 | 205 | [Back to the top ↑](#reputation) 206 | -------------------------------------------------------------------------------- /docs/generated_docs/globalConstraints/GlobalConstraintInterface.md: -------------------------------------------------------------------------------- 1 | # GlobalConstraintInterface 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/globalConstraints/GlobalConstraintInterface.sol) 3 | 4 | 5 | **Execution cost**: No bound available 6 | 7 | **Deployment cost**: No bound available 8 | 9 | **Combined cost**: No bound available 10 | 11 | 12 | 13 | 14 | ## Methods 15 | ### post(address,bytes32,bytes32) 16 | 17 | 18 | **Execution cost**: No bound available 19 | 20 | 21 | Params: 22 | 23 | 1. **_scheme** *of type `address`* 24 | 2. **_params** *of type `bytes32`* 25 | 3. **_method** *of type `bytes32`* 26 | 27 | Returns: 28 | 29 | 30 | 1. **output_0** *of type `bool`* 31 | 32 | --- 33 | ### pre(address,bytes32,bytes32) 34 | 35 | 36 | **Execution cost**: No bound available 37 | 38 | 39 | Params: 40 | 41 | 1. **_scheme** *of type `address`* 42 | 2. **_params** *of type `bytes32`* 43 | 3. **_method** *of type `bytes32`* 44 | 45 | Returns: 46 | 47 | 48 | 1. **output_0** *of type `bool`* 49 | 50 | --- 51 | ### when() 52 | 53 | 54 | **Execution cost**: No bound available 55 | 56 | 57 | 58 | Returns: 59 | 60 | 61 | 1. **output_0** *of type `uint8`* 62 | 63 | [Back to the top ↑](#globalconstraintinterface) 64 | -------------------------------------------------------------------------------- /docs/generated_docs/globalConstraints/TokenCapGC.md: -------------------------------------------------------------------------------- 1 | # TokenCapGC 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/globalConstraints/TokenCapGC.sol) 3 | > Token Cap Global Constraint 4 | 5 | 6 | **Execution cost**: less than 209 gas 7 | 8 | **Deployment cost**: less than 169800 gas 9 | 10 | **Combined cost**: less than 170009 gas 11 | 12 | 13 | 14 | 15 | ## Methods 16 | ### getParametersHash(address,uint256) 17 | > 18 | > calculate and returns the hash of the given parameters 19 | 20 | 21 | **Execution cost**: less than 485 gas 22 | 23 | **Attributes**: constant 24 | 25 | 26 | Params: 27 | 28 | 1. **_token** *of type `address`* 29 | 30 | > the token to add to the params. 31 | 32 | 2. **_cap** *of type `uint256`* 33 | 34 | > the cap to check the total supply against. 35 | 36 | 37 | Returns: 38 | 39 | > the calculated parameters hash 40 | 41 | 1. **output_0** *of type `bytes32`* 42 | 43 | --- 44 | ### parameters(bytes32) 45 | 46 | 47 | **Execution cost**: less than 846 gas 48 | 49 | **Attributes**: constant 50 | 51 | 52 | Params: 53 | 54 | 1. **param_0** *of type `bytes32`* 55 | 56 | Returns: 57 | 58 | 59 | 1. **token** *of type `address`* 60 | 2. **cap** *of type `uint256`* 61 | 62 | --- 63 | ### post(address,bytes32,bytes32) 64 | > 65 | > check the total supply cap. 66 | 67 | 68 | **Execution cost**: No bound available 69 | 70 | **Attributes**: constant 71 | 72 | 73 | Params: 74 | 75 | 1. **param_0** *of type `address`* 76 | 2. **_paramsHash** *of type `bytes32`* 77 | 78 | > the parameters hash to check the total supply cap against. 79 | 80 | 3. **param_2** *of type `bytes32`* 81 | 82 | Returns: 83 | 84 | > bool which represents a success 85 | 86 | 1. **output_0** *of type `bool`* 87 | 88 | --- 89 | ### pre(address,bytes32,bytes32) 90 | > 91 | > check the constraint after the action. This global constraint only checks the state after the action, so here we just return true: 92 | 93 | 94 | **Execution cost**: less than 347 gas 95 | 96 | **Attributes**: constant 97 | 98 | 99 | Params: 100 | 101 | 1. **param_0** *of type `address`* 102 | 2. **param_1** *of type `bytes32`* 103 | 3. **param_2** *of type `bytes32`* 104 | 105 | Returns: 106 | 107 | > true 108 | 109 | 1. **output_0** *of type `bool`* 110 | 111 | --- 112 | ### setParameters(address,uint256) 113 | > 114 | > adding a new set of parameters 115 | 116 | 117 | **Execution cost**: less than 40998 gas 118 | 119 | 120 | Params: 121 | 122 | 1. **_token** *of type `address`* 123 | 124 | > the token to add to the params. 125 | 126 | 2. **_cap** *of type `uint256`* 127 | 128 | > the cap to check the total supply against. 129 | 130 | 131 | Returns: 132 | 133 | > the calculated parameters hash 134 | 135 | 1. **output_0** *of type `bytes32`* 136 | 137 | --- 138 | ### when() 139 | > 140 | > when return if this globalConstraints is pre, post or both. 141 | 142 | 143 | **Execution cost**: less than 325 gas 144 | 145 | **Attributes**: constant 146 | 147 | 148 | 149 | Returns: 150 | 151 | > CallPhase enum indication Pre, Post or PreAndPost. 152 | 153 | 1. **output_0** *of type `uint8`* 154 | 155 | [Back to the top ↑](#tokencapgc) 156 | -------------------------------------------------------------------------------- /docs/generated_docs/test/ActionMock.md: -------------------------------------------------------------------------------- 1 | # ActionMock 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/test/ActionMock.sol) 3 | 4 | 5 | **Execution cost**: less than 191 gas 6 | 7 | **Deployment cost**: less than 152800 gas 8 | 9 | **Combined cost**: less than 152991 gas 10 | 11 | 12 | ## Events 13 | ### Action(address,bytes32) 14 | 15 | 16 | **Execution cost**: No bound available 17 | 18 | 19 | Params: 20 | 21 | 1. **_sender** *of type `address`* 22 | 2. **_param** *of type `bytes32`* 23 | 24 | 25 | ## Methods 26 | ### action(bytes32[]) 27 | 28 | 29 | **Execution cost**: No bound available 30 | 31 | 32 | Params: 33 | 34 | 1. **params** *of type `bytes32[]`* 35 | 36 | Returns: 37 | 38 | 39 | 1. **output_0** *of type `bool`* 40 | 41 | --- 42 | ### genericAction(address,bytes32[]) 43 | 44 | 45 | **Execution cost**: No bound available 46 | 47 | 48 | Params: 49 | 50 | 1. **avatar** *of type `address`* 51 | 2. **params** *of type `bytes32[]`* 52 | 53 | Returns: 54 | 55 | 56 | 1. **output_0** *of type `bool`* 57 | 58 | [Back to the top ↑](#actionmock) 59 | -------------------------------------------------------------------------------- /docs/generated_docs/test/Debug.md: -------------------------------------------------------------------------------- 1 | # Debug 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/test/Debug.sol) 3 | 4 | 5 | **Execution cost**: less than 61 gas 6 | 7 | **Deployment cost**: less than 10600 gas 8 | 9 | **Combined cost**: less than 10661 gas 10 | 11 | 12 | ## Events 13 | ### LogAddress(address) 14 | 15 | 16 | **Execution cost**: No bound available 17 | 18 | 19 | Params: 20 | 21 | 1. **_msg** *of type `address`* 22 | 23 | --- 24 | ### LogBool(bool) 25 | 26 | 27 | **Execution cost**: No bound available 28 | 29 | 30 | Params: 31 | 32 | 1. **_msg** *of type `bool`* 33 | 34 | --- 35 | ### LogBytes(bytes) 36 | 37 | 38 | **Execution cost**: No bound available 39 | 40 | 41 | Params: 42 | 43 | 1. **_msg** *of type `bytes`* 44 | 45 | --- 46 | ### LogBytes32(bytes32) 47 | 48 | 49 | **Execution cost**: No bound available 50 | 51 | 52 | Params: 53 | 54 | 1. **_msg** *of type `bytes32`* 55 | 56 | --- 57 | ### LogInt(int256) 58 | 59 | 60 | **Execution cost**: No bound available 61 | 62 | 63 | Params: 64 | 65 | 1. **_msg** *of type `int256`* 66 | 67 | --- 68 | ### LogString(string) 69 | 70 | 71 | **Execution cost**: No bound available 72 | 73 | 74 | Params: 75 | 76 | 1. **_msg** *of type `string`* 77 | 78 | --- 79 | ### LogUint(uint256) 80 | 81 | 82 | **Execution cost**: No bound available 83 | 84 | 85 | Params: 86 | 87 | 1. **_msg** *of type `uint256`* 88 | 89 | 90 | 91 | [Back to the top ↑](#debug) 92 | -------------------------------------------------------------------------------- /docs/generated_docs/test/ExecutableTest.md: -------------------------------------------------------------------------------- 1 | # ExecutableTest 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/test/ExecutableTest.sol) 3 | 4 | 5 | **Execution cost**: less than 118 gas 6 | 7 | **Deployment cost**: less than 74000 gas 8 | 9 | **Combined cost**: less than 74118 gas 10 | 11 | 12 | ## Events 13 | ### LogAddress(address) 14 | 15 | 16 | **Execution cost**: No bound available 17 | 18 | 19 | Params: 20 | 21 | 1. **_msg** *of type `address`* 22 | 23 | --- 24 | ### LogBool(bool) 25 | 26 | 27 | **Execution cost**: No bound available 28 | 29 | 30 | Params: 31 | 32 | 1. **_msg** *of type `bool`* 33 | 34 | --- 35 | ### LogBytes(bytes) 36 | 37 | 38 | **Execution cost**: No bound available 39 | 40 | 41 | Params: 42 | 43 | 1. **_msg** *of type `bytes`* 44 | 45 | --- 46 | ### LogBytes32(bytes32) 47 | 48 | 49 | **Execution cost**: No bound available 50 | 51 | 52 | Params: 53 | 54 | 1. **_msg** *of type `bytes32`* 55 | 56 | --- 57 | ### LogInt(int256) 58 | 59 | 60 | **Execution cost**: No bound available 61 | 62 | 63 | Params: 64 | 65 | 1. **_msg** *of type `int256`* 66 | 67 | --- 68 | ### LogString(string) 69 | 70 | 71 | **Execution cost**: No bound available 72 | 73 | 74 | Params: 75 | 76 | 1. **_msg** *of type `string`* 77 | 78 | --- 79 | ### LogUint(uint256) 80 | 81 | 82 | **Execution cost**: No bound available 83 | 84 | 85 | Params: 86 | 87 | 1. **_msg** *of type `uint256`* 88 | 89 | 90 | ## Methods 91 | ### execute(bytes32,address,int256) 92 | 93 | 94 | **Execution cost**: less than 3379 gas 95 | 96 | 97 | Params: 98 | 99 | 1. **_proposalId** *of type `bytes32`* 100 | 2. **_avatar** *of type `address`* 101 | 3. **_param** *of type `int256`* 102 | 103 | Returns: 104 | 105 | 106 | 1. **output_0** *of type `bool`* 107 | 108 | [Back to the top ↑](#executabletest) 109 | -------------------------------------------------------------------------------- /docs/generated_docs/test/GenesisProtocolFormulasMock.md: -------------------------------------------------------------------------------- 1 | # GenesisProtocolFormulasMock 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/test/GenesisProtocolFormulasMock.sol) 3 | 4 | 5 | **Execution cost**: less than 450 gas 6 | 7 | **Deployment cost**: less than 416400 gas 8 | 9 | **Combined cost**: less than 416850 gas 10 | 11 | 12 | 13 | 14 | ## Methods 15 | ### getRedeemableReputationProposer(bytes32) 16 | 17 | 18 | **Execution cost**: less than 354 gas 19 | 20 | **Attributes**: constant 21 | 22 | 23 | Params: 24 | 25 | 1. **param_0** *of type `bytes32`* 26 | 27 | Returns: 28 | 29 | 30 | 1. **output_0** *of type `int256`* 31 | 32 | --- 33 | ### getRedeemableTokensStaker(bytes32,address) 34 | 35 | 36 | **Execution cost**: No bound available 37 | 38 | **Attributes**: constant 39 | 40 | 41 | Params: 42 | 43 | 1. **_proposalId** *of type `bytes32`* 44 | 2. **_staker** *of type `address`* 45 | 46 | Returns: 47 | 48 | 49 | 1. **output_0** *of type `uint256`* 50 | 51 | --- 52 | ### getRedeemableTokensVoter(bytes32,address) 53 | 54 | 55 | **Execution cost**: less than 374 gas 56 | 57 | **Attributes**: constant 58 | 59 | 60 | Params: 61 | 62 | 1. **param_0** *of type `bytes32`* 63 | 2. **param_1** *of type `address`* 64 | 65 | Returns: 66 | 67 | 68 | 1. **output_0** *of type `uint256`* 69 | 70 | --- 71 | ### score(bytes32) 72 | > 73 | > score return the proposal score 74 | 75 | 76 | **Execution cost**: No bound available 77 | 78 | **Attributes**: constant 79 | 80 | 81 | Params: 82 | 83 | 1. **_proposalId** *of type `bytes32`* 84 | 85 | > the ID of the proposal 86 | 87 | 88 | Returns: 89 | 90 | > uint proposal score. 91 | 92 | 1. **output_0** *of type `int256`* 93 | 94 | --- 95 | ### shouldBoost(bytes32) 96 | > 97 | > isBoost check if the proposal will shift to the relative voting phase. 98 | 99 | 100 | **Execution cost**: No bound available 101 | 102 | **Attributes**: constant 103 | 104 | 105 | Params: 106 | 107 | 1. **_proposalId** *of type `bytes32`* 108 | 109 | > the ID of the proposal 110 | 111 | 112 | Returns: 113 | 114 | > bool true or false. 115 | 116 | 1. **output_0** *of type `bool`* 117 | 118 | --- 119 | ### threshold(address) 120 | > 121 | > threshold return the organization's score threshold which required by a proposal to shift to boosted state. This threshold is dynamically set and it depend on the number of boosted proposal. 122 | 123 | 124 | **Execution cost**: No bound available 125 | 126 | **Attributes**: constant 127 | 128 | 129 | Params: 130 | 131 | 1. **_avatar** *of type `address`* 132 | 133 | > the organization avatar 134 | 135 | 136 | Returns: 137 | 138 | > int thresholdConstA. 139 | 140 | 1. **output_0** *of type `int256`* 141 | 142 | [Back to the top ↑](#genesisprotocolformulasmock) 143 | -------------------------------------------------------------------------------- /docs/generated_docs/test/GlobalConstraintMock.md: -------------------------------------------------------------------------------- 1 | # GlobalConstraintMock 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/test/GlobalConstraintMock.sol) 3 | 4 | 5 | **Execution cost**: less than 178 gas 6 | 7 | **Deployment cost**: less than 136400 gas 8 | 9 | **Combined cost**: less than 136578 gas 10 | 11 | 12 | 13 | 14 | ## Methods 15 | ### currentCallPhase() 16 | 17 | 18 | **Execution cost**: less than 421 gas 19 | 20 | **Attributes**: constant 21 | 22 | 23 | 24 | Returns: 25 | 26 | 27 | 1. **output_0** *of type `uint8`* 28 | 29 | --- 30 | ### post(address,bytes32,bytes32) 31 | 32 | 33 | **Execution cost**: less than 562 gas 34 | 35 | **Attributes**: constant 36 | 37 | 38 | Params: 39 | 40 | 1. **param_0** *of type `address`* 41 | 2. **param_1** *of type `bytes32`* 42 | 3. **method** *of type `bytes32`* 43 | 44 | Returns: 45 | 46 | 47 | 1. **output_0** *of type `bool`* 48 | 49 | --- 50 | ### pre(address,bytes32,bytes32) 51 | 52 | 53 | **Execution cost**: less than 573 gas 54 | 55 | **Attributes**: constant 56 | 57 | 58 | Params: 59 | 60 | 1. **param_0** *of type `address`* 61 | 2. **param_1** *of type `bytes32`* 62 | 3. **method** *of type `bytes32`* 63 | 64 | Returns: 65 | 66 | 67 | 1. **output_0** *of type `bool`* 68 | 69 | --- 70 | ### setConstraint(bytes32,bool,bool) 71 | 72 | 73 | **Execution cost**: less than 40910 gas 74 | 75 | 76 | Params: 77 | 78 | 1. **method** *of type `bytes32`* 79 | 2. **pre** *of type `bool`* 80 | 3. **post** *of type `bool`* 81 | 82 | Returns: 83 | 84 | 85 | 1. **output_0** *of type `bool`* 86 | 87 | --- 88 | ### testParams(bytes32) 89 | 90 | 91 | **Execution cost**: less than 554 gas 92 | 93 | **Attributes**: constant 94 | 95 | 96 | Params: 97 | 98 | 1. **param_0** *of type `bytes32`* 99 | 100 | Returns: 101 | 102 | 103 | 1. **pre** *of type `bool`* 104 | 2. **post** *of type `bool`* 105 | 106 | --- 107 | ### when() 108 | 109 | 110 | **Execution cost**: less than 531 gas 111 | 112 | **Attributes**: constant 113 | 114 | 115 | 116 | Returns: 117 | 118 | 119 | 1. **output_0** *of type `uint8`* 120 | 121 | [Back to the top ↑](#globalconstraintmock) 122 | -------------------------------------------------------------------------------- /docs/generated_docs/test/UniversalSchemeMock.md: -------------------------------------------------------------------------------- 1 | # UniversalSchemeMock 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/test/UniversalSchemeMock.sol) 3 | 4 | 5 | **Execution cost**: less than 20515 gas 6 | 7 | **Deployment cost**: less than 98600 gas 8 | 9 | **Combined cost**: less than 119115 gas 10 | 11 | ## Constructor 12 | 13 | 14 | 15 | 16 | ## Events 17 | ### OwnershipTransferred(address,address) 18 | 19 | 20 | **Execution cost**: No bound available 21 | 22 | 23 | Params: 24 | 25 | 1. **previousOwner** *of type `address`* 26 | 2. **newOwner** *of type `address`* 27 | 28 | 29 | ## Methods 30 | ### hashedParameters() 31 | 32 | 33 | **Execution cost**: less than 439 gas 34 | 35 | **Attributes**: constant 36 | 37 | 38 | 39 | Returns: 40 | 41 | 42 | 1. **output_0** *of type `bytes32`* 43 | 44 | --- 45 | ### owner() 46 | 47 | 48 | **Execution cost**: less than 548 gas 49 | 50 | **Attributes**: constant 51 | 52 | 53 | 54 | Returns: 55 | 56 | 57 | 1. **output_0** *of type `address`* 58 | 59 | --- 60 | ### transferOwnership(address) 61 | > 62 | > Allows the current owner to transfer control of the contract to a newOwner. 63 | 64 | 65 | **Execution cost**: less than 22788 gas 66 | 67 | 68 | Params: 69 | 70 | 1. **newOwner** *of type `address`* 71 | 72 | > The address to transfer ownership to. 73 | 74 | 75 | 76 | --- 77 | ### updateParameters(bytes32) 78 | 79 | 80 | **Execution cost**: less than 20443 gas 81 | 82 | 83 | Params: 84 | 85 | 1. **_hashedParameters** *of type `bytes32`* 86 | 87 | 88 | [Back to the top ↑](#universalschememock) 89 | -------------------------------------------------------------------------------- /docs/generated_docs/universalSchemes/ControllerCreator.md: -------------------------------------------------------------------------------- 1 | # ControllerCreator 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/universalSchemes/DaoCreator.sol) 3 | > ControllerCreator for creating a single controller. 4 | 5 | 6 | **Execution cost**: less than 3320 gas 7 | 8 | **Deployment cost**: less than 3026600 gas 9 | 10 | **Combined cost**: less than 3029920 gas 11 | 12 | 13 | 14 | 15 | ## Methods 16 | ### create(address) 17 | 18 | 19 | **Execution cost**: No bound available 20 | 21 | 22 | Params: 23 | 24 | 1. **_avatar** *of type `address`* 25 | 26 | Returns: 27 | 28 | 29 | 1. **output_0** *of type `address`* 30 | 31 | [Back to the top ↑](#controllercreator) 32 | -------------------------------------------------------------------------------- /docs/generated_docs/universalSchemes/DaoCreator.md: -------------------------------------------------------------------------------- 1 | # DaoCreator 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/universalSchemes/DaoCreator.sol) 3 | > Genesis Scheme that creates organizations 4 | 5 | 6 | **Execution cost**: less than 22864 gas 7 | 8 | **Deployment cost**: less than 2275200 gas 9 | 10 | **Combined cost**: less than 2298064 gas 11 | 12 | ## Constructor 13 | 14 | 15 | 16 | Params: 17 | 18 | 1. **_controllerCreator** *of type `address`* 19 | 20 | ## Events 21 | ### InitialSchemesSet(address) 22 | 23 | 24 | **Execution cost**: No bound available 25 | 26 | 27 | Params: 28 | 29 | 1. **_avatar** *of type `address`* 30 | 31 | --- 32 | ### NewOrg(address) 33 | 34 | 35 | **Execution cost**: No bound available 36 | 37 | 38 | Params: 39 | 40 | 1. **_avatar** *of type `address`* 41 | 42 | 43 | ## Methods 44 | ### forgeOrg(bytes32,string,string,address[],uint256[],uint256[],address,uint256) 45 | > 46 | > Create a new organization 47 | 48 | 49 | **Execution cost**: No bound available 50 | 51 | 52 | Params: 53 | 54 | 1. **_orgName** *of type `bytes32`* 55 | 56 | > The name of the new organization 57 | 58 | 2. **_tokenName** *of type `string`* 59 | 60 | > The name of the token associated with the organization 61 | 62 | 3. **_tokenSymbol** *of type `string`* 63 | 64 | > The symbol of the token 65 | 66 | 4. **_founders** *of type `address[]`* 67 | 68 | > An array with the addresses of the founders of the organization 69 | 70 | 5. **_foundersTokenAmount** *of type `uint256[]`* 71 | 72 | > An array of amount of tokens that the founders receive in the new organization 73 | 74 | 6. **_foundersReputationAmount** *of type `uint256[]`* 75 | 76 | > An array of amount of reputation that the founders receive in the new organization 77 | 78 | 7. **_uController** *of type `address`* 79 | 80 | > universal controller instance if _uController address equal to zero the organization will use none universal controller. 81 | 82 | 8. **_cap** *of type `uint256`* 83 | 84 | > token cap - 0 for no cap. 85 | 86 | 87 | Returns: 88 | 89 | > The address of the avatar of the controller 90 | 91 | 1. **output_0** *of type `address`* 92 | 93 | --- 94 | ### locks(address) 95 | 96 | 97 | **Execution cost**: less than 739 gas 98 | 99 | **Attributes**: constant 100 | 101 | 102 | Params: 103 | 104 | 1. **param_0** *of type `address`* 105 | 106 | Returns: 107 | 108 | 109 | 1. **output_0** *of type `address`* 110 | 111 | --- 112 | ### setSchemes(address,address[],bytes32[],bytes4[]) 113 | > 114 | > Set initial schemes for the organization. 115 | 116 | 117 | **Execution cost**: No bound available 118 | 119 | 120 | Params: 121 | 122 | 1. **_avatar** *of type `address`* 123 | 124 | > organization avatar (returns from forgeOrg) 125 | 126 | 2. **_schemes** *of type `address[]`* 127 | 128 | > the schemes to register for the organization 129 | 130 | 3. **_params** *of type `bytes32[]`* 131 | 132 | > the schemes's params 133 | 134 | 4. **_permissions** *of type `bytes4[]`* 135 | 136 | > the schemes permissions. 137 | 138 | 139 | 140 | [Back to the top ↑](#daocreator) 141 | -------------------------------------------------------------------------------- /docs/generated_docs/universalSchemes/ExecutableInterface.md: -------------------------------------------------------------------------------- 1 | # ExecutableInterface 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/universalSchemes/ExecutableInterface.sol) 3 | 4 | 5 | **Execution cost**: No bound available 6 | 7 | **Deployment cost**: No bound available 8 | 9 | **Combined cost**: No bound available 10 | 11 | 12 | 13 | 14 | ## Methods 15 | ### execute(bytes32,address,int256) 16 | 17 | 18 | **Execution cost**: No bound available 19 | 20 | 21 | Params: 22 | 23 | 1. **_proposalId** *of type `bytes32`* 24 | 2. **_avatar** *of type `address`* 25 | 3. **_param** *of type `int256`* 26 | 27 | Returns: 28 | 29 | 30 | 1. **output_0** *of type `bool`* 31 | 32 | [Back to the top ↑](#executableinterface) 33 | -------------------------------------------------------------------------------- /docs/generated_docs/universalSchemes/MirrorContractICO.md: -------------------------------------------------------------------------------- 1 | # MirrorContractICO 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/universalSchemes/SimpleICO.sol) 3 | > An avatar contract for ICO. 4 | 5 | 6 | **Execution cost**: less than 61130 gas 7 | 8 | **Deployment cost**: less than 155800 gas 9 | 10 | **Combined cost**: less than 216930 gas 11 | 12 | ## Constructor 13 | 14 | 15 | 16 | Params: 17 | 18 | 1. **_organization** *of type `address`* 19 | 2. **_simpleICO** *of type `address`* 20 | 21 | ## Events 22 | ### OwnershipTransferred(address,address) 23 | 24 | 25 | **Execution cost**: No bound available 26 | 27 | 28 | Params: 29 | 30 | 1. **previousOwner** *of type `address`* 31 | 2. **newOwner** *of type `address`* 32 | 33 | ## Fallback 34 | 35 | 36 | **Execution cost**: No bound available 37 | 38 | **Attributes**: payable 39 | 40 | 41 | 42 | ## Methods 43 | ### destroy() 44 | > 45 | > Transfers the current balance to the owner and terminates the contract. 46 | 47 | 48 | **Execution cost**: No bound available 49 | 50 | 51 | 52 | 53 | --- 54 | ### destroyAndSend(address) 55 | 56 | 57 | **Execution cost**: No bound available 58 | 59 | 60 | Params: 61 | 62 | 1. **_recipient** *of type `address`* 63 | 64 | 65 | --- 66 | ### organization() 67 | 68 | 69 | **Execution cost**: No bound available 70 | 71 | **Attributes**: constant 72 | 73 | 74 | 75 | Returns: 76 | 77 | 78 | 1. **output_0** *of type `address`* 79 | 80 | --- 81 | ### owner() 82 | 83 | 84 | **Execution cost**: No bound available 85 | 86 | **Attributes**: constant 87 | 88 | 89 | 90 | Returns: 91 | 92 | 93 | 1. **output_0** *of type `address`* 94 | 95 | --- 96 | ### simpleICO() 97 | 98 | 99 | **Execution cost**: No bound available 100 | 101 | **Attributes**: constant 102 | 103 | 104 | 105 | Returns: 106 | 107 | 108 | 1. **output_0** *of type `address`* 109 | 110 | --- 111 | ### transferOwnership(address) 112 | > 113 | > Allows the current owner to transfer control of the contract to a newOwner. 114 | 115 | 116 | **Execution cost**: No bound available 117 | 118 | 119 | Params: 120 | 121 | 1. **newOwner** *of type `address`* 122 | 123 | > The address to transfer ownership to. 124 | 125 | 126 | 127 | [Back to the top ↑](#mirrorcontractico) 128 | -------------------------------------------------------------------------------- /docs/generated_docs/universalSchemes/OrganizationRegister.md: -------------------------------------------------------------------------------- 1 | # OrganizationRegister 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/universalSchemes/OrganizationRegister.sol) 3 | > A universal organization registry. 4 | 5 | 6 | **Execution cost**: less than 20754 gas 7 | 8 | **Deployment cost**: less than 350200 gas 9 | 10 | **Combined cost**: less than 370954 gas 11 | 12 | ## Constructor 13 | 14 | 15 | 16 | 17 | ## Events 18 | ### OrgAdded(address,address) 19 | 20 | 21 | **Execution cost**: No bound available 22 | 23 | 24 | Params: 25 | 26 | 1. **_registry** *of type `address`* 27 | 2. **_org** *of type `address`* 28 | 29 | --- 30 | ### OwnershipTransferred(address,address) 31 | 32 | 33 | **Execution cost**: No bound available 34 | 35 | 36 | Params: 37 | 38 | 1. **previousOwner** *of type `address`* 39 | 2. **newOwner** *of type `address`* 40 | 41 | --- 42 | ### Promotion(address,address,uint256) 43 | 44 | 45 | **Execution cost**: No bound available 46 | 47 | 48 | Params: 49 | 50 | 1. **_registry** *of type `address`* 51 | 2. **_org** *of type `address`* 52 | 3. **_amount** *of type `uint256`* 53 | 54 | 55 | ## Methods 56 | ### addOrPromoteAddress(address,address,uint256) 57 | > 58 | > Adding or promoting an address on the registry. An address(record) to add or promote can be organization address or any contract address. Adding a record is done by paying at least the minimum required by the registry params. Promoting a record is done by paying(adding)amount of token to the registry beneficiary. 59 | 60 | 61 | **Execution cost**: No bound available 62 | 63 | 64 | Params: 65 | 66 | 1. **_avatar** *of type `address`* 67 | 68 | > The _avatar of the organization which own the registry. 69 | 70 | 2. **_record** *of type `address`* 71 | 72 | > The address to add or promote. 73 | 74 | 3. **_amount** *of type `uint256`* 75 | 76 | > amount to pay for adding or promoting 77 | 78 | 79 | 80 | --- 81 | ### getParametersHash(address,uint256,address) 82 | > 83 | > Hash the parameters ,and return the hash value 84 | 85 | 86 | **Execution cost**: less than 722 gas 87 | 88 | **Attributes**: constant 89 | 90 | 91 | Params: 92 | 93 | 1. **_token** *of type `address`* 94 | 95 | > - the token to pay for register or promotion an address. 96 | 97 | 2. **_fee** *of type `uint256`* 98 | 99 | > - fee needed for register an address. 100 | 101 | 3. **_beneficiary** *of type `address`* 102 | 103 | > - the beneficiary payment address 104 | 105 | 106 | Returns: 107 | 108 | > bytes32 -the parameters hash 109 | 110 | 1. **output_0** *of type `bytes32`* 111 | 112 | --- 113 | ### hashedParameters() 114 | 115 | 116 | **Execution cost**: less than 612 gas 117 | 118 | **Attributes**: constant 119 | 120 | 121 | 122 | Returns: 123 | 124 | 125 | 1. **output_0** *of type `bytes32`* 126 | 127 | --- 128 | ### organizationsRegistry(address,address) 129 | 130 | 131 | **Execution cost**: less than 736 gas 132 | 133 | **Attributes**: constant 134 | 135 | 136 | Params: 137 | 138 | 1. **param_0** *of type `address`* 139 | 2. **param_1** *of type `address`* 140 | 141 | Returns: 142 | 143 | 144 | 1. **output_0** *of type `uint256`* 145 | 146 | --- 147 | ### owner() 148 | 149 | 150 | **Execution cost**: less than 677 gas 151 | 152 | **Attributes**: constant 153 | 154 | 155 | 156 | Returns: 157 | 158 | 159 | 1. **output_0** *of type `address`* 160 | 161 | --- 162 | ### parameters(bytes32) 163 | 164 | 165 | **Execution cost**: less than 1157 gas 166 | 167 | **Attributes**: constant 168 | 169 | 170 | Params: 171 | 172 | 1. **param_0** *of type `bytes32`* 173 | 174 | Returns: 175 | 176 | 177 | 1. **fee** *of type `uint256`* 178 | 2. **token** *of type `address`* 179 | 3. **beneficiary** *of type `address`* 180 | 181 | --- 182 | ### setParameters(address,uint256,address) 183 | > 184 | > Hash the parameters, save if needed and return the hash value 185 | 186 | 187 | **Execution cost**: less than 61765 gas 188 | 189 | 190 | Params: 191 | 192 | 1. **_token** *of type `address`* 193 | 194 | > - the token to pay for register or promotion an address. 195 | 196 | 2. **_fee** *of type `uint256`* 197 | 198 | > - fee needed for register an address. 199 | 200 | 3. **_beneficiary** *of type `address`* 201 | 202 | > - the beneficiary payment address 203 | 204 | 205 | Returns: 206 | 207 | > bytes32 -the parameters hash 208 | 209 | 1. **output_0** *of type `bytes32`* 210 | 211 | --- 212 | ### transferOwnership(address) 213 | > 214 | > Allows the current owner to transfer control of the contract to a newOwner. 215 | 216 | 217 | **Execution cost**: less than 22961 gas 218 | 219 | 220 | Params: 221 | 222 | 1. **newOwner** *of type `address`* 223 | 224 | > The address to transfer ownership to. 225 | 226 | 227 | 228 | --- 229 | ### updateParameters(bytes32) 230 | 231 | 232 | **Execution cost**: less than 20550 gas 233 | 234 | 235 | Params: 236 | 237 | 1. **_hashedParameters** *of type `bytes32`* 238 | 239 | 240 | [Back to the top ↑](#organizationregister) 241 | -------------------------------------------------------------------------------- /docs/generated_docs/universalSchemes/UniversalScheme.md: -------------------------------------------------------------------------------- 1 | # UniversalScheme 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/universalSchemes/UniversalScheme.sol) 3 | 4 | 5 | **Execution cost**: less than 20496 gas 6 | 7 | **Deployment cost**: less than 98600 gas 8 | 9 | **Combined cost**: less than 119096 gas 10 | 11 | 12 | ## Events 13 | ### OwnershipTransferred(address,address) 14 | 15 | 16 | **Execution cost**: No bound available 17 | 18 | 19 | Params: 20 | 21 | 1. **previousOwner** *of type `address`* 22 | 2. **newOwner** *of type `address`* 23 | 24 | 25 | ## Methods 26 | ### hashedParameters() 27 | 28 | 29 | **Execution cost**: less than 439 gas 30 | 31 | **Attributes**: constant 32 | 33 | 34 | 35 | Returns: 36 | 37 | 38 | 1. **output_0** *of type `bytes32`* 39 | 40 | --- 41 | ### owner() 42 | 43 | 44 | **Execution cost**: less than 548 gas 45 | 46 | **Attributes**: constant 47 | 48 | 49 | 50 | Returns: 51 | 52 | 53 | 1. **output_0** *of type `address`* 54 | 55 | --- 56 | ### transferOwnership(address) 57 | > 58 | > Allows the current owner to transfer control of the contract to a newOwner. 59 | 60 | 61 | **Execution cost**: less than 22788 gas 62 | 63 | 64 | Params: 65 | 66 | 1. **newOwner** *of type `address`* 67 | 68 | > The address to transfer ownership to. 69 | 70 | 71 | 72 | --- 73 | ### updateParameters(bytes32) 74 | 75 | 76 | **Execution cost**: less than 20443 gas 77 | 78 | 79 | Params: 80 | 81 | 1. **_hashedParameters** *of type `bytes32`* 82 | 83 | 84 | [Back to the top ↑](#universalscheme) 85 | -------------------------------------------------------------------------------- /docs/generated_docs/universalSchemes/UniversalSchemeInterface.md: -------------------------------------------------------------------------------- 1 | # UniversalSchemeInterface 2 | [see the source](https://github.com/daostack/arc/tree/master/contracts/universalSchemes/UniversalSchemeInterface.sol) 3 | 4 | 5 | **Execution cost**: No bound available 6 | 7 | **Deployment cost**: No bound available 8 | 9 | **Combined cost**: No bound available 10 | 11 | 12 | 13 | 14 | ## Methods 15 | ### updateParameters(bytes32) 16 | 17 | 18 | **Execution cost**: No bound available 19 | 20 | 21 | Params: 22 | 23 | 1. **_hashedParameters** *of type `bytes32`* 24 | 25 | 26 | [Back to the top ↑](#universalschemeinterface) 27 | -------------------------------------------------------------------------------- /docs/img/controller.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daostack/arc/532183b0778c29c7b4e5aab539570b631beb84f1/docs/img/controller.png -------------------------------------------------------------------------------- /docs/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daostack/arc/532183b0778c29c7b4e5aab539570b631beb84f1/docs/img/favicon.ico -------------------------------------------------------------------------------- /docs/img/the_dao_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daostack/arc/532183b0778c29c7b4e5aab539570b631beb84f1/docs/img/the_dao_stack.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | require("@nomiclabs/hardhat-truffle5"); 3 | require("@nomiclabs/hardhat-solhint"); 4 | require("solidity-coverage"); 5 | 6 | // This is a sample Hardhat task. To learn how to create your own go to 7 | // https://hardhat.org/guides/create-task.html 8 | task("accounts", "Prints the list of accounts", async () => { 9 | const accounts = await ethers.getSigners(); 10 | 11 | for (const account of accounts) { 12 | console.log(account.address); 13 | } 14 | }); 15 | 16 | // You need to export an object to set up your config 17 | // Go to https://hardhat.org/config/ to learn more 18 | 19 | /** 20 | * @type import('hardhat/config').HardhatUserConfig 21 | */ 22 | module.exports = { 23 | paths: { 24 | artifacts: './build/contracts' 25 | }, 26 | networks: { 27 | hardhat: { 28 | accounts: [ 29 | { 30 | privateKey: 31 | "0xc5e8f61d1ab959b397eecc0a37a6517b8e67a0e7cf1f4bce5591f3ed80199122", 32 | balance: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 33 | }, 34 | { 35 | privateKey: 36 | "0xd49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb", 37 | balance: "10000000000000000000000" 38 | }, 39 | { 40 | privateKey: 41 | "0x23c601ae397441f3ef6f1075dcb0031ff17fb079837beadaf3c84d96c6f3e569", 42 | balance: "10000000000000000000000" 43 | }, 44 | { 45 | privateKey: 46 | "0xee9d129c1997549ee09c0757af5939b2483d80ad649a0eda68e8b0357ad11131", 47 | balance: "10000000000000000000000" 48 | }, 49 | { 50 | privateKey: 51 | "0x87630b2d1de0fbd5044eb6891b3d9d98c34c8d310c852f98550ba774480e47cc", 52 | balance: "10000000000000000000000" 53 | }, 54 | { 55 | privateKey: 56 | "0x275cc4a2bfd4f612625204a20a2280ab53a6da2d14860c47a9f5affe58ad86d4", 57 | balance: "10000000000000000000000" 58 | }, 59 | { 60 | privateKey: 61 | "0x7f307c41137d1ed409f0a7b028f6c7596f12734b1d289b58099b99d60a96efff", 62 | balance: "10000000000000000000000" 63 | }, 64 | { 65 | privateKey: 66 | "0x2a8aede924268f84156a00761de73998dac7bf703408754b776ff3f873bcec60", 67 | balance: "10000000000000000000000" 68 | }, 69 | { 70 | privateKey: 71 | "0x8b24fd94f1ce869d81a34b95351e7f97b2cd88a891d5c00abc33d0ec9501902e", 72 | balance: "10000000000000000000000" 73 | }, 74 | { 75 | privateKey: 76 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29085", 77 | balance: "10000000000000000000000" 78 | }, 79 | { 80 | privateKey: 81 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29086", 82 | balance: "10000000000000000000000" 83 | }, 84 | { 85 | privateKey: 86 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29087", 87 | balance: "10000000000000000000000" 88 | }, 89 | { 90 | privateKey: 91 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29088", 92 | balance: "10000000000000000000000" 93 | }, 94 | { 95 | privateKey: 96 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29089", 97 | balance: "10000000000000000000000" 98 | }, 99 | { 100 | privateKey: 101 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908a", 102 | balance: "10000000000000000000000" 103 | }, 104 | { 105 | privateKey: 106 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908b", 107 | balance: "10000000000000000000000" 108 | }, 109 | { 110 | privateKey: 111 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908c", 112 | balance: "10000000000000000000000" 113 | }, 114 | { 115 | privateKey: 116 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908d", 117 | balance: "10000000000000000000000" 118 | }, 119 | { 120 | privateKey: 121 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908e", 122 | balance: "10000000000000000000000" 123 | }, 124 | { 125 | privateKey: 126 | "0x28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b2908f", 127 | balance: "10000000000000000000000" 128 | } 129 | ] 130 | } 131 | }, 132 | solidity: { 133 | version: "0.5.17", 134 | settings: { 135 | optimizer: { 136 | enabled: true, 137 | runs: 200 138 | } 139 | } 140 | } 141 | }; 142 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: DAOstack Arc Docs 2 | repo_url: https://github.com/daostack/arc/ 3 | repo_name: daostack/arc 4 | site_description: A platform for building DAOs 5 | docs_dir: docs 6 | extra_templates: 7 | - index.html 8 | markdown_extensions: 9 | - admonition 10 | - codehilite: 11 | linenums: true 12 | - toc: 13 | permalink: true 14 | theme: 15 | name: 'material' 16 | favicon: 'img/favicon.ico' 17 | palette: 18 | primary: 'teal' 19 | accent: 'amber' 20 | extra: 21 | social: 22 | - type: 'github' 23 | link: 'https://github.com/daostack/arc' 24 | - type: 'slack' 25 | link: 'https://daostack.slack.com' 26 | - type: 'telegram' 27 | link: 'https://t.me/daostackcommunity' 28 | 29 | pages: 30 | - Home: README.md 31 | - 'Contracts': 32 | - 'Contracts Home': 'contracts/README.md' 33 | - Controller: 34 | - 'Controller Home': 'contracts/controller/README.md' 35 | - Avatar: 'contracts/controller/Avatar.md' 36 | - Controller: 'contracts/controller/Controller.md' 37 | - DAOToken: 'contracts/controller/DAOToken.md' 38 | - Reputation: 'contracts/controller/Reputation.md' 39 | - UController: 'contracts/controller/UController.md' 40 | - 'Global Constraints': 41 | - 'Global Constraints Home': 'contracts/globalConstraints/README.md' 42 | - TokenCapGC: 'contracts/globalConstraints/TokenCapGC.md' 43 | - 'Universal Schemes': 44 | - 'Universal Schemes Home': 'contracts/universalSchemes/README.md' 45 | - 'Voting Machines': 46 | - 'Voting Machines Home': 'contracts/VotingMachines/README.md' 47 | - 'Generated Docs': 48 | - 'Generated Docs Home': 'generated_docs/README.md' 49 | - Controller: 50 | - ActionInterface: 'generated_docs/controller/ActionInterface.md' 51 | - Avatar: 'generated_docs/controller/Avatar.md' 52 | - Controller: 'generated_docs/controller/Controller.md' 53 | - ControllerInterface: 'generated_docs/controller/ControllerInterface.md' 54 | - DAOToken: 'generated_docs/controller/DAOToken.md' 55 | - Reputation: 'generated_docs/controller/Reputation.md' 56 | - UController: 'generated_docs/controller/UController.md' 57 | - 'Global Constraints': 58 | - GlobalConstraintInterface: 'generated_docs/globalConstraints/GlobalConstraintInterface.md' 59 | - TokenCapGC: 'generated_docs/globalConstraints/TokenCapGC.md' 60 | - 'Universal Schemes': 61 | - ContributionReward: 'generated_docs/universalSchemes/ContributionReward.md' 62 | - DaoCreator: 'generated_docs/universalSchemes/DaoCreator.md' 63 | - ExecutableInterface: 'generated_docs/universalSchemes/ExecutableInterface.md' 64 | - GlobalConstraintRegistrar: 'generated_docs/universalSchemes/GlobalConstraintRegistrar.md' 65 | - OrganizationRegister: 'generated_docs/universalSchemes/OrganizationRegister.md' 66 | - SchemeRegistrar: 'generated_docs/universalSchemes/SchemeRegistrar.md' 67 | - SimpleICO: 'generated_docs/universalSchemes/SimpleICO.md' 68 | - UniversalScheme: 'generated_docs/universalSchemes/UniversalScheme.md' 69 | - UniversalSchemeInterface: 'generated_docs/universalSchemes/UniversalSchemeInterface.md' 70 | - UpgradeScheme: 'generated_docs/universalSchemes/UpgradeScheme.md' 71 | - VestingScheme: 'generated_docs/universalSchemes/VestingScheme.md' 72 | - VoteInOrganizationScheme: 'generated_docs/universalSchemes/VoteInOrganizationScheme.md' 73 | - 'Voting Machines': 74 | - AbsoluteVote: 'generated_docs/VotingMachines/AbsoluteVote.md' 75 | - GenesisProtocol: 'generated_docs/VotingMachines/GenesisProtocol.md' 76 | - GenesisProtocolFormulasInterface: 'generated_docs/VotingMachines/GenesisProtocolFormulasInterface.md' 77 | - IntVoteInterface: 'generated_docs/VotingMachines/IntVoteInterface.md' 78 | - QuorumVote: 'generated_docs/VotingMachines/QuorumVote.md' 79 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@daostack/arc", 3 | "version": "0.0.1-rc.57", 4 | "description": "A platform for building DAOs", 5 | "files": [ 6 | "contracts/", 7 | "docs/", 8 | "build/contracts/", 9 | "migrations/", 10 | "test/", 11 | "truffle.js", 12 | "tsconfig.json" 13 | ], 14 | "config": { 15 | "gasLimit": "6200000" 16 | }, 17 | "scripts": { 18 | "lint": "eslint .", 19 | "lint --fix": "eslint --fix .", 20 | "coveralls": "hardhat coverage && cat coverage/lcov.info | coveralls", 21 | "extractabis": "node scripts/extract-abis.js" 22 | }, 23 | "devDependencies": { 24 | "@babel/cli": "^7.2.3", 25 | "@nomiclabs/hardhat-solhint": "2.0.0", 26 | "@nomiclabs/hardhat-truffle5": "2.0.0", 27 | "@nomiclabs/hardhat-web3": "2.0.0", 28 | "@nomiclabs/hardhat-ethers": "^2.0.0", 29 | "@nomiclabs/hardhat-waffle": "^2.0.0", 30 | "babel-eslint": "^10.1.0", 31 | "bignumber.js": "^5.0.0", 32 | "chai": "^4.2.0", 33 | "coveralls": "^3.1.0", 34 | "default-options": "^1.0.0", 35 | "eslint": "^6.8.0", 36 | "eslint-config-standard": "^14.1.1", 37 | "eslint-plugin-import": "^2.20.2", 38 | "eslint-plugin-node": "^11.1.0", 39 | "eslint-plugin-promise": "^4.2.1", 40 | "eslint-plugin-standard": "^4.0.1", 41 | "ethereum-waffle": "^3.2.0", 42 | "ethereumjs-abi": "^0.6.5", 43 | "ethers": "^5.0.21", 44 | "hardhat": "2.0.5", 45 | "mocha": "^7.1.1", 46 | "pm2": "^4.2.3", 47 | "promisify": "^0.0.3", 48 | "pug": "^2.0.0-rc.4", 49 | "rimraf": "^2.6.2", 50 | "run-with-ganache": "^0.1.1", 51 | "solhint": "^2.2.0", 52 | "solidity-coverage": "^0.7.11", 53 | "uint32": "^0.2.1" 54 | }, 55 | "repository": { 56 | "type": "git", 57 | "url": "https://github.com/daostack/arc.git" 58 | }, 59 | "keywords": [ 60 | "solidity", 61 | "ethereum", 62 | "smart", 63 | "contracts", 64 | "security", 65 | "daostack", 66 | "arc" 67 | ], 68 | "engines": { 69 | "node": ">=12.16.1" 70 | }, 71 | "author": "DAOstack (https://www.daostack.io)", 72 | "license": "GPL-3.0", 73 | "bugs": { 74 | "url": "https://github.com/daostack/arc/issues" 75 | }, 76 | "homepage": "https://daostack.io", 77 | "dependencies": { 78 | "@daostack/infra": "0.0.1-rc.21", 79 | "math": "0.0.3", 80 | "openzeppelin-solidity": "2.4.0", 81 | "truffle-flattener": "^1.4.2" 82 | }, 83 | "peerDependencies": { 84 | "ganache-cli": "^6.4.1" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf ./node_modules 4 | rm -rf ./build 5 | git checkout origin/master 6 | echo "npm install ..." 7 | npm i 8 | echo "truffle compile ..." 9 | npx hardhat clean 10 | npx hardhat compile 11 | echo "extract-abis" 12 | npm run extractabis 13 | # publish npm 14 | echo "Publishing to npm..." 15 | npm publish 16 | # tag on github 17 | git tag $(cat package.json | jq -r '.version') 18 | git push --tags 19 | # done 20 | echo "Release done!" 21 | -------------------------------------------------------------------------------- /scripts/extract-abis.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | /** 5 | * Extract abis from Arc contracts folder into truffle compatible format 6 | */ 7 | async function extractAbis (base) { 8 | var files = fs.readdirSync(base); 9 | for (var i = 0; i < files.length; i++) { 10 | var filename = path.join(base, files[i]); 11 | var stat = fs.lstatSync(filename); 12 | if (stat.isDirectory()) { 13 | extractAbis(filename); // recurse 14 | } else if (filename.indexOf('.json') >= 0 && filename.indexOf('.dbg') === -1) { 15 | console.log('-- found: ', filename); 16 | const contract = JSON.parse(fs.readFileSync(filename, 'utf-8')); 17 | fs.writeFileSync( 18 | path.join('./build/contracts', files[i]), 19 | JSON.stringify(contract, undefined, 2), 20 | 'utf-8' 21 | ); 22 | } 23 | } 24 | } 25 | 26 | if (require.main === module) { 27 | extractAbis('./build/contracts/contracts').catch(err => { 28 | console.log(err); 29 | process.exit(1); 30 | }); 31 | } else { 32 | module.exports = { 33 | extractAbis 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /test/agreement.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | var AgreementMock = artifacts.require("./AgreementMock.sol"); 3 | 4 | 5 | const setup = async function (accounts, _agreementHash = helpers.SOME_HASH) { 6 | var testSetup = new helpers.TestSetup(); 7 | testSetup.agreementMock = await AgreementMock.new(); 8 | testSetup.agreementHash = _agreementHash; 9 | await testSetup.agreementMock.setAgreementHashTest(_agreementHash); 10 | return testSetup; 11 | }; 12 | 13 | contract('Agreement', accounts => { 14 | it("setAgreementHash", async () => { 15 | let testSetup = await setup(accounts); 16 | assert.equal(await testSetup.agreementMock.getAgreementHash(),testSetup.agreementHash); 17 | }); 18 | 19 | it("cannot setAgreementHash twice", async () => { 20 | let testSetup = await setup(accounts); 21 | try { 22 | await testSetup.agreementMock.setAgreementHashTest(helpers.NULL_HASH); 23 | assert(false, "cannot setAgreementHash twice"); 24 | } catch(error) { 25 | helpers.assertVMException(error); 26 | } 27 | }); 28 | 29 | it("onlyAgree", async () => { 30 | let testSetup = await setup(accounts); 31 | await testSetup.agreementMock.test(helpers.SOME_HASH); 32 | try { 33 | await testSetup.agreementMock.test(helpers.NULL_HASH); 34 | assert(false, "onlyAgree"); 35 | } catch(error) { 36 | helpers.assertVMException(error); 37 | } 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /test/avatar.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | const Avatar = artifacts.require("./Avatar.sol"); 3 | const ERC20Mock = artifacts.require('./test/ERC20Mock.sol'); 4 | const ActionMock = artifacts.require('./test/ActionMock.sol'); 5 | const UniversalSchemeMock = artifacts.require('./test/UniversalSchemeMock.sol'); 6 | 7 | let avatar; 8 | 9 | const setup = async function (accounts) { 10 | avatar = await Avatar.new("0x1234", accounts[0], accounts[1]); 11 | return avatar; 12 | }; 13 | 14 | contract('Avatar', accounts => { 15 | 16 | it("genericCall no owner", async () => { 17 | avatar = await setup(accounts); 18 | let actionMock = await ActionMock.new(); 19 | var scheme = await UniversalSchemeMock.new(); 20 | let a = 7; 21 | let b = actionMock.address; 22 | let c = "0x1234"; 23 | try{ 24 | await scheme.genericCallDirect.call(avatar.address,actionMock.address,a,b,c,0,{from :accounts[1]}); 25 | assert(false, "genericAction should fail due to wrong owner"); 26 | } catch (ex) { 27 | helpers.assertVMException(ex); 28 | } 29 | }); 30 | 31 | it("generic call", async () => { 32 | avatar = await setup(accounts); 33 | let actionMock = await ActionMock.new(); 34 | var scheme = await UniversalSchemeMock.new(); 35 | await avatar.transferOwnership(scheme.address); 36 | let a = 7; 37 | let b = actionMock.address; 38 | let c = "0x1234"; 39 | await web3.eth.sendTransaction({from:accounts[0],to:avatar.address, value: web3.utils.toWei('1', "ether")}); 40 | var result = await scheme.genericCallDirect.call(avatar.address,actionMock.address,a,b,c,100); 41 | assert.equal(result[1],a*2); 42 | await scheme.genericCallDirect(avatar.address,actionMock.address,a,b,c,100); 43 | assert.equal(await web3.eth.getBalance(actionMock.address),100); 44 | 45 | }); 46 | 47 | it("generic call should not revert if action revert", async () => { 48 | avatar = await setup(accounts); 49 | let actionMock = await ActionMock.new(); 50 | var scheme = await UniversalSchemeMock.new(); 51 | await avatar.transferOwnership(scheme.address); 52 | let a = 7; 53 | let b = actionMock.address; 54 | let c = "0x4567"; //the action test function require 0x1234 55 | await scheme.genericCallDirect.call(avatar.address,actionMock.address,a,b,c,0); 56 | }); 57 | 58 | it("pay ether to avatar", async () => { 59 | avatar = await setup(accounts); 60 | await web3.eth.sendTransaction({from:accounts[0],to:avatar.address, value: web3.utils.toWei('1', "ether")}); 61 | var avatarBalance = await web3.eth.getBalance(avatar.address)/web3.utils.toWei('1', "ether"); 62 | assert.equal(avatarBalance,1); 63 | }); 64 | 65 | it("sendEther from ", async () => { 66 | avatar = await setup(accounts); 67 | let otherAvatar = await Avatar.new('otheravatar', helpers.NULL_ADDRESS, helpers.NULL_ADDRESS); 68 | await web3.eth.sendTransaction({from:accounts[0],to:avatar.address, value: web3.utils.toWei('1', "ether")}); 69 | var avatarBalance = await web3.eth.getBalance(avatar.address)/web3.utils.toWei('1', "ether"); 70 | assert.equal(avatarBalance,1); 71 | var tx = await avatar.sendEther(web3.utils.toWei('1', "ether"),otherAvatar.address); 72 | assert.equal(tx.logs.length, 2); 73 | assert.equal(tx.logs[1].event, "SendEther"); 74 | avatarBalance =await web3.eth.getBalance(avatar.address)/web3.utils.toWei('1', "ether"); 75 | assert.equal(avatarBalance,0); 76 | var otherAvatarBalance = await web3.eth.getBalance(otherAvatar.address)/web3.utils.toWei('1', "ether"); 77 | assert.equal(otherAvatarBalance,1); 78 | }); 79 | 80 | it("externalTokenTransfer ", async () => { 81 | avatar = await setup(accounts); 82 | var standardToken = await ERC20Mock.new(avatar.address, 100); 83 | let balanceAvatar = await standardToken.balanceOf(avatar.address); 84 | assert.equal(balanceAvatar, 100); 85 | var tx = await avatar.externalTokenTransfer(standardToken.address,accounts[1],50); 86 | assert.equal(tx.logs.length, 1); 87 | assert.equal(tx.logs[0].event, "ExternalTokenTransfer"); 88 | balanceAvatar = await standardToken.balanceOf(avatar.address); 89 | assert.equal(balanceAvatar, 50); 90 | let balance1 = await standardToken.balanceOf(accounts[1]); 91 | assert.equal(balance1, 50); 92 | }); 93 | 94 | it("externalTokenTransferFrom & externalTokenApproval", async () => { 95 | var tx; 96 | var to = accounts[1]; 97 | avatar = await setup(accounts); 98 | var standardToken = await ERC20Mock.new(avatar.address, 100); 99 | tx = await avatar.externalTokenApproval(standardToken.address,avatar.address,50); 100 | assert.equal(tx.logs.length, 1); 101 | assert.equal(tx.logs[0].event, "ExternalTokenApproval"); 102 | tx = await avatar.externalTokenTransferFrom(standardToken.address,avatar.address,to,50); 103 | assert.equal(tx.logs.length, 1); 104 | assert.equal(tx.logs[0].event, "ExternalTokenTransferFrom"); 105 | let balanceAvatar = await standardToken.balanceOf(avatar.address); 106 | assert.equal(balanceAvatar, 50); 107 | let balanceTo = await standardToken.balanceOf(to); 108 | assert.equal(balanceTo, 50); 109 | }); 110 | 111 | it("metaData event", async () => { 112 | avatar = await setup(accounts); 113 | let tx = await avatar.metaData(helpers.SOME_HASH); 114 | assert.equal(tx.logs.length, 1); 115 | assert.equal(tx.logs[0].event, "MetaData"); 116 | assert.equal(tx.logs[0].args["_metaData"], helpers.SOME_HASH); 117 | }); 118 | }); 119 | -------------------------------------------------------------------------------- /test/competitionfactory.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | 3 | const Competition = artifacts.require('./Competition.sol'); 4 | const ContributionRewardExt = artifacts.require('./ContributionRewardExt.sol'); 5 | const CompetitionFactory = artifacts.require('./CompetitionFactory.sol'); 6 | 7 | const params = [ 8 | [ 9 | 50, 10 | 1800, 11 | 600, 12 | 600, 13 | 2000, 14 | 300, 15 | web3.utils.toWei('5', "ether"), 16 | 1, 17 | web3.utils.toWei('10', "ether"), 18 | 10, 19 | 0 20 | ], 21 | [ 22 | 50, 23 | 604800, 24 | 129600, 25 | 43200, 26 | 1200, 27 | 86400, 28 | web3.utils.toWei('10', "ether"), 29 | 1, 30 | web3.utils.toWei('50', "ether"), 31 | 10, 32 | 0 33 | ], 34 | [ 35 | 50, 36 | 2592000, 37 | 345600, 38 | 86400, 39 | 1200, 40 | 172800, 41 | web3.utils.toWei('50', "ether"), 42 | 4, 43 | web3.utils.toWei('150', "ether"), 44 | 10, 45 | 0 46 | ], 47 | [ 48 | 50, 49 | 5184000, 50 | 691200, 51 | 172800, 52 | 1500, 53 | 345600, 54 | web3.utils.toWei('200', "ether"), 55 | 4, 56 | web3.utils.toWei('500', "ether"), 57 | 10, 58 | 0 59 | ] 60 | ]; 61 | 62 | const setup = async function () { 63 | var testSetup = new helpers.TestSetup(); 64 | testSetup.competitionFactory = await CompetitionFactory.new(); 65 | return testSetup; 66 | }; 67 | 68 | contract('competitionFactory', function(accounts) { 69 | it('initialize', async () => { 70 | let testSetup = await setup(); 71 | let votingMachine = await helpers.setupGenesisProtocol(accounts,helpers.SOME_ADDRESS,0,helpers.NULL_ADDRESS); 72 | 73 | for (let i=0; i < 4; i++) { 74 | let addresses = await testSetup.competitionFactory.createCompetition.call( 75 | helpers.SOME_ADDRESS, 76 | votingMachine.genesisProtocol.address, 77 | i, 78 | (i === 0 ? params[0] : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 79 | helpers.NULL_ADDRESS 80 | ); 81 | 82 | let competitionAddress = addresses['0']; 83 | let creAddress = addresses['1']; 84 | 85 | await testSetup.competitionFactory.createCompetition( 86 | helpers.SOME_ADDRESS, 87 | votingMachine.genesisProtocol.address, 88 | i, 89 | (i === 0 ? params[0] : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 90 | helpers.NULL_ADDRESS 91 | ); 92 | 93 | let contributionRewardExt = await ContributionRewardExt.at(creAddress); 94 | let competition = await Competition.at(competitionAddress); 95 | assert.equal(await contributionRewardExt.avatar(), helpers.SOME_ADDRESS); 96 | assert.equal(await contributionRewardExt.votingMachine(), votingMachine.genesisProtocol.address); 97 | assert.equal( 98 | await contributionRewardExt.voteParams(), 99 | await votingMachine.genesisProtocol.getParametersHash(params[i], helpers.NULL_ADDRESS) 100 | ); 101 | assert.equal(await contributionRewardExt.rewarder(), competitionAddress); 102 | assert.equal(await competition.contributionRewardExt(), creAddress); 103 | } 104 | 105 | try { 106 | await testSetup.competitionFactory.createCompetition( 107 | helpers.SOME_ADDRESS, 108 | votingMachine.genesisProtocol.address, 109 | 4, 110 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 111 | helpers.NULL_ADDRESS, 112 | ); 113 | assert(false, "Vote params type specified does not exist"); 114 | } catch(error) { 115 | helpers.assertVMException(error); 116 | } 117 | 118 | }); 119 | 120 | }); 121 | -------------------------------------------------------------------------------- /test/constants.js: -------------------------------------------------------------------------------- 1 | const ARC_GAS_LIMIT = 6200000; 2 | 3 | module.exports = { ARC_GAS_LIMIT }; 4 | -------------------------------------------------------------------------------- /test/continuouslocking4reputationfactory.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | 3 | const ERC20Mock = artifacts.require('./test/ERC20Mock.sol'); 4 | const ContinuousLocking4Reputation = artifacts.require('./ContinuousLocking4Reputation.sol'); 5 | const ContinuousLocking4ReputationFactory = artifacts.require('./ContinuousLocking4ReputationFactory.sol'); 6 | 7 | const setup = async function () { 8 | var testSetup = new helpers.TestSetup(); 9 | testSetup.continuousLocking4ReputationFactory = await ContinuousLocking4ReputationFactory.new(); 10 | return testSetup; 11 | }; 12 | 13 | contract('competitionFactory', function(accounts) { 14 | it('initialize', async () => { 15 | let testSetup = await setup(); 16 | testSetup.lockingToken = await ERC20Mock.new(accounts[0], web3.utils.toWei('100', "ether")); 17 | testSetup.startTime = (await web3.eth.getBlock("latest")).timestamp; 18 | testSetup.redeemEnableTime = (await web3.eth.getBlock("latest")).timestamp + (30*60*60); 19 | testSetup.continuousLocking4Reputation = await ContinuousLocking4Reputation.new(); 20 | testSetup.periodsUnit = (30*60*60); 21 | testSetup.agreementHash = helpers.SOME_HASH; 22 | testSetup.maxLockingPeriod = 12; 23 | 24 | testSetup.repRewardConstA = 85000; 25 | testSetup.repRewardConstB = 900; 26 | testSetup.reputationReward = 850000; 27 | testSetup.periodsCap = 100; 28 | let cl4rAddress = await testSetup.continuousLocking4ReputationFactory.createCL4R.call( 29 | helpers.SOME_ADDRESS, 30 | testSetup.reputationReward, 31 | testSetup.startTime, 32 | testSetup.periodsUnit, 33 | testSetup.redeemEnableTime, 34 | testSetup.maxLockingPeriod, 35 | testSetup.repRewardConstA, 36 | testSetup.repRewardConstB, 37 | testSetup.periodsCap, 38 | testSetup.lockingToken.address, 39 | testSetup.agreementHash 40 | ); 41 | await testSetup.continuousLocking4ReputationFactory.createCL4R( 42 | helpers.SOME_ADDRESS, 43 | testSetup.reputationReward, 44 | testSetup.startTime, 45 | testSetup.periodsUnit, 46 | testSetup.redeemEnableTime, 47 | testSetup.maxLockingPeriod, 48 | testSetup.repRewardConstA, 49 | testSetup.repRewardConstB, 50 | testSetup.periodsCap, 51 | testSetup.lockingToken.address, 52 | testSetup.agreementHash 53 | ); 54 | let continuousLocking4Reputation = await ContinuousLocking4Reputation.at(cl4rAddress); 55 | assert.equal(await continuousLocking4Reputation.reputationRewardLeft(),testSetup.reputationReward); 56 | assert.equal(await continuousLocking4Reputation.startTime(),testSetup.startTime); 57 | assert.equal(await continuousLocking4Reputation.redeemEnableTime(),testSetup.redeemEnableTime); 58 | assert.equal(await continuousLocking4Reputation.token(),testSetup.lockingToken.address); 59 | assert.equal(await continuousLocking4Reputation.batchTime(),testSetup.periodsUnit); 60 | assert.equal(await continuousLocking4Reputation.getAgreementHash(),testSetup.agreementHash); 61 | assert.equal(await continuousLocking4Reputation.batchesIndexCap(),testSetup.periodsCap); 62 | }); 63 | 64 | }); 65 | -------------------------------------------------------------------------------- /test/nectarrepallocation.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | const NectarToken = artifacts.require('./Reputation.sol'); 3 | var NectarRepAllocation = artifacts.require("./NectarRepAllocation.sol"); 4 | 5 | 6 | const setup = async function (accounts, 7 | _initialize = true, 8 | _reputationReward = 100000, 9 | _claimingStartTime = 0, 10 | _claimingEndTime = (30*60*60*24) 11 | ) { 12 | var testSetup = new helpers.TestSetup(); 13 | testSetup.nectarToken = await NectarToken.new(); 14 | await testSetup.nectarToken.mint(accounts[0],100); 15 | await testSetup.nectarToken.mint(accounts[1],200); 16 | testSetup.blockReference = await web3.eth.getBlockNumber(); 17 | 18 | await testSetup.nectarToken.mint(accounts[2],300); 19 | 20 | testSetup.claimingStartTime = (await web3.eth.getBlock("latest")).timestamp + _claimingStartTime; 21 | testSetup.claimingEndTime = (await web3.eth.getBlock("latest")).timestamp + _claimingEndTime; 22 | 23 | testSetup.nectarRepAllocation = await NectarRepAllocation.new(); 24 | 25 | testSetup.reputationReward = _reputationReward; 26 | if (_initialize === true ) { 27 | await testSetup.nectarRepAllocation.initialize( 28 | testSetup.reputationReward, 29 | testSetup.claimingStartTime, 30 | testSetup.claimingEndTime, 31 | testSetup.blockReference, 32 | testSetup.nectarToken.address); 33 | } 34 | 35 | return testSetup; 36 | }; 37 | 38 | contract('NectarRepAllocation', accounts => { 39 | it("initialize", async () => { 40 | let testSetup = await setup(accounts); 41 | assert.equal(await testSetup.nectarRepAllocation.claimingStartTime(),testSetup.claimingStartTime); 42 | assert.equal(await testSetup.nectarRepAllocation.claimingEndTime(),testSetup.claimingEndTime); 43 | assert.equal(await testSetup.nectarRepAllocation.blockReference(),testSetup.blockReference); 44 | assert.equal(await testSetup.nectarRepAllocation.token(),testSetup.nectarToken.address); 45 | }); 46 | 47 | it("balanceOf", async () => { 48 | let testSetup = await setup(accounts); 49 | assert.equal(await testSetup.nectarRepAllocation.balanceOf(accounts[0]),Math.floor((100*testSetup.reputationReward)/300)); 50 | assert.equal(await testSetup.nectarRepAllocation.balanceOf(accounts[1]),Math.floor((200*testSetup.reputationReward)/300)); 51 | assert.equal(await testSetup.nectarRepAllocation.balanceOf(accounts[2]),0); 52 | 53 | }); 54 | 55 | it("cannot initialize twice", async () => { 56 | let testSetup = await setup(accounts); 57 | try { 58 | await testSetup.nectarRepAllocation.initialize( 59 | testSetup.reputationReward, 60 | testSetup.claimingStartTime, 61 | testSetup.claimingEndTime, 62 | testSetup.blockReference, 63 | testSetup.nectarToken.address); 64 | assert(false, "cannot initialize twice"); 65 | 66 | } catch(error) { 67 | helpers.assertVMException(error); 68 | } 69 | }); 70 | 71 | it("claim after end return 0", async () => { 72 | let testSetup = await setup(accounts); 73 | await helpers.increaseTime((30*60*60*24)+1); 74 | assert.equal(await testSetup.nectarRepAllocation.balanceOf(accounts[0]),0); 75 | }); 76 | 77 | 78 | }); 79 | -------------------------------------------------------------------------------- /test/organizationregister.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | 3 | const OrganizationRegister = artifacts.require('./OrganizationRegister.sol'); 4 | const ERC20Mock = artifacts.require('./test/ERC20Mock.sol'); 5 | const DaoCreator = artifacts.require("./DaoCreator.sol"); 6 | const ControllerCreator = artifacts.require("./ControllerCreator.sol"); 7 | const DAOTracker = artifacts.require("./DAOTracker.sol"); 8 | 9 | class OrganizationRegisterParams { 10 | constructor() { 11 | } 12 | } 13 | 14 | const setupOrganizationRegisterParams = async function( 15 | organizationRegister, 16 | tokenAddress, 17 | beneficiary, 18 | 19 | ) { 20 | var organizationRegisterParams = new OrganizationRegisterParams(); 21 | organizationRegisterParams.votingMachine = await helpers.setupAbsoluteVote(); 22 | await organizationRegister.setParameters(tokenAddress,13,beneficiary); 23 | organizationRegisterParams.paramsHash = await organizationRegister.getParametersHash(tokenAddress,13,beneficiary); 24 | return organizationRegisterParams; 25 | }; 26 | 27 | const setup = async function (accounts) { 28 | var testSetup = new helpers.TestSetup(); 29 | testSetup.fee = 10; 30 | testSetup.standardTokenMock = await ERC20Mock.new(accounts[1],100); 31 | testSetup.organizationRegister = await OrganizationRegister.new(); 32 | var controllerCreator = await ControllerCreator.new(); 33 | var daoTracker = await DAOTracker.new(); 34 | testSetup.daoCreator = await DaoCreator.new(controllerCreator.address,daoTracker.address); 35 | testSetup.org = await helpers.setupOrganization(testSetup.daoCreator,accounts[0],1000,1000); 36 | testSetup.organizationRegisterParams= await setupOrganizationRegisterParams(testSetup.organizationRegister,testSetup.standardTokenMock.address,accounts[2]); 37 | var permissions = "0x00000000"; 38 | await testSetup.daoCreator.setSchemes(testSetup.org.avatar.address,[testSetup.organizationRegister.address],[testSetup.organizationRegisterParams.paramsHash],[permissions],"metaData"); 39 | 40 | return testSetup; 41 | }; 42 | 43 | contract('OrganizationRegister',accounts => { 44 | before(function() { 45 | helpers.etherForEveryone(accounts); 46 | }); 47 | 48 | it("setParameters", async() => { 49 | var organizationRegister = await OrganizationRegister.new(); 50 | await organizationRegister.setParameters(accounts[3],13,accounts[2]); 51 | var paramHash = await organizationRegister.getParametersHash(accounts[3],13,accounts[2]); 52 | var parameters = await organizationRegister.parameters(paramHash); 53 | assert.equal(parameters[1],accounts[3]); 54 | assert.equal(parameters[0],13); 55 | assert.equal(parameters[2],accounts[2]); 56 | }); 57 | 58 | 59 | it("addOrPromoteAddress add and promote ", async function() { 60 | var testSetup = await setup(accounts); 61 | var record = accounts[4]; 62 | var amount = 13; 63 | 64 | 65 | await testSetup.standardTokenMock.approve(testSetup.organizationRegister.address,100,{from:accounts[1]}); 66 | 67 | var tx = await testSetup.organizationRegister.addOrPromoteAddress(testSetup.org.avatar.address, 68 | record, 69 | amount,{from:accounts[1]}); 70 | assert.equal(tx.logs.length, 2); 71 | assert.equal(tx.logs[0].event, "OrgAdded"); 72 | assert.equal(tx.logs[1].event, "Promotion"); 73 | var registery = await helpers.getValueFromLogs(tx, '_registry'); 74 | var org = await helpers.getValueFromLogs(tx, '_org'); 75 | var registeryAmount = await testSetup.organizationRegister.organizationsRegistry(registery,org); 76 | assert.equal(amount,registeryAmount); 77 | //now try to promote. 78 | tx = await testSetup.organizationRegister.addOrPromoteAddress(testSetup.org.avatar.address, 79 | record, 80 | 1,{from:accounts[1]}); 81 | assert.equal(tx.logs.length, 1); 82 | assert.equal(tx.logs[0].event, "Promotion"); 83 | registery = await helpers.getValueFromLogs(tx, '_registry'); 84 | org = await helpers.getValueFromLogs(tx, '_org'); 85 | registeryAmount = await testSetup.organizationRegister.organizationsRegistry(registery,org); 86 | assert.equal(amount+1,registeryAmount); 87 | }); 88 | 89 | it("addOrPromoteAddress add without enough fee should fail ", async function() { 90 | var testSetup = await setup(accounts); 91 | var record = accounts[4]; 92 | var amount = 12; 93 | 94 | 95 | await testSetup.standardTokenMock.approve(testSetup.organizationRegister.address,100,{from:accounts[1]}); 96 | 97 | try{ 98 | await testSetup.organizationRegister.addOrPromoteAddress(testSetup.org.avatar.address, 99 | record, 100 | amount,{from:accounts[1]}); 101 | assert(false,"addOrPromoteAddress should fail - due to amount { 7 | let curve = await PolkaCurve.new(); 8 | var total_reputation = await curve.TOTAL_REPUTATION(); 9 | assert.equal(total_reputation,800000); 10 | var sum_of_sqrt = await curve.SUM_OF_SQRTS(); 11 | assert.equal(sum_of_sqrt,1718050); 12 | var expected; 13 | for (let i = 0;i<1000;i = i+ 50) { 14 | expected = Math.floor((( math.sqrt(i) * total_reputation)/sum_of_sqrt) * 1000000000) * 1000000000; 15 | assert.equal(Math.floor((await curve.calc(i))/10000000000), Math.floor(expected/10000000000)); 16 | } 17 | let bigNum = 1000000000; 18 | expected = Math.floor((( math.sqrt(bigNum) * total_reputation)/sum_of_sqrt) * 1000000000) * 1000000000; 19 | assert.equal(Math.floor((await curve.calc(bigNum.toString(10)))/10000000000),Math.floor(expected/10000000000)); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/ragequitwithtoken.js: -------------------------------------------------------------------------------- 1 | const helpers = require("./helpers"); 2 | 3 | const RageQuitWithToken = artifacts.require("./RageQuitWithToken.sol"); 4 | const ERC20Mock = artifacts.require('./test/ERC20Mock.sol'); 5 | const DaoCreator = artifacts.require("./DaoCreator.sol"); 6 | const ControllerCreator = artifacts.require("./ControllerCreator.sol"); 7 | const DAOTracker = artifacts.require("./DAOTracker.sol"); 8 | 9 | 10 | const setup = async function (accounts) { 11 | var testSetup = new helpers.TestSetup(); 12 | testSetup.rageQuitToken = await ERC20Mock.new(accounts[0],100000); 13 | 14 | var controllerCreator = await ControllerCreator.new(); 15 | var daoTracker = await DAOTracker.new(); 16 | testSetup.daoCreator = await DaoCreator.new(controllerCreator.address,daoTracker.address); 17 | 18 | testSetup.reputationArray = [0,0,0]; 19 | testSetup.tokenArray = [100,200,300]; 20 | testSetup.founderAccounts = [accounts[1],accounts[2],accounts[3]]; 21 | 22 | testSetup.org = await helpers.setupOrganizationWithArrays(testSetup.daoCreator, 23 | testSetup.founderAccounts, 24 | testSetup.tokenArray, 25 | testSetup.reputationArray); 26 | 27 | testSetup.rageQuitWithToken = await RageQuitWithToken.new(); 28 | 29 | await testSetup.rageQuitWithToken.initialize( 30 | testSetup.org.avatar.address, 31 | testSetup.rageQuitToken.address 32 | ); 33 | 34 | var permissions = "0x00000000"; 35 | await testSetup.daoCreator.setSchemes(testSetup.org.avatar.address, 36 | [testSetup.rageQuitWithToken.address], 37 | [helpers.NULL_HASH],[permissions],"metaData"); 38 | 39 | return testSetup; 40 | }; 41 | contract('RageQuitWithToken', accounts => { 42 | 43 | it("initialize", async function() { 44 | var testSetup = await setup(accounts); 45 | assert.equal(await testSetup.rageQuitWithToken.rageQuitToken(),testSetup.rageQuitToken.address); 46 | assert.equal(await testSetup.rageQuitWithToken.avatar(),testSetup.org.avatar.address); 47 | }); 48 | 49 | it("rageQuit", async function() { 50 | var testSetup = await setup(accounts); 51 | //send the dao some rageQuitTokens 52 | await testSetup.rageQuitToken.transfer(testSetup.org.avatar.address,1000); 53 | assert.equal(await testSetup.rageQuitToken.balanceOf(testSetup.org.avatar.address),1000); 54 | //accounts 1 ragequit with all is tokens (100) 55 | assert.equal((await testSetup.org.token.balanceOf(accounts[1])).toNumber(),100); 56 | //give approval for burn 57 | await testSetup.org.token.approve(testSetup.rageQuitWithToken.address,100,{from:accounts[1]}); 58 | var tx = await testSetup.rageQuitWithToken.rageQuit(100,{from:accounts[1]}); 59 | assert.equal(tx.logs.length, 1); 60 | var expectedRefund = Math.floor((100/(100+200+300)) * 1000); 61 | assert.equal(tx.logs[0].event, "RageQuit"); 62 | assert.equal(tx.logs[0].args._rageQuitter, accounts[1]); 63 | assert.equal(tx.logs[0].args._refund.toNumber(),expectedRefund); 64 | assert.equal(await testSetup.rageQuitToken.balanceOf(testSetup.org.avatar.address),1000-expectedRefund); 65 | assert.equal(await testSetup.rageQuitToken.balanceOf(accounts[1]),expectedRefund); 66 | try { 67 | await testSetup.org.token.approve(testSetup.rageQuitWithToken.address,100,{from:accounts[1]}); 68 | await testSetup.rageQuitWithToken.rageQuit(100,{from:accounts[1]}); 69 | assert(false, "cannot rageQuit twice"); 70 | } catch(error) { 71 | helpers.assertVMException(error); 72 | } 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /test/safeerc20.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | const SafeERC20Mock = artifacts.require('./test/SafeERC20Mock.sol'); 3 | const BadERC20 = artifacts.require('./test/BadERC20.sol'); 4 | const ERC20Mock = artifacts.require('./test/ERC20Mock.sol'); 5 | 6 | 7 | contract('safe erc 20', accounts => { 8 | 9 | it("transfer bad token", async () => { 10 | var badERC20 = await BadERC20.new(); 11 | var safeERC20Mock = await SafeERC20Mock.new(badERC20.address); 12 | assert.equal(await safeERC20Mock.transferWithFix.call(accounts[1],123),true); 13 | await safeERC20Mock.transferWithFix(accounts[1],123); 14 | assert.equal(await badERC20.balances(accounts[1]),123); 15 | }); 16 | 17 | it("transfer bad token without the fix revert", async () => { 18 | var badERC20 = await BadERC20.new(); 19 | var safeERC20Mock = await SafeERC20Mock.new(badERC20.address); 20 | try { 21 | await safeERC20Mock.transfer(accounts[1],123); 22 | assert(false, "transfer bad token without the fix revert"); 23 | } catch(error) { 24 | helpers.assertVMException(error); 25 | } 26 | }); 27 | 28 | it("transfer good token", async () => { 29 | var goodToken = await ERC20Mock.new(accounts[0], web3.utils.toWei('100', "ether")); 30 | var safeERC20Mock = await SafeERC20Mock.new(goodToken.address); 31 | await goodToken.transfer(safeERC20Mock.address,123); 32 | assert.equal(await safeERC20Mock.transferWithFix.call(accounts[1],123,{from:accounts[0]}),true); 33 | await safeERC20Mock.transferWithFix(accounts[1],123,{from:accounts[0]}); 34 | assert.equal(await goodToken.balanceOf(accounts[1]),123); 35 | }); 36 | 37 | 38 | it("transferFrom bad token", async () => { 39 | var badERC20 = await BadERC20.new(); 40 | var safeERC20Mock = await SafeERC20Mock.new(badERC20.address); 41 | assert.equal(await safeERC20Mock.transferFromWithFix.call(accounts[0],accounts[1],123),true); 42 | await safeERC20Mock.transferFromWithFix(accounts[0],accounts[1],123); 43 | assert.equal(await badERC20.balances(accounts[1]),123); 44 | }); 45 | 46 | 47 | it("transferFrom good token", async () => { 48 | var goodToken = await ERC20Mock.new(accounts[0], web3.utils.toWei('100', "ether")); 49 | var safeERC20Mock = await SafeERC20Mock.new(goodToken.address); 50 | await goodToken.approve(safeERC20Mock.address,123); 51 | assert.equal(await safeERC20Mock.transferFromWithFix.call(accounts[0],accounts[1],123,{from:accounts[0]}),true); 52 | await safeERC20Mock.transferFromWithFix(accounts[0],accounts[1],123,{from:accounts[0]}); 53 | assert.equal(await goodToken.balanceOf(accounts[1]),123); 54 | }); 55 | 56 | it("approve bad token", async () => { 57 | var badERC20 = await BadERC20.new(); 58 | var safeERC20Mock = await SafeERC20Mock.new(badERC20.address); 59 | assert.equal(await safeERC20Mock.approveWithFix.call(accounts[0],123),true); 60 | await safeERC20Mock.approveWithFix(accounts[0],123); 61 | assert.equal(await badERC20.allowance(safeERC20Mock.address,accounts[0]),123); 62 | }); 63 | 64 | 65 | it("approve good token", async () => { 66 | var goodToken = await ERC20Mock.new(accounts[0], web3.utils.toWei('100', "ether")); 67 | var safeERC20Mock = await SafeERC20Mock.new(goodToken.address); 68 | assert.equal(await safeERC20Mock.approveWithFix.call(accounts[0],123),true); 69 | await safeERC20Mock.approveWithFix(accounts[0],123); 70 | assert.equal(await goodToken.allowance(safeERC20Mock.address,accounts[0]),123); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /test/tokencapgc.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | const DAOToken = artifacts.require("./DAOToken.sol"); 3 | const TokenCapGC = artifacts.require('./globalConstraints/TokenCapGC.sol'); 4 | const Controller = artifacts.require("./Controller.sol"); 5 | const Reputation = artifacts.require("./Reputation.sol"); 6 | const Avatar = artifacts.require("./Avatar.sol"); 7 | 8 | 9 | 10 | let reputation, avatar,token,controller; 11 | const setup = async function (permission='0') { 12 | var _controller; 13 | token = await DAOToken.new("TEST","TST",0); 14 | // set up a reputation system 15 | reputation = await Reputation.new(); 16 | avatar = await Avatar.new('name', token.address, reputation.address); 17 | if (permission !== '0'){ 18 | _controller = await Controller.new(avatar.address,{from:accounts[1]}); 19 | await _controller.registerScheme(accounts[0],0,permission,0,{from:accounts[1]}); 20 | await _controller.unregisterSelf(0,{from:accounts[1]}); 21 | } 22 | else { 23 | _controller = await Controller.new(avatar.address,); 24 | } 25 | controller = _controller; 26 | return _controller; 27 | }; 28 | 29 | contract('TokenCapGC', accounts => { 30 | it("setParameters", async () => { 31 | var paramsHash; 32 | var tokenCapGC = await TokenCapGC.new(); 33 | var token = await DAOToken.new("TEST","TST",0); 34 | await tokenCapGC.setParameters(token.address,100); 35 | paramsHash = await tokenCapGC.getParametersHash(token.address,100); 36 | var param = await tokenCapGC.parameters(paramsHash); 37 | assert.equal(param[1].toNumber(),100); 38 | }); 39 | 40 | it("pre and post", async () => { 41 | var paramsHash,post,pre; 42 | var tokenCapGC = await TokenCapGC.new(); 43 | var token = await DAOToken.new("TEST","TST",0); 44 | await tokenCapGC.setParameters(token.address,100); 45 | paramsHash = await tokenCapGC.getParametersHash(token.address,100); 46 | pre = await tokenCapGC.pre(token.address,paramsHash,helpers.NULL_HASH); 47 | assert.equal(pre,true); 48 | post = await tokenCapGC.post(token.address,paramsHash,helpers.NULL_HASH); 49 | //token total supply is 0 50 | assert.equal(post,true); 51 | //increase the total supply 52 | await token.mint(accounts[2], 101); 53 | post = await tokenCapGC.post(token.address,paramsHash,helpers.NULL_HASH); 54 | //token total supply is 101 55 | assert.equal(post,false); 56 | }); 57 | 58 | it("post with wrong paramHash", async () => { 59 | var post; 60 | var tokenCapGC = await TokenCapGC.new(); 61 | var token = await DAOToken.new("TEST","TST",0); 62 | await tokenCapGC.setParameters(token.address,100); 63 | await tokenCapGC.getParametersHash(token.address,100); 64 | post = await tokenCapGC.post(token.address,"0x0001",helpers.NULL_HASH); 65 | //token total supply is 0 66 | assert.equal(post,true); 67 | //increase the total supply 68 | await token.mint(accounts[2], 101); 69 | post = await tokenCapGC.post(token.address,"0x0001",helpers.NULL_HASH); 70 | //token total supply is 101 71 | assert.equal(post,true); 72 | }); 73 | 74 | it("mintTokens check", async () => { 75 | 76 | controller = await setup(); 77 | var tokenCapGC = await TokenCapGC.new(); 78 | await tokenCapGC.setParameters(token.address,100); 79 | var tokenCapGCParamsHash = await tokenCapGC.getParametersHash(token.address,100); 80 | await controller.addGlobalConstraint(tokenCapGC.address,tokenCapGCParamsHash,avatar.address); 81 | //var globalConstraints = await constraint("mintTokens"); 82 | await token.transferOwnership(controller.address); 83 | await controller.mintTokens(50,accounts[0],avatar.address); 84 | try { 85 | await controller.mintTokens(51,accounts[0],avatar.address); 86 | assert(false,"mint tokens should fail due to the tokenCapGC global constraint "); 87 | } 88 | catch(ex){ 89 | helpers.assertVMException(ex); 90 | } 91 | }); 92 | }); 93 | -------------------------------------------------------------------------------- /test/votingmachinecallbacks.js: -------------------------------------------------------------------------------- 1 | const helpers = require('./helpers'); 2 | 3 | const ERC20Mock = artifacts.require('./test/ERC20Mock.sol'); 4 | const DaoCreator = artifacts.require("./DaoCreator.sol"); 5 | const ControllerCreator = artifacts.require("./ControllerCreator.sol"); 6 | const DAOTracker = artifacts.require("./DAOTracker.sol"); 7 | const ARCVotingMachineCallbacksMock = artifacts.require("./ARCVotingMachineCallbacksMock.sol"); 8 | 9 | const proposalId = "0x1234000000000000000000000000000000000000000000000000000000000000"; 10 | const setup = async function (accounts) { 11 | var testSetup = new helpers.TestSetup(); 12 | var controllerCreator = await ControllerCreator.new(); 13 | var daoTracker = await DAOTracker.new(); 14 | testSetup.daoCreator = await DaoCreator.new(controllerCreator.address,daoTracker.address); 15 | testSetup.org = await helpers.setupOrganization(testSetup.daoCreator,accounts[0],1000,1000); 16 | testSetup.standardTokenMock = await ERC20Mock.new(testSetup.org.avatar.address,100); 17 | 18 | testSetup.arcVotingMachineCallbacksMock = await ARCVotingMachineCallbacksMock.new(); 19 | 20 | var permissions = "0x00000000"; 21 | await testSetup.daoCreator.setSchemes(testSetup.org.avatar.address, 22 | [testSetup.arcVotingMachineCallbacksMock.address], 23 | [helpers.NULL_HASH], 24 | [permissions],"metaData"); 25 | await testSetup.arcVotingMachineCallbacksMock.propose(proposalId, 26 | testSetup.org.avatar.address, 27 | accounts[0]); 28 | 29 | 30 | return testSetup; 31 | }; 32 | contract('VotingMachineCallbacks', function(accounts) { 33 | 34 | it("getTotalReputationSupply & reputationOf ", async function() { 35 | var testSetup = await setup(accounts); 36 | assert.equal(await testSetup.arcVotingMachineCallbacksMock.getTotalReputationSupply(proposalId),1000); 37 | assert.equal(await testSetup.arcVotingMachineCallbacksMock.reputationOf(accounts[0],proposalId),1000); 38 | }); 39 | 40 | it("mintReputation allowed only for genesisProtocol", async function() { 41 | var testSetup = await setup(accounts); 42 | try { 43 | await testSetup.arcVotingMachineCallbacksMock.mintReputation(1000,accounts[0],proposalId,{from:accounts[1]}); 44 | assert(false, 'mintReputation allowed only for votingMachine'); 45 | } catch (ex) { 46 | helpers.assertVMException(ex); 47 | } 48 | }); 49 | 50 | it("mintReputation ", async function() { 51 | var testSetup = await setup(accounts); 52 | await testSetup.arcVotingMachineCallbacksMock.mintReputation(1000,accounts[2],proposalId,{from:accounts[0]}); 53 | assert.equal(await testSetup.org.reputation.totalSupply(),2000); 54 | }); 55 | 56 | it("burnReputation allowed only for votingMachine", async function() { 57 | var testSetup = await setup(accounts); 58 | try { 59 | await testSetup.arcVotingMachineCallbacksMock.burnReputation(500,accounts[0],proposalId,{from:accounts[1]}); 60 | assert(false, 'burnReputation allowed only for votingMachine'); 61 | } catch (ex) { 62 | helpers.assertVMException(ex); 63 | } 64 | }); 65 | 66 | it("burnReputation ", async function() { 67 | var testSetup = await setup(accounts); 68 | await testSetup.arcVotingMachineCallbacksMock.burnReputation(500,accounts[0],proposalId,{from:accounts[0]}); 69 | assert.equal(await testSetup.org.reputation.totalSupply(),500); 70 | }); 71 | 72 | it("stakingTokenTransfer allowed only for votingMachine", async function() { 73 | var testSetup = await setup(accounts); 74 | try { 75 | await testSetup.arcVotingMachineCallbacksMock.stakingTokenTransfer(testSetup.standardTokenMock.address, 76 | accounts[0], 77 | 100, 78 | proposalId, 79 | {from:accounts[1]}); 80 | assert(false, 'stakingTokenTransfer allowed only for votingMachine'); 81 | } catch (ex) { 82 | helpers.assertVMException(ex); 83 | } 84 | }); 85 | 86 | it("stakingTokenTransfer ", async function() { 87 | var testSetup = await setup(accounts); 88 | assert.equal(await testSetup.standardTokenMock.balanceOf(accounts[0]),0); 89 | await testSetup.arcVotingMachineCallbacksMock.stakingTokenTransfer(testSetup.standardTokenMock.address, 90 | accounts[0], 91 | 100, 92 | proposalId, 93 | {from:accounts[0]}); 94 | assert.equal(await testSetup.standardTokenMock.balanceOf(accounts[0]),100); 95 | }); 96 | 97 | it("balanceOfStakingToken", async function() { 98 | var testSetup = await setup(accounts); 99 | assert.equal(await testSetup.arcVotingMachineCallbacksMock.balanceOfStakingToken(testSetup.standardTokenMock.address,proposalId),100); 100 | }); 101 | }); 102 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | require("babel-polyfill"); 2 | require("babel-register")({ 3 | "presets": ["es2015"], 4 | "plugins": ["syntax-async-functions","transform-regenerator"] 5 | }); 6 | 7 | module.exports = { 8 | networks: { 9 | live: { 10 | network_id: 1, 11 | host: "localhost", 12 | port: 8546, 13 | gas: 4543760 14 | }, 15 | ropsten: { 16 | network_id: 3, 17 | host: "localhost", 18 | port: 8545, 19 | gas: 4543760 20 | }, 21 | rinkeby: { 22 | network_id: 4, 23 | host: "localhost", 24 | port: 8545, 25 | gas: 4543760 26 | }, 27 | kovan: { 28 | network_id: 42, 29 | host: "localhost", 30 | port: 8545, 31 | gas: 4543760 32 | }, 33 | development: { 34 | network_id: "*", 35 | host: "localhost", 36 | port: 8545, 37 | gas: 6200000 38 | }, 39 | coverage: { 40 | host: 'localhost', 41 | network_id: '*', // eslint-disable-line camelcase 42 | port: 8555, 43 | gas: 0xfffffffffff, 44 | gasPrice: 0x01, 45 | } 46 | }, 47 | rpc: { 48 | host: "localhost", 49 | port: 8545 50 | }, 51 | solc: { 52 | optimizer: { 53 | enabled: true, 54 | runs: 200 55 | } 56 | }, 57 | compilers: { 58 | solc: { 59 | version: "0.5.17", // Fetch exact version from solc-bin (default: truffle's version) 60 | optimizer: { 61 | enabled: true, 62 | runs: 200 63 | } 64 | } 65 | }, 66 | plugins: ["solidity-coverage"] 67 | }; 68 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noImplicitAny": true, 5 | "outFile": "./build/tsc.js", 6 | "preserveConstEnums": true, 7 | "sourceMap": true 8 | }, 9 | "include": [ 10 | "lib/**/*", 11 | "./node_modules/web3-typescript-typings/index.d.ts", 12 | ], 13 | "typeRoots" : [ 14 | "node_modules/@types", 15 | "node_modules/web3-typescript-typings" 16 | ] 17 | } --------------------------------------------------------------------------------