Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CredETH- EthIndia Project #26

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CredEth/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
build/
node_modules/
.vscode/
.env
17 changes: 17 additions & 0 deletions CredEth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# CredEth-core
Credeth is the open reputation protocol powered by DAOStack that makes on-chain governance easier

## Pre-requisite
Node >= 10.15.1
daoStack-arc version 0.0.1-rc.23

## Deployment
```
npm run compile
node migrations/2_deploy_dao.js
npm run migrate:local
```

## Network

To change the network and the provider URL in the `.env` file and in the `truffle.js` file
169 changes: 169 additions & 0 deletions CredEth/contracts/CredEth.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
pragma solidity ^0.5.7;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";

contract CredEth {

using SafeMath for uint256;

uint256 public constant INITIAL_REP = 1000;
uint256 public constant PER_DAY_VOUCHE_COUNT = 3;
uint256 public constant DAO_CAP = 1000000;
uint256 public constant LOCKDROP_CAP = 1000000;

uint256 public distributedByDao;
uint256 public distributedByLockdrop;
address public daoAddress;

modifier onlyDAO() {
require(msg.sender == daoAddress, "Not Authorised");
_;
}

modifier onlyPartner() {
require(partnersIndex[msg.sender] != uint256(0), "Not authorised");
_;
}

struct Reputation {
uint256 rep;
uint256 lastVouchTime;
uint256 vouchCount;
}

address[] members;
address[] partners;

mapping(address => Reputation) addressToReputation;
mapping(address => uint256) partnersIndex;

event Vouched(address indexed _vouchee, address indexed _voucher, uint256 _vouchedAmount);
event DaoDistribution(address indexed _to, uint256 _reputation);
event Signaled();
event IssueReputation(address indexed _to, uint256 _reputation);
event PartnerAdded(address indexed _partner);
event MintReputation(address indexed _to, uint256 _amount, address indexed _mintedBy);

constructor () public {
}

function setDAO(address _daoAddress) public {
require(daoAddress == address(0), "Already set");
require(_daoAddress != address(0), "Invalid address");
daoAddress = _daoAddress;
}

function vouch(address _vouchee) external {
require(_vouchee != msg.sender, "Not allowed");
Reputation storage voucher = addressToReputation[msg.sender];
if (now.sub(voucher.lastVouchTime) > 24 hours) {
voucher.lastVouchTime = now;
voucher.vouchCount = 0;
}
voucher.vouchCount++;
require(voucher.vouchCount <= PER_DAY_VOUCHE_COUNT, "Exceeding limit");
uint256 voucherRep = getReputation(msg.sender);
_addNewMember(_vouchee);
uint256 voucheeRep = getReputation(_vouchee);
uint256 vouchedGiven = log_2(voucherRep * voucherRep);
_mint(_vouchee, vouchedGiven, msg.sender);
emit Vouched(_vouchee, msg.sender, vouchedGiven);
}

function daoDistribution(address _to, uint256 _rep) external onlyDAO {
require(_to != address(0), "Invalid address");
require(_rep > 0, "Invalid reputation");
require(DAO_CAP > distributedByDao.add(_rep), "Exceeding cap limit");
distributedByDao = distributedByDao.add(_rep);
_addNewMember(_to);
_mint(_to, _rep, msg.sender);
emit DaoDistribution(_to, _rep);
}

function signal() external {
emit Signaled();
}

function issueReputation(address _to, uint256 _reputation) external onlyDAO {
require(_to != address(0), "Invalid address");
require(_reputation > 0, "Invalid reputation");
require(LOCKDROP_CAP > distributedByLockdrop.add(_reputation), "Exceeding cap limit");
distributedByLockdrop = distributedByLockdrop.add(_reputation);
_addNewMember(_to);
_mint(_to, _reputation, msg.sender);
emit IssueReputation(_to, _reputation);
}

function getReputation(address _of) public view returns(uint256 reputation) {
reputation = addressToReputation[_of].rep == 0 ? 1000 : addressToReputation[_of].rep;
}

function _addNewMember(address _holder) internal {
if (addressToReputation[_holder].rep == 0)
members.push(_holder);
}

function getAllMembers() public view returns(address[] memory, uint256[] memory) {
uint256[] memory reputations = new uint256[](members.length);
for (uint256 i = 0; i < members.length; i++) {
reputations[i] = addressToReputation[members[i]].rep;
}
return (members, reputations);
}

function addPartner(address _partner) external onlyDAO {
require(_partner != address(0), "Invalid address");
require(partnersIndex[_partner] == 0, "Already exists");
partners.push(_partner);
partnersIndex[_partner] = partners.length;
emit PartnerAdded(_partner);
}

function mintReputation(address _to, uint256 _amount) external onlyPartner {
require(_to != address(0), "Invalid address");
require(_amount > 0, "Invalid amount");
_mint(_to, _amount, msg.sender);
}

function _mint(address _to, uint256 _amount, address _mintedBy) internal {
uint256 currentReputation = getReputation(_to);
addressToReputation[_to].rep = currentReputation.add(_amount);
emit MintReputation(_to, _amount, _mintedBy);
}


/**
* @notice function used to calculate the celing of logn for base 2
* @dev referenced from https://ethereum.stackexchange.com/a/30168/15915
*/
function log_2(uint x) public pure returns (uint y){
assembly {
let arg := x
x := sub(x,1)
x := or(x, div(x, 0x02))
x := or(x, div(x, 0x04))
x := or(x, div(x, 0x10))
x := or(x, div(x, 0x100))
x := or(x, div(x, 0x10000))
x := or(x, div(x, 0x100000000))
x := or(x, div(x, 0x10000000000000000))
x := or(x, div(x, 0x100000000000000000000000000000000))
x := add(x, 1)
let m := mload(0x40)
mstore(m, 0xf8f9cbfae6cc78fbefe7cdc3a1793dfcf4f0e8bbd8cec470b6a28a7a5a3e1efd)
mstore(add(m,0x20), 0xf5ecf1b3e9debc68e1d9cfabc5997135bfb7a7a3938b7b606b5b4b3f2f1f0ffe)
mstore(add(m,0x40), 0xf6e4ed9ff2d6b458eadcdf97bd91692de2d4da8fd2d0ac50c6ae9a8272523616)
mstore(add(m,0x60), 0xc8c0b887b0a8a4489c948c7f847c6125746c645c544c444038302820181008ff)
mstore(add(m,0x80), 0xf7cae577eec2a03cf3bad76fb589591debb2dd67e0aa9834bea6925f6a4a2e0e)
mstore(add(m,0xa0), 0xe39ed557db96902cd38ed14fad815115c786af479b7e83247363534337271707)
mstore(add(m,0xc0), 0xc976c13bb96e881cb166a933a55e490d9d56952b8d4e801485467d2362422606)
mstore(add(m,0xe0), 0x753a6d1b65325d0c552a4d1345224105391a310b29122104190a110309020100)
mstore(0x40, add(m, 0x100))
let magic := 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff
let shift := 0x100000000000000000000000000000000000000000000000000000000000000
let a := div(mul(x, magic), shift)
y := div(mload(add(m,sub(255,a))), shift)
y := add(y, mul(256, gt(arg, 0x8000000000000000000000000000000000000000000000000000000000000000)))
}
}
}
14 changes: 14 additions & 0 deletions CredEth/contracts/CredEthScheme.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pragma solidity ^0.5.7;

