@@ -7,6 +7,7 @@ import {Decimal} from "../common/Decimal.sol";
77import {NodeDriverAuth} from "./NodeDriverAuth.sol " ;
88import {ConstantsManager} from "./ConstantsManager.sol " ;
99import {Version} from "../version/Version.sol " ;
10+ import {IStakeSubscriber} from "../interfaces/IStakeSubscriber.sol " ;
1011
1112/**
1213 * @title Special Fee Contract for Sonic network
@@ -84,17 +85,17 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
8485
8586 struct EpochSnapshot {
8687 // validator ID => validator weight in the epoch
87- mapping (uint256 => uint256 ) receivedStake;
88+ mapping (uint256 validatorID = > uint256 ) receivedStake;
8889 // validator ID => accumulated ( delegatorsReward * 1e18 / receivedStake )
89- mapping (uint256 => uint256 ) accumulatedRewardPerToken;
90+ mapping (uint256 validatorID = > uint256 ) accumulatedRewardPerToken;
9091 // validator ID => accumulated online time
91- mapping (uint256 => uint256 ) accumulatedUptime;
92+ mapping (uint256 validatorID = > uint256 ) accumulatedUptime;
9293 // validator ID => average uptime as a percentage
93- mapping (uint256 => AverageUptime) averageUptime;
94+ mapping (uint256 validatorID = > AverageUptime) averageUptime;
9495 // validator ID => gas fees from txs originated by the validator
95- mapping (uint256 => uint256 ) accumulatedOriginatedTxsFee;
96- mapping (uint256 => uint256 ) offlineTime;
97- mapping (uint256 => uint256 ) offlineBlocks;
96+ mapping (uint256 validatorID = > uint256 ) accumulatedOriginatedTxsFee;
97+ mapping (uint256 validatorID = > uint256 ) offlineTime;
98+ mapping (uint256 validatorID = > uint256 ) offlineBlocks;
9899 uint256 [] validatorIDs;
99100 uint256 endTime;
100101 uint256 endBlock;
@@ -224,7 +225,7 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
224225 event TreasuryFeesResolved (uint256 amount );
225226
226227 modifier onlyDriver () {
227- if (! isNode (msg .sender )) {
228+ if (! _isNode (msg .sender )) {
228229 revert NotDriverAuth ();
229230 }
230231 _;
@@ -293,7 +294,7 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
293294 }
294295
295296 /// Accept redirection proposal.
296- /// Redirection must by accepted by the validator key holder before it start to be applied.
297+ /// Redirection must by accepted by the validator key holder before it starts to be applied.
297298 function redirect (address to ) external {
298299 address from = msg .sender ;
299300 if (to == address (0 )) {
@@ -605,6 +606,11 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
605606 return getEpochSnapshot[epoch].endBlock;
606607 }
607608
609+ /// Get epoch end time.
610+ function epochEndTime (uint256 epoch ) public view returns (uint256 ) {
611+ return getEpochSnapshot[epoch].endTime;
612+ }
613+
608614 /// Check whether the given validator is slashed - the stake (or its part) cannot
609615 /// be withdrawn because of misbehavior (double-sign) of the validator.
610616 function isSlashed (uint256 validatorID ) public view returns (bool ) {
@@ -625,7 +631,7 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
625631 }
626632
627633 /// Check if an address is the NodeDriverAuth contract.
628- function isNode (address addr ) internal view virtual returns (bool ) {
634+ function _isNode (address addr ) internal view virtual returns (bool ) {
629635 return addr == address (node);
630636 }
631637
@@ -702,7 +708,7 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
702708 }
703709
704710 /// Get slashing penalty for a stake.
705- function getSlashingPenalty (
711+ function _getSlashingPenalty (
706712 uint256 amount ,
707713 bool isCheater ,
708714 uint256 refundRatio
@@ -746,7 +752,7 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
746752
747753 uint256 amount = getWithdrawalRequest[delegator][toValidatorID][wrID].amount;
748754 bool isCheater = isSlashed (toValidatorID);
749- uint256 penalty = getSlashingPenalty (amount, isCheater, slashingRefundRatio[toValidatorID]);
755+ uint256 penalty = _getSlashingPenalty (amount, isCheater, slashingRefundRatio[toValidatorID]);
750756 delete getWithdrawalRequest[delegator][toValidatorID][wrID];
751757
752758 if (amount <= penalty) {
@@ -834,11 +840,6 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
834840 }
835841 }
836842
837- /// Get epoch end time.
838- function epochEndTime (uint256 epoch ) internal view returns (uint256 ) {
839- return getEpochSnapshot[epoch].endTime;
840- }
841-
842843 /// Check if an address is redirected.
843844 function _redirected (address addr ) internal view returns (bool ) {
844845 return getRedirection[addr] != address (0 );
@@ -1022,6 +1023,7 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
10221023
10231024 if (cur.averageUptime > Decimal.unit ()) {
10241025 cur.averageUptime = uint64 (Decimal.unit ());
1026+ cur.remainder = 0 ; // reset the remainder when capping the averageUptime
10251027 }
10261028 if (prev.epochs < c.averageUptimeEpochWindow ()) {
10271029 cur.epochs = prev.epochs + 1 ;
@@ -1105,14 +1107,30 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
11051107 totalSupply = totalSupply + amount;
11061108 }
11071109
1110+ /// Sync validator with node.
1111+ function _syncValidator (uint256 validatorID , bool syncPubkey ) internal {
1112+ if (! _validatorExists (validatorID)) {
1113+ revert ValidatorNotExists ();
1114+ }
1115+ // emit special log for node
1116+ uint256 weight = getValidator[validatorID].receivedStake;
1117+ if (getValidator[validatorID].status != OK_STATUS) {
1118+ weight = 0 ;
1119+ }
1120+ node.updateValidatorWeight (validatorID, weight);
1121+ if (syncPubkey && weight != 0 ) {
1122+ node.updateValidatorPubkey (validatorID, getValidatorPubkey[validatorID]);
1123+ }
1124+ }
1125+
11081126 /// Notify stake subscriber about staking changes.
11091127 /// Used to recount votes from delegators in the governance contract.
11101128 function _notifyStakeSubscriber (address delegator , address validatorAuth , bool strict ) internal {
11111129 if (stakeSubscriberAddress != address (0 )) {
11121130 // Don't allow announceStakeChange to use up all the gas
11131131 // solhint-disable-next-line avoid-low-level-calls
11141132 (bool success , ) = stakeSubscriberAddress.call {gas: 8000000 }(
1115- abi.encodeWithSignature ( " announceStakeChange(address,address) " , delegator, validatorAuth)
1133+ abi.encodeCall (IStakeSubscriber. announceStakeChange, ( delegator, validatorAuth) )
11161134 );
11171135 // Don't revert if announceStakeChange failed unless strict mode enabled
11181136 if (! success && strict) {
@@ -1142,22 +1160,6 @@ contract SFC is OwnableUpgradeable, UUPSUpgradeable, Version {
11421160 }
11431161 }
11441162
1145- /// Sync validator with node.
1146- function _syncValidator (uint256 validatorID , bool syncPubkey ) public {
1147- if (! _validatorExists (validatorID)) {
1148- revert ValidatorNotExists ();
1149- }
1150- // emit special log for node
1151- uint256 weight = getValidator[validatorID].receivedStake;
1152- if (getValidator[validatorID].status != OK_STATUS) {
1153- weight = 0 ;
1154- }
1155- node.updateValidatorWeight (validatorID, weight);
1156- if (syncPubkey && weight != 0 ) {
1157- node.updateValidatorPubkey (validatorID, getValidatorPubkey[validatorID]);
1158- }
1159- }
1160-
11611163 /// Check if a validator exists.
11621164 function _validatorExists (uint256 validatorID ) internal view returns (bool ) {
11631165 return getValidator[validatorID].createdTime != 0 ;
0 commit comments