diff --git a/contracts/test/NectarRepAllocation.sol b/contracts/test/NectarRepAllocation.sol new file mode 100644 index 00000000..651cccc7 --- /dev/null +++ b/contracts/test/NectarRepAllocation.sol @@ -0,0 +1,72 @@ +pragma solidity ^0.5.11; + +import "openzeppelin-solidity/contracts/math/SafeMath.sol"; + + +contract MiniMeToken { + function balanceOfAt(address _owner, uint _blockNumber) public view returns (uint); + function totalSupplyAt(uint _blockNumber) public view returns(uint); +} + +/** + * @title NectarRepAllocation contract + * This contract should be use to calculate reputation allocation for nextar dao bootstrat + * this contract can be used as the rep mapping contract for RepitationFromToken contract. + */ + +contract NectarRepAllocation { + using SafeMath for uint256; + + uint256 public reputationReward; + uint256 public claimingStartTime; + uint256 public claimingEndTime; + uint256 public totalTokenSupplyAt; + uint256 public blockReference; + MiniMeToken public token; + + /** + * @dev initialize + * @param _reputationReward the total reputation which will be used to calc the reward + * for the token locking + * @param _claimingStartTime claiming starting period time. + * @param _claimingEndTime the claiming end time. + * claiming is disable after this time. + * @param _blockReference the block nbumber reference which is used to takle the balance from. + * @param _token nectar token address + */ + function initialize( + uint256 _reputationReward, + uint256 _claimingStartTime, + uint256 _claimingEndTime, + uint256 _blockReference, + MiniMeToken _token) + external + { + require(token == MiniMeToken(0), "can be called only one time"); + require(_token != MiniMeToken(0), "token cannot be zero"); + token = _token; + reputationReward = _reputationReward; + claimingStartTime = _claimingStartTime; + claimingEndTime = _claimingEndTime; + blockReference = _blockReference; + if ((claimingStartTime != 0) || (claimingEndTime != 0)) { + require(claimingEndTime > claimingStartTime, "claimingStartTime > claimingEndTime"); + } + totalTokenSupplyAt = token.totalSupplyAt(_blockReference); + } + + /** + * @dev get balanceOf _beneficiary function + * @param _beneficiary addresses + */ + function balanceOf(address _beneficiary) public view returns(uint256 reputation) { + if (((claimingStartTime != 0) || (claimingEndTime != 0)) && + // solhint-disable-next-line not-rely-on-time + ((now >= claimingEndTime) || (now < claimingStartTime))) { + reputation = 0; + } else { + reputation = token.balanceOfAt(_beneficiary, blockReference).mul(reputationReward).div(totalTokenSupplyAt); + } + } + +} diff --git a/test/nectarrepallocation.js b/test/nectarrepallocation.js new file mode 100644 index 00000000..35622cad --- /dev/null +++ b/test/nectarrepallocation.js @@ -0,0 +1,78 @@ +const helpers = require('./helpers'); +const NectarToken = artifacts.require('./Reputation.sol'); +var NectarRepAllocation = artifacts.require("./NectarRepAllocation.sol"); + + +const setup = async function (accounts, + _initialize = true, + _reputationReward = 100000, + _claimingStartTime = 0, + _claimingEndTime = (30*60*60*24) + ) { + var testSetup = new helpers.TestSetup(); + testSetup.nectarToken = await NectarToken.new(); + await testSetup.nectarToken.mint(accounts[0],100); + await testSetup.nectarToken.mint(accounts[1],200); + testSetup.blockReference = await web3.eth.getBlockNumber(); + + await testSetup.nectarToken.mint(accounts[2],300); + + testSetup.claimingStartTime = (await web3.eth.getBlock("latest")).timestamp + _claimingStartTime; + testSetup.claimingEndTime = (await web3.eth.getBlock("latest")).timestamp + _claimingEndTime; + + testSetup.nectarRepAllocation = await NectarRepAllocation.new(); + + testSetup.reputationReward = _reputationReward; + if (_initialize === true ) { + await testSetup.nectarRepAllocation.initialize( + testSetup.reputationReward, + testSetup.claimingStartTime, + testSetup.claimingEndTime, + testSetup.blockReference, + testSetup.nectarToken.address); + } + + return testSetup; +}; + +contract('NectarRepAllocation', accounts => { + it("initialize", async () => { + let testSetup = await setup(accounts); + assert.equal(await testSetup.nectarRepAllocation.claimingStartTime(),testSetup.claimingStartTime); + assert.equal(await testSetup.nectarRepAllocation.claimingEndTime(),testSetup.claimingEndTime); + assert.equal(await testSetup.nectarRepAllocation.blockReference(),testSetup.blockReference); + assert.equal(await testSetup.nectarRepAllocation.token(),testSetup.nectarToken.address); + }); + + it("balanceOf", async () => { + let testSetup = await setup(accounts); + assert.equal(await testSetup.nectarRepAllocation.balanceOf(accounts[0]),Math.floor((100*testSetup.reputationReward)/300)); + assert.equal(await testSetup.nectarRepAllocation.balanceOf(accounts[1]),Math.floor((200*testSetup.reputationReward)/300)); + assert.equal(await testSetup.nectarRepAllocation.balanceOf(accounts[2]),0); + + }); + + it("cannot initialize twice", async () => { + let testSetup = await setup(accounts); + try { + await testSetup.nectarRepAllocation.initialize( + testSetup.reputationReward, + testSetup.claimingStartTime, + testSetup.claimingEndTime, + testSetup.blockReference, + testSetup.nectarToken.address); + assert(false, "cannot initialize twice"); + + } catch(error) { + helpers.assertVMException(error); + } + }); + + it("claim after end return 0", async () => { + let testSetup = await setup(accounts); + await helpers.increaseTime((30*60*60*24)+1); + assert.equal(await testSetup.nectarRepAllocation.balanceOf(accounts[0]),0); + }); + + +}); diff --git a/test/reputationfromtoken.js b/test/reputationfromtoken.js index 1f99547c..66cac759 100644 --- a/test/reputationfromtoken.js +++ b/test/reputationfromtoken.js @@ -7,6 +7,40 @@ var RepAllocation = artifacts.require("./RepAllocation.sol"); var PolkaCurve = artifacts.require("./PolkaCurve.sol"); +var NectarRepAllocation = artifacts.require("./NectarRepAllocation.sol"); +const NectarToken = artifacts.require('./Reputation.sol'); + + +const setupNectar = async function (accounts) { + 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.nectarToken = await NectarToken.new(); + await testSetup.nectarToken.mint(accounts[0],100); + await testSetup.nectarToken.mint(accounts[1],200); + testSetup.blockReference = await web3.eth.getBlockNumber(); + testSetup.nectarRepAllocation = await NectarRepAllocation.new(); + testSetup.reputationReward = 100000; + await testSetup.nectarRepAllocation.initialize( + testSetup.reputationReward, + 0, + 0, + testSetup.blockReference, + testSetup.nectarToken.address); + + testSetup.reputationFromToken = await ReputationFromToken.new(); + testSetup.curve = helpers.NULL_ADDRESS; + await testSetup.reputationFromToken.initialize(testSetup.org.avatar.address, + testSetup.nectarRepAllocation.address, + helpers.NULL_ADDRESS); + + + var permissions = "0x00000000"; + await testSetup.daoCreator.setSchemes(testSetup.org.avatar.address,[testSetup.reputationFromToken.address],[helpers.NULL_HASH],[permissions],"metaData"); + return testSetup; +}; + const setup = async function (accounts, _initialize = true) { var testSetup = new helpers.TestSetup(); var controllerCreator = await ControllerCreator.new({gas: constants.ARC_GAS_LIMIT}); @@ -123,4 +157,17 @@ contract('ReputationFromToken and RepAllocation', accounts => { helpers.assertVMException(error); } }); + + it("redeem nectar", async () => { + let testSetup = await setupNectar(accounts); + var tx = await testSetup.reputationFromToken.redeem(accounts[1],{from:accounts[1]}); + var expected = Math.floor((200*testSetup.reputationReward)/300); + assert.equal(tx.logs.length,1); + assert.equal(tx.logs[0].event,"Redeem"); + assert.equal(tx.logs[0].args._beneficiary,accounts[1]); + assert.equal(tx.logs[0].args._amount.toString(),expected); + assert.equal(tx.logs[0].args._sender,accounts[1]); + assert.equal(await testSetup.org.reputation.balanceOf(accounts[0]),1000); + assert.equal(await testSetup.org.reputation.balanceOf(accounts[1]),expected); + }); });