diff --git a/contracts/src/arbitration/KlerosCore.sol b/contracts/src/arbitration/KlerosCore.sol index cfee3e003..728382859 100644 --- a/contracts/src/arbitration/KlerosCore.sol +++ b/contracts/src/arbitration/KlerosCore.sol @@ -95,6 +95,13 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { uint256 repartition; // The index of the repartition to execute. } + struct JurorBalance { + uint256 totalStaked; // The total amount of PNKs staked on the arbitrator. + uint256 totalLocked; // The total amount of PNKs locked on the arbitrator. + uint256 stakedInCourt; // The amount of PNKs staked in a particular court. + uint256 nbCourts; // The number of courts the juror has staked in. + } + struct CurrencyRate { bool feePaymentAccepted; uint64 rateInEth; @@ -1000,15 +1007,12 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { return disputes[_disputeID].rounds.length; } - function getJurorBalance( - address _juror, - uint96 _courtID - ) external view returns (uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, uint256 nbCourts) { + function getJurorBalance(address _juror, uint96 _courtID) external view returns (JurorBalance memory balance) { Juror storage juror = jurors[_juror]; - totalStaked = juror.stakedPnk; - totalLocked = juror.lockedPnk; - stakedInCourt = juror.stakedPnkByCourt[_courtID]; - nbCourts = juror.courtIDs.length; + balance.totalStaked = juror.stakedPnk; + balance.totalLocked = juror.lockedPnk; + balance.stakedInCourt = juror.stakedPnkByCourt[_courtID]; + balance.nbCourts = juror.courtIDs.length; } function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) { diff --git a/contracts/src/arbitration/SortitionModule.sol b/contracts/src/arbitration/SortitionModule.sol index 67c787aff..244a0451b 100644 --- a/contracts/src/arbitration/SortitionModule.sol +++ b/contracts/src/arbitration/SortitionModule.sol @@ -212,8 +212,8 @@ contract SortitionModule is ISortitionModule, UUPSProxiable, Initializable { uint96 _courtID, uint256 _stake ) external override onlyByCore returns (preStakeHookResult) { - (, , uint256 currentStake, uint256 nbCourts) = core.getJurorBalance(_account, _courtID); - if (currentStake == 0 && nbCourts >= MAX_STAKE_PATHS) { + KlerosCore.JurorBalance memory jurorBalance = core.getJurorBalance(_account, _courtID); + if (jurorBalance.stakedInCourt == 0 && jurorBalance.nbCourts >= MAX_STAKE_PATHS) { // Prevent staking beyond MAX_STAKE_PATHS but unstaking is always allowed. return preStakeHookResult.failed; } else { diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol index 1912633c3..0304663a1 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol @@ -606,7 +606,7 @@ contract DisputeKitClassic is IDisputeKit, Initializable, UUPSProxiable { uint256 lockedAmountPerJuror = core .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1) .pnkAtStakePerJuror; - (uint256 totalStaked, uint256 totalLocked, , ) = core.getJurorBalance(_juror, courtID); - return totalStaked >= totalLocked + lockedAmountPerJuror; + KlerosCore.JurorBalance memory jurorBalance = core.getJurorBalance(_juror, courtID); + return jurorBalance.totalStaked >= jurorBalance.totalLocked + lockedAmountPerJuror; } } diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol b/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol index 54bafb40c..c2e5d08b7 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol @@ -624,8 +624,8 @@ contract DisputeKitSybilResistant is IDisputeKit, Initializable, UUPSProxiable { uint256 lockedAmountPerJuror = core .getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1) .pnkAtStakePerJuror; - (uint256 totalStaked, uint256 totalLocked, , ) = core.getJurorBalance(_juror, courtID); - if (totalStaked < totalLocked + lockedAmountPerJuror) { + KlerosCore.JurorBalance memory jurorBalance = core.getJurorBalance(_juror, courtID); + if (jurorBalance.totalStaked < jurorBalance.totalLocked + lockedAmountPerJuror) { return false; } else { return _proofOfHumanity(_juror); diff --git a/web/src/components/Popup/Description/StakeWithdraw.tsx b/web/src/components/Popup/Description/StakeWithdraw.tsx index e781a462b..844dbe548 100644 --- a/web/src/components/Popup/Description/StakeWithdraw.tsx +++ b/web/src/components/Popup/Description/StakeWithdraw.tsx @@ -88,7 +88,7 @@ const StakeWithdraw: React.FC = ({ pnkStaked, courtName, isStake My Stake:{" "} - {`${formatUnits(jurorBalance?.[2] ?? BigInt(0), 18)} PNK`} + {`${formatUnits(jurorBalance?.stakedInCourt ?? BigInt(0), 18)} PNK`} ); diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx index b78c9579d..271b023d7 100644 --- a/web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx +++ b/web/src/pages/Courts/CourtDetails/StakePanel/InputDisplay.tsx @@ -83,7 +83,7 @@ const InputDisplay: React.FC = ({ args: [address, id], watch: true, }); - const parsedStake = formatPNK(jurorBalance?.[2] || 0n, 0, true); + const parsedStake = formatPNK(jurorBalance?.stakedInCourt || 0n, 0, true); const isStaking = action === ActionType.stake; return ( diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/JurorStakeDisplay.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/JurorStakeDisplay.tsx index 940328bd1..41d6363b2 100644 --- a/web/src/pages/Courts/CourtDetails/StakePanel/JurorStakeDisplay.tsx +++ b/web/src/pages/Courts/CourtDetails/StakePanel/JurorStakeDisplay.tsx @@ -45,7 +45,14 @@ const bigIntRatioToPercentage = (numerator: bigint, denominator: bigint): string }; const useCalculateJurorOdds = ( - jurorBalance: readonly [bigint, bigint, bigint] | undefined, + jurorBalance: + | { + totalStaked: bigint; + totalLocked: bigint; + stakedInCourt: bigint; + nbCourts: bigint; + } + | undefined, stakedByAllJurors: string | undefined, loading: boolean ): string => { @@ -58,7 +65,7 @@ const useCalculateJurorOdds = ( return "0.00%"; } - return bigIntRatioToPercentage(jurorBalance[2], BigInt(stakedByAllJurors)); + return bigIntRatioToPercentage(jurorBalance.stakedInCourt, BigInt(stakedByAllJurors)); }, [jurorBalance, stakedByAllJurors, loading]); }; @@ -78,10 +85,10 @@ const JurorBalanceDisplay = () => { const [previousStakedByAllJurors, setPreviousStakedByAllJurors] = useState(undefined); useEffect(() => { - if (previousJurorBalance !== undefined && jurorBalance?.[2] !== previousJurorBalance) { + if (previousJurorBalance !== undefined && jurorBalance?.stakedInCourt !== previousJurorBalance) { setLoading(true); } - setPreviousJurorBalance(jurorBalance?.[2]); + setPreviousJurorBalance(jurorBalance?.stakedInCourt); }, [jurorBalance, previousJurorBalance]); useEffect(() => { @@ -99,12 +106,12 @@ const JurorBalanceDisplay = () => { { icon: PNKIcon, name: "My Stake", - value: `${format(jurorBalance?.[2])} PNK`, + value: `${format(jurorBalance?.stakedInCourt)} PNK`, }, { icon: LockerIcon, name: "Locked Stake", - value: `${format(jurorBalance?.[1])} PNK`, + value: `${format(jurorBalance?.totalLocked)} PNK`, }, { icon: DiceIcon, diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/StakeWithdrawButton.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/StakeWithdrawButton.tsx index ab3137959..cfbd98d2a 100644 --- a/web/src/pages/Courts/CourtDetails/StakePanel/StakeWithdrawButton.tsx +++ b/web/src/pages/Courts/CourtDetails/StakePanel/StakeWithdrawButton.tsx @@ -68,9 +68,9 @@ const StakeWithdrawButton: React.FC = ({ if (isAllowance) { return parsedAmount; } else if (isStaking) { - return jurorBalance[2] + parsedAmount; + return jurorBalance.stakedInCourt + parsedAmount; } else { - return jurorBalance[2] - parsedAmount; + return jurorBalance.stakedInCourt - parsedAmount; } } return 0n; @@ -121,7 +121,7 @@ const StakeWithdrawButton: React.FC = ({ }, [ActionType.withdraw]: { text: "Withdraw", - checkDisabled: () => !jurorBalance || parsedAmount > jurorBalance[2], + checkDisabled: () => !jurorBalance || parsedAmount > jurorBalance.stakedInCourt, onClick: handleStake, }, };