Skip to content

Commit 587a6fa

Browse files
author
Dev Kalra
authored
feat(contract_manager): upgrade deploy scripts to use wormhole store (#1523)
* upgrade deploy scripts to use wormhole store * deploy not find * deploy price feed and entropy to taiko * rename type * rename method * address feedback * update js docs * deploy to olive testnet * pre commit * rename deploy config to base deploy config
1 parent a592c6b commit 587a6fa

File tree

11 files changed

+177
-118
lines changed

11 files changed

+177
-118
lines changed

contract_manager/scripts/common.ts

Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
import { DefaultStore, EvmChain, EvmEntropyContract, PrivateKey } from "../src";
1+
import {
2+
DefaultStore,
3+
EvmChain,
4+
EvmEntropyContract,
5+
EvmWormholeContract,
6+
getDefaultDeploymentConfig,
7+
PrivateKey,
8+
} from "../src";
29
import { existsSync, readFileSync, writeFileSync } from "fs";
310
import { join } from "path";
411
import Web3 from "web3";
512
import { Contract } from "web3-eth-contract";
613
import { InferredOptionType } from "yargs";
714

8-
interface DeployConfig {
15+
export interface BaseDeployConfig {
916
gasMultiplier: number;
1017
gasPriceMultiplier: number;
1118
jsonOutputDir: string;
@@ -19,7 +26,7 @@ interface DeployConfig {
1926
export async function deployIfNotCached(
2027
cacheFile: string,
2128
chain: EvmChain,
22-
config: DeployConfig,
29+
config: BaseDeployConfig,
2330
artifactName: string,
2431
deployArgs: any[], // eslint-disable-line @typescript-eslint/no-explicit-any
2532
cacheKey?: string
@@ -212,3 +219,118 @@ export function findEvmChain(chainName: string): EvmChain {
212219
}
213220
return chain;
214221
}
222+
223+
/**
224+
* Finds the wormhole contract for a given EVM chain.
225+
* @param {EvmChain} chain The EVM chain to find the wormhole contract for.
226+
* @returns If found, the wormhole contract for the given EVM chain. Else, undefined
227+
*/
228+
export function findWormholeContract(
229+
chain: EvmChain
230+
): EvmWormholeContract | undefined {
231+
for (const contract of Object.values(DefaultStore.wormhole_contracts)) {
232+
if (
233+
contract instanceof EvmWormholeContract &&
234+
contract.getChain().getId() === chain.getId()
235+
) {
236+
return contract;
237+
}
238+
}
239+
}
240+
241+
export interface DeployWormholeReceiverContractsConfig
242+
extends BaseDeployConfig {
243+
saveContract: boolean;
244+
type: "stable" | "beta";
245+
}
246+
/**
247+
* Deploys the wormhole receiver contract for a given EVM chain.
248+
* @param {EvmChain} chain The EVM chain to find the wormhole receiver contract for.
249+
* @param {DeployWormholeReceiverContractsConfig} config The deployment configuration.
250+
* @param {string} cacheFile The path to the cache file.
251+
* @returns {EvmWormholeContract} The wormhole contract for the given EVM chain.
252+
*/
253+
export async function deployWormholeContract(
254+
chain: EvmChain,
255+
config: DeployWormholeReceiverContractsConfig,
256+
cacheFile: string
257+
): Promise<EvmWormholeContract> {
258+
const receiverSetupAddr = await deployIfNotCached(
259+
cacheFile,
260+
chain,
261+
config,
262+
"ReceiverSetup",
263+
[]
264+
);
265+
266+
const receiverImplAddr = await deployIfNotCached(
267+
cacheFile,
268+
chain,
269+
config,
270+
"ReceiverImplementation",
271+
[]
272+
);
273+
274+
// Craft the init data for the proxy contract
275+
const setupContract = getWeb3Contract(
276+
config.jsonOutputDir,
277+
"ReceiverSetup",
278+
receiverSetupAddr
279+
);
280+
281+
const { wormholeConfig } = getDefaultDeploymentConfig(config.type);
282+
283+
const initData = setupContract.methods
284+
.setup(
285+
receiverImplAddr,
286+
wormholeConfig.initialGuardianSet.map((addr: string) => "0x" + addr),
287+
chain.getWormholeChainId(),
288+
wormholeConfig.governanceChainId,
289+
"0x" + wormholeConfig.governanceContract
290+
)
291+
.encodeABI();
292+
293+
const wormholeReceiverAddr = await deployIfNotCached(
294+
cacheFile,
295+
chain,
296+
config,
297+
"WormholeReceiver",
298+
[receiverSetupAddr, initData]
299+
);
300+
301+
const wormholeContract = new EvmWormholeContract(chain, wormholeReceiverAddr);
302+
303+
if (config.type === "stable") {
304+
console.log(`Syncing mainnet guardian sets for ${chain.getId()}...`);
305+
// TODO: Add a way to pass gas configs to this
306+
await wormholeContract.syncMainnetGuardianSets(config.privateKey);
307+
console.log(`✅ Synced mainnet guardian sets for ${chain.getId()}`);
308+
}
309+
310+
if (config.saveContract) {
311+
DefaultStore.wormhole_contracts[wormholeContract.getId()] =
312+
wormholeContract;
313+
DefaultStore.saveAllContracts();
314+
}
315+
316+
return wormholeContract;
317+
}
318+
319+
/**
320+
* Returns the wormhole contract for a given EVM chain.
321+
* If there was no wormhole contract deployed for the given chain, it will deploy the wormhole contract and save it to the default store.
322+
* @param {EvmChain} chain The EVM chain to find the wormhole contract for.
323+
* @param {DeployWormholeReceiverContractsConfig} config The deployment configuration.
324+
* @param {string} cacheFile The path to the cache file.
325+
* @returns {EvmWormholeContract} The wormhole contract for the given EVM chain.
326+
*/
327+
export async function getOrDeployWormholeContract(
328+
chain: EvmChain,
329+
config: DeployWormholeReceiverContractsConfig,
330+
cacheFile: string
331+
): Promise<EvmWormholeContract> {
332+
return (
333+
findWormholeContract(chain) ??
334+
(await deployWormholeContract(chain, config, cacheFile))
335+
);
336+
}

contract_manager/scripts/deploy_evm_entropy_contracts.ts

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,23 @@ import { DefaultStore } from "../src/store";
55
import {
66
DeploymentType,
77
EvmEntropyContract,
8-
EvmPriceFeedContract,
98
getDefaultDeploymentConfig,
10-
PrivateKey,
119
toDeploymentType,
1210
toPrivateKey,
13-
EvmWormholeContract,
1411
} from "../src";
1512
import {
1613
COMMON_DEPLOY_OPTIONS,
1714
deployIfNotCached,
1815
getWeb3Contract,
16+
getOrDeployWormholeContract,
17+
BaseDeployConfig,
1918
} from "./common";
2019
import Web3 from "web3";
2120

22-
type DeploymentConfig = {
21+
interface DeploymentConfig extends BaseDeployConfig {
2322
type: DeploymentType;
24-
gasMultiplier: number;
25-
gasPriceMultiplier: number;
26-
privateKey: PrivateKey;
27-
jsonOutputDir: string;
28-
wormholeAddr: string;
2923
saveContract: boolean;
30-
};
24+
}
3125

3226
const CACHE_FILE = ".cache-deploy-evm-entropy-contracts";
3327
const ENTROPY_DEFAULT_PROVIDER = {
@@ -51,7 +45,8 @@ const parser = yargs(hideBin(process.argv))
5145

5246
async function deployExecutorContracts(
5347
chain: EvmChain,
54-
config: DeploymentConfig
48+
config: DeploymentConfig,
49+
wormholeAddr: string
5550
): Promise<string> {
5651
const executorImplAddr = await deployIfNotCached(
5752
CACHE_FILE,
@@ -72,7 +67,7 @@ async function deployExecutorContracts(
7267

7368
const executorInitData = executorImplContract.methods
7469
.initialize(
75-
config.wormholeAddr,
70+
wormholeAddr,
7671
0, // lastExecutedSequence,
7772
chain.getWormholeChainId(),
7873
governanceDataSource.emitterChain,
@@ -161,19 +156,6 @@ async function topupProviderIfNecessary(
161156
}
162157
}
163158

164-
async function findWormholeAddress(
165-
chain: EvmChain
166-
): Promise<string | undefined> {
167-
for (const contract of Object.values(DefaultStore.contracts)) {
168-
if (
169-
contract instanceof EvmPriceFeedContract &&
170-
contract.getChain().getId() === chain.getId()
171-
) {
172-
return (await contract.getWormholeContract()).address;
173-
}
174-
}
175-
}
176-
177159
async function main() {
178160
const argv = await parser.argv;
179161

@@ -185,31 +167,21 @@ async function main() {
185167
throw new Error(`Chain ${chainName} is not an EVM chain`);
186168
}
187169

188-
const wormholeAddr = await findWormholeAddress(chain);
189-
if (!wormholeAddr) {
190-
// TODO: deploy wormhole if necessary and maintain a wormhole store
191-
throw new Error(`Wormhole contract not found for chain ${chain.getId()}`);
192-
}
193-
194170
const deploymentConfig: DeploymentConfig = {
195171
type: toDeploymentType(argv.deploymentType),
196172
gasMultiplier: argv.gasMultiplier,
197173
gasPriceMultiplier: argv.gasPriceMultiplier,
198174
privateKey: toPrivateKey(argv.privateKey),
199175
jsonOutputDir: argv.stdOutputDir,
200176
saveContract: argv.saveContract,
201-
wormholeAddr,
202177
};
203-
const wormholeContract = new EvmWormholeContract(
178+
179+
const wormholeContract = await getOrDeployWormholeContract(
204180
chain,
205-
deploymentConfig.wormholeAddr
181+
deploymentConfig,
182+
CACHE_FILE
206183
);
207-
const wormholeChainId = await wormholeContract.getChainId();
208-
if (chain.getWormholeChainId() != wormholeChainId) {
209-
throw new Error(
210-
`Wormhole chain id mismatch. Expected ${chain.getWormholeChainId()} but got ${wormholeChainId}`
211-
);
212-
}
184+
213185
await topupProviderIfNecessary(chain, deploymentConfig);
214186

215187
console.log(
@@ -218,7 +190,11 @@ async function main() {
218190

219191
console.log(`Deploying entropy contracts on ${chain.getId()}...`);
220192

221-
const executorAddr = await deployExecutorContracts(chain, deploymentConfig);
193+
const executorAddr = await deployExecutorContracts(
194+
chain,
195+
deploymentConfig,
196+
wormholeContract.address
197+
);
222198
const entropyAddr = await deployEntropyContracts(
223199
chain,
224200
deploymentConfig,

contract_manager/scripts/deploy_evm_pricefeed_contracts.ts

Lines changed: 9 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,23 @@ import {
66
DeploymentType,
77
EvmPriceFeedContract,
88
getDefaultDeploymentConfig,
9-
PrivateKey,
109
toDeploymentType,
1110
toPrivateKey,
12-
EvmWormholeContract,
1311
} from "../src";
1412
import {
1513
COMMON_DEPLOY_OPTIONS,
1614
deployIfNotCached,
1715
getWeb3Contract,
16+
getOrDeployWormholeContract,
17+
BaseDeployConfig,
1818
} from "./common";
1919

20-
type DeploymentConfig = {
20+
interface DeploymentConfig extends BaseDeployConfig {
2121
type: DeploymentType;
2222
validTimePeriodSeconds: number;
2323
singleUpdateFeeInWei: number;
24-
gasMultiplier: number;
25-
gasPriceMultiplier: number;
26-
privateKey: PrivateKey;
27-
jsonOutputDir: string;
2824
saveContract: boolean;
29-
};
25+
}
3026

3127
const CACHE_FILE = ".cache-deploy-evm";
3228

@@ -51,65 +47,6 @@ const parser = yargs(hideBin(process.argv))
5147
},
5248
});
5349

54-
async function deployWormholeReceiverContracts(
55-
chain: EvmChain,
56-
config: DeploymentConfig
57-
): Promise<string> {
58-
const receiverSetupAddr = await deployIfNotCached(
59-
CACHE_FILE,
60-
chain,
61-
config,
62-
"ReceiverSetup",
63-
[]
64-
);
65-
66-
const receiverImplAddr = await deployIfNotCached(
67-
CACHE_FILE,
68-
chain,
69-
config,
70-
"ReceiverImplementation",
71-
[]
72-
);
73-
74-
// Craft the init data for the proxy contract
75-
const setupContract = getWeb3Contract(
76-
config.jsonOutputDir,
77-
"ReceiverSetup",
78-
receiverSetupAddr
79-
);
80-
81-
const { wormholeConfig } = getDefaultDeploymentConfig(config.type);
82-
83-
const initData = setupContract.methods
84-
.setup(
85-
receiverImplAddr,
86-
wormholeConfig.initialGuardianSet.map((addr: string) => "0x" + addr),
87-
chain.getWormholeChainId(),
88-
wormholeConfig.governanceChainId,
89-
"0x" + wormholeConfig.governanceContract
90-
)
91-
.encodeABI();
92-
93-
const wormholeReceiverAddr = await deployIfNotCached(
94-
CACHE_FILE,
95-
chain,
96-
config,
97-
"WormholeReceiver",
98-
[receiverSetupAddr, initData]
99-
);
100-
101-
const wormholeContract = new EvmWormholeContract(chain, wormholeReceiverAddr);
102-
103-
if (config.type === "stable") {
104-
console.log(`Syncing mainnet guardian sets for ${chain.getId()}...`);
105-
// TODO: Add a way to pass gas configs to this
106-
await wormholeContract.syncMainnetGuardianSets(config.privateKey);
107-
console.log(`✅ Synced mainnet guardian sets for ${chain.getId()}`);
108-
}
109-
110-
return wormholeReceiverAddr;
111-
}
112-
11350
async function deployPriceFeedContracts(
11451
chain: EvmChain,
11552
config: DeploymentConfig,
@@ -183,14 +120,16 @@ async function main() {
183120

184121
console.log(`Deploying price feed contracts on ${chain.getId()}...`);
185122

186-
const wormholeAddr = await deployWormholeReceiverContracts(
123+
const wormholeContract = await getOrDeployWormholeContract(
187124
chain,
188-
deploymentConfig
125+
deploymentConfig,
126+
CACHE_FILE
189127
);
128+
190129
const priceFeedAddr = await deployPriceFeedContracts(
191130
chain,
192131
deploymentConfig,
193-
wormholeAddr
132+
wormholeContract.address
194133
);
195134

196135
if (deploymentConfig.saveContract) {

contract_manager/store/chains/EvmChains.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,3 +569,8 @@
569569
rpcUrl: https://olive-network-testnet.rpc.caldera.xyz/http
570570
networkId: 8101902
571571
type: EvmChain
572+
- id: taiko_hekla
573+
mainnet: false
574+
rpcUrl: https://rpc.hekla.taiko.xyz/
575+
networkId: 167009
576+
type: EvmChain

0 commit comments

Comments
 (0)