Skip to content

Commit 4467927

Browse files
committed
feat: made more contracts upgradable, fixed state variable init, nonce arithmetics in deploy scripts
1 parent 487fc5b commit 4467927

16 files changed

+251
-105
lines changed

contracts/deploy/00-home-chain-arbitrable.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
22
import { DeployFunction } from "hardhat-deploy/types";
33
import disputeTemplate from "../test/fixtures/DisputeTemplate.simple.json";
44
import { HomeChains, isSkipped } from "./utils";
5+
import { deployUpgradable } from "./utils/deployUpgradable";
56

67
const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
78
const { deployments, getNamedAccounts, getChainId } = hre;
@@ -17,11 +18,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
1718
"0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003"; // General court, 3 jurors
1819
const weth = await deployments.get("WETH");
1920

20-
const disputeTemplateRegistry = await deploy("DisputeTemplateRegistry", {
21-
from: deployer,
22-
args: [],
23-
log: true,
24-
});
21+
const disputeTemplateRegistry = await deployUpgradable(hre, deployer, "DisputeTemplateRegistry", [deployer]);
2522

2623
await deploy("ArbitrableExample", {
2724
from: deployer,

contracts/deploy/00-home-chain-arbitration.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
5252
randomizerByChain.set(HomeChains[HomeChains[chainId]], randomizerMock.address);
5353
}
5454

55-
await deploy("PolicyRegistry", {
56-
from: deployer,
57-
args: [deployer],
58-
log: true,
59-
});
55+
await deployUpgradable(hre, deployer, "PolicyRegistry", [deployer]);
6056

6157
const randomizer = randomizerByChain.get(Number(await getChainId())) ?? AddressZero;
6258
const rng = await deployUpgradable(hre, deployer, "RandomizerRNG", [randomizer, deployer]);
@@ -66,8 +62,8 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
6662
let klerosCoreAddress = await deployments.getOrNull("KlerosCore").then((deployment) => deployment?.address);
6763
if (!klerosCoreAddress) {
6864
const nonce = await ethers.provider.getTransactionCount(deployer);
69-
klerosCoreAddress = getContractAddress(deployer, nonce + 3); // Deploying an upgradeable version of SortitionModule requires 2 transactions instead of 1 (implementation then proxy)
70-
console.log("calculated future KlerosCore address for nonce %d: %s", nonce, klerosCoreAddress);
65+
klerosCoreAddress = getContractAddress(deployer, nonce + 3); // deployed on the 4th tx (nonce+3): SortitionModule Impl tx, SortitionModule Proxy tx, KlerosCore Impl tx, KlerosCore Proxy tx
66+
console.log("calculated future KlerosCore address for nonce %d: %s", nonce + 3, klerosCoreAddress);
7167
}
7268

7369
const sortitionModule = await deployUpgradable(hre, deployer, "SortitionModule", [
@@ -77,7 +73,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
7773
1800, // maxFreezingTime
7874
rng.address,
7975
RNG_LOOKAHEAD,
80-
]);
76+
]); // nonce (implementation), nonce+1 (proxy)
8177

8278
const pnk = pnkByChain.get(chainId) ?? AddressZero;
8379
const dai = daiByChain.get(chainId) ?? AddressZero;
@@ -95,7 +91,7 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
9591
[0, 0, 0, 10], // evidencePeriod, commitPeriod, votePeriod, appealPeriod
9692
ethers.utils.hexlify(5), // Extra data for sortition module will return the default value of K
9793
sortitionModule.address,
98-
]);
94+
]); // nonce+2 (implementation), nonce+3 (proxy)
9995

10096
// execute DisputeKitClassic.changeCore() only if necessary
10197
const currentCore = await hre.ethers.getContractAt("DisputeKitClassic", disputeKit.address).then((dk) => dk.core());

