Skip to content

Commit

Permalink
Merge branch 'feat/l2-epoch-system' into m-chrzan/reset-pending-payment
Browse files Browse the repository at this point in the history
  • Loading branch information
m-chrzan authored Sep 18, 2024
2 parents a5e0c77 + cfe3b30 commit df63497
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 19 deletions.
8 changes: 6 additions & 2 deletions packages/protocol/contracts-0.8/common/EpochManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ contract EpochManager is
epochProcessing.toProcessGroups++;
uint256 groupScore = getScoreReader().getGroupScore(group);
// We need to precompute epoch rewards for each group since computation depends on total active votes for all groups.
uint256 epochRewards = getElection().getGroupEpochRewards(
uint256 epochRewards = getElection().getGroupEpochRewardsBasedOnScore(
group,
epochProcessing.totalRewardsVoter,
groupScore
Expand All @@ -229,7 +229,7 @@ contract EpochManager is
greaters[i]
);

// by doing this, we avoid processing a group twice
epochProcessing.toProcessGroups = 0;
delete processedGroups[groups[i]];
}
getCeloUnreleasedTreasure().release(
Expand Down Expand Up @@ -340,6 +340,10 @@ contract EpochManager is
validatorPendingPayments[elected[i]] += validatorReward;
totalRewards += validatorReward;
}
if (totalRewards == 0) {
return;
}

