Skip to content

Commit

Permalink
feat(governance) refactored the script to check multisig signers and …
Browse files Browse the repository at this point in the history
…settings (#13488)

refactored the script to check multisig signers and settings
  • Loading branch information
julien51 committed Mar 19, 2024
1 parent 8fb443f commit 588de46
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 18 deletions.
9 changes: 4 additions & 5 deletions governance/scripts/multisig/_helpers.js
Expand Up @@ -18,11 +18,10 @@ const getProvider = async (chainId) => {

// custom services URL for network not supported by Safe
const safeServiceURLs = {
42220: 'http://mainnet-tx-svc.celo-safe-prod.celo-networks-dev.org/',
// mumbai isnt supported by Safe Global, you need to run Safe infrastructure locally
80001: 'http://localhost:8000/cgw/',
// for some reasons, zkevm throws in lib
1101: 'https://safe-transaction-zkevm.safe.global',
324: 'https://safe-transaction-zksync.safe.global/api',
1101: 'https://safe-transaction-zkevm.safe.global/api',
534352: 'https://transaction.safe.scroll.xyz/api',
59144: 'https://safe.linea.build/api',
}

// get safeAddress directly from unlock if needed
Expand Down
1 change: 0 additions & 1 deletion governance/scripts/multisig/addOwner.js
@@ -1,5 +1,4 @@
const { ethers } = require('hardhat')

const { getNetwork } = require('@unlock-protocol/hardhat-helpers')
const Safe = require('@safe-global/protocol-kit').default
const { EthersAdapter } = require('@safe-global/protocol-kit')
Expand Down
54 changes: 42 additions & 12 deletions governance/scripts/multisig/info.js
Expand Up @@ -5,8 +5,25 @@ const { networks } = require('@unlock-protocol/networks')

const SafeApiKit = require('@safe-global/api-kit').default

const getMultigiInfo = async (chainId, multisig) => {
const prodSigners = [
'0x9d3ea9e9adde71141f4534dB3b9B80dF3D03Ee5f', // cc
'0x4Ce2DD8373ECe0d7baAA16E559A5817CC875b16a', // jg
'0x4011d09a86D0acA8377a4A8baD691F1ACeeCd672', // nf
'0xcFd35259E3A468E7bDF84a95bCddAc0B614A9212', // aa
'0xccb5D94FbfBFDc4953Ca8a114f88773C2fF98e80', // sm
'0x246A13358Fb27523642D86367a51C2aEB137Ac6C', // cr
].sort()

const devSigners = [
'0x4Ce2DD8373ECe0d7baAA16E559A5817CC875b16a', // jg
'0x246A13358Fb27523642D86367a51C2aEB137Ac6C', // cr
'0x9d3ea9e9adde71141f4534dB3b9B80dF3D03Ee5f', // cc
].sort()

const getMultiSigInfo = async (chainId, multisig) => {
const errors = []
const { isTestNetwork } = networks[chainId]
const expectedSigners = isTestNetwork ? devSigners : prodSigners
const provider = await getProvider(chainId)
// get Safe service
const safeService = new SafeApiKit({
Expand All @@ -26,24 +43,37 @@ const getMultigiInfo = async (chainId, multisig) => {
// queued: false,
// })

const safe = new ethers.Contract(multisig, multisigABI, provider)
const owners = await safe.getOwners()
const policy = await safe.getThreshold()
if (!multisig) {
errors.push('Missing multisig')
} else {
if (policy == 1) {
errors.push('❌ Single policy owner!')
const safe = new ethers.Contract(multisig, multisigABI, provider)
const owners = await safe.getOwners()
const policy = await safe.getThreshold()

if (isTestNetwork && policy < 2) {
errors.push('❌ Policy below 2!')
}
if (!isTestNetwork && policy < 4) {
errors.push(
`❌ Unexpected policy: ${policy}/${owners.length} for 4/${expectedSigners.length} expected`
)
}
if (policy <= 2 || policy / BigInt(owners.length) > 1.5) {
errors.push(`Low policy owner (${policy}/${owners.length})`)

let extraSigners = owners.filter((x) => !expectedSigners.includes(x))
if (extraSigners.length > 0) {
errors.push(`❌ Extra signers: ${[...extraSigners].sort()}`)
}

let missingSigners = expectedSigners.filter((x) => !owners.includes(x))
if (missingSigners.length > 0) {
errors.push(`❌ Missing signers: ${missingSigners}`)
}
}
return errors
}

const log = (name, chainId, msg) =>
console.log(`[${name} (${chainId})]: ${msg}`)
const log = (name, chainId, multisig, msg) =>
console.log(`[${name} (${chainId})]: ${multisig} ${msg}`)

async function main() {
for (let chainId in networks) {
Expand All @@ -52,11 +82,11 @@ async function main() {
const { multisig, name } = networks[chainId]

try {
errors = await getMultigiInfo(chainId, multisig)
errors = await getMultiSigInfo(chainId, multisig)
} catch (error) {
errors = [`Couldn't fetch multisig info: ${error.message}`]
}
errors.forEach((error) => log(name, chainId, error))
errors.forEach((error) => log(name, chainId, multisig, error))
}
}

Expand Down

0 comments on commit 588de46

Please sign in to comment.