Skip to content
2 changes: 2 additions & 0 deletions contracts/deploy/00-chainlink-rng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ const deployRng: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
],
log: true,
});

console.log("Register this Chainlink consumer here: http://vrf.chain.link/");
};

deployRng.tags = ["ChainlinkRNG"];
Expand Down
22 changes: 6 additions & 16 deletions contracts/deploy/00-home-chain-arbitration-neo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const { ethers, deployments, getNamedAccounts, getChainId } = hre;
const { deploy } = deployments;
const { ZeroAddress } = hre.ethers;
const RNG_LOOKAHEAD = 20;

// fallback to hardhat node signers on local network
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address;
Expand Down Expand Up @@ -50,16 +49,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const maxTotalStaked = PNK(2_000_000);
const sortitionModule = await deployUpgradable(deployments, "SortitionModuleNeo", {
from: deployer,
args: [
deployer,
klerosCoreAddress,
minStakingTime,
maxFreezingTime,
rng.target,
RNG_LOOKAHEAD,
maxStakePerJuror,
maxTotalStaked,
],
args: [deployer, klerosCoreAddress, minStakingTime, maxFreezingTime, rng.target, maxStakePerJuror, maxTotalStaked],
log: true,
}); // nonce (implementation), nonce+1 (proxy)

Expand Down Expand Up @@ -94,11 +84,11 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
await disputeKitContract.changeCore(klerosCore.address);
}

// rng.changeSortitionModule() only if necessary
const rngSortitionModule = await rng.sortitionModule();
if (rngSortitionModule !== sortitionModule.address) {
console.log(`rng.changeSortitionModule(${sortitionModule.address})`);
await rng.changeSortitionModule(sortitionModule.address);
// rng.changeConsumer() only if necessary
const rngConsumer = await rng.consumer();
if (rngConsumer !== sortitionModule.address) {
console.log(`rng.changeConsumer(${sortitionModule.address})`);
await rng.changeConsumer(sortitionModule.address);
}

const core = (await hre.ethers.getContract("KlerosCoreNeo")) as KlerosCoreNeo;
Expand Down
13 changes: 6 additions & 7 deletions contracts/deploy/00-home-chain-arbitration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const { ethers, deployments, getNamedAccounts, getChainId } = hre;
const { deploy } = deployments;
const { ZeroAddress } = hre.ethers;
const RNG_LOOKAHEAD = 20;

// fallback to hardhat node signers on local network
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address;
Expand Down Expand Up @@ -53,7 +52,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const rng = (await ethers.getContract("ChainlinkRNG")) as ChainlinkRNG;
const sortitionModule = await deployUpgradable(deployments, "SortitionModule", {
from: deployer,
args: [deployer, klerosCoreAddress, minStakingTime, maxFreezingTime, rng.target, RNG_LOOKAHEAD],
args: [deployer, klerosCoreAddress, minStakingTime, maxFreezingTime, rng.target],
log: true,
}); // nonce (implementation), nonce+1 (proxy)

Expand Down Expand Up @@ -87,11 +86,11 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
await disputeKitContract.changeCore(klerosCore.address);
}

// rng.changeSortitionModule() only if necessary
const rngSortitionModule = await rng.sortitionModule();
if (rngSortitionModule !== sortitionModule.address) {
console.log(`rng.changeSortitionModule(${sortitionModule.address})`);
await rng.changeSortitionModule(sortitionModule.address);
// rng.changeConsumer() only if necessary
const rngConsumer = await rng.consumer();
if (rngConsumer !== sortitionModule.address) {
console.log(`rng.changeConsumer(${sortitionModule.address})`);
await rng.changeConsumer(sortitionModule.address);
}

const core = (await hre.ethers.getContract("KlerosCore")) as KlerosCore;
Expand Down
1 change: 0 additions & 1 deletion contracts/deploy/00-home-chain-resolver.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { HomeChains, isSkipped } from "./utils";
import { deployUpgradable } from "./utils/deployUpgradable";

const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const { deployments, getNamedAccounts, getChainId } = hre;
Expand Down
11 changes: 7 additions & 4 deletions contracts/deploy/00-rng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { SortitionModule } from "../typechain-types";
import { HomeChains, isMainnet, isSkipped } from "./utils";
import { deployUpgradable } from "./utils/deployUpgradable";
import { getContractOrDeploy } from "./utils/getContractOrDeploy";

const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const { deployments, getNamedAccounts, getChainId, ethers } = hre;
const { deploy } = deployments;
const RNG_LOOKAHEAD = 20;
const RNG_LOOKAHEAD_TIME = 30 * 60; // 30 minutes in seconds

// fallback to hardhat node signers on local network
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address;
Expand All @@ -32,11 +31,15 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)