import "@daostack/arc/contracts/universalSchemes/GenericScheme.sol";


/**
* @title A universal scheme for proposing "Credit reputation status" and rewarding proposers with reputation
* @dev An agent can propose the organization a "reason of the credit reputation" to send.
* if accepted the proposal will be posted by the organization
* and the proposer will receive Credit reputation.
*/
contract CredEthScheme is GenericScheme {

}
25 changes: 25 additions & 0 deletions CredEth/contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pragma solidity ^0.5.7;

contract Migrations {
address public owner;

uint public lastCompletedMigration;

modifier restricted() {
require(msg.sender == owner, "Sender must be owner");
_;
}

constructor() public {
owner = msg.sender;
}

function setCompleted(uint _completed) public restricted {
lastCompletedMigration = _completed;
}

function upgrade(address _newAddress) public restricted {
Migrations upgraded = Migrations(_newAddress);
upgraded.setCompleted(lastCompletedMigration);
}
}
25 changes: 25 additions & 0 deletions CredEth/data/migration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"private": {
"base": {
"0.0.1-rc.23": {
"GEN": "0x9095b8e8a5a4E7Fcb7F569dDc325eAB089732B26",
"DAORegistry": "0x126CF548F9110Ed46FA3021E8AEAaC2Ba4538896",
"ControllerCreator": "0x102EB6c9895955Ce780508f1e9ee7Ac2bdd1CE57",
"DaoCreator": "0x457f0f599CC62A41B221cC94bC9d5Cf0012D21A8",
"UController": "0x0937F524C8A7d3D6Af3023875CF6c7f293F3B994",
"GenesisProtocol": "0x1932400a9A132D20c3961E2848DE4bA3Ce8Ff30B",
"SchemeRegistrar": "0x79e0ba0C34ED4cc6a493ebCdf11A84491Cb6f5ea",
"UpgradeScheme": "0x467fD9FEA4e77AC79504a23B45631D29e42eaa4A",
"GlobalConstraintRegistrar": "0x4d040B247949a76cB8134203Da822Da50C674557",
"ContributionReward": "0xE4B293636F4b10c9cBD8E798B80A75bba71a90cE",
"AbsoluteVote": "0xc080828C1A20E7cb0D20AD5191314e64286989E5",
"QuorumVote": "0x3B2d33aC0B76462c8Eb58548ed7db68BC826F15E",
"TokenCapGC": "0xD44d92D878Bb19649bE73702E514560743B3CF86",
"VoteInOrganizationScheme": "0xe00b745b5e71337507d43a8584320c4192CA7994",
"OrganizationRegister": "0x3e5399049a779489000583dD0d14576D0472Fe94",
"Redeemer": "0x0d31fD995E1540CE90Fd98462Cf3284b1693Ad8C",
"GenericScheme": "0x92472cBcfc8E6dB1806374d543a140d49f83D7b5"
}
}
}
}
62 changes: 62 additions & 0 deletions CredEth/data/migrations-params.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"orgName": "CredETH",
"tokenName": "CredETH token",
"tokenSymbol": "CRED",

