Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/code-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- run: npm ci
env:
GH_TOKEN: ${{ secrets.github_token }}
- run: npx hardhat test --coverage
- run: npx hardhat test mocha --coverage
env:
NO_GAS_ENFORCE: '1'
COVERAGE: 'true'
14 changes: 14 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ upgrade env network="":
generate-safe-batch env="mainnet":
npx tsx scripts/generate-safe-batch.ts --env {{env}}

# Generate hotfix deployment attestation for a two-module mainnet hotfix
generate-hotfix-attestation env clusters validators network="":
npx tsx scripts/generate-hotfix-attestation.ts --env {{env}} --clusters {{clusters}} --validators {{validators}} {{ if network == "" { "" } else { "--network " + network } }}

# Generate hotfix SAFE batch with exactly SSVClusters and SSVValidators updateModule calls
generate-hotfix-safe-batch env clusters validators:
npx tsx scripts/generate-hotfix-safe-batch.ts --env {{env}} --clusters {{clusters}} --validators {{validators}}

# Generate deployment attestation (bytecode hashes + config summary for committee review)
generate-attestation env="mainnet" network="":
npx tsx scripts/generate-deployment-attestation.ts --env {{env}} {{ if network == "" { "" } else { "--network " + network } }}
Expand Down Expand Up @@ -108,6 +116,12 @@ attach-module env module module-address network="":
npx hardhat compile --force
npx tsx scripts/attach-module.ts --env {{env}} --module {{module}} --module-address {{module-address}} {{ if network == "" { "" } else { "--network " + network } }}

# Deploy a new module implementation and attach it to the proxy in one step
# Example: just update-module SSVValidators 0xProxyAddress hoodi
update-module module proxy network:
npx hardhat compile --force
npx tsx scripts/update-module.ts --module {{module}} --proxy-address {{proxy}} --network {{network}}

