Skip to content

Commit

Permalink
Merge pull request #203 from Thetta/dev2RostyslavLiquid
Browse files Browse the repository at this point in the history
Change delegateMyVoiceTo() behaviour #196
  • Loading branch information
AnthonyAkentiev committed Jul 19, 2018
2 parents 21d7e35 + ca4ee3c commit cbaf1b6
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 47 deletions.
112 changes: 67 additions & 45 deletions contracts/governance/Voting_Liquid.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,16 @@ import "./Voting_SimpleToken.sol";


contract LiquidVoting is IDelegationTable, Voting_SimpleToken {
struct Delegator {
mapping (address => uint) tokensDelegatedForVotingFromAddress; // check delegated tokens from concret address (for deleting delegation)
mapping (address => bool) isDelegatedForFrom; // check if for account was delegated any from this address
mapping (address => bool) isDelegatorFor; // check if account delegate any for this address
uint delegatorsAmount; // amount of delegators which delegated any tokens for this address
uint delegatedForAmount; // amount of delegations which this address have done
uint tokensDelegatedForVoting; // tokens which was delegated for address
uint blockedTokensDelegatedForVoting; // tokens which account delegated for other addresses
bool isDelegatedFor; // true if someone delegated tokens for this account
bool isDelegator; // true if this account delegated any tokens for someone
struct Delegation {
address _address;
uint amount;
bool isDelegator;
}

event DelegatedTo(address _sender, uint _blocked);
event DelegationRemoved(address _sender, uint _tokensAmount);
event DelegatedTo(address _sender, uint _tokensAmount);
event DelegationRemoved(address _from, address _to);

mapping (address => Delegator) delegations;
mapping (address => Delegation[]) delegations;

constructor(IDaoBase _dao, IProposal _proposal,
address _origin, uint _minutesToVote,
Expand All @@ -47,55 +41,83 @@ contract LiquidVoting is IDelegationTable, Voting_SimpleToken {
}

function getPowerOf(address _who) public view returns(uint){
if(delegations[_who].isDelegator || delegations[_who].isDelegatedFor){
return stdDaoToken.getBalanceAtVoting(votingID, _who) - delegations[_who].blockedTokensDelegatedForVoting + delegations[_who].tokensDelegatedForVoting;
uint res = stdDaoToken.getBalanceAtVoting(votingID, _who);

for(uint i = 0; i < delegations[_who].length; i++){
if(!delegations[_who][i].isDelegator){
res += delegations[_who][i].amount;
}
if(delegations[_who][i].isDelegator){
res -= delegations[_who][i].amount;
}
}

return stdDaoToken.getBalanceAtVoting(votingID, _who);
return res;
}

function getDelegatedPowerOf(address _of) public view returns(uint) {
return delegations[_of].tokensDelegatedForVoting;
uint res;

for(uint i = 0; i < delegations[_of].length; i++){
if(!delegations[_of][i].isDelegator){
res += delegations[_of][i].amount;
}
}

return res;
}

function getDelegatedPowerByMe(address _to) public view returns(uint) {
return delegations[_to].blockedTokensDelegatedForVoting;
uint res;

for(uint i = 0; i < delegations[msg.sender].length; i++){
if(delegations[msg.sender][i]._address == _to){
if(delegations[msg.sender][i].isDelegator){
res += delegations[msg.sender][i].amount;
}
}
}

return res;
}

function delegateMyVoiceTo(address _to, uint _tokenAmount) public {
require (_to!= address(0));
require (_tokenAmount >= stdDaoToken.balanceOf(msg.sender));

delegations[_to].tokensDelegatedForVoting += _tokenAmount;
delegations[_to].tokensDelegatedForVotingFromAddress[msg.sender] += _tokenAmount;
delegations[_to].delegatorsAmount += 1;
delegations[_to].isDelegatedFor = true;
delegations[_to].isDelegatedForFrom[msg.sender] = true;
delegations[msg.sender].blockedTokensDelegatedForVoting += _tokenAmount;
emit DelegatedTo(msg.sender, _tokenAmount);
delegations[msg.sender].isDelegator = true;
delegations[msg.sender].isDelegatorFor[_to] = true;
delegations[msg.sender].delegatedForAmount += 1;
require (_tokenAmount <= stdDaoToken.getBalanceAtVoting(votingID, msg.sender));

for(uint i = 0; i < delegations[_to].length; i++){
if(delegations[_to][i]._address == msg.sender){
delegations[_to][i].amount = _tokenAmount;
}
}

for(i = 0; i < delegations[msg.sender].length; i++){
if(delegations[msg.sender][i]._address == _to){
delegations[msg.sender][i].amount = _tokenAmount;
emit DelegatedTo(_to, _tokenAmount);
return;
}
}

delegations[_to].push(Delegation(msg.sender, _tokenAmount, false));
delegations[msg.sender].push(Delegation(_to, _tokenAmount, true));
}

function removeDelegation(address _to) public {
require (_to!= address(0));
require (delegations[_to].isDelegatedForFrom[msg.sender]);
require (delegations[msg.sender].isDelegatorFor[_to]);

delegations[_to].tokensDelegatedForVoting -= delegations[_to].tokensDelegatedForVotingFromAddress[msg.sender];
delegations[msg.sender].blockedTokensDelegatedForVoting -= delegations[_to].tokensDelegatedForVotingFromAddress[msg.sender];
emit DelegationRemoved(_to, delegations[_to].tokensDelegatedForVotingFromAddress[msg.sender]);
delegations[_to].tokensDelegatedForVotingFromAddress[msg.sender] = 0;
delegations[_to].isDelegatedForFrom[msg.sender] = false;
delegations[msg.sender].isDelegatorFor[_to] = false;
delegations[_to].delegatorsAmount -= 1;
delegations[msg.sender].delegatedForAmount -= 1;
if(delegations[_to].delegatorsAmount == 0){
delegations[_to].isDelegatedFor = false;

for(uint i = 0; i < delegations[_to].length; i++){
if(delegations[_to][i]._address == msg.sender){
delegations[_to][i].amount = 0;
}
}
if(delegations[msg.sender].delegatedForAmount == 0){
delegations[_to].isDelegator = false;

for(i = 0; i < delegations[msg.sender].length; i++){
if(delegations[msg.sender][i]._address == _to){
delegations[msg.sender][i].amount = 0;
}
}

emit DelegationRemoved(msg.sender, _to);
}
}
23 changes: 21 additions & 2 deletions test/governance/voting_liquid.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require('chai')
contract('LiquidVoting(quorumPercent, consensusPercent)', (accounts) => {
const creator = accounts[0];
const employee1 = accounts[1];
const employee2 = accounts[2];

let r2;
let token;
Expand All @@ -37,6 +38,7 @@ contract('LiquidVoting(quorumPercent, consensusPercent)', (accounts) => {
token = await StdDaoToken.new("StdToken","STDT",18, true, true, 1000000000);
await token.mintFor(creator, 1);
await token.mintFor(employee1, 1);
await token.mintFor(employee2, 2);

let store = await DaoStorage.new([token.address],{ from: creator });
daoBase = await DaoBaseWithUnpackers.new(store.address,{ from: creator });
Expand Down Expand Up @@ -116,13 +118,13 @@ contract('LiquidVoting(quorumPercent, consensusPercent)', (accounts) => {
assert.equal(r2.toNumber(),0,'yes');
r2 = await voting.getPowerOf(employee1);
assert.equal(r2.toNumber(),2,'yes');
r2 = await voting.getDelegatedPowerByMe(creator);
r2 = await voting.getDelegatedPowerByMe(employee1);
assert.equal(r2.toNumber(),1,'yes');
});
});

describe('delegateMyVoiceTo()', function () {
it('Check delegateMyVoiceTo()',async() => {
it('Should delegate from A to B',async() => {
const voting = await LiquidVoting.new(daoBase.address, creator, creator, 0, 100, 100, token.address, false);

r2 = await voting.getDelegatedPowerOf(creator);
Expand All @@ -133,6 +135,23 @@ contract('LiquidVoting(quorumPercent, consensusPercent)', (accounts) => {
r2 = await voting.getDelegatedPowerOf(creator);
assert.equal(r2.toNumber(),1);
});

it('Should delegate from A to B then from A to B again with the same amount',async() => {
const voting = await LiquidVoting.new(daoBase.address, creator, creator, 0, 100, 100, token.address, false);

r2 = await voting.getDelegatedPowerOf(creator);
assert.equal(r2.toNumber(),0);

await voting.delegateMyVoiceTo(creator, 1, {from: employee2});

r2 = await voting.getDelegatedPowerOf(creator);
assert.equal(r2.toNumber(),1);

await voting.delegateMyVoiceTo(creator, 1, {from: employee2});

r2 = await voting.getDelegatedPowerOf(creator);
assert.equal(r2.toNumber(),1);
});
});

describe('removeDelegation()', function () {
Expand Down

0 comments on commit cbaf1b6

Please sign in to comment.