@@ -9,6 +9,7 @@ import {IArbitratorV2, IArbitrableV2} from "../../src/arbitration/KlerosCore.sol
99import {IERC20 } from "../../src/libraries/SafeERC20.sol " ;
1010import "../../src/libraries/Constants.sol " ;
1111import {console} from "forge-std/console.sol " ;
12+ import {MaliciousArbitrableMock} from "../../src/test/MaliciousArbitrableMock.sol " ;
1213
1314/// @title KlerosCore_ExecutionTest
1415/// @dev Tests for KlerosCore execution, rewards, and ruling finalization
@@ -655,6 +656,48 @@ contract KlerosCore_ExecutionTest is KlerosCore_TestBase {
655656 assertEq (ruled, true , "Should be ruled " );
656657 }
657658
659+ function test_executeRuling_arbitrableRevert () public {
660+ MaliciousArbitrableMock maliciousArbitrable = new MaliciousArbitrableMock (
661+ core,
662+ templateData,
663+ templateDataMappings,
664+ arbitratorExtraData,
665+ registry,
666+ feeToken
667+ );
668+ uint256 disputeID = 0 ;
669+
670+ vm.prank (staker1);
671+ core.setStake (GENERAL_COURT, 20000 );
672+ vm.prank (disputer);
673+ maliciousArbitrable.createDispute {value: feeForJuror * DEFAULT_NB_OF_JURORS}("Action " );
674+ vm.warp (block .timestamp + minStakingTime);
675+ sortitionModule.passPhase (); // Generating
676+ vm.warp (block .timestamp + rngLookahead);
677+ sortitionModule.passPhase (); // Drawing phase
678+
679+ core.draw (disputeID, DEFAULT_NB_OF_JURORS);
680+ vm.warp (block .timestamp + timesPerPeriod[0 ]);
681+ core.passPeriod (disputeID); // Vote
682+
683+ uint256 [] memory voteIDs = new uint256 [](3 );
684+ voteIDs[0 ] = 0 ;
685+ voteIDs[1 ] = 1 ;
686+ voteIDs[2 ] = 2 ;
687+
688+ vm.prank (staker1);
689+ disputeKit.castVote (disputeID, voteIDs, 2 , 0 , "XYZ " );
690+ core.passPeriod (disputeID); // Appeal
691+
692+ vm.warp (block .timestamp + timesPerPeriod[3 ]);
693+ core.passPeriod (disputeID); // Execution
694+
695+ vm.expectRevert (MaliciousArbitrableMock.RuleReverted.selector );
696+ core.executeRuling (disputeID); // Reverts
697+
698+ disputeKit.withdrawFeesAndRewards (disputeID, payable (staker1), 2 ); // Should not revert even if executeRuling() reverted
699+ }
700+
658701 function test_executeRuling_appealSwitch () public {
659702 // Check that the ruling switches if only one side was funded
660703 uint256 disputeID = 0 ;
@@ -730,12 +773,13 @@ contract KlerosCore_ExecutionTest is KlerosCore_TestBase {
730773 disputeKit.fundAppeal {value: 0.41 ether }(disputeID, 2 ); // Underpay a bit to not create an appeal and withdraw the funded sum fully
731774
732775 vm.warp (block .timestamp + timesPerPeriod[3 ]);
733- core.passPeriod (disputeID); // Execution
734776
735777 vm.expectRevert (DisputeKitClassicBase.DisputeNotResolved.selector );
736778 disputeKit.withdrawFeesAndRewards (disputeID, payable (staker1), 1 );
737779
738- core.executeRuling (disputeID);
780+ core.passPeriod (disputeID); // Execution
781+ // executeRuling() should be irrelevant for withdrawals in case malicious arbitrable reverts rule()
782+ //core.executeRuling(disputeID);
739783
740784 vm.prank (owner);
741785 core.pause ();
@@ -769,22 +813,15 @@ contract KlerosCore_ExecutionTest is KlerosCore_TestBase {
769813 // 4. move sortition to staking phase
770814 uint256 disputeID = 0 ;
771815 uint256 amountToStake = 20000 ;
772- _stakePnk_createDispute_moveToDrawingPhase (disputeID, staker1, amountToStake);
816+ _stakePnk_createDispute_moveToDrawingPhase (staker1, amountToStake);
773817
774818 KlerosCore.Round memory round = core.getRoundInfo (disputeID, 0 );
775819 uint256 pnkAtStakePerJuror = round.pnkAtStakePerJuror;
776820 _stakeBalanceForJuror (staker1, type (uint256 ).max);
777821 _drawJurors_advancePeriodToVoting (disputeID);
778822 _vote_execute (disputeID, staker1);
779823 sortitionModule.passPhase (); // set it to staking phase
780- _assertJurorBalance (
781- disputeID,
782- staker1,
783- amountToStake,
784- pnkAtStakePerJuror * DEFAULT_NB_OF_JURORS,
785- amountToStake,
786- 1
787- );
824+ _assertJurorBalance (staker1, amountToStake, pnkAtStakePerJuror * DEFAULT_NB_OF_JURORS, amountToStake, 1 );
788825
789826 console.log ("totalStaked before: %e " , sortitionModule.totalStaked ());
790827
@@ -793,14 +830,7 @@ contract KlerosCore_ExecutionTest is KlerosCore_TestBase {
793830
794831 // post condition: inflated totalStaked
795832 console.log ("totalStaked after: %e " , sortitionModule.totalStaked ());
796- _assertJurorBalance (
797- disputeID,
798- staker1,
799- amountToStake,
800- pnkAtStakePerJuror * DEFAULT_NB_OF_JURORS,
801- amountToStake,
802- 1
803- );
833+ _assertJurorBalance (staker1, amountToStake, pnkAtStakePerJuror * DEFAULT_NB_OF_JURORS, amountToStake, 1 );
804834
805835 // new juror tries to stake but totalStaked already reached type(uint256).max
806836 // it reverts with "arithmetic underflow or overflow (0x11)"
@@ -909,19 +939,18 @@ contract KlerosCore_ExecutionTest is KlerosCore_TestBase {
909939 ///////// Internal //////////
910940
911941 function _assertJurorBalance (
912- uint256 disputeID ,
913- address juror ,
914- uint256 totalStakedPnk ,
915- uint256 totalLocked ,
916- uint256 stakedInCourt ,
917- uint256 nbCourts
918- ) internal {
942+ address _juror ,
943+ uint256 _totalStakedPnk ,
944+ uint256 _totalLocked ,
945+ uint256 _stakedInCourt ,
946+ uint256 _nbCourts
947+ ) internal view {
919948 (uint256 totalStakedPnk , uint256 totalLocked , uint256 stakedInCourt , uint256 nbCourts ) = sortitionModule
920- .getJurorBalance (juror , GENERAL_COURT);
921- assertEq (totalStakedPnk , totalStakedPnk, "Wrong totalStakedPnk " ); // jurors total staked a.k.a juror.stakedPnk
922- assertEq (totalLocked , totalLocked, "Wrong totalLocked " );
923- assertEq (stakedInCourt , stakedInCourt, "Wrong stakedInCourt " ); // juror staked in court a.k.a _stakeOf
924- assertEq (nbCourts , nbCourts, "Wrong nbCourts " );
949+ .getJurorBalance (_juror , GENERAL_COURT);
950+ assertEq (_totalStakedPnk , totalStakedPnk, "Wrong totalStakedPnk " ); // jurors total staked a.k.a juror.stakedPnk
951+ assertEq (_totalLocked , totalLocked, "Wrong totalLocked " );
952+ assertEq (_stakedInCourt , stakedInCourt, "Wrong stakedInCourt " ); // juror staked in court a.k.a _stakeOf
953+ assertEq (_nbCourts , nbCourts, "Wrong nbCourts " );
925954 }
926955
927956 function _stakeBalanceForJuror (address juror , uint256 amount ) internal {
@@ -930,7 +959,7 @@ contract KlerosCore_ExecutionTest is KlerosCore_TestBase {
930959 core.setStake (GENERAL_COURT, amount);
931960 }
932961
933- function _stakePnk_createDispute_moveToDrawingPhase (uint256 disputeID , address juror , uint256 amount ) internal {
962+ function _stakePnk_createDispute_moveToDrawingPhase (address juror , uint256 amount ) internal {
934963 vm.prank (juror);
935964 core.setStake (GENERAL_COURT, amount);
936965 vm.prank (disputer);
0 commit comments