@@ -194,8 +194,8 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
194194 // * State Modifiers * //
195195 // ************************************* //
196196
197- /// @dev Passes the phase.
198- function passPhase () external {
197+ /// @inheritdoc ISortitionModule
198+ function passPhase () external override {
199199 if (phase == Phase.staking) {
200200 if (block .timestamp - lastPhaseChange < minStakingTime) revert MinStakingTimeNotPassed ();
201201 if (disputesWithoutJurors == 0 ) revert NoDisputesThatNeedJurors ();
@@ -216,18 +216,15 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
216216 emit NewPhase (phase);
217217 }
218218
219- /// @dev Create a sortition sum tree at the specified key.
220- /// @param _courtID The ID of the court.
221- /// @param _extraData Extra data that contains the number of children each node in the tree should have.
219+ /// @inheritdoc ISortitionModule
222220 function createTree (uint96 _courtID , bytes memory _extraData ) external override onlyByCore {
223221 TreeKey key = CourtID.wrap (_courtID).toTreeKey ();
224222 uint256 K = _extraDataToTreeK (_extraData);
225223 sortitionSumTrees.createTree (key, K);
226224 }
227225
228- /// @dev Executes the next delayed stakes.
229- /// @param _iterations The number of delayed stakes to execute.
230- function executeDelayedStakes (uint256 _iterations ) external {
226+ /// @inheritdoc ISortitionModule
227+ function executeDelayedStakes (uint256 _iterations ) external override {
231228 if (phase != Phase.staking) revert NotStakingPhase ();
232229 if (delayedStakeWriteIndex < delayedStakeReadIndex) revert NoDelayedStakeToExecute ();
233230
@@ -244,29 +241,17 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
244241 delayedStakeReadIndex = newDelayedStakeReadIndex;
245242 }
246243
247- /// @dev Triggers the state changes after dispute creation.
244+ /// @inheritdoc ISortitionModule
248245 function createDisputeHook (uint256 /*_disputeID*/ , uint256 /*_roundID*/ ) external override onlyByCore {
249246 disputesWithoutJurors++ ;
250247 }
251248
252- /// @dev Triggers the state changes after drawing.
249+ /// @inheritdoc ISortitionModule
253250 function postDrawHook (uint256 /*_disputeID*/ , uint256 /*_roundID*/ ) external override onlyByCore {
254251 disputesWithoutJurors-- ;
255252 }
256253
257- /// @dev Saves the random number to use it in sortition. Not used by this contract because the storing of the number is inlined in passPhase().
258- /// @param _randomNumber Random number returned by RNG contract.
259- function notifyRandomNumber (uint256 _randomNumber ) public override {}
260-
261- /// @dev Validate the specified juror's new stake for a court.
262- /// Note: no state changes should be made when returning stakingResult != Successful, otherwise delayed stakes might break invariants.
263- /// @param _account The address of the juror.
264- /// @param _courtID The ID of the court.
265- /// @param _newStake The new stake.
266- /// @param _noDelay True if the stake change should not be delayed.
267- /// @return pnkDeposit The amount of PNK to be deposited.
268- /// @return pnkWithdrawal The amount of PNK to be withdrawn.
269- /// @return stakingResult The result of the staking operation.
254+ /// @inheritdoc ISortitionModule
270255 function validateStake (
271256 address _account ,
272257 uint96 _courtID ,
@@ -283,7 +268,7 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
283268 bool _noDelay
284269 ) internal returns (uint256 pnkDeposit , uint256 pnkWithdrawal , StakingResult stakingResult ) {
285270 Juror storage juror = jurors[_account];
286- uint256 currentStake = stakeOf (_account, _courtID);
271+ uint256 currentStake = _stakeOf (_account, _courtID);
287272 bool stakeIncrease = _newStake > currentStake;
288273 uint256 stakeChange = stakeIncrease ? _newStake - currentStake : currentStake - _newStake;
289274
@@ -332,17 +317,7 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
332317 return (pnkDeposit, pnkWithdrawal, StakingResult.Successful);
333318 }
334319
335- /// @dev Update the state of the stakes, called by KC at the end of setStake flow.
336- /// `O(n + p * log_k(j))` where
337- /// `n` is the number of courts the juror has staked in,
338- /// `p` is the depth of the court tree,
339- /// `k` is the minimum number of children per node of one of these courts' sortition sum tree,
340- /// and `j` is the maximum number of jurors that ever staked in one of these courts simultaneously.
341- /// @param _account The address of the juror.
342- /// @param _courtID The ID of the court.
343- /// @param _pnkDeposit The amount of PNK to be deposited.
344- /// @param _pnkWithdrawal The amount of PNK to be withdrawn.
345- /// @param _newStake The new stake.
320+ /// @inheritdoc ISortitionModule
346321 function setStake (
347322 address _account ,
348323 uint96 _courtID ,
@@ -353,59 +328,40 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
353328 _setStake (_account, _courtID, _pnkDeposit, _pnkWithdrawal, _newStake);
354329 }
355330
356- /// @dev Update the state of the stakes with a PNK reward deposit, called by KC during rewards execution.
357- /// `O(n + p * log_k(j))` where
358- /// `n` is the number of courts the juror has staked in,
359- /// `p` is the depth of the court tree,
360- /// `k` is the minimum number of children per node of one of these courts' sortition sum tree,
361- /// and `j` is the maximum number of jurors that ever staked in one of these courts simultaneously.
362- /// @param _account The address of the juror.
363- /// @param _courtID The ID of the court.
364- /// @param _penalty The amount of PNK to be deducted.
365- /// @return pnkBalance The updated total PNK balance of the juror, including the penalty.
366- /// @return newCourtStake The updated stake of the juror in the court.
367- /// @return availablePenalty The amount of PNK that was actually deducted.
331+ /// @inheritdoc ISortitionModule
368332 function setStakePenalty (
369333 address _account ,
370334 uint96 _courtID ,
371335 uint256 _penalty
372336 ) external override onlyByCore returns (uint256 pnkBalance , uint256 newCourtStake , uint256 availablePenalty ) {
373337 Juror storage juror = jurors[_account];
374338 availablePenalty = _penalty;
375- newCourtStake = stakeOf (_account, _courtID);
339+ newCourtStake = _stakeOf (_account, _courtID);
376340 if (juror.stakedPnk < _penalty) {
377341 availablePenalty = juror.stakedPnk;
378342 }
379343
380344 if (availablePenalty == 0 ) return (juror.stakedPnk, newCourtStake, 0 ); // No penalty to apply.
381345
382- uint256 currentStake = stakeOf (_account, _courtID);
346+ uint256 currentStake = _stakeOf (_account, _courtID);
383347 uint256 newStake = 0 ;
384348 if (currentStake >= availablePenalty) {
385349 newStake = currentStake - availablePenalty;
386350 }
387351 _setStake (_account, _courtID, 0 , availablePenalty, newStake);
388352 pnkBalance = juror.stakedPnk; // updated by _setStake()
389- newCourtStake = stakeOf (_account, _courtID); // updated by _setStake()
353+ newCourtStake = _stakeOf (_account, _courtID); // updated by _setStake()
390354 }
391355
392- /// @dev Update the state of the stakes with a PNK reward deposit, called by KC during rewards execution.
393- /// `O(n + p * log_k(j))` where
394- /// `n` is the number of courts the juror has staked in,
395- /// `p` is the depth of the court tree,
396- /// `k` is the minimum number of children per node of one of these courts' sortition sum tree,
397- /// and `j` is the maximum number of jurors that ever staked in one of these courts simultaneously.
398- /// @param _account The address of the juror.
399- /// @param _courtID The ID of the court.
400- /// @param _reward The amount of PNK to be deposited as a reward.
356+ /// @inheritdoc ISortitionModule
401357 function setStakeReward (
402358 address _account ,
403359 uint96 _courtID ,
404360 uint256 _reward
405361 ) external override onlyByCore returns (bool success ) {
406362 if (_reward == 0 ) return true ; // No reward to add.
407363
408- uint256 currentStake = stakeOf (_account, _courtID);
364+ uint256 currentStake = _stakeOf (_account, _courtID);
409365 if (currentStake == 0 ) return false ; // Juror has been unstaked, don't increase their stake.
410366
411367 uint256 newStake = currentStake + _reward;
@@ -422,7 +378,7 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
422378 ) internal {
423379 Juror storage juror = jurors[_account];
424380 if (_pnkDeposit > 0 ) {
425- uint256 currentStake = stakeOf (_account, _courtID);
381+ uint256 currentStake = _stakeOf (_account, _courtID);
426382 if (currentStake == 0 ) {
427383 juror.courtIDs.push (_courtID);
428384 }
@@ -459,17 +415,13 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
459415 emit StakeSet (_account, _courtID, _newStake, juror.stakedPnk);
460416 }
461417
462- /// @dev Locks the tokens of the drawn juror.
463- /// @param _account The address of the juror.
464- /// @param _relativeAmount The amount to lock.
418+ /// @inheritdoc ISortitionModule
465419 function lockStake (address _account , uint256 _relativeAmount ) external override onlyByCore {
466420 jurors[_account].lockedPnk += _relativeAmount;
467421 emit StakeLocked (_account, _relativeAmount, false );
468422 }
469423
470- /// @dev Unlocks the tokens of the drawn juror.
471- /// @param _account The address of the juror.
472- /// @param _relativeAmount The amount to unlock.
424+ /// @inheritdoc ISortitionModule
473425 function unlockStake (address _account , uint256 _relativeAmount ) external override onlyByCore {
474426 Juror storage juror = jurors[_account];
475427 juror.lockedPnk -= _relativeAmount;
@@ -481,38 +433,20 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
481433 }
482434 }
483435
484- /// @dev Unstakes the inactive juror from all courts.
485- /// `O(n * (p * log_k(j)) )` where
486- /// `n` is the number of courts the juror has staked in,
487- /// `p` is the depth of the court tree,
488- /// `k` is the minimum number of children per node of one of these courts' sortition sum tree,
489- /// and `j` is the maximum number of jurors that ever staked in one of these courts simultaneously.
490- /// @param _account The juror to unstake.
436+ /// @inheritdoc ISortitionModule
491437 function forcedUnstakeAllCourts (address _account ) external override onlyByCore {
492438 uint96 [] memory courtIDs = getJurorCourtIDs (_account);
493439 for (uint256 j = courtIDs.length ; j > 0 ; j-- ) {
494440 core.setStakeBySortitionModule (_account, courtIDs[j - 1 ], 0 );
495441 }
496442 }
497443
498- /// @dev Unstakes the inactive juror from a specific court.
499- /// `O(n * (p * log_k(j)) )` where
500- /// `n` is the number of courts the juror has staked in,
501- /// `p` is the depth of the court tree,
502- /// `k` is the minimum number of children per node of one of these courts' sortition sum tree,
503- /// and `j` is the maximum number of jurors that ever staked in one of these courts simultaneously.
504- /// @param _account The juror to unstake.
505- /// @param _courtID The ID of the court.
444+ /// @inheritdoc ISortitionModule
506445 function forcedUnstake (address _account , uint96 _courtID ) external override onlyByCore {
507446 core.setStakeBySortitionModule (_account, _courtID, 0 );
508447 }
509448
510- /// @dev Gives back the locked PNKs in case the juror fully unstaked earlier.
511- /// Note that since locked and staked PNK are async it is possible for the juror to have positive staked PNK balance
512- /// while having 0 stake in courts and 0 locked tokens (eg. when the juror fully unstaked during dispute and later got his tokens unlocked).
513- /// In this case the juror can use this function to withdraw the leftover tokens.
514- /// Also note that if the juror has some leftover PNK while not fully unstaked he'll have to manually unstake from all courts to trigger this function.
515- /// @param _account The juror whose PNK to withdraw.
449+ /// @inheritdoc ISortitionModule
516450 function withdrawLeftoverPNK (address _account ) external override {
517451 // Can withdraw the leftover PNK if fully unstaked, has no tokens locked and has positive balance.
518452 // This withdrawal can't be triggered by calling setStake() in KlerosCore because current stake is technically 0, thus it is done via separate function.
@@ -527,15 +461,7 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
527461 // * Public Views * //
528462 // ************************************* //
529463
530- /// @dev Draw an ID from a tree using a number.
531- /// Note that this function reverts if the sum of all values in the tree is 0.
532- /// @param _courtID The ID of the court.
533- /// @param _coreDisputeID Index of the dispute in Kleros Core.
534- /// @param _nonce Nonce to hash with random number.
535- /// @return drawnAddress The drawn address.
536- /// `O(k * log_k(n))` where
537- /// `k` is the maximum number of children per node in the tree,
538- /// and `n` is the maximum number of nodes ever appended.
464+ /// @inheritdoc ISortitionModule
539465 function draw (
540466 uint96 _courtID ,
541467 uint256 _coreDisputeID ,
@@ -547,23 +473,7 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
547473 (drawnAddress, fromSubcourtID) = sortitionSumTrees[key].draw (_coreDisputeID, _nonce, randomNumber);
548474 }
549475
550- /// @dev Get the stake of a juror in a court.
551- /// @param _juror The address of the juror.
552- /// @param _courtID The ID of the court.
553- /// @return value The stake of the juror in the court.
554- function stakeOf (address _juror , uint96 _courtID ) public view returns (uint256 ) {
555- bytes32 stakePathID = SortitionTrees.toStakePathID (_juror, _courtID);
556- TreeKey key = CourtID.wrap (_courtID).toTreeKey ();
557- return sortitionSumTrees[key].stakeOf (stakePathID);
558- }
559-
560- /// @dev Gets the balance of a juror in a court.
561- /// @param _juror The address of the juror.
562- /// @param _courtID The ID of the court.
563- /// @return totalStakedPnk The total amount of tokens staked including locked tokens and penalty deductions. Equivalent to the effective stake in the General court.
564- /// @return totalLocked The total amount of tokens locked in disputes.
565- /// @return stakedInCourt The amount of tokens staked in the specified court including locked tokens and penalty deductions.
566- /// @return nbCourts The number of courts the juror has directly staked in.
476+ /// @inheritdoc ISortitionModule
567477 function getJurorBalance (
568478 address _juror ,
569479 uint96 _courtID
@@ -576,26 +486,21 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
576486 Juror storage juror = jurors[_juror];
577487 totalStakedPnk = juror.stakedPnk;
578488 totalLocked = juror.lockedPnk;
579- stakedInCourt = stakeOf (_juror, _courtID);
489+ stakedInCourt = _stakeOf (_juror, _courtID);
580490 nbCourts = juror.courtIDs.length ;
581491 }
582492
583- /// @dev Gets the court identifiers where a specific `_juror` has staked.
584- /// @param _juror The address of the juror.
493+ /// @inheritdoc ISortitionModule
585494 function getJurorCourtIDs (address _juror ) public view override returns (uint96 [] memory ) {
586495 return jurors[_juror].courtIDs;
587496 }
588497
589- /// @dev Checks if the juror is staked in any court.
590- /// @param _juror The address of the juror.
591- /// @return Whether the juror is staked or not.
498+ /// @inheritdoc ISortitionModule
592499 function isJurorStaked (address _juror ) external view override returns (bool ) {
593500 return jurors[_juror].stakedPnk > 0 ;
594501 }
595502
596- /// @dev Checks if the juror has any leftover PNK in the contract.
597- /// @param _juror The address of the juror.
598- /// @return Whether the juror has leftover PNK.
503+ /// @inheritdoc ISortitionModule
599504 function getJurorLeftoverPNK (address _juror ) public view override returns (uint256 ) {
600505 Juror storage juror = jurors[_juror];
601506 if (juror.courtIDs.length == 0 && juror.lockedPnk == 0 ) {
@@ -609,6 +514,16 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
609514 // * Internal * //
610515 // ************************************* //
611516
517+ /// @dev Get the stake of a juror in a court.
518+ /// @param _juror The address of the juror.
519+ /// @param _courtID The ID of the court.
520+ /// @return value The stake of the juror in the court.
521+ function _stakeOf (address _juror , uint96 _courtID ) internal view returns (uint256 ) {
522+ bytes32 stakePathID = SortitionTrees.toStakePathID (_juror, _courtID);
523+ TreeKey key = CourtID.wrap (_courtID).toTreeKey ();
524+ return sortitionSumTrees[key].stakeOf (stakePathID);
525+ }
526+
612527 /// @dev Converts sortition extradata into K value of sortition tree.
613528 /// @param _extraData Sortition extra data.
614529 /// @return K The value of K.
0 commit comments