Skip to content

Commit

Permalink
Scripts to generate payloads needed to do administrative config chang…
Browse files Browse the repository at this point in the history
…es on dvn
  • Loading branch information
MohammadChavosh committed Dec 13, 2024
1 parent a2cc86f commit 48edd29
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 0 deletions.
129 changes: 129 additions & 0 deletions scripts/configChangePayloads/createSetQuorumSignatures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { GcpKmsSigner } from 'ethers-gcp-kms-signer'
import { ethers } from 'ethers'
import { parse } from 'ts-command-line-args'
import { GcpKmsKey, parseKmsKeyIds } from './kms'
import { getChainIdForNetwork } from '@layerzerolabs/lz-definitions'

import path from 'path'
import fs from 'fs'

const PATH = path.join(__dirname)
const FILE_PATH = `${PATH}/quorum-change-payloads.json`

/**
* This script creates signature payloads to be submitted by an Admin of the DVN contract
* that will change the quorum of the DVN contract
*/

const args = parse({
environment: {
alias: 'e',
type: String,
defaultValue: 'mainnet',
description: 'environment',
},
chainNames: {
alias: 'c',
type: String,
description: 'comma separated list of chain names',
},
oldQuorum: {
type: Number,
description:
'old quorum, which is number of signatures required for change to happen',
},
newQuorum: {
type: Number,
description: 'new quorum',
},
})

const setQuorumFunctionSig = 'function setQuorum(uint64 _quorum)'
const EXPIRATION = Date.now() + 7 * 24 * 60 * 60 * 1000 // 1 week expiration from now

const iface = new ethers.utils.Interface([setQuorumFunctionSig])

const getCallData = (newQuorum: number) => {
return iface.encodeFunctionData('setQuorum', [newQuorum])
}

const hashCallData = (target: string, callData: string, vId: string) => {
return ethers.utils.keccak256(
ethers.utils.solidityPack(
['uint32', 'address', 'uint', 'bytes'],
[vId, target, EXPIRATION, callData],
),
)
}

interface Signature {
signature: string
address: string
}

const main = async () => {
const { environment, chainNames, oldQuorum, newQuorum } = args
const dvnAddresses = require(`./data/dvn-addresses-${environment}.json`)
const keyIds = require(`./data/kms-keyids-${environment}.json`)
const signers = await Promise.all(
keyIds.map(async (credentials: GcpKmsKey) => {
return new GcpKmsSigner(credentials)
}),
)
const availableChainNames = chainNames.split(',')

const results: { [chainName: string]: { [sendVersion: string]: any } } = {}
await Promise.all(
availableChainNames.map(async (chainName) => {
results[chainName] = results[chainName] || {}
const vId = getChainIdForNetwork(chainName, environment, '2')
const callData = getCallData(newQuorum)
const hash = hashCallData(dvnAddresses[chainName], callData, vId)
// sign
const signatures = await Promise.all(
signers.map(async (signer) => ({
signature: await signer.signMessage(
ethers.utils.arrayify(hash),
),
address: await signer.getAddress(),
})),
)

signatures.sort((a: Signature, b: Signature) =>
a.address.localeCompare(b.address),
)
const signaturesForQuorum = signatures.slice(0, oldQuorum)
const signaturePayload = ethers.utils.solidityPack(
signaturesForQuorum.map(() => 'bytes'),
signaturesForQuorum.map((s: Signature) => s.signature),
)

results[chainName] = {
args: {
target: dvnAddresses[chainName],
signatures: signaturePayload,
callData,
expiration: EXPIRATION,
vid: vId,
},
info: {
signatures,
hashCallData: hash,
oldQuorum,
newQuorum,
},
}
}),
)
fs.writeFileSync(FILE_PATH, JSON.stringify(results))
console.log(`Results written to: ${FILE_PATH}`)
}

main()
.then(() => {
process.exit(0)
})
.catch((err: any) => {
console.error(err)
process.exit(1)
})
4 changes: 4 additions & 0 deletions scripts/configChangePayloads/data/dvn-addresses-testnet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"bsc": "0xfb5257b22111ed53df225bd71bce8a6e27311170",
"avalanche": "0xd28fa1395a45bf2d30af5afded0c7487b156f705"
}
16 changes: 16 additions & 0 deletions scripts/configChangePayloads/data/kms-keyids-testnet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[
{
"projectId": "gasolina-gcp-test",
"locationId": "global",
"keyRingId": "gasolinaKeyRing",
"keyId": "gasolinaKey1",
"keyVersion": "1"
},
{
"projectId": "gasolina-gcp-test",
"locationId": "global",
"keyRingId": "gasolinaKeyRing",
"keyId": "gasolinaKey2",
"keyVersion": "1"
}
]
18 changes: 18 additions & 0 deletions scripts/configChangePayloads/kms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Defines a GCP KMS Key.
*/
export interface GcpKmsKey {
projectId: string
locationId: string
keyRingId: string
keyId: string
keyVersion: string
}

/**
* Utility to parse GCP KMS Keys from a file.
* @param {string} input
*/
export const parseKmsKeyIds = (input: string): GcpKmsKey[] => {
return JSON.parse(input) as GcpKmsKey[]
}
17 changes: 17 additions & 0 deletions scripts/configChangePayloads/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "@layerzerolabs/gasolina-gcp-scripts",
"version": "1.0.0",
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"@ethersproject/bytes": "5.7.0",
"@ethersproject/providers": "^5.7.0",
"@typechain/ethers-v5": "^10.2.0",
"ethers": "^5.7.2",
"@layerzerolabs/lz-definitions": "^1.5.70",
"ethers-gcp-kms-signer": "^1.1.6",
"typechain": "^8.1.0"
},
"devDependencies": {
"@types/node": "^20.16.10"
}
}

0 comments on commit 48edd29

Please sign in to comment.