contracts/deploy/01-foreign-gateway-on-ethereum.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
22
import { DeployFunction } from "hardhat-deploy/types";
33
import getContractAddress from "./utils/getContractAddress";
44
import { KlerosCore__factory } from "../typechain-types";
5-
import { ForeignChains, HardhatChain, isSkipped } from "./utils";
5+
import { ForeignChains, isSkipped } from "./utils";
6+
import { deployUpgradable } from "./utils/deployUpgradable";
67

78
const deployForeignGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
89
const { ethers, deployments, getNamedAccounts, getChainId, config } = hre;
@@ -24,7 +25,7 @@ const deployForeignGateway: DeployFunction = async (hre: HardhatRuntimeEnvironme
2425
// TODO: use deterministic deployments
2526
const homeChainProvider = new ethers.providers.JsonRpcProvider(homeNetworks[ForeignChains[chainId]].url);
2627
let nonce = await homeChainProvider.getTransactionCount(deployer);
27-
nonce += 2; // HomeGatewayToEthereum deploy tx will the third tx after this on its home network, so we add two to the current nonce.
28+
nonce += 1; // HomeGatewayToEthereum Proxy deploy tx will be the 2nd tx after this on its home network, so we add 1 to the current nonce.
2829
const homeGatewayAddress = getContractAddress(deployer, nonce);
2930
console.log("Calculated future HomeGatewayToEthereum address for nonce %d: %s", nonce, homeGatewayAddress);
3031

@@ -33,21 +34,24 @@ const deployForeignGateway: DeployFunction = async (hre: HardhatRuntimeEnvironme
3334

3435
const homeChainId = (await homeChainProvider.getNetwork()).chainId;
3536
const homeChainIdAsBytes32 = hexZeroPad(hexlify(homeChainId), 32);
36-
await deploy("ForeignGatewayOnEthereum", {
37-
from: deployer,
38-
contract: "ForeignGateway",
39-
args: [deployer, veaOutbox.address, homeChainIdAsBytes32, homeGatewayAddress],
40-
gasLimit: 4000000,
41-
log: true,
42-
});
37+
await deployUpgradable(
38+
hre,
39+
deployer,
40+
"ForeignGatewayOnEthereum",
41+
[deployer, veaOutbox.address, homeChainIdAsBytes32, homeGatewayAddress],
42+
{
43+
contract: "ForeignGateway",
44+
gasLimit: 4000000,
45+
}
46+
);
4347

4448
// TODO: disable the gateway until fully initialized with the correct fees OR allow disputeCreators to add funds again if necessary.
4549
const coreDeployment = await hre.companionNetworks.home.deployments.get("KlerosCore");
4650
const core = await KlerosCore__factory.connect(coreDeployment.address, homeChainProvider);
4751
// TODO: set up the correct fees for the FORKING_COURT
4852
const courtId = await core.GENERAL_COURT();
4953
const fee = (await core.courts(courtId)).feeForJuror;
50-
await execute("ForeignGatewayOnGnosis", { from: deployer, log: true }, "changeCourtJurorFee", courtId, fee);
54+
await execute("ForeignGatewayOnEthereum", { from: deployer, log: true }, "changeCourtJurorFee", courtId, fee);
5155
// TODO: set up the correct fees for the lower courts
5256
};
5357

contracts/deploy/01-foreign-gateway-on-gnosis.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { DeployFunction } from "hardhat-deploy/types";
44
import getContractAddress from "./utils/getContractAddress";
55
import { KlerosCore__factory } from "../typechain-types";
66
import { ForeignChains, isSkipped } from "./utils";
7+
import { deployUpgradable } from "./utils/deployUpgradable";
78

89
const ONE_GWEI = parseUnits("1", "gwei");
910

@@ -26,9 +27,8 @@ const deployForeignGateway: DeployFunction = async (hre: HardhatRuntimeEnvironme
2627
// Hack to predict the deployment address on the home chain.
2728
// TODO: use deterministic deployments
2829
const homeChainProvider = new ethers.providers.JsonRpcProvider(homeNetworks[ForeignChains[chainId]].url);
29-
const nonce = await homeChainProvider.getTransactionCount(deployer);
30-
31-
// FIXME: this computed address is wrong for deploys to testnets, okay on Hardhat
30+
let nonce = await homeChainProvider.getTransactionCount(deployer);
31+
nonce += 1; // HomeGatewayToEthereum Proxy deploy tx will be the 2nd tx after this on its home network, so we add 1 to the current nonce.
3232
const homeGatewayAddress = getContractAddress(deployer, nonce); // HomeGateway deploy tx will be the next tx home network
3333
console.log("Calculated future HomeGatewayToEthereum address for nonce %d: %s", nonce, homeGatewayAddress);
3434

@@ -37,14 +37,17 @@ const deployForeignGateway: DeployFunction = async (hre: HardhatRuntimeEnvironme
3737

3838
const homeChainId = (await homeChainProvider.getNetwork()).chainId;
3939
const homeChainIdAsBytes32 = hexZeroPad(hexlify(homeChainId), 32);
40-
await deploy("ForeignGatewayOnGnosis", {
41-
from: deployer,
42-
contract: "ForeignGateway",
43-
args: [deployer, veaOutbox.address, homeChainIdAsBytes32, homeGatewayAddress],
44-
log: true,
45-
maxFeePerGas: ONE_GWEI,
46-
maxPriorityFeePerGas: ONE_GWEI,
47-
});
40+
await deployUpgradable(
41+
hre,
42+
deployer,
43+
"ForeignGatewayOnGnosis",
44+
[deployer, veaOutbox.address, homeChainIdAsBytes32, homeGatewayAddress],
45+
{
46+
contract: "ForeignGateway",
47+
maxFeePerGas: ONE_GWEI,
48+
maxPriorityFeePerGas: ONE_GWEI,
49+
}
50+
);
4851

4952
// TODO: disable the gateway until fully initialized with the correct fees OR allow disputeCreators to add funds again if necessary.
5053
const coreDeployment = await hre.companionNetworks.home.deployments.get("KlerosCore");

contracts/deploy/02-home-gateway-to-ethereum.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
22
import { DeployFunction } from "hardhat-deploy/types";
33
import { ethers } from "hardhat";
44
import { HardhatChain, HomeChains, isSkipped } from "./utils";
5+
import { deployUpgradable } from "./utils/deployUpgradable";
56

67
// TODO: use deterministic deployments
78

@@ -22,19 +23,20 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
2223
const foreignChainName = await hre.companionNetworks.foreignGoerli.deployments.getNetworkName();
2324
console.log("Using ForeignGateway %s on chainId %s (%s)", foreignGateway.address, foreignChainId, foreignChainName);
2425

25-
await deploy("HomeGatewayToEthereum", {
26-
from: deployer,
27-
contract: "HomeGateway",
28-
args: [
26+
await deployUpgradable(
27+
hre,
28+
deployer,
29+
"HomeGatewayToEthereum",
30+
[
2931
deployer,
3032
klerosCore.address,
3133
veaInbox.address,
3234
foreignChainId,
3335
foreignGateway.address,
3436
ethers.constants.AddressZero, // feeToken is ETH
3537
],
36-
log: true,
37-
}); // nonce+0
38+
{ contract: "HomeGateway" }
39+
); // nonce+0
3840
};
3941

4042
deployHomeGateway.tags = ["HomeGatewayToEthereum"];

contracts/deploy/02-home-gateway-to-gnosis.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { HardhatRuntimeEnvironment } from "hardhat/types";
22
import { DeployFunction } from "hardhat-deploy/types";
33
import { HardhatChain, HomeChains, isSkipped } from "./utils";
4+
import { deployUpgradable } from "./utils/deployUpgradable";
45

56
// TODO: use deterministic deployments
67

@@ -22,12 +23,13 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
2223
const foreignChainName = await hre.companionNetworks.foreignChiado.deployments.getNetworkName();
2324
console.log("Using ForeignGateway %s on chainId %s (%s)", foreignGateway.address, foreignChainId, foreignChainName);
2425

25-
await deploy("HomeGatewayToGnosis", {
26-
from: deployer,
27-
contract: "HomeGateway",
28-
args: [deployer, klerosCore.address, veaInbox.address, foreignChainId, foreignGateway.address, dai.address],
29-
log: true,
30-
}); // nonce+0
26+
await deployUpgradable(
27+
hre,
28+
deployer,
29+
"HomeGatewayToGnosis",
30+
[deployer, klerosCore.address, veaInbox.address, foreignChainId, foreignGateway.address, dai.address],
31+
{ contract: "HomeGateway" }
32+
); // nonce+0
3133
};
3234

3335
deployHomeGateway.tags = ["HomeGatewayToGnosis"];

contracts/deploy/03-vea-mock.ts

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import getContractAddress from "./utils/getContractAddress";
44
import { KlerosCore__factory } from "../typechain-types";
55
import disputeTemplate from "../test/fixtures/DisputeTemplate.simple.json";
66
import { HardhatChain, isSkipped } from "./utils";
7+
import { deployUpgradable } from "./utils/deployUpgradable";
78

89
// TODO: use deterministic deployments
910

@@ -23,33 +24,42 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
2324
log: true,
2425
});
2526

