Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions contracts/src/arbitration/KlerosCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ contract KlerosCore is IArbitratorV2, Initializable, UUPSProxiable {
bool public arbitrableWhitelistEnabled; // Whether the arbitrable whitelist is enabled.
IERC721 public jurorNft; // Eligible jurors NFT.
IRatesConverter public ratesConverter; // Contract to convert ETH value to fee tokens.
address public forkSettlement; // The forking settlement contract authorized to capture/redistribute stakes. Appended last for upgrade-safety.

// ************************************* //
// * Events * //
Expand Down Expand Up @@ -271,6 +272,11 @@ contract KlerosCore is IArbitratorV2, Initializable, UUPSProxiable {
/// @param _gracePeriodEnd Timestamp after which period transitions can resume.
event ArbitrationUnpaused(uint256 _gracePeriodEnd);

/// @notice Emitted when a dispute jumps into the forking court and the terminal forking round opens.
/// @param _disputeID The dispute entering the forking court.
/// @param _roundID The forking round ID.
event ForkingRoundStarted(uint256 indexed _disputeID, uint256 _roundID);

// ************************************* //
// * Function Modifiers * //
// ************************************* //
Expand All @@ -295,6 +301,11 @@ contract KlerosCore is IArbitratorV2, Initializable, UUPSProxiable {
_;
}

modifier onlyByForkSettlement() {
require(forkSettlement != address(0) && msg.sender == forkSettlement, ForkSettlementOnly());
_;
}

// ************************************* //
// * Constructor * //
// ************************************* //
Expand Down Expand Up @@ -468,6 +479,12 @@ contract KlerosCore is IArbitratorV2, Initializable, UUPSProxiable {
ratesConverter = _ratesConverter;
}

/// @notice Sets the forking settlement contract authorized to capture and redistribute stakes.
/// @param _forkSettlement The new value for the `forkSettlement` storage variable.
function setForkSettlement(address _forkSettlement) external onlyByOwner {
forkSettlement = _forkSettlement;
}

/// @notice Changes the `_sortitionModule` storage variable.
/// Note that the new module should be initialized for all courts.
/// @param _sortitionModule The new value for the `sortitionModule` storage variable.
Expand Down Expand Up @@ -687,6 +704,30 @@ contract KlerosCore is IArbitratorV2, Initializable, UUPSProxiable {
require(pinakion.safeTransfer(_account, _amount), TransferFailed());
}

/// @notice Captures a fork joiner's entire staked PNK for the main fork (G-7), surrendering it without
/// refund. The PNK stays in this contract as the redistribution mass. Only callable by the
/// forking settlement contract.
/// @dev TDD skeleton β€” reverts `NotImplemented()`. Implementation calls
/// `sortitionModule.captureUnstakeAllCourts` and accumulates the captured pool.
/// @param _joiner The joiner whose stake to capture.
/// @return captured The amount of PNK captured.
function captureStakeForForking(address _joiner) external onlyByForkSettlement returns (uint256 captured) {
_joiner;
revert NotImplemented();
}

/// @notice Credits a main-fork stayer their supply-equalized share of the captured pool (G-5/G-7).
/// No token transfer occurs (the PNK is already held here); the stayer's stake is scaled up.
/// Only callable by the forking settlement contract; freeze-exempt (settlement-internal).
/// @dev TDD skeleton β€” reverts `NotImplemented()`.
/// @param _stayer The main-fork participant to credit.
/// @param _amount The PNK amount to credit to their main-fork stake.
function distributeForking(address _stayer, uint256 _amount) external onlyByForkSettlement {
_stayer;
_amount;
revert NotImplemented();
}

/// @notice Create a dispute and pay for the fees in the native currency, typically ETH.
/// @dev Must be called by the arbitrable contract and pay at least `arbitrationCost(_extraData)` in ETH.
/// @param _numberOfChoices The number of choices the arbitrator can choose from in this dispute.
Expand Down Expand Up @@ -1540,6 +1581,10 @@ contract KlerosCore is IArbitratorV2, Initializable, UUPSProxiable {
error GuardianOrOwnerOnly();
error DisputeKitOnly();
error SortitionModuleOnly();
error ForkSettlementOnly();
error AppealNotAllowed();
error NotForkingCourt();
error NotImplemented();
error UnsuccessfulCall();
error InvalidDisputeKitParent();
error MinStakeLowerThanParentCourt();
Expand Down
45 changes: 45 additions & 0 deletions contracts/src/arbitration/SortitionModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
uint256 public maxStakePerJuror; // The maximum amount of PNK that a juror can stake across the courts. Accrued rewards do not count toward this limit.
uint256 public maxTotalStaked; // The maximum amount of PNK that all the jurors can stake across the courts.
uint256 public totalStaked; // The amount of PNK that is currently staked across the courts.
bool public stakingFrozen; // True while a forking round is live; blocks all staked-balance mutations (G-2). Appended last for upgrade-safety.

// ************************************* //
// * Events * //
Expand Down Expand Up @@ -96,6 +97,13 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
/// @param _amount The amount of PNK withdrawn.
event LeftoverPNKWithdrawn(address indexed _account, uint256 _amount);

/// @notice Emitted when staking is frozen for a forking round.
/// @param _disputeID The forking dispute that triggered the freeze.
event StakingFreezeEngaged(uint256 indexed _disputeID);

/// @notice Emitted when staking is unfrozen after a forking round settles.
event StakingFreezeReleased();

// ************************************* //
// * Constructor * //
// ************************************* //
Expand Down Expand Up @@ -527,6 +535,39 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
core.setStakeBySortitionModule(_account, _courtID, 0);
}

// ************************************* //
// * Forking (G-2 / G-7) * //
// ************************************* //

/// @notice Freezes all staked-balance mutations for the duration of a forking round (G-2). Makes the
/// live `stakedPnk` the vote snapshot. Stake locking/unlocking and drawing remain allowed.
/// @dev TDD skeleton β€” reverts `NotImplemented()`. Implementation sets `stakingFrozen = true`,
/// records `_disputeID`, and emits `StakingFreezeEngaged`. The guard itself is added to
/// `_setStake` / `executeDelayedStakes` / `validateStake` in the implementation pass.
/// @param _disputeID The forking dispute triggering the freeze.
function freeze(uint256 _disputeID) external override onlyByCore {
_disputeID;
revert NotImplemented();
}

/// @notice Releases the stake freeze once a forking round has settled.
/// @dev TDD skeleton β€” reverts `NotImplemented()`.
function unfreeze() external override onlyByCore {
revert NotImplemented();
}

/// @notice Surrenders a fork joiner's entire staked PNK to the main fork WITHOUT refunding them:
/// zeroes their sortition-tree slots, `courtIDs` and `stakedPnk`, decrements `totalStaked`,
/// and performs NO token transfer (the PNK stays in `KlerosCore`'s balance as the
/// redistribution mass). Contrast `forcedUnstakeAllCourts`, which refunds the juror.
/// @dev TDD skeleton β€” reverts `NotImplemented()`.
/// @param _account The joiner to capture.
/// @return captured The amount of PNK surrendered (the joiner's former `stakedPnk`).
function captureUnstakeAllCourts(address _account) external override onlyByCore returns (uint256 captured) {
_account;
revert NotImplemented();
}

/// @notice Gives back the locked PNKs in case the juror fully unstaked earlier.
///
/// @dev that since locked and staked PNK are async it is possible for the juror to have positive staked PNK balance
Expand Down Expand Up @@ -662,4 +703,8 @@ contract SortitionModule is ISortitionModule, Initializable, UUPSProxiable {
error NoDelayedStakeToExecute();
error NotEligibleForWithdrawal();
error NotDrawingPhase();
error NotImplemented();
error StakingFrozen();
error AlreadyFrozen();
error NotFrozen();
}
Loading
Loading