Skip to content

Commit

Permalink
add RepAllocation contract (#651)
Browse files Browse the repository at this point in the history
* add RepAllocation contract

* bump v to rc.23

* return value to redeem.
  • Loading branch information
orenyodfat authored Jul 24, 2019
1 parent c7745e8 commit 20eb410
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 36 deletions.
4 changes: 3 additions & 1 deletion contracts/schemes/ReputationFromToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ contract ReputationFromToken {
/**
* @dev redeem function
* @param _beneficiary the beneficiary address to redeem for
* @return uint256 minted reputation
*/
function redeem(address _beneficiary) public {
function redeem(address _beneficiary) public returns(uint256) {
require(avatar != Avatar(0), "should initialize first");
require(redeems[msg.sender] == false, "redeeming twice from the same account is not allowed");
redeems[msg.sender] = true;
Expand All @@ -53,5 +54,6 @@ contract ReputationFromToken {
avatar.owner())
.mintReputation(tokenAmount, _beneficiary, address(avatar)), "mint reputation should succeed");
emit Redeem(_beneficiary, msg.sender, tokenAmount);
return tokenAmount;
}
}
61 changes: 61 additions & 0 deletions contracts/utils/RepAllocation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
pragma solidity ^0.5.4;

import "openzeppelin-solidity/contracts/ownership/Ownable.sol";


/**
* @title reputation allocation contract
* This scheme can be used to allocate a pre define amount of reputation to whitelisted
* beneficiaries.
* this contract can be used as the rep mapping contract for RepitationFromToken contract.
*/
contract RepAllocation is Ownable {


// beneficiary -> amount
mapping(address => uint256) public reputationAllocations;
bool public isFreeze;

event BeneficiaryAddressAdded(address indexed _beneficiary, uint256 indexed _amount);

/**
* @dev addBeneficiary function
* @param _beneficiary to be whitelisted
*/
function addBeneficiary(address _beneficiary, uint256 _amount) public onlyOwner {
require(!isFreeze, "can add beneficiary only if not disable");

if (reputationAllocations[_beneficiary] == 0) {
reputationAllocations[_beneficiary] = _amount;
emit BeneficiaryAddressAdded(_beneficiary, _amount);
}
}

/**
* @dev add addBeneficiaries function
* @param _beneficiaries addresses
*/
function addBeneficiaries(address[] memory _beneficiaries, uint256[] memory _amounts) public onlyOwner {
require(_beneficiaries.length == _amounts.length);
for (uint256 i = 0; i < _beneficiaries.length; i++) {
addBeneficiary(_beneficiaries[i], _amounts[i]);
}
}

/**
* @dev freeze function
* cannot defreeze
*/
function freeze() public onlyOwner {
isFreeze = true;
}

/**
* @dev get balanceOf _beneficiary function
* @param _beneficiary addresses
*/
function balanceOf(address _beneficiary) public view returns(uint256) {
return reputationAllocations[_beneficiary];
}

}
44 changes: 22 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@daostack/arc",
"version": "0.0.1-rc.22",
"version": "0.0.1-rc.23",
"description": "A platform for building DAOs",
"files": [
"contracts/",
Expand Down
55 changes: 43 additions & 12 deletions test/reputationfromtoken.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,25 @@ const DaoCreator = artifacts.require("./DaoCreator.sol");
const ControllerCreator = artifacts.require("./ControllerCreator.sol");
const constants = require('./constants');
var ReputationFromToken = artifacts.require("./ReputationFromToken.sol");
var ExternalTokenLockerMock = artifacts.require("./ExternalTokenLockerMock.sol");
var RepAllocation = artifacts.require("./RepAllocation.sol");

var PolkaCurve = artifacts.require("./PolkaCurve.sol");

const setup = async function (accounts, _initialize = true) {
var testSetup = new helpers.TestSetup();
var controllerCreator = await ControllerCreator.new({gas: constants.ARC_GAS_LIMIT});
testSetup.daoCreator = await DaoCreator.new(controllerCreator.address,{gas:constants.ARC_GAS_LIMIT});
testSetup.org = await helpers.setupOrganization(testSetup.daoCreator,accounts[0],1000,1000);
testSetup.extetnalTokenLockerMock = await ExternalTokenLockerMock.new();
await testSetup.extetnalTokenLockerMock.lock(100,accounts[0]);
await testSetup.extetnalTokenLockerMock.lock(200,accounts[1]);
await testSetup.extetnalTokenLockerMock.lock(300,accounts[2]);
testSetup.repAllocation = await RepAllocation.new();
await testSetup.repAllocation.addBeneficiary(accounts[0],100);
await testSetup.repAllocation.addBeneficiary(accounts[1],200);
await testSetup.repAllocation.addBeneficiary(accounts[2],300);

testSetup.reputationFromToken = await ReputationFromToken.new();
testSetup.curve = await PolkaCurve.new();
if (_initialize === true) {
await testSetup.reputationFromToken.initialize(testSetup.org.avatar.address,
testSetup.extetnalTokenLockerMock.address,
testSetup.repAllocation.address,
testSetup.curve.address);
}

Expand All @@ -29,25 +30,55 @@ const setup = async function (accounts, _initialize = true) {
return testSetup;
};

contract('ReputationFromToken', accounts => {
contract('ReputationFromToken and RepAllocation', accounts => {
it("initialize", async () => {
let testSetup = await setup(accounts);
assert.equal(await testSetup.reputationFromToken.tokenContract(),testSetup.extetnalTokenLockerMock.address);
assert.equal(await testSetup.reputationFromToken.tokenContract(),testSetup.repAllocation.address);
assert.equal(await testSetup.reputationFromToken.avatar(),testSetup.org.avatar.address);
assert.equal(await testSetup.reputationFromToken.curve(),testSetup.curve.address);
});

it("externalLockingMock is onlyOwner", async () => {
it("repAllocation is onlyOwner", async () => {
let testSetup = await setup(accounts);
try {
await testSetup.extetnalTokenLockerMock.lock(1030,accounts[3],{from:accounts[1]});
assert(false, "externalLockingMock is onlyOwner");
await testSetup.repAllocation.addBeneficiary(accounts[3],1030,{from:accounts[1]});
assert(false, "repAllocation is onlyOwner");
} catch(error) {
helpers.assertVMException(error);
}

});

it("repAllocation cannot allocate after freeze", async () => {
let testSetup = await setup(accounts);
await testSetup.repAllocation.addBeneficiary(accounts[3],1030);
await testSetup.repAllocation.freeze();


try {
await testSetup.repAllocation.addBeneficiary(accounts[4],1030);
assert(false, "cannot allocate after freeze");
} catch(error) {
helpers.assertVMException(error);
}

});

it("repAllocation cannot allocate twice", async () => {
let testSetup = await setup(accounts);
assert(await testSetup.repAllocation.balanceOf(accounts[1]),200);
await testSetup.repAllocation.addBeneficiary(accounts[1],1030);
assert(await testSetup.repAllocation.balanceOf(accounts[1]),200);
});

it("repAllocation addBeneficiaries", async () => {
let testSetup = await setup(accounts);
let tx = await testSetup.repAllocation.addBeneficiaries([accounts[3],accounts[4]],[300,400]);
assert.equal(tx.logs.length,2);
});



it("redeem", async () => {
let testSetup = await setup(accounts);
var tx = await testSetup.reputationFromToken.redeem(accounts[1]);
Expand Down Expand Up @@ -84,7 +115,7 @@ contract('ReputationFromToken', accounts => {
let testSetup = await setup(accounts);
try {
await testSetup.reputationFromToken.initialize(testSetup.org.avatar.address,
testSetup.extetnalTokenLockerMock.address,
testSetup.repAllocation.address,
testSetup.curve.address
);
assert(false, "cannot initialize twice");
Expand Down

0 comments on commit 20eb410

Please sign in to comment.