Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@
"recharts": "^2.15.4",
"rehype-katex": "^7.0.1",
"remark-math": "^6.0.0",
"solc": "^0.8.31",
"solc": "^0.8.34",
"solidity-docgen": "^0.5.17",
"turndown": "^7.1.2",
"turndown": "^7.2.2",
"turndown-plugin-gfm": "^1.0.2",
"viem": "^2.41.2"
"viem": "^2.46.3"
},
"browserslist": {
"production": [
Expand Down
37 changes: 36 additions & 1 deletion scripts/fetchedAddressData.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"timeLastChecked": 1770347214,
"timeLastChecked": 1771960246,
"addressesData": {
"v3ContractAddresses": {
"topLevel": {
Expand Down Expand Up @@ -71,11 +71,38 @@
"yGauge DAI-2 yVault": "0x38E3d865e34f7367a69f096C80A4fc329DB38BF4",
"yGauge WETH-2 yVault": "0x8E2485942B399EA41f3C910c1Bb8567128f79859",
"yGauge crvUSD-2 yVault": "0x71c3223D6f836f84cAA7ab5a68AAb6ECe21A9f3b"
},
"yearnMultisigMembers": {
"multisigAddress": "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52",
"docsMemberAddresses": [
"0x6F2A8Ee9452ba7d336b3fba03caC27f7818AeAD6",
"0xeA6c0837fef621E77329f85820F503cA09f2B3a9",
"0x70aF5a3368606c6557D2B3ce2EEC8796B914EAa3",
"0xf5D3dbda5F41A0E26D71B948e29522398e71cFaE",
"0x5Db9926c93085a92F14A85daBF6FF27b07362Cae",
"0x2B888954421b424C5D3D9Ce9bB67c9bD47537d12",
"0xFe45baf0F18c207152A807c1b05926583CFE2e4b",
"0x962228a90eaC69238c7D1F216d80037e61eA9255",
"0x700F1a984C962b447CcDb95c4c2D8074C65098a3"
],
"onChainOwners": [
"0xf5D3dbda5F41A0E26D71B948e29522398e71cFaE",
"0xeA6c0837fef621E77329f85820F503cA09f2B3a9",
"0x6F2A8Ee9452ba7d336b3fba03caC27f7818AeAD6",
"0x2B888954421b424C5D3D9Ce9bB67c9bD47537d12",
"0xFe45baf0F18c207152A807c1b05926583CFE2e4b",
"0x962228a90eaC69238c7D1F216d80037e61eA9255",
"0x70aF5a3368606c6557D2B3ce2EEC8796B914EAa3",
"0x5Db9926c93085a92F14A85daBF6FF27b07362Cae",
"0x700F1a984C962b447CcDb95c4c2D8074C65098a3"
],
"docsSourcePath": "docs/developers/security/multisig.md"
}
},
"addressChecks": {
"allV3ChecksPassed": true,
"allVeYfiChecksPassed": true,
"allMultisigChecksPassed": true,
"failedChecks": [],
"v3Checks": {
"topLevel": {
Expand Down Expand Up @@ -128,6 +155,14 @@
"yGauge DAI-2 yVault": true,
"yGauge WETH-2 yVault": true,
"yGauge crvUSD-2 yVault": true
},
"multisigChecks": {
"docsMembersSectionParsed": true,
"docsAddressesValid": true,
"docsOwnerCountMatch": true,
"docsUniqueOwnersCheck": true,
"onChainUniqueOwnersCheck": true,
"exactMembersMatch": true
}
}
}
33 changes: 29 additions & 4 deletions scripts/runAddressChecks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
fetchAndCheckYearnV3Addresses,
} from '../src/ethereum/v3Checks'
import { veYfiChecks } from '../src/ethereum/veYfiChecks'
import { checkYearnMultisigMembers } from '../src/ethereum/multisigChecks'
import { yfiContracts, veYfiContracts } from '../src/ethereum/constants'
import {
ContractAddresses,
Expand All @@ -18,7 +19,13 @@ import { mainnet } from 'viem/chains'

dotenv.config()

const alchemyKey = process.env.ALCHEMY_API_KEY
const alchemyKey = process.env.ALCHEMY_API_KEY?.trim()
const invalidAlchemyValues = new Set(['', 'undefined', 'null', 'yourApiKeyHere'])

if (!alchemyKey || invalidAlchemyValues.has(alchemyKey)) {
console.error('Environment vars not set properly')
process.exit(1)
}

const publicClient = createPublicClient({
batch: {
Expand Down Expand Up @@ -90,16 +97,29 @@ const fetchAddresses = async () => {
veYfiCheckFlag = veYfiData?.checkFlag
if (!veYfiData) throw new Error('Failed to fetch veYFI gauge addresses')

let multisigCheckFlag: boolean | undefined
multisigCheckFlag = true
const multisigData = await checkYearnMultisigMembers(
yearnV3Data.addresses.yearnDaddy,
publicClient,
multisigCheckFlag,
failedChecks
)
multisigCheckFlag = multisigData?.checkFlag
if (!multisigData) throw new Error('Failed to fetch multisig owners')

const addressesData: ContractAddresses = {
v3ContractAddresses: v3AddressData,
yfiTokenContracts: yfiContracts,
veYfiContracts: veYfiContracts,
veYfiGaugeAddresses: veYfiData.veYfiGaugeAddresses,
yearnMultisigMembers: multisigData.addresses,
}

const addressChecks: AddressChecks = {
allV3ChecksPassed: v3CheckFlag,
allVeYfiChecksPassed: veYfiCheckFlag,
allMultisigChecksPassed: multisigCheckFlag,
failedChecks,
v3Checks: {
topLevel: topLevelData.checks,
Expand All @@ -108,12 +128,15 @@ const fetchAddresses = async () => {
yearnV3: yearnV3Data.checks,
},
veYfiChecks: veYfiData.veYfiGaugeChecks,
multisigChecks: multisigData.checks,
}
if (
v3CheckFlag === false ||
v3CheckFlag === undefined ||
veYfiCheckFlag === false ||
veYfiCheckFlag === undefined
veYfiCheckFlag === undefined ||
multisigCheckFlag === false ||
multisigCheckFlag === undefined
) {
console.log('Addresses:', addressesData)
console.log('Checks:', addressChecks)
Expand Down Expand Up @@ -141,7 +164,9 @@ async function runAddressCheck() {
}

const allChecksPassed =
addressChecks.allV3ChecksPassed && addressChecks.allVeYfiChecksPassed
addressChecks.allV3ChecksPassed &&
addressChecks.allVeYfiChecksPassed &&
addressChecks.allMultisigChecksPassed
process.env.ALL_CHECKS_PASSED = allChecksPassed ? 'true' : 'false'
console.log('allChecksPassed: ', process.env.ALL_CHECKS_PASSED)

Expand All @@ -156,7 +181,7 @@ async function runAddressCheck() {
issueContent += `- ${check}\n`
})
issueContent +=
'\nThe addresses shown above should be the updated, correct addresses. Please review and change the values in `src/ethereum/constants.ts`.\n'
'\nThe addresses shown above should be the updated, correct addresses. Please review and update the relevant source (`src/ethereum/constants.ts` and/or `docs/developers/security/multisig.md`).\n'

fs.writeFileSync('issue_body.md', issueContent)
console.log('Issue content generated.')
Expand Down
9 changes: 9 additions & 0 deletions src/ethereum/ABIs/gnosisSafeABI.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const gnosisSafeABI = [
{
stateMutability: 'view',
type: 'function',
name: 'getOwners',
inputs: [],
outputs: [{ name: '', type: 'address[]' }],
},
]
1 change: 1 addition & 0 deletions src/ethereum/ABIs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './v3VaultFactoryBlueprintABI'
export * from './veyfiABI'
export * from './yPoolsGenericGovernorABI'
export * from './yPoolsInclusionVoteABI'
export * from './gnosisSafeABI'
18 changes: 18 additions & 0 deletions src/ethereum/multisigCalls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Address, PublicClient, getContract } from 'viem'
import { gnosisSafeABI } from './ABIs'

export const readSafeOwners = async (
safeAddress: Address,
publicClient: PublicClient
) => {
const contract = getContract({
address: safeAddress,
abi: gnosisSafeABI,
client: publicClient,
})

console.log('Fetching Gnosis Safe owners...')
const owners = await contract.read.getOwners()
console.log('Gnosis Safe owners fetched.')
return owners
}
Loading