2017-10-23 21:25:06 +00:00
/* eslint-env mocha */
/* eslint-disable no-await-in-loop */
2018-06-16 17:54:30 +00:00
const Ganache = require ( 'ganache-cli' ) ;
2017-10-23 21:25:06 +00:00
const Web3 = require ( 'web3' ) ;
2018-04-24 20:39:58 +00:00
const { assert } = require ( 'chai' ) ;
2018-06-16 17:54:30 +00:00
const { test } = require ( '../index' ) ;
const deployLP = require ( './helpers/deployLP' ) ;
2017-10-23 21:25:06 +00:00
2018-06-16 17:54:30 +00:00
const { assertFail } = test ;
2017-10-23 21:25:06 +00:00
2018-04-24 20:39:58 +00:00
const printState = async liquidPledgingState => {
2017-10-23 21:25:06 +00:00
const st = await liquidPledgingState . getState ( ) ;
console . log ( JSON . stringify ( st , null , 2 ) ) ;
} ;
2018-04-24 20:39:58 +00:00
describe ( 'DelegationChain test' , function ( ) {
2017-10-23 21:25:06 +00:00
this . timeout ( 0 ) ;
2018-02-12 22:55:11 +00:00
2018-06-16 17:54:30 +00:00
let ganache ;
2017-10-23 21:25:06 +00:00
let web3 ;
let accounts ;
let liquidPledging ;
let liquidPledgingState ;
let vault ;
let giver1 ;
let giver2 ;
let delegate1 ;
let delegate2 ;
let delegate3 ;
let adminProject1 ;
2018-02-16 21:44:44 +00:00
let token ;
2017-10-23 21:25:06 +00:00
2018-01-22 19:00:30 +00:00
const gasUsage = { } ;
2017-10-23 21:25:06 +00:00
before ( async ( ) => {
2018-06-16 17:54:30 +00:00
ganache = Ganache . server ( {
2018-02-12 22:55:11 +00:00
gasLimit : 6700000 ,
total _accounts : 10 ,
2017-10-23 21:25:06 +00:00
} ) ;
2018-06-16 17:54:30 +00:00
ganache . listen ( 8545 , '127.0.0.1' ) ;
2017-10-23 21:25:06 +00:00
2018-02-12 23:24:26 +00:00
web3 = new Web3 ( 'http://localhost:8545' ) ;
2017-10-23 21:25:06 +00:00
accounts = await web3 . eth . getAccounts ( ) ;
delegate1 = accounts [ 2 ] ;
delegate2 = accounts [ 3 ] ;
delegate3 = accounts [ 4 ] ;
adminProject1 = accounts [ 5 ] ;
giver2 = accounts [ 6 ] ;
2018-06-16 17:54:30 +00:00
const deployment = await deployLP ( web3 ) ;
giver1 = deployment . giver1 ;
vault = deployment . vault ;
liquidPledging = deployment . liquidPledging ;
liquidPledgingState = deployment . liquidPledgingState ;
token = deployment . token ;
2017-10-23 21:25:06 +00:00
} ) ;
2018-04-24 20:39:58 +00:00
after ( done => {
2018-06-16 17:54:30 +00:00
ganache . close ( ) ;
2017-10-23 21:25:06 +00:00
done ( ) ;
} ) ;
it ( 'Should add pledgeAdmins' , async ( ) => {
2017-10-24 00:02:47 +00:00
await liquidPledging . addGiver ( 'Giver1' , 'URLGiver1' , 86400 , 0 , { from : giver1 } ) ; // pledgeAdmin 1
await liquidPledging . addDelegate ( 'Delegate1' , 'URLDelegate1' , 259200 , 0 , { from : delegate1 } ) ; // pledgeAdmin 2
2017-10-23 21:25:06 +00:00
await liquidPledging . addDelegate ( 'Delegate2' , 'URLDelegate2' , 0 , 0 , { from : delegate2 } ) ; // pledgeAdmin 3
await liquidPledging . addDelegate ( 'Delegate3' , 'URLDelegate3' , 0 , 0 , { from : delegate3 } ) ; // pledgeAdmin 4
2018-04-24 20:39:58 +00:00
await liquidPledging . addProject ( 'Project1' , 'URLProject1' , adminProject1 , 0 , 0 , 0 , {
from : adminProject1 ,
} ) ; // pledgeAdmin 5
2017-10-23 21:25:06 +00:00
await liquidPledging . addGiver ( 'Giver2' , 'URLGiver2' , 0 , 0 , { from : giver2 } ) ; // pledgeAdmin 6
const nAdmins = await liquidPledging . numberOfPledgeAdmins ( ) ;
assert . equal ( nAdmins , 6 ) ;
} ) ;
it ( 'Should allow previous delegate to transfer pledge' , async ( ) => {
2018-02-16 21:44:44 +00:00
await liquidPledging . donate ( 1 , 2 , token . $address , 1000 , { from : giver1 } ) ;
2017-10-23 21:25:06 +00:00
// add delegate2 to chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 2 , 1000 , 3 , { from : delegate1 } ) ;
2017-10-23 21:25:06 +00:00
// delegate 1 transfer pledge back to self, thus undelegating delegate2
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 3 , 1000 , 2 , { from : delegate1 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
const st = await liquidPledgingState . getState ( ) ;
assert . equal ( st . pledges [ 2 ] . amount , 1000 ) ;
assert . equal ( st . pledges [ 3 ] . amount , 0 ) ;
} ) ;
it ( 'Should allow any delegate in chain to transfer pledge and undelegate all delegates occurring later in chain' , async ( ) => {
// add delegate2 to chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 2 , 1000 , 3 , { from : delegate1 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
// add delegate3 to chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 3 , 3 , 1000 , 4 , { from : delegate2 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
// delegate 1 transfer pledge to project1. should also undelegate all delegates occurring later in chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 4 , 1000 , 5 , { from : delegate1 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
const st = await liquidPledgingState . getState ( ) ;
assert . equal ( st . pledges [ 5 ] . amount , 1000 ) ;
assert . equal ( st . pledges [ 5 ] . intendedProject , 5 ) ;
assert . equal ( st . pledges [ 5 ] . delegates . length , 1 ) ;
assert . equal ( st . pledges [ 5 ] . delegates [ 0 ] . id , 2 ) ;
assert . equal ( st . pledges [ 3 ] . amount , 0 ) ;
assert . equal ( st . pledges [ 4 ] . amount , 0 ) ;
} ) ;
it ( 'Should throw if delegate2 is not in delegationChain' , async ( ) => {
2018-02-12 22:55:11 +00:00
await assertFail ( liquidPledging . transfer ( 3 , 5 , 1000 , 1 , { from : delegate2 , gas : 4000000 } ) ) ;
2017-10-23 21:25:06 +00:00
} ) ;
it ( 'Delegate1 should not be able to transfer to another giver' , async ( ) => {
2018-02-12 22:55:11 +00:00
await assertFail ( liquidPledging . transfer ( 2 , 5 , 1000 , 6 , { from : delegate1 , gas : 4000000 } ) ) ;
2017-10-23 21:25:06 +00:00
} ) ;
it ( 'Delegate1 should be able to transfer pledge back to owner' , async ( ) => {
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 5 , 1000 , 1 , { from : delegate1 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
const st = await liquidPledgingState . getState ( ) ;
assert . equal ( st . pledges [ 1 ] . amount , 1000 ) ;
assert . equal ( st . pledges [ 1 ] . delegates . length , 0 ) ;
assert . equal ( st . pledges [ 5 ] . amount , 0 ) ;
} ) ;
it ( 'Delegate1 should be able to change delegation' , async ( ) => {
// add delegate1 to chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 1 , 1 , 1000 , 2 , { from : giver1 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
// delegate1 add delegate2 to chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 2 , 1000 , 3 , { from : delegate1 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
// delegate1 remove delegate2 and add delegate3 to chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 3 , 1000 , 4 , { from : delegate1 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
const st = await liquidPledgingState . getState ( ) ;
assert . equal ( st . pledges [ 1 ] . amount , 0 ) ;
assert . equal ( st . pledges [ 6 ] . amount , 1000 ) ;
assert . equal ( st . pledges [ 6 ] . delegates . length , 2 ) ;
assert . equal ( st . pledges [ 6 ] . delegates [ 0 ] . id , 2 ) ;
assert . equal ( st . pledges [ 6 ] . delegates [ 1 ] . id , 4 ) ;
} ) ;
it ( 'delegate in chain should be able to delegate to previous delegate, thus undelegating themselves and any delegate after the previous delegate' , async ( ) => {
// add delegate2 to chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 4 , 6 , 1000 , 3 , { from : delegate3 } ) ;
2017-10-23 21:25:06 +00:00
// delegate2 transfer back to delegate1, thus undelegating delegate2 & delegate3
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 3 , 7 , 1000 , 2 , { from : delegate2 , $extraGas : 200000 } ) ;
2017-10-23 21:25:06 +00:00
const st = await liquidPledgingState . getState ( ) ;
assert . equal ( st . pledges [ 7 ] . amount , 0 ) ;
assert . equal ( st . pledges [ 2 ] . amount , 1000 ) ;
assert . equal ( st . pledges [ 2 ] . delegates . length , 1 ) ;
assert . equal ( st . pledges [ 2 ] . delegates [ 0 ] . id , 2 ) ;
} ) ;
2017-10-23 23:17:39 +00:00
it ( 'Should not append delegate on veto delegation' , async ( ) => {
// propose the delegation
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 2 , 1000 , 5 , { from : delegate1 , $extraGas : 200000 } ) ;
2017-10-23 23:17:39 +00:00
const origPledge = await liquidPledging . getPledge ( 2 ) ;
assert . equal ( origPledge . amount , '0' ) ;
// veto the delegation
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 1 , 5 , 1000 , 2 , { from : giver1 , $extraGas : 200000 } ) ;
2017-10-23 23:17:39 +00:00
const currentPledge = await liquidPledging . getPledge ( 2 ) ;
assert . equal ( currentPledge . amount , '1000' ) ;
assert . equal ( currentPledge . nDelegates , 1 ) ;
} ) ;
2017-10-24 00:02:47 +00:00
it ( 'Pledge should have longest commitTime in delegation chain' , async ( ) => {
// delegate1 add delegate2 to chain
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 2 , 2 , 1000 , 3 , { from : delegate1 , $extraGas : 200000 } ) ;
2017-10-24 00:02:47 +00:00
2017-10-24 17:07:12 +00:00
// set the time
2017-10-24 00:02:47 +00:00
const now = Math . floor ( new Date ( ) . getTime ( ) / 1000 ) ;
2018-02-12 22:55:11 +00:00
await liquidPledging . setMockedTime ( now , { $extraGas : 200000 } ) ;
2017-10-24 17:07:12 +00:00
// propose project delegation
2018-01-25 23:09:58 +00:00
await liquidPledging . transfer ( 3 , 3 , 1000 , 5 , { from : delegate2 } ) ;
2017-10-24 00:02:47 +00:00
const pledge = await liquidPledging . getPledge ( 8 ) ;
2017-10-24 17:07:12 +00:00
assert . equal ( pledge . commitTime , now + 259200 ) ; // 259200 is longest commitTime in delegationChain
2017-11-10 15:33:12 +00:00
} ) ;
2018-04-24 20:39:58 +00:00
it ( "delegation chain should remain the same when owner veto's delegation" , async ( ) => {
2017-10-23 21:26:38 +00:00
// owner veto delegation to project1
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 1 , 8 , 1000 , 3 , { from : giver1 , $extraGas : 200000 } ) ;
2017-10-23 21:26:38 +00:00
const st = await liquidPledgingState . getState ( ) ;
2018-02-12 22:55:11 +00:00
assert . equal ( st . pledges [ 8 ] . amount , 0 ) ;
assert . equal ( st . pledges [ 3 ] . amount , 1000 ) ;
assert . equal ( st . pledges [ 3 ] . delegates . length , 2 ) ;
assert . equal ( st . pledges [ 3 ] . delegates [ 0 ] . id , 2 ) ;
assert . equal ( st . pledges [ 3 ] . delegates [ 1 ] . id , 3 ) ;
2017-11-10 16:39:58 +00:00
} ) ;
2018-04-24 20:39:58 +00:00
it ( "delegation chain should remain the same upto delegate of reciever when owner veto's delegation" , async ( ) => {
2017-11-10 16:39:58 +00:00
// propose project1 delegation
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 3 , 3 , 1000 , 5 , { from : delegate2 , $extraGas : 200000 } ) ;
2017-11-10 16:39:58 +00:00
// owner veto delegation to project1 and remove delegate2
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 1 , 8 , 1000 , 2 , { from : giver1 , $extraGas : 200000 } ) ;
2017-11-10 16:39:58 +00:00
const pledge = await liquidPledging . getPledge ( 2 ) ;
assert . equal ( pledge . amount , 1000 ) ;
} ) ;
it ( 'owner should be able to transfer pledge to a new delegate at any time' , async ( ) => {
// propose project1 delegation
2018-01-25 23:09:58 +00:00
await liquidPledging . transfer ( 2 , 2 , 1000 , 5 , { from : delegate1 } ) ;
2017-11-10 16:39:58 +00:00
// owner veto delegation to project1 and assign new delgate
2018-02-12 22:55:11 +00:00
await liquidPledging . transfer ( 1 , 9 , 1000 , 3 , { from : giver1 , $extraGas : 200000 } ) ;
2017-11-10 16:39:58 +00:00
const pledge = await liquidPledging . getPledge ( 10 ) ;
assert . equal ( pledge . amount , 1000 ) ;
assert . equal ( pledge . nDelegates , 1 ) ;
// owner assign new delegate w/o vetoing intendedProject
await liquidPledging . transfer ( 1 , 10 , 1000 , 2 , { from : giver1 , $extraGas : 100000 } ) ;
const pledge2 = await liquidPledging . getPledge ( 2 ) ;
assert . equal ( pledge2 . amount , 1000 ) ;
2017-11-10 15:33:12 +00:00
} ) ;
2017-10-23 21:25:06 +00:00
} ) ;