// Mint all cUSD required for payment and the corresponding CELO
validators.mintStableToEpochManager(totalRewards);
// this should have a setter for the oracle.
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/contracts-0.8/governance/Validators.sol
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ contract Validators is
* @dev Fails if the account is already a validator or validator group.
* @dev Fails if the account does not have sufficient Locked Gold.
*/
function registerValidator(
function registerValidatorNoBls(
bytes calldata ecdsaPublicKey
) external nonReentrant onlyL2 returns (bool) {
address account = getAccounts().validatorSignerToAccount(msg.sender);
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/contracts/governance/Election.sol
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ contract Election is
* @return The amount of rewards that voters for `group` are due at the end of an epoch.
* @dev Eligible groups that have received their maximum number of votes cannot receive more.
*/
function getGroupEpochRewards(
function getGroupEpochRewardsBasedOnScore(
address group,
uint256 totalEpochRewards,
uint256 groupScore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ interface IElection {
uint256,
uint256[] calldata
) external view returns (uint256);
function getGroupEpochRewards(
function getGroupEpochRewardsBasedOnScore(
address group,
uint256 totalEpochRewards,
uint256 groupScore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface IValidators {
bytes calldata,
bytes calldata
) external returns (bool);
function registerValidator(bytes calldata ecdsaPublicKey) external returns (bool);
function registerValidatorNoBls(bytes calldata ecdsaPublicKey) external returns (bool);
function deregisterValidator(uint256) external returns (bool);
function affiliate(address) external returns (bool);
function deaffiliate() external returns (bool);
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/scripts/foundry/constants.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export CARBON_OFFSETTING_FRACTION="10000000000000000000" # 0.001 in fixidity for
export REGISTRY_STORAGE_LOCATION="0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103" # Position is bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1);
GOLD_TOKEN_CELO_SUPPLY_CAP=1000000000 # `GoldToken.CELO_SUPPLY_CAP()`
GOLD_TOKEN_TOTAL_SUPPLY=700000000 # Arbitrary amount chosen to be approximately equal to `GoldToken.totalSupply()` on the L1 Mainnet (695,313,643 CELO as of this commit).
export CELO_DISTRIBUTION_SCHEDULE_INITIAL_BALANCE="$(($GOLD_TOKEN_CELO_SUPPLY_CAP - $GOLD_TOKEN_TOTAL_SUPPLY))" # During the real L2 genesis, the VM will calculate and set an appropriate balance.
export CELO_UNRELEASED_TREASURE_INITIAL_BALANCE="$(($GOLD_TOKEN_CELO_SUPPLY_CAP - $GOLD_TOKEN_TOTAL_SUPPLY))" # During the real L2 genesis, the VM will calculate and set an appropriate balance.

# Contract libraries
export LIBRARIES_PATH=("contracts/common/linkedlists/AddressSortedLinkedListWithMedian.sol:AddressSortedLinkedListWithMedian"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ cast rpc anvil_setCode \
--rpc-url $ANVIL_RPC_URL

# Fetch address of Celo distribution
CELO_DISTRIBUTION_SCHEDULE_ADDRESS=$(
CELO_UNRELEASED_TREASURE_ADDRESS=$(
cast call \
$REGISTRY_ADDRESS \
"getAddressForStringOrDie(string calldata identifier)(address)" \
Expand All @@ -31,9 +31,10 @@ CELO_DISTRIBUTION_SCHEDULE_ADDRESS=$(
# implement the receive function nor does it allow ERC20 transfers. This is the only way I
# managed to give the CeloUnreleasedTreasure a balance.
echo "Setting CeloUnreleasedTreasure balance..."
HEX_CELO_UNRELEASED_TREASURE_INITIAL_BALANCE=$(cast to-hex $CELO_UNRELEASED_TREASURE_INITIAL_BALANCE"000000000000000000")
cast rpc \
anvil_setBalance \
$CELO_DISTRIBUTION_SCHEDULE_ADDRESS $CELO_DISTRIBUTION_SCHEDULE_INITIAL_BALANCE \
$CELO_UNRELEASED_TREASURE_ADDRESS $HEX_CELO_UNRELEASED_TREASURE_INITIAL_BALANCE \
--rpc-url $ANVIL_RPC_URL

# Run L2 migrations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,11 @@ contract E2E_EpochManager_FinishNextEpochProcess is E2E_EpochManager {
groupWithVotes[i] = GroupWithVotes(
groupsEligible[i],
values[i] +
election.getGroupEpochRewards(groupsEligible[i], totalRewardsVote, groupScore[i])
election.getGroupEpochRewardsBasedOnScore(
groupsEligible[i],
totalRewardsVote,
groupScore[i]
)
);
}

Expand Down Expand Up @@ -275,8 +279,23 @@ contract E2E_EpochManager_FinishNextEpochProcess is E2E_EpochManager {
assertEq(election.getActiveVotesForGroup(groupsEligible[i]), groupWithVotes[i].votes);
assertGt(election.getActiveVotesForGroup(groupsEligible[i]), groupActiveBalances[i]);
}

timeTravel(vm, epochDuration + 1);
epochManager.startNextEpochProcess();
epochManager.finishNextEpochProcess(groups, lessers, greaters);

assertEq(currentEpoch + 2, epochManager.getCurrentEpochNumber());

address[] memory newlyElected2 = epochManager.getElected();

for (uint256 i = 0; i < currentlyElected.length; i++) {
assertEq(originalyElected.contains(newlyElected2[i]), true);
}
}

// TODO: add test when new groups are elected
// TODO: add test when groups are removed

// Bubble sort algorithm since it is a small array
function sort(GroupWithVotes[] memory items) public {
uint length = items.length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ contract ValidatorsTest is Test, TestConstants, Utils, ECDSAHelper {
accounts.authorizeValidatorSigner(signer, v, r, s);

vm.prank(validator);
validators.registerValidator(_ecdsaPubKey);
validators.registerValidatorNoBls(_ecdsaPubKey);
validatorRegistrationEpochNumber = epochManager.getCurrentEpochNumber();
return _ecdsaPubKey;
}
Expand Down Expand Up @@ -859,7 +859,7 @@ contract ValidatorsTest_RegisterValidator_NoBls is ValidatorsTest {

vm.expectRevert("Cannot vote for more than max number of groups");
vm.prank(validator);
validators.registerValidator(pubKey);
validators.registerValidatorNoBls(pubKey);
}

function test_Reverts_WhenDelagatingCELO() public {
Expand All @@ -872,7 +872,7 @@ contract ValidatorsTest_RegisterValidator_NoBls is ValidatorsTest {

vm.expectRevert("Cannot delegate governance power");
vm.prank(validator);
validators.registerValidator(pubKey);
validators.registerValidatorNoBls(pubKey);
}

function test_ShouldMarkAccountAsValidator_WhenAccountHasAuthorizedValidatorSigner() public {
Expand All @@ -897,7 +897,7 @@ contract ValidatorsTest_RegisterValidator_NoBls is ValidatorsTest {

vm.expectRevert("This method is not supported in L1.");
vm.prank(validator);
validators.registerValidator(_ecdsaPubKey);
validators.registerValidatorNoBls(_ecdsaPubKey);
validatorRegistrationEpochNumber = IPrecompiles(address(validators)).getEpochNumber();
}

Expand Down Expand Up @@ -973,7 +973,7 @@ contract ValidatorsTest_RegisterValidator_NoBls is ValidatorsTest {
emit ValidatorBlsPublicKeyUpdated(validator, blsPublicKey);

vm.prank(validator);
validators.registerValidator(_ecdsaPubKey);
validators.registerValidatorNoBls(_ecdsaPubKey);
}

function test_Emits_ValidatorRegisteredEvent() public {
Expand All @@ -990,23 +990,23 @@ contract ValidatorsTest_RegisterValidator_NoBls is ValidatorsTest {
emit ValidatorRegistered(validator);

vm.prank(validator);
validators.registerValidator(_ecdsaPubKey);
validators.registerValidatorNoBls(_ecdsaPubKey);
}

function test_Reverts_WhenAccountAlreadyRegisteredAsValidator() public {
_whenL2();
bytes memory _registeredEcdsaPubKey = _registerValidatorWithSignerHelper_noBls();
vm.prank(validator);
vm.expectRevert("Already registered");
validators.registerValidator(_registeredEcdsaPubKey);
validators.registerValidatorNoBls(_registeredEcdsaPubKey);
}

function test_Reverts_WhenAccountAlreadyRegisteredAsValidatorGroup() public {
_whenL2();
_registerValidatorGroupHelper(validator, 1);
vm.prank(validator);
vm.expectRevert("Already registered");
validators.registerValidator(
validators.registerValidatorNoBls(
abi.encodePacked(bytes32(0x0101010101010101010101010101010101010101010101010101010101010101))
);
}
Expand All @@ -1019,7 +1019,7 @@ contract ValidatorsTest_RegisterValidator_NoBls is ValidatorsTest {
);
vm.expectRevert("Deposit too small");
vm.prank(validator);
validators.registerValidator(
validators.registerValidatorNoBls(
abi.encodePacked(bytes32(0x0101010101010101010101010101010101010101010101010101010101010101))
);
}
Expand Down

0 comments on commit df63497

Please sign in to comment.