const rng2 = await deploy("BlockHashRNG", {
from: deployer,
args: [],
args: [
deployer, // governor
sortitionModule.target, // consumer
RNG_LOOKAHEAD_TIME,
],
log: true,
});

await sortitionModule.changeRandomNumberGenerator(rng2.address, RNG_LOOKAHEAD);
await sortitionModule.changeRandomNumberGenerator(rng2.address);
};

deployArbitration.tags = ["RNG"];
Expand Down
8 changes: 4 additions & 4 deletions contracts/deploy/change-sortition-module-rng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ const task: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
sortitionModule = await ethers.getContract<SortitionModule>("SortitionModule");
}

console.log(`chainlinkRng.changeSortitionModule(${sortitionModule.target})`);
await chainlinkRng.changeSortitionModule(sortitionModule.target);
console.log(`chainlinkRng.changeConsumer(${sortitionModule.target})`);
await chainlinkRng.changeConsumer(sortitionModule.target);

console.log(`sortitionModule.changeRandomNumberGenerator(${chainlinkRng.target}, 0)`);
await sortitionModule.changeRandomNumberGenerator(chainlinkRng.target, 0);
console.log(`sortitionModule.changeRandomNumberGenerator(${chainlinkRng.target})`);
await sortitionModule.changeRandomNumberGenerator(chainlinkRng.target);
};

task.tags = ["ChangeSortitionModuleRNG"];
Expand Down
8 changes: 3 additions & 5 deletions contracts/src/arbitration/SortitionModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pragma solidity ^0.8.24;

import {SortitionModuleBase, KlerosCore, RNG} from "./SortitionModuleBase.sol";
import {SortitionModuleBase, KlerosCore, IRNG} from "./SortitionModuleBase.sol";

/// @title SortitionModule
/// @dev A factory of trees that keeps track of staked values for sortition.
Expand All @@ -24,16 +24,14 @@ contract SortitionModule is SortitionModuleBase {
/// @param _minStakingTime Minimal time to stake
/// @param _maxDrawingTime Time after which the drawing phase can be switched
/// @param _rng The random number generator.
/// @param _rngLookahead Lookahead value for rng.
function initialize(
address _governor,
KlerosCore _core,
uint256 _minStakingTime,
uint256 _maxDrawingTime,
RNG _rng,
uint256 _rngLookahead
IRNG _rng
) external reinitializer(1) {
__SortitionModuleBase_initialize(_governor, _core, _minStakingTime, _maxDrawingTime, _rng, _rngLookahead);
__SortitionModuleBase_initialize(_governor, _core, _minStakingTime, _maxDrawingTime, _rng);
}

function initialize4() external reinitializer(4) {
Expand Down
28 changes: 11 additions & 17 deletions contracts/src/arbitration/SortitionModuleBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {ISortitionModule} from "./interfaces/ISortitionModule.sol";
import {IDisputeKit} from "./interfaces/IDisputeKit.sol";
import {Initializable} from "../proxy/Initializable.sol";
import {UUPSProxiable} from "../proxy/UUPSProxiable.sol";
import {RNG} from "../rng/RNG.sol";
import {IRNG} from "../rng/IRNG.sol";
import "../libraries/Constants.sol";

/// @title SortitionModuleBase
Expand Down Expand Up @@ -50,11 +50,11 @@ abstract contract SortitionModuleBase is ISortitionModule, Initializable, UUPSPr
uint256 public minStakingTime; // The time after which the phase can be switched to Drawing if there are open disputes.
uint256 public maxDrawingTime; // The time after which the phase can be switched back to Staking.
uint256 public lastPhaseChange; // The last time the phase was changed.
uint256 public randomNumberRequestBlock; // Number of the block when RNG request was made.
uint256 public randomNumberRequestBlock; // DEPRECATED: to be removed in the next redeploy
uint256 public disputesWithoutJurors; // The number of disputes that have not finished drawing jurors.
RNG public rng; // The random number generator.
IRNG public rng; // The random number generator.
uint256 public randomNumber; // Random number returned by RNG.
uint256 public rngLookahead; // Minimal block distance between requesting and obtaining a random number.
uint256 public rngLookahead; // DEPRECATED: to be removed in the next redeploy
uint256 public delayedStakeWriteIndex; // The index of the last `delayedStake` item that was written to the array. 0 index is skipped.
uint256 public delayedStakeReadIndex; // The index of the next `delayedStake` item that should be processed. Starts at 1 because 0 index is skipped.
mapping(bytes32 treeHash => SortitionSumTree) sortitionSumTrees; // The mapping trees by keys.
Expand Down Expand Up @@ -104,16 +104,14 @@ abstract contract SortitionModuleBase is ISortitionModule, Initializable, UUPSPr
KlerosCore _core,
uint256 _minStakingTime,
uint256 _maxDrawingTime,
RNG _rng,
uint256 _rngLookahead
IRNG _rng
) internal onlyInitializing {
governor = _governor;
core = _core;
minStakingTime = _minStakingTime;
maxDrawingTime = _maxDrawingTime;
lastPhaseChange = block.timestamp;
rng = _rng;
rngLookahead = _rngLookahead;
delayedStakeReadIndex = 1;
}

Expand Down Expand Up @@ -153,15 +151,12 @@ abstract contract SortitionModuleBase is ISortitionModule, Initializable, UUPSPr
maxDrawingTime = _maxDrawingTime;
}

