Skip to content

Commit

Permalink
Merge branch 'dev' into feat/restriction-roles
Browse files Browse the repository at this point in the history
  • Loading branch information
Harman-singh-waraich committed Dec 19, 2024
2 parents b454a3c + f9cb5a6 commit 5c43453
Show file tree
Hide file tree
Showing 134 changed files with 12,652 additions and 959 deletions.
40 changes: 18 additions & 22 deletions .github/workflows/contracts-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@ jobs:
54.185.253.63:443
- name: Setup Node.js environment
uses: actions/setup-node@v4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: 18.x

- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive

- name: Cache node modules
uses: actions/cache@v4
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
env:
cache-name: cache-node-modules
with:
Expand All @@ -57,28 +59,22 @@ jobs:
key: ${{ runner.os }}-build-${{ secrets.CACHE_VERSION }}-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-build-${{ secrets.CACHE_VERSION }}-${{ env.cache-name }}-
#- name: Install parent dependencies
# run: |
# echo "current dir: $PWD"
# yarn install

- name: Install contracts dependencies
run: |
yarn workspace @kleros/kleros-v2-contracts install
- name: Compile
run: |
yarn hardhat compile
working-directory: contracts

- name: Test with coverage
run: |
yarn hardhat coverage --solcoverjs ./.solcover.js --temp artifacts --testfiles './test/**/*.ts' --show-stack-traces
working-directory: contracts
run: yarn workspace @kleros/kleros-v2-contracts install

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 # v1.2.0

- name: Install lcov
run: sudo apt-get install -y lcov

- name: Run Hardhat and Foundry tests with coverage
run: yarn coverage
working-directory: contracts

- name: Upload a build artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: code-coverage-report
path: contracts/coverage
4 changes: 2 additions & 2 deletions contracts/.solcover.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const shell = require("shelljs");
// The environment variables are loaded in hardhat.config.ts