# Upgrade a contract via UUPS proxy pattern (optionally with pre-deployed impl)
upgrade-contract contract proxy network *impl:
npx hardhat compile --force
Expand Down
4 changes: 4 additions & 0 deletions contracts/modules/SSVClusters.sol
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ contract SSVClusters is ISSVClusters, SSVReentrancyGuard {
// Deviation-only model: baseline added via ethValidatorCount (in updateClusterOperatorsMigration above)
// Only add deviation if cluster has explicit EB tracking
uint64 vUnitsCluster = ebSnapshot.vUnits;
if (cluster.validatorCount == 0 && vUnitsCluster > 0) {
ebSnapshot.vUnits = 0;
vUnitsCluster = 0;
}
if (vUnitsCluster > 0) {
uint64 baseline = uint64(cluster.validatorCount) * BPS_DENOMINATOR;

Expand Down
6 changes: 6 additions & 0 deletions contracts/modules/SSVValidators.sol
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,12 @@ contract SSVValidators is ISSVValidators {
}

cluster.validatorCount -= validatorsRemoved;

if (cluster.validatorCount == 0) {
StorageEB storage seb = SSVStorageEB.load();
seb.clusterEB[hashedCluster].vUnits = 0;
}

s.clusters[hashedCluster] = cluster.hashClusterData();
} else {
revert IncorrectClusterVersion();
Expand Down
25 changes: 25 additions & 0 deletions deployments/hoodi-prod/deploy-result.v2.0.0-upgrade4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"deployer": "0xC564AF154621Ee8D0589758d535511aEc8f67b40",
"chainId": "560048",
"network": "hoodi",
"deployedAt": "2026-03-17T12:18:01.926Z",
"blockNumber": 2434756,
"implementations": {
"SSVNetworkSSVStakingUpgrade": "0x80Be9D66831Ab6a40f16c10f78a81e6CDfB15057",
"SSVNetworkViews": "0xf70E9396a801BabDfe972D74ECce9716f164335b"
},
"cssvToken": {
"address": "0x6e1a5d27361c666f681af06535c8Ac773E571d4d",
"deployed": false
},
"modules": {
"SSVOperators": "0x6D4AeD4a18fAb66733EE3C52Eeb795b1ef660a85",
"SSVClusters": "0xD2E740424D339F36a6912e53684d901db2dfD236",
"SSVDAO": "0xf3929A559Aa14C75F41Bc59BfeB5BdCEd0e2ea1D",
"SSVViews": "0xc3d2F9eBa309a666C8c3Fd8580365366530FC1AF",
"SSVOperatorsWhitelist": "0xCd273a679f617144f290B5DBe81575E221965060",
"SSVStaking": "0x6C9aae90F5AFF6d282cE529aEFe258EaF7bd4d70",
"SSVValidators": "0x023Af0382D4243637F4b5264bebA97Ab81AE27A6"
},
"updatedAt": "2026-04-07T12:17:51.362Z"
}
4 changes: 2 additions & 2 deletions deployments/hoodi-prod/deploy-result.v2.0.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
},
"modules": {
"SSVOperators": "0x6D4AeD4a18fAb66733EE3C52Eeb795b1ef660a85",
"SSVClusters": "0xD2E740424D339F36a6912e53684d901db2dfD236",
"SSVClusters": "0xa5D12C6c73cA08c70D4b19575320EEAB4c22c51c",
"SSVDAO": "0xf3929A559Aa14C75F41Bc59BfeB5BdCEd0e2ea1D",
"SSVViews": "0xc3d2F9eBa309a666C8c3Fd8580365366530FC1AF",
"SSVOperatorsWhitelist": "0xCd273a679f617144f290B5DBe81575E221965060",
"SSVStaking": "0x6C9aae90F5AFF6d282cE529aEFe258EaF7bd4d70",
"SSVValidators": "0x023Af0382D4243637F4b5264bebA97Ab81AE27A6"
"SSVValidators": "0x3965Ebe3302b7dEC0563DaCc2f20DE5171E9ec2D"
},
"updatedAt": "2026-04-07T12:17:51.362Z"
}
24 changes: 24 additions & 0 deletions deployments/hoodi-stage/deploy-result.v2.0.0-upgrade7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"deployer": "0xC564AF154621Ee8D0589758d535511aEc8f67b40",
"chainId": "560048",
"network": "hoodi",
"deployedAt": "2026-03-17T10:15:01.803Z",
"blockNumber": 1773756095,
"implementations": {
"SSVNetworkSSVStakingUpgrade": "0x6749B3Ade59FbA80f4e5c4066A993181843E1c00",
"SSVNetworkViews": "0x4c6f92E6d13748a83E96dF2AA5D3839a9Ed2b607"
},
"cssvToken": {
"address": "0x6455a0d83FeB099182Fb6D024B9Ae0c2E26C0859",
"deployed": false
},
"modules": {
"SSVOperators": "0x4a4972222E277794E697759Da629B9dB21b19246",
"SSVClusters": "0x5add198304F3d2596c253edF2A260e8e66c2042c",
"SSVDAO": "0x824e169e138B3B91977e040F80547Fce3779db97",
"SSVViews": "0xae12ceCA94a14aAC6c15A473FAAD9Cb75B2be53A",
"SSVOperatorsWhitelist": "0x5734A479F463e3DddDBB8fFC2C82253d41777BbC",
"SSVStaking": "0x99f2B313BD913d6E11E91BA7B3c5B51c4E486bE5",
"SSVValidators": "0x57aE505496ED7BF377A28bb645d4242CC5c74330"
}
}
4 changes: 2 additions & 2 deletions deployments/hoodi-stage/deploy-result.v2.0.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
},
"modules": {
"SSVOperators": "0x4a4972222E277794E697759Da629B9dB21b19246",
"SSVClusters": "0x5add198304F3d2596c253edF2A260e8e66c2042c",
"SSVClusters": "0xa5D12C6c73cA08c70D4b19575320EEAB4c22c51c",
"SSVDAO": "0x824e169e138B3B91977e040F80547Fce3779db97",
"SSVViews": "0xae12ceCA94a14aAC6c15A473FAAD9Cb75B2be53A",
"SSVOperatorsWhitelist": "0x5734A479F463e3DddDBB8fFC2C82253d41777BbC",
"SSVStaking": "0x99f2B313BD913d6E11E91BA7B3c5B51c4E486bE5",
"SSVValidators": "0x57aE505496ED7BF377A28bb645d4242CC5c74330"
"SSVValidators": "0x3965Ebe3302b7dEC0563DaCc2f20DE5171E9ec2D"
}
}
24 changes: 24 additions & 0 deletions deployments/mainnet/deploy-result.v2.0.0-initial.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"deployer": "0x3187a42658417a4d60866163A4534Ce00D40C0C8",
"chainId": "1",
"network": "mainnet",
"deployedAt": "2026-04-19T08:25:37.577Z",
"blockNumber": 24912723,
"implementations": {
"SSVNetworkSSVStakingUpgrade": "0xa72a8F31163d74D708664493d09167dfa13008E9",
"SSVNetworkViews": "0xAdEb99eb2307F874D72b1F814fCa106f6BFaA8E9"
},
"cssvToken": {
"address": "0xe018D31F120A637828F46aFD6c64EC099d960546",
"deployed": false
},
"modules": {
"SSVOperators": "0x38DaA3fC4B1E5c02742b67F241B27Dceb8BFFA45",
"SSVClusters": "0x5DD8980c3c8B48BAce3A2Ec481bD61f7dE1523a9",
"SSVDAO": "0x94ef691dAa32cC2d31897aE8767e02988f1add4F",
"SSVViews": "0xf73954Ad8C96647c2238e6B7A435557Def23c19F",
"SSVOperatorsWhitelist": "0xE8CEac3f59EF0214c957Fd72F003bc9671a7196B",
"SSVStaking": "0x238C9C4f6026924c7B51400fa63452FAFF8e959A",
"SSVValidators": "0xCFA765F971B1D10b7bf989aad80cab817b92Fe1e"
}
}
4 changes: 2 additions & 2 deletions deployments/mainnet/deploy-result.v2.0.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
},
"modules": {
"SSVOperators": "0x38DaA3fC4B1E5c02742b67F241B27Dceb8BFFA45",
"SSVClusters": "0x5DD8980c3c8B48BAce3A2Ec481bD61f7dE1523a9",
"SSVClusters": "0x3611D36A7C052211D6f3B1a39326ad38A02832B4",
"SSVDAO": "0x94ef691dAa32cC2d31897aE8767e02988f1add4F",
"SSVViews": "0xf73954Ad8C96647c2238e6B7A435557Def23c19F",
"SSVOperatorsWhitelist": "0xE8CEac3f59EF0214c957Fd72F003bc9671a7196B",
"SSVStaking": "0x238C9C4f6026924c7B51400fa63452FAFF8e959A",
"SSVValidators": "0xCFA765F971B1D10b7bf989aad80cab817b92Fe1e"
"SSVValidators": "0x9122Fded65Ed6b562243efDC9E55ff0bEF5E7499"
}
}
44 changes: 44 additions & 0 deletions deployments/mainnet/hotfix-deployment-attestation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"generatedAt": "2026-05-06T17:21:30.504Z",
"hotfix": {
"env": "mainnet",
"network": "mainnet",
"chainId": "1",
"ssvNetworkProxy": "0xDD9BC35aE942eF0cFa76930954a156B3fF30a4E1",
"owner": "0xb35096b074fdb9bBac63E3AdaE0Bbde512B2E6b6",
"description": "Hotfix deployment attestation for replacing only SSVClusters and SSVValidators module pointers."
},
"contracts": {
"SSVClusters": {
"address": "0x3611D36A7C052211D6f3B1a39326ad38A02832B4",
"moduleId": 1,
"constructorArgs": {},
"bytecodeHash": "0x2711afb14d4a81c44ea925939951ba37c5b3dfd49dd78ed4b235eb3052332e90"
},
"SSVValidators": {
"address": "0x9122Fded65Ed6b562243efDC9E55ff0bEF5E7499",
"moduleId": 6,
"constructorArgs": {},
"bytecodeHash": "0x91b323fa83a049400037c0d0e04843850719c1598385c2780df8bfc2d1a0d2b1"
}
},
"intendedSafeTransactions": [
{
"target": "0xDD9BC35aE942eF0cFa76930954a156B3fF30a4E1",
"function": "updateModule(uint8,address)",
"moduleName": "SSVClusters",
"moduleId": 1,
"moduleAddress": "0x3611D36A7C052211D6f3B1a39326ad38A02832B4"
},
{
"target": "0xDD9BC35aE942eF0cFa76930954a156B3fF30a4E1",
"function": "updateModule(uint8,address)",
"moduleName": "SSVValidators",
"moduleId": 6,
"moduleAddress": "0x9122Fded65Ed6b562243efDC9E55ff0bEF5E7499"
}
],
"relatedFileHashes": {
"hotfix-multisig-batch.json": "0xff5ea2ace65e5738340bf7d6512ebd1ebb574325f8cc27c2344575c313ff8bc2"
}
}
56 changes: 56 additions & 0 deletions deployments/mainnet/hotfix-multisig-batch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"version": "1.0",
"chainId": "1",
"createdAt": 1778088000273,
"meta": {
"name": "SSV Network Module Hotfix (mainnet)",
"description": "Hotfix batch for SSVNetwork.updateModule on SSVClusters and SSVValidators only. No proxy upgrade or parameter changes.",
"createdFromSafeAddress": "0xb35096b074fdb9bBac63E3AdaE0Bbde512B2E6b6"
},
"transactions": [
{
"to": "0xDD9BC35aE942eF0cFa76930954a156B3fF30a4E1",
"value": "0",
"data": "0xe3e324b000000000000000000000000000000000000000000000000000000000000000010000000000000000000000003611d36a7c052211d6f3b1a39326ad38a02832b4",
"contractMethod": {
"name": "updateModule",
"inputs": [
{
"name": "moduleId",
"type": "uint8"
},
{
"name": "moduleAddress",
"type": "address"
}
]
},
"contractInputsValues": {
"moduleId": "1",
"moduleAddress": "0x3611D36A7C052211D6f3B1a39326ad38A02832B4"
}
},
{
"to": "0xDD9BC35aE942eF0cFa76930954a156B3fF30a4E1",
"value": "0",
"data": "0xe3e324b000000000000000000000000000000000000000000000000000000000000000060000000000000000000000009122fded65ed6b562243efdc9e55ff0bef5e7499",
"contractMethod": {
"name": "updateModule",
"inputs": [
{
"name": "moduleId",
"type": "uint8"
},
{
"name": "moduleAddress",
"type": "address"
}
]
},
"contractInputsValues": {
"moduleId": "6",
"moduleAddress": "0x9122Fded65Ed6b562243efDC9E55ff0bEF5E7499"
}
}
]
}
Loading
Loading