/// @dev Changes the `_rng` and `_rngLookahead` storage variables.
/// @param _rng The new value for the `RNGenerator` storage variable.
/// @param _rngLookahead The new value for the `rngLookahead` storage variable.
function changeRandomNumberGenerator(RNG _rng, uint256 _rngLookahead) external onlyByGovernor {
/// @dev Changes the `rng` storage variable.
/// @param _rng The new random number generator.
function changeRandomNumberGenerator(IRNG _rng) external onlyByGovernor {
rng = _rng;
rngLookahead = _rngLookahead;
if (phase == Phase.generating) {
rng.requestRandomness(block.number + rngLookahead);
randomNumberRequestBlock = block.number;
rng.requestRandomness();
}
}

Expand All @@ -176,11 +171,10 @@ abstract contract SortitionModuleBase is ISortitionModule, Initializable, UUPSPr
"The minimum staking time has not passed yet."
);
require(disputesWithoutJurors > 0, "There are no disputes that need jurors.");
rng.requestRandomness(block.number + rngLookahead);
randomNumberRequestBlock = block.number;
rng.requestRandomness();
phase = Phase.generating;
} else if (phase == Phase.generating) {
randomNumber = rng.receiveRandomness(randomNumberRequestBlock + rngLookahead);
randomNumber = rng.receiveRandomness();
require(randomNumber != 0, "Random number is not ready yet");
phase = Phase.drawing;
} else if (phase == Phase.drawing) {
Expand Down
8 changes: 3 additions & 5 deletions contracts/src/arbitration/SortitionModuleNeo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

pragma solidity ^0.8.24;

import {SortitionModuleBase, KlerosCore, RNG, StakingResult} from "./SortitionModuleBase.sol";
import {SortitionModuleBase, KlerosCore, IRNG, StakingResult} from "./SortitionModuleBase.sol";

/// @title SortitionModuleNeo
/// @dev A factory of trees that keeps track of staked values for sortition.
Expand Down Expand Up @@ -32,20 +32,18 @@ contract SortitionModuleNeo is SortitionModuleBase {
/// @param _minStakingTime Minimal time to stake
/// @param _maxDrawingTime Time after which the drawing phase can be switched
/// @param _rng The random number generator.
/// @param _rngLookahead Lookahead value for rng.
/// @param _maxStakePerJuror The maximum amount of PNK a juror can stake in a court.
/// @param _maxTotalStaked The maximum amount of PNK that can be staked in all courts.
function initialize(
address _governor,
KlerosCore _core,
uint256 _minStakingTime,
uint256 _maxDrawingTime,
RNG _rng,
uint256 _rngLookahead,
IRNG _rng,
uint256 _maxStakePerJuror,
uint256 _maxTotalStaked
) external reinitializer(2) {
__SortitionModuleBase_initialize(_governor, _core, _minStakingTime, _maxDrawingTime, _rng, _rngLookahead);
__SortitionModuleBase_initialize(_governor, _core, _minStakingTime, _maxDrawingTime, _rng);
maxStakePerJuror = _maxStakePerJuror;
maxTotalStaked = _maxTotalStaked;
}
Expand Down
Loading
Loading