"ContributionReward": {
"voteParams": 0
},
"SchemeRegistrar": {
"voteRegisterParams": 0,
"voteRemoveParams": 0
},
"CustomSchemes": {
"CredEthScheme": {
"isUniversal": true,
"params": [
{ "voteParams": 0 },
"GenesisProtocolAddress",
"0x2a79BA9ebD1211E97af91a7F05d3bB3a085C3238"
],
"permissions": "0x00000001"
}
},
"VotingMachinesParams": [
{
"boostedVotePeriodLimit": 600,
"daoBountyConst": 10,
"minimumDaoBounty": 100,
"queuedVotePeriodLimit": 1800,
"queuedVoteRequiredPercentage": 50,
"preBoostedVotePeriodLimit": 600,
"proposingRepReward": 5,
"quietEndingPeriod": 300,
"thresholdConst": 2000,
"voteOnBehalf": "0x0000000000000000000000000000000000000000",
"votersReputationLossRatio": 1,
"activationTime": 0
}
],
"schemes": {
"ContributionReward": true,
"GenericScheme": false,
"SchemeRegistrar": true,
"GlobalConstraintRegistrar": false,
"UpgradeScheme": false
},
"unregisterOwner": true,
"useUController": true,
"useDaoCreator": false,
"founders": [
{
"address": "0x1B2D2797A56c9eBa12aa821D643aB0dBa66C3772",
"tokens": 1000,
"reputation": 1000
},
{
"address": "0x735C5229B6EdC09650E2011b3cCB04de106b7961",
"tokens": 1000,
"reputation": 1000
}
]
}
5 changes: 5 additions & 0 deletions CredEth/example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
NETWORK='private'
PROVIDER='http://localhost:8545'
# Use Private key or seed-phrase no need for both
PRIVATE_KEY='Add-your-priv-key'
SEED_PHRASE='Add-Your-Seed-Phrase'
18 changes: 18 additions & 0 deletions CredEth/migrations/1_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const CredETH = artifacts.require("./CredEth.sol");
const migrationDao = JSON.parse(require("fs").readFileSync("../data/migration.json").toString());

// It may not work because DaoStack migration is not working so np proper migration.json data exists
module.exports = async (deployer, network, accounts) => {
let owner;
let daoAddress;
if (network == "development") {
owner = accounts[0];
daoAddress = migrationDao.private.base["0.0.1-rc.23"].CredEthScheme;
}
else if (network == "kovan") {
owner = accounts[0];
daoAddress = migrationDao.kovan.base["0.0.1-rc.23"].CredEthScheme;
}
await deployer.deploy(CredETH, {from: owner});
await CredETH.setDao(daoAddress, {from: owner});
}
40 changes: 40 additions & 0 deletions CredEth/migrations/2_deploy_dao.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const DAOstackMigration = require('@daostack/migration');
const migrationSpec = require('../data/migrations-params.json');
require('dotenv').config();


async function migrate() {

// ganache-core object with already migrated contracts
// options are as specified in https://github.com/trufflesuite/ganache-cli#library
// DAOstackMigration.Ganache.provider(process.env.PROVIDER);
// // migration result object for ganache
//DAOstackMigration.migration(process.env.NETWORK);

const options = {
provider: process.env.PROVIDER,
gasPrice: 3.4,
quiet: false,
force: true,
output: 'data/migration.json',
privateKey: process.env.PRIVATE_KEY,
params: {
private: migrationSpec,
customABIsLocation: "build/contracts"
},
};

switch (process.env.NETWORK) {
case "ganache":
case "private":
options.prevmigration = " ";
console.log("Everything is working at here");
const migrationBaseResult = await DAOstackMigration.migrateBase(options);
console.log("deployed base")
options.prevmigration = options.output;
break;
}
const migrationDAOResult = await DAOstackMigration.migrateDAO(options);
}

migrate()
Loading