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 cd58c7d
Show file tree
Hide file tree
Showing 6 changed files with 234 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"
}
}
50 changes: 50 additions & 0 deletions scripts/configChangePayloads/quorum-change-payloads.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"bsc": {
"args": {
"target": "0xfb5257b22111ed53df225bd71bce8a6e27311170",
"signatures": "0x3c5c5887993007e2042395d7224847444a4685c310282f63cb13d0431bb5f4b4320baf12485d4e967fa24503d8b90d4f593b28dce8f65f9bcfd497b115b38f691bf8cc39482552e0d198609bafa42cd4786dc85039f99f5ad24ddb64e5c61a3f563b26b509808e35659edbf310d5244ce8fb1914f3a2531b1fd5512d1817a20e6a1b",
"callData": "0x8585c9450000000000000000000000000000000000000000000000000000000000000001",
"expiration": 1734735312437,
"vid": "10102"
},
"info": {
"signatures": [
{
"signature": "0x3c5c5887993007e2042395d7224847444a4685c310282f63cb13d0431bb5f4b4320baf12485d4e967fa24503d8b90d4f593b28dce8f65f9bcfd497b115b38f691b",
"address": "0x6a73853254eadca287346cc69d32b5a24b18a063"
},
{
"signature": "0xf8cc39482552e0d198609bafa42cd4786dc85039f99f5ad24ddb64e5c61a3f563b26b509808e35659edbf310d5244ce8fb1914f3a2531b1fd5512d1817a20e6a1b",
"address": "0x85e4857b7f15bbbbbc72d933a6357d3c22a0bbc7"
}
],
"hashCallData": "0x35b891a625434c32d1c0106cd7d21188d58e979e61ab584717e57962d6f3778c",
"oldQuorum": 2,
"newQuorum": 1
}
},
"avalanche": {
"args": {
"target": "0xd28fa1395a45bf2d30af5afded0c7487b156f705",
"signatures": "0xae2f47ccf90b256b2942330bb74c74d59b41873d04732c7ea9997e916b88d63d7a6d7bf723d62d46b038f7b48f640403e3b78fc5ed61b059064e0895fc4260e91c5f8de2df9354743bcb0742ba3c9f7d5bced41d523c55ce44dabc61c5a5073bb175bf31a9a19e46be7d5262b092031bfdc4e432a24d8659811ebc01500e9d4e801c",
"callData": "0x8585c9450000000000000000000000000000000000000000000000000000000000000001",
"expiration": 1734735312437,
"vid": "10106"
},
"info": {
"signatures": [
{
"signature": "0xae2f47ccf90b256b2942330bb74c74d59b41873d04732c7ea9997e916b88d63d7a6d7bf723d62d46b038f7b48f640403e3b78fc5ed61b059064e0895fc4260e91c",
"address": "0x6a73853254eadca287346cc69d32b5a24b18a063"
},
{
"signature": "0x5f8de2df9354743bcb0742ba3c9f7d5bced41d523c55ce44dabc61c5a5073bb175bf31a9a19e46be7d5262b092031bfdc4e432a24d8659811ebc01500e9d4e801c",
"address": "0x85e4857b7f15bbbbbc72d933a6357d3c22a0bbc7"
}
],
"hashCallData": "0x87bbba75ae24aeddbd1fc7a376f991e8ff9f18e85aae98446cd666806ba706ab",
"oldQuorum": 2,
"newQuorum": 1
}
}
}

0 comments on commit cd58c7d

Please sign in to comment.