Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgradability improvements and bumped hardhat-deploy #1274

Merged
merged 5 commits into from
Oct 16, 2023
Merged
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
2 changes: 1 addition & 1 deletion contracts/deploy/00-home-chain-arbitrable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
"0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003"; // General court, 3 jurors
const weth = await deployments.get("WETH");

const disputeTemplateRegistry = await deployUpgradable(hre, "DisputeTemplateRegistry", {
const disputeTemplateRegistry = await deployUpgradable(deployments, "DisputeTemplateRegistry", {
from: deployer,
args: [deployer],
log: true,
Expand Down
14 changes: 9 additions & 5 deletions contracts/deploy/00-home-chain-arbitration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,16 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
randomizerByChain.set(HomeChains[HomeChains[chainId]], randomizerMock.address);
}

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

const randomizer = randomizerByChain.get(Number(await getChainId())) ?? AddressZero;
const rng = await deployUpgradable(hre, "RandomizerRNG", { from: deployer, args: [randomizer, deployer], log: true });
const rng = await deployUpgradable(deployments, "RandomizerRNG", {
from: deployer,
args: [randomizer, deployer],
log: true,
});

const disputeKit = await deployUpgradable(hre, "DisputeKitClassic", {
const disputeKit = await deployUpgradable(deployments, "DisputeKitClassic", {
from: deployer,
args: [deployer, AddressZero],
log: true,
Expand All @@ -72,7 +76,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const devnet = isDevnet(hre.network);
const minStakingTime = devnet ? 180 : 1800;
const maxFreezingTime = devnet ? 600 : 1800;
const sortitionModule = await deployUpgradable(hre, "SortitionModule", {
const sortitionModule = await deployUpgradable(deployments, "SortitionModule", {
from: deployer,
args: [deployer, klerosCoreAddress, minStakingTime, maxFreezingTime, rng.address, RNG_LOOKAHEAD],
log: true,
Expand All @@ -84,7 +88,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const minStake = BigNumber.from(10).pow(20).mul(2);
const alpha = 10000;
const feeForJuror = BigNumber.from(10).pow(17);
const klerosCore = await deployUpgradable(hre, "KlerosCore", {
const klerosCore = await deployUpgradable(deployments, "KlerosCore", {
from: deployer,
args: [
deployer,
Expand Down
2 changes: 1 addition & 1 deletion contracts/deploy/00-rng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
}

const randomizer = randomizerByChain.get(Number(await getChainId())) ?? AddressZero;
await deployUpgradable(hre, "RandomizerRNG", { from: deployer, args: [randomizer, deployer], log: true });
await deployUpgradable(deployments, "RandomizerRNG", { from: deployer, args: [randomizer, deployer], log: true });
const rng = await deploy("BlockHashRNG", {
from: deployer,
args: [],
Expand Down
2 changes: 1 addition & 1 deletion contracts/deploy/01-foreign-gateway-on-ethereum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const deployForeignGateway: DeployFunction = async (hre: HardhatRuntimeEnvironme

const homeChainId = (await homeChainProvider.getNetwork()).chainId;
const homeChainIdAsBytes32 = hexZeroPad(hexlify(homeChainId), 32);
await deployUpgradable(hre, "ForeignGatewayOnEthereum", {
await deployUpgradable(deployments, "ForeignGatewayOnEthereum", {
from: deployer,
contract: "ForeignGateway",
args: [deployer, veaOutbox.address, homeChainIdAsBytes32, homeGatewayAddress],
Expand Down
2 changes: 1 addition & 1 deletion contracts/deploy/01-foreign-gateway-on-gnosis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const deployForeignGateway: DeployFunction = async (hre: HardhatRuntimeEnvironme

const homeChainId = (await homeChainProvider.getNetwork()).chainId;
const homeChainIdAsBytes32 = hexZeroPad(hexlify(homeChainId), 32);
await deployUpgradable(hre, "ForeignGatewayOnGnosis", {
await deployUpgradable(deployments, "ForeignGatewayOnGnosis", {
from: deployer,
contract: "ForeignGateway",
args: [deployer, veaOutbox.address, homeChainIdAsBytes32, homeGatewayAddress],
Expand Down
2 changes: 1 addition & 1 deletion contracts/deploy/02-home-gateway-to-ethereum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const foreignChainName = await hre.companionNetworks.foreignGoerli.deployments.getNetworkName();
console.log("Using ForeignGateway %s on chainId %s (%s)", foreignGateway.address, foreignChainId, foreignChainName);

await deployUpgradable(hre, "HomeGatewayToEthereum", {
await deployUpgradable(deployments, "HomeGatewayToEthereum", {
from: deployer,
contract: "HomeGateway",
args: [
Expand Down
2 changes: 1 addition & 1 deletion contracts/deploy/02-home-gateway-to-gnosis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
const foreignChainName = await hre.companionNetworks.foreignChiado.deployments.getNetworkName();
console.log("Using ForeignGateway %s on chainId %s (%s)", foreignGateway.address, foreignChainId, foreignChainName);

await deployUpgradable(hre, "HomeGatewayToGnosis", {
await deployUpgradable(deployments, "HomeGatewayToGnosis", {
from: deployer,
contract: "HomeGateway",
args: [deployer, klerosCore.address, veaInbox.address, foreignChainId, foreignGateway.address, dai.address],
Expand Down
6 changes: 3 additions & 3 deletions contracts/deploy/03-vea-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
console.log("Calculated future HomeGatewayToEthereum address for nonce %d: %s", nonce, homeGatewayAddress);

const homeChainIdAsBytes32 = hexZeroPad(hexlify(HardhatChain.HARDHAT), 32);
const foreignGateway = await deployUpgradable(hre, "ForeignGatewayOnEthereum", {
const foreignGateway = await deployUpgradable(deployments, "ForeignGatewayOnEthereum", {
from: deployer,
contract: "ForeignGateway",
args: [deployer, vea.address, homeChainIdAsBytes32, homeGatewayAddress],
Expand All @@ -39,7 +39,7 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
}); // nonce (implementation), nonce+1 (proxy)
console.log("foreignGateway.address: ", foreignGateway.address);

await deployUpgradable(hre, "HomeGatewayToEthereum", {
await deployUpgradable(deployments, "HomeGatewayToEthereum", {
from: deployer,
contract: "HomeGateway",
args: [
Expand All @@ -62,7 +62,7 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
await execute("ForeignGatewayOnEthereum", { from: deployer, log: true }, "changeCourtJurorFee", Courts.GENERAL, fee);
// TODO: set up the correct fees for the lower courts

const disputeTemplateRegistry = await deployUpgradable(hre, "DisputeTemplateRegistry", {
const disputeTemplateRegistry = await deployUpgradable(deployments, "DisputeTemplateRegistry", {
from: deployer,
args: [deployer],
log: true,
Expand Down
2 changes: 1 addition & 1 deletion contracts/deploy/upgrade-kleros-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const deployUpgradeKlerosCore: DeployFunction = async (hre: HardhatRuntimeEnviro
const sortitionModule = await deployments.get("SortitionModule");

console.log("Upgrading the KlerosCore...");
await deployUpgradable(hre, "KlerosCore", {
await deployUpgradable(deployments, "KlerosCore", {
from: deployer,
args: [
deployer,
Expand Down
2 changes: 1 addition & 1 deletion contracts/deploy/upgrade-sortition-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const deployUpgradeSortitionModule: DeployFunction = async (hre: HardhatRuntimeE
const klerosCoreAddress = klerosCore.address;

console.log("Upgrading the SortitionModule...");
await deployUpgradable(hre, "SortitionModule", {
await deployUpgradable(deployments, "SortitionModule", {
from: deployer,
args: [
deployer,
Expand Down
84 changes: 62 additions & 22 deletions contracts/deploy/utils/deployUpgradable.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,70 @@
import { DeployResult, DeployOptions } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";

export function deployUpgradable(
hre: HardhatRuntimeEnvironment,
contract: string,
options: DeployOptions
): Promise<DeployResult> {
const { deploy } = hre.deployments;
const { args, ...otherOptions } = options;
return deploy(contract, {
import {
DeployResult,
DeployOptions,
DeploymentsExtension,
DeployOptionsBase,
ProxyOptions,
} from "hardhat-deploy/types";

// Rationale: https://github.com/kleros/kleros-v2/pull/1214#issue-1879116629
const PROXY_OPTIONS: ProxyOptions = {
proxyContract: "UUPSProxy",
proxyArgs: ["{implementation}", "{data}"],
checkProxyAdmin: false, // Not relevant for UUPSProxy
checkABIConflict: false, // Not relevant for UUPSProxy
upgradeFunction: {
methodName: "upgradeToAndCall",
upgradeArgs: ["{implementation}", "{data}"],
},
};

type DeployUpgradableOptions = {
newImplementation?: string;
initializer?: string;
} & DeployOptionsBase;

export const deployUpgradable = async (
deployments: DeploymentsExtension,
proxy: string,
options: DeployUpgradableOptions
): Promise<DeployResult> => {
const { deploy } = deployments;
const { newImplementation, initializer, args: initializerArgs, ...otherOptions } = options;

const methodName = initializer ?? "initialize";
const args = initializerArgs ?? [];

const contract: Partial<DeployOptions> = newImplementation
? {
contract: newImplementation,
}
: {};

const implementationName: Partial<ProxyOptions> = newImplementation
? {
implementationName: newImplementation + "_Implementation",
}
: {};

const fullOptions: DeployOptions = {
...otherOptions,
...contract,
proxy: {
proxyContract: "UUPSProxy",
proxyArgs: ["{implementation}", "{data}"],
checkProxyAdmin: false,
checkABIConflict: false,
...PROXY_OPTIONS,
...implementationName,
execute: {
init: {
methodName: "initialize",
args: args ?? [],
methodName,
args,
},
onUpgrade: {
methodName: "governor",
args: [],
methodName,
args,
},
},
},
...otherOptions,
});
}
};

// console.debug("fullOptions: ", JSON.stringify(fullOptions));
return deploy(proxy, fullOptions);
};
2 changes: 1 addition & 1 deletion contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"graphql-request": "^6.1.0",
"hardhat": "^2.15.0",
"hardhat-contract-sizer": "^2.10.0",
"hardhat-deploy": "^0.11.37",
"hardhat-deploy": "^0.11.42",
"hardhat-deploy-ethers": "^0.4.0-next.1",
"hardhat-deploy-tenderly": "^0.2.0",
"hardhat-docgen": "^1.3.0",
Expand Down
11 changes: 5 additions & 6 deletions contracts/src/arbitration/KlerosCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
uint256 private constant ALPHA_DIVISOR = 1e4; // The number to divide `Court.alpha` by.
uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2) / 2; // An amount higher than the supply of ETH.
uint256 private constant SEARCH_ITERATIONS = 10; // Number of iterations to search for suitable parent court before jumping to the top court.
IERC20 private constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.

address public governor; // The governor of the contract.
IERC20 public pinakion; // The Pinakion token contract.
Expand Down Expand Up @@ -516,7 +515,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
) external payable override returns (uint256 disputeID) {
if (msg.value < arbitrationCost(_extraData)) revert ArbitrationFeesNotEnough();

return _createDispute(_numberOfChoices, _extraData, NATIVE_CURRENCY, msg.value);
return _createDispute(_numberOfChoices, _extraData, Constants.NATIVE_CURRENCY, msg.value);
}

/// @inheritdoc IArbitratorV2
Expand Down Expand Up @@ -553,7 +552,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
Round storage round = dispute.rounds.push();

// Obtain the feeForJuror in the same currency as the _feeAmount
uint256 feeForJuror = (_feeToken == NATIVE_CURRENCY)
uint256 feeForJuror = (_feeToken == Constants.NATIVE_CURRENCY)
? court.feeForJuror
: convertEthToTokenAmount(_feeToken, court.feeForJuror);
round.nbVotes = _feeAmount / feeForJuror;
Expand Down Expand Up @@ -810,7 +809,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
}
if (_params.repartition == _params.numberOfVotesInRound - 1 && _params.coherentCount == 0) {
// No one was coherent, send the rewards to the governor.
if (round.feeToken == NATIVE_CURRENCY) {
if (round.feeToken == Constants.NATIVE_CURRENCY) {
// The dispute fees were paid in ETH
payable(governor).send(round.totalFeesForJurors);
} else {
Expand Down Expand Up @@ -865,7 +864,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
uint256 feeReward = ((round.totalFeesForJurors / _params.coherentCount) * degreeOfCoherence) / ALPHA_DIVISOR;
round.sumFeeRewardPaid += feeReward;
pinakion.safeTransfer(account, pnkReward);
if (round.feeToken == NATIVE_CURRENCY) {
if (round.feeToken == Constants.NATIVE_CURRENCY) {
// The dispute fees were paid in ETH
payable(account).send(feeReward);
} else {
Expand All @@ -891,7 +890,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
pinakion.safeTransfer(governor, leftoverPnkReward);
}
if (leftoverFeeReward != 0) {
if (round.feeToken == NATIVE_CURRENCY) {
if (round.feeToken == Constants.NATIVE_CURRENCY) {
// The dispute fees were paid in ETH
payable(governor).send(leftoverFeeReward);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ contract DisputeKitSybilResistant is IDisputeKit, IEvidence, Initializable, UUPS
/// @dev Initializer.
/// @param _governor The governor's address.
/// @param _core The KlerosCore arbitrator.
/// @param _poh The Proof of Humanity registry.
function initialize(address _governor, KlerosCore _core, IProofOfHumanity _poh) external reinitializer(1) {
governor = _governor;
core = _core;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

pragma solidity 0.8.18;

import "./IArbitratorV2.sol";

/// @title IDisputeTemplate
/// @notice Dispute Template interface.
interface IDisputeTemplateRegistry {
Expand Down
9 changes: 6 additions & 3 deletions contracts/src/gateway/ForeignGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pragma solidity 0.8.18;
import "./interfaces/IForeignGateway.sol";
import "../proxy/UUPSProxiable.sol";
import "../proxy/Initializable.sol";
import "../libraries/Constants.sol";

/// Foreign Gateway
/// Counterpart of `HomeGateway`
Expand All @@ -37,7 +38,6 @@ contract ForeignGateway is IForeignGateway, UUPSProxiable, Initializable {
// * Storage * //
// ************************************* //

uint256 public constant DEFAULT_NB_OF_JURORS = 3; // The default number of jurors in a dispute.
uint256 internal localDisputeID; // The disputeID must start from 1 as the KlerosV1 proxy governor depends on this implementation. We now also depend on localDisputeID not ever being zero.
mapping(uint96 => uint256) public feeForJuror; // feeForJuror[v2CourtID], it mirrors the value on KlerosCore.
address public governor;
Expand Down Expand Up @@ -78,6 +78,9 @@ contract ForeignGateway is IForeignGateway, UUPSProxiable, Initializable {

/// @dev Constructs the `PolicyRegistry` contract.
/// @param _governor The governor's address.
/// @param _veaOutbox The address of the VeaOutbox.
/// @param _homeChainID The chainID of the home chain.
/// @param _homeGateway The address of the home gateway.
function initialize(
address _governor,
address _veaOutbox,
Expand Down Expand Up @@ -263,10 +266,10 @@ contract ForeignGateway is IForeignGateway, UUPSProxiable, Initializable {
minJurors := mload(add(_extraData, 0x40))
}
if (feeForJuror[courtID] == 0) courtID = 0;
if (minJurors == 0) minJurors = DEFAULT_NB_OF_JURORS;
if (minJurors == 0) minJurors = Constants.DEFAULT_NB_OF_JURORS;
} else {
courtID = 0;
minJurors = DEFAULT_NB_OF_JURORS;
minJurors = Constants.DEFAULT_NB_OF_JURORS;
}
}
}
11 changes: 8 additions & 3 deletions contracts/src/gateway/HomeGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pragma solidity 0.8.18;
import "./interfaces/IForeignGateway.sol";
import "./interfaces/IHomeGateway.sol";
import "../libraries/SafeERC20.sol";
import "../libraries/Constants.sol";
import "../proxy/UUPSProxiable.sol";
import "../proxy/Initializable.sol";

Expand All @@ -32,7 +33,6 @@ contract HomeGateway is IHomeGateway, UUPSProxiable, Initializable {
// * Storage * //
// ************************************* //

IERC20 public constant NATIVE_CURRENCY = IERC20(address(0)); // The native currency, such as ETH on Arbitrum, Optimism and Ethereum L1.
address public governor;
IArbitratorV2 public arbitrator;
IVeaInbox public veaInbox;
Expand Down Expand Up @@ -64,6 +64,11 @@ contract HomeGateway is IHomeGateway, UUPSProxiable, Initializable {

/// @dev Constructs the `PolicyRegistry` contract.
/// @param _governor The governor's address.
/// @param _arbitrator The address of the arbitrator.
/// @param _veaInbox The address of the vea inbox.
/// @param _foreignChainID The ID of the foreign chain.
/// @param _foreignGateway The address of the foreign gateway.
/// @param _feeToken The address of the fee token.
function initialize(
address _governor,
IArbitratorV2 _arbitrator,
Expand Down Expand Up @@ -128,7 +133,7 @@ contract HomeGateway is IHomeGateway, UUPSProxiable, Initializable {

/// @inheritdoc IHomeGateway
function relayCreateDispute(RelayCreateDisputeParams memory _params) external payable override {
require(feeToken == NATIVE_CURRENCY, "Fees paid in ERC20 only");
require(feeToken == Constants.NATIVE_CURRENCY, "Fees paid in ERC20 only");
require(_params.foreignChainID == foreignChainID, "Foreign chain ID not supported");

bytes32 disputeHash = keccak256(
Expand Down Expand Up @@ -166,7 +171,7 @@ contract HomeGateway is IHomeGateway, UUPSProxiable, Initializable {

/// @inheritdoc IHomeGateway
function relayCreateDispute(RelayCreateDisputeParams memory _params, uint256 _feeAmount) external {
require(feeToken != NATIVE_CURRENCY, "Fees paid in native currency only");
require(feeToken != Constants.NATIVE_CURRENCY, "Fees paid in native currency only");
require(_params.foreignChainID == foreignChainID, "Foreign chain ID not supported");

bytes32 disputeHash = keccak256(
Expand Down
Loading