diff --git a/baklava_genesis_balances.json b/baklava_genesis_balances.json index 0a00d4560b4..c1da88eba39 100644 --- a/baklava_genesis_balances.json +++ b/baklava_genesis_balances.json @@ -1,5 +1,5 @@ { - "value": "12000000000000000000", + "value": "12000000000000000000000", "addresses": [ "d5c181972763b082d4d6ca84662878674c0bd35c", "0c561cfe5616e01467ba9792f0bc320314c7b1c6", diff --git a/packages/cli/src/commands/election/list.ts b/packages/cli/src/commands/election/list.ts index b0195723394..c3f66077702 100644 --- a/packages/cli/src/commands/election/list.ts +++ b/packages/cli/src/commands/election/list.ts @@ -18,6 +18,7 @@ export default class List extends BaseCommand { cli.action.stop() cli.table(groupVotes, { address: {}, + name: {}, votes: { get: (g) => g.votes.toFixed() }, capacity: { get: (g) => g.capacity.toFixed() }, eligible: {}, diff --git a/packages/contractkit/src/wrappers/Election.ts b/packages/contractkit/src/wrappers/Election.ts index 4644cae73f9..3db0ff2ec0a 100644 --- a/packages/contractkit/src/wrappers/Election.ts +++ b/packages/contractkit/src/wrappers/Election.ts @@ -18,6 +18,7 @@ import { export interface ValidatorGroupVote { address: Address + name: string votes: BigNumber capacity: BigNumber eligible: boolean @@ -175,8 +176,11 @@ export class ElectionWrapper extends BaseWrapper { const votes = await this.contract.methods.getTotalVotesForGroup(address).call() const eligible = await this.contract.methods.getGroupEligibility(address).call() const numVotesReceivable = await this.contract.methods.getNumVotesReceivable(address).call() + const accounts = await this.kit.contracts.getAccounts() + const name = (await accounts.getName(address)) || '' return { address, + name, votes: toBigNumber(votes), capacity: toBigNumber(numVotesReceivable).minus(votes), eligible, @@ -187,7 +191,7 @@ export class ElectionWrapper extends BaseWrapper { */ async getValidatorGroupsVotes(): Promise { const validators = await this.kit.contracts.getValidators() - const groups = (await validators.getRegisteredValidatorGroups()).map((g) => g.address) + const groups = await validators.getRegisteredValidatorGroupsAddresses() return concurrentMap(5, groups, (g) => this.getValidatorGroupVotes(g)) } @@ -283,6 +287,7 @@ export class ElectionWrapper extends BaseWrapper { return zip( (a, b) => ({ address: a, + name: '', votes: new BigNumber(b), capacity: new BigNumber(0), eligible: true, @@ -306,6 +311,7 @@ export class ElectionWrapper extends BaseWrapper { } else { currentVotes.push({ address: votedGroup, + name: '', votes: voteWeight, // Not used for the purposes of finding lesser and greater. capacity: new BigNumber(0), diff --git a/packages/contractkit/src/wrappers/Validators.test.ts b/packages/contractkit/src/wrappers/Validators.test.ts index ad5454c7654..ecdad5e622d 100644 --- a/packages/contractkit/src/wrappers/Validators.test.ts +++ b/packages/contractkit/src/wrappers/Validators.test.ts @@ -26,11 +26,14 @@ testWithGanache('Validators Wrapper', (web3) => { let validators: ValidatorsWrapper let lockedGold: LockedGoldWrapper - const registerAccountWithLockedGold = async (account: string) => { + const registerAccountWithLockedGold = async ( + account: string, + value: string = minLockedGoldValue + ) => { if (!(await accountsInstance.isAccount(account))) { await accountsInstance.createAccount().sendAndWaitForReceipt({ from: account }) } - await lockedGold.lock().sendAndWaitForReceipt({ from: account, value: minLockedGoldValue }) + await lockedGold.lock().sendAndWaitForReceipt({ from: account, value }) } beforeAll(async () => { @@ -40,8 +43,11 @@ testWithGanache('Validators Wrapper', (web3) => { accountsInstance = await kit.contracts.getAccounts() }) - const setupGroup = async (groupAccount: string) => { - await registerAccountWithLockedGold(groupAccount) + const setupGroup = async (groupAccount: string, members: number = 1) => { + await registerAccountWithLockedGold( + groupAccount, + new BigNumber(minLockedGoldValue).times(members).toFixed() + ) await (await validators.registerValidatorGroup(new BigNumber(0.1))).sendAndWaitForReceipt({ from: groupAccount, }) @@ -111,7 +117,7 @@ testWithGanache('Validators Wrapper', (web3) => { beforeEach(async () => { groupAccount = accounts[0] - await setupGroup(groupAccount) + await setupGroup(groupAccount, 2) validator1 = accounts[1] validator2 = accounts[2] diff --git a/packages/protocol/contracts/governance/Validators.sol b/packages/protocol/contracts/governance/Validators.sol index 8ccef26d594..ab062c2c7c4 100644 --- a/packages/protocol/contracts/governance/Validators.sol +++ b/packages/protocol/contracts/governance/Validators.sol @@ -688,9 +688,9 @@ contract Validators is require(_group.members.numElements < maxGroupSize, "group would exceed maximum size"); require(validators[validator].affiliation == group && !_group.members.contains(validator)); uint256 numMembers = _group.members.numElements.add(1); + _group.members.push(validator); require(meetsAccountLockedGoldRequirements(group)); require(meetsAccountLockedGoldRequirements(validator)); - _group.members.push(validator); if (numMembers == 1) { getElection().markGroupEligible(group, lesser, greater); } diff --git a/packages/protocol/lib/test-utils.ts b/packages/protocol/lib/test-utils.ts index 7af5c0d6a76..b15b3a5da95 100644 --- a/packages/protocol/lib/test-utils.ts +++ b/packages/protocol/lib/test-utils.ts @@ -82,14 +82,11 @@ export async function assertBalance(address: string, balance: BigNumber) { export async function assertRevert(promise: any, errorMessage: string = '') { try { await promise - assert.fail('Expected revert not received') + assert.fail('Expected transaction to revert') } catch (error) { - const revertFound = error.message.search('revert') >= 0 - if (errorMessage === '') { - assert(revertFound, `Expected "revert", got ${error} instead`) - } else { - assert(revertFound, errorMessage) - } + const revertFound = error.message.search('VM Exception while processing transaction: revert') >= 0 + const msg = errorMessage === '' ? `Expected "revert", got ${error} instead` : errorMessage + assert(revertFound, msg) } } diff --git a/packages/protocol/test/governance/validators.ts b/packages/protocol/test/governance/validators.ts index 4db673d0595..cac17ea4208 100644 --- a/packages/protocol/test/governance/validators.ts +++ b/packages/protocol/test/governance/validators.ts @@ -142,13 +142,16 @@ contract('Validators', (accounts: string[]) => { ) } - const registerValidatorGroup = async (group: string) => { - await mockLockedGold.setAccountTotalLockedGold(group, groupLockedGoldRequirements.value) + const registerValidatorGroup = async (group: string, numMembers: number = 1) => { + await mockLockedGold.setAccountTotalLockedGold( + group, + groupLockedGoldRequirements.value.times(numMembers) + ) await validators.registerValidatorGroup(commission, { from: group }) } const registerValidatorGroupWithMembers = async (group: string, members: string[]) => { - await registerValidatorGroup(group) + await registerValidatorGroup(group, members.length) for (const validator of members) { await registerValidator(validator) await validators.affiliate(group, { from: validator }) @@ -774,9 +777,9 @@ contract('Validators', (accounts: string[]) => { }) }) - describe('when it has been `validatorLockedGoldRequirements.duration` since the validator was removed from the group', () => { + describe('when it has been less than `validatorLockedGoldRequirements.duration` since the validator was removed from the group', () => { beforeEach(async () => { - await timeTravel(validatorLockedGoldRequirements.duration.toNumber(), web3) + await timeTravel(validatorLockedGoldRequirements.duration.minus(1).toNumber(), web3) }) it('should revert', async () => { @@ -1518,15 +1521,34 @@ contract('Validators', (accounts: string[]) => { }) describe('when the group does not meet the locked gold requirements', () => { - beforeEach(async () => { - await mockLockedGold.setAccountTotalLockedGold( - group, - groupLockedGoldRequirements.value.minus(1) - ) + describe('when the group does not have a member', () => { + beforeEach(async () => { + await mockLockedGold.setAccountTotalLockedGold( + group, + groupLockedGoldRequirements.value.minus(1) + ) + }) + + it('should revert', async () => { + await assertRevert(validators.addFirstMember(validator, NULL_ADDRESS, NULL_ADDRESS)) + }) }) - it('should revert', async () => { - await assertRevert(validators.addFirstMember(validator, NULL_ADDRESS, NULL_ADDRESS)) + describe('when the group already has a member', () => { + const validator2 = accounts[2] + beforeEach(async () => { + await mockLockedGold.setAccountTotalLockedGold( + group, + groupLockedGoldRequirements.value.times(2).minus(1) + ) + await validators.addFirstMember(validator, NULL_ADDRESS, NULL_ADDRESS) + await registerValidator(validator2) + await validators.affiliate(group, { from: validator2 }) + }) + + it('should revert', async () => { + await assertRevert(validators.addMember(validator2)) + }) }) }) }) diff --git a/packages/protocol/test/stability/reserve.ts b/packages/protocol/test/stability/reserve.ts index 85290d16951..84f3e9b95b8 100644 --- a/packages/protocol/test/stability/reserve.ts +++ b/packages/protocol/test/stability/reserve.ts @@ -100,10 +100,6 @@ contract('Reserve', (accounts: string[]) => { assert.equal(events[0].args.token.toLowerCase(), anAddress.toLowerCase()) }) - it('should revert when the token does not have an exchange rate with gold', async () => { - await assertRevert(reserve.addToken(web3.utils.randomHex(20))) - }) - describe('when the token has already been added', () => { beforeEach(async () => { await reserve.addToken(anAddress)