26-
const nonce = await ethers.provider.getTransactionCount(deployer);
27-
const homeGatewayAddress = getContractAddress(deployer, nonce + 1);
27+
let nonce = await ethers.provider.getTransactionCount(deployer);
28+
nonce += 3; // deployed on the 4th tx (nonce+3): SortitionModule Impl tx, SortitionModule Proxy tx, KlerosCore Impl tx, KlerosCore Proxy tx
29+
const homeGatewayAddress = getContractAddress(deployer, nonce);
2830
console.log("Calculated future HomeGatewayToEthereum address for nonce %d: %s", nonce, homeGatewayAddress);
2931

3032
const homeChainIdAsBytes32 = hexZeroPad(hexlify(HardhatChain.HARDHAT), 32);
31-
const foreignGateway = await deploy("ForeignGatewayOnEthereum", {
32-
from: deployer,
33-
contract: "ForeignGateway",
34-
args: [deployer, vea.address, homeChainIdAsBytes32, homeGatewayAddress],
35-
gasLimit: 4000000,
36-
log: true,
37-
}); // nonce+0
33+
const foreignGateway = await deployUpgradable(
34+
hre,
35+
deployer,
36+
"ForeignGatewayOnEthereum",
37+
[deployer, vea.address, homeChainIdAsBytes32, homeGatewayAddress],
38+
{
39+
contract: "ForeignGateway",
40+
gasLimit: 4000000,
41+
}
42+
); // nonce (implementation), nonce+1 (proxy)
43+
console.log("foreignGateway.address: ", foreignGateway.address);
3844

