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

BREAKING_CHANGE: refactor repo #138

Open
wants to merge 28 commits into
base: release/v0.8.2
Choose a base branch
from
Open

Conversation

TuDo1403
Copy link
Collaborator

@TuDo1403 TuDo1403 commented Oct 18, 2024

Description

Contract changes

The table below shows the following info:

  • Logic: the logic is changed.
  • ABI: the ABI is changed.
  • Init data: new storage field is declared and needs initializing.
  • Dependent: needs to be changed due to changes in other contracts.
Contract name Logic ABI Init data Dependent
FastFinalityTracking
GovernanceAdmin
Maintenance
Profile
SlashIndicator
Staking
StakingVesting
ValidatorSet

Checklist

  • I have chosen the base of the PR to the release/** branch.
  • I have named the PR following the format of [contract_name] what_is_changed, where contract_name is the list of changed contracts, separated by |, or is * if there is changed in more than 3 contracts
  • I have ticked in the Contract changes table to guide the deployer which contracts to be upgraded.
  • I have clearly commented on all the main functions following the NatSpec Format
  • The box that allows repo maintainers to update this PR is checked
  • I tested locally to make sure this feature/fix works

@TuDo1403 TuDo1403 changed the title Feature/refactor BREAKING_CHANGE: refactor repo Oct 21, 2024
@TuDo1403 TuDo1403 force-pushed the feature/refactor branch 3 times, most recently from 6058231 to b2e7abf Compare October 22, 2024 04:55
Copy link

github-actions bot commented Oct 22, 2024

Slither report

THIS CHECKLIST IS NOT COMPLETE. Use --show-ignored-findings to show all the results.
Summary

reentrancy-eth

Impact: High
Confidence: Medium

function wrapUpEpoch() external payable virtual override onlyCoinbase whenEpochEnding oncePerEpoch {
unchecked {
uint256 newPeriod = _computePeriod(block.timestamp);
bool periodEnding = _isPeriodEnding(newPeriod);
uint256 lastPeriod = currentPeriod();
uint256 epoch = epochOf(block.number);
uint256 nextEpoch = epoch + 1;
IRandomBeacon randomBeacon = IRandomBeacon(getContract(ContractType.RANDOM_BEACON));
// This request is actually only invoked at the first epoch of the period.
randomBeacon.execRequestRandomSeedForNextPeriod(lastPeriod, newPeriod);
// Get all candidate ids
address[] memory allCids = _candidateIds;
_syncFastFinalityReward({ epoch: epoch, validatorIds: allCids });
if (periodEnding) {
ISlashIndicator slashIndicatorContract = ISlashIndicator(getContract(ContractType.SLASH_INDICATOR));
// Slash submit random beacon proof unavailability first, then update credit scores.
randomBeacon.execRecordAndSlashUnavailability(lastPeriod, newPeriod, address(slashIndicatorContract), allCids);
slashIndicatorContract.execUpdateCreditScores(allCids, lastPeriod);
(uint256[] memory delegatorBlockMiningRewards, uint256[] memory delegatorFastFinalityRewards) =
_distributeRewardToTreasuriesAndCalculateTotalDelegatorsReward(lastPeriod, allCids);
_settleAndTransferDelegatingRewards(
lastPeriod, allCids, delegatorBlockMiningRewards, delegatorFastFinalityRewards
);
_tryRecycleLockedFundsFromEmergencyExits();
_recycleDeprecatedRewards();
address[] memory revokedCandidateIds = _syncCandidateSet(newPeriod);
if (revokedCandidateIds.length > 0) {
// Re-update `allCids` after unsatisfied candidates get removed.
allCids = _candidateIds;
slashIndicatorContract.execResetCreditScores(revokedCandidateIds);
}
// Wrap up the beacon period includes (1) finalizing the beacon proof, and (2) determining the validator list for the next period by new proof.
// Should wrap up the beacon after unsatisfied candidates get removed.
randomBeacon.execFinalizeBeaconAndPendingCids(lastPeriod, newPeriod, allCids);
_periodEndBlock[lastPeriod] = block.number;
_currentPeriodStartAtBlock = block.number + 1;
}
// Clear the previous validator set and block producer set before sync the new set from beacon.
_clearPreviousValidatorSetAndBlockProducerSet();
// Query the new validator set for upcoming epoch from the random beacon contract.
// Save new set into the contract storage.
address[] memory newValidatorIds = _syncValidatorSet(randomBeacon, newPeriod, nextEpoch);
// Activate applicable validators into the block producer set.
_updateApplicableValidatorToBlockProducerSet(newPeriod, nextEpoch, newValidatorIds);
emit WrappedUpEpoch(lastPeriod, epoch, periodEnding);
_periodOf[nextEpoch] = newPeriod;
_lastUpdatedPeriod = newPeriod;
}
}

function _distributeRewardToTreasuriesAndCalculateTotalDelegatorsReward(
uint256 lastPeriod,
address[] memory cids
) private returns (uint256[] memory delegatorBlockMiningRewards, uint256[] memory delegatorFastFinalityRewards) {
address vId; // validator id
address payable treasury;
uint256 length = cids.length;
delegatorBlockMiningRewards = new uint256[](length);
delegatorFastFinalityRewards = new uint256[](length);
(uint256 minRate, uint256 maxRate) = IStaking(getContract(ContractType.STAKING)).getCommissionRateRange();
for (uint256 i; i < length; ++i) {
vId = cids[i];
treasury = _candidateInfo[vId].__shadowedTreasury;
if (!_isJailedById(vId) && !_miningRewardDeprecatedById(vId, lastPeriod)) {
(uint256 validatorFFReward, uint256 delegatorFFReward) = _calcCommissionReward({
vId: vId,
totalReward: _fastFinalityReward[vId],
maxCommissionRate: maxRate,
minCommissionRate: minRate
});
delegatorBlockMiningRewards[i] = _delegatorMiningReward[vId];
delegatorFastFinalityRewards[i] = delegatorFFReward;
_distributeMiningReward(vId, treasury);
_distributeFastFinalityReward(vId, treasury, validatorFFReward);
} else {
_totalDeprecatedReward += _validatorMiningReward[vId] + _delegatorMiningReward[vId] + _fastFinalityReward[vId];
}
delete _delegatorMiningReward[vId];
delete _validatorMiningReward[vId];
delete _fastFinalityReward[vId];
}
}

function wrapUpEpoch() external payable virtual override onlyCoinbase whenEpochEnding oncePerEpoch {
unchecked {
uint256 newPeriod = _computePeriod(block.timestamp);
bool periodEnding = _isPeriodEnding(newPeriod);
uint256 lastPeriod = currentPeriod();
uint256 epoch = epochOf(block.number);
uint256 nextEpoch = epoch + 1;
IRandomBeacon randomBeacon = IRandomBeacon(getContract(ContractType.RANDOM_BEACON));
// This request is actually only invoked at the first epoch of the period.
randomBeacon.execRequestRandomSeedForNextPeriod(lastPeriod, newPeriod);
// Get all candidate ids
address[] memory allCids = _candidateIds;
_syncFastFinalityReward({ epoch: epoch, validatorIds: allCids });
if (periodEnding) {
ISlashIndicator slashIndicatorContract = ISlashIndicator(getContract(ContractType.SLASH_INDICATOR));
// Slash submit random beacon proof unavailability first, then update credit scores.
randomBeacon.execRecordAndSlashUnavailability(lastPeriod, newPeriod, address(slashIndicatorContract), allCids);
slashIndicatorContract.execUpdateCreditScores(allCids, lastPeriod);
(uint256[] memory delegatorBlockMiningRewards, uint256[] memory delegatorFastFinalityRewards) =
_distributeRewardToTreasuriesAndCalculateTotalDelegatorsReward(lastPeriod, allCids);
_settleAndTransferDelegatingRewards(
lastPeriod, allCids, delegatorBlockMiningRewards, delegatorFastFinalityRewards
);
_tryRecycleLockedFundsFromEmergencyExits();
_recycleDeprecatedRewards();
address[] memory revokedCandidateIds = _syncCandidateSet(newPeriod);
if (revokedCandidateIds.length > 0) {
// Re-update `allCids` after unsatisfied candidates get removed.
allCids = _candidateIds;
slashIndicatorContract.execResetCreditScores(revokedCandidateIds);
}
// Wrap up the beacon period includes (1) finalizing the beacon proof, and (2) determining the validator list for the next period by new proof.
// Should wrap up the beacon after unsatisfied candidates get removed.
randomBeacon.execFinalizeBeaconAndPendingCids(lastPeriod, newPeriod, allCids);
_periodEndBlock[lastPeriod] = block.number;
_currentPeriodStartAtBlock = block.number + 1;
}
// Clear the previous validator set and block producer set before sync the new set from beacon.
_clearPreviousValidatorSetAndBlockProducerSet();
// Query the new validator set for upcoming epoch from the random beacon contract.
// Save new set into the contract storage.
address[] memory newValidatorIds = _syncValidatorSet(randomBeacon, newPeriod, nextEpoch);
// Activate applicable validators into the block producer set.
_updateApplicableValidatorToBlockProducerSet(newPeriod, nextEpoch, newValidatorIds);
emit WrappedUpEpoch(lastPeriod, epoch, periodEnding);
_periodOf[nextEpoch] = newPeriod;
_lastUpdatedPeriod = newPeriod;
}
}

function wrapUpEpoch() external payable virtual override onlyCoinbase whenEpochEnding oncePerEpoch {
unchecked {
uint256 newPeriod = _computePeriod(block.timestamp);
bool periodEnding = _isPeriodEnding(newPeriod);
uint256 lastPeriod = currentPeriod();
uint256 epoch = epochOf(block.number);
uint256 nextEpoch = epoch + 1;
IRandomBeacon randomBeacon = IRandomBeacon(getContract(ContractType.RANDOM_BEACON));
// This request is actually only invoked at the first epoch of the period.
randomBeacon.execRequestRandomSeedForNextPeriod(lastPeriod, newPeriod);
// Get all candidate ids
address[] memory allCids = _candidateIds;
_syncFastFinalityReward({ epoch: epoch, validatorIds: allCids });
if (periodEnding) {
ISlashIndicator slashIndicatorContract = ISlashIndicator(getContract(ContractType.SLASH_INDICATOR));
// Slash submit random beacon proof unavailability first, then update credit scores.
randomBeacon.execRecordAndSlashUnavailability(lastPeriod, newPeriod, address(slashIndicatorContract), allCids);
slashIndicatorContract.execUpdateCreditScores(allCids, lastPeriod);
(uint256[] memory delegatorBlockMiningRewards, uint256[] memory delegatorFastFinalityRewards) =
_distributeRewardToTreasuriesAndCalculateTotalDelegatorsReward(lastPeriod, allCids);
_settleAndTransferDelegatingRewards(
lastPeriod, allCids, delegatorBlockMiningRewards, delegatorFastFinalityRewards
);
_tryRecycleLockedFundsFromEmergencyExits();
_recycleDeprecatedRewards();
address[] memory revokedCandidateIds = _syncCandidateSet(newPeriod);
if (revokedCandidateIds.length > 0) {
// Re-update `allCids` after unsatisfied candidates get removed.
allCids = _candidateIds;
slashIndicatorContract.execResetCreditScores(revokedCandidateIds);
}
// Wrap up the beacon period includes (1) finalizing the beacon proof, and (2) determining the validator list for the next period by new proof.
// Should wrap up the beacon after unsatisfied candidates get removed.
randomBeacon.execFinalizeBeaconAndPendingCids(lastPeriod, newPeriod, allCids);
_periodEndBlock[lastPeriod] = block.number;
_currentPeriodStartAtBlock = block.number + 1;
}
// Clear the previous validator set and block producer set before sync the new set from beacon.
_clearPreviousValidatorSetAndBlockProducerSet();
// Query the new validator set for upcoming epoch from the random beacon contract.
// Save new set into the contract storage.
address[] memory newValidatorIds = _syncValidatorSet(randomBeacon, newPeriod, nextEpoch);
// Activate applicable validators into the block producer set.
_updateApplicableValidatorToBlockProducerSet(newPeriod, nextEpoch, newValidatorIds);
emit WrappedUpEpoch(lastPeriod, epoch, periodEnding);
_periodOf[nextEpoch] = newPeriod;
_lastUpdatedPeriod = newPeriod;
}
}

function wrapUpEpoch() external payable virtual override onlyCoinbase whenEpochEnding oncePerEpoch {
unchecked {
uint256 newPeriod = _computePeriod(block.timestamp);
bool periodEnding = _isPeriodEnding(newPeriod);
uint256 lastPeriod = currentPeriod();
uint256 epoch = epochOf(block.number);
uint256 nextEpoch = epoch + 1;
IRandomBeacon randomBeacon = IRandomBeacon(getContract(ContractType.RANDOM_BEACON));
// This request is actually only invoked at the first epoch of the period.
randomBeacon.execRequestRandomSeedForNextPeriod(lastPeriod, newPeriod);
// Get all candidate ids
address[] memory allCids = _candidateIds;
_syncFastFinalityReward({ epoch: epoch, validatorIds: allCids });
if (periodEnding) {
ISlashIndicator slashIndicatorContract = ISlashIndicator(getContract(ContractType.SLASH_INDICATOR));
// Slash submit random beacon proof unavailability first, then update credit scores.
randomBeacon.execRecordAndSlashUnavailability(lastPeriod, newPeriod, address(slashIndicatorContract), allCids);
slashIndicatorContract.execUpdateCreditScores(allCids, lastPeriod);
(uint256[] memory delegatorBlockMiningRewards, uint256[] memory delegatorFastFinalityRewards) =
_distributeRewardToTreasuriesAndCalculateTotalDelegatorsReward(lastPeriod, allCids);
_settleAndTransferDelegatingRewards(
lastPeriod, allCids, delegatorBlockMiningRewards, delegatorFastFinalityRewards
);
_tryRecycleLockedFundsFromEmergencyExits();
_recycleDeprecatedRewards();
address[] memory revokedCandidateIds = _syncCandidateSet(newPeriod);
if (revokedCandidateIds.length > 0) {
// Re-update `allCids` after unsatisfied candidates get removed.
allCids = _candidateIds;
slashIndicatorContract.execResetCreditScores(revokedCandidateIds);
}
// Wrap up the beacon period includes (1) finalizing the beacon proof, and (2) determining the validator list for the next period by new proof.
// Should wrap up the beacon after unsatisfied candidates get removed.
randomBeacon.execFinalizeBeaconAndPendingCids(lastPeriod, newPeriod, allCids);
_periodEndBlock[lastPeriod] = block.number;
_currentPeriodStartAtBlock = block.number + 1;
}
// Clear the previous validator set and block producer set before sync the new set from beacon.
_clearPreviousValidatorSetAndBlockProducerSet();
// Query the new validator set for upcoming epoch from the random beacon contract.
// Save new set into the contract storage.
address[] memory newValidatorIds = _syncValidatorSet(randomBeacon, newPeriod, nextEpoch);
// Activate applicable validators into the block producer set.
_updateApplicableValidatorToBlockProducerSet(newPeriod, nextEpoch, newValidatorIds);
emit WrappedUpEpoch(lastPeriod, epoch, periodEnding);
_periodOf[nextEpoch] = newPeriod;
_lastUpdatedPeriod = newPeriod;
}
}

function execDeprecatePools(
address[] calldata poolIds,
uint256 newPeriod
) external override onlyContract(ContractType.VALIDATOR) {
if (poolIds.length == 0) {
return;
}
for (uint256 i = 0; i < poolIds.length;) {
address poolId = poolIds[i];
PoolDetail storage _pool = _poolDetail[poolId];
// Deactivate the pool admin in the active mapping.
delete _adminOfActivePoolMapping[_pool.__shadowedPoolAdmin];
// Deduct and transfer the self staking amount to the pool admin.
uint256 deductingAmount = _pool.stakingAmount;
if (deductingAmount > 0) {
_deductStakingAmount(_pool, deductingAmount);
if (!_unsafeSendRONLimitGas(payable(_pool.__shadowedPoolAdmin), deductingAmount, DEFAULT_ADDITION_GAS)) {
emit StakingAmountTransferFailed(_pool.pid, _pool.__shadowedPoolAdmin, deductingAmount, address(this).balance);
}
}
// Settle the unclaimed reward and transfer to the pool admin.
uint256 lastRewardAmount = _claimReward(poolId, _pool.__shadowedPoolAdmin, newPeriod);
if (lastRewardAmount > 0) {
_unsafeSendRONLimitGas(payable(_pool.__shadowedPoolAdmin), lastRewardAmount, DEFAULT_ADDITION_GAS);
}
unchecked {
++i;
}
}
emit PoolsDeprecated(poolIds);
}

shadowing-state

Impact: High
Confidence: High

uint256[49] private ______gap;

uint256[50] private ______gap;

uninitialized-state

Impact: High
Confidence: High

uint256 internal _firstTrackedPeriodEnd;

uint256 internal _numberOfBlocksInEpoch;

mapping(uint256 epoch => uint256 period) internal _periodOf;

mapping(address => Schedule) internal _schedule;

mapping(address => mapping(uint256 => bool)) internal _miningRewardDeprecatedAtPeriod;

uint256 internal _lastUpdatedPeriod;

mapping(address => uint256) internal _blockProducerJailedBlock;

mapping(address cid => bool isBlockProducer) internal _validatorMap;

mapping(uint256 period => uint256 endedAtBlock) internal _periodEndBlock;

mapping(uint256 idx => address cid) internal _validatorIds;

uint256 internal _currentPeriodStartAtBlock;

@TuDo1403 TuDo1403 force-pushed the feature/refactor branch 2 times, most recently from 454631d to fe14020 Compare October 22, 2024 11:40
Copy link
Collaborator

@huyhuynh3103 huyhuynh3103 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants