Skip to content

Commit f3f5f16

Browse files
authored
feat: sepolia deployments (#4717)
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
1 parent c389e70 commit f3f5f16

22 files changed

+561
-37
lines changed

packages/common/src/Constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
export const interfaceName = {
33
FinancialContractsAdmin: "FinancialContractsAdmin",
44
Oracle: "Oracle",
5+
VotingV2: "Oracle",
56
Registry: "Registry",
67
Store: "Store",
78
IdentifierWhitelist: "IdentifierWhitelist",
@@ -14,6 +15,7 @@ export const interfaceName = {
1415
MockOracleAncillary: "Oracle",
1516
SinkOracle: "Oracle",
1617
SkinnyOptimisticOracle: "SkinnyOptimisticOracle",
18+
SkinnyOptimisticOracleV2: "SkinnyOptimisticOracleV2",
1719
ChildMessenger: "ChildMessenger",
1820
OracleSpoke: "OracleSpoke",
1921
OracleHub: "OracleHub",

packages/common/src/Enums.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,10 @@ export const InsuredBridgeRelayStateEnum = {
4545
PENDING: "1",
4646
FINALIZED: "2",
4747
};
48+
49+
// Corresponds to GovernorV2.Roles.
50+
export const GovernorV2RolesEnum = {
51+
OWNER: "0",
52+
PROPOSER: "1",
53+
EMERGENCY_PROPOSER: "2",
54+
};

packages/common/src/HardhatConfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export function getHardhatConfig(
111111
},
112112
rinkeby: { chainId: 4, url: getNodeUrl("rinkeby", true, 4), accounts: { mnemonic } },
113113
goerli: { chainId: 5, url: getNodeUrl("goerli", true, 5), accounts: { mnemonic } },
114+
sepolia: { chainId: 11155111, url: getNodeUrl("sepolia", true, 11155111), accounts: { mnemonic } },
114115
"base-goerli": { chainId: 84531, url: getNodeUrl("base-goerli", true, 84531), accounts: { mnemonic } },
115116
"blast-sepolia": {
116117
chainId: 168587773,

packages/common/src/hardhat/tasks/collateralWhitelist.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,41 @@ const wrappedTokenBridgeAbi: AbiItem[] = [
6969
},
7070
];
7171

72+
task("whitelist-collateral", "Approve single currency to collateral whitelist and set its final fee")
73+
.addParam("address", "Collateral address to whitelist", "", types.string)
74+
.addParam("finalfee", "Raw amount of final fee to set in Store", "0", types.string)
75+
.setAction(async function (taskArguments, hre_) {
76+
const hre = hre_ as CombinedHRE;
77+
const { deployments, getNamedAccounts, web3 } = hre;
78+
const { deployer } = await getNamedAccounts();
79+
const { address, finalfee } = taskArguments;
80+
81+
const CollateralWhitelist = await deployments.get("AddressWhitelist");
82+
const collateralWhitelist = new web3.eth.Contract(CollateralWhitelist.abi, CollateralWhitelist.address);
83+
console.log(`Using AddressWhitelist @ ${collateralWhitelist.options.address}`);
84+
85+
const isCollateralApproved = await collateralWhitelist.methods.isOnWhitelist(address).call();
86+
if (!isCollateralApproved) {
87+
const txn = await collateralWhitelist.methods.addToWhitelist(address).send({ from: deployer });
88+
console.log(`Added ${address} to AddressWhitelist, tx: ${txn.transactionHash}`);
89+
} else {
90+
console.log(`${address} already is on AddressWhitelist`);
91+
}
92+
93+
const Store = await deployments.get("Store");
94+
const store = new web3.eth.Contract(Store.abi, Store.address);
95+
console.log(`Using Store @ ${store.options.address}`);
96+
97+
const currentFinalFee = (await store.methods.computeFinalFee(address).call()).rawValue;
98+
const matchingFinalFee = currentFinalFee == finalfee;
99+
if (!matchingFinalFee) {
100+
const txn = await store.methods.setFinalFee(address, { rawValue: finalfee }).send({ from: deployer });
101+
console.log(`Set ${address} finalFee in Store to ${finalfee}, tx: ${txn.transactionHash}`);
102+
} else {
103+
console.log(`${address} already has its finalFee set to ${finalfee} in Store`);
104+
}
105+
});
106+
72107
task("migrate-collateral-whitelist", "Migrate collateral whitelist, extracted from one EVM chain to another")
73108
.addParam("l1chainid", "Chain Id of the origin chain (normally 1 for L1 ethereum)", "1", types.string)
74109
.addParam("l2chainid", "Chain Id of the destination chain to write the new whitelist to", "", types.string)
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
import { interfaceName } from "../../Constants";
2+
import { task } from "hardhat/config";
3+
import { Contract } from "web3-eth-contract";
4+
import { CombinedHRE } from "./types";
5+
import { GovernorV2RolesEnum, TokenRolesEnum } from "../../Enums";
6+
import Web3 from "web3";
7+
const { padRight, utf8ToHex } = Web3.utils;
8+
9+
type InterfaceName = keyof typeof interfaceName;
10+
function isInterfaceName(name: string): name is InterfaceName {
11+
return name in interfaceName;
12+
}
13+
14+
const registeredContracts = new Set([
15+
"OptimisticOracle",
16+
"OptimisticOracleV2",
17+
"OptimisticOracleV3",
18+
"SkinnyOptimisticOracle",
19+
"SkinnyOptimisticOracleV2",
20+
"GovernorV2",
21+
"ProposerV2",
22+
]);
23+
24+
// Gets all contract deployments that can be added to the Finder.
25+
async function getContractsForFinder(hre_: CombinedHRE, mockOracle: boolean) {
26+
const { deployments, web3 } = hre_;
27+
28+
const supportedFinderContracts = Object.keys(interfaceName);
29+
const contractsForFinder = new Map<InterfaceName, Contract>();
30+
31+
for (const contractName of supportedFinderContracts) {
32+
if (!isInterfaceName(contractName)) throw new Error(`No mapped interface name for contract name ${contractName}`);
33+
34+
// Depending on mockOracle flag skip either VotingV2 or MockOracleAncillary
35+
if (mockOracle && contractName === "VotingV2") continue;
36+
if (!mockOracle && contractName === "MockOracleAncillary") continue;
37+
38+
try {
39+
const deployed = await deployments.get(contractName);
40+
contractsForFinder.set(contractName, new web3.eth.Contract(deployed.abi, deployed.address));
41+
} catch {
42+
// Do nothing if network does not have this contract deployed.
43+
}
44+
}
45+
46+
return contractsForFinder;
47+
}
48+
49+
// Gets all contract deployments that can be added to the Registry.
50+
async function getContractsForRegistry(hre_: CombinedHRE) {
51+
const { deployments } = hre_;
52+
53+
const contractsForRegistry = new Map<string, string>();
54+
55+
for (const contractName of registeredContracts) {
56+
try {
57+
const deployed = await deployments.get(contractName);
58+
contractsForRegistry.set(contractName, deployed.address);
59+
} catch {
60+
// Do nothing if network does not have this contract deployed.
61+
}
62+
}
63+
64+
return contractsForRegistry;
65+
}
66+
67+
task("setup-dvmv2-testnet", "Configures DVMv2 on L1 testnet")
68+
.addFlag("mockoracle", "Use if you want to set MockOracleAncillary as the Oracle")
69+
.setAction(async function (taskArguments, hre_) {
70+
const hre = hre_ as CombinedHRE;
71+
const { deployments, getNamedAccounts, web3 } = hre;
72+
const { deployer } = await getNamedAccounts();
73+
const { mockoracle } = taskArguments;
74+
75+
/** ***********************************
76+
* Adding contracts to Finder
77+
*************************************/
78+
79+
const Finder = await deployments.get("Finder");
80+
const finder = new web3.eth.Contract(Finder.abi, Finder.address);
81+
console.log(`Using Finder @ ${finder.options.address}`);
82+
83+
const contractsForFinder = await getContractsForFinder(hre, !!mockoracle);
84+
for (const [contractName, contract] of contractsForFinder) {
85+
const nameInFinder = interfaceName[contractName];
86+
87+
const identifierHex = padRight(utf8ToHex(nameInFinder), 64);
88+
const currentlySetAddress = await finder.methods.interfacesImplemented(identifierHex).call();
89+
if (currentlySetAddress !== contract.options.address) {
90+
const txn = await finder.methods
91+
.changeImplementationAddress(identifierHex, contract.options.address)
92+
.send({ from: deployer });
93+
console.log(
94+
`Set ${contractName} in Finder to "${nameInFinder}" @ ${contract.options.address}, tx: ${txn.transactionHash}`
95+
);
96+
} else {
97+
console.log(`Already set ${contractName} in Finder to "${nameInFinder}" @ ${contract.options.address}`);
98+
}
99+
}
100+
101+
/** ***********************************
102+
* Adding contracts to Registry
103+
*************************************/
104+
105+
const contractsForRegistry = await getContractsForRegistry(hre);
106+
for (const [contractName, account] of contractsForRegistry) {
107+
console.log(`Trying to add ${contractName} to Registry`);
108+
await hre.run("register-accounts", { account });
109+
}
110+
111+
/** ***********************************
112+
* Adding minter role for VotingV2
113+
*************************************/
114+
115+
const VotingToken = await deployments.get("VotingToken");
116+
const votingToken = new web3.eth.Contract(VotingToken.abi, VotingToken.address);
117+
console.log(`Using VotingToken @ ${votingToken.options.address}`);
118+
119+
const VotingV2 = await deployments.get("VotingV2");
120+
121+
const hasMinterRole = await votingToken.methods.holdsRole(TokenRolesEnum.MINTER, VotingV2.address).call();
122+
if (!hasMinterRole) {
123+
const txn = await votingToken.methods.addMember(TokenRolesEnum.MINTER, VotingV2.address).send({ from: deployer });
124+
console.log(`Added token minter role to VotingV2 @ ${VotingV2.address}, tx: ${txn.transactionHash}`);
125+
} else {
126+
console.log(`VotingV2 @ ${VotingV2.address} already has token minter role`);
127+
}
128+
129+
/** ***********************************
130+
* Setting up roles for GovernorV2
131+
*************************************/
132+
133+
const GovernorV2 = await deployments.get("GovernorV2");
134+
const governorV2 = new web3.eth.Contract(GovernorV2.abi, GovernorV2.address);
135+
console.log(`Using GovernorV2 @ ${governorV2.options.address}`);
136+
137+
const ProposerV2 = await deployments.get("ProposerV2");
138+
const hasProposerRole = await governorV2.methods.holdsRole(GovernorV2RolesEnum.PROPOSER, ProposerV2.address).call();
139+
if (!hasProposerRole) {
140+
const txn = await governorV2.methods
141+
.resetMember(GovernorV2RolesEnum.PROPOSER, ProposerV2.address)
142+
.send({ from: deployer });
143+
console.log(`Reset proposer role to ProposerV2 @ ${ProposerV2.address}, tx: ${txn.transactionHash}`);
144+
} else {
145+
console.log(`ProposerV2 @ ${ProposerV2.address} already has proposer role`);
146+
}
147+
148+
const EmergencyProposer = await deployments.get("EmergencyProposer");
149+
const hasEmergencyProposerRole = await governorV2.methods
150+
.holdsRole(GovernorV2RolesEnum.EMERGENCY_PROPOSER, EmergencyProposer.address)
151+
.call();
152+
if (!hasEmergencyProposerRole) {
153+
const txn = await governorV2.methods
154+
.resetMember(GovernorV2RolesEnum.EMERGENCY_PROPOSER, EmergencyProposer.address)
155+
.send({ from: deployer });
156+
console.log(
157+
`Reset emergency proposer role to EmergencyProposer @ ${EmergencyProposer.address}, tx: ${txn.transactionHash}`
158+
);
159+
} else {
160+
console.log(`EmergencyProposer @ ${EmergencyProposer.address} already has emergency proposer role`);
161+
}
162+
163+
/** ***********************************
164+
* Sync OptimisticOracleV3
165+
*************************************/
166+
167+
// If Oracle was changed OptimisticOracleV3 requires syncing its cached values. We do this only if already have
168+
// deployed OptimisticOracleV3 for the network.
169+
try {
170+
const OptimisticOracleV3 = await deployments.get("OptimisticOracleV3");
171+
const optimisticOraclev3 = new web3.eth.Contract(OptimisticOracleV3.abi, OptimisticOracleV3.address);
172+
console.log(`Using OptimisticOracleV3 @ ${optimisticOraclev3.options.address}`);
173+
174+
const defaultIdentifier = await optimisticOraclev3.methods.defaultIdentifier().call();
175+
const defaultCurrency = await optimisticOraclev3.methods.defaultCurrency().call();
176+
const txn = await optimisticOraclev3.methods
177+
.syncUmaParams(defaultIdentifier, defaultCurrency)
178+
.send({ from: deployer });
179+
console.log(`Synced OptimisticOracleV3 cached params, tx: ${txn.transactionHash}`);
180+
} catch {
181+
console.log("OptimisticOracleV3 not deployed for this network");
182+
}
183+
});

packages/common/src/hardhat/tasks/registry.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,27 @@ import { CombinedHRE } from "./types";
66
const _registerAccount = async (account: string, registry: Contract, deployer: string) => {
77
const isRegistered = await registry.methods.isContractRegistered(account).call();
88
if (!isRegistered) {
9+
// Only those holding the ContractCreator role can register contracts. So we'll first add the deployer
10+
// as a ContractCreator so that it can register itself.
11+
const isCreator = await registry.methods.holdsRole(RegistryRolesEnum.CONTRACT_CREATOR, deployer).call();
12+
if (!isCreator) {
13+
console.log("Adding deployer as a Contract Creator...");
14+
const txn = await registry.methods
15+
.addMember(RegistryRolesEnum.CONTRACT_CREATOR, deployer)
16+
.send({ from: deployer });
17+
console.log(`...Receipt: ${txn.transactionHash}`);
18+
}
19+
920
console.log(`Registering ${account}...`);
1021
const registerTxn = await registry.methods.registerContract([], account).send({ from: deployer });
1122
console.log(`...Receipt: ${registerTxn.transactionHash}`);
23+
24+
// Remove deployer from contract creator role.
25+
console.log("Removing deployer as Contract Creator...");
26+
const txn = await registry.methods
27+
.removeMember(RegistryRolesEnum.CONTRACT_CREATOR, deployer)
28+
.send({ from: deployer });
29+
console.log(`...Receipt: ${txn.transactionHash}`);
1230
} else {
1331
console.log(`${account} is already registered!`);
1432
}
@@ -26,26 +44,7 @@ task("register-accounts", "Register custom account with Registry capable of maki
2644
const registry = new web3.eth.Contract(Registry.abi, Registry.address);
2745
console.log(`Using Registry @ ${registry.options.address}`);
2846

29-
// Only those holding the ContractCreator role can register contracts. So we'll first add the deployer
30-
// as a ContractCreator so that it can register itself.
31-
const isCreator = await registry.methods.holdsRole(RegistryRolesEnum.CONTRACT_CREATOR, deployer).call();
32-
if (!isCreator) {
33-
console.log("Adding deployer as a Contract Creator...");
34-
const txn = await registry.methods
35-
.addMember(RegistryRolesEnum.CONTRACT_CREATOR, deployer)
36-
.send({ from: deployer });
37-
console.log(`...Receipt: ${txn.transactionHash}`);
38-
}
39-
40-
// Register custom account.
4147
if (account !== "") {
4248
await _registerAccount(account, registry, deployer);
4349
}
44-
45-
// Remove deployer from contract creator role.
46-
console.log("Removing deployer as Contract Creator...");
47-
const txn = await registry.methods
48-
.removeMember(RegistryRolesEnum.CONTRACT_CREATOR, deployer)
49-
.send({ from: deployer });
50-
console.log(`...Receipt: ${txn.transactionHash}`);
5150
});

0 commit comments

Comments
 (0)