39-
await deploy("HomeGatewayToEthereum", {
40-
from: deployer,
41-
contract: "HomeGateway",
42-
args: [
45+
await deployUpgradable(
46+
hre,
47+
deployer,
48+
"HomeGatewayToEthereum",
49+
[
4350
deployer,
4451
klerosCore.address,
4552
vea.address,
4653
HardhatChain.HARDHAT,
4754
foreignGateway.address,
4855
ethers.constants.AddressZero, // feeToken
4956
],
50-
gasLimit: 4000000,
51-
log: true,
52-
}); // nonce+1
57+
{
58+
contract: "HomeGateway",
59+
gasLimit: 4000000,
60+
log: true,
61+
}
62+
); // nonce+2 (implementation), nonce+3 (proxy)
5363

5464
// TODO: disable the gateway until fully initialized with the correct fees OR allow disputeCreators to add funds again if necessary.
5565
const signer = (await hre.ethers.getSigners())[0];
@@ -60,11 +70,7 @@ const deployHomeGateway: DeployFunction = async (hre: HardhatRuntimeEnvironment)
6070
await execute("ForeignGatewayOnEthereum", { from: deployer, log: true }, "changeCourtJurorFee", courtId, fee);
6171
// TODO: set up the correct fees for the lower courts
6272

63-
const disputeTemplateRegistry = await deploy("DisputeTemplateRegistry", {
64-
from: deployer,
65-
args: [],
66-
log: true,
67-
});
73+
const disputeTemplateRegistry = await deployUpgradable(hre, deployer, "DisputeTemplateRegistry", [deployer]);
6874

6975
// TODO: debug why this extraData fails but "0x00" works
7076
// const extraData =

contracts/deploy/utils/deployUpgradable.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { DeployResult } from "hardhat-deploy/types";
1+
import { DeployResult, DeployOptions } from "hardhat-deploy/types";
22
import { HardhatRuntimeEnvironment } from "hardhat/types";
33

44
export function deployUpgradable(
55
hre: HardhatRuntimeEnvironment,
66
deployer: string,
77
contract: string,
8-
params: any[]
8+
params: any[],
9+
deployOptions?: Omit<DeployOptions, "from">
910
): Promise<DeployResult> {
1011
const { deploy } = hre.deployments;
1112
return deploy(contract, {
@@ -27,5 +28,6 @@ export function deployUpgradable(
2728
},
2829
},
2930
log: true,
31+
...deployOptions,
3032
});
3133
}

