Skip to content

Commit c4456c9

Browse files
authored
Merge pull request #607 from lidofinance/feat/vote-199-add-council-rotation
feat: Stakefish council deamon rotation
2 parents fe09542 + d280b06 commit c4456c9

File tree

3 files changed

+63
-10
lines changed

3 files changed

+63
-10
lines changed

configs/config_mainnet.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,10 @@
233233
DSM_GUARDIANS = [
234234
"0x5fd0dDbC3351d009eb3f88DE7Cd081a614C519F1",
235235
"0x7912Fa976BcDe9c2cf728e213e892AD7588E6AaF",
236-
"0xd4EF84b638B334699bcf5AF4B0410B8CCD71943f",
236+
"0x6d22aE126eB2c37F67a1391B37FF4f2863e61389",
237237
"0xf82D88217C249297C6037BA77CE34b3d8a90ab43",
238238
"0xa56b128Ea2Ea237052b0fA2a96a387C0E43157d8",
239-
"0x6d22aE126eB2c37F67a1391B37FF4f2863e61389",
239+
"0x4B87F16B8d32cb5a859a4C48a88edB5adBe3498E",
240240
]
241241
DSM_GUARDIAN_QUORUM = 4
242242

scripts/vote_2026_04_08.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
1.21. Decrease limit from 1000 to 150 stETH per 12 months on Gas Supply AllowedRecipientsRegistry 0x49d1363016aA899bba09ae972a1BF200dDf8C55F
2626
1.22. Set spent amount to 0 on Gas Supply AllowedRecipientsRegistry 0x49d1363016aA899bba09ae972a1BF200dDf8C55F
2727
1.23. Raise CSM (MODULE_ID = 3) stake share limit from 750 BP to 850 BP and priority exit threshold from 900 BP to 1020 BP in Staking Router 0xFdDf38947aFB03C621C71b06C9C70bce73f12999
28+
1.24. Remove old Stakefish address 0xd4EF84b638B334699bcf5AF4B0410B8CCD71943f from Deposit Security Module 0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD and keep quorum size as 4
29+
1.25. Add new Stakefish address 0x4B87F16B8d32cb5a859a4C48a88edB5adBe3498E to Deposit Security Module 0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD and keep quorum size as 4
2830
2931
=== NON-DG ITEMS ===
3032
2. Remove old Simple DVT SubmitValidatorsExitRequestHashes factory 0xB7668B5485d0f826B86a75b0115e088bB9ee03eE from Easy Track 0xF0211b7660680B49De1A7E9f25C65660F0a13Fea
@@ -53,6 +55,7 @@
5355
from utils.mainnet_fork import pass_and_exec_dao_vote
5456
from utils.dual_governance import submit_proposals
5557
from utils.agent import agent_forward
58+
from utils.dsm import encode_remove_guardian, encode_add_guardian
5659
from utils.easy_track import add_evmscript_factory, remove_evmscript_factory, create_permissions
5760
from utils.node_operators import (
5861
deactivate_node_operator,
@@ -89,6 +92,12 @@
8992
CS_HASH_CONSENSUS = "0x71093efF8D8599b5fA340D665Ad60fA7C80688e4"
9093
HASH_CONSENSUS_FOR_VEBO = "0x7FaDB6358950c5fAA66Cb5EB8eE5147De3df355a"
9194

95+
DEPOSIT_SECURITY_MODULE = "0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD"
96+
97+
STAKEFISH_DSM_GUARDIAN_OLD = "0xd4EF84b638B334699bcf5AF4B0410B8CCD71943f"
98+
STAKEFISH_DSM_GUARDIAN_NEW = "0x4B87F16B8d32cb5a859a4C48a88edB5adBe3498E"
99+
DSM_QUORUM_SIZE = 4
100+
92101
GAS_SUPPLY_ALLOWED_RECIPIENTS_REGISTRY = "0x49d1363016aA899bba09ae972a1BF200dDf8C55F"
93102

94103
OLD_SDVT_SUBMIT_EXIT_HASHES_FACTORY = "0xB7668B5485d0f826B86a75b0115e088bB9ee03eE"
@@ -146,14 +155,16 @@
146155
8. **Set Node Operator Chorus One soft target validators limit to 0**, [as requested on the forum](https://research.lido.fi/t/chorus-one-joins-bitwise/11250/3). Item 1.20.
147156
9. **Decrease Gas Supply Easy Track limit from 1000 to 150 stETH per year and reset spent amount for the 2026 period**, [as proposed on the forum](https://research.lido.fi/t/nominate-the-gas-supply-committee-as-a-supervisor-for-gas-expenditure/4724/14). Items 1.21, 1.22.
148157
10. **Raise Community Staking Module stake share limit to 8.5% and priority exit threshold to 10.2%**, [as per Snapshot decision](https://snapshot.org/#/s:lido-snapshot.eth/proposal/0xc3f92bcdf8926cfa7528ca6a979c0fdce1e4d0cfaaa72dd6410a76a2e1e55766). Details in the [forum post](https://research.lido.fi/t/community-staking-module/5917/201). Item 1.23.
149-
11. **Upgrade Curated and SDVT Staking Modules Easy Track factories for validator exit request hashes submission**, [as proposed on the forum](https://research.lido.fi/t/security-bulletin-batched-immunefi-reported-weakness-disclosure-march-2026-funds-not-at-risk/11342/3). Audit & deployment verification: [MixBytes](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Easy%20Track%20Security%20Audit%20Report%2003-26.pdf). Items 2-5.
150-
12. **Upgrade stVaults Easy Track factories to register groups and register & alter tiers in Operator Grid**, [as proposed on the forum](https://research.lido.fi/t/stvaults-committee-proposal/10608/15). Audit & deployment verification: [MixBytes](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Easy%20Track%20stVaults%20Security%20Audit%20Report%2003-26.pdf). Items 6-11.
158+
11. **Rotate Deposit Security Committee address for Stakefish**, [as requested on the forum](https://research.lido.fi/t/stakefish-is-updating-the-address-for-council-daemon/11394). Items 1.24, 1.25.
159+
12. **Upgrade Curated and SDVT Staking Modules Easy Track factories for validator exit request hashes submission**, [as proposed on the forum](https://research.lido.fi/t/security-bulletin-batched-immunefi-reported-weakness-disclosure-march-2026-funds-not-at-risk/11342/3). Audit & deployment verification: [MixBytes](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Easy%20Track%20Security%20Audit%20Report%2003-26.pdf). Items 2-5.
160+
13. **Upgrade stVaults Easy Track factories to register groups and register & alter tiers in Operator Grid**, [as proposed on the forum](https://research.lido.fi/t/stvaults-committee-proposal/10608/15). Audit & deployment verification: [MixBytes](https://github.com/lidofinance/audits/blob/main/MixBytes%20Lido%20Easy%20Track%20stVaults%20Security%20Audit%20Report%2003-26.pdf). Items 6-11.
151161
"""
152162

153163

154164
# ================================ Main ======================================
155165
def get_dg_items() -> List[Tuple[str, str]]:
156166
staking_router = interface.StakingRouter(STAKING_ROUTER)
167+
dsm = interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE)
157168
no_registry = interface.NodeOperatorsRegistry(CURATED_MODULE)
158169
hash_consensus_for_accounting_oracle = interface.HashConsensus(HASH_CONSENSUS_FOR_AO)
159170
cs_hash_consensus = interface.CSHashConsensus(CS_HASH_CONSENSUS)
@@ -367,6 +378,18 @@ def get_dg_items() -> List[Tuple[str, str]]:
367378
)
368379
]
369380
),
381+
# 1.24. Remove old Stakefish address 0xd4EF84b638B334699bcf5AF4B0410B8CCD71943f from Deposit Security Module 0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD and keep quorum size as 4
382+
agent_forward(
383+
[
384+
encode_remove_guardian(dsm=dsm, guardian_address=STAKEFISH_DSM_GUARDIAN_OLD, quorum_size=DSM_QUORUM_SIZE),
385+
]
386+
),
387+
# 1.25. Add new Stakefish address 0x4B87F16B8d32cb5a859a4C48a88edB5adBe3498E to Deposit Security Module 0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD and keep quorum size as 4
388+
agent_forward(
389+
[
390+
encode_add_guardian(dsm=dsm, guardian_address=STAKEFISH_DSM_GUARDIAN_NEW, quorum_size=DSM_QUORUM_SIZE),
391+
]
392+
),
370393
]
371394

372395

@@ -380,14 +403,14 @@ def get_vote_items() -> Tuple[List[str], List[Tuple[str, str]]]:
380403
[
381404
(
382405
dg_items,
383-
"Deactivate A41, change name and reward address for Stakin, upgrade Lazy Oracle, Vault Hub and ZKSync Bridge, rotate addresses for Chorus One and Stakefish oracle set members, set Chorus One target validators limit, decrease Gas Supply ET limit and reset spent amount, raise CSM stake share limit and priority exit threshold",
406+
"Deactivate A41, change name and reward address for Stakin, upgrade Lazy Oracle, Vault Hub and ZKSync Bridge, rotate addresses for Chorus One and Stakefish oracle set members, set Chorus One target validators limit, decrease Gas Supply ET limit and reset spent amount, raise CSM stake share limit and priority exit threshold, rotate DSC address for Stakefish",
384407
)
385408
]
386409
)
387410

388411
vote_desc_items, call_script_items = zip(
389412
(
390-
"1. Submit a Dual Governance proposal to deactivate A41, change name and reward address for Stakin, upgrade Lazy Oracle, Vault Hub and ZKSync Bridge, rotate addresses for Chorus One and Stakefish oracle set members, set Chorus One target validators limit, decrease Gas Supply ET limit and reset spent amount, raise CSM stake share limit and priority exit threshold",
413+
"1. Submit a Dual Governance proposal to deactivate A41, change name and reward address for Stakin, upgrade Lazy Oracle, Vault Hub and ZKSync Bridge, rotate addresses for Chorus One and Stakefish oracle set members, set Chorus One target validators limit, decrease Gas Supply ET limit and reset spent amount, raise CSM stake share limit and priority exit threshold, rotate DSC address for Stakefish",
391414
dg_call_script[0],
392415
),
393416
(

tests/test_2026_04_08.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@
105105
STAKEFISH_ORACLE_MEMBER_OLD = "0x946D3b081ed19173dC83Cd974fC69e1e760B7d78"
106106
STAKEFISH_ORACLE_MEMBER_NEW = "0x042a9e5acCfa17e28300F1b5967f20891E973922"
107107

108+
# Stakefish DSM council daemon rotation
109+
DEPOSIT_SECURITY_MODULE = "0xfFA96D84dEF2EA035c7AB153D8B991128e3d72fD"
110+
STAKEFISH_DSM_GUARDIAN_OLD = "0xd4EF84b638B334699bcf5AF4B0410B8CCD71943f"
111+
STAKEFISH_DSM_GUARDIAN_NEW = "0x4B87F16B8d32cb5a859a4C48a88edB5adBe3498E"
112+
DSM_QUORUM_SIZE = 4
113+
108114
# Node operators
109115
A41_NO_ID = 32
110116
A41_NAME = "A41"
@@ -178,10 +184,10 @@
178184
EXPECTED_VOTE_ID = 199
179185
EXPECTED_DG_PROPOSAL_ID = 9
180186
EXPECTED_VOTE_EVENTS_COUNT = 11 # 1 DG submit + 5 factory removes + 5 factory adds
181-
EXPECTED_DG_EVENTS_FROM_AGENT = 23
182-
EXPECTED_DG_EVENTS_COUNT = 23
183-
IPFS_DESCRIPTION_HASH = "bafkreic2fhcjelgdwpiiy7vxm7kf4g3kuhmmbaerfyoxkns2x5jzovqvaa"
184-
DG_PROPOSAL_METADATA = "Deactivate A41, change name and reward address for Stakin, upgrade Lazy Oracle, Vault Hub and ZKSync Bridge, rotate addresses for Chorus One and Stakefish oracle set members, set Chorus One target validators limit, decrease Gas Supply ET limit and reset spent amount, raise CSM stake share limit and priority exit threshold"
187+
EXPECTED_DG_EVENTS_FROM_AGENT = 25
188+
EXPECTED_DG_EVENTS_COUNT = 25
189+
IPFS_DESCRIPTION_HASH = "bafkreighlr7xyy7ptew2qxpyta4jyyaqh3ra63q3ge7cemrzoajvcr5ytq"
190+
DG_PROPOSAL_METADATA = "Deactivate A41, change name and reward address for Stakin, upgrade Lazy Oracle, Vault Hub and ZKSync Bridge, rotate addresses for Chorus One and Stakefish oracle set members, set Chorus One target validators limit, decrease Gas Supply ET limit and reset spent amount, raise CSM stake share limit and priority exit threshold, rotate DSC address for Stakefish"
185191

186192

187193
@pytest.fixture(scope="module")
@@ -489,6 +495,7 @@ def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, stranger, dual_g
489495
gas_supply_registry = interface.AllowedRecipientRegistry(GAS_SUPPLY_ALLOWED_RECIPIENTS_REGISTRY)
490496
staking_router = interface.StakingRouter(STAKING_ROUTER)
491497
vebo = interface.ValidatorsExitBusOracle(VEBO)
498+
dsm = interface.DepositSecurityModule(DEPOSIT_SECURITY_MODULE)
492499

493500
# =========================================================================
494501
# ======================== Identify or Create vote ========================
@@ -728,6 +735,12 @@ def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, stranger, dual_g
728735
assert csm_module_before["maxDepositsPerBlock"] == CSM_MAX_DEPOSITS_PER_BLOCK
729736
assert csm_module_before["minDepositBlockDistance"] == CSM_MIN_DEPOSIT_BLOCK_DISTANCE
730737

738+
# 1.24-1.25. Stakefish DSM guardian rotation before
739+
assert dsm.isGuardian(STAKEFISH_DSM_GUARDIAN_OLD)
740+
assert not dsm.isGuardian(STAKEFISH_DSM_GUARDIAN_NEW)
741+
dsm_guardians_before = dsm.getGuardians()
742+
dsm_quorum_before = dsm.getGuardianQuorum()
743+
731744
ao_quorum_before = hash_consensus_for_ao.getQuorum()
732745
ao_members_before = len(hash_consensus_for_ao.getMembers()[0])
733746
csm_quorum_before = cs_hash_consensus.getQuorum()
@@ -936,6 +949,16 @@ def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, stranger, dual_g
936949
emitted_by=STAKING_ROUTER,
937950
)
938951

952+
# 1.24. Remove Stakefish council daemon from DSM
953+
assert "GuardianRemoved" in dg_events[23]
954+
assert dg_events[23]["GuardianRemoved"]["guardian"].lower() == STAKEFISH_DSM_GUARDIAN_OLD.lower()
955+
assert dg_events[23]["GuardianRemoved"]["_emitted_by"].lower() == DEPOSIT_SECURITY_MODULE.lower()
956+
957+
# 1.25. Add new Stakefish council daemon to DSM
958+
assert "GuardianAdded" in dg_events[24]
959+
assert dg_events[24]["GuardianAdded"]["guardian"].lower() == STAKEFISH_DSM_GUARDIAN_NEW.lower()
960+
assert dg_events[24]["GuardianAdded"]["_emitted_by"].lower() == DEPOSIT_SECURITY_MODULE.lower()
961+
939962
# =========================================================================
940963
# ==================== After DG proposal executed checks ==================
941964
# =========================================================================
@@ -1015,6 +1038,13 @@ def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, stranger, dual_g
10151038
assert csm_module_after["maxDepositsPerBlock"] == CSM_MAX_DEPOSITS_PER_BLOCK
10161039
assert csm_module_after["minDepositBlockDistance"] == CSM_MIN_DEPOSIT_BLOCK_DISTANCE
10171040

1041+
# 1.24-1.25. Stakefish DSM guardian rotation after
1042+
assert not dsm.isGuardian(STAKEFISH_DSM_GUARDIAN_OLD)
1043+
assert dsm.isGuardian(STAKEFISH_DSM_GUARDIAN_NEW)
1044+
assert len(dsm.getGuardians()) == len(dsm_guardians_before)
1045+
assert dsm.getGuardianQuorum() == dsm_quorum_before
1046+
assert dsm.getGuardianQuorum() == DSM_QUORUM_SIZE
1047+
10181048
ao_quorum_after = hash_consensus_for_ao.getQuorum()
10191049
ao_members_after = len(hash_consensus_for_ao.getMembers()[0])
10201050
csm_quorum_after = cs_hash_consensus.getQuorum()

0 commit comments

Comments
 (0)