From 46a0f390588d1faa029e0a5d5de5a10476897844 Mon Sep 17 00:00:00 2001 From: unknownunknown1 Date: Fri, 1 Mar 2024 18:39:22 +1000 Subject: [PATCH] feat(KC): add NFT filter and maxTotalPNK --- contracts/deploy/00-home-chain-arbitration.ts | 3 +++ contracts/src/arbitration/KlerosCore.sol | 27 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/contracts/deploy/00-home-chain-arbitration.ts b/contracts/deploy/00-home-chain-arbitration.ts index 18da3f8c7..e15f3853b 100644 --- a/contracts/deploy/00-home-chain-arbitration.ts +++ b/contracts/deploy/00-home-chain-arbitration.ts @@ -62,6 +62,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) }); // nonce (implementation), nonce+1 (proxy) const minStake = BigNumber.from(10).pow(20).mul(2); + const maxTotalStake = BigNumber.from(10).pow(25).mul(2); const alpha = 10000; const feeForJuror = BigNumber.from(10).pow(17); const klerosCore = await deployUpgradable(deployments, "KlerosCore", { @@ -77,6 +78,8 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) [0, 0, 0, 10], // evidencePeriod, commitPeriod, votePeriod, appealPeriod ethers.utils.hexlify(5), // Extra data for sortition module will return the default value of K sortitionModule.address, + maxTotalStake, + AddressZero, // TODO: ], log: true, }); // nonce+2 (implementation), nonce+3 (proxy) diff --git a/contracts/src/arbitration/KlerosCore.sol b/contracts/src/arbitration/KlerosCore.sol index 4f4098d26..a7ec98b7d 100644 --- a/contracts/src/arbitration/KlerosCore.sol +++ b/contracts/src/arbitration/KlerosCore.sol @@ -16,6 +16,7 @@ import {Constants} from "../libraries/Constants.sol"; import {OnError} from "../libraries/Types.sol"; import {UUPSProxiable} from "../proxy/UUPSProxiable.sol"; import {Initializable} from "../proxy/Initializable.sol"; +import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; /// @title KlerosCore /// Core arbitrator contract for Kleros v2. @@ -102,6 +103,8 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { address public guardian; // The address that is capable to pause the asset withdrawals. bool public paused; + uint256 public maxTotalStaked; + IERC721 public nftContract; address public jurorProsecutionModule; // The module for juror's prosecution. ISortitionModule public sortitionModule; // Sortition module for drawing. @@ -211,6 +214,8 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { /// @param _timesPerPeriod The `timesPerPeriod` property value of the general court. /// @param _sortitionExtraData The extra data for sortition module. /// @param _sortitionModuleAddress The sortition module responsible for sortition of the jurors. + /// @param _maxTotalStaked Maximal amount of PNK that can be staked in all courts combined. + /// @param _nftContract NFT contract to vet the jurors. function initialize( address _governor, address _guardian, @@ -221,7 +226,9 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { uint256[4] memory _courtParameters, uint256[4] memory _timesPerPeriod, bytes memory _sortitionExtraData, - ISortitionModule _sortitionModuleAddress + ISortitionModule _sortitionModuleAddress, + uint256 _maxTotalStaked, + IERC721 _nftContract ) external reinitializer(1) { governor = _governor; guardian = _guardian; @@ -254,6 +261,8 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { court.timesPerPeriod = _timesPerPeriod; sortitionModule.createTree(bytes32(uint256(Constants.GENERAL_COURT)), _sortitionExtraData); + maxTotalStaked = _maxTotalStaked; + nftContract = _nftContract; emit CourtCreated( 1, @@ -332,6 +341,18 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { pinakion = _pinakion; } + /// @dev Changes the `maxTotalStaked` storage variable. + /// @param _maxTotalStaked The new value for the `maxTotalStaked` storage variable. + function changeMaxTotalStaked(uint256 _maxTotalStaked) external onlyByGovernor { + maxTotalStaked = _maxTotalStaked; + } + + /// @dev Changes the `nftContract` storage variable. + /// @param _nftContract The new value for the `nftContract` storage variable. + function changeNFT(IERC721 _nftContract) external onlyByGovernor { + nftContract = _nftContract; + } + /// @dev Changes the `jurorProsecutionModule` storage variable. /// @param _jurorProsecutionModule The new value for the `jurorProsecutionModule` storage variable. function changeJurorProsecutionModule(address _jurorProsecutionModule) external onlyByGovernor { @@ -505,6 +526,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { /// @param _newStake The new stake. /// Note that the existing delayed stake will be nullified as non-relevant. function setStake(uint96 _courtID, uint256 _newStake) external whenNotPaused { + if (nftContract.balanceOf(msg.sender) == 0) revert NotEligibleForStaking(); _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert); } @@ -1129,12 +1151,14 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { _stakingFailed(_onError); return false; } + maxTotalStaked += pnkDeposit; } if (pnkWithdrawal > 0) { if (!pinakion.safeTransfer(_account, pnkWithdrawal)) { _stakingFailed(_onError); return false; } + maxTotalStaked -= pnkWithdrawal; } return true; } @@ -1215,4 +1239,5 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable { error WhenNotPausedOnly(); error WhenPausedOnly(); error ArbitrableNotWhitelisted(); + error NotEligibleForStaking(); }