module.exports = {
istanbulReporter: ["html"],
istanbulReporter: ["lcov"],
onCompileComplete: async function (_config) {
await run("typechain");
},
Expand All @@ -14,7 +14,7 @@ module.exports = {
shell.rm("-rf", "./artifacts");
shell.rm("-rf", "./typechain");
},
skipFiles: ["mocks", "test"],
skipFiles: ["test", "token", "kleros-v1", "proxy/mock", "gateway/mock", "rng/mock"],
mocha: {
timeout: 20000,
grep: "@skip-on-coverage", // Find everything with this tag
Expand Down
4 changes: 4 additions & 0 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments

#### Arbitrum One

- [BlockHashRNG](https://arbiscan.io/address/0x39D123fc4cFD24EA5bB76195f9ecFE1f0DF35b0B)
- [ChainlinkRNG](https://arbiscan.io/address/0x897d83a7d5F23555eFA15e1BE297d5503522cbA3)
- [DisputeKitClassicNeo: proxy](https://arbiscan.io/address/0x70B464be85A547144C72485eBa2577E5D3A45421), [implementation](https://arbiscan.io/address/0xAF0325dbBFa812a574743Bb5A085266D31e3e03a)
- [DisputeResolverNeo](https://arbiscan.io/address/0xb5526D022962A1fFf6eD32C93e8b714c901F4323)
- [DisputeTemplateRegistry: proxy](https://arbiscan.io/address/0x0cFBaCA5C72e7Ca5fFABE768E135654fB3F2a5A2), [implementation](https://arbiscan.io/address/0x57EfD43DAfCeb6C58Df57932b2B299f46fef5c87)
Expand All @@ -27,6 +29,7 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments
#### Arbitrum Sepolia

- [BlockHashRNG](https://sepolia.arbiscan.io/address/0x0298a3EFa6Faf90865725E2b48Cf0F66e5d52754)
- [ChainlinkRNG](https://sepolia.arbiscan.io/address/0xAd5cCc93429e3A977c273cEeD106Ef16A69EAf79)
- [DAI](https://sepolia.arbiscan.io/address/0xc34aeFEa232956542C5b2f2EE55fD5c378B35c03)
- [DAIFaucet](https://sepolia.arbiscan.io/address/0x1Fa58B52326488D62A406E71DBaD839560e810fF)
- [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x0c38f115D001d3b5bBec5e8D44f78C7B61A27D94), [implementation](https://sepolia.arbiscan.io/address/0xDb0B7908C46E2Bb08459bf9b3155b9bb8F8713E1)
Expand Down Expand Up @@ -67,6 +70,7 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments

- [ArbitrableExample](https://sepolia.arbiscan.io/address/0x3Eae72F076c68F5c354C73abC33EAA291ef1b2Fa)
- [BlockHashRNG](https://sepolia.arbiscan.io/address/0x56d6d65Fe202232714794B5D5e4ed9894466Ee01)
- [ChainlinkRNG](https://sepolia.arbiscan.io/address/0x6c40D7F5d5bE3492fe9EF70e4eCb2BD773c12AF8)
- [DAI](https://sepolia.arbiscan.io/address/0x593e89704D285B0c3fbF157c7CF2537456CE64b5)
- [DAIFaucet](https://sepolia.arbiscan.io/address/0xB5b39A1bcD2D7097A8824B3cC18Ebd2dFb0D9B5E)
- [DisputeKitClassic: proxy](https://sepolia.arbiscan.io/address/0x9426F127116C3652A262AE1eA48391AC8F44D35b), [implementation](https://sepolia.arbiscan.io/address/0x692CC78F2570181FFB99297965FeAA8352ab12E8)
Expand Down
80 changes: 80 additions & 0 deletions contracts/deploy/00-chainlink-rng.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { HomeChains, isSkipped } from "./utils";
import { getContractOrDeploy } from "./utils/getContractOrDeploy";

const deployRng: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const { deployments, getNamedAccounts, getChainId } = hre;
const { deploy } = deployments;

// fallback to hardhat node signers on local network
const deployer = (await getNamedAccounts()).deployer ?? (await hre.ethers.getSigners())[0].address;
const chainId = Number(await getChainId()) as unknown as HomeChains; // Checked at runtime by skip()
console.log("deploying to %s with deployer %s", HomeChains[chainId], deployer);

const KEY_HASHES = {
// https://docs.chain.link/vrf/v2-5/supported-networks#arbitrum-mainnet
[HomeChains.ARBITRUM_ONE]: {
2: "0x9e9e46732b32662b9adc6f3abdf6c5e926a666d174a4d6b8e39c4cca76a38897",
30: "0x8472ba59cf7134dfe321f4d61a430c4857e8b19cdd5230b09952a92671c24409",
150: "0xe9f223d7d83ec85c4f78042a4845af3a1c8df7757b4997b815ce4b8d07aca68c",
},
// https://docs.chain.link/vrf/v2-5/supported-networks#arbitrum-sepolia-testnet
[HomeChains.ARBITRUM_SEPOLIA]: {
150: "0x1770bdc7eec7771f7ba4ffd640f34260d7f095b79c92d34a5b2551d6f6cfd2be",
},
[HomeChains.HARDHAT]: {
0: "0x0000000000000000000000000000000000000000000000000000000000000000",
},
};

const SUBSCRIPTION_ID = {
[HomeChains.ARBITRUM_ONE]: "66240499937595191069677958665918759554657443303079118766000192000140992834352",
[HomeChains.ARBITRUM_SEPOLIA]: "38502597312983100069991953687934627561654236680431968938019951490339399569548",
[HomeChains.HARDHAT]: "0x0000000000000000000000000000000000000000000000000000000000000001",
};

function getKeyHash({ gasPrice }: { gasPrice: keyof (typeof KEY_HASHES)[HomeChains.ARBITRUM_ONE] }): string {
const validGasPrices = Object.keys(KEY_HASHES[HomeChains.ARBITRUM_ONE]).map(Number);
if (!validGasPrices.includes(gasPrice)) {
throw new Error(`Invalid gas price ${gasPrice}. Valid values are: ${validGasPrices.join(", ")}`);
}
if (chainId == HomeChains.HARDHAT) return KEY_HASHES[chainId][0];
if (chainId == HomeChains.ARBITRUM_ONE) return KEY_HASHES[chainId][gasPrice];
if (chainId == HomeChains.ARBITRUM_SEPOLIA) return KEY_HASHES[chainId][150];
throw new Error(`Unknown chainId ${chainId}`);
}

const ChainlinkVRFCoordinator = await getContractOrDeploy(hre, "ChainlinkVRFCoordinator", {
from: deployer,
contract: "ChainlinkVRFCoordinatorV2Mock",
args: [],
log: true,
});

const keyHash = getKeyHash({ gasPrice: 30 });
const subscriptionId = SUBSCRIPTION_ID[chainId];
const requestConfirmations = 200; // between 1 and 200 L2 blocks
const callbackGasLimit = 100000;

await deploy("ChainlinkRNG", {
from: deployer,
args: [
deployer,
deployer, // The consumer is configured as the SortitionModule later
ChainlinkVRFCoordinator.target,
keyHash,
subscriptionId,
requestConfirmations,
callbackGasLimit,
],
log: true,
});
};

deployRng.tags = ["ChainlinkRNG"];
deployRng.skip = async ({ network }) => {
return isSkipped(network, !HomeChains[network.config.chainId ?? 0]);
};

export default deployRng;
1 change: 0 additions & 1 deletion contracts/deploy/00-home-chain-arbitrable.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import disputeTemplate from "../test/fixtures/DisputeTemplate.simple.json";
import { HomeChains, isSkipped } from "./utils";
import { deployUpgradable } from "./utils/deployUpgradable";

Expand Down
30 changes: 13 additions & 17 deletions contracts/deploy/00-home-chain-arbitration-neo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { changeCurrencyRate } from "./utils/klerosCoreHelper";
import { HomeChains, isSkipped, isDevnet, PNK, ETH } from "./utils";
import { getContractOrDeploy, getContractOrDeployUpgradable } from "./utils/getContractOrDeploy";
import { deployERC20AndFaucet, deployERC721 } from "./utils/deployTokens";
import { DisputeKitClassic, KlerosCoreNeo } from "../typechain-types";
import { ChainlinkRNG, DisputeKitClassic, KlerosCoreNeo, RandomizerRNG } from "../typechain-types";

const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const { ethers, deployments, getNamedAccounts, getChainId } = hre;
Expand All @@ -29,19 +29,6 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)

await deployUpgradable(deployments, "EvidenceModule", { from: deployer, args: [deployer], log: true });

const randomizerOracle = await getContractOrDeploy(hre, "RandomizerOracle", {
from: deployer,
contract: "RandomizerMock",
args: [],
log: true,
});

const rng = await deployUpgradable(deployments, "RandomizerRNG", {
from: deployer,
args: [randomizerOracle.target, deployer],
log: true,
});

const disputeKit = await deployUpgradable(deployments, "DisputeKitClassicNeo", {
from: deployer,
contract: "DisputeKitClassic",
Expand All @@ -58,6 +45,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const devnet = isDevnet(hre.network);
const minStakingTime = devnet ? 180 : 1800;
const maxFreezingTime = devnet ? 600 : 1800;
const rng = (await ethers.getContract("ChainlinkRNG")) as ChainlinkRNG;
const maxStakePerJuror = PNK(2_000);
const maxTotalStaked = PNK(2_000_000);
const sortitionModule = await deployUpgradable(deployments, "SortitionModuleNeo", {
Expand All @@ -67,7 +55,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
klerosCoreAddress,
minStakingTime,
maxFreezingTime,
rng.address,
rng.target,
RNG_LOOKAHEAD,
maxStakePerJuror,
maxTotalStaked,
Expand All @@ -85,7 +73,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
deployer,
deployer,
pnk.target,
ZeroAddress,
ZeroAddress, // KlerosCore is configured later
disputeKit.address,
false,
[minStake, alpha, feeForJuror, jurorsForCourtJump],
Expand All @@ -97,14 +85,21 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
log: true,
}); // nonce+2 (implementation), nonce+3 (proxy)

// execute DisputeKitClassic.changeCore() only if necessary
// disputeKit.changeCore() only if necessary
const disputeKitContract = (await hre.ethers.getContract("DisputeKitClassicNeo")) as DisputeKitClassic;
const currentCore = await disputeKitContract.core();
if (currentCore !== klerosCore.address) {
console.log(`disputeKit.changeCore(${klerosCore.address})`);
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);
}

const core = (await hre.ethers.getContract("KlerosCoreNeo")) as KlerosCoreNeo;
try {
await changeCurrencyRate(core, await weth.getAddress(), true, 1, 1);
Expand All @@ -130,6 +125,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
};

deployArbitration.tags = ["ArbitrationNeo"];
deployArbitration.dependencies = ["ChainlinkRNG"];
deployArbitration.skip = async ({ network }) => {
return isSkipped(network, !HomeChains[network.config.chainId ?? 0]);
};
Expand Down
6 changes: 3 additions & 3 deletions contracts/deploy/00-home-chain-arbitration-university.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { deployUpgradable } from "./utils/deployUpgradable";
import { changeCurrencyRate } from "./utils/klerosCoreHelper";
import { ETH, HomeChains, PNK, isSkipped } from "./utils";
import { deployERC20AndFaucet } from "./utils/deployTokens";
import { DisputeKitClassic, KlerosCore, KlerosCoreUniversity } from "../typechain-types";
import { DisputeKitClassic, KlerosCoreUniversity } from "../typechain-types";
import { getContractOrDeploy, getContractOrDeployUpgradable } from "./utils/getContractOrDeploy";

const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
Expand Down Expand Up @@ -53,7 +53,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
deployer, // governor
deployer, // instructor
pnk.target,
ZeroAddress,
ZeroAddress, // KlerosCore is configured later
disputeKit.address,
false,
[minStake, alpha, feeForJuror, jurorsForCourtJump],
Expand All @@ -63,7 +63,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
log: true,
}); // nonce+2 (implementation), nonce+3 (proxy)

// changeCore() only if necessary
// disputeKit.changeCore() only if necessary
const disputeKitContract = (await ethers.getContract("DisputeKitClassicUniversity")) as DisputeKitClassic;
const currentCore = await disputeKitContract.core();
if (currentCore !== klerosCore.address) {
Expand Down
41 changes: 13 additions & 28 deletions contracts/deploy/00-home-chain-arbitration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { DeployFunction } from "hardhat-deploy/types";
import { getContractAddress } from "./utils/getContractAddress";
import { deployUpgradable } from "./utils/deployUpgradable";
import { changeCurrencyRate } from "./utils/klerosCoreHelper";
import { HomeChains, isSkipped, isDevnet, isMainnet, PNK, ETH } from "./utils";
import { HomeChains, isSkipped, isDevnet, PNK, ETH } from "./utils";
import { getContractOrDeploy, getContractOrDeployUpgradable } from "./utils/getContractOrDeploy";
import { deployERC20AndFaucet } from "./utils/deployTokens";
import { DisputeKitClassic, KlerosCore } from "../typechain-types";
import { ChainlinkRNG, DisputeKitClassic, KlerosCore } from "../typechain-types";

const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const { ethers, deployments, getNamedAccounts, getChainId } = hre;
Expand All @@ -28,30 +28,6 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)

await getContractOrDeployUpgradable(hre, "EvidenceModule", { from: deployer, args: [deployer], log: true });

// Randomizer.ai: https://randomizer.ai/docs#addresses
const randomizerOracle = await getContractOrDeploy(hre, "RandomizerOracle", {
from: deployer,
contract: "RandomizerMock", // The mock is deployed only on the Hardhat network
args: [],
log: true,
});

const randomizerRng = await getContractOrDeployUpgradable(hre, "RandomizerRNG", {
from: deployer,
args: [randomizerOracle.target, deployer],
log: true,
});

const blockhashRng = await getContractOrDeploy(hre, "BlockHashRNG", {
from: deployer,
args: [],
log: true,
});

// RNG fallback on Arbitrum Sepolia because the Randomizer.ai oracle contract is unverified and not officially supported.
const rng = isMainnet(hre.network) ? randomizerRng : blockhashRng;
console.log(isMainnet(hre.network) ? "using RandomizerRNG on mainnet" : "using BlockHashRNG on testnet/devnet");

const disputeKit = await deployUpgradable(deployments, "DisputeKitClassic", {
from: deployer,
args: [deployer, ZeroAddress],
Expand All @@ -67,6 +43,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const devnet = isDevnet(hre.network);
const minStakingTime = devnet ? 180 : 1800;
const maxFreezingTime = devnet ? 600 : 1800;
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],
Expand All @@ -83,7 +60,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
deployer,
deployer,
pnk.target,
ZeroAddress,
ZeroAddress, // KlerosCore is configured later
disputeKit.address,
false,
[minStake, alpha, feeForJuror, jurorsForCourtJump],
Expand All @@ -94,14 +71,21 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
log: true,
}); // nonce+2 (implementation), nonce+3 (proxy)

// changeCore() only if necessary
// disputeKit.changeCore() only if necessary
const disputeKitContract = (await ethers.getContract("DisputeKitClassic")) as DisputeKitClassic;
const currentCore = await disputeKitContract.core();
if (currentCore !== klerosCore.address) {
console.log(`disputeKit.changeCore(${klerosCore.address})`);
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);
}

const core = (await hre.ethers.getContract("KlerosCore")) as KlerosCore;
try {
await changeCurrencyRate(core, await pnk.getAddress(), true, 12225583, 12);
Expand All @@ -113,6 +97,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
};

deployArbitration.tags = ["Arbitration"];
deployArbitration.dependencies = ["ChainlinkRNG"];
deployArbitration.skip = async ({ network }) => {
return isSkipped(network, !HomeChains[network.config.chainId ?? 0]);
};
Expand Down
Loading

0 comments on commit 5c43453

Please sign in to comment.