Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-work locked gold requirements for validators and groups #1474

Merged
merged 133 commits into from
Nov 2, 2019
Merged
Show file tree
Hide file tree
Changes from 123 commits
Commits
Show all changes
133 commits
Select commit Hold shift + click to select a range
02f39db
Most things that don't touch incentives
Sep 19, 2019
0f226c8
Trying to get things to compile
Sep 19, 2019
721b9da
More work
Sep 19, 2019
17a624e
More changes
Sep 19, 2019
6ce7f7e
Compiling
Sep 20, 2019
c19b8b6
Updated validators test
Sep 21, 2019
a6921d3
LockedGold tests passing
Sep 24, 2019
871d06d
Validators tests passing
Sep 24, 2019
e0e8cf7
Fix governance tests
Sep 24, 2019
223536d
Add election test file
Sep 24, 2019
651009d
Election tests passing
Sep 26, 2019
a795125
Fix governance test
Sep 30, 2019
9b4d431
Most e2e governance tests passing
Oct 1, 2019
e866ca7
end to end tests passing
Oct 2, 2019
3a31670
Point to celo-blockchain branch
Oct 2, 2019
3f35c70
Merge master
Oct 2, 2019
c466d78
Add some natspecs
Oct 2, 2019
f02b05a
Linting
Oct 2, 2019
70d7478
Small fix
Oct 2, 2019
69f6ab2
ContractKit building
Oct 3, 2019
15d2e8c
cli builds
Oct 3, 2019
d6ef3ec
Update oclif
Oct 3, 2019
615ec4f
Checkpoint
Oct 3, 2019
1bbf1e0
Merge master
Oct 3, 2019
3ff2fe4
CLI seems to be working
Oct 3, 2019
d3b83c8
cleanup
Oct 3, 2019
2887651
Fix
Oct 3, 2019
2d61f63
Fix
Oct 3, 2019
a427d46
Begin work on validator/group payments
Oct 4, 2019
47a247c
Added test for epoch payment distribution
Oct 4, 2019
767c651
Validator set changing again
Oct 5, 2019
7f82317
Epoch payments and rewards appear to be working
Oct 6, 2019
50d6029
Update membership history upon validator registration
Oct 6, 2019
999bca2
End to end tests passing
Oct 7, 2019
03dc663
Add epoch size precompile, among other things
Oct 8, 2019
055d50f
Merge master
Oct 8, 2019
b491453
Revert "Feature #909 proxy delegatecall (#1152)"
asaj Oct 8, 2019
9cccd70
Merge branch 'revert-1152-feature/909-proxy-delegatecall' into asaj/p…
Oct 8, 2019
96f7a7a
Governance end-to-end tests working again
Oct 8, 2019
e40eaf0
Address comments
Oct 8, 2019
2fd2f9d
Merge master
Oct 9, 2019
adcad0b
Fix linting issues
Oct 9, 2019
53e4977
Make things build, tests pass
Oct 9, 2019
c2ea8e1
Merge branch 'master' into asaj/pos
Oct 9, 2019
ed62a4d
Merge asaj/pos
Oct 9, 2019
a5aa266
Fix unit tests
Oct 9, 2019
115a457
Fix migration
Oct 9, 2019
884773b
Add addFirstMember function
Oct 9, 2019
b2858d0
Rework balance requirements
Oct 10, 2019
0492b15
Fix build issues in contractkit
Oct 10, 2019
c0c1f27
Merge master
Oct 10, 2019
3c8739c
Merge asaj/pos
Oct 10, 2019
264a7f5
Fix
Oct 10, 2019
99d3fcc
Remove registry from governance test
Oct 10, 2019
7d9c5cc
Fix linting issues
Oct 10, 2019
f15e844
Add missing cli doc
Oct 10, 2019
993339c
Governance end-to-end test passing
Oct 10, 2019
44f9a43
Fix migration
Oct 10, 2019
3f5c804
Merge branch 'master' into asaj/pos
Oct 10, 2019
1ca67ac
Merge asaj/pos
Oct 10, 2019
2abdd08
Merge branch 'master' into asaj/pos
Oct 10, 2019
f59ca01
Fix CLI build
Oct 10, 2019
00f8061
Add electabilityThreshold enforcement
Oct 10, 2019
aba8552
Don't pay out epoch payments unless validator and group meet balance …
Oct 10, 2019
16f476c
Don't pay out epoch rewards unless the group meets balance requirements
Oct 10, 2019
3616cc6
Fix migrations
Oct 10, 2019
64016a7
Beef up documentation
Oct 11, 2019
6ffdd36
Merge branch 'master' into asaj/pos
Oct 11, 2019
b494b87
Merge branch 'master' into asaj/pos-2
Oct 11, 2019
67966e0
Merge asaj/pos
Oct 11, 2019
fb5e8b4
Fix linting issues
Oct 11, 2019
449e1ed
Add documentation
Oct 11, 2019
143a69c
Fix interface
Oct 11, 2019
1f18108
Expire previously upvoted proposals
Oct 11, 2019
506a77b
Address comments
Oct 11, 2019
23054fc
Merge branch 'master' into asaj/pos
Oct 11, 2019
0e207d0
Point to asaj/pos-2
Oct 11, 2019
90e8b58
Address comments
Oct 14, 2019
32557cf
Merge master
Oct 14, 2019
610cfe3
Base group locked gold requirement on number of members
Oct 16, 2019
b8e1797
Address comments
Oct 16, 2019
631894a
Merge master
Oct 16, 2019
4a4d6e2
Address comments
Oct 16, 2019
1d36857
Merge branch 'master' into asaj/pos
Oct 16, 2019
f3515ac
Fix tests, linting
Oct 16, 2019
c697213
Merge branch 'master' into asaj/pos
Oct 16, 2019
9aa6ec3
Remove bondeddeposits test
Oct 16, 2019
ed8e5a0
Merge branch 'master' into asaj/pos
Oct 16, 2019
89364ab
Fix test
Oct 16, 2019
98d8feb
Merge branch 'master' into asaj/pos
Oct 16, 2019
d85fc78
Merge asaj/pos
Oct 16, 2019
4faaf75
Merge master
Oct 16, 2019
931ceba
Address comments; remove url and authorizedBy.active, allow for varia…
Oct 18, 2019
92e254e
Fix build
Oct 18, 2019
a288e2b
Merge master
Oct 18, 2019
d9c2cc0
Fix migrations, end-to-end tests
Oct 18, 2019
0b894ac
Fix tests
Oct 18, 2019
44aa9f9
Update CLI docs
Oct 18, 2019
262c002
Fix end-to-end transfer tests
Oct 18, 2019
7346fa8
Merge branch 'master' into asaj/pos-2
Oct 18, 2019
97372e7
Fix contractkit tests
Oct 18, 2019
15ace64
Merge master
Oct 22, 2019
c6b2656
merge master
Oct 22, 2019
ef71139
Fix contractkit tests
Oct 22, 2019
c152286
Merge branch 'asaj/pos-2' into asaj/pos-3
Oct 22, 2019
b8eafd7
Fix
Oct 22, 2019
3847bef
Cleanup
Oct 22, 2019
ae1be93
Fix circle config
Oct 22, 2019
2b1da94
Contract unit tests passing
Oct 22, 2019
19488c7
Re-add isVoting tests
Oct 22, 2019
e3e3809
Small cleanup
Oct 22, 2019
fb7c235
Merge branch 'master' into asaj/pos-2
Oct 22, 2019
e39ff0a
Clean up election setters
Oct 23, 2019
1eb0e40
Merge branch 'master' into asaj/pos-2
Oct 23, 2019
035e7e2
Merge master
Oct 24, 2019
44d6f51
Fix contractkit test
Oct 24, 2019
aaf02cd
Remove outdated comment
Oct 24, 2019
5e2ec52
Merge branch 'asaj/pos-2' into asaj/pos-3
Oct 24, 2019
7e60132
Merge master
Oct 24, 2019
a6c9bb6
Merge branch 'master' into asaj/pos-3
Oct 25, 2019
59dedea
Fix Validators contract wrapper
Oct 25, 2019
7c25aed
Merge branch 'master' into asaj/pos-3
Oct 30, 2019
6fa6ee1
Merge master
Oct 31, 2019
9281b4c
Make precompile public
Oct 31, 2019
15c928e
Merge branch 'master' into asaj/pos-3
Oct 31, 2019
95c77d9
Fix migrations
Oct 31, 2019
c561862
Merge master
Nov 1, 2019
2bc75cc
Fix typo
Nov 1, 2019
6316dde
merge master
Nov 1, 2019
a871d67
Fix merge conflicts
Nov 1, 2019
fc95abc
Merge branch 'master' into asaj/pos-3
Nov 2, 2019
990fc14
reduce gold requirement for contractkit tests
Nov 2, 2019
5d910c9
Be sure to migrate random contract in validator order end-to-end tests
Nov 2, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 21 additions & 26 deletions packages/contractkit/src/wrappers/Validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,14 @@ export interface ValidatorGroup {
commission: BigNumber
}

