@@ -344,48 +344,33 @@ abstract contract StakeControllerBase is IStakeController, Initializable, UUPSPr
344344 JurorStake storage currentJurorStake = jurorStakes[_account];
345345 uint256 currentStakeInCourt = currentJurorStake.stakes[_courtID];
346346
347- // Check for MAX_STAKE_PATHS before calculating deposit/withdrawal if it's a new court stake
348- if (currentStakeInCourt == 0 && _newStake > 0 ) {
349- if (currentJurorStake.stakedCourtIDs.length >= MAX_STAKE_PATHS) {
347+ if (currentStakeInCourt == 0 ) {
348+ if (_newStake == 0 )
349+ // No change needed
350+ return (0 , 0 , StakingResult.CannotStakeZeroWhenNoStake);
351+ else if (_newStake > 0 && currentJurorStake.stakedCourtIDs.length >= MAX_STAKE_PATHS)
352+ // Cannot stake in more courts
350353 return (0 , 0 , StakingResult.CannotStakeInMoreCourts);
351- }
352354 }
353355
354- uint256 previousTotalStake = currentJurorStake.totalStake; // Keep track for potential revert
356+ currentJurorStake.stakes[_courtID] = _newStake;
357+
355358 if (_newStake > currentStakeInCourt) {
356359 pnkDeposit = _newStake - currentStakeInCourt;
357- currentJurorStake.totalStake = previousTotalStake + pnkDeposit;
360+ currentJurorStake.totalStake += pnkDeposit;
358361 } else if (_newStake < currentStakeInCourt) {
359362 pnkWithdrawal = currentStakeInCourt - _newStake;
360- currentJurorStake.totalStake = previousTotalStake - pnkWithdrawal;
363+ currentJurorStake.totalStake -= pnkWithdrawal;
361364 }
362365
363- currentJurorStake.stakes[_courtID] = _newStake;
364-
365366 // Manage stakedCourtIDs
366367 if (currentStakeInCourt == 0 && _newStake > 0 ) {
367368 currentJurorStake.stakedCourtIDs.push (_courtID);
368369 } else if (currentStakeInCourt > 0 && _newStake == 0 ) {
369370 _removeCourt (currentJurorStake.stakedCourtIDs, _courtID);
370371 }
371372
372- stakingResult = sortitionModule.setStake (_account, _courtID, _newStake);
373- if (stakingResult != StakingResult.Successful) {
374- // Revert local changes if sortitionModule update fails
375- currentJurorStake.stakes[_courtID] = currentStakeInCourt;
376- currentJurorStake.totalStake = previousTotalStake;
377- if (currentStakeInCourt == 0 && _newStake > 0 ) {
378- // revert insertion: was a push, so pop
379- uint96 [] storage stakedCourtsRevert = currentJurorStake.stakedCourtIDs;
380- if (stakedCourtsRevert.length > 0 && stakedCourtsRevert[stakedCourtsRevert.length - 1 ] == _courtID) {
381- stakedCourtsRevert.pop ();
382- }
383- } else if (currentStakeInCourt > 0 && _newStake == 0 ) {
384- // revert removal: was a remove, so add it back (order might not be preserved by simple push)
385- currentJurorStake.stakedCourtIDs.push (_courtID);
386- }
387- return (0 , 0 , stakingResult);
388- }
373+ sortitionModule.setStake (_account, _courtID, _newStake);
389374
390375 emit StakeSet (_account, _courtID, _newStake, currentJurorStake.totalStake);
391376 }
@@ -402,6 +387,10 @@ abstract contract StakeControllerBase is IStakeController, Initializable, UUPSPr
402387 uint96 _courtID ,
403388 uint256 _newStake
404389 ) internal virtual returns (uint256 pnkDeposit , uint256 pnkWithdrawal , StakingResult stakingResult ) {
390+ if (phase == Phase.staking) {
391+ return _setStakeBySystem (_account, _courtID, _newStake);
392+ }
393+
405394 JurorStake storage currentJurorStake = jurorStakes[_account];
406395 uint256 currentStakeInCourt = currentJurorStake.stakes[_courtID];
407396
@@ -411,70 +400,25 @@ abstract contract StakeControllerBase is IStakeController, Initializable, UUPSPr
411400 pnkWithdrawal = currentStakeInCourt - _newStake;
412401 }
413402
414- if (phase != Phase.staking) {
415- // MAX_STAKE_PATHS is checked when _setStakeBySystem() is called during executeDelayedStakes().
416- DelayedStake storage delayedStake = delayedStakes[++ delayedStakeWriteIndex];
417- delayedStake.account = _account;
418- delayedStake.courtID = _courtID;
419- delayedStake.stake = _newStake;
420- return (pnkDeposit, pnkWithdrawal, StakingResult.Delayed);
421- }
422-
423- // Check for MAX_STAKE_PATHS if it's a new court stake
424- if (currentStakeInCourt == 0 && _newStake > 0 ) {
425- if (currentJurorStake.stakedCourtIDs.length >= MAX_STAKE_PATHS) {
426- return (0 , 0 , StakingResult.CannotStakeInMoreCourts);
427- }
428- }
429-
430- // Update local stake records first
431- uint256 previousTotalStake = currentJurorStake.totalStake; // Keep track for potential revert
432- if (_newStake > currentStakeInCourt) {
433- currentJurorStake.totalStake = previousTotalStake + pnkDeposit;
434- } else if (_newStake < currentStakeInCourt) {
435- currentJurorStake.totalStake = previousTotalStake - pnkWithdrawal;
436- }
437- currentJurorStake.stakes[_courtID] = _newStake;
438-
439- // Manage stakedCourtIDs
440- if (currentStakeInCourt == 0 && _newStake > 0 ) {
441- currentJurorStake.stakedCourtIDs.push (_courtID);
442- } else if (currentStakeInCourt > 0 && _newStake == 0 ) {
443- _removeCourt (currentJurorStake.stakedCourtIDs, _courtID);
444- }
445-
446- stakingResult = sortitionModule.setStake (_account, _courtID, _newStake);
447- if (stakingResult != StakingResult.Successful) {
448- // Revert local changes if sortitionModule update fails
449- currentJurorStake.stakes[_courtID] = currentStakeInCourt;
450- currentJurorStake.totalStake = previousTotalStake;
451- if (currentStakeInCourt == 0 && _newStake > 0 ) {
452- // revert insertion: was a push, so pop
453- uint96 [] storage stakedCourtsRevert = currentJurorStake.stakedCourtIDs;
454- if (stakedCourtsRevert.length > 0 && stakedCourtsRevert[stakedCourtsRevert.length - 1 ] == _courtID) {
455- stakedCourtsRevert.pop ();
456- }
457- } else if (currentStakeInCourt > 0 && _newStake == 0 ) {
458- // revert removal: was a remove, so add it back (order might not be preserved by simple push)
459- currentJurorStake.stakedCourtIDs.push (_courtID);
460- }
461- return (0 , 0 , stakingResult);
462- }
463-
464- emit StakeSet (_account, _courtID, _newStake, currentJurorStake.totalStake);
403+ // MAX_STAKE_PATHS is checked by _setStakeBySystem() called during executeDelayedStakes().
404+ DelayedStake storage delayedStake = delayedStakes[++ delayedStakeWriteIndex];
405+ delayedStake.account = _account;
406+ delayedStake.courtID = _courtID;
407+ delayedStake.stake = _newStake;
408+ return (pnkDeposit, pnkWithdrawal, StakingResult.Delayed);
465409 }
466410
467411 /// @dev Removes a court from a juror's list of staked courts.
468412 /// @param _stakedCourts Storage pointer to the juror's array of staked court IDs.
469413 /// @param _courtID The ID of the court to remove.
470414 function _removeCourt (uint96 [] storage _stakedCourts , uint96 _courtID ) internal {
471- uint256 len = _stakedCourts.length ;
472- if (len == 0 ) {
415+ uint256 length = _stakedCourts.length ;
416+ if (length == 0 ) {
473417 return ; // Nothing to remove
474418 }
475419
476420 uint256 courtIndexToRemove = type (uint256 ).max; // Sentinel value indicates not found
477- for (uint256 i = 0 ; i < len ; i++ ) {
421+ for (uint256 i = 0 ; i < length ; i++ ) {
478422 if (_stakedCourts[i] == _courtID) {
479423 courtIndexToRemove = i;
480424 break ;
@@ -484,8 +428,8 @@ abstract contract StakeControllerBase is IStakeController, Initializable, UUPSPr
484428 if (courtIndexToRemove != type (uint256 ).max) {
485429 // If the courtID was found in the array
486430 // If it's not the last element, swap the last element into its place
487- if (courtIndexToRemove != len - 1 ) {
488- _stakedCourts[courtIndexToRemove] = _stakedCourts[len - 1 ];
431+ if (courtIndexToRemove != length - 1 ) {
432+ _stakedCourts[courtIndexToRemove] = _stakedCourts[length - 1 ];
489433 }
490434 // Remove the last element (either the original last, or the one that was swapped)
491435 _stakedCourts.pop ();
0 commit comments