@@ -463,22 +463,25 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
463
463
/// @param _newStake The new stake.
464
464
/// Note that the existing delayed stake will be nullified as non-relevant.
465
465
function setStake (uint96 _courtID , uint256 _newStake ) external virtual whenNotPaused {
466
- _setStake (msg .sender , _courtID, _newStake, false , OnError.Revert);
466
+ _setStake (msg .sender , _courtID, _newStake, OnError.Revert);
467
467
}
468
468
469
469
/// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors.
470
470
/// @param _account The account whose stake is being set.
471
471
/// @param _courtID The ID of the court.
472
472
/// @param _newStake The new stake.
473
- /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract.
474
- function setStakeBySortitionModule (
475
- address _account ,
476
- uint96 _courtID ,
477
- uint256 _newStake ,
478
- bool _alreadyTransferred
479
- ) external {
473
+ function setStakeBySortitionModule (address _account , uint96 _courtID , uint256 _newStake ) external {
480
474
if (msg .sender != address (sortitionModule)) revert SortitionModuleOnly ();
481
- _setStake (_account, _courtID, _newStake, _alreadyTransferred, OnError.Return);
475
+ _setStake (_account, _courtID, _newStake, OnError.Return);
476
+ }
477
+
478
+ /// @dev Transfers PNK to the juror by SortitionModule.
479
+ /// @param _account The account of the juror whose PNK to transfer.
480
+ /// @param _amount The amount to transfer.
481
+ function transferBySortitionModule (address _account , uint256 _amount ) external {
482
+ if (msg .sender != address (sortitionModule)) revert SortitionModuleOnly ();
483
+ // Note eligibility is checked in SortitionModule.
484
+ pinakion.safeTransfer (_account, _amount);
482
485
}
483
486
484
487
/// @inheritdoc IArbitratorV2
@@ -774,26 +777,25 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
774
777
775
778
// Fully coherent jurors won't be penalized.
776
779
uint256 penalty = (round.pnkAtStakePerJuror * (ALPHA_DIVISOR - degreeOfCoherence)) / ALPHA_DIVISOR;
777
- _params.pnkPenaltiesInRound += penalty;
778
780
779
781
// Unlock the PNKs affected by the penalty
780
782
address account = round.drawnJurors[_params.repartition];
781
783
sortitionModule.unlockStake (account, penalty);
782
784
783
785
// Apply the penalty to the staked PNKs.
784
- sortitionModule.penalizeStake (account, penalty);
786
+ (uint256 pnkBalance , uint256 availablePenalty ) = sortitionModule.penalizeStake (account, penalty);
787
+ _params.pnkPenaltiesInRound += availablePenalty;
785
788
emit TokenAndETHShift (
786
789
account,
787
790
_params.disputeID,
788
791
_params.round,
789
792
degreeOfCoherence,
790
- - int256 (penalty ),
793
+ - int256 (availablePenalty ),
791
794
0 ,
792
795
round.feeToken
793
796
);
794
-
795
- if (! disputeKit.isVoteActive (_params.disputeID, _params.round, _params.repartition)) {
796
- // The juror is inactive, unstake them.
797
+ // Unstake the juror from all courts if he was inactive or his balance can't cover penalties anymore.
798
+ if (pnkBalance == 0 || ! disputeKit.isVoteActive (_params.disputeID, _params.round, _params.repartition)) {
797
799
sortitionModule.setJurorInactive (account);
798
800
}
799
801
if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0 ) {
@@ -844,11 +846,6 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
844
846
// Release the rest of the PNKs of the juror for this round.
845
847
sortitionModule.unlockStake (account, pnkLocked);
846
848
847
- // Give back the locked PNKs in case the juror fully unstaked earlier.
848
- if (! sortitionModule.isJurorStaked (account)) {
849
- pinakion.safeTransfer (account, pnkLocked);
850
- }
851
-
852
849
// Transfer the rewards
853
850
uint256 pnkReward = ((_params.pnkPenaltiesInRound / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;
854
851
round.sumPnkRewardPaid += pnkReward;
@@ -1074,16 +1071,9 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
1074
1071
/// @param _account The account to set the stake for.
1075
1072
/// @param _courtID The ID of the court to set the stake for.
1076
1073
/// @param _newStake The new stake.
1077
- /// @param _alreadyTransferred Whether the PNKs were already transferred to/from the staking contract.
1078
1074
/// @param _onError Whether to revert or return false on error.
1079
1075
/// @return Whether the stake was successfully set or not.
1080
- function _setStake (
1081
- address _account ,
1082
- uint96 _courtID ,
1083
- uint256 _newStake ,
1084
- bool _alreadyTransferred ,
1085
- OnError _onError
1086
- ) internal returns (bool ) {
1076
+ function _setStake (address _account , uint96 _courtID , uint256 _newStake , OnError _onError ) internal returns (bool ) {
1087
1077
if (_courtID == FORKING_COURT || _courtID >= courts.length ) {
1088
1078
_stakingFailed (_onError, StakingResult.CannotStakeInThisCourt); // Staking directly into the forking court is not allowed.
1089
1079
return false ;
@@ -1092,15 +1082,16 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
1092
1082
_stakingFailed (_onError, StakingResult.CannotStakeLessThanMinStake); // Staking less than the minimum stake is not allowed.
1093
1083
return false ;
1094
1084
}
1095
- (uint256 pnkDeposit , uint256 pnkWithdrawal , StakingResult stakingResult ) = sortitionModule.setStake (
1085
+ (uint256 pnkDeposit , uint256 pnkWithdrawal , StakingResult stakingResult ) = sortitionModule.validateStake (
1096
1086
_account,
1097
1087
_courtID,
1098
- _newStake,
1099
- _alreadyTransferred
1088
+ _newStake
1100
1089
);
1101
- if (stakingResult != StakingResult.Successful) {
1090
+ if (stakingResult != StakingResult.Successful && stakingResult != StakingResult.Delayed ) {
1102
1091
_stakingFailed (_onError, stakingResult);
1103
1092
return false ;
1093
+ } else if (stakingResult == StakingResult.Delayed) {
1094
+ return true ;
1104
1095
}
1105
1096
if (pnkDeposit > 0 ) {
1106
1097
if (! pinakion.safeTransferFrom (_account, address (this ), pnkDeposit)) {
@@ -1114,6 +1105,8 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
1114
1105
return false ;
1115
1106
}
1116
1107
}
1108
+ sortitionModule.setStake (_account, _courtID, pnkDeposit, pnkWithdrawal, _newStake);
1109
+
1117
1110
return true ;
1118
1111
}
1119
1112
0 commit comments