contracts/src/arbitration/DisputeTemplateRegistry.sol

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,70 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity 0.8.18;
33

4+
import "../proxy/UUPSProxiable.sol";
5+
import "../proxy/Initializable.sol";
46
import "./interfaces/IDisputeTemplateRegistry.sol";
57

68
/// @title Dispute Template Registry
79
/// @dev A contract to maintain a registry of dispute templates.
8-
contract DisputeTemplateRegistry is IDisputeTemplateRegistry {
9-
uint256 public templates;
10+
contract DisputeTemplateRegistry is IDisputeTemplateRegistry, UUPSProxiable, Initializable {
11+
// ************************************* //
12+
// * Storage * //
13+
// ************************************* //
14+
15+
address public governor; // The address that can withdraw funds.
16+
uint256 public templates; // The number of templates.
17+
18+
// ************************************* //
19+
// * Function Modifiers * //
20+
// ************************************* //
21+
22+
modifier onlyByGovernor() {
23+
require(governor == msg.sender, "Governor only");
24+
_;
25+
}
26+
27+
// ************************************* //
28+
// * Constructor * //
29+
// ************************************* //
30+
31+
/// @dev Constructor, initializing the implementation to reduce attack surface.
32+
constructor() {
33+
_disableInitializers();
34+
}
35+
36+
/// @dev Initializer
37+
/// @param _governor Governor of the contract.
38+
function initialize(address _governor) external reinitializer(1) {
39+
governor = _governor;
40+
}
41+
42+
// ************************ //
43+
// * Governance * //
44+
// ************************ //
45+
46+
/**
47+
* @dev Access Control to perform implementation upgrades (UUPS Proxiable)
48+
* @dev Only the governor can perform upgrades (`onlyByGovernor`)
49+
*/
50+
function _authorizeUpgrade(address) internal view override onlyByGovernor {
51+
// NOP
52+
}
53+
54+
/// @dev Changes the governor of the contract.
55+
/// @param _governor The new governor.
56+
function changeGovernor(address _governor) external onlyByGovernor {
57+
governor = _governor;
58+
}
1059

1160
// ************************************* //
1261
// * State Modifiers * //
1362
// ************************************* //
1463

64+
/// @dev Registers a new dispute template.
65+
/// @param _templateTag The tag of the template (optional).
66+
/// @param _templateData The data of the template.
67+
/// @param _templateDataMappings The data mappings of the template.
1568
function setDisputeTemplate(
1669
string memory _templateTag,
1770
string memory _templateData,

0 commit comments

Comments
 (0)