export interface BalanceRequirements {
group: BigNumber
validator: BigNumber
}

export interface DeregistrationLockups {
group: BigNumber
validator: BigNumber
export interface LockedGoldRequirements {
value: BigNumber
duration: BigNumber
}

export interface ValidatorsConfig {
balanceRequirements: BalanceRequirements
deregistrationLockups: DeregistrationLockups
groupLockedGoldRequirements: LockedGoldRequirements
validatorLockedGoldRequirements: LockedGoldRequirements
maxGroupSize: BigNumber
}

Expand Down Expand Up @@ -77,26 +72,26 @@ export class ValidatorsWrapper extends BaseWrapper<Validators> {
}
}
/**
* Returns the current registration requirements.
* @returns Group and validator registration requirements.
* Returns the Locked Gold requirements for validators.
* @returns The Locked Gold requirements for validators.
*/
async getBalanceRequirements(): Promise<BalanceRequirements> {
const res = await this.contract.methods.getBalanceRequirements().call()
async getValidatorLockedGoldRequirements(): Promise<LockedGoldRequirements> {
const res = await this.contract.methods.getValidatorLockedGoldRequirements().call()
return {
group: toBigNumber(res[0]),
validator: toBigNumber(res[1]),
value: toBigNumber(res[0]),
duration: toBigNumber(res[1]),
}
}

/**
* Returns the lockup periods after deregistering groups and validators.
* @return The lockup periods after deregistering groups and validators.
* Returns the Locked Gold requirements for validator groups.
* @returns The Locked Gold requirements for validator groups.
*/
async getDeregistrationLockups(): Promise<DeregistrationLockups> {
const res = await this.contract.methods.getDeregistrationLockups().call()
async getGroupLockedGoldRequirements(): Promise<LockedGoldRequirements> {
const res = await this.contract.methods.getGroupLockedGoldRequirements().call()
return {
group: toBigNumber(res[0]),
validator: toBigNumber(res[1]),
value: toBigNumber(res[0]),
duration: toBigNumber(res[1]),
}
}

Expand All @@ -105,13 +100,13 @@ export class ValidatorsWrapper extends BaseWrapper<Validators> {
*/
async getConfig(): Promise<ValidatorsConfig> {
const res = await Promise.all([
this.getBalanceRequirements(),
this.getDeregistrationLockups(),
this.getValidatorLockedGoldRequirements(),
this.getGroupLockedGoldRequirements(),
this.contract.methods.maxGroupSize().call(),
])
return {
balanceRequirements: res[0],
deregistrationLockups: res[1],
validatorLockedGoldRequirements: res[0],
groupLockedGoldRequirements: res[1],
maxGroupSize: toBigNumber(res[2]),
}
}
Expand Down
22 changes: 22 additions & 0 deletions packages/protocol/contracts/common/UsingPrecompiles.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pragma solidity ^0.5.3;

// TODO(asa): Limit assembly usage by using X.staticcall instead.
contract UsingPrecompiles {
address constant PROOF_OF_POSSESSION = address(0xff - 4);

/**
* @notice calculate a * b^x for fractions a, b to `decimals` precision
Expand Down Expand Up @@ -122,4 +124,24 @@ contract UsingPrecompiles {

return numberValidators;
}

/**
* @notice Checks a BLS proof of possession.
* @param proofOfPossessionBytes The public key and signature of the proof of possession.
* @return True upon success.
*/
function checkProofOfPossession(
address sender,
bytes memory proofOfPossessionBytes
)
private
returns (bool)
{
bool success;
(success, ) = PROOF_OF_POSSESSION
.call
.value(0)
.gas(gasleft())(abi.encodePacked(sender, proofOfPossessionBytes));
return success;
}
}
5 changes: 5 additions & 0 deletions packages/protocol/contracts/common/UsingRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "./interfaces/IERC20Token.sol";
import "./interfaces/IRegistry.sol";

import "../governance/interfaces/IElection.sol";
import "../governance/interfaces/IGovernance.sol";
import "../governance/interfaces/ILockedGold.sol";
import "../governance/interfaces/IValidators.sol";

Expand Down Expand Up @@ -63,6 +64,10 @@ contract UsingRegistry is Ownable {
return IERC20Token(registry.getAddressForOrDie(GOLD_TOKEN_REGISTRY_ID));
}

function getGovernance() internal view returns (IGovernance) {
return IGovernance(registry.getAddressForOrDie(GOVERNANCE_REGISTRY_ID));
}

function getLockedGold() internal view returns (ILockedGold) {
return ILockedGold(registry.getAddressForOrDie(LOCKED_GOLD_REGISTRY_ID));
}
Expand Down
56 changes: 11 additions & 45 deletions packages/protocol/contracts/governance/Election.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ contract Election is
uint256 public maxNumGroupsVotedFor;
// Groups must receive at least this fraction of the total votes in order to be considered in
// elections.
// TODO(asa): Implement this constraint.
FixidityLib.Fraction public electabilityThreshold;

event ElectableValidatorsSet(
Expand Down Expand Up @@ -151,9 +150,9 @@ contract Election is
{
_transferOwnership(msg.sender);
setRegistry(registryAddress);
_setElectableValidators(minElectableValidators, maxElectableValidators);
_setMaxNumGroupsVotedFor(_maxNumGroupsVotedFor);
_setElectabilityThreshold(_electabilityThreshold);
setElectableValidators(minElectableValidators, maxElectableValidators);
setMaxNumGroupsVotedFor(_maxNumGroupsVotedFor);
setElectabilityThreshold(_electabilityThreshold);
}

/**
Expand All @@ -162,8 +161,12 @@ contract Election is
* @param max The maximum number of validators that can be elected.
* @return True upon success.
*/
function setElectableValidators(uint256 min, uint256 max) external onlyOwner returns (bool) {
return _setElectableValidators(min, max);
function setElectableValidators(uint256 min, uint256 max) public onlyOwner returns (bool) {
require(0 < min && min <= max);
require(min != electableValidators.min || max != electableValidators.max);
electableValidators = ElectableValidators(min, max);
emit ElectableValidatorsSet(min, max);
return true;
}

/**
Expand All @@ -174,20 +177,6 @@ contract Election is
return (electableValidators.min, electableValidators.max);
}

/**
* @notice Updates the minimum and maximum number of validators that can be elected.
* @param min The minimum number of validators that can be elected.
* @param max The maximum number of validators that can be elected.
* @return True upon success.
*/
function _setElectableValidators(uint256 min, uint256 max) private returns (bool) {
require(0 < min && min <= max);
require(min != electableValidators.min || max != electableValidators.max);
electableValidators = ElectableValidators(min, max);
emit ElectableValidatorsSet(min, max);
return true;
}

/**
* @notice Updates the maximum number of groups an account can be voting for at once.
* @param _maxNumGroupsVotedFor The maximum number of groups an account can vote for.
Expand All @@ -196,19 +185,10 @@ contract Election is
function setMaxNumGroupsVotedFor(
uint256 _maxNumGroupsVotedFor
)
external
public
onlyOwner
returns (bool)
{
return _setMaxNumGroupsVotedFor(_maxNumGroupsVotedFor);
}

/**
* @notice Updates the maximum number of groups an account can be voting for at once.
* @param _maxNumGroupsVotedFor The maximum number of groups an account can vote for.
* @return True upon success.
*/
function _setMaxNumGroupsVotedFor(uint256 _maxNumGroupsVotedFor) private returns (bool) {
require(_maxNumGroupsVotedFor != maxNumGroupsVotedFor);
maxNumGroupsVotedFor = _maxNumGroupsVotedFor;
emit MaxNumGroupsVotedForSet(_maxNumGroupsVotedFor);
Expand All @@ -221,15 +201,6 @@ contract Election is
* @return True upon success.
*/
function setElectabilityThreshold(uint256 threshold) public onlyOwner returns (bool) {
return _setElectabilityThreshold(threshold);
}

/**
* @notice Sets the electability threshold.
* @param threshold Electability threshold as unwrapped Fraction.
* @return True upon success.
*/
function _setElectabilityThreshold(uint256 threshold) private returns (bool) {
electabilityThreshold = FixidityLib.wrap(threshold);
require(
electabilityThreshold.lt(FixidityLib.fixed1()),
Expand Down Expand Up @@ -486,12 +457,7 @@ contract Election is
{
// The group must meet the balance requirements in order for their voters to receive epoch
// rewards.
bool meetsBalanceRequirements = (
getLockedGold().getAccountTotalLockedGold(group) >=
getValidators().getAccountBalanceRequirement(group)
);

if (meetsBalanceRequirements && votes.active.total > 0) {
if (getValidators().meetsAccountLockedGoldRequirements(group) && votes.active.total > 0) {
return totalEpochRewards.mul(votes.active.forGroup[group].total).div(votes.active.total);
} else {
return 0;
Expand Down
16 changes: 16 additions & 0 deletions packages/protocol/contracts/governance/Governance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,22 @@ contract Governance is IGovernance, Ownable, Initializable, ReentrancyGuard, Usi
);
}

/**
* @notice Returns whether or not a particular account is voting on proposals.
* @param account The address of the account.
* @return Whether or not the account is voting on proposals.
*/
function isVoting(address account) external view returns (bool) {
Voter storage voter = voters[account];
uint256 upvotedProposal = voter.upvote.proposalId;
bool isVotingQueue = upvotedProposal != 0 && isQueued(upvotedProposal);
Proposals.Proposal storage proposal = proposals[voter.mostRecentReferendumProposal];
bool isVotingReferendum = (
proposal.getDequeuedStage(stageDurations) == Proposals.Stage.Referendum
);
return isVotingQueue || isVotingReferendum;
}

/**
* @notice Returns the number of seconds proposals stay in the approval stage.
* @return The number of seconds proposals stay in the execution stage.
Expand Down
5 changes: 4 additions & 1 deletion packages/protocol/contracts/governance/LockedGold.sol
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,10 @@ contract LockedGold is ILockedGold, ReentrancyGuard, Initializable, UsingRegistr
function unlock(uint256 value) external nonReentrant {
require(isAccount(msg.sender));
Account storage account = accounts[msg.sender];
uint256 balanceRequirement = getValidators().getAccountBalanceRequirement(msg.sender);
// Prevent unlocking gold when voting on governance proposals so that the gold cannot be
// used to vote more than once.
require(!getGovernance().isVoting(msg.sender));
uint256 balanceRequirement = getValidators().getAccountLockedGoldRequirement(msg.sender);
require(
balanceRequirement == 0 ||
balanceRequirement <= getAccountTotalLockedGold(msg.sender).sub(value)
Expand Down
Loading