|
|
@@ -0,0 +1,79 @@
|
|
|
+import yargs from "yargs";
|
|
|
+import { hideBin } from "yargs/helpers";
|
|
|
+import { EvmChain } from "../src/chains";
|
|
|
+import { DefaultStore } from "../src/store";
|
|
|
+import {
|
|
|
+ EvmUpgradeContract,
|
|
|
+ getProposalInstructions,
|
|
|
+ MultisigParser,
|
|
|
+ WormholeMultisigInstruction,
|
|
|
+} from "xc_admin_common";
|
|
|
+import SquadsMesh from "@sqds/mesh";
|
|
|
+import {
|
|
|
+ getPythClusterApiUrl,
|
|
|
+ PythCluster,
|
|
|
+} from "@pythnetwork/client/lib/cluster";
|
|
|
+import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
|
|
|
+import { AccountMeta, Keypair, PublicKey } from "@solana/web3.js";
|
|
|
+import { EvmContract } from "../src/contracts/evm";
|
|
|
+
|
|
|
+const parser = yargs(hideBin(process.argv))
|
|
|
+ .scriptName("check_proposal.ts")
|
|
|
+ .usage("Usage: $0 --cluster <cluster_id> --proposal <proposal_address>")
|
|
|
+ .options({
|
|
|
+ cluster: {
|
|
|
+ type: "string",
|
|
|
+ demandOption: true,
|
|
|
+ desc: "Multsig Cluster name to check proposal on can be one of [devnet, testnet, mainnet-beta]",
|
|
|
+ },
|
|
|
+ proposal: {
|
|
|
+ type: "string",
|
|
|
+ demandOption: true,
|
|
|
+ desc: "The proposal address to check",
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+async function main() {
|
|
|
+ const argv = await parser.argv;
|
|
|
+ const cluster = argv.cluster as PythCluster;
|
|
|
+ const squad = SquadsMesh.endpoint(
|
|
|
+ getPythClusterApiUrl(cluster),
|
|
|
+ new NodeWallet(Keypair.generate()) // dummy wallet
|
|
|
+ );
|
|
|
+ const transaction = await squad.getTransaction(new PublicKey(argv.proposal));
|
|
|
+ const instructions = await getProposalInstructions(squad, transaction);
|
|
|
+ const multisigParser = MultisigParser.fromCluster(cluster);
|
|
|
+ const parsedInstructions = instructions.map((instruction) => {
|
|
|
+ return multisigParser.parseInstruction({
|
|
|
+ programId: instruction.programId,
|
|
|
+ data: instruction.data as Buffer,
|
|
|
+ keys: instruction.keys as AccountMeta[],
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ for (const instruction of parsedInstructions) {
|
|
|
+ if (instruction instanceof WormholeMultisigInstruction) {
|
|
|
+ if (instruction.governanceAction instanceof EvmUpgradeContract) {
|
|
|
+ console.log(
|
|
|
+ `Verifying EVM Upgrade Contract on ${instruction.governanceAction.targetChainId}`
|
|
|
+ );
|
|
|
+ for (const chain of Object.values(DefaultStore.chains)) {
|
|
|
+ if (
|
|
|
+ chain instanceof EvmChain &&
|
|
|
+ chain.isMainnet() === (cluster === "mainnet-beta") &&
|
|
|
+ chain.wormholeChainName ===
|
|
|
+ instruction.governanceAction.targetChainId
|
|
|
+ ) {
|
|
|
+ const address = instruction.governanceAction.address;
|
|
|
+ const contract = new EvmContract(chain, address);
|
|
|
+ const code = await contract.getCodeDigestWithoutAddress();
|
|
|
+ // this should be the same keccak256 of the deployedCode property generated by truffle
|
|
|
+ console.log(`Address:${address} digest:${code}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+main();
|