@@ -514,40 +514,44 @@ contract KlerosCore is IArbitrator {
514
514
}
515
515
516
516
/** @dev Switches the phases between Staking and Freezing, also signal the switch to the dispute kits.
517
- * Note: Invariant: do not emit a `NewPhase` event if the phase is unchanged.
518
517
*/
519
518
function passPhase () external {
520
519
if (phase == Phase.staking) {
521
520
require (block .timestamp - lastPhaseChange >= minStakingTime, "The minimal staking time has not passed yet " );
522
521
require (disputesKitIDsThatNeedFreezing.length > 0 , "There are no dispute kit which need freezing " );
523
-
524
522
phase = Phase.freezing;
525
523
freezeBlock = block .number ;
526
- lastPhaseChange = block . timestamp ;
527
- emit NewPhase ( phase);
528
- } else if (phase == Phase.freezing) {
529
- bool freezingPhaseFinished = block . timestamp - lastPhaseChange >= maxFreezingTime;
530
- for ( uint256 i = disputesKitIDsThatNeedFreezing. length - 1 ; i >= 0 ; -- i) {
531
- IDisputeKit disputeKit = disputeKitNodes[disputesKitIDsThatNeedFreezing[i ]].disputeKit;
524
+ } else {
525
+ // phase == Phase.freezing
526
+ bool freezingPhaseFinished = this . freezingPhaseTimeout ();
527
+ for ( int256 i = int256 (disputesKitIDsThatNeedFreezing. length ) - 1 ; i >= 0 ; -- i) {
528
+ uint256 disputeKitID = disputesKitIDsThatNeedFreezing[ uint256 (i)];
529
+ IDisputeKit disputeKit = disputeKitNodes[disputesKitIDsThatNeedFreezing[uint256 (i) ]].disputeKit;
532
530
if (freezingPhaseFinished && ! disputeKit.isResolving ()) {
533
531
// Force the dispute kit to be ready for Staking phase.
534
- disputeKit.passPhase (); // Warning: don't call if already in Resolving phase, because it reverts.
532
+ disputeKit.passPhase (); // Should not be called if already in Resolving phase, because it reverts.
535
533
require (disputeKit.isResolving (), "A dispute kit has not passed to Resolving phase " );
536
534
} else {
537
535
// Check if the dispute kit is ready for Staking phase.
538
536
require (disputeKit.isResolving (), "A dispute kit has not passed to Resolving phase " );
539
-
540
537
if (disputeKit.disputesWithoutJurors () == 0 ) {
541
538
// The dispute kit had time to finish drawing jurors for all its disputes.
542
- disputeKitNodes[disputesKitIDsThatNeedFreezing[i]].needsFreezing = false ;
539
+ disputeKitNodes[disputeKitID].needsFreezing = false ;
540
+ if (i < int256 (disputesKitIDsThatNeedFreezing.length ) - 1 ) {
541
+ // This is not the last element so copy the last element to the current one, then pop.
542
+ disputesKitIDsThatNeedFreezing[uint256 (i)] = disputesKitIDsThatNeedFreezing[
543
+ disputesKitIDsThatNeedFreezing.length - 1
544
+ ];
545
+ }
543
546
disputesKitIDsThatNeedFreezing.pop ();
544
547
}
545
548
}
546
549
}
547
550
phase = Phase.staking;
548
- lastPhaseChange = block .timestamp ;
549
- emit NewPhase (phase);
550
551
}
552
+ // Should not be reached if the phase is unchanged.
553
+ lastPhaseChange = block .timestamp ;
554
+ emit NewPhase (phase);
551
555
}
552
556
553
557
/** @dev Passes the period of a specified dispute.
@@ -1002,8 +1006,8 @@ contract KlerosCore is IArbitrator {
1002
1006
return freezeBlock;
1003
1007
}
1004
1008
1005
- function isFreezingPhaseFinished () external view returns (bool ) {
1006
- return block .timestamp - lastPhaseChange >= maxFreezingTime;
1009
+ function freezingPhaseTimeout () external view returns (bool ) {
1010
+ return phase == Phase.freezing && block .timestamp - lastPhaseChange >= maxFreezingTime;
1007
1011
}
1008
1012
1009
1013
/** @dev Returns true if the dispute kit will be switched to a parent DK.
0 commit comments