Compare commits

..
Author SHA1 Message Date
bumi 7f878a8757 Remove aragon-cli as direct development dependency
aragon-cli now is a global pre-requirement and not direct dependency
anymore.
The uncountable npm dependencies and npm package.json hacks in the
aragon-cli package made it too hard to maintain.
2019-07-08 23:45:12 +02:00
128 changed files with 91187 additions and 34281 deletions

No files matched your search

-1
View File
@@ -28,6 +28,5 @@ module.exports = {
named: 'always',
asyncArrow: 'always',
}],
'indent': ['error', 2]
}
}
-4
View File
@@ -1,4 +0,0 @@
template: |
## Changes
$CHANGES
+2 -4
View File
@@ -1,10 +1,8 @@
build
flattened_contracts
node_modules
**/node_modules
.ganache-db
.tm_properties
yarn-error.log
.DS_Store
cache
artifacts
.openzeppelin
-1
View File
@@ -1 +0,0 @@
16
+2 -21
View File
@@ -1,37 +1,18 @@
---
language: node_js
node_js:
- "12"
- "lts/*"
sudo: false
dist: xenial
cache:
directories:
- node_modules
- apps/contribution/node_modules
- apps/contributor/node_modules
- apps/proposal/node_modules
- apps/token/node_modules
- apps/vault/node_modules
install:
- npm install -g @aragon/cli
- npm install -g truffle
- npm install
before_script:
- npm run devchain &
- sleep 10
script:
- npm run lint:wrapper
- npm run lint:contract-tests
# FIXME Fix tests
# - npm run test:token
# - npm run test:contributor
# - npm run test:contribution
# - npm run test:proposal
# - yarn lint:contracts
branches:
only:
+138 -73
View File
@@ -2,150 +2,215 @@
# Kredits Contracts
This repository contains the Solidity smart contracts and the JavaScript API
wrapper for [Kosmos Kredits](https://wiki.kosmos.org/Kredits).
This repository contains the Solidity smart contracts organized as
[Aragon](https://hack.aragon.org/) apps and JavaScript API wrapper for [Kosmos
Kredits](https://wiki.kosmos.org/Kredits).
It is based on [aragonOS](https://hack.aragon.org/docs/aragonos-intro.html) and
follows the aragonOS conventions. Aragon itself uses the [Truffle
framework](http://truffleframework.com/) for some things.
## Development
### Installation
#### App dependencies
All requirements are defined in `package.json`.
$ npm install
Each of the aragon apps are separate packages:
$ cd apps/[app]
$ npm install
You can use `npm run install-all` to install all app dependencies at once.
### Local development chain
We use [hardhat](https://hardhat.org/) as development environment for the
smart contracts.
For local development it is recommended to use
[ganache](http://truffleframework.com/ganache/) to run a local development
chain. Using the ganache simulator no full Ethereum node is required.
To run a local development chain run:
We use the default aragon-cli devchain command to confgure and run a local
development ganache.
$ npm run devchain # or: hardhat node --network hardhat
$ npm run devchain (or aragon devchain --port 7545)
To clear/reset the chain use (e.g. if you run out of funds on your devchain)
$ npm run devchain -- --reset (or aragon devchain --port 7545 --reset)
We default to port 7545 for development to not get in conflict with the default
Ethereum RPC port.
### Bootstrap
1. Run an Ethereum node and ipfs
1. Run an Ethereum node and ipfs
$ npm run devchain
$ ipfs daemon
2. Compile contracts and build ABIs
2. Deploy each app to the devchain
(compiled artifacts will be in `/artifacts`)
$ npm run build
(make sure you've run `npm install` for every app - see installation)
$ npm run deploy:apps
3. Deploy new upgradable contract proxies
3. Deploy a new KreditsKit and create a new DAO with the latest app versions
$ npm run deploy:kit
$ npm run deploy:dao
4. Execute seeds to create demo contributors, contributions, etc. (optional)
4. Execute seeds to create demo contributors, contributons, etc. (optional)
$ npm run seeds
**Step 2-4 is also summarized in `npm run bootstrap`**
5. Show contract addresses
If you want to reset your local setup:
$ cat lib/addresses.json
## Fund a local development account
If you need to fund development accounts with devchain coins:
$ npm run fund # or hardhat fund --network localhost
$ npm run reset // deploys a new kit and a new DAO
$ npm run reset:hard // deploys all apps and does reset
## Contract architecture
We use the [OpenZeppelin hardhat
proxy](https://www.npmjs.com/package/@openzeppelin/hardhat-upgrades) for
deploying and managing upgradeable contracts. (see `scripts/create-proxy.js`)
Contracts are organized in independent apps (see `/apps`) and are developed and
deployed independently. Each app has a version and can be "installed" on the
Kredits DAO independently.
![](docs/kredits-diagram.png)
A DAO can be deployed using the `scripts/deploy-kit.js` script or with the
`npm run deploy:dao` command. This deploys a new Kredits DAO, installs the
latest app versions and sets the required permissions.
See each app in `/apps/*` for details.
Each contract is independent and is connected to its dependencies by storing
the addresses of the other contracts.
## Helper scripts
`scripts/` contains some helper scripts to interact with the contracts from the
CLI. _At some point these should be moved into a real nice CLI._
To run these scripts use `hardhat run`. For example: `hardhat run
scripts/list-contributors.js --network localhost`. (NOTE: add `--network
localhost` or the network you want to use)
To run these scripts use `truffle exec`. For example: `truffle exec
scripts/add-proposal.js`.
Some scripts are also defined as npm script, see `package.json`.
Some scripts are also defined as npm script, see package.json.
### repl/console
### cli.js
Call any function on any contract:
$ truffle exec scripts/cli.js
### repl.js
Similar to cli.js but only provides a REPL with an initialized `kredits`
instance.
$ hardhat console --network localhost
$ truffle exec scripts/repl.js
### add-{contributor, contribution, proposal}.js
Script to add a new entries to the contracts using the JS wrapper
$ hardhat run scripts/add-{contributor, contribution, proposal}.js --network localhost
$ truffle exec scripts/add-{contributor, contribution, proposal}.js
### list-{contributors, contributions, proposals}.js
List contract entries
$ hardhat run scripts/list-{contributors, contributions, proposals}.js --network localhost
$ truffle exec scripts/list-{contributors, contributions, proposals}.js
### send-funds.js
Sends funds to an address. Helpful in development mode to for example fund a
metamask account.
$ truffle exec scripts/send-funds.js
### seeds.js
Run seeds defined in `config/seeds.js`.
$ truffle exec scripts/seeds.js
or
$ npm run seeds
### Get the contract addresses
### current-address.js
All contract addresses are stored in `lib/addresses.json`
Prints all known DAO addresses and the DAO address for the current network
$ cat lib/addresses.json
$ truffle exec scripts/current-address.js
or
$ npm run dao:address
### deploy-kit.js
Deploys a new KreditsKit that allows to create a new DAO
$ truffle exec script/deploy-kit.js
or
$ npm run deploy:kit
`ENS` address is required as environment variable.
`DAO_FACTORY` can optionally be set as environment variable. (see aragon)
### new-dao.js
Creates and configures a new DAO instance.
$ truffle exec script/new-dao.js
or
$ npm run deploy:dao
KreditsKit address is load from `lib/addresses/KreditsKit.json` or can be
configured through the `KREDITS_KIT` environment variable.
### deploy-apps.sh
Runs `npm install` for each app and publishes a new version.
$ ./scripts/deploy-apps.sh
or
$ npm run deploy:apps
## Deployment
### Apps deployment
To deploy a new app version run:
$ aragon apm publish major --environment=NETWORK_TO_DEPLOY
### KreditsKit
deploy the KreditsKit as Kit to create new DAOs
$ truffle exec scripts/deploy-kit.js --network=NETWORK_TO_DEPLOY
### Creating a new DAO
make sure all apps and the KreditsKit are deployed, then create a new DAO:
$ truffle exec scripts/new-dao.js --network=NETWORK_TO_DEPLOY
## ACL / Permissions
## Upgradeable contracts
We use OpenZeppelin for an upgradeable contracts:
[https://www.npmjs.com/package/@openzeppelin/hardhat-upgrades](https://www.npmjs.com/package/@openzeppelin/hardhat-upgrades)
We use aragonOS for upgradeablity of the different contracts. Refer to the
[aragonOS upgradeablity documentation](https://hack.aragon.org/docs/upgradeability-intro)
for more details.
Refer to the OpenZeppelin README and `scripts/create-proxy.js`
[OpenZeppelin Step by Step guide](https://forum.openzeppelin.com/t/openzeppelin-upgrades-step-by-step-tutorial-for-hardhat/3580)
For an upgrade example checkout `scripts/upgrade-example.js`
## Deployment to other networks
Deployable networks are configured in the `hardhat.config.js`.
To deploy to those networks provide the `--network` argument to the hardhat
commands, e.g. `--network rsk`.
Please note that some npm scripts combine multiple hardhat commands. In those
cases the hardhat commands needs to be run manually with the `--network`
argument. (=> don't use `npm run bootstrap`)
Set a `DEPLOY_KEY` environment variable with the private key (HEX) which will
be used as a root/deploy account
Typical deployment flow:
$ npm run build
$ hardhat run scripts/create-proxy.js --network rsk
# OR with deploy key:
$ DEPLOY_KEY=0xsomething hardhat run scripts/create-proxy.js --network rsk
$ # commit the new addresses in the addresses.json file if needed
To run the console on one of the non localhost networks you can also just pass
on the --network argument.
$ hardhat console --network rsk
### Example
1. Setup (see #Bootstrap)
1. Deploy each contract/apps (see `/apps/*`)
2. Create a new DAO (see scripts/deploy-kit.js)
2. Update
1. Deploy a new Version of the contract/app (see `/apps/*`)
2. Use the `aragon dao upgrade` command to "install" the new version for the DAO
(`aragon dao upgrade <DAO address> <app name>`)
## Known Issues
+12
View File
@@ -0,0 +1,12 @@
module.exports = {
'globals': {
contract: true,
describe: true,
it: true,
},
rules: {
'no-unused-vars': ['error', {
'argsIgnorePattern': '^_',
}],
}
}
+4
View File
@@ -0,0 +1,4 @@
node_modules
build
.cache
dist
+14
View File
@@ -0,0 +1,14 @@
# Git files
.gitignore
# Build files
.cache
node_modules
build
# Lock files
package-lock.json
yarn.lock
# Others
test
+1
View File
@@ -0,0 +1 @@
# Kredits Contribution
+38
View File
@@ -0,0 +1,38 @@
{
"roles": [
{
"name": "Add contributions",
"id": "ADD_CONTRIBUTION_ROLE",
"params": []
},
{
"name": "Manage token contract",
"id": "MANAGE_TOKEN_CONTRACT_ROLE",
"params": []
},
{
"name": "Veto contributions",
"id": "VETO_CONTRIBUTION_ROLE",
"params": []
}
],
"environments": {
"default": {
"network": "development",
"appName": "kredits-contribution.open.aragonpm.eth"
},
"rinkeby": {
"registry": "0x98df287b6c145399aaa709692c8d308357bc085d",
"appName": "kredits-contribution.open.aragonpm.eth",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"network": "rinkeby"
},
"production": {
"registry": "0x314159265dd8dbb310642f98f50c066173c1259b",
"appName": "contribution.open.aragonpm.eth",
"wsRPC": "wss://mainnet.eth.aragon.network/ws",
"network": "mainnet"
}
},
"path": "contracts/Contribution.sol"
}
File diff suppressed because it is too large. Load diff
@@ -1,22 +1,28 @@
pragma solidity ^0.8.0;
pragma solidity ^0.4.24;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/kernel/IKernel.sol";
interface IToken {
function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) external;
function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) public;
}
interface ContributorInterface {
function getContributorAddressById(uint32 contributorId) external view returns (address);
function getContributorIdByAddress(address contributorAccount) external view returns (uint32);
function addressIsCore(address sender) external view returns (bool);
function getContributorAddressById(uint32 contributorId) public view returns (address);
function getContributorIdByAddress(address contributorAccount) public view returns (uint32);
// TODO Maybe use for validation
// function exists(uint32 contributorId) public view returns (bool);
}
contract Contribution is Initializable {
ContributorInterface public contributorContract;
IToken public tokenContract;
contract Contribution is AragonApp {
bytes32 public constant ADD_CONTRIBUTION_ROLE = keccak256("ADD_CONTRIBUTION_ROLE");
bytes32 public constant VETO_CONTRIBUTION_ROLE = keccak256("VETO_CONTRIBUTION_ROLE");
bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
// ensure alphabetic order
enum Apps { Contribution, Contributor, Proposal, Token }
bytes32[4] public appIds;
struct ContributionData {
uint32 contributorId;
@@ -48,42 +54,41 @@ contract Contribution is Initializable {
event ContributionClaimed(uint32 id, uint32 indexed contributorId, uint32 amount);
event ContributionVetoed(uint32 id, address vetoedByAccount);
modifier onlyCore {
require(contributorContract.addressIsCore(tx.origin), "Core only");
_;
function initialize(bytes32[4] _appIds) public onlyInit {
appIds = _appIds;
blocksToWait = 40320; // 7 days; 15 seconds block time
initialized();
}
function initialize(uint32 blocksToWait_) public initializer {
blocksToWait = blocksToWait_;
// TODO refactor into a single function
function getTokenContract() public view returns (address) {
IKernel k = IKernel(kernel());
return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Token)]);
}
function setTokenContract(address token) public {
require(address(tokenContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
tokenContract = IToken(token);
}
function setContributorContract(address contributor) public {
require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
contributorContract = ContributorInterface(contributor);
function getContributorContract() public view returns (address) {
IKernel k = IKernel(kernel());
return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Contributor)]);
}
function getContributorIdByAddress(address contributorAccount) public view returns (uint32) {
return contributorContract.getContributorIdByAddress(contributorAccount);
address contributor = getContributorContract();
return ContributorInterface(contributor).getContributorIdByAddress(contributorAccount);
}
function getContributorAddressById(uint32 contributorId) public view returns (address) {
return contributorContract.getContributorAddressById(contributorId);
address contributor = getContributorContract();
return ContributorInterface(contributor).getContributorAddressById(contributorId);
}
//
// Token standard functions (ERC 721)
//
function name() external view returns (string memory) {
function name() external view returns (string) {
return name_;
}
function symbol() external view returns (string memory) {
function symbol() external view returns (string) {
return symbol_;
}
@@ -105,7 +110,7 @@ contract Contribution is Initializable {
return ownedContributions[contributorId][index];
}
function tokenMetadata(uint32 contributionId) public view returns (string memory) {
function tokenMetadata(uint32 contributionId) public view returns (string) {
return contributions[contributionId].tokenMetadataURL;
}
@@ -150,9 +155,8 @@ contract Contribution is Initializable {
);
}
function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public {
function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_CONTRIBUTION_ROLE) {
//require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint32[](0)), 'nope');
require(balanceOf(msg.sender) > 0 || contributorContract.addressIsCore(msg.sender), 'must have kredits or core');
uint32 contributionId = contributionsCount + 1;
ContributionData storage c = contributions[contributionId];
c.exists = true;
@@ -165,7 +169,7 @@ contract Contribution is Initializable {
if (contributionId < 10) {
c.confirmedAtBlock = block.number;
} else {
c.confirmedAtBlock = block.number + 1 + blocksToWait;
c.confirmedAtBlock = block.number + blocksToWait;
}
contributionsCount++;
@@ -176,8 +180,7 @@ contract Contribution is Initializable {
emit ContributionAdded(contributionId, contributorId, amount);
}
function veto(uint32 contributionId) public onlyCore {
function veto(uint32 contributionId) public isInitialized auth(VETO_CONTRIBUTION_ROLE) {
ContributionData storage c = contributions[contributionId];
require(c.exists, 'NOT_FOUND');
require(!c.claimed, 'ALREADY_CLAIMED');
@@ -187,7 +190,7 @@ contract Contribution is Initializable {
emit ContributionVetoed(contributionId, msg.sender);
}
function claim(uint32 contributionId) public {
function claim(uint32 contributionId) public isInitialized {
ContributionData storage c = contributions[contributionId];
require(c.exists, 'NOT_FOUND');
require(!c.claimed, 'ALREADY_CLAIMED');
@@ -195,14 +198,14 @@ contract Contribution is Initializable {
require(block.number >= c.confirmedAtBlock, 'NOT_CLAIMABLE');
c.claimed = true;
address token = getTokenContract();
address contributorAccount = getContributorAddressById(c.contributorId);
uint256 amount = uint256(c.amount);
tokenContract.mintFor(contributorAccount, amount, contributionId);
IToken(token).mintFor(contributorAccount, amount, contributionId);
emit ContributionClaimed(contributionId, c.contributorId, c.amount);
}
function exists(uint32 contributionId) public view returns (bool) {
function exists(uint32 contributionId) view public returns (bool) {
return contributions[contributionId].exists;
}
}
@@ -0,0 +1,23 @@
pragma solidity ^0.4.24;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"name": "Contribution",
"description": "Kredits contribution app"
}
@@ -0,0 +1,5 @@
var Migrations = artifacts.require('./Migrations.sol')
module.exports = function (deployer) {
deployer.deploy(Migrations)
}
@@ -0,0 +1,5 @@
var Contribution = artifacts.require('Contribution.sol')
module.exports = function (deployer) {
deployer.deploy(Contribution)
}
+4599
View File
File diff suppressed because it is too large. Load diff
+34
View File
@@ -0,0 +1,34 @@
{
"name": "kredits-contribution",
"version": "1.0.0",
"description": "",
"dependencies": {
"@aragon/os": "^4.2.0"
},
"devDependencies": {
"@aragon/test-helpers": "^1.1.0",
"eth-gas-reporter": "^0.2.0",
"ganache-cli": "^6.4.3",
"solidity-coverage": "^0.5.11"
},
"scripts": {
"start": "npm run start:aragon:ipfs",
"start:aragon:ipfs": "aragon run",
"start:aragon:http": "aragon run --http localhost:8001 --http-served-from ./dist",
"start:app": "",
"compile": "aragon contracts compile",
"sync-assets": "",
"build:app": "",
"build:script": "",
"build": "",
"publish:patch": "aragon apm publish patch",
"publish:minor": "aragon apm publish minor",
"publish:major": "aragon apm publish major",
"versions": "aragon apm versions",
"test": "TRUFFLE_TEST=true PORT=7545 npm run ganache-cli:test",
"test:gas": "GAS_REPORTER=true npm test",
"coverage": "SOLIDITY_COVERAGE=true npm run ganache-cli:test",
"ganache-cli:test": "./node_modules/@aragon/test-helpers/ganache-cli.sh"
},
"keywords": []
}
+5
View File
@@ -0,0 +1,5 @@
// const Contribution = artifacts.require('Contribution.sol');
contract('Contribution', (_accounts) => {
it('should be tested');
});
+1
View File
@@ -0,0 +1 @@
module.exports = require("../../truffle.js");
File diff suppressed because it is too large. Load diff
+4
View File
@@ -0,0 +1,4 @@
node_modules
build
.cache
dist
+14
View File
@@ -0,0 +1,14 @@
# Git files
.gitignore
# Build files
.cache
node_modules
build
# Lock files
package-lock.json
yarn.lock
# Others
test
+1
View File
@@ -0,0 +1 @@
# Kredits Contributor
+28
View File
@@ -0,0 +1,28 @@
{
"roles": [
{
"name": "Manage contributors",
"id": "MANAGE_CONTRIBUTORS_ROLE",
"params": []
}
],
"environments": {
"default": {
"network": "development",
"appName": "kredits-contributor.open.aragonpm.eth"
},
"rinkeby": {
"registry": "0x98df287b6c145399aaa709692c8d308357bc085d",
"appName": "kredits-contributor.open.aragonpm.eth",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"network": "rinkeby"
},
"production": {
"registry": "0x314159265dd8dbb310642f98f50c066173c1259b",
"appName": "contributor.open.aragonpm.eth",
"wsRPC": "wss://mainnet.eth.aragon.network/ws",
"network": "mainnet"
}
},
"path": "contracts/Contributor.sol"
}
@@ -1,19 +1,19 @@
pragma solidity ^0.8.0;
pragma solidity ^0.4.24;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/kernel/IKernel.sol";
interface ITokenBalance {
function balanceOf(address contributorAccount) external view returns (uint256);
function balanceOf(address contributorAccount) public view returns (uint256);
}
interface IContributionBalance {
function totalKreditsEarnedByContributor(uint32 contributorId, bool confirmedOnly) external view returns (uint32 amount);
function balanceOf(address owner) external view returns (uint256);
function totalKreditsEarnedByContributor(uint32 contributorId, bool confirmedOnly) public view returns (uint32 amount);
function balanceOf(address owner) public view returns (uint256);
}
contract Contributor is Initializable {
address deployer;
IContributionBalance public contributionContract;
ITokenBalance public tokenContract;
contract Contributor is AragonApp {
bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
bytes32 public constant MANAGE_CONTRIBUTORS_ROLE = keccak256("MANAGE_CONTRIBUTORS_ROLE");
struct Contributor {
address account;
@@ -27,30 +27,33 @@ contract Contributor is Initializable {
mapping (uint32 => Contributor) public contributors;
uint32 public contributorsCount;
// ensure alphabetic order
enum Apps { Contribution, Contributor, Proposal, Token }
bytes32[4] public appIds;
event ContributorProfileUpdated(uint32 id, bytes32 oldHashDigest, bytes32 newHashDigest); // what should be logged
event ContributorAccountUpdated(uint32 id, address oldAccount, address newAccount);
event ContributorAdded(uint32 id, address account);
modifier onlyCore {
require(addressIsCore(tx.origin), "Core only");
_;
function initialize(address root,bytes32[4] _appIds) public onlyInit {
appIds = _appIds;
initialized();
}
function initialize() public initializer {
deployer = msg.sender;
function getTokenContract() public view returns (address) {
IKernel k = IKernel(kernel());
return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Token)]);
}
function setContributionContract(address contribution) public onlyCore {
require(address(contributionContract) == address(0) || addressIsCore(msg.sender), "Core only");
contributionContract = IContributionBalance(contribution);
function getContributionContract() public view returns (address) {
IKernel k = IKernel(kernel());
return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Contribution)]);
}
function setTokenContract(address token) public onlyCore {
require(address(tokenContract) == address(0) || addressIsCore(msg.sender), "Core only");
tokenContract = ITokenBalance(token);
}
function coreContributorsCount() public view returns (uint32) {
function coreContributorsCount() view public returns (uint32) {
uint32 count = 0;
for (uint32 i = 1; i <= contributorsCount; i++) {
if (isCoreTeam(i)) {
@@ -60,17 +63,14 @@ contract Contributor is Initializable {
return count;
}
function updateContributorAccount(uint32 id, address oldAccount, address newAccount) public onlyCore {
require(newAccount != address(0), "invalid new account address");
require(getContributorAddressById(id) == oldAccount, "contributor does not exist");
function updateContributorAccount(uint32 id, address oldAccount, address newAccount) public auth(MANAGE_CONTRIBUTORS_ROLE) {
contributorIds[oldAccount] = 0;
contributorIds[newAccount] = id;
contributors[id].account = newAccount;
emit ContributorAccountUpdated(id, oldAccount, newAccount);
ContributorAccountUpdated(id, oldAccount, newAccount);
}
function updateContributorProfileHash(uint32 id, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore {
function updateContributorProfileHash(uint32 id, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(MANAGE_CONTRIBUTORS_ROLE) {
Contributor storage c = contributors[id];
bytes32 oldHashDigest = c.hashDigest;
c.hashDigest = hashDigest;
@@ -80,7 +80,7 @@ contract Contributor is Initializable {
ContributorProfileUpdated(id, oldHashDigest, c.hashDigest);
}
function addContributor(address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore {
function addContributor(address account, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(MANAGE_CONTRIBUTORS_ROLE) {
require(!addressExists(account));
uint32 _id = contributorsCount + 1;
assert(!contributors[_id].exists); // this can not be acually
@@ -99,7 +99,7 @@ contract Contributor is Initializable {
function isCoreTeam(uint32 id) view public returns (bool) {
// TODO: for simplicity we simply define the first contributors as core
// later this needs to be changed to something more dynamic
return id > 0 && id < 7;
return id < 7;
}
function exists(uint32 id) view public returns (bool) {
@@ -107,10 +107,6 @@ contract Contributor is Initializable {
}
function addressIsCore(address account) view public returns (bool) {
// the deployer is always core
if(account == deployer) {
return true;
}
uint32 id = getContributorIdByAddress(account);
return isCoreTeam(id);
}
@@ -127,7 +123,7 @@ contract Contributor is Initializable {
return contributors[id].account;
}
function getContributorByAddress(address account) internal view returns (Contributor memory) {
function getContributorByAddress(address account) internal view returns (Contributor) {
uint32 id = contributorIds[account];
return contributors[id];
}
@@ -140,10 +136,24 @@ contract Contributor is Initializable {
hashFunction = c.hashFunction;
hashSize = c.hashSize;
isCore = isCoreTeam(id);
balance = tokenContract.balanceOf(c.account);
totalKreditsEarned = contributionContract.totalKreditsEarnedByContributor(_id, true);
contributionsCount = contributionContract.balanceOf(c.account);
address token = getTokenContract();
balance = ITokenBalance(token).balanceOf(c.account);
address contribution = getContributionContract();
totalKreditsEarned = IContributionBalance(contribution).totalKreditsEarnedByContributor(_id, true);
contributionsCount = IContributionBalance(contribution).balanceOf(c.account);
exists = c.exists;
}
function canPerform(address _who, address _where, bytes32 _what, uint256[] memory _how) public returns (bool) {
address sender = _who;
if (sender == address(-1)) {
sender = tx.origin;
}
// _what == keccak256('VOTE_PROPOSAL_ROLE')
if (_what == 0xd61216798314d2fc33e42ff2021d66707b1e38517d3f7166798a9d3a196a9c96) {
return contributorIds[sender] != uint256(0);
}
return addressIsCore(sender);
}
}
@@ -0,0 +1,23 @@
pragma solidity ^0.4.24;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"name": "Contributor",
"description": "Kredits Contributor app"
}
@@ -0,0 +1,5 @@
var Migrations = artifacts.require('./Migrations.sol')
module.exports = function (deployer) {
deployer.deploy(Migrations)
}
@@ -0,0 +1,5 @@
var Contributor = artifacts.require('Contributor.sol')
module.exports = function (deployer) {
deployer.deploy(Contributor)
}
+13120
View File
File diff suppressed because it is too large. Load diff
+34
View File
@@ -0,0 +1,34 @@
{
"name": "kredits-contributor",
"version": "1.0.0",
"description": "",
"dependencies": {
"@aragon/os": "^4.2.0"
},
"devDependencies": {
"@aragon/test-helpers": "^1.1.0",
"eth-gas-reporter": "^0.2.0",
"ganache-cli": "^6.4.3",
"solidity-coverage": "^0.5.11"
},
"scripts": {
"start": "npm run start:aragon:ipfs",
"start:aragon:ipfs": "aragon run",
"start:aragon:http": "aragon run --http localhost:8001 --http-served-from ./dist",
"start:app": "",
"compile": "aragon contracts compile",
"sync-assets": "",
"build:app": "",
"build:script": "",
"build": "",
"publish:patch": "aragon apm publish patch",
"publish:minor": "aragon apm publish minor",
"publish:major": "aragon apm publish major",
"versions": "aragon apm versions",
"test": "TRUFFLE_TEST=true PORT=7545 npm run ganache-cli:test",
"test:gas": "GAS_REPORTER=true npm test",
"coverage": "SOLIDITY_COVERAGE=true npm run ganache-cli:test",
"ganache-cli:test": "./node_modules/@aragon/test-helpers/ganache-cli.sh"
},
"keywords": []
}
+5
View File
@@ -0,0 +1,5 @@
// const Contributor = artifacts.require('Contributor.sol');
contract('Contributor', (_accounts) => {
it('should be tested');
});
+1
View File
@@ -0,0 +1 @@
module.exports = require("../../truffle.js");
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
# Kredits Proposal
+33
View File
@@ -0,0 +1,33 @@
{
"roles": [
{
"name": "Add proposal",
"id": "ADD_PROPOSAL_ROLE",
"params": []
},
{
"name": "Vote proposals",
"id": "VOTE_PROPOSAL_ROLE",
"params": []
}
],
"environments": {
"default": {
"network": "development",
"appName": "kredits-proposal.open.aragonpm.eth"
},
"rinkeby": {
"registry": "0x98df287b6c145399aaa709692c8d308357bc085d",
"appName": "kredits-proposal.open.aragonpm.eth",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"network": "rinkeby"
},
"production": {
"registry": "0x314159265dd8dbb310642f98f50c066173c1259b",
"appName": "proposal.open.aragonpm.eth",
"wsRPC": "wss://mainnet.eth.aragon.network/ws",
"network": "mainnet"
}
},
"path": "contracts/Proposal.sol"
}
+133
View File
@@ -0,0 +1,133 @@
pragma solidity ^0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/kernel/IKernel.sol";
interface IContributor {
function getContributorAddressById(uint32 contributorId) public view returns (address);
function getContributorIdByAddress(address contributorAccount) public view returns (uint32);
function exists(uint32 contributorId) public view returns (bool);
}
interface IContribution {
function add(uint32 amount, uint32 contributorId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public;
}
contract Proposal is AragonApp {
bytes32 public constant ADD_PROPOSAL_ROLE = keccak256("ADD_PROPOSAL_ROLE");
bytes32 public constant VOTE_PROPOSAL_ROLE = keccak256("VOTE_PROPOSAL_ROLE");
bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
// ensure alphabetic order
enum Apps { Contribution, Contributor, Proposal, Token }
bytes32[4] public appIds;
struct Proposal {
address creatorAccount;
uint32 contributorId;
uint16 votesCount;
uint16 votesNeeded;
uint32 amount;
bool executed;
bytes32 hashDigest;
uint8 hashFunction;
uint8 hashSize;
uint32[] voterIds;
mapping (uint32 => bool) votes;
bool exists;
}
mapping(uint32 => Proposal) public proposals;
uint32 public proposalsCount;
event ProposalCreated(uint32 id, address creatorAccount, uint32 contributorId, uint32 amount);
event ProposalVoted(uint32 id, uint32 voterId, uint16 totalVotes);
event ProposalExecuted(uint32 id, uint32 contributorId, uint32 amount);
function initialize(bytes32[4] _appIds) public onlyInit {
appIds = _appIds;
initialized();
}
function getContributorContract() public view returns (address) {
return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Contributor)]);
}
function getContributionContract() public view returns (address) {
return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Contribution)]);
}
function addProposal(uint32 contributorId, uint32 amount, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_PROPOSAL_ROLE) {
require(IContributor(getContributorContract()).exists(contributorId), 'CONTRIBUTOR_NOT_FOUND');
uint32 proposalId = proposalsCount + 1;
uint16 _votesNeeded = 1; //contributorsContract().coreContributorsCount() / 100 * 75;
Proposal storage p = proposals[proposalId];
p.creatorAccount = msg.sender;
p.contributorId = contributorId;
p.amount = amount;
p.hashDigest = hashDigest;
p.hashFunction = hashFunction;
p.hashSize = hashSize;
p.votesCount = 0;
p.votesNeeded = _votesNeeded;
p.exists = true;
proposalsCount++;
emit ProposalCreated(proposalId, msg.sender, p.contributorId, p.amount);
}
function getProposal(uint32 proposalId) public view returns (uint32 id, address creatorAccount, uint32 contributorId, uint16 votesCount, uint16 votesNeeded, uint32 amount, bool executed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint32[] voterIds, bool exists) {
id = proposalId;
Proposal storage p = proposals[id];
return (
id,
p.creatorAccount,
p.contributorId,
p.votesCount,
p.votesNeeded,
p.amount,
p.executed,
p.hashDigest,
p.hashFunction,
p.hashSize,
p.voterIds,
p.exists
);
}
function vote(uint32 proposalId) public isInitialized auth(VOTE_PROPOSAL_ROLE) {
Proposal storage p = proposals[proposalId];
require(!p.executed, 'ALREADY_EXECUTED');
uint32 voterId = IContributor(getContributorContract()).getContributorIdByAddress(msg.sender);
require(p.votes[voterId] != true, 'ALREADY_VOTED');
p.voterIds.push(voterId);
p.votes[voterId] = true;
p.votesCount++;
if (p.votesCount >= p.votesNeeded) {
executeProposal(proposalId);
}
emit ProposalVoted(proposalId, voterId, p.votesCount);
}
function batchVote(uint32[] _proposalIds) public isInitialized auth(VOTE_PROPOSAL_ROLE) {
for (uint32 i = 0; i < _proposalIds.length; i++) {
vote(_proposalIds[i]);
}
}
function executeProposal(uint32 proposalId) private {
Proposal storage p = proposals[proposalId];
require(!p.executed, 'ALREADY_EXECUTED');
require(p.votesCount >= p.votesNeeded, 'MISSING_VOTES');
p.executed = true;
IContribution(getContributionContract()).add(p.amount, p.contributorId, p.hashDigest, p.hashFunction, p.hashSize);
emit ProposalExecuted(proposalId, p.contributorId, p.amount);
}
}
@@ -0,0 +1,23 @@
pragma solidity ^0.4.24;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"name": "Proposal",
"description": "Kredits Proposal app"
}
@@ -0,0 +1,5 @@
var Migrations = artifacts.require('./Migrations.sol')
module.exports = function (deployer) {
deployer.deploy(Migrations)
}
+13120
View File
File diff suppressed because it is too large. Load diff
+34
View File
@@ -0,0 +1,34 @@
{
"name": "kredits-proposal",
"version": "1.0.0",
"description": "",
"dependencies": {
"@aragon/os": "^4.2.0"
},
"devDependencies": {
"@aragon/test-helpers": "^1.1.0",
"eth-gas-reporter": "^0.2.0",
"ganache-cli": "^6.4.3",
"solidity-coverage": "^0.5.11"
},
"scripts": {
"start": "npm run start:aragon:ipfs",
"start:aragon:ipfs": "aragon run",
"start:aragon:http": "aragon run --http localhost:8001 --http-served-from ./dist",
"start:app": "",
"compile": "aragon contracts compile",
"sync-assets": "",
"build:app": "",
"build:script": "",
"build": "",
"publish:patch": "aragon apm publish patch",
"publish:minor": "aragon apm publish minor",
"publish:major": "aragon apm publish major",
"versions": "aragon apm versions",
"test": "TRUFFLE_TEST=true PORT=7545 npm run ganache-cli:test",
"test:gas": "GAS_REPORTER=true npm test",
"coverage": "SOLIDITY_COVERAGE=true npm run ganache-cli:test",
"ganache-cli:test": "./node_modules/@aragon/test-helpers/ganache-cli.sh"
},
"keywords": []
}
+5
View File
@@ -0,0 +1,5 @@
// const Proposal = artifacts.require('Proposal.sol');
contract('Proposal', (_accounts) => {
it('should be tested');
});
+1
View File
@@ -0,0 +1 @@
module.exports = require("../../truffle.js");
File diff suppressed because it is too large. Load diff
+4
View File
@@ -0,0 +1,4 @@
node_modules
build
.cache
dist
+14
View File
@@ -0,0 +1,14 @@
# Git files
.gitignore
# Build files
.cache
node_modules
build
# Lock files
package-lock.json
yarn.lock
# Others
test
+1
View File
@@ -0,0 +1 @@
# Kredits Token
+28
View File
@@ -0,0 +1,28 @@
{
"roles": [
{
"name": "Mint token",
"id": "MINT_TOKEN_ROLE",
"params": []
}
],
"environments": {
"default": {
"network": "development",
"appName": "kredits-token.open.aragonpm.eth"
},
"rinkeby": {
"registry": "0x98df287b6c145399aaa709692c8d308357bc085d",
"appName": "kredits-token.open.aragonpm.eth",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"network": "rinkeby"
},
"mainnet": {
"registry": "0x314159265dd8dbb310642f98f50c066173c1259b",
"appName": "kredits-token.open.aragonpm.eth",
"wsRPC": "wss://mainnet.eth.aragon.network/ws",
"network": "mainnet"
}
},
"path": "contracts/Token.sol"
}
+173
View File
@@ -0,0 +1,173 @@
pragma solidity ^0.4.24;
import "@aragon/os/contracts/lib/math/SafeMath.sol";
/**
* beause ERC20.sol conflicts with the aragon ERC20.sol this is copied and modified from:
* https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20.sol
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* https://eips.ethereum.org/EIPS/eip-20
* Originally based on code by FirstBlood:
* https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*
* This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
* all accounts just by listening to said events. Note that this isn't required by the specification, and other
* compliant implementations may not do it.
*/
contract ERC20Token {
using SafeMath for uint256;
mapping (address => uint256) public _balances;
mapping (address => mapping (address => uint256)) private _allowed;
uint256 public _totalSupply;
string public name;
string public symbol;
uint8 public decimals;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
/**
* @dev Gets the balance of the specified address.
* @param owner The address to query the balance of.
* @return A uint256 representing the amount owned by the passed address.
*/
function balanceOf(address owner) public view returns (uint256) {
return _balances[owner];
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param owner address The address which owns the funds.
* @param spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address owner, address spender) public view returns (uint256) {
return _allowed[owner][spender];
}
/**
* @dev Transfer token to a specified address
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
function transfer(address to, uint256 value) public returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
*/
function approve(address spender, uint256 value) public returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
/**
* @dev Transfer tokens from one address to another.
* Note that while this function emits an Approval event, this is not required as per the specification,
* and other compliant implementations may not emit the event.
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 the amount of tokens to be transferred
*/
function transferFrom(address from, address to, uint256 value) public returns (bool) {
_transfer(from, to, value);
_approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
return true;
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when _allowed[msg.sender][spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* Emits an Approval event.
* @param spender The address which will spend the funds.
* @param addedValue The amount of tokens to increase the allowance by.
*/
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when _allowed[msg.sender][spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* Emits an Approval event.
* @param spender The address which will spend the funds.
* @param subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));
return true;
}
/**
* @dev Transfer token for a specified addresses
* @param from The address to transfer from.
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
function _transfer(address from, address to, uint256 value) internal {
require(to != address(0));
_balances[from] = _balances[from].sub(value);
_balances[to] = _balances[to].add(value);
emit Transfer(from, to, value);
}
/**
* @dev Internal function that mints an amount of the token and assigns it to
* an account. This encapsulates the modification of balances such that the
* proper events are emitted.
* @param account The account that will receive the created tokens.
* @param value The amount that will be created.
*/
function _mint(address account, uint256 value) internal {
require(account != address(0), 'invalid address');
_totalSupply = _totalSupply.add(value);
_balances[account] = _balances[account].add(value);
emit Transfer(address(0), account, value);
}
/**
* @dev Approve an address to spend another addresses' tokens.
* @param owner The address that owns the tokens.
* @param spender The address that will spend the tokens.
* @param value The number of tokens that can be spent.
*/
function _approve(address owner, address spender, uint256 value) internal {
require(spender != address(0));
require(owner != address(0));
_allowed[owner][spender] = value;
emit Approval(owner, spender, value);
}
}
+29
View File
@@ -0,0 +1,29 @@
pragma solidity ^0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "./ERC20Token.sol";
contract Token is ERC20Token, AragonApp {
bytes32 public constant MINT_TOKEN_ROLE = keccak256("MINT_TOKEN_ROLE");
// ensure alphabetic order
enum Apps { Contribution, Contributor, Proposal, Token }
bytes32[4] public appIds;
event LogMint(address indexed recipient, uint256 amount, uint32 contributionId);
function initialize(bytes32[4] _appIds) public onlyInit {
appIds = _appIds;
name = 'Kredits';
symbol = '₭S';
decimals = 18;
initialized();
}
function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) public isInitialized auth(MINT_TOKEN_ROLE) {
uint256 amountInWei = amount.mul(1 ether);
_mint(contributorAccount, amountInWei);
emit LogMint(contributorAccount, amount, contributionId);
}
}
+23
View File
@@ -0,0 +1,23 @@
pragma solidity ^0.4.24;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
constructor() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"name": "Token",
"description": "Kredits Token app"
}
@@ -0,0 +1,5 @@
var Migrations = artifacts.require('./Migrations.sol')
module.exports = function (deployer) {
deployer.deploy(Migrations)
}
@@ -0,0 +1,5 @@
var Token = artifacts.require('Token.sol')
module.exports = function (deployer) {
deployer.deploy(Token)
}
+13120
View File
File diff suppressed because it is too large. Load diff
+34
View File
@@ -0,0 +1,34 @@
{
"name": "kredits-token",
"version": "1.0.0",
"description": "",
"dependencies": {
"@aragon/os": "^4.2.0"
},
"devDependencies": {
"@aragon/test-helpers": "^1.1.0",
"eth-gas-reporter": "^0.2.0",
"ganache-cli": "^6.4.3",
"solidity-coverage": "^0.5.11"
},
"scripts": {
"start": "npm run start:aragon:ipfs",
"start:aragon:ipfs": "aragon run",
"start:aragon:http": "aragon run --http localhost:8001 --http-served-from ./dist",
"start:app": "",
"compile": "aragon contracts compile",
"sync-assets": "",
"build:app": "",
"build:script": "",
"build": "",
"publish:patch": "aragon apm publish patch",
"publish:minor": "aragon apm publish minor",
"publish:major": "aragon apm publish major",
"versions": "aragon apm versions",
"test": "TRUFFLE_TEST=true PORT=7545 npm run ganache-cli:test",
"test:gas": "GAS_REPORTER=true npm test",
"coverage": "SOLIDITY_COVERAGE=true npm run ganache-cli:test",
"ganache-cli:test": "./node_modules/@aragon/test-helpers/ganache-cli.sh"
},
"keywords": []
}
+5
View File
@@ -0,0 +1,5 @@
// const Token = artifacts.require('Token.sol');
contract('Token', (_accounts) => {
it('should be tested');
});
+1
View File
@@ -0,0 +1 @@
module.exports = require("../../truffle.js");
+8145
View File
File diff suppressed because it is too large. Load diff
+60
View File
@@ -0,0 +1,60 @@
{
"roles": [
{
"name": "Add contributions",
"id": "ADD_CONTRIBUTION_ROLE",
"params": []
},
{
"name": "Veto contributions",
"id": "VETO_CONTRIBUTION_ROLE",
"params": []
},
{
"name": "Manage contributors",
"id": "MANAGE_CONTRIBUTORS_ROLE",
"params": []
},
{
"name": "Mint token",
"id": "MINT_TOKEN_ROLE",
"params": []
},
{
"name": "Add proposal",
"id": "ADD_PROPOSAL_ROLE",
"params": []
},
{
"name": "Vote proposal",
"id": "VOTE_PROPOSAL_ROLE",
"params": []
}
],
"environments": {
"development": {
"network": "development",
"apm": "open.aragonpm.eth",
"registry": "0x5f6f7e8cc7346a11ca2def8f827b7a0b612c56a1",
"appName": "dummy.open.aragonpm.eth"
},
"rinkeby": {
"network": "rinkeby",
"registry": "0x98Df287B6C145399Aaa709692c8D308357bC085D",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"daoFactory": "0x2298d27a9b847c681d2b2c2828ab9d79013f5f1d",
"appName": "dummy.open.aragonpm.eth",
"apm": "open.aragonpm.eth"
},
"kovan": {
"network": "kovan",
"appName": "dummy.aragonpm.eth"
},
"default": {
"network": "development",
"appName": "dummy.aragonpm.eth",
"apm": "open.aragonpm.eth"
}
},
"path": "contracts/misc/DummyApp.sol"
}
+6 -12
View File
@@ -31,19 +31,13 @@ const contractCalls = [
wiki_username: 'Manuel',
}, { gasLimit: 200000 }]],
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Test this thing', url: '' }, { gasLimit: 350000 }]],
['Proposal', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-09', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Ran the seeds', url: '' }, { gasLimit: 350000 }]],
['Proposal', 'add', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-10', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Ran the seeds', url: '' }, { gasLimit: 350000 }]],
['Proposal', 'add', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Hacked on kredits', url: '' }, { gasLimit: 350000 }]],
['Proposal', 'vote', [1, { gasLimit: 550000 }]],
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 5000, kind: 'dev', description: '[67P/kredits-contracts] Introduce contribution token', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 1500, kind: 'dev', description: '[67P/kredits-web] Reviewed stuff', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 1500, kind: 'dev', description: '[67P/kredits-contracts] Add tests', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 1500, kind: 'dev', description: '[67P/kredits-contracts] Introduce contribution token', url: '' }, { gasLimit: 350000 }]],
['Contribution', 'add', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 5000, kind: 'dev', description: '[67P/kredits-web] Expense UI, first draft', url: '' }, { gasLimit: 350000 }]],
['Reimbursement', 'add', [{amount: 1116000, recipientId: 1, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [
{ title: 'Server rent', description: 'Dedicated server: andromeda.kosmos.org, April 2020', amount: 61, currency: 'EUR', date: '2020-05-28' },
{ title: 'Server rent', description: 'Dedicated server: centaurus.kosmos.org, April 2020', amount: 32, currency: 'EUR', date: '2020-05-28' }
]}, { gasLimit: 300000 }]],
['Reimbursement', 'add', [{amount: 166800, recipientId: 2, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [
{ title: 'Domain kosmos.chat', description: 'Yearly registration fee for domain kosmos.chat', amount: 13.90, currency: 'EUR', date: '2020-05-30' }
]}, { gasLimit: 300000 }]],
['Contribution', 'claim', [1, { gasLimit: 300000 }]],
];
const funds = [
+90
View File
@@ -0,0 +1,90 @@
pragma solidity 0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/kernel/Kernel.sol";
import "@aragon/os/contracts/acl/ACL.sol";
import "@aragon/kits-base/contracts/KitBase.sol";
import "../apps/contribution/contracts/Contribution.sol";
import "../apps/contributor/contracts/Contributor.sol";
import "../apps/token/contracts/Token.sol";
import "../apps/proposal/contracts/Proposal.sol";
contract KreditsKit is KitBase {
// ensure alphabetic order
enum Apps { Contribution, Contributor, Proposal, Token }
bytes32[4] public appIds;
event DeployInstance(address dao);
event InstalledApp(address dao, address appProxy, bytes32 appId);
constructor (DAOFactory _fac, ENS _ens, bytes32[4] _appIds) public KitBase(_fac, _ens) {
appIds = _appIds;
}
function newInstance() public returns (Kernel dao) {
address root = msg.sender;
dao = fac.newDAO(this);
ACL acl = ACL(dao.acl());
acl.createPermission(this, dao, dao.APP_MANAGER_ROLE(), this);
Contributor contributor = Contributor(_installApp(dao, appIds[uint8(Apps.Contributor)]));
contributor.initialize(root, appIds);
acl.createPermission(root, contributor, contributor.MANAGE_CONTRIBUTORS_ROLE(), this);
Token token = Token(_installApp(dao, appIds[uint8(Apps.Token)]));
token.initialize(appIds);
Contribution contribution = Contribution(_installApp(dao, appIds[uint8(Apps.Contribution)]));
contribution.initialize(appIds);
Proposal proposal = Proposal(_installApp(dao, appIds[uint8(Apps.Proposal)]));
proposal.initialize(appIds);
acl.createPermission(root, contribution, contribution.ADD_CONTRIBUTION_ROLE(), this);
acl.createPermission(root, contribution, contribution.VETO_CONTRIBUTION_ROLE(), this);
acl.grantPermission(proposal, contribution, contribution.ADD_CONTRIBUTION_ROLE());
uint256[] memory params = new uint256[](1);
params[0] = uint256(203) << 248 | uint256(1) << 240 | uint240(contributor);
acl.grantPermissionP(acl.ANY_ENTITY(), contribution, contribution.ADD_CONTRIBUTION_ROLE(), params);
acl.grantPermissionP(acl.ANY_ENTITY(), contribution, contribution.VETO_CONTRIBUTION_ROLE(), params);
acl.grantPermissionP(acl.ANY_ENTITY(), contributor, contributor.MANAGE_CONTRIBUTORS_ROLE(), params);
//acl.setPermissionManager(this, proposal, proposal.VOTE_PROPOSAL_ROLE();
acl.createPermission(root, proposal, proposal.VOTE_PROPOSAL_ROLE(), this);
acl.grantPermissionP(acl.ANY_ENTITY(), proposal, proposal.VOTE_PROPOSAL_ROLE(), params);
acl.createPermission(root, proposal, proposal.ADD_PROPOSAL_ROLE(), this);
//acl.grantPermissionP(address(-1), proposal, proposal.ADD_PROPOSAL_ROLE(), params);
acl.grantPermission(acl.ANY_ENTITY(), proposal, proposal.ADD_PROPOSAL_ROLE());
acl.setPermissionManager(root, proposal, proposal.VOTE_PROPOSAL_ROLE());
acl.setPermissionManager(root, proposal, proposal.ADD_PROPOSAL_ROLE());
acl.setPermissionManager(root, contribution, contribution.ADD_CONTRIBUTION_ROLE());
acl.setPermissionManager(root, contribution, contribution.VETO_CONTRIBUTION_ROLE());
acl.setPermissionManager(root, contributor, contributor.MANAGE_CONTRIBUTORS_ROLE());
acl.createPermission(root, token, token.MINT_TOKEN_ROLE(), this);
acl.grantPermission(contribution, token, token.MINT_TOKEN_ROLE());
acl.setPermissionManager(root, token, token.MINT_TOKEN_ROLE());
cleanupDAOPermissions(dao, acl, root);
emit DeployInstance(dao);
return dao;
}
function _installApp(Kernel _dao, bytes32 _appId) internal returns (AragonApp) {
address baseAppAddress = latestVersionAppBase(_appId);
require(baseAppAddress != address(0), "App should be deployed");
AragonApp appProxy = AragonApp(_dao.newAppInstance(_appId, baseAppAddress, new bytes(0), true));
emit InstalledApp(_dao, appProxy, _appId);
return appProxy;
}
}
-113
View File
@@ -1,113 +0,0 @@
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
interface ContributorInterface {
function getContributorAddressById(uint32 contributorId) external view returns (address);
function getContributorIdByAddress(address contributorAccount) external view returns (uint32);
function addressIsCore(address sender) external view returns (bool);
// TODO Maybe use for validation
// function exists(uint32 contributorId) public view returns (bool);
}
contract Reimbursement is Initializable {
ContributorInterface public contributorContract;
struct ReimbursementData {
uint32 recipientId;
uint256 amount;
address token;
bytes32 hashDigest;
uint8 hashFunction;
uint8 hashSize;
uint256 confirmedAtBlock;
bool vetoed;
bool exists;
}
mapping(uint32 => ReimbursementData) public reimbursements;
uint32 public reimbursementsCount;
uint32 public blocksToWait;
event ReimbursementAdded(uint32 id, address indexed addedByAccount, uint256 amount);
event ReimbursementVetoed(uint32 id, address vetoedByAccount);
function initialize() public initializer {
blocksToWait = 40320; // 7 days; 15 seconds block time
}
modifier onlyCore {
require(contributorContract.addressIsCore(tx.origin), "Core only");
_;
}
function setContributorContract(address contributor) public {
require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
contributorContract = ContributorInterface(contributor);
}
function getContributorIdByAddress(address contributorAccount) public view returns (uint32) {
return contributorContract.getContributorIdByAddress(contributorAccount);
}
function getContributorAddressById(uint32 contributorId) public view returns (address) {
return contributorContract.getContributorAddressById(contributorId);
}
function totalAmount(bool confirmedOnly) public view returns (uint256 amount) {
for (uint32 i = 1; i <= reimbursementsCount; i++) {
ReimbursementData memory r = reimbursements[i];
if (!r.vetoed && (block.number >= r.confirmedAtBlock || !confirmedOnly)) {
amount += r.amount; // should use safemath
}
}
}
function get(uint32 reimbursementId) public view returns (uint32 id, uint32 recipientId, uint256 amount, address token, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint256 confirmedAtBlock, bool exists, bool vetoed) {
id = reimbursementId;
ReimbursementData storage r = reimbursements[id];
return (
id,
r.recipientId,
r.amount,
r.token,
r.hashDigest,
r.hashFunction,
r.hashSize,
r.confirmedAtBlock,
r.exists,
r.vetoed
);
}
function add(uint256 amount, address token, uint32 recipientId, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public onlyCore {
uint32 reimbursementId = reimbursementsCount + 1;
ReimbursementData storage r = reimbursements[reimbursementId];
r.exists = true;
r.amount = amount;
r.token = token;
r.recipientId = recipientId;
r.hashDigest = hashDigest;
r.hashFunction = hashFunction;
r.hashSize = hashSize;
r.confirmedAtBlock = block.number + blocksToWait;
reimbursementsCount++;
emit ReimbursementAdded(reimbursementId, msg.sender, amount);
}
function veto(uint32 reimbursementId) public onlyCore {
ReimbursementData storage r = reimbursements[reimbursementId];
require(r.exists, 'NOT_FOUND');
require(block.number < r.confirmedAtBlock, 'VETO_PERIOD_ENDED');
r.vetoed = true;
emit ReimbursementVetoed(reimbursementId, msg.sender);
}
function exists(uint32 reimbursementId) public view returns (bool) {
return reimbursements[reimbursementId].exists;
}
}
-44
View File
@@ -1,44 +0,0 @@
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol";
interface ContributorInterface {
function getContributorAddressById(uint32 contributorId) external view returns (address);
function getContributorIdByAddress(address contributorAccount) external view returns (uint32);
function addressIsCore(address sender) external view returns (bool);
// TODO Maybe use for validation
// function exists(uint32 contributorId) public view returns (bool);
}
contract Token is Initializable, ERC20Upgradeable {
ContributorInterface public contributorContract;
using SafeMathUpgradeable for uint256;
address public contributionContract;
event LogMint(address indexed recipient, uint256 amount, uint32 contributionId);
function initialize() public virtual initializer {
__ERC20_init('Kredits', 'KS');
}
function setContributionContract(address contribution) public {
require(address(contributionContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
contributionContract = contribution;
}
function setContributorContract(address contributor) public {
require(address(contributorContract) == address(0) || contributorContract.addressIsCore(msg.sender), "Core only");
contributorContract = ContributorInterface(contributor);
}
function mintFor(address contributorAccount, uint256 amount, uint32 contributionId) public {
require(contributionContract == msg.sender, "Only Contribution");
require(amount > 0, "INVALID_AMOUNT");
uint256 amountInWei = amount.mul(1 ether);
_mint(contributorAccount, amountInWei);
emit LogMint(contributorAccount, amount, contributionId);
}
}
+13
View File
@@ -0,0 +1,13 @@
pragma solidity 0.4.24;
import "@aragon/os/contracts/apm/APMNamehash.sol";
contract APMNamehashOpen is APMNamehash {
bytes32 public constant OPEN_TITLE = keccak256("open");
bytes32 public constant OPEN_APM_NODE = keccak256(abi.encodePacked(APM_NODE, OPEN_TITLE));
function apmNamehashOpen(string name) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(OPEN_APM_NODE, keccak256(name)));
}
}
+16
View File
@@ -0,0 +1,16 @@
pragma solidity 0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
// This is a "Dummy" app which's only purpose to exist is because
// Aragon's CLI still doesn't support running a Kit inside a project
// which isn't considered to be a "valid" Aragon project.
// It requires us to have an arrap.json file pointing to the contract
// and a manifest.json file which describes the front-end structure.
contract DummyApp is AragonApp {
function initialize() public onlyInit {
initialized();
}
}
+23
View File
@@ -0,0 +1,23 @@
pragma solidity ^0.4.4;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
function constructor() public {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
-30
View File
@@ -2,36 +2,6 @@
aragon apm publish major --environment=rinkeby"
## 20212-01-14
apps/contribution@master » aragon apm publish major --environment=rinkeby
eth-provider | Invalid provider preset/location: "local"
✔ Start IPFS
✔ Applying version bump (major)
↓ Building frontend [skipped]
→ build script not defined in package.json
✔ Deploy contract
✔ Determine contract address for version
✔ Prepare files for publishing
✔ Generate application artifact
✔ Publish intent
⚠ Publishing files from the project's root folder is not recommended. Consider using the distribution folder of your project: "--files <folder>".
The following information will be published:
Contract address: 0x914Da982ef17B56D2e868E3a67E923EbED1aE017
Content (ipfs): QmdVrY2R48NFqwLopd8ix1anAK1d6WafDGauou3ZJrB9gf
? Publish to kredits-contribution.open.aragonpm.eth repo Yes
✔ Publish kredits-contribution.open.aragonpm.eth
Successfully published kredits-contribution.open.aragonpm.eth v7.0.0 :
Transaction hash: 0xb817b2e80e90a6be60b45dd39987498e3132c9962c0501feb7549ad30186c6d5
## 2019-04-24 update balances
✔ Successfully published kredits-contribution.open.aragonpm.eth v6.0.0:
-11
View File
@@ -1,16 +1,5 @@
# Kredits deployment
## 2021-01-14
apps/contribution@master » aragon dao upgrade 0xc34edf7d11b7f8433d597f0bb0697acdff55ef14 kredits-contribution.open.aragonpm.eth --environment=rinkeby
eth-provider | Invalid provider preset/location: "local"
✔ Fetching kredits-contribution.open.aragonpm.eth@latest
✔ Fetching kredits-contribution.open.aragonpm.eth@latest
✔ Upgrading app
✔ Successfully executed: "Upgrade 'kredits-contribution.open.aragonpm.eth' app instances to v7.0.0"
## 2019-04-25 canPerfom fix
aragon dao upgrade 0xc34edf7d11b7f8433d597f0bb0697acdff55ef14 kredits-contributor.open.aragonpm.eth --environment=rinkeby
-89
View File
@@ -1,89 +0,0 @@
require("@nomiclabs/hardhat-waffle");
require("hardhat-deploy");
require("hardhat-deploy-ethers");
require("@openzeppelin/hardhat-upgrades");
const Kredits = require("./lib/kredits");
const promptly = require("promptly");
extendEnvironment(async (hre) => {
hre.kredits = new Kredits(
hre.ethers.provider,
hre.ethers.provider.getSigner()
);
await hre.kredits.init();
});
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async () => {
const accounts = await ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
task("fund", "Send eth to an address", async () => {
const to = await promptly.prompt("Address:");
const value = await promptly.prompt("Value:");
const signer = await ethers.getSigners();
const fundTransaction = await signer[0].sendTransaction({
to: to,
value: ethers.utils.parseEther(value),
});
console.log(fundTransaction);
});
task("create-wallet", "Creates a new wallet json", async () => {
const wallet = ethers.Wallet.createRandom();
console.log("New wallet:");
console.log(`Address: ${wallet.address}`);
console.log(`Public key: ${wallet.publicKey}`);
console.log(`Private key: ${wallet.privateKey}`);
console.log(`Mnemonic: ${JSON.stringify(wallet.mnemonic)}`);
const password = await promptly.prompt("Encryption password: ");
const encryptedJSON = await wallet.encrypt(password);
console.log("Encrypted wallet JSON:");
console.log(encryptedJSON);
});
// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more
/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.2",
defaultNetwork: "localhost",
networks: {
hardhat: {
chainId: 1337,
},
rinkeby: {
url: "https://rinkeby.infura.io/v3/2e73045db2e84711912f8d0e5968f309",
accounts: [
process.env.DEPLOY_KEY ||
"0xffb4230bdf9b1f1dd48f0bc54e4007436733f225a4f163d4f7e58e620ae329eb",
],
},
rsk: {
url: "https://rsk-testnet.kosmos.org",
accounts: [
process.env.DEPLOY_KEY ||
"0xffb4230bdf9b1f1dd48f0bc54e4007436733f225a4f163d4f7e58e620ae329eb",
],
},
},
namedAccounts: {
deployer: {
default: 0,
},
},
};
+1
View File
@@ -0,0 +1 @@
[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"NO_PERMISSION","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CREATE_PERMISSIONS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ANY_ENTITY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EMPTY_PARAM_HASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BURN_ENTITY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"entity","type":"address"},{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":false,"name":"allowed","type":"bool"}],"name":"SetPermission","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"entity","type":"address"},{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":false,"name":"paramsHash","type":"bytes32"}],"name":"SetPermissionParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":true,"name":"manager","type":"address"}],"name":"ChangePermissionManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"constant":false,"inputs":[{"name":"_permissionsCreator","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_manager","type":"address"}],"name":"createPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"grantPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"grantPermissionP","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"Line truncated
+1 -1
View File
@@ -1 +1 @@
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"contributorId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"ContributionClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ContributionVetoed","type":"event"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributionOwner","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributions","outputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"string","name":"tokenMetadataURL","type":"string"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"getContribution","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"contributorId","type":"uint32"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"blocksToWait_","type":"uint32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownedContributions","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributionILine truncated
[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ADD_CONTRIBUTION_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributionsCount","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KERNEL_APP_ADDR_NAMESPACE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint32"}],"name":"contributionOwner","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint32"}],"name":"contributions","outputs":[{"name":"contributorId","type":"uint32"},{"name":"amount","type":"uint32"},{"name":"claimed","type":"bool"},{"name":"hashDigest","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"tokenMetadataURL","type":"string"},{"name":"confirmedAtBlock","type":"uint256"},{"name":"vetoed","type":"bool"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint32"},{"name":"","type":"uint256"}],"name":"ownedContributions","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"blocksToWait","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"appIds","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VETO_CONTRIBUTION_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":true,"name":"contributorId","type":"uint32"},{"indexed":false,"name":"amount","type":"uint32"}],"name":"ContributionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":true,"name":"contributorId","type":"uint32"},{"indexed":false,"name":"amount","type":"uint32"}],"name":"ContributionClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":false,"name":"vetoedByAccount","type":"address"}],"name":"ContributionVetoed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"constant":false,"inputs":[{"name":"_appIds","type":"bytes32[4]"}],"name":"initialize","outputs":[],"payable":falLine truncated
+1 -1
View File
@@ -1 +1 @@
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"oldAccount","type":"address"},{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"ContributorAccountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"ContributorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"bytes32","name":"oldHashDigest","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"newHashDigest","type":"bytes32"}],"name":"ContributorProfileUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"addContributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addressExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addressIsCore","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionContract","outputs":[{"internalType":"contract IContributionBalance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"contributorIds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"contributors","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coreContributorsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_id","type":"uint32"}],"name":"getContributorById","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"bool","name":"isCore","type":"bool"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint32","name":"totalKreditsEarned","type":"uint32"},{"internalType":"uint256","name":"contributionsCount","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"}],"name":"isCoreTeam","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contribution","type":"address"}],"name":"setContributionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setTokenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"contract ITokenBalance","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"oldAccount","type":"address"},{"internaLine truncated
[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"contributorIds","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KERNEL_APP_ADDR_NAMESPACE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MANAGE_CONTRIBUTORS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint32"}],"name":"contributors","outputs":[{"name":"account","type":"address"},{"name":"hashDigest","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"appIds","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":false,"name":"oldHashDigest","type":"bytes32"},{"indexed":false,"name":"newHashDigest","type":"bytes32"}],"name":"ContributorProfileUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":false,"name":"oldAccount","type":"address"},{"indexed":false,"name":"newAccount","type":"address"}],"name":"ContributorAccountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":false,"name":"account","type":"address"}],"name":"ContributorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"constant":false,"inputs":[{"name":"root","type":"address"},{"name":"_appIds","type":"bytes32[4]"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTokenContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getContributionContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint32"},{"name":"oldAccount","type":"address"},{"name":"newAccount","type":"address"}],"name":"updateContributorAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint32"},{"name":"hashDigest","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"namLine truncated
+1
View File
@@ -0,0 +1 @@
[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"bytes32"}],"name":"apps","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"recoveryVaultAppId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"APP_MANAGER_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"},{"name":"_initializePayload","type":"bytes"}],"name":"newAppProxyPinned","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"}],"name":"newAppProxy","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"},{"name":"_initializePayload","type":"bytes"}],"name":"newAppProxy","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_kernel","type":"address"},{"name":"_appId","type":"bytes32"}],"name":"newAppProxyPinned","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_shouldPetrify","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proxy","type":"address"},{"indexed":false,"name":"isUpgradeable","type":"bool"},{"indexed":false,"name":"appId","type":"bytes32"}],"name":"NewAppProxy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"namespace","type":"bytes32"},{"indexed":true,"name":"appId","type":"bytes32"},{"indexed":false,"name":"app","type":"address"}],"name":"SetApp","type":"event"},{"constant":false,"inputs":[{"name":"_baseAcl","type":"address"},{"name":"_permissionsCreator","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_appId","type":"bytes32"},{"name":"_appBase","type":"address"},{"name":"_initializePayload","type":"bytes"},{"name":"_setDefault","type":"bool"}],"name":"newAppInstance","outputs":[{"name":"appProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_appId","type":"bytes32"},{"name":"_appBase","type":"address"}],"name":"newAppInstance","outputs":[{"name":"appProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_appId","type":"bytes32"},{"name":"_appBase","type":"address"}],"name":"newPinnedAppInstance","outputs":[{"name":"appProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_appId","type":"bytes32"},{"name":"_appBase","type":"address"},{"name":"_initializePayload","type":"bytes"},{"name":"_setDefault","type":"bool"}],"name":"newPinnedAppInstance","outputs":[{"name":"appProxy","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_namespace","type":"bytes32"},{"name":"_appId","type":"bytes32"},{"name":"_app","type":"address"}],"name":"setApp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_recoveryVaultAppId","type":"bytes32"}],"name":"setRecoveryVaultAppId","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"CORE_NAMESPACE","outputs":[{"name":"","type":"bytes32"}],"payable":false,Line truncated
+1
View File
@@ -0,0 +1 @@
[{"constant":true,"inputs":[],"name":"ens","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fac","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"appId","type":"bytes32"}],"name":"latestVersionAppBase","outputs":[{"name":"base","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"appIds","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_fac","type":"address"},{"name":"_ens","type":"address"},{"name":"_appIds","type":"bytes32[4]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"dao","type":"address"}],"name":"DeployInstance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"dao","type":"address"},{"indexed":false,"name":"appProxy","type":"address"},{"indexed":false,"name":"appId","type":"bytes32"}],"name":"InstalledApp","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"appProxy","type":"address"},{"indexed":false,"name":"appId","type":"bytes32"}],"name":"InstalledApp","type":"event"},{"constant":false,"inputs":[],"name":"newInstance","outputs":[{"name":"dao","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]
+1
View File
@@ -0,0 +1 @@
[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proposalsCount","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint32"}],"name":"proposals","outputs":[{"name":"creatorAccount","type":"address"},{"name":"contributorId","type":"uint32"},{"name":"votesCount","type":"uint16"},{"name":"votesNeeded","type":"uint16"},{"name":"amount","type":"uint32"},{"name":"executed","type":"bool"},{"name":"hashDigest","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_PROPOSAL_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"KERNEL_APP_ADDR_NAMESPACE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"appIds","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ADD_PROPOSAL_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":false,"name":"creatorAccount","type":"address"},{"indexed":false,"name":"contributorId","type":"uint32"},{"indexed":false,"name":"amount","type":"uint32"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":false,"name":"voterId","type":"uint32"},{"indexed":false,"name":"totalVotes","type":"uint16"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint32"},{"indexed":false,"name":"contributorId","type":"uint32"},{"indexed":false,"name":"amount","type":"uint32"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"constant":false,"inputs":[{"name":"_appIds","type":"bytes32[4]"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getContributorContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getContributionContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"contributorId","type":"uint32"},{"name":"amount","tyLine truncated
-1
View File
@@ -1 +0,0 @@
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"address","name":"addedByAccount","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReimbursementAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ReimbursementVetoed","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"get","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"reimbursements","outputs":[{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reimbursementsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalAmount","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}]
+1 -1
View File
@@ -1 +1 @@
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributionContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"contributionId","type":"uint32"}],"name":"mintFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contribution","type":"address"}],"name":"setContributionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"_balances","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MINT_TOKEN_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"appIds","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"contributionId","type":"uint32"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":faLine truncated
-8
View File
@@ -1,8 +0,0 @@
{
"1337": {
"Contributor": "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
"Contribution": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
"Token": "0x0165878A594ca255338adfa4d48449f69242Eb8F",
"Reimbursement": "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6"
}
}
+17
View File
@@ -0,0 +1,17 @@
const Base = require('./base');
const EthersUtils = require('ethers').utils;
class Acl extends Base {
hasPermission (fromAddress, contractAddress, roleID, params = null) {
let roleHash = EthersUtils.keccak256(EthersUtils.toUtf8Bytes(roleID));
return this.functions.hasPermission(
fromAddress,
contractAddress,
roleHash,
params
);
}
}
module.exports = Acl;
+10 -4
View File
@@ -1,19 +1,25 @@
const deprecate = require('../utils/deprecate');
class Base {
constructor (contract) {
this.contract = contract;
}
get functions () {
deprecate('The property `functions` is deprecated. contract functions are now directly defined on the ethers contract object. https://github.com/ethers-io/ethers.js/issues/920#issuecomment-650836642');
return this.contract;
return this.contract.functions;
}
get address () {
return this.contract.address;
}
get ipfs () {
if (!this._ipfsAPI) { throw new Error('IPFS API not configured; please set an ipfs instance'); }
return this._ipfsAPI;
}
set ipfs (ipfsAPI) {
this._ipfsAPI = ipfsAPI;
}
on (type, callback) {
return this.contract.on(type, callback);
}
+7 -7
View File
@@ -4,33 +4,33 @@ const deprecate = require('../utils/deprecate');
class Contribution extends Record {
get count () {
return this.contract.contributionsCount();
return this.functions.contributionsCount();
}
getById (id) {
return this.contract.getContribution(id)
return this.functions.getContribution(id)
.then(data => {
return this.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
});
}
getData (id) {
return this.contract.getContribution(id);
return this.functions.getContribution(id);
}
getByContributorId (contributorId) {
return this.contract.getContributorAddressById(contributorId)
return this.functions.getContributorAddressById(contributorId)
.then(address => this.getByContributorAddress(address));
}
getByContributorAddress (address) {
return this.contract.balanceOf(address)
return this.functions.balanceOf(address)
.then(async (balance) => {
const count = balance.toNumber();
const contributions = [];
for (let index = 0; index < count; index++) {
const id = await this.contract.tokenOfOwnerByIndex(address, index);
const id = await this.functions.tokenOfOwnerByIndex(address, index);
const contribution = await this.getById(id);
contributions.push(contribution);
}
@@ -58,7 +58,7 @@ class Contribution extends Record {
ipfsHashAttr.hashSize,
];
return this.contract.add(...contribution, callOptions);
return this.functions.add(...contribution, callOptions);
});
}
+6 -7
View File
@@ -4,20 +4,19 @@ const formatKredits = require('../utils/format-kredits');
class Contributor extends Record {
get count () {
return this.contract.contributorsCount();
return this.functions.contributorsCount();
}
getById (id) {
return this.contract.getContributorById(id)
.then(contractData => {
let data = {...contractData};
return this.functions.getContributorById(id)
.then(data => {
data.balanceInt = formatKredits(data.balance);
return this.ipfs.catAndMerge(data, ContributorSerializer.deserialize);
});
}
getData (id) {
return this.contract.getContributorById(id);
return this.functions.getContributorById(id);
}
filterByAccount (search) {
@@ -62,7 +61,7 @@ class Contributor extends Record {
ipfsHashAttr.hashSize,
];
return this.contract.addContributor(...contributor, callOptions);
return this.functions.addContributor(...contributor, callOptions);
});
}
@@ -79,7 +78,7 @@ class Contributor extends Record {
return this.ipfs
.add(jsonStr)
.then(ipfsHashAttr => {
return this.contract.updateContributorProfileHash(
return this.functions.updateContributorProfileHash(
contributorId,
ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction,
+2 -1
View File
@@ -3,5 +3,6 @@ module.exports = {
Contribution: require('./contribution'),
Proposal: require('./proposal'),
Token: require('./token'),
Reimbursement: require('./reimbursement'),
Kernel: require('./kernel'),
Acl: require('./acl'),
};
+24
View File
@@ -0,0 +1,24 @@
const namehash = require('ethers').utils.namehash;
const Base = require('./base');
const KERNEL_APP_ADDR_NAMESPACE = '0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb';
class Kernel extends Base {
constructor (contract) {
super(contract);
this.apm = 'open.aragonpm.eth'; // can be overwritten if needed
}
getApp (appName) {
if (appName === 'Acl') {
return this.functions.acl();
}
return this.functions.getApp(KERNEL_APP_ADDR_NAMESPACE, this.appNamehash(appName));
}
appNamehash (appName) {
return namehash(`kredits-${appName.toLowerCase()}.${this.apm}`);
}
}
module.exports = Kernel;
+3 -3
View File
@@ -4,11 +4,11 @@ const deprecate = require('../utils/deprecate');
class Proposal extends Record {
get count () {
return this.contract.proposalsCount();
return this.functions.proposalsCount();
}
getById (id) {
return this.contract.getProposal(id)
return this.functions.getProposal(id)
.then(data => {
return this.ipfs.catAndMerge(data, ContributionSerializer.deserialize);
});
@@ -33,7 +33,7 @@ class Proposal extends Record {
ipfsHashAttr.hashSize,
];
return this.contract.addProposal(...proposal, callOptions);
return this.functions.addProposal(...proposal, callOptions);
});
}
-67
View File
@@ -1,67 +0,0 @@
const Record = require("./record");
const ExpenseSerializer = require("../serializers/expense");
class Reimbursement extends Record {
get count () {
return this.contract.reimbursementsCount();
}
getById (id) {
return this.contract.get(id).then((data) => {
return this.ipfs.catAndMerge(data, (ipfsDocument) => {
const expenses = JSON.parse(ipfsDocument);
return { expenses };
});
});
}
getData (id) {
return this.contract.getReimbursement(id);
}
async add (attrs, callOptions = {}) {
const amount = parseInt(attrs.amount);
const token = attrs.token;
const recipientId = attrs.recipientId;
const expenses = attrs.expenses.map((e) => new ExpenseSerializer(e));
let errorMessage;
if (typeof amount !== "number" || amount <= 0) {
errorMessage = "Invalid data: amount must be a positive number.";
}
if (!token || token === "") {
errorMessage = "Invalid data: token must be a token address.";
}
if (!recipientId || recipientId === "") {
errorMessage = "Invalid data: recipientId is required.";
}
if (expenses.length === 0) {
errorMessage = "Invalid data: at least one expense item is required.";
}
if (errorMessage) {
return Promise.reject(new Error(errorMessage));
}
return Promise.all(expenses.map((e) => e.validate())).then(() => {
const jsonStr = JSON.stringify(
expenses.map((e) => e.data),
null,
2
);
return this.ipfs.add(jsonStr).then((ipfsHashAttr) => {
const reimbursement = [
amount,
token,
parseInt(recipientId),
ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction,
ipfsHashAttr.hashSize,
];
return this.contract.add(...reimbursement, callOptions);
});
});
}
}
module.exports = Reimbursement;
+45 -23
View File
@@ -6,16 +6,19 @@ const deprecate = require('./utils/deprecate');
const ABIS = {
Contributor: require('./abis/Contributor.json'),
Contribution: require('./abis/Contribution.json'),
Reimbursement: require('./abis/Reimbursement.json'),
Token: require('./abis/Token.json'),
Proposal: require('./abis/Proposal.json'),
Kernel: require('./abis/Kernel.json'),
Acl: require('./abis/ACL.json'),
};
// const APP_CONTRACTS = [
// 'Contributor',
// 'Contribution',
// 'Token',
// 'Reimbursement',
// ];
const Addresses = require('./addresses.json');
const APP_CONTRACTS = [
'Contributor',
'Contribution',
'Token',
'Proposal',
'Acl',
];
const DaoAddresses = require('./addresses/dao.json');
const Contracts = require('./contracts');
const IPFS = require('./utils/ipfs');
@@ -29,7 +32,7 @@ function capitalize (word) {
class Kredits {
constructor (provider, signer, options = {}) {
const { addresses, abis, ipfsConfig } = options;
let { addresses, abis, ipfsConfig } = options;
this.provider = provider;
this.signer = signer;
@@ -40,15 +43,21 @@ class Kredits {
this.contracts = {};
}
init (/* names */) {
// TODO implement
// const contractsToLoad = names || APP_CONTRACTS;
init (names) {
let contractsToLoad = names || APP_CONTRACTS;
return this.provider.getNetwork().then(network => {
if (Object.keys(this.addresses).length === 0) {
this.addresses = Addresses[network.chainId.toString()];
}
return this;
this.addresses['Kernel'] = this.addresses['Kernel'] || DaoAddresses[network.chainId.toString()];
let addressPromises = contractsToLoad.map((contractName) => {
return this.Kernel.getApp(contractName).then((address) => {
this.addresses[contractName] = address;
}).catch((error) => {
throw new Error(`Failed to get address for ${contractName} from DAO at ${this.Kernel.contract.address}
- ${error.message}`
);
});
});
return Promise.all(addressPromises).then(() => { return this; });
});
}
@@ -75,7 +84,16 @@ class Kredits {
}
static availableNetworks () {
return Object.keys(Addresses);
return Object.keys(DaoAddresses);
}
get Kernel () {
let k = this.contractFor('Kernel');
// in case we want to use a special apm (e.g. development vs. production)
if (this.options.apm) {
k.apm = this.options.apm;
}
return k;
}
get Contributor () {
@@ -84,7 +102,11 @@ class Kredits {
get Contributors () {
deprecate('Contributors is deprecated use Contributor instead');
return this.contractFor('Contributor');
return this.Contributor;
}
get Proposal () {
return this.contractFor('Proposal');
}
get Operator () {
@@ -99,8 +121,8 @@ class Kredits {
return this.contractFor('Contribution');
}
get Reimbursement () {
return this.contractFor('Reimbursement');
get Acl () {
return this.contractFor('Acl');
}
// Should be private
@@ -116,8 +138,8 @@ class Kredits {
throw new Error(`Address or ABI not found for ${contractName}`);
}
const signerOrProvider = this.signer || this.provider;
const contract = new ethers.Contract(address, abi, signerOrProvider);
let signerOrProvider = this.signer || this.provider;
let contract = new ethers.Contract(address, abi, signerOrProvider);
this.contracts[name] = new Contracts[contractName](contract);
this.contracts[name].ipfs = this.ipfs;
+3 -3
View File
@@ -29,12 +29,12 @@ class KreditsKit {
appIdFor (contractName) {
// see appIds in KreditsKit.sol for more details
const knownContracts = ['Contribution', 'Contributor', 'Proposal', 'Reimbursement', 'Token'];
return this.contract.appIds(knownContracts.indexOf(contractName));
const knownContracts = ['Contribution', 'Contributor', 'Proposal', 'Token'];
return this.contract.functions.appIds(knownContracts.indexOf(contractName));
}
newDAO (options = {}) {
return this.contract.newInstance(options).then(transaction => {
return this.contract.functions.newInstance(options).then(transaction => {
return transaction.wait().then(result => {
const deployEvent = result.events.find(e => e.event === 'DeployInstance');
return {
+1 -1
View File
@@ -1,4 +1,4 @@
const schemas = require('@kosmos/schemas');
const schemas = require('kosmos-schemas');
const validator = require('../utils/validator');
/**
+5 -17
View File
@@ -1,4 +1,4 @@
const schemas = require('@kosmos/schemas');
const schemas = require('kosmos-schemas');
const validator = require('../utils/validator');
/**
* Handle serialization for JSON-LD object of the contributor, according to
@@ -13,7 +13,7 @@ class Contributor {
Object.keys(attrs).forEach(a => this[a] = attrs[a]);
}
/**
/**
* Serialize object to JSON
*
* @method
@@ -28,7 +28,7 @@ class Contributor {
github_username,
gitea_username,
wiki_username,
zoom_display_name,
accounts,
} = this;
let data = {
@@ -36,7 +36,7 @@ class Contributor {
'@type': 'Contributor',
kind,
name,
accounts: [],
accounts: accounts || [],
};
if (url) {
@@ -68,13 +68,6 @@ class Contributor {
});
}
if (zoom_display_name) {
data.accounts.push({
'site': 'zoom.us',
'username': zoom_display_name,
});
}
// Write it pretty to ipfs
return JSON.stringify(data, null, 2);
}
@@ -104,11 +97,10 @@ class Contributor {
accounts,
} = JSON.parse(serialized.toString('utf8'));
let github_username, github_uid, gitea_username, wiki_username, zoom_display_name;
let github_username, github_uid, gitea_username, wiki_username;
let github = accounts.find(a => a.site === 'github.com');
let gitea = accounts.find(a => a.site === 'gitea.kosmos.org');
let wiki = accounts.find(a => a.site === 'wiki.kosmos.org');
let zoom = accounts.find(a => a.site === 'zoom.us');
if (github) {
(({ username: github_username, uid: github_uid} = github));
@@ -119,9 +111,6 @@ class Contributor {
if (wiki) {
(({ username: wiki_username } = wiki));
}
if (zoom) {
(({ username: zoom_display_name } = zoom));
}
return {
name,
@@ -132,7 +121,6 @@ class Contributor {
github_username,
gitea_username,
wiki_username,
zoom_display_name,
ipfsData: serialized,
};
}
-100
View File
@@ -1,100 +0,0 @@
const schemas = require('@kosmos/schemas');
const validator = require('../utils/validator');
/**
* Serialization and validation for JSON-LD document of the Expense
*
* @class
* @public
*/
class ExpenseSerializer {
constructor (attrs) {
Object.keys(attrs).forEach(a => this[a] = attrs[a]);
}
/**
* Serialize object to JSON
*
* @public
*/
serialize () {
// Write it pretty to ipfs
return JSON.stringify(this.data, null, 2);
}
get data () {
const {
title,
description,
currency,
amount,
date,
url,
tags,
details,
} = this;
const data = {
'@context': 'https://schema.kosmos.org',
'@type': 'Expense',
title,
description,
currency,
amount,
date,
'tags': tags || [],
'details': details || {},
};
if (url) {
data['url'] = url;
}
return data;
}
/**
* Validate serialized data against schema
*
* @public
*/
validate () {
const serialized = JSON.parse(this.serialize());
const valid = validator.validate(serialized, schemas['expense']);
return valid ? Promise.resolve() : Promise.reject(validator.error);
}
/**
* Deserialize JSON to object
*
* @public
*/
static deserialize (serialized) {
const {
title,
description,
currency,
amount,
date,
url,
tags,
details,
} = JSON.parse(serialized.toString('utf8'));
return {
title,
description,
currency,
amount,
date,
url,
tags,
details,
ipfsData: serialized,
};
}
}
module.exports = ExpenseSerializer;
+13 -18
View File
@@ -8,11 +8,10 @@ class IPFS {
config = { host: 'localhost', port: '5001', protocol: 'http' };
}
this._config = config;
this._ipfsAPI = ipfsClient.create(config);
this._ipfsAPI = ipfsClient(config);
}
async catAndMerge (contractData, deserialize) {
let data = {...contractData}; // data from ethers.js is not extensible. this copy the attributes in a new object
catAndMerge (data, deserialize) {
// if no hash details are found simply return the data; nothing to merge
if (!data.hashSize || data.hashSize === 0) {
return data;
@@ -22,38 +21,34 @@ class IPFS {
return this.cat(data.ipfsHash)
.then(deserialize)
.then(attributes => {
.then((attributes) => {
return Object.assign({}, data, attributes);
});
}
async add (data) {
return this._ipfsAPI.add(data)
.then(res => {
return this.decodeHash(res.path);
add (data) {
return this._ipfsAPI
.add(ipfsClient.Buffer.from(data))
.then((res) => {
return this.decodeHash(res[0].hash);
});
}
async cat (hashData) {
cat (hashData) {
let ipfsHash = hashData; // default - if it is a string
if (Object.prototype.hasOwnProperty.call(hashData, 'hashSize')) {
if (hashData.hasOwnProperty('hashSize')) {
ipfsHash = this.encodeHash(hashData);
}
if (this._config['gatewayUrl']) {
return fetch(`${this._config['gatewayUrl']}/${ipfsHash}`).then(r => r.text());
} else {
const res = this._ipfsAPI.cat(ipfsHash);
let str = '';
for await (const buffer of res) {
str += buffer.toString();
}
return Promise.resolve(str);
return this._ipfsAPI.cat(ipfsHash);
}
}
pin (hashData) {
let ipfsHash = hashData; // default - if it is a string
if (Object.prototype.hasOwnProperty.call(hashData, 'hashSize')) {
if (hashData.hasOwnProperty('hashSize')) {
ipfsHash = this.encodeHash(hashData);
}
return this._ipfsAPI.pin.add(multihashes.toB58String(ipfsHash));
@@ -70,7 +65,7 @@ class IPFS {
}
encodeHash (hashData) {
const digest = Buffer.from(hashData.hashDigest.slice(2), 'hex');
let digest = ipfsClient.Buffer.from(hashData.hashDigest.slice(2), 'hex');
return multihashes.encode(digest, hashData.hashFunction, hashData.hashSize);
}
}
+5
View File
@@ -0,0 +1,5 @@
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};
+2393 -33095
View File
File diff suppressed because it is too large. Load diff
+30 -40
View File
@@ -1,27 +1,29 @@
{
"name": "kredits-contracts",
"version": "7.0.0-beta.0",
"version": "5.4.0",
"description": "Ethereum contracts and npm wrapper for Kredits",
"main": "./lib/kredits.js",
"directories": {
"test": "test"
},
"scripts": {
"wallet:create": "hardhat create-wallet",
"devchain": "hardhat node --network hardhat",
"deploy:dao": "hardhat run scripts/create-proxy.js",
"install-all": "./scripts/every-app.sh \"npm install\"",
"postshrinkwrap": "node scripts/fix-package-lock.js &>/dev/null || true",
"build": "npm run build:contracts && npm run build:json",
"build:contracts": "hardhat compile --force",
"build:json": "node ./scripts/build-json.js",
"seeds": "hardhat run scripts/seeds.js",
"fund": "hardhat fund",
"bootstrap": "npm run build && npm run deploy:dao && npm run seeds",
"repl": "hardhat console",
"build-json": "npm run compile-contracts && node ./scripts/build-json.js",
"repl": "truffle exec scripts/repl.js",
"seeds": "truffle exec scripts/seeds.js",
"compile-contracts": "truffle compile --all",
"bootstrap": "npm run reset:hard && npm run seeds",
"reset": "npm run deploy:kit && npm run deploy:dao",
"reset:hard": "npm run deploy:apps && npm run reset",
"deploy:kit": "npm run compile-contracts && aragon contracts exec scripts/deploy-kit.js",
"deploy:dao": "aragon contracts exec scripts/new-dao.js",
"deploy:apps": "./scripts/every-app.sh \"aragon apm publish major --skip-confirmation\"",
"devchain": "aragon devchain --port 7545",
"dao:address": "truffle exec scripts/current-address.js",
"lint:contracts": "solhint \"contracts/**/*.sol\" \"apps/*/contracts/**/*.sol\"",
"lint:contract-tests": "eslint apps/*/test",
"lint:wrapper": "eslint lib/",
"test": "npm run test:token && npm run test:contributor && npm run test:contribution && npm run test:proposal",
"test:token": "cd apps/token && npm run test",
"test:contributor": "cd apps/contributor && npm run test",
"test:contribution": "cd apps/contribution && npm run test",
@@ -30,45 +32,33 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/67P/kredits-contracts.git"
"url": "git+https://github.com/67P/truffle-kredits.git"
},
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/67P/kredits-contracts/issues"
"url": "https://github.com/67P/truffle-kredits/issues"
},
"homepage": "https://github.com/67P/kredits-contracts#readme",
"homepage": "https://github.com/67P/truffle-kredits#readme",
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@openzeppelin/contracts-upgradeable": "^4.3.2",
"@openzeppelin/hardhat-upgrades": "^1.10.0",
"@aragon/kits-base": "^1.0.0",
"@aragon/os": "^4.2.0",
"async-each-series": "^1.1.0",
"cli-table": "^0.3.1",
"colors": "^1.0.3",
"eslint": "^8.14.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.0.0",
"eth-provider": "^0.11.0",
"ethereum-block-by-date": "^1.4.0",
"ethereum-waffle": "^3.4.0",
"hardhat": "^2.6.4",
"hardhat-deploy": "^0.11.4",
"hardhat-deploy-ethers": "^0.3.0-beta.10",
"homedir": "^0.6.0",
"eslint": "^5.16.0",
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-promise": "^4.1.1",
"eth-provider": "^0.2.2",
"promptly": "^3.0.3",
"solhint": "^3.3.7",
"truffle-hdwallet-provider": "^1.0.17",
"truffle-hdwallet-provider-privkey": "^0.3.0",
"web3-providers-ws": "^1.7.3",
"yargs": "^15.0.0"
"solc": "^0.4.26",
"solhint": "^2.1.0",
"yargs": "^12.0.0"
},
"dependencies": {
"@kosmos/schemas": "^3.1.0",
"ethers": "^5.4.7",
"ipfs-http-client": "^56.0.3",
"multihashes": "^4.0.3",
"ethers": "^4.0.29",
"ipfs-http-client": "^30.1.3",
"kosmos-schemas": "^2.1.0",
"node-fetch": "^2.6.0",
"tv4": "^1.3.0"
},
+14 -11
View File
@@ -1,12 +1,16 @@
const promptly = require('promptly');
const { inspect } = require('util');
const { ethers } = require("hardhat");
const Kredits = require('../lib/kredits');
const initKredits = require('./helpers/init_kredits.js');
async function main() {
kredits = new Kredits(hre.ethers.provider, hre.ethers.provider.getSigner())
await kredits.init();
module.exports = async function(callback) {
let kredits;
try {
kredits = await initKredits(web3);
} catch(e) {
callback(e);
return;
}
console.log(`Using Contributions at: ${kredits.Contribution.contract.address}`);
@@ -15,10 +19,10 @@ async function main() {
let contributorAccount;
if (contributor.length < 5) {
contributorId = contributor;
contributorAccount = await kredits.Contributor.contract.getContributorAddressById(contributor);
contributorAccount = await kredits.Contributor.functions.getContributorAddressById(contributor);
} else {
contributorAccount = contributor;
contributorId = await kredits.Contributor.contract.getContributorIdByAddress(contributor);
contributorId = await kredits.Contributor.functions.getContributorIdByAddress(contributor);
}
console.log(`Creating a contribution for contributor account ${contributorAccount} ID: ${contributorId}`);
@@ -41,15 +45,14 @@ async function main() {
console.log("\nAdding contribution:");
console.log(contributionAttributes);
kredits.Contribution.add(contributionAttributes, { gasLimit: 300000 })
kredits.Contribution.addContribution(contributionAttributes, { gasLimit: 300000 })
.then(result => {
console.log("\n\nResult:");
console.log(result);
callback();
})
.catch(error => {
console.log('Failed to create contribution');
console.log(error);
callback(inspect(error));
});
}
main();
Loaded 100 of 128 files, more files were not shown because too many files have